Ticket #981: 981-v2.patch

File 981-v2.patch, 20.3 KB (added by danielk, 16 years ago)

updated patch

  • libs/libmythtv/tv_play.cpp

     
    33053305    queuedChanID  = 0;
    33063306}
    33073307
    3308 void TV::AddKeyToInputQueue(char key)
     3308/*
     3309void
    33093310{
    3310     static char *spacers[5] = { "_", "-", "#", ".", NULL };
     3311    query.prepare(
     3312        "SELECT cardid"
     3313        "WHERE channel.chanid   = :CHANID AND"
     3314        "      channel.sourceid = cardinput.sourceid");
     3315    query.bindValue(":CHANID", found_chanid[0]);
    33113316
    3312     if (key)
     3317    if (!query.exec() || !query.isActive())
    33133318    {
    3314         QMutexLocker locker(&queuedInputLock);
    3315         queuedInput   = queuedInput.append(key).right(kInputKeysMax);
    3316         queuedChanNum = queuedChanNum.append(key).right(kInputKeysMax);
     3319        MythContext::DBError("checkchannel -- locate cardid", query);
    33173320    }
     3321    else if (query.size() && query.next())
     3322    {
     3323        is_complete_valid_channel_on_rec = query.value(0).toUInt();
     3324        needed_spacer = QDeepCopy<QString>(needed_spacers[0]);
    33183325
    3319     /*
    3320      * Always use smartChannelChange when channel numbers are entered in
    3321      * browse mode because in browse mode space/enter exit browse mode and
    3322      * change to the currently browsed channel. This makes smartChannelChange
    3323      * the only way to enter a channel number to browse without waiting for the
    3324      * OSD to fadeout after entering numbers.
    3325      */
    3326     bool do_smart = StateIsLiveTV(GetState()) &&
    3327         !ccInputMode && !asInputMode &&
    3328         (smartChannelChange || browsemode);
    3329     QString chan = GetQueuedChanNum();
    3330     if (!chan.isEmpty() && do_smart)
     3326        // if this channel is available on multiple cards
     3327        // we want the current card to be the on_rec card.
     3328        while (query.next())
     3329        {
     3330            if (query.value(0).toUInt() == cardid)
     3331                is_complete_valid_channel_on_rec = cardid;
     3332        }
     3333    }
     3334}
     3335*/
     3336
     3337static QString add_spacer(const QString &chan, const QString &spacer)
     3338{
     3339    if ((chan.length() > 2) && !spacer.isEmpty())
     3340        return chan.left(chan.length()-1) + spacer + chan.right(1);
     3341    return chan;
     3342}
     3343
     3344#define DEBUG_CHANNEL_PREFIX
     3345
     3346/**
     3347 *  \return true if this could be a prefix to a valid channel
     3348 */
     3349bool check_channel_prefix(uint           cardid,
     3350                          const QString &name,
     3351                          uint          &is_complete_valid_channel_on_rec,
     3352                          bool          &is_extra_char_useful,
     3353                          QString       &needed_spacer)
     3354{
     3355    static const uint kSpacerListSize = 5;
     3356    static const QString spacers[kSpacerListSize] = { "", "_", "-", "#", "." };
     3357
     3358    MSqlQuery query(MSqlQuery::InitCon());
     3359    QString basequery = QString(
     3360        "SELECT channel.chanid, channel.channum, cardinput.cardid "
     3361        "FROM channel, capturecard, cardinput "
     3362        "WHERE channel.channum LIKE '%1%%'               AND "
     3363        "      channel.sourceid     = cardinput.sourceid AND "
     3364        "      cardinput.cardid     = capturecard.cardid");
     3365
     3366    QString cardquery[2] =
    33313367    {
    3332         // Look for channel in line-up
    3333         bool unique = false;
    3334         bool ok = activerecorder->CheckChannelPrefix(chan, unique);
     3368        QString(" AND capturecard.cardid  = '%1'").arg(cardid),
     3369        QString(" AND capturecard.cardid != '%1'").arg(cardid),
     3370    };
    33353371
    3336         // If pure channel not in line-up, try adding a spacer
    3337         QString mod = chan;
    3338         for (uint i=0; (spacers[i] != NULL) && !ok; ++i)
     3372    vector<uint>    fchanid;
     3373    vector<QString> fchannum;
     3374    vector<uint>    fcardid;
     3375    vector<QString> fspacer;
     3376
     3377    for (uint i = 0; i < 2; i++)
     3378    {
     3379        for (uint j = 0; j < kSpacerListSize; j++)
    33393380        {
    3340             mod = chan.left(chan.length()-1) + spacers[i] + chan.right(1);
    3341             ok = activerecorder->CheckChannelPrefix(mod, unique);
     3381            QString qname = add_spacer(name, spacers[j]);
     3382            query.prepare(basequery.arg(qname) + cardquery[i]);
     3383
     3384            if (!query.exec() || !query.isActive())
     3385            {
     3386                MythContext::DBError("checkchannel -- locate channum", query);
     3387            }
     3388            else if (query.size())
     3389            {
     3390                while (query.next())
     3391                {
     3392                    fchanid.push_back(query.value(0).toUInt());
     3393                    fchannum.push_back(query.value(1).toString());
     3394                    fcardid.push_back(query.value(2).toUInt());
     3395                    fspacer.push_back(spacers[j]);
     3396#ifdef DEBUG_CHANNEL_PREFIX
     3397                    VERBOSE(VB_IMPORTANT, QString("(%1,%2) Adding %3 rec %4")
     3398                            .arg(i).arg(j).arg(query.value(1).toString(),6)
     3399                            .arg(query.value(2).toUInt()));
     3400#endif
     3401                }
     3402            }
     3403
     3404            if (name.length() < 2)
     3405                break;
    33423406        }
     3407    }
    33433408
    3344         // Use valid channel if it is there, otherwise reset...
     3409    // Now process the lists for the info we need...
     3410    is_extra_char_useful = false;
     3411    is_complete_valid_channel_on_rec = 0;
     3412    needed_spacer = "";
     3413
     3414    if (fchanid.size() == 1) // Unique channel...
     3415    {
     3416        needed_spacer = QDeepCopy<QString>(fspacer[0]);
     3417        bool nc       = (fchannum[0] != add_spacer(name, fspacer[0]));
     3418
     3419        is_complete_valid_channel_on_rec = (nc) ? 0 : fcardid[0];
     3420        is_extra_char_useful             = nc;
     3421    }
     3422    else if (fchanid.size() > 1)
     3423    {
     3424        // Is an extra characher useful for disambiguation?
     3425        for (uint i = 0; i < fchannum.size(); i++)
     3426        {
     3427            if (fchannum[i] != add_spacer(name, fspacer[0]))
     3428            {
     3429                is_extra_char_useful = true;
     3430                break;
     3431            }
     3432        }
     3433
     3434        // Are any of the channels complete w/o spacer?
     3435        // If so set is_complete_valid_channel_on_rec,
     3436        // with a preference for our cardid.
     3437        for (uint i = 0; i < fchannum.size(); i++)
     3438        {
     3439            if (fchannum[i] == add_spacer(name, fspacer[0]))
     3440            {
     3441                is_complete_valid_channel_on_rec = fcardid[i];
     3442                if (fcardid[i] == cardid)
     3443                    break;
     3444            }
     3445        }
     3446
     3447        // Add a spacer, if one is needed to select a valid channel.
     3448        if (!is_complete_valid_channel_on_rec)
     3449        {
     3450            bool spacer_needed = true;
     3451            for (uint i = 0; i < fspacer.size(); i++)
     3452            {
     3453                if (fspacer[i].isEmpty())
     3454                {
     3455                    spacer_needed = false;
     3456                    break;
     3457                }
     3458            }
     3459            if (spacer_needed)
     3460                needed_spacer = QDeepCopy<QString>(fspacer[0]);
     3461        }       
     3462    }
     3463
     3464    return fchanid.size() > 0;
     3465}
     3466
     3467bool TV::ProcessSmartChannel(QString &inputStr)
     3468{
     3469    QString chan = GetQueuedChanNum();
     3470
     3471    if (chan.isEmpty())
     3472        return false;
     3473
     3474    // Check for and remove duplicate separator characters
     3475    if ((chan.length() > 2) && (chan.right(1) == chan.right(2).left(1)) &&
     3476        !chan.right(1).toUInt())
     3477    {
     3478        chan = chan.left(chan.length()-1);
     3479
    33453480        QMutexLocker locker(&queuedInputLock);
    3346         queuedChanNum = QDeepCopy<QString>((ok) ? mod : chan.right(1));
    3347         do_smart &= unique;
     3481        queuedChanNum = QDeepCopy<QString>(chan);
    33483482    }
    33493483
    3350     QString inputStr = QString::null;
     3484    // Look for channel in line-up
     3485    QString needed_spacer;
     3486    uint    pref_cardid;
     3487    uint    cardid = activerecorder->GetRecorderNumber();
     3488    bool    is_not_complete;
     3489
     3490    bool valid_prefix = check_channel_prefix(
     3491        cardid, chan, pref_cardid, is_not_complete, needed_spacer);
     3492
     3493#ifdef DEBUG_CHANNEL_PREFIX
     3494    VERBOSE(VB_IMPORTANT, QString("valid_pref(%1) cardid(%2) chan(%3) "
     3495                                  "pref_cardid(%4) complete(%5) sp(%6)")
     3496            .arg(valid_prefix).arg(cardid).arg(chan)
     3497            .arg(pref_cardid).arg(is_not_complete).arg(needed_spacer));
     3498#endif
     3499
     3500    if (!valid_prefix)
    33513501    {
     3502        // not a valid prefix.. reset...
    33523503        QMutexLocker locker(&queuedInputLock);
    3353         inputStr = QDeepCopy<QString>
    3354             ((do_smart) ? queuedChanNum : queuedInput);
     3504        queuedChanNum = "";
    33553505    }
     3506    else if (!needed_spacer.isEmpty())
     3507    {
     3508        // need a spacer..
     3509        QMutexLocker locker(&queuedInputLock);
     3510        queuedChanNum = add_spacer(chan, needed_spacer);
     3511    }
    33563512
     3513#ifdef DEBUG_CHANNEL_PREFIX
     3514    VERBOSE(VB_IMPORTANT, QString(" ValidPref(%1) CardId(%2) Chan(%3) "
     3515                                  " PrefCardId(%4) Complete(%5) Sp(%6)")
     3516            .arg(valid_prefix).arg(cardid).arg(GetQueuedChanNum())
     3517            .arg(pref_cardid).arg(is_not_complete).arg(needed_spacer));
     3518#endif
     3519
     3520    QMutexLocker locker(&queuedInputLock);
     3521    inputStr = QDeepCopy<QString>(queuedChanNum);
     3522
     3523    return !is_not_complete;
     3524}
     3525
     3526void TV::AddKeyToInputQueue(char key)
     3527{
     3528    if (key)
     3529    {
     3530        QMutexLocker locker(&queuedInputLock);
     3531        queuedInput   = queuedInput.append(key).right(kInputKeysMax);
     3532        queuedChanNum = queuedChanNum.append(key).right(kInputKeysMax);
     3533    }
     3534
     3535    bool commit_smart = false;
     3536    QString inputStr = GetQueuedInput();
     3537
     3538    // Always use smartChannelChange when channel numbers are entered
     3539    // in browse mode because in browse mode space/enter exit browse
     3540    // mode and change to the currently browsed channel.
     3541    if (StateIsLiveTV(GetState()) && !ccInputMode && !asInputMode &&
     3542        (smartChannelChange || browsemode))
     3543    {
     3544        commit_smart = ProcessSmartChannel(inputStr);
     3545    }
     3546 
     3547    // Handle OSD...
    33573548    inputStr = inputStr.isEmpty() ? "?" : inputStr;
    33583549    if (ccInputMode)
    33593550    {
     
    33643555        inputStr = tr("Seek:", "seek to location") + " " + inputStr;
    33653556    UpdateOSDTextEntry(inputStr);
    33663557
    3367     if (do_smart)
     3558    // Commit the channel if it is complete and smart changing is enabled.
     3559    if (commit_smart)
    33683560        CommitQueuedInput();
    33693561}
    33703562
     
    34143606            if (activenvp == nvp && GetOSD())
    34153607                GetOSD()->HideSet("channel_number");
    34163608        }
    3417         else if (GetQueuedChanID() ||
    3418                  (!channum.isEmpty() && activerecorder->CheckChannel(channum)))
     3609        else if (GetQueuedChanID() || !channum.isEmpty())
    34193610            ChangeChannel(GetQueuedChanID(), channum);
    3420         else if (!chaninput.isEmpty())
    3421             ChangeChannel(GetQueuedChanID(), chaninput);
    34223611    }
    34233612
    34243613    ClearInputQueues(true);
    34253614}
    34263615
    3427 void TV::ChangeChannel(uint chanid, const QString &channum)
     3616void TV::ChangeChannel(uint chanid, const QString &chan)
    34283617{
     3618    QString channum = chan;
    34293619    VERBOSE(VB_PLAYBACK, LOC + QString("ChangeChannel(%1, '%2') ")
    34303620            .arg(chanid).arg(channum));
    34313621
     3622    if (!chanid && channum.isEmpty())
     3623        return;
     3624
    34323625    QStringList reclist;
    34333626    bool muted = false;
    34343627
    34353628    if (activerecorder)
    34363629    {
    3437         bool getit = false, unique = false;
     3630        bool getit = false;
     3631
    34383632        if (chanid)
     3633        {
    34393634            getit = activerecorder->ShouldSwitchToAnotherCard(
    34403635                QString::number(chanid));
     3636        }
    34413637        else
    3442             getit = !activerecorder->CheckChannelPrefix(channum, unique);
     3638        {
     3639            QString needed_spacer;
     3640            uint pref_cardid, cardid = activerecorder->GetRecorderNumber();
     3641            bool dummy;
    34433642
     3643            check_channel_prefix(cardid, channum, pref_cardid,
     3644                                 dummy, needed_spacer);
     3645
     3646            channum = add_spacer(channum, needed_spacer);
     3647            getit = (pref_cardid != cardid);
     3648        }
     3649
    34443650        if (getit)
    34453651            reclist = GetValidRecorderList(chanid, channum);
    34463652    }
  • libs/libmythtv/remoteencoder.h

     
    5050    int SetSignalMonitoringRate(int msec, bool notifyFrontend = true);
    5151    bool CheckChannel(QString channel);
    5252    bool ShouldSwitchToAnotherCard(QString channelid);
    53     bool CheckChannelPrefix(QString channel, bool &unique);
     53    bool CheckChannelPrefix(QString channel, bool &unique, bool &other_rec);
    5454    void GetNextProgram(int direction,
    5555                        QString &title, QString &subtitle, QString &desc,
    5656                        QString &category, QString &starttime, QString &endtime,
  • libs/libmythtv/tv_play.h

     
    216216    void AddKeyToInputQueue(char key);
    217217    void ClearInputQueues(bool hideosd = false);
    218218    void CommitQueuedInput(void);
     219    bool ProcessSmartChannel(QString&);
    219220
    220221    // query key queues
    221222    bool HasQueuedInput(void) const
  • libs/libmythtv/remoteencoder.cpp

     
    503503    return retval;
    504504}
    505505
    506 bool RemoteEncoder::CheckChannelPrefix(QString channel, bool &unique)
     506bool RemoteEncoder::CheckChannelPrefix(
     507    QString channel, bool &unique, bool &other_rec)
    507508{
    508509    QStringList strlist = QString("QUERY_RECORDER %1").arg(recordernum);
    509510    strlist << "CHECK_CHANNEL_PREFIX";
     
    512513    SendReceiveStringList(strlist);
    513514
    514515    bool retval = strlist[0].toInt();
    515     unique = strlist[1].toInt();
     516    unique      = strlist[1].toInt();
     517    other_rec   = strlist[2].toInt();
    516518
    517519    return retval;
    518520}
  • libs/libmythtv/tv_rec.cpp

     
    19791979    return ret;
    19801980}
    19811981
    1982 /** \fn TVRec::CheckChannelPrefix(QString name, bool &unique)
     1982/** \fn TVRec::CheckChannelPrefix(QString, bool&, bool&)
    19831983 *  \brief Returns true if the numbers in prefix_num match the first digits
    19841984 *         of any channel, if it unquely identifies a channel the unique
    19851985 *         parameter is set.
     
    19951995 *  \param prefix_num Channel number prefix to check
    19961996 *  \param unique     This is set to true if prefix uniquely identifies
    19971997 *                    channel, false otherwise.
     1998 *  \param other_rec  This channel is on another recorder
    19981999 *  \return true if the prefix matches any channels.
    19992000 *
    20002001 */
    2001 bool TVRec::CheckChannelPrefix(QString name, bool &unique)
     2002bool TVRec::CheckChannelPrefix(QString name, bool &unique, bool &other_rec)
    20022003{
    20032004    if (!channel)
    20042005        return false;
    20052006
    20062007    bool ret = false;
    20072008    unique = false;
     2009    other_rec = false;
    20082010
    20092011    QString channelinput = channel->GetCurrentInput();
    20102012
     
    20132015    if (!query.isConnected())
    20142016        return true;
    20152017
    2016     QString querystr = QString(
    2017         "SELECT channel.chanid "
     2018    QString basequery = QString(
     2019        "SELECT channel.chanid, channel.channum "
    20182020        "FROM channel, capturecard, cardinput "
    20192021        "WHERE channel.channum LIKE '%1%%'               AND "
    20202022        "      channel.sourceid     = cardinput.sourceid AND "
    2021         "      cardinput.cardid     = capturecard.cardid AND "
    2022         "      capturecard.cardid   = '%2'               AND "
    2023         "      capturecard.hostname = '%3'")
    2024         .arg(name)
    2025         .arg(cardid)
    2026         .arg(gContext->GetHostName());
     2023        "      cardinput.cardid     = capturecard.cardid").arg(name);
    20272024
    2028     query.prepare(querystr);
     2025    QString cardquery = QString(" AND capturecard.cardid = '%2'").arg(cardid);
    20292026
     2027    // Check for any input on this card..
     2028    VERBOSE(VB_IMPORTANT, "QUERY: "<<basequery + cardquery);
     2029    query.prepare(basequery + cardquery);
     2030
    20302031    if (!query.exec() || !query.isActive())
    20312032    {
    20322033        MythContext::DBError("checkchannel", query);
    20332034    }
    2034     else if (query.size() > 0)
     2035    else if (query.size() && query.next())
    20352036    {
    2036         if (query.size() == 1)
     2037        unique = ((query.size() == 1) &&
     2038                  (query.value(1).toString() == name));
     2039        return true;
     2040    }
     2041    else
     2042    {
     2043        // Check any card..
     2044        VERBOSE(VB_IMPORTANT, "QUERY2: "<<basequery);
     2045        query.prepare(basequery);
     2046        if (!query.exec() || !query.isActive())
     2047            MythContext::DBError("checkchannel -- any rec", query);
     2048        else if (query.size() && query.next())
    20372049        {
    2038             unique = CheckChannel(name);
     2050            unique = ((query.size() == 1) &&
     2051                      (query.value(1).toString() == name));
     2052            VERBOSE(VB_IMPORTANT, "val(1): '"<<query.value(1).toString()
     2053                    <<"'  name: '"<<name<<"'");
     2054            other_rec = true;
     2055            return true;
    20392056        }
    2040         return true;
    20412057    }
    20422058
     2059    // No idea what this is for -- dtk 1/2006
    20432060    query.prepare("SELECT NULL FROM channel");
    20442061    query.exec();
    20452062
    20462063    if (query.size() == 0)
    20472064    {
     2065        VERBOSE(VB_IMPORTANT, "null query returned nothing");
    20482066        unique = true;
    20492067        ret = true;
    20502068    }
  • libs/libmythtv/tv_rec.h

     
    200200    int ChangeHue(bool direction);
    201201    bool CheckChannel(QString name);
    202202    bool ShouldSwitchToAnotherCard(QString chanid);
    203     bool CheckChannelPrefix(QString name, bool &unique);
     203    bool CheckChannelPrefix(QString name, bool &unique, bool &other_rec);
    204204    void GetNextProgram(int direction,
    205205                        QString &title,       QString &subtitle,
    206206                        QString &desc,        QString &category,
  • programs/mythbackend/encoderlink.h

     
    8585    int ChangeHue(bool direction);
    8686    bool CheckChannel(const QString &name);
    8787    bool ShouldSwitchToAnotherCard(const QString &channelid);
    88     bool CheckChannelPrefix(const QString &name, bool &unique);
     88    bool CheckChannelPrefix(const QString &name, bool &unique, bool &other);
    8989    void GetNextProgram(int direction,
    9090                        QString &title, QString &subtitle, QString &desc,
    9191                        QString &category, QString &starttime,
  • programs/mythbackend/mainserver.cpp

     
    25352535    }
    25362536    else if (command == "CHECK_CHANNEL_PREFIX")
    25372537    {
    2538         bool unique;
     2538        bool unique, other_rec;
    25392539        QString name = slist[2];
    2540         retlist << QString::number((int)(enc->CheckChannelPrefix(name,
    2541                                                                  unique)));
     2540        bool match = enc->CheckChannelPrefix(name, unique, other_rec);
     2541        retlist << QString::number((int)match);
    25422542        retlist << QString::number((int)unique);
     2543        retlist << QString::number((int)other_rec);
    25432544    }
    25442545    else if (command == "GET_NEXT_PROGRAM_INFO")
    25452546    {
  • programs/mythbackend/encoderlink.cpp

     
    814814    return false;
    815815}
    816816
    817 /** \fn EncoderLink::CheckChannelPrefix(const QString&,bool&)
     817/** \fn EncoderLink::CheckChannelPrefix(const QString&,bool&,bool&)
    818818 *  \brief Returns true if the numbers in prefix_num match the first digits
    819819 *         of any channel, if it unquely identifies a channel the unique
    820820 *         parameter is set.
     
    823823 *  \param prefix_num Channel number prefix to check
    824824 *  \param unique     This is set to true if prefix uniquely identifies
    825825 *                    channel, false otherwise.
     826 *  \param other_rec  This channel is on another recorder
    826827 *  \return true if the prefix matches any channels.
    827828 */
    828 bool EncoderLink::CheckChannelPrefix(const QString &prefix_num, bool &unique)
     829bool EncoderLink::CheckChannelPrefix(const QString &prefix_num,
     830                                     bool &unique, bool &other_rec)
    829831{
    830832    if (local)
    831         return tv->CheckChannelPrefix(prefix_num, unique);
     833        return tv->CheckChannelPrefix(prefix_num, unique, other_rec);
    832834
    833835    VERBOSE(VB_IMPORTANT, "Should be local only query: CheckChannelPrefix");
    834836    unique = false;