Ticket #199: channelgroup.3.diff

File channelgroup.3.diff, 52.7 KB (added by wstewart@…, 15 years ago)

updated for trunk, see comment. Will not work with 0.21-fixes.

  • libs/libmythtv/channelgroup.cpp

    diff -Naurp -x '*.orig' mythtv-orig/libs/libmythtv/channelgroup.cpp mythtv/libs/libmythtv/channelgroup.cpp
    old new  
     1#include "mythcontext.h"
     2#include "libmythdb/mythdbcon.h"
     3#include <qsqldatabase.h>
     4#include <qcursor.h>
     5#include <qlayout.h>
     6#include <iostream>
     7#include "mythstorage.h"
     8#include "mythdb.h"
     9#include "channelutil.h"
     10#include "channelgroup.h"
     11
     12#define LOC QString("Channel Group: ")
     13#define LOC_ERR QString("Channel Group, Error: ")
     14
     15ChannelGroupItem& ChannelGroupItem::operator=(const ChannelGroupItem &other)
     16{
     17    grpid     = other.grpid;
     18    name      = (other.name);
     19 
     20    return *this;
     21}
     22
     23ChannelGroupItem::ChannelGroupItem(const ChannelGroupItem &other)
     24{
     25    (*this) = other;
     26}
     27
     28inline bool lt_group(const ChannelGroupItem &a, const ChannelGroupItem &b)
     29{
     30    return QString::localeAwareCompare(a.name, b.name) < 0;
     31}
     32
     33bool ChannelGroup::ToggleChannel(uint chanid,int changrpid, int delete_chan)
     34{
     35    // Check if it already exists for that chanid...
     36    MSqlQuery query(MSqlQuery::InitCon());
     37    query.prepare(
     38        "SELECT channelgroup.id "
     39        "FROM channelgroup "
     40        "WHERE channelgroup.chanid = :CHANID AND "
     41        "channelgroup.grpid = :GRPID "
     42        "LIMIT 1");
     43    query.bindValue(":CHANID", chanid);
     44    query.bindValue(":GRPID", changrpid);
     45
     46    if (!query.exec() || !query.isActive())
     47    {
     48        MythDB::DBError("ChannelGroup::ToggleChannel", query);
     49        return false;
     50    }
     51    else if ((query.size() > 0) && delete_chan)
     52    {
     53        // We have a record...Remove it to toggle...
     54        query.next();
     55        QString id = query.value(0).toString();
     56        query.prepare(
     57            QString("DELETE FROM channelgroup "
     58                    "WHERE id = '%1'").arg(id));
     59        query.exec();
     60        VERBOSE(VB_IMPORTANT, LOC + QString("Removing channel with id=%1.").arg(id));
     61    }
     62    else if (query.size() == 0)
     63    {
     64        // We have no record...Add one to toggle...
     65        query.prepare(
     66            QString("INSERT INTO channelgroup (chanid,grpid) "
     67                    "VALUES ('%1','%2')").arg(chanid).arg(changrpid));
     68        query.exec();
     69        VERBOSE(VB_IMPORTANT, LOC + QString("Adding channel %1 to group %2.").arg(chanid).arg(changrpid));
     70    }
     71
     72    return true;
     73}
     74
     75ChannelGroupList ChannelGroup::GetChannelGroups(void)
     76{
     77    ChannelGroupList list;
     78   
     79    MSqlQuery query(MSqlQuery::InitCon());
     80   
     81    QString qstr = "SELECT grpid, name FROM channelgroupnames";
     82   
     83    query.prepare(qstr);
     84
     85    if (!query.exec() || !query.isActive())
     86        MythDB::DBError("ChannelGroup::GetChannelGroups", query);
     87    else
     88    {
     89        while (query.next())
     90        {
     91           ChannelGroupItem group(query.value(0).toUInt(),
     92                              query.value(1).toString());
     93           list.push_back(group);
     94        }
     95    }
     96   
     97    stable_sort(list.begin(), list.end(), lt_group);
     98
     99    return list;
     100}
     101
     102// Cycle through the available groups, then all channels
     103// Will cycle through to end then return -1
     104// To signify all channels.
     105int ChannelGroup::GetNextChannelGroup(const ChannelGroupList &sorted, int grpid)
     106{
     107    // If no groups return -1 for all channels
     108    if (sorted.empty())
     109      return -1;
     110   
     111    // If grpid is all channels (-1), then return the first grpid 
     112    if (grpid == -1)
     113      return sorted[0].grpid;
     114     
     115    ChannelGroupList::const_iterator it = find(sorted.begin(), sorted.end(), grpid);
     116
     117    // If grpid is not in the list, return -1 for all channels
     118    if (it == sorted.end())
     119        return -1;
     120
     121    ++it;
     122
     123    // If we reached the end, the next option is all channels (-1)
     124    if (it == sorted.end())
     125       return -1;
     126
     127    return it->grpid;
     128}
     129
     130QString ChannelGroup::GetChannelGroupName(const ChannelGroupList &sorted, int grpid)
     131{
     132    // All Channels
     133    if (grpid == -1)
     134      return "All Channels";
     135
     136    ChannelGroupList::const_iterator it = find(sorted.begin(), sorted.end(), grpid);
     137       
     138    // If grpid wasn't found, return blank.   
     139    if (it == sorted.end())
     140       return "";
     141    else
     142       return it->name;
     143}
  • libs/libmythtv/channelgroup.h

    diff -Naurp -x '*.orig' mythtv-orig/libs/libmythtv/channelgroup.h mythtv/libs/libmythtv/channelgroup.h
    old new  
     1#ifndef CHANNELGROUP_H
     2#define CHANNELGROUP_H
     3
     4class ChannelGroupItem
     5{
     6  public:
     7    ChannelGroupItem(const ChannelGroupItem&);
     8    ChannelGroupItem(const uint _grpid,
     9                  const QString &_name) :
     10        grpid(_grpid), name(_name) {}
     11
     12    bool operator == (uint _grpid) const
     13        { return grpid == _grpid; }
     14
     15    ChannelGroupItem& operator=(const ChannelGroupItem&);
     16
     17  public:
     18    uint    grpid;
     19    QString name;
     20};
     21typedef vector<ChannelGroupItem> ChannelGroupList;
     22
     23/** \class ChannelGroup
     24*/
     25class MPUBLIC ChannelGroup
     26{
     27  public:
     28    // ChannelGroup
     29    static ChannelGroupList  GetChannelGroups(void);
     30    static bool              ToggleChannel(uint chanid,int changrpid, int delete_chan);
     31    static int               GetNextChannelGroup(const ChannelGroupList &sorted, int grpid);
     32    static QString           GetChannelGroupName(const ChannelGroupList &sorted, int grpid);
     33
     34   
     35  private:
     36
     37};
     38
     39#endif
  • libs/libmythtv/channelgroupsettings.cpp

    diff -Naurp -x '*.orig' mythtv-orig/libs/libmythtv/channelgroupsettings.cpp mythtv/libs/libmythtv/channelgroupsettings.cpp
    old new  
     1#include "mythcontext.h"
     2#include "libmythdb/mythdbcon.h"
     3#include <qsqldatabase.h>
     4#include <qcursor.h>
     5#include <qlayout.h>
     6#include <iostream>
     7#include "mythstorage.h"
     8#include "mythdb.h"
     9#include "channelutil.h"
     10#include "channelgroup.h"
     11#include "channelgroupsettings.h"
     12
     13#define LOC QString("Channel Group Settings: ")
     14#define LOC_ERR QString("Channel Group Settings, Error: ")
     15
     16// Storage class for channel group editor in settings
     17class ChannelGroupStorage : public Storage
     18{
     19  public:
     20    ChannelGroupStorage(Setting *_setting,
     21                    uint _chanid, QString _grpname) :
     22        setting(_setting), chanid(_chanid), grpname(_grpname) {}
     23    virtual ~ChannelGroupStorage() {};
     24
     25    virtual void Load(void);
     26    virtual void Save(void);
     27    virtual void Save(QString destination);
     28
     29  protected:
     30    Setting *setting;
     31    uint    chanid;
     32    QString grpname;
     33    int     grpid;
     34};
     35
     36void ChannelGroupStorage::Load(void)
     37{
     38    setting->setValue("0");
     39    setting->setUnchanged();
     40   
     41    MSqlQuery query(MSqlQuery::InitCon());
     42   
     43    QString qstr = "SELECT grpid FROM channelgroupnames WHERE name = :GRPNAME";
     44   
     45    query.prepare(qstr);
     46    query.bindValue(":GRPNAME", grpname);
     47
     48    if (!query.exec() || !query.isActive())
     49        MythDB::DBError("ChannelGroupStorage::Load", query);
     50    else
     51    {
     52      query.next();
     53      grpid = query.value(0).toUInt();
     54   
     55      qstr = "SELECT * FROM channelgroup WHERE grpid = :GRPID AND chanid = :CHANID";
     56      query.prepare(qstr);
     57      query.bindValue(":GRPID",  grpid);
     58      query.bindValue(":CHANID", chanid);
     59
     60      if (!query.exec() || !query.isActive())
     61          MythDB::DBError("ChannelGroupStorage::Load", query);
     62      else if (query.size() > 0)
     63        setting->setValue("1");
     64    }
     65}
     66
     67void ChannelGroupStorage::Save(void)
     68{
     69    if (!setting->isChanged())
     70      return;
     71   
     72    QString value = setting->getValue();
     73   
     74    if (value == "1")
     75        ChannelGroup::ToggleChannel(chanid, grpid, false);
     76    else
     77        ChannelGroup::ToggleChannel(chanid, grpid, true);   
     78}
     79
     80void ChannelGroupStorage::Save(QString destination)
     81{
     82    Save();
     83}
     84
     85class ChannelCheckBox : public CheckBoxSetting, public ChannelGroupStorage
     86{
     87  public:
     88    ChannelCheckBox(const ChannelGroupConfig& _parent, const uint chanid, const QString channum,
     89               const QString channame, const QString grpname):
     90        CheckBoxSetting(this),
     91        ChannelGroupStorage(this, chanid, grpname)
     92    {
     93        setLabel(QString("%1 %2").arg(channum).arg(channame));
     94        setHelpText(QObject::tr("Select/Unselect channels for this channel group"));
     95    };
     96};
     97
     98ChannelGroupConfig::ChannelGroupConfig(QString _name)
     99    : name(_name)
     100{
     101    VerticalConfigurationGroup   *cgroup;
     102    HorizontalConfigurationGroup *columns;
     103
     104    DBChanList chanlist = ChannelUtil::GetChannels(0, true, "channum, callsign");
     105    ChannelUtil::SortChannels(chanlist, "channum", true);
     106
     107    DBChanList::iterator it = chanlist.begin();
     108    int i,j = 0;
     109    int p = 1;
     110    int pages = (int)((float)chanlist.size() / 8.0 / 3.0 + 0.5);
     111   
     112    do
     113    { 
     114        columns = new HorizontalConfigurationGroup(false,false,false,false);
     115        columns->setLabel(getName() + " " +
     116                          QObject::tr("Channel Group - Page ") + QString("%1").arg(p) +
     117                          QObject::tr("of") + QString("%1").arg(pages));
     118       
     119        for (j = 0; ((j < 3) && (it < chanlist.end())); ++j)
     120        {
     121            cgroup = new VerticalConfigurationGroup(false,false,false,false);
     122           
     123            for (i = 0; ((i < 8) && (it < chanlist.end())); ++i)
     124            {
     125                cgroup->addChild(new ChannelCheckBox(*this, it->chanid, it->channum, it->name, _name));
     126                ++it;
     127            }
     128            columns->addChild(cgroup);
     129        }
     130       
     131        ++p;
     132        addChild(columns);
     133    } while (it < chanlist.end());
     134
     135}
     136
     137ChannelGroupEditor::ChannelGroupEditor(void) :
     138    listbox(new ListBoxSetting(this)), lastValue("__CREATE_NEW_GROUP__")
     139{
     140    listbox->setLabel(tr("Channel Groups"));
     141    addChild(listbox);
     142}
     143
     144void ChannelGroupEditor::open(QString name)
     145{
     146    lastValue = name;
     147    bool created = false;
     148
     149    if (name == "__CREATE_NEW_GROUP__")
     150    {
     151        name = "";
     152       
     153        bool ok = MythPopupBox::showGetTextPopup(gContext->GetMainWindow(),
     154            tr("Create New Channel Group"),
     155            tr("Enter group name or press SELECT to enter text via the "
     156               "On Screen Keyboard"), name);
     157        if (!ok)
     158            return;
     159
     160        MSqlQuery query(MSqlQuery::InitCon());
     161        query.prepare("INSERT INTO channelgroupnames (name) VALUES (:NAME);");
     162        query.bindValue(":NAME", name);
     163        if (!query.exec())
     164            MythDB::DBError("ChannelGroupEditor::open", query);
     165        else
     166            created = true;
     167    }
     168   
     169    ChannelGroupConfig group(name);
     170   
     171    if (group.exec() == QDialog::Accepted || !created)
     172        lastValue = name;
     173
     174};
     175
     176void ChannelGroupEditor::doDelete(void)
     177{
     178    QString name = listbox->getValue();
     179    if (name == "__CREATE_NEW_GROUP__")
     180        return;
     181
     182    QString message = tr("Delete '%1' Channel group?").arg(name);
     183   
     184    DialogCode value = MythPopupBox::Show2ButtonPopup(
     185        gContext->GetMainWindow(),
     186        "", message,
     187        tr("Yes, delete group"),
     188        tr("No, Don't delete group"), kDialogCodeButton1);
     189
     190    if (kDialogCodeButton0 == value)
     191    {
     192        MSqlQuery query(MSqlQuery::InitCon());
     193
     194        // Find out channel group id
     195        query.prepare("SELECT grpid FROM channelgroupnames WHERE name = :NAME;");
     196        query.bindValue(":NAME", name);
     197        if (!query.exec())
     198            MythDB::DBError("ChannelGroupEditor::doDelete", query);
     199        query.next();
     200        uint grpid = query.value(0).toUInt();
     201
     202        // Delete channels from this group
     203        query.prepare("DELETE FROM channelgroup WHERE grpid = :GRPID;");
     204        query.bindValue(":GRPID", grpid);
     205        if (!query.exec())
     206            MythDB::DBError("ChannelGroupEditor::doDelete", query);
     207       
     208        // Now delete the group from channelgroupnames
     209        query.prepare("DELETE FROM channelgroupnames WHERE name = :NAME;");
     210        query.bindValue(":NAME", name);
     211        if (!query.exec())
     212            MythDB::DBError("ChannelGroupEditor::doDelete", query);
     213
     214        lastValue = "__CREATE_NEW_GROUP__";
     215        Load();
     216    }
     217
     218    listbox->setFocus();
     219}
     220
     221void ChannelGroupEditor::Load(void)
     222{
     223    listbox->clearSelections();
     224   
     225    ChannelGroupList changrplist;
     226
     227    changrplist = ChannelGroup::GetChannelGroups();
     228
     229    ChannelGroupList::iterator it;
     230
     231    for (it = changrplist.begin(); it < changrplist.end(); ++it)
     232       listbox->addSelection(it->name);
     233       
     234    listbox->addSelection(tr("(Create new group)"), "__CREATE_NEW_GROUP__");
     235
     236    listbox->setValue(lastValue);
     237}
     238
     239DialogCode ChannelGroupEditor::exec(void)
     240{
     241    while (ConfigurationDialog::exec() == kDialogCodeAccepted)
     242        open(listbox->getValue());
     243
     244    return kDialogCodeRejected;
     245}
     246
     247MythDialog* ChannelGroupEditor::dialogWidget(MythMainWindow* parent,
     248                                          const char* widgetName)
     249{
     250    dialog = ConfigurationDialog::dialogWidget(parent, widgetName);
     251    connect(dialog, SIGNAL(menuButtonPressed()), this, SLOT(doDelete()));
     252    connect(dialog, SIGNAL(deleteButtonPressed()), this, SLOT(doDelete()));
     253    return dialog;
     254}
  • libs/libmythtv/channelgroupsettings.h

    diff -Naurp -x '*.orig' mythtv-orig/libs/libmythtv/channelgroupsettings.h mythtv/libs/libmythtv/channelgroupsettings.h
    old new  
     1#ifndef CHANNELGROUPSETTINGS_H
     2#define CHANNELGROUPSETTINGS_H
     3
     4#include "libmyth/settings.h"
     5
     6class MPUBLIC ChannelGroupConfig: public ConfigurationWizard
     7{
     8 public:
     9    ChannelGroupConfig(QString _name);
     10    QString getName(void) const { return name; }
     11
     12 private:
     13    QString name;
     14};
     15
     16class MPUBLIC ChannelGroupEditor : public QObject, public ConfigurationDialog
     17{
     18    Q_OBJECT
     19
     20  public:
     21    ChannelGroupEditor(void);
     22    virtual DialogCode exec(void);
     23    virtual void Load(void);
     24    virtual void Save(void) { };
     25    virtual void Save(QString) { };
     26    virtual MythDialog* dialogWidget(MythMainWindow* parent,
     27                                     const char* widgetName=0);
     28
     29  protected slots:
     30    void open(QString name);
     31    void doDelete(void);
     32
     33  protected:
     34    ListBoxSetting *listbox;
     35    QString         lastValue;
     36};
     37
     38#endif
  • libs/libmythtv/channelutil.cpp

    diff -Naurp -x '*.orig' mythtv-orig/libs/libmythtv/channelutil.cpp mythtv/libs/libmythtv/channelutil.cpp
    old new bool ChannelUtil::GetChannelSettings(int 
    15701570    return true;
    15711571}
    15721572
    1573 DBChanList ChannelUtil::GetChannels(uint sourceid, bool vis_only, QString grp)
     1573DBChanList ChannelUtil::GetChannels(uint sourceid, bool vis_only, QString grp, int changrpid)
    15741574{
    15751575    DBChanList list;
    1576     QMap<uint,uint> favorites;
     1576   
    15771577    MSqlQuery query(MSqlQuery::InitCon());
    1578     query.prepare(
    1579         "SELECT chanid, favid "
    1580         "FROM favorites");
    1581     if (!query.exec() || !query.isActive())
    1582         MythDB::DBError("get channels -- favorites", query);
    1583     else
    1584     {
    1585         while (query.next())
    1586             favorites[query.value(0).toUInt()] = query.value(1).toUInt();
    1587     }
    15881578
    15891579    QString qstr =
    1590         "SELECT channum, callsign, chanid, "
     1580        "SELECT channum, callsign, channel.chanid, "
    15911581        "       atsc_major_chan, atsc_minor_chan, "
    15921582        "       name, icon, mplexid, visible "
    15931583        "FROM channel ";
    15941584
     1585    // Select only channels from the specified channel group
     1586    if (changrpid > -1)
     1587        qstr += QString(",channelgroup ");
     1588
    15951589    if (sourceid)
    15961590        qstr += QString("WHERE sourceid='%1' ").arg(sourceid);
    15971591    else
    DBChanList ChannelUtil::GetChannels(uint 
    15991593            "WHERE cardinput.sourceid = channel.sourceid   AND "
    16001594            "      cardinput.cardid   = capturecard.cardid     ";
    16011595
     1596    if (changrpid > -1)
     1597    {
     1598        qstr += QString("AND channel.chanid = channelgroup.chanid "
     1599                        "AND channelgroup.grpid ='%1' ").arg(changrpid);
     1600    }
     1601
    16021602    if (vis_only)
    16031603        qstr += "AND visible=1 ";
    16041604
    DBChanList ChannelUtil::GetChannels(uint 
    16231623            query.value(2).toUInt(),                      /* chanid     */
    16241624            query.value(3).toUInt(),                      /* ATSC major */
    16251625            query.value(4).toUInt(),                      /* ATSC minor */
    1626             favorites[query.value(2).toUInt()],           /* favid      */
    16271626            query.value(7).toUInt(),                      /* mplexid    */
    16281627            query.value(8).toBool(),                      /* visible    */
    16291628            query.value(5).toString(),                    /* name       */
    uint ChannelUtil::GetNextChannel( 
    18061805                (mplexid_restriction &&
    18071806                 (mplexid_restriction != it->mplexid))));
    18081807    }
    1809     else if (CHANNEL_DIRECTION_UP == direction)
     1808    else if ((CHANNEL_DIRECTION_UP == direction) || (CHANNEL_DIRECTION_FAVORITE == direction))
    18101809    {
    18111810        do
    18121811        {
    uint ChannelUtil::GetNextChannel( 
    18191818                (mplexid_restriction &&
    18201819                 (mplexid_restriction != it->mplexid))));
    18211820    }
    1822     else if (CHANNEL_DIRECTION_FAVORITE == direction)
    1823     {
    1824         do
    1825         {
    1826             it++;
    1827             if (it == sorted.end())
    1828                 it = sorted.begin();
    1829         }
    1830         while ((it != start) &&
    1831                (!it->favorite ||
    1832                 (skip_non_visible && !it->visible) ||
    1833                 (mplexid_restriction &&
    1834                  (mplexid_restriction != it->mplexid))));
    1835     }
    18361821
    18371822    return it->chanid;
    18381823}
  • libs/libmythtv/channelutil.h

    diff -Naurp -x '*.orig' mythtv-orig/libs/libmythtv/channelutil.h mythtv/libs/libmythtv/channelutil.h
    old new class MPUBLIC ChannelUtil 
    168168    static QString GetVideoFilters(uint sourceid, const QString &channum)
    169169        { return GetChannelValueStr("videofilters", sourceid, channum); }
    170170
    171     static DBChanList GetChannels(uint srcid, bool vis_only, QString grp="");
     171    static DBChanList GetChannels(uint srcid, bool vis_only, QString grp="", int changrpid=-1);
    172172    static void    SortChannels(DBChanList &list, const QString &order,
    173173                                bool eliminate_duplicates = false);
    174174    static void    EliminateDuplicateChanNum(DBChanList &list);
  • libs/libmythtv/dbchannelinfo.cpp

    diff -Naurp -x '*.orig' mythtv-orig/libs/libmythtv/dbchannelinfo.cpp mythtv/libs/libmythtv/dbchannelinfo.cpp
    old new DBChannel::DBChannel(const DBChannel &ot 
    1616DBChannel::DBChannel(
    1717    const QString &_channum, const QString &_callsign,
    1818    uint _chanid, uint _major_chan, uint _minor_chan,
    19     uint _favorite, uint _mplexid, bool _visible,
     19    uint _mplexid, bool _visible,
    2020    const QString &_name, const QString &_icon) :
    2121    channum(_channum),
    2222    callsign(_callsign), chanid(_chanid),
    2323    major_chan(_major_chan), minor_chan(_minor_chan),
    24     favorite(_favorite), mplexid(_mplexid), visible(_visible),
     24    mplexid(_mplexid), visible(_visible),
    2525    name(_name), icon(_icon)
    2626{
    2727    channum.detach();
    DBChannel &DBChannel::operator=(const DB 
    3939    chanid     = other.chanid;
    4040    major_chan = other.major_chan;
    4141    minor_chan = other.minor_chan;
    42     favorite   = other.favorite;
    4342    mplexid    = (other.mplexid == 32767) ? 0 : other.mplexid;
    4443    visible    = other.visible;
    4544    name       = other.name; name.detach();
  • libs/libmythtv/dbchannelinfo.h

    diff -Naurp -x '*.orig' mythtv-orig/libs/libmythtv/dbchannelinfo.h mythtv/libs/libmythtv/dbchannelinfo.h
    old new class MPUBLIC DBChannel 
    2121    DBChannel(const DBChannel&);
    2222    DBChannel(const QString &_channum, const QString &_callsign,
    2323              uint _chanid, uint _major_chan, uint _minor_chan,
    24               uint _favorite, uint _mplexid, bool _visible,
     24              uint _mplexid, bool _visible,
    2525              const QString &_name, const QString &_icon);
    2626    DBChannel& operator=(const DBChannel&);
    2727
    class MPUBLIC DBChannel 
    3434    uint    chanid;
    3535    uint    major_chan;
    3636    uint    minor_chan;
    37     uint    favorite;
    3837    uint    mplexid;
    3938    bool    visible;
    4039    QString name;
  • libs/libmythtv/guidegrid.cpp

    diff -Naurp -x '*.orig' mythtv-orig/libs/libmythtv/guidegrid.cpp mythtv/libs/libmythtv/guidegrid.cpp
    old new using namespace std; 
    2121#include "libmyth/mythcontext.h"
    2222#include "libmythdb/mythdbcon.h"
    2323#include "libmythdb/mythverbose.h"
    24 #include "guidegrid.h"
    2524#include "infostructs.h"
    2625#include "programinfo.h"
    2726#include "scheduledrecording.h"
    using namespace std; 
    3433#include "util.h"
    3534#include "remoteutil.h"
    3635#include "channelutil.h"
     36#include "guidegrid.h"
    3737#include "cardutil.h"
    3838
    3939#define LOC      QString("GuideGrid: ")
    DBChanList GuideGrid::Run( 
    161161    const QString &channum,
    162162    bool           thread,
    163163    TV            *player,
    164     bool           allowsecondaryepg)
     164    bool           allowsecondaryepg,
     165    int           *changrpid)
    165166{
    166167    DBChanList channel_changed;
     168    int        channel_group  = -1;
     169
     170    if (changrpid != NULL)
     171      channel_group = *changrpid;
    167172
    168173    //if (thread)
    169174    //    qApp->lock();
    DBChanList GuideGrid::Run( 
    172177
    173178    GuideGrid *gg = new GuideGrid(gContext->GetMainWindow(),
    174179                                  chanid, channum,
    175                                   player, allowsecondaryepg, "guidegrid");
     180                                  player, allowsecondaryepg, "guidegrid",
     181                                  channel_group);
    176182
    177183    gg->Show();
    178184
    DBChanList GuideGrid::Run( 
    199205    //if (thread)
    200206    //    qApp->lock();
    201207
     208    if (changrpid != NULL)
     209      *changrpid = gg->GetChanGrp();
     210
    202211    delete gg;
    203212
    204213    gContext->removeCurrentLocation();
    DBChanList GuideGrid::Run( 
    212221GuideGrid::GuideGrid(MythMainWindow *parent,
    213222                     uint chanid, QString channum,
    214223                     TV *player, bool allowsecondaryepg,
    215                      const char *name) :
     224                     const char *name, int changrpid) :
    216225    MythDialog(parent, name),
    217226    jumpToChannelLock(QMutex::Recursive),
    218227    jumpToChannel(NULL),
    GuideGrid::GuideGrid(MythMainWindow *par 
    223232    DISPLAY_TIMES = 30;
    224233    int maxchannel = 0;
    225234    m_currentStartChannel = 0;
     235    m_changrpid = changrpid;
     236    m_changrplist = ChannelGroup::GetChannelGroups();
    226237
    227238    m_player = player;
    228239
    GuideGrid::GuideGrid(MythMainWindow *par 
    237248    infoRect = QRect(0, 0, 0, 0);
    238249    curInfoRect = QRect(0, 0, 0, 0);
    239250    videoRect = QRect(0, 0, 0, 0);
     251    changrpRect = QRect(0, 0, 0, 0);
    240252
    241253    jumpToChannelEnabled =
    242254        gContext->GetNumSetting("EPGEnableJumpToChannel", 1);
    GuideGrid::GuideGrid(MythMainWindow *par 
    254266    if (m_player && m_player->IsRunning() && !allowsecondaryepg)
    255267        videoRect = QRect(0, 0, 1, 1);
    256268
    257     showFavorites = gContext->GetNumSetting("EPGShowFavorites", 0);
    258269    gridfilltype = gContext->GetNumSetting("EPGFillType", UIGuideType::Alpha);
    259270    if (gridfilltype < (int)UIGuideType::Alpha)
    260271    { // update old settings to new fill types
    GuideGrid::GuideGrid(MythMainWindow *par 
    311322            container->SetDrawFontShadow(false);
    312323    }
    313324
     325    container = theme->GetSet("channel_group");
     326    if (container)
     327    {
     328        UITextType *type = (UITextType *)container->GetType("changroup");
     329        QString changroup;
     330       
     331        changroup = ChannelGroup::GetChannelGroupName(m_changrplist, m_changrpid);
     332       
     333        if (type)
     334            type->SetText(changroup);
     335    }
     336
    314337    channelOrdering = gContext->GetSetting("ChannelOrdering", "channum");
    315338    dateformat = gContext->GetSetting("ShortDateFormat", "ddd d");
    316339    unknownTitle = gContext->GetSetting("UnknownTitle", "Unknown");
    void GuideGrid::parseContainer(QDomEleme 
    687710        curInfoRect = area;
    688711    if (name.toLower() == "current_video")
    689712        videoRect = area;
     713    if (name.toLower() == "channel_group")
     714        changrpRect = area;
    690715}
    691716
    692717PixmapChannel *GuideGrid::GetChannelInfo(uint chan_idx, int sel)
    void GuideGrid::fillChannelInfos(bool go 
    885910    m_channelInfoIdx.clear();
    886911    m_currentStartChannel = 0;
    887912
    888     DBChanList channels = ChannelUtil::GetChannels(0, true);
     913    DBChanList channels = ChannelUtil::GetChannels(0, true, "", m_changrpid);
    889914    ChannelUtil::SortChannels(channels, channelOrdering, false);
    890915
    891     if (showFavorites)
    892     {
    893         DBChanList tmp;
    894         for (uint i = 0; i < channels.size(); i++)
    895         {
    896             if (channels[i].favorite)
    897                 tmp.push_back(channels[i]);
    898         }
    899 
    900         if (!tmp.empty())
    901             channels = tmp;
    902     }
    903 
    904916    typedef vector<uint> uint_list_t;
    905917    QMap<QString,uint_list_t> channum_to_index_map;
    906918    QMap<QString,uint_list_t> callsign_to_index_map;
    void GuideGrid::fillProgramInfos(void) 
    11161128    }
    11171129}
    11181130
     1131void GuideGrid::fillChanGroupInfo(void)
     1132{
     1133    LayerSet   *container = NULL;
     1134    UITextType *type = NULL;
     1135   
     1136    container = theme->GetSet("channel_group");
     1137    if (container)
     1138    {
     1139        type = (UITextType *)container->GetType("changroup");
     1140        QString changroup;
     1141       
     1142        changroup = ChannelGroup::GetChannelGroupName(m_changrplist, m_changrpid);
     1143       
     1144        if (type)
     1145            type->SetText(changroup);
     1146    }
     1147}
     1148
    11191149void GuideGrid::fillProgramRowInfos(unsigned int row)
    11201150{
    11211151    LayerSet *container = NULL;
    void GuideGrid::paintEvent(QPaintEvent * 
    13961426        paintPrograms(&p);
    13971427    if (r.intersects(curInfoRect))
    13981428        paintCurrentInfo(&p);
     1429    if (r.intersects(changrpRect))
     1430        paintChanGroupInfo(&p);
    13991431
    14001432    // if jumpToChannel has its own rect, use that;
    14011433    // otherwise use the date's rect
    void GuideGrid::paintCurrentInfo(QPainte 
    15181550    p->drawPixmap(dr.topLeft(), pix);
    15191551}
    15201552
     1553void GuideGrid::paintChanGroupInfo(QPainter *p)
     1554{
     1555    QRect dr = changrpRect;
     1556    QPixmap pix(dr.size());
     1557    pix.fill(this, dr.topLeft());
     1558    QPainter tmp(&pix);
     1559
     1560    LayerSet *container = NULL;
     1561    container = theme->GetSet("channel_group");
     1562    if (container)
     1563    {
     1564        container->Draw(&tmp, 1, m_context);
     1565        container->Draw(&tmp, 2, m_context);
     1566        container->Draw(&tmp, 3, m_context);
     1567        container->Draw(&tmp, 4, m_context);
     1568        container->Draw(&tmp, 5, m_context);
     1569        container->Draw(&tmp, 6, m_context);
     1570        container->Draw(&tmp, 7, m_context);
     1571        container->Draw(&tmp, 8, m_context);
     1572    }
     1573    tmp.end();
     1574    p->drawPixmap(dr.topLeft(), pix);
     1575}
     1576
    15211577bool GuideGrid::paintChannels(QPainter *p)
    15221578{
    15231579    QRect cr = channelRect;
    bool GuideGrid::paintChannels(QPainter * 
    16031659        }
    16041660
    16051661        QString tmpChannelFormat = channelFormat;
    1606         if (chinfo->favorite > 0)
    1607         {
    1608             tmpChannelFormat.insert(
    1609                 tmpChannelFormat.indexOf('<'), "<MARK:fav>");
    1610         }
    16111662
    16121663        if (unavailable)
    16131664        {
    bool GuideGrid::paintChannels(QPainter * 
    16431694        }
    16441695    }
    16451696
     1697    if (m_channelInfos.size() == 0)
     1698    {
     1699       // if the user has selected a channel group with no channels
     1700       // Reset the text and icon. This will display one blank line
     1701       // to show that the channel group has no channels
     1702       if (type)
     1703       {
     1704         type->SetText(0, "");
     1705         type->ResetImage(0);
     1706       }
     1707    }
     1708
    16461709    if (container)
    16471710    {
    16481711        container->Draw(&tmp, 1, m_context);
    void GuideGrid::paintInfo(QPainter *p) 
    17781841
    17791842void GuideGrid::toggleGuideListing()
    17801843{
    1781     showFavorites = (!showFavorites);
    1782     generateListings();
     1844    int oldchangrpid = m_changrpid;
     1845   
     1846    m_changrpid = ChannelGroup::GetNextChannelGroup(m_changrplist, oldchangrpid);
     1847   
     1848    if (oldchangrpid != m_changrpid)
     1849      generateListings();
     1850     
     1851    fillChanGroupInfo();
     1852    update(changrpRect);
    17831853}
    17841854
    17851855void GuideGrid::generateListings()
    void GuideGrid::generateListings() 
    17981868    update(fullRect);
    17991869}
    18001870
     1871int GuideGrid::SelectChannelGroup()
     1872{
     1873    if (m_changrplist.empty())
     1874    {
     1875      MythPopupBox::showOkPopup(gContext->GetMainWindow(), "",
     1876                                "You don't have any channel groups defined");
     1877
     1878      return -1;
     1879    }
     1880   
     1881    MythPopupBox *popup = new MythPopupBox(gContext->GetMainWindow(), "SelectChannelGroup Popup");
     1882    popup->addLabel("Select Channel Group");
     1883
     1884    for (uint i = 0; i < m_changrplist.size(); i++)
     1885      popup->addButton(m_changrplist[i].name);
     1886
     1887    popup->addButton(tr("Cancel"))->setFocus();
     1888
     1889    DialogCode result = popup->ExecPopup();
     1890   
     1891    popup->deleteLater();
     1892
     1893    // If the user cancelled, return a special value
     1894    if (result == MythDialog::Rejected)
     1895      return -1;
     1896    else
     1897      return m_changrplist[result - kDialogCodeListStart].grpid;
     1898}
     1899
    18011900void GuideGrid::toggleChannelFavorite()
    18021901{
    1803     MSqlQuery query(MSqlQuery::InitCon());
     1902    int grpid;
     1903
     1904    if (m_changrpid == -1)
     1905    {
     1906      grpid = SelectChannelGroup();
     1907     
     1908      if (grpid == -1)
     1909        return;
     1910    }
     1911    else
     1912      grpid = m_changrpid;
    18041913
    18051914    // Get current channel id, and make sure it exists...
    18061915    int chanNum = m_currentRow + m_currentStartChannel;
    void GuideGrid::toggleChannelFavorite() 
    18121921        chanNum = 0;
    18131922
    18141923    PixmapChannel *ch = GetChannelInfo(chanNum);
    1815     uint favid  = ch->favorite;
    18161924    uint chanid = ch->chanid;
    18171925
    1818     if (favid > 0)
    1819     {
    1820         query.prepare("DELETE FROM favorites WHERE favid = :FAVID ;");
    1821         query.bindValue(":FAVID", favid);
    1822         query.exec();
    1823     }
    1824     else
    1825     {
    1826         // We have no favorites record...Add one to toggle...
    1827         query.prepare("INSERT INTO favorites (chanid) VALUES (:FAVID);");
    1828         query.bindValue(":FAVID", chanid);
    1829         query.exec();
    1830     }
    1831 
    1832     if (showFavorites)
     1926    if (m_changrpid == -1)
     1927        // If currently viewing all channels, allow to add only not delete
     1928        ChannelGroup::ToggleChannel(chanid, grpid, false);
     1929     else
     1930        // Only allow delete if viewing the favorite group in question
     1931        ChannelGroup::ToggleChannel(chanid, grpid, true);
     1932     
     1933    // If viewing favorites, refresh because a channel was removed
     1934    if (m_changrpid != -1)
    18331935        generateListings();
    1834     else
    1835     {
    1836         int maxchannel = 0;
    1837         DISPLAY_CHANS = desiredDisplayChans;
    1838         fillChannelInfos(false);
    1839         maxchannel = max((int)GetChannelCount() - 1, 0);
    1840         DISPLAY_CHANS = min(DISPLAY_CHANS, maxchannel + 1);
    1841 
    1842         repaint(channelRect);
    1843     }
    18441936}
    18451937
    18461938void GuideGrid::cursorLeft()
  • libs/libmythtv/guidegrid.h

    diff -Naurp -x '*.orig' mythtv-orig/libs/libmythtv/guidegrid.h mythtv/libs/libmythtv/guidegrid.h
    old new  
    1616#include "uitypes.h"
    1717#include "xmlparse.h"
    1818#include "libmythtv/programinfo.h"
     19#include "libmythtv/channelgroup.h"
    1920#include "channelutil.h"
    2021
    2122using namespace std;
    class MPUBLIC GuideGrid : public MythDia 
    8182                          const QString &startChanNum,
    8283                          bool           thread = false,
    8384                          TV            *player = NULL,
    84                           bool           allowsecondaryepg = true);
     85                          bool           allowsecondaryepg = true,
     86                          int           *changrpid = NULL);
    8587
    8688    DBChanList GetSelection(void) const;
    8789
    class MPUBLIC GuideGrid : public MythDia 
    131133    GuideGrid(MythMainWindow *parent,
    132134              uint chanid = 0, QString channum = "",
    133135              TV *player = NULL, bool allowsecondaryepg = true,
    134               const char *name = "GuideGrid");
     136              const char *name = "GuideGrid",
     137              int changrpid=-1);
    135138   ~GuideGrid();
    136139
     140    int  GetChanGrp(void) {return m_changrpid;}
    137141    void paintEvent(QPaintEvent *);
    138142
    139143  private slots:
    class MPUBLIC GuideGrid : public MythDia 
    152156    void paintPrograms(QPainter *);
    153157    void paintCurrentInfo(QPainter *);
    154158    void paintInfo(QPainter *);
     159    void paintChanGroupInfo(QPainter *p);
    155160 
    156161    void resizeImage(QPixmap *, QString);
    157162    void LoadWindow(QDomElement &);
    class MPUBLIC GuideGrid : public MythDia 
    176181    QRect infoRect;
    177182    QRect curInfoRect;
    178183    QRect videoRect;
     184    QRect changrpRect;
    179185
    180186    void fillChannelInfos(bool gotostartchannel = true);
    181187    int  FindChannel(uint chanid, const QString &channum,
    class MPUBLIC GuideGrid : public MythDia 
    185191
    186192    void fillProgramInfos(void);
    187193    void fillProgramRowInfos(unsigned int row);
     194   
     195    void fillChanGroupInfo(void);
    188196
    189197    void setStartChannel(int newStartChannel);
    190198
    191199    void createProgramLabel(int, int);
     200   
     201    int SelectChannelGroup();
    192202
    193203    PixmapChannel       *GetChannelInfo(uint chan_idx, int sel = -1);
    194204    const PixmapChannel *GetChannelInfo(uint chan_idx, int sel = -1) const;
    class MPUBLIC GuideGrid : public MythDia 
    218228    int m_currentCol;
    219229
    220230    bool selectState;
    221     bool showFavorites;
    222231    bool sortReverse;
    223232    QString channelFormat;
    224233
    class MPUBLIC GuideGrid : public MythDia 
    241250    QTimer *videoRepaintTimer;
    242251
    243252    bool keyDown;
     253   
     254    int  m_changrpid;
     255    ChannelGroupList m_changrplist;
    244256
    245257    QMutex         jumpToChannelLock;
    246258    JumpToChannel *jumpToChannel;
  • libs/libmythtv/libmythtv.pro

    diff -Naurp -x '*.orig' mythtv-orig/libs/libmythtv/libmythtv.pro mythtv/libs/libmythtv/libmythtv.pro
    old new HEADERS += playgroup.h prog 
    147147HEADERS += channeleditor.h          channelsettings.h
    148148HEADERS += previewgenerator.h       transporteditor.h
    149149HEADERS += importicons.h
     150HEADERS += channelgroup.h           channelgroupsettings.h
    150151
    151152SOURCES += programinfo.cpp          proglist.cpp
    152153SOURCES += RingBuffer.cpp           avfringbuffer.cpp
    SOURCES += progdetails.cpp 
    169170SOURCES += channeleditor.cpp        channelsettings.cpp
    170171SOURCES += previewgenerator.cpp     transporteditor.cpp
    171172SOURCES += importicons.cpp
     173SOURCES += channelgroup.cpp         channelgroupsettings.cpp
    172174
    173175# DiSEqC
    174176HEADERS += diseqc.h                 diseqcsettings.h
  • libs/libmythtv/tv_play.cpp

    diff -Naurp -x '*.orig' mythtv-orig/libs/libmythtv/tv_play.cpp mythtv/libs/libmythtv/tv_play.cpp
    old new bool TV::StartTV (ProgramInfo *tvrec, bo 
    263263
    264264    bool allowrerecord = tv->getAllowRerecord();
    265265    bool deleterecording = tv->getRequestDelete();
     266   
     267    tv->SaveChannelGroup();
    266268
    267269    delete tv;
    268270
    void TV::InitKeys(void) 
    325327            "in the program guide", "0");
    326328    REG_KEY("TV Frontend", "GUIDE", "Show the Program Guide", "S");
    327329    REG_KEY("TV Frontend", "FINDER", "Show the Program Finder", "#");
    328     REG_KEY("TV Frontend", "NEXTFAV", "Toggle showing all channels or just "
    329             "favorites in the program guide.", "/");
     330    REG_KEY("TV Frontend", "NEXTFAV", "Cycle through channel groups and all channels "
     331            "in the program guide.", "/,S");
    330332    REG_KEY("TV Frontend", "CHANUPDATE", "Switch channels without exiting "
    331333            "guide in Live TV mode.", "X");
    332334    REG_KEY("TV Frontend", "VOLUMEDOWN", "Volume down", "[,{,F10,Volume Down");
    bool TV::Init(bool createWindow) 
    664666    autoCommercialSkip   = (enum commSkipMode)gContext->GetNumSetting(
    665667                            "AutoCommercialSkip", CommSkipOff);
    666668    tryUnflaggedSkip     = gContext->GetNumSetting("TryUnflaggedSkip", 0);
     669    channel_group_id     = gContext->GetNumSetting("ChannelGroupDefault", -1);
     670    browse_changrp       = gContext->GetNumSetting("BrowseChannelGroup", 0);
    667671    smartForward         = gContext->GetNumSetting("SmartForward", 0);
    668672    stickykeys           = gContext->GetNumSetting("StickyKeys");
    669673    ff_rew_repos         = gContext->GetNumSetting("FFRewReposTime", 100)/100.0;
    bool TV::Init(bool createWindow) 
    678682    if (!feVBI.isEmpty())
    679683        vbimode = VBIMode::Parse(gContext->GetSetting(feVBI));
    680684
     685    channel_group_id     = gContext->GetNumSetting("ChannelGroupDefault", -1);
     686    browse_changrp       = gContext->GetNumSetting("BrowseChannelGroup", 0);
     687   
     688    if (browse_changrp && (channel_group_id > -1))
     689    {
     690      m_channellist = ChannelUtil::GetChannels(0, true, "channum, callsign", channel_group_id);
     691      ChannelUtil::SortChannels(m_channellist, "channum", true);
     692    }
     693   
     694    m_changrplist  = ChannelGroup::GetChannelGroups();
     695
    681696    if (createWindow)
    682697    {
    683698        MythMainWindow *mainWindow = gContext->GetMainWindow();
    TV::~TV(void) 
    853868    }
    854869}
    855870
     871void TV::SaveChannelGroup(void)
     872{
     873    int changrpid             = gContext->GetNumSetting("ChannelGroupDefault", -1);
     874    int remember_last_changrp = gContext->GetNumSetting("ChannelGroupRememberLast", 0);
     875
     876    if (remember_last_changrp && (changrpid != channel_group_id))
     877       gContext->SaveSetting("ChannelGroupDefault", channel_group_id);
     878}
     879
    856880TVState TV::GetState(void) const
    857881{
    858882    if (InStateChange())
    void TV::ToggleInputs(uint inputid) 
    47684792
    47694793void TV::ToggleChannelFavorite(void)
    47704794{
    4771     activerecorder->ToggleChannelFavorite();
     4795//    activerecorder->ToggleChannelFavorite();
    47724796}
    47734797
    47744798void TV::ChangeChannel(int direction)
    47754799{
    47764800    bool muted = false;
    47774801
     4802    if ((browse_changrp || (direction == CHANNEL_DIRECTION_FAVORITE)) &&
     4803        (channel_group_id > -1) && (direction != CHANNEL_DIRECTION_SAME))
     4804    {
     4805       uint    chanid;
     4806     
     4807       // Collect channel info
     4808       pbinfoLock.lock();
     4809       uint    old_chanid  = playbackinfo->chanid.toUInt();
     4810       pbinfoLock.unlock();
     4811
     4812       chanid = ChannelUtil::GetNextChannel(m_channellist, old_chanid, 0, direction);
     4813
     4814       ChangeChannel(chanid, "");     
     4815       return;
     4816    } else if (direction == CHANNEL_DIRECTION_FAVORITE)
     4817        direction = CHANNEL_DIRECTION_UP;
     4818
    47784819    if (activenvp && (activenvp == nvp))
    47794820        muted = activenvp->SetMuted(true);
    47804821
    void TV::doEditSchedule(int editType) 
    58985939
    58995940    DBChanList changeChannel;
    59005941    ProgramInfo *nextProgram = NULL;
     5942    int changrpid = channel_group_id;
    59015943
    59025944    bool stayPaused = paused;
    59035945    TV *player = NULL;
    void TV::doEditSchedule(int editType) 
    59165958            if (StateIsLiveTV(GetState()))
    59175959            {
    59185960                changeChannel = GuideGrid::Run(chanid, channum, false,
    5919                                             player, allowsecondary);
     5961                                            player, allowsecondary, &changrpid);
    59205962            }
    59215963            else
    5922                 GuideGrid::Run(chanid, channum, false, player);
     5964                GuideGrid::Run(chanid, channum, false, player, true, &changrpid);
    59235965            break;
    59245966        }
    59255967        case kScheduleProgramFinder:
    void TV::doEditSchedule(int editType) 
    59646006        exitPlayer = true;
    59656007        delete nextProgram;
    59666008    }
     6009   
    59676010    // Resize the window back to the MythTV Player size
    59686011    if (!using_gui_size_for_tv)
    59696012    {
    void TV::doEditSchedule(int editType) 
    59746017    if (nvp && nvp->getVideoOutput())
    59756018        nvp->getVideoOutput()->ResizeForVideo();
    59766019
     6020    // if channel group was changed in EPG update local info
     6021    if ((changrpid != channel_group_id) && (editType == kScheduleProgramGuide))
     6022    {
     6023        channel_group_id = changrpid;
     6024       
     6025        if (browse_changrp)
     6026        {
     6027            VERBOSE(VB_IMPORTANT, LOC +
     6028               QString("Reloading channel group list for %1").arg(channel_group_id));
     6029       
     6030            m_channellist = ChannelUtil::GetChannels(0, true, "channum, callsign", channel_group_id);
     6031            ChannelUtil::SortChannels(m_channellist, "channum", true);
     6032        }
     6033    }
     6034   
    59776035    // If user selected a new channel in the EPG, change to that channel
    59786036    if (changeChannel.size())
    59796037        ChangeChannel(changeChannel);
    void TV::BrowseDispInfo(int direction) 
    66246682{
    66256683    if (!browsemode)
    66266684        BrowseStart();
     6685VERBOSE(VB_IMPORTANT,"In BrowseDispInfo");
     6686    // if browsing channel groups is enabled or direction if BROWSE_FAVORITES
     6687    // Then pick the next channel in the channel group list to browse
     6688    // If channel group is ALL CHANNELS (-1), then bypass picking from
     6689    // the channel group list
     6690    if ((browse_changrp || (direction == BROWSE_FAVORITE)) &&
     6691        (channel_group_id > -1) && (direction != BROWSE_SAME) &&
     6692        (direction != BROWSE_RIGHT) && (direction != BROWSE_LEFT))
     6693    {
     6694      uint chanid;
     6695      int  dir;
     6696     
     6697      if ( (direction == BROWSE_UP) || (direction == BROWSE_FAVORITE) )
     6698        dir = CHANNEL_DIRECTION_UP;
     6699      else if (direction == BROWSE_DOWN)
     6700        dir = CHANNEL_DIRECTION_DOWN;
     6701      else // this should never happen, but just in case
     6702        dir = direction;
     6703       
     6704      chanid = ChannelUtil::GetNextChannel(m_channellist, browsechanid.toUInt(), 0, dir);
     6705      VERBOSE(VB_IMPORTANT, QString("Get channel: %1").arg(chanid));
     6706      browsechanid  = QString("%1").arg(chanid);
     6707      browsechannum = QString::null;
     6708      direction     = BROWSE_SAME;
     6709    }
     6710    else if ((channel_group_id == -1) && (direction == BROWSE_FAVORITE))
     6711      direction = BROWSE_UP;
    66276712
    66286713    InfoMap infoMap;
    66296714    QDateTime curtime  = QDateTime::currentDateTime();
    void TV::TreeMenuSelected(OSDListTreeTyp 
    73997484    }
    74007485    else if (action == "GUIDE")
    74017486        EditSchedule(kScheduleProgramGuide);
     7487    else if (action.left(10) == "CHANGROUP_")
     7488        processChanGroupEntry(action);
    74027489    else if (action == "FINDER")
    74037490        EditSchedule(kScheduleProgramFinder);
    74047491    else if (action == "SCHEDULE")
    void TV::TreeMenuSelected(OSDListTreeTyp 
    75007587    }
    75017588}
    75027589
     7590void TV::processChanGroupEntry(QString action)
     7591{
     7592    if (action == "CHANGROUP_ALL_CHANNELS")
     7593      channel_group_id = -1;
     7594    else
     7595    {
     7596      action.remove("CHANGROUP_");
     7597      channel_group_id = action.toInt();
     7598         
     7599      if (browse_changrp)
     7600      {
     7601         m_channellist = ChannelUtil::GetChannels(0, true, "channum, callsign", channel_group_id);
     7602         ChannelUtil::SortChannels(m_channellist, "channum", true);
     7603      }
     7604    }
     7605}
     7606
    75037607void TV::ShowOSDTreeMenu(void)
    75047608{
    75057609    BuildOSDTreeMenu();
    void TV::FillMenuLiveTV(OSDGenericTree * 
    76867790
    76877791    new OSDGenericTree(treeMenu, tr("Program Guide"), "GUIDE");
    76887792
     7793    OSDGenericTree *cg_item = new OSDGenericTree(treeMenu, tr("Channel Groups"),
     7794                                                 "CHANGROUP");
     7795    new OSDGenericTree(cg_item, tr("All Channels"), "CHANGROUP_ALL_CHANNELS",
     7796                                 (channel_group_id == -1) ? 1 : 0,
     7797                                 NULL, "CHANNELGROUP");
     7798       
     7799    ChannelGroupList::iterator it;
     7800       
     7801    for (it = m_changrplist.begin(); it != m_changrplist.end(); ++it)
     7802    {
     7803        QString name = QString("CHANGROUP_%1").arg(it->grpid);
     7804        new OSDGenericTree(cg_item, it->name, name,
     7805                           ((int)(it->grpid) == channel_group_id) ? 1 : 0,
     7806                           NULL, "CHANNELGROUP");
     7807    }   
     7808
    76897809    if (!gContext->GetNumSetting("JumpToProgramOSD", 1))
    76907810    {
    76917811        OSDGenericTree *jtpo_item =
  • libs/libmythtv/tv_play.h

    diff -Naurp -x '*.orig' mythtv-orig/libs/libmythtv/tv_play.h mythtv/libs/libmythtv/tv_play.h
    old new  
    2020#include "channelutil.h"
    2121#include "videoouttypes.h"
    2222#include "inputinfo.h"
     23#include "channelgroup.h"
    2324
    2425#include <qobject.h>
    2526
    class MPUBLIC TV : public QThread 
    239240    // Used by EPG
    240241    void ChangeVolume(bool up);
    241242    void ToggleMute(void);
     243   
     244    // Channel Groups
     245    void SaveChannelGroup(void);
    242246
    243247    // Used for UDPNotify
    244248    bool HasUDPNotifyEvent(void) const;
    class MPUBLIC TV : public QThread 
    414418    void ShowOSDTreeMenu(void);
    415419    void FillMenuLiveTV(OSDGenericTree *treeMenu);
    416420    void FillMenuPlaying(OSDGenericTree *treeMenu);
     421    void processChanGroupEntry(QString action);
    417422
    418423    void UpdateLCD(void);
    419424    void ShowLCDChannelInfo(void);
    class MPUBLIC TV : public QThread 
    710715    static const uint kNextSource;
    711716    static const uint kPreviousSource;
    712717
     718    // Channel favorite group stuff   
     719    int channel_group_id;
     720    uint browse_changrp;
     721    ChannelGroupList m_changrplist;
     722    DBChanList m_channellist;
     723
    713724    // Network Control stuff
    714725    MythDeque<QString> networkControlCommands;
    715726    QMutex ncLock;
  • programs/mythfrontend/globalsettings.cpp

    diff -Naurp -x '*.orig' mythtv-orig/programs/mythfrontend/globalsettings.cpp mythtv/programs/mythfrontend/globalsettings.cpp
    old new static HostCheckBox *EPGShowChannelIcon( 
    30923092    return gc;
    30933093}
    30943094
    3095 static HostCheckBox *EPGShowFavorites()
    3096 {
    3097     HostCheckBox *gc = new HostCheckBox("EPGShowFavorites");
    3098     gc->setLabel(QObject::tr("Only display 'favorite' channels"));
    3099     gc->setHelpText(QObject::tr("If enabled, the EPG will initially display "
    3100                     "only the channels marked as favorites. Pressing "
    3101                     "\"4\" will toggle between displaying favorites and all "
    3102                     "channels."));
    3103     gc->setValue(false);
    3104     return gc;
    3105 }
    31063095
    31073096static HostSpinBox *EPGChanDisplay()
    31083097{
    static GlobalCheckBox *EPGEnableJumpToCh 
    31303119    return gc;
    31313120}
    31323121
     3122static HostCheckBox *ChannelGroupRememberLast()
     3123{
     3124    HostCheckBox *gc = new HostCheckBox("ChannelGroupRememberLast");
     3125    gc->setLabel(QObject::tr("Remember last channel group"));
     3126    gc->setHelpText(QObject::tr("If enabled, the EPG will initially display "
     3127                    "only the channels from the last channel group selected. Pressing "
     3128                    "\"4\" will toggle channel group."));
     3129    gc->setValue(false);
     3130    return gc;
     3131}
     3132
     3133static HostComboBox *ChannelGroupDefault()
     3134{
     3135    HostComboBox *gc = new HostComboBox("ChannelGroupDefault");
     3136    gc->setLabel(QObject::tr("Default channel group"));
     3137
     3138    ChannelGroupList changrplist;
     3139
     3140    changrplist = ChannelGroup::GetChannelGroups();
     3141
     3142    gc->addSelection(QObject::tr("All Channels"), "-1");
     3143
     3144    ChannelGroupList::iterator it;
     3145
     3146    for (it = changrplist.begin(); it < changrplist.end(); ++it)
     3147       gc->addSelection(it->name, QString("%1").arg(it->grpid));
     3148
     3149    gc->setHelpText(QObject::tr("Default channel group to be shown in the the EPG"
     3150                    "Pressing "
     3151                    "\"4\" will toggle channel group."));
     3152    gc->setValue(false);
     3153    return gc;
     3154}
     3155
     3156static HostCheckBox *BrowseChannelGroup()
     3157{
     3158    HostCheckBox *gc = new HostCheckBox("BrowseChannelGroup");
     3159    gc->setLabel(QObject::tr("Browse/Change channels from Channel Group"));
     3160    gc->setHelpText(QObject::tr("If enabled, LiveTV will browse or change channels "
     3161                    "from the selected channel group. \"All Channels\" "
     3162                    "channel group may be selected to browse all channels."));
     3163    gc->setValue(false);
     3164    return gc;
     3165}
     3166
     3167// Channel Group Settings
     3168class ChannelGroupSettings : public TriggeredConfigurationGroup
     3169{
     3170  public:
     3171    ChannelGroupSettings() : TriggeredConfigurationGroup(false, true, false, false)
     3172    {
     3173         setLabel(QObject::tr("Remember last channel group"));
     3174         setUseLabel(false);
     3175
     3176         Setting* RememberChanGrpEnabled = ChannelGroupRememberLast();
     3177         addChild(RememberChanGrpEnabled);
     3178         setTrigger(RememberChanGrpEnabled);
     3179
     3180         ConfigurationGroup* settings = new VerticalConfigurationGroup(false);
     3181         settings->addChild(ChannelGroupDefault());
     3182         addTarget("0", settings);
     3183
     3184         // show nothing if RememberChanGrpEnabled is on
     3185         addTarget("1", new VerticalConfigurationGroup(true));
     3186     };
     3187};
     3188
    31333189// General RecPriorities settings
    31343190
    31353191static GlobalCheckBox *GRSchedMoveHigher()
    GeneralSettings::GeneralSettings() 
    48964952    general2->addChild(CategoryOverTimeSettings());
    48974953    addChild(general2);
    48984954
     4955    VerticalConfigurationGroup* changrp = new VerticalConfigurationGroup(false);
     4956    changrp->setLabel(QObject::tr("General (Channel Groups)"));
     4957    ChannelGroupSettings *changroupsettings = new ChannelGroupSettings();
     4958    changrp->addChild(changroupsettings);
     4959    changrp->addChild(BrowseChannelGroup());
     4960    addChild(changrp);
    48994961}
    49004962
    49014963EPGSettings::EPGSettings()
    49024964{
    49034965    VerticalConfigurationGroup* epg = new VerticalConfigurationGroup(false);
    4904     epg->setLabel(QObject::tr("Program Guide") + " 1/2");
     4966    epg->setLabel(QObject::tr("Program Guide") + " 1/3");
    49054967    epg->addChild(EPGFillType());
    49064968    epg->addChild(EPGShowCategoryColors());
    49074969    epg->addChild(EPGShowCategoryText());
    49084970    epg->addChild(EPGScrollType());
    49094971    epg->addChild(EPGShowChannelIcon());
    4910     epg->addChild(EPGShowFavorites());
    49114972    epg->addChild(WatchTVGuide());
    49124973    epg->addChild(EPGChanDisplay());
    49134974    epg->addChild(EPGTimeDisplay());
    49144975    addChild(epg);
    49154976
    49164977    VerticalConfigurationGroup* gen = new VerticalConfigurationGroup(false);
    4917     gen->setLabel(QObject::tr("Program Guide") + " 2/2");
     4978    gen->setLabel(QObject::tr("Program Guide") + " 2/3");
    49184979    gen->addChild(UnknownTitle());
    49194980    gen->addChild(UnknownCategory());
    49204981    gen->addChild(DefaultTVChannel());
    49214982    gen->addChild(SelectChangesChannel());
    49224983    gen->addChild(EPGRecThreshold());
    49234984    gen->addChild(EPGEnableJumpToChannel());
    4924     addChild(gen);
     4985    addChild(gen);   
    49254986}
    49264987
    49274988GeneralRecPrioritiesSettings::GeneralRecPrioritiesSettings()
  • programs/mythfrontend/main.cpp

    diff -Naurp -x '*.orig' mythtv-orig/programs/mythfrontend/main.cpp mythtv/programs/mythfrontend/main.cpp
    old new using namespace std; 
    5353#include "lcddevice.h"
    5454#include "langsettings.h"
    5555#include "mythcommandlineparser.h"
     56#include "channelgroupsettings.h"
    5657
    5758#include "myththemedmenu.h"
    5859#include "myththemebase.h"
    void TVMenuCallback(void *data, QString  
    443444        EPGSettings settings;
    444445        settings.exec();
    445446    }
     447    else if (sel == "settings channelgroups")
     448    {
     449        ChannelGroupEditor editor;
     450        editor.exec();
     451     }
    446452    else if (sel == "settings generalrecpriorities")
    447453    {
    448454        GeneralRecPrioritiesSettings settings;
  • programs/mythfrontend/tv_settings.xml

    diff -Naurp -x '*.orig' mythtv-orig/programs/mythfrontend/tv_settings.xml mythtv/programs/mythfrontend/tv_settings.xml
    old new  
    9090      <text lang="DE">Wiedergabe OSD</text>
    9191      <action>SETTINGS OSD</action>
    9292   </button>
     93   
     94   <button>
     95      <type>TV_SETTINGS_CHANNEL_GROUP</type>
     96      <text>Channel Groups</text>
     97      <action>SETTINGS CHANNELGROUPS</action>
     98   </button>
    9399
    94100   <button>
    95101      <type>TV_SETTINGS_PLAYBACK_GROUPS</type>
  • themes/classic/tv_settings.xml

    diff -Naurp -x '*.orig' mythtv-orig/themes/classic/tv_settings.xml mythtv/themes/classic/tv_settings.xml
    old new  
    7171   </button>
    7272
    7373   <button>
     74      <type>TV_SETTINGS_CHANNEL_GROUP</type>
     75      <text>Channel Groups</text>
     76      <action>SETTINGS CHANNELGROUPS</action>
     77   </button>
     78
     79   <button>
    7480      <type>TV_SETTINGS_PLAYBACK_GROUPS</type>
    7581      <text>Playback Groups</text>
    7682      <text lang="IT">Gruppi di Riproduzione</text>
  • themes/DVR/tv_settings.xml

    diff -Naurp -x '*.orig' mythtv-orig/themes/DVR/tv_settings.xml mythtv/themes/DVR/tv_settings.xml
    old new  
    7474   </button>
    7575
    7676   <button>
     77      <type>TV_SETTINGS_CHANNEL_GROUP</type>
     78      <text>Channel Groups</text>
     79      <action>SETTINGS CHANNELGROUPS</action>
     80   </button>
     81
     82   <button>
    7783      <type>TV_SETTINGS_PLAYBACK_GROUPS</type>
    7884      <text>Playback Groups</text>
    7985      <text lang="SV">Uppspelningsgrupper</text>