Ticket #199: 00-199-channelgroups.7.2.patch

File 00-199-channelgroups.7.2.patch, 57.0 KB (added by Matthew Wire <devel@…>, 15 years ago)

Refresh against 20301

  • mythtv/themes/classic/tv_settings.xml

     
    8181    </button>
    8282
    8383    <button>
     84        <type>TV_SETTINGS_CHANNEL_GROUP</type>
     85        <text>Channel Groups</text>
     86        <action>SETTINGS CHANNELGROUPS</action>
     87    </button>
     88
     89    <button>
    8490        <type>TV_SETTINGS_PLAYBACK_GROUPS</type>
    8591        <text>Playback Groups</text>
    8692        <text lang="IT">Gruppi di Riproduzione</text>
  • mythtv/themes/DVR/tv_settings.xml

     
    8484    </button>
    8585
    8686    <button>
     87        <type>TV_SETTINGS_CHANNEL_GROUP</type>
     88        <text>Channel Groups</text>
     89        <action>SETTINGS CHANNELGROUPS</action>
     90    </button>
     91
     92    <button>
    8793        <type>TV_SETTINGS_PLAYBACK_GROUPS</type>
    8894        <text>Playback Groups</text>
    8995        <text lang="SV">Uppspelningsgrupper</text>
  • mythtv/themes/defaultmenu/tv_settings.xml

     
    9595        <action>SETTINGS OSD</action>
    9696    </button>
    9797
    98   <button>
     98    <button>
    9999        <type>TV_SETTINGS_OSD_MENU_EDITOR</type>
    100100        <text>OSD Menu Editor</text>
    101101        <action>OSDMENUEDITOR</action>
    102   </button>
     102    </button>
     103
    103104    <button>
     105        <type>TV_SETTINGS_CHANNEL_GROUP</type>
     106        <text>Channel Groups</text>
     107        <action>SETTINGS CHANNELGROUPS</action>
     108    </button>
     109
     110    <button>
    104111        <type>TV_SETTINGS_PLAYBACK_GROUPS</type>
    105112        <text>Playback Groups</text>
    106113        <text lang="IT">Gruppi di Riproduzione</text>
  • mythtv/libs/libmythtv/dbchannelinfo.cpp

     
    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();
     
    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();
  • mythtv/libs/libmythtv/channelutil.h

     
    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);
  • mythtv/libs/libmythtv/dbchannelinfo.h

     
    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
     
    3434    uint    chanid;
    3535    uint    major_chan;
    3636    uint    minor_chan;
    37     uint    favorite;
    3837    uint    mplexid;
    3938    bool    visible;
    4039    QString name;
  • mythtv/libs/libmythtv/libmythtv.pro

     
    161161HEADERS += viewschdiff.h            livetvchain.h
    162162HEADERS += playgroup.h              progdetails.h
    163163HEADERS += channelsettings.h        previewgenerator.h
    164 HEADERS += transporteditor.h
     164HEADERS += transporteditor.h       
    165165HEADERS += myth_imgconvert.h
     166HEADERS += channelgroup.h           channelgroupsettings.h
    166167
    167168# Remove when everything is switched to MythUI
    168169HEADERS += proglist_qt.h
     
    186187SOURCES += progdetails.cpp
    187188SOURCES += channelsettings.cpp      previewgenerator.cpp
    188189SOURCES += transporteditor.cpp
     190SOURCES += channelgroup.cpp         channelgroupsettings.cpp
    189191
    190192contains( CONFIG_SWSCALE, yes ) {
    191193    SOURCES += myth_imgconvert.cpp
  • mythtv/libs/libmythtv/guidegrid.h

     
    1818#include "programinfo.h"
    1919#include "programlist.h"
    2020#include "channelutil.h"
     21#include "channelgroup.h"
    2122
    2223using namespace std;
    2324
     
    8485                          const QString &startChanNum,
    8586                          bool           thread = false,
    8687                          TV            *player = NULL,
    87                           bool           allowsecondaryepg = true);
     88                          bool           allowsecondaryepg = true,
     89                          int           *changrpid = NULL);
    8890
    8991    DBChanList GetSelection(void) const;
    9092
     
    134136    GuideGrid(MythMainWindow *parent,
    135137              uint chanid = 0, QString channum = "",
    136138              TV *player = NULL, bool allowsecondaryepg = true,
    137               const char *name = "GuideGrid");
     139              const char *name = "GuideGrid",
     140              int changrpid=-1);
    138141   ~GuideGrid();
    139142
     143    int  GetChanGrp(void) {return m_changrpid;}
    140144    void paintEvent(QPaintEvent *);
    141145
    142146  private slots:
     
    155159    void paintPrograms(QPainter *);
    156160    void paintCurrentInfo(QPainter *);
    157161    void paintInfo(QPainter *);
     162    void paintChanGroupInfo(QPainter *p);
    158163    void paintVideo(QPainter *);
    159164 
    160165    void resizeImage(QPixmap *, QString);
     
    180185    QRect infoRect;
    181186    QRect curInfoRect;
    182187    QRect videoRect;
     188    QRect changrpRect;
    183189
    184190    void fillChannelInfos(bool gotostartchannel = true);
    185191    int  FindChannel(uint chanid, const QString &channum,
     
    189195
    190196    void fillProgramInfos(void);
    191197    void fillProgramRowInfos(unsigned int row);
     198   
     199    void fillChanGroupInfo(void);
    192200
    193201    void setStartChannel(int newStartChannel);
    194202
    195203    void createProgramLabel(int, int);
     204   
     205    int SelectChannelGroup();
    196206
    197207    PixmapChannel       *GetChannelInfo(uint chan_idx, int sel = -1);
    198208    const PixmapChannel *GetChannelInfo(uint chan_idx, int sel = -1) const;
     
    222232    int m_currentCol;
    223233
    224234    bool selectState;
    225     bool showFavorites;
    226235    bool sortReverse;
    227236    QString channelFormat;
    228237
     
    247256    QTimer *timeCheck;
    248257
    249258    bool keyDown;
     259   
     260    int  m_changrpid;
     261    ChannelGroupList m_changrplist;
    250262
    251263    QMutex         jumpToChannelLock;
    252264    JumpToChannel *jumpToChannel;
  • mythtv/libs/libmythtv/tv_play.h

     
    2525#include "videoouttypes.h"
    2626#include "volumebase.h"
    2727#include "inputinfo.h"
     28#include "channelgroup.h"
    2829
    2930#include <qobject.h>
    3031
     
    266267    void ToggleMute(PlayerContext*);
    267268
    268269    void SetNextProgPIPState(PIPState state) { jumpToProgramPIPState = state; }
     270   
     271    // Channel Groups
     272    void SaveChannelGroup(void);
    269273
    270274    // Used for UDPNotify
    271275    bool HasUDPNotifyEvent(void) const;
     
    520524    void FillMenuTimeStretch(   const PlayerContext*, OSDGenericTree*) const;
    521525    void FillMenuSleepMode(     const PlayerContext*, OSDGenericTree*) const;
    522526    bool FillMenuTracks(        const PlayerContext*, OSDGenericTree*, uint type) const;
     527    void FillMenuChanGroups(    const PlayerContext*, OSDGenericTree*) const;
    523528
     529    void processChanGroupEntry(QString action);
     530
    524531    void UpdateLCD(void);
    525532    bool HandleLCDTimerEvent(void);
    526533    void ShowLCDChannelInfo(const PlayerContext*);
     
    750757    QMap<int,int>             recorderPlaybackInfoTimerId;
    751758    QMap<int,ProgramInfo>     recorderPlaybackInfo;
    752759
     760    // Channel favorite group stuff   
     761    int channel_group_id;
     762    uint browse_changrp;
     763    ChannelGroupList m_changrplist;
     764    DBChanList m_channellist;
     765
    753766    // Network Control stuff
    754767    MythDeque<QString> networkControlCommands;
    755768
  • mythtv/libs/libmythtv/guidegrid.cpp

     
    3434#include "util.h"
    3535#include "remoteutil.h"
    3636#include "channelutil.h"
     37#include "guidegrid.h"
    3738#include "cardutil.h"
    3839
    3940QWaitCondition epgIsVisibleCond;
     
    171172    const QString &channum,
    172173    bool           thread,
    173174    TV            *player,
    174     bool           allowsecondaryepg)
     175    bool           allowsecondaryepg,
     176    int           *changrpid)
    175177{
    176178    DBChanList channel_changed;
     179    int        channel_group  = -1;
    177180
     181    if (changrpid != NULL)
     182      channel_group = *changrpid;
     183
    178184    //if (thread)
    179185    //    qApp->lock();
    180186
     
    182188
    183189    GuideGrid *gg = new GuideGrid(gContext->GetMainWindow(),
    184190                                  chanid, channum,
    185                                   player, allowsecondaryepg, "guidegrid");
     191                                  player, allowsecondaryepg, "guidegrid",
     192                                  channel_group);
    186193
    187194    gg->Show();
    188195
     
    210217    //if (thread)
    211218    //    qApp->lock();
    212219
     220    if (changrpid != NULL)
     221      *changrpid = gg->GetChanGrp();
     222
    213223    delete gg;
    214224
    215225    gContext->removeCurrentLocation();
     
    223233GuideGrid::GuideGrid(MythMainWindow *parent,
    224234                     uint chanid, QString channum,
    225235                     TV *player, bool allowsecondaryepg,
    226                      const char *name) :
     236                     const char *name, int changrpid) :
    227237    MythDialog(parent, name),
    228238    m_player(player),
    229239    using_null_video(false),
     
    240250    DISPLAY_TIMES = 30;
    241251    int maxchannel = 0;
    242252    m_currentStartChannel = 0;
     253    m_changrpid = changrpid;
     254    m_changrplist = ChannelGroup::GetChannelGroups();
    243255
    244256    m_context = 0;
    245257
     
    252264    infoRect = QRect(0, 0, 0, 0);
    253265    curInfoRect = QRect(0, 0, 0, 0);
    254266    videoRect = QRect(0, 0, 0, 0);
     267    changrpRect = QRect(0, 0, 0, 0);
    255268
    256269    jumpToChannelEnabled =
    257270        gContext->GetNumSetting("EPGEnableJumpToChannel", 1);
     
    274287            EmbedTVWindow();
    275288    }
    276289
    277     showFavorites = gContext->GetNumSetting("EPGShowFavorites", 0);
    278290    gridfilltype = gContext->GetNumSetting("EPGFillType", UIGuideType::Alpha);
    279291    if (gridfilltype < (int)UIGuideType::Alpha)
    280292    { // update old settings to new fill types
     
    331343            container->SetDrawFontShadow(false);
    332344    }
    333345
     346    container = theme->GetSet("channel_group");
     347    if (container)
     348    {
     349        UITextType *type = (UITextType *)container->GetType("changroup");
     350        QString changroup;
     351       
     352        changroup = ChannelGroup::GetChannelGroupName(m_changrplist, m_changrpid);
     353       
     354        if (type)
     355            type->SetText(changroup);
     356    }
     357
    334358    channelOrdering = gContext->GetSetting("ChannelOrdering", "channum");
    335359    dateformat = gContext->GetSetting("ShortDateFormat", "ddd d");
    336360    unknownTitle = gContext->GetSetting("UnknownTitle", "Unknown");
     
    703727        curInfoRect = area;
    704728    if (name.toLower() == "current_video")
    705729        videoRect = area;
     730    if (name.toLower() == "channel_group")
     731        changrpRect = area;
    706732}
    707733
    708734PixmapChannel *GuideGrid::GetChannelInfo(uint chan_idx, int sel)
     
    891917    m_channelInfoIdx.clear();
    892918    m_currentStartChannel = 0;
    893919
    894     DBChanList channels = ChannelUtil::GetChannels(0, true);
     920    DBChanList channels = ChannelUtil::GetChannels(0, true, "", m_changrpid);
    895921    ChannelUtil::SortChannels(channels, channelOrdering, false);
    896922
    897     if (showFavorites)
    898     {
    899         DBChanList tmp;
    900         for (uint i = 0; i < channels.size(); i++)
    901         {
    902             if (channels[i].favorite)
    903                 tmp.push_back(channels[i]);
    904         }
    905 
    906         if (!tmp.empty())
    907             channels = tmp;
    908     }
    909 
    910923    typedef vector<uint> uint_list_t;
    911924    QMap<QString,uint_list_t> channum_to_index_map;
    912925    QMap<QString,uint_list_t> callsign_to_index_map;
     
    11321145    }
    11331146}
    11341147
     1148void GuideGrid::fillChanGroupInfo(void)
     1149{
     1150    LayerSet   *container = NULL;
     1151    UITextType *type = NULL;
     1152   
     1153    container = theme->GetSet("channel_group");
     1154    if (container)
     1155    {
     1156        type = (UITextType *)container->GetType("changroup");
     1157        QString changroup;
     1158       
     1159        changroup = ChannelGroup::GetChannelGroupName(m_changrplist, m_changrpid);
     1160       
     1161        if (type)
     1162            type->SetText(changroup);
     1163    }
     1164}
     1165
    11351166void GuideGrid::fillProgramRowInfos(unsigned int row)
    11361167{
    11371168    LayerSet *container = NULL;
     
    14091440        paintPrograms(&p);
    14101441    if (r.intersects(curInfoRect))
    14111442        paintCurrentInfo(&p);
     1443    if (r.intersects(changrpRect))
     1444        paintChanGroupInfo(&p);
    14121445
    14131446    // if jumpToChannel has its own rect, use that;
    14141447    // otherwise use the date's rect
     
    15461579    p->drawPixmap(dr.topLeft(), pix);
    15471580}
    15481581
     1582void GuideGrid::paintChanGroupInfo(QPainter *p)
     1583{
     1584    QRect dr = changrpRect;
     1585    QPixmap pix(dr.size());
     1586    pix.fill(this, dr.topLeft());
     1587    QPainter tmp(&pix);
     1588
     1589    LayerSet *container = NULL;
     1590    container = theme->GetSet("channel_group");
     1591    if (container)
     1592    {
     1593        container->Draw(&tmp, 1, m_context);
     1594        container->Draw(&tmp, 2, m_context);
     1595        container->Draw(&tmp, 3, m_context);
     1596        container->Draw(&tmp, 4, m_context);
     1597        container->Draw(&tmp, 5, m_context);
     1598        container->Draw(&tmp, 6, m_context);
     1599        container->Draw(&tmp, 7, m_context);
     1600        container->Draw(&tmp, 8, m_context);
     1601    }
     1602    tmp.end();
     1603    p->drawPixmap(dr.topLeft(), pix);
     1604}
     1605
    15491606bool GuideGrid::paintChannels(QPainter *p)
    15501607{
    15511608    QRect cr = channelRect;
     
    16411698        }
    16421699
    16431700        QString tmpChannelFormat = channelFormat;
    1644         if (chinfo->favorite > 0)
    1645         {
    1646             tmpChannelFormat.insert(
    1647                 tmpChannelFormat.indexOf('<'), "<MARK:fav>");
    1648         }
    16491701
    16501702        if (unavailable)
    16511703        {
     
    16811733        }
    16821734    }
    16831735
     1736    if (m_channelInfos.size() == 0)
     1737    {
     1738       // if the user has selected a channel group with no channels
     1739       // Reset the text and icon. This will display one blank line
     1740       // to show that the channel group has no channels
     1741       if (type)
     1742       {
     1743         type->SetText(0, "");
     1744         type->ResetImage(0);
     1745       }
     1746    }
     1747
    16841748    if (container)
    16851749    {
    16861750        container->Draw(&tmp, 1, m_context);
     
    18161880
    18171881void GuideGrid::toggleGuideListing()
    18181882{
    1819     showFavorites = (!showFavorites);
    1820     generateListings();
     1883    int oldchangrpid = m_changrpid;
     1884   
     1885    m_changrpid = ChannelGroup::GetNextChannelGroup(m_changrplist, oldchangrpid);
     1886   
     1887    if (oldchangrpid != m_changrpid)
     1888      generateListings();
     1889     
     1890    fillChanGroupInfo();
     1891    update(changrpRect);
    18211892}
    18221893
    18231894void GuideGrid::generateListings()
     
    18361907    update(fullRect);
    18371908}
    18381909
     1910int GuideGrid::SelectChannelGroup()
     1911{
     1912    if (m_changrplist.empty())
     1913    {
     1914      MythPopupBox::showOkPopup(gContext->GetMainWindow(), "",
     1915                                "You don't have any channel groups defined");
     1916
     1917      return -1;
     1918    }
     1919   
     1920    MythPopupBox *popup = new MythPopupBox(gContext->GetMainWindow(), "SelectChannelGroup Popup");
     1921    popup->addLabel("Select Channel Group");
     1922
     1923    for (uint i = 0; i < m_changrplist.size(); i++)
     1924      popup->addButton(m_changrplist[i].name);
     1925
     1926    popup->addButton(tr("Cancel"))->setFocus();
     1927
     1928    DialogCode result = popup->ExecPopup();
     1929   
     1930    popup->deleteLater();
     1931
     1932    // If the user cancelled, return a special value
     1933    if (result == MythDialog::Rejected)
     1934      return -1;
     1935    else
     1936      return m_changrplist[result - kDialogCodeListStart].grpid;
     1937}
     1938
    18391939void GuideGrid::toggleChannelFavorite()
    18401940{
    1841     MSqlQuery query(MSqlQuery::InitCon());
     1941    int grpid;
    18421942
     1943    if (m_changrpid == -1)
     1944    {
     1945      grpid = SelectChannelGroup();
     1946     
     1947      if (grpid == -1)
     1948        return;
     1949    }
     1950    else
     1951      grpid = m_changrpid;
     1952
    18431953    // Get current channel id, and make sure it exists...
    18441954    int chanNum = m_currentRow + m_currentStartChannel;
    18451955    if (chanNum >= (int)m_channelInfos.size())
     
    18501960        chanNum = 0;
    18511961
    18521962    PixmapChannel *ch = GetChannelInfo(chanNum);
    1853     uint favid  = ch->favorite;
    18541963    uint chanid = ch->chanid;
    18551964
    1856     if (favid > 0)
    1857     {
    1858         query.prepare("DELETE FROM favorites WHERE favid = :FAVID ;");
    1859         query.bindValue(":FAVID", favid);
    1860         query.exec();
    1861     }
    1862     else
    1863     {
    1864         // We have no favorites record...Add one to toggle...
    1865         query.prepare("INSERT INTO favorites (chanid) VALUES (:FAVID);");
    1866         query.bindValue(":FAVID", chanid);
    1867         query.exec();
    1868     }
    1869 
    1870     if (showFavorites)
     1965    if (m_changrpid == -1)
     1966        // If currently viewing all channels, allow to add only not delete
     1967        ChannelGroup::ToggleChannel(chanid, grpid, false);
     1968     else
     1969        // Only allow delete if viewing the favorite group in question
     1970        ChannelGroup::ToggleChannel(chanid, grpid, true);
     1971     
     1972    // If viewing favorites, refresh because a channel was removed
     1973    if (m_changrpid != -1)
    18711974        generateListings();
    1872     else
    1873     {
    1874         int maxchannel = 0;
    1875         DISPLAY_CHANS = desiredDisplayChans;
    1876         fillChannelInfos(false);
    1877         maxchannel = max((int)GetChannelCount() - 1, 0);
    1878         DISPLAY_CHANS = min(DISPLAY_CHANS, maxchannel + 1);
    1879 
    1880         repaint(channelRect);
    1881     }
    18821975}
    18831976
    18841977void GuideGrid::cursorLeft()
  • mythtv/libs/libmythtv/channelutil.cpp

     
    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
     
    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
     
    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       */
     
    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        {
     
    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}
  • mythtv/libs/libmythtv/tv_play.cpp

     
    347347
    348348    bool allowrerecord = tv->getAllowRerecord();
    349349    bool deleterecording = tv->getRequestDelete();
     350   
     351    tv->SaveChannelGroup();
    350352
    351353    delete tv;
    352354
     
    422424            "in the program guide", "0");
    423425    REG_KEY("TV Frontend", "GUIDE", "Show the Program Guide", "S");
    424426    REG_KEY("TV Frontend", "FINDER", "Show the Program Finder", "#");
    425     REG_KEY("TV Frontend", "NEXTFAV", "Toggle showing all channels or just "
    426             "favorites in the program guide.", "/");
     427    REG_KEY("TV Frontend", "NEXTFAV", "Cycle through channel groups and all channels "
     428            "in the program guide.", "/,S");
    427429    REG_KEY("TV Frontend", "CHANUPDATE", "Switch channels without exiting "
    428430            "guide in Live TV mode.", "X");
    429431    REG_KEY("TV Frontend", "VOLUMEDOWN", "Volume down", "[,{,F10,Volume Down");
     
    788790    osd_general_timeout  = gContext->GetNumSetting("OSDGeneralTimeout", 2);
    789791    osd_prog_info_timeout= gContext->GetNumSetting("OSDProgramInfoTimeout", 3);
    790792    tryUnflaggedSkip     = gContext->GetNumSetting("TryUnflaggedSkip", 0);
     793    channel_group_id     = gContext->GetNumSetting("ChannelGroupDefault", -1);
     794    browse_changrp       = gContext->GetNumSetting("BrowseChannelGroup", 0);
    791795    smartForward         = gContext->GetNumSetting("SmartForward", 0);
    792796    stickykeys           = gContext->GetNumSetting("StickyKeys");
    793797    ff_rew_repos         = gContext->GetNumSetting("FFRewReposTime", 100)/100.0;
     
    802806    if (!feVBI.isEmpty())
    803807        vbimode = VBIMode::Parse(gContext->GetSetting(feVBI));
    804808
     809    channel_group_id     = gContext->GetNumSetting("ChannelGroupDefault", -1);
     810    browse_changrp       = gContext->GetNumSetting("BrowseChannelGroup", 0);
     811   
     812    if (browse_changrp && (channel_group_id > -1))
     813    {
     814      m_channellist = ChannelUtil::GetChannels(0, true, "channum, callsign", channel_group_id);
     815      ChannelUtil::SortChannels(m_channellist, "channum", true);
     816    }
     817   
     818    m_changrplist  = ChannelGroup::GetChannelGroups();
     819
    805820    if (createWindow)
    806821    {
    807822        MythMainWindow *mainWindow = gContext->GetMainWindow();
     
    967982    VERBOSE(VB_PLAYBACK, "TV::~TV() -- end");
    968983}
    969984
     985void TV::SaveChannelGroup(void)
     986{
     987    int changrpid             = gContext->GetNumSetting("ChannelGroupDefault", -1);
     988    int remember_last_changrp = gContext->GetNumSetting("ChannelGroupRememberLast", 0);
     989 
     990    if (remember_last_changrp && (changrpid != channel_group_id))
     991       gContext->SaveSetting("ChannelGroupDefault", channel_group_id);
     992}
     993
    970994/**
    971995 * \brief get tv state of active player context
    972996 */
     
    62326256
    62336257void TV::ToggleChannelFavorite(PlayerContext *ctx)
    62346258{
    6235     if (ctx->recorder)
    6236         ctx->recorder->ToggleChannelFavorite();
     6259//    if (ctx->recorder)
     6260//        ctx->recorder->ToggleChannelFavorite();
    62376261}
    62386262
    62396263QString TV::GetQueuedInput(void) const
     
    64886512{
    64896513    bool muted = false;
    64906514
     6515    if ((browse_changrp || (direction == CHANNEL_DIRECTION_FAVORITE)) &&
     6516        (channel_group_id > -1) && (direction != CHANNEL_DIRECTION_SAME))
     6517    {
     6518        uint chanid;
     6519       
     6520        // Collect channel info
     6521        //DEBUG
     6522        //pbinfoLock.lock();
     6523        ctx->LockPlayingInfo(__FILE__, __LINE__);
     6524        uint old_chanid  = ctx->playingInfo->chanid.toUInt();
     6525        ctx->LockPlayingInfo(__FILE__, __LINE__);
     6526//        pbinfoLock.unlock();
     6527 
     6528        chanid = ChannelUtil::GetNextChannel(m_channellist, old_chanid, 0, direction);
     6529 
     6530        ChangeChannel(ctx, chanid, "");     
     6531        return;
     6532    }
     6533    else if (direction == CHANNEL_DIRECTION_FAVORITE)
     6534    {
     6535        direction = CHANNEL_DIRECTION_UP;
     6536    }
     6537
    64916538    QString oldinputname = ctx->recorder->GetInput();
    64926539
    64936540    ctx->LockDeleteNVP(__FILE__, __LINE__);
     
    76647711    // Actually show the pop-up UI
    76657712    DBChanList changeChannel;
    76667713    ProgramInfo *nextProgram = NULL;
     7714    int changrpid = channel_group_id;
    76677715    switch (editType)
    76687716    {
    76697717        case kScheduleProgramGuide:
     
    76717719            TV *player = (pause_active) ? NULL : this;
    76727720            changeChannel = GuideGrid::Run(
    76737721                chanid, channum, false, player,
    7674                 isLiveTV && player && allowEPG);
     7722                isLiveTV && player && allowEPG, &changrpid);
    76757723            break;
    76767724        }
    76777725        case kScheduleProgramFinder:
     
    77107758    actx = GetPlayerReadLock(-1, __FILE__, __LINE__);
    77117759    StopEmbedding(actx);               // Undo any embedding
    77127760    DoSetPauseState(actx, was_paused); // Restore pause states
     7761   
     7762    // if channel group was changed in EPG update local info
     7763    if ((changrpid != channel_group_id) && (editType == kScheduleProgramGuide))
     7764    {
     7765        channel_group_id = changrpid;
     7766       
     7767        if (browse_changrp)
     7768        {
     7769            VERBOSE(VB_IMPORTANT, LOC +
     7770               QString("Reloading channel group list for %1").arg(channel_group_id));
     7771       
     7772            m_channellist = ChannelUtil::GetChannels(0, true, "channum, callsign", channel_group_id);
     7773            ChannelUtil::SortChannels(m_channellist, "channum", true);
     7774        }
     7775    }
     7776
    77137777    // If user selected a new channel in the EPG, change to that channel
    77147778    if (isLiveTV && changeChannel.size())
    77157779        ChangeChannel(actx, changeChannel);
     
    85598623{
    85608624    if (!browsemode)
    85618625        BrowseStart(ctx);
     8626   
     8627    VERBOSE(VB_IMPORTANT,"In BrowseDispInfo");
     8628    // if browsing channel groups is enabled or direction if BROWSE_FAVORITES
     8629    // Then pick the next channel in the channel group list to browse
     8630    // If channel group is ALL CHANNELS (-1), then bypass picking from
     8631    // the channel group list
     8632    if ((browse_changrp || (direction == BROWSE_FAVORITE)) &&
     8633        (channel_group_id > -1) && (direction != BROWSE_SAME) &&
     8634        (direction != BROWSE_RIGHT) && (direction != BROWSE_LEFT))
     8635    {
     8636        uint chanid;
     8637        int  dir;
     8638     
     8639        if ( (direction == BROWSE_UP) || (direction == BROWSE_FAVORITE) )
     8640            dir = CHANNEL_DIRECTION_UP;
     8641        else if (direction == BROWSE_DOWN)
     8642            dir = CHANNEL_DIRECTION_DOWN;
     8643        else // this should never happen, but just in case
     8644            dir = direction;
     8645         
     8646        chanid = ChannelUtil::GetNextChannel(m_channellist, browsechanid, 0, dir);
     8647        VERBOSE(VB_IMPORTANT, QString("Get channel: %1").arg(chanid));
     8648        browsechanid  = chanid;
     8649        browsechannum = QString::null;
     8650        direction     = BROWSE_SAME;
     8651    }
     8652    else if ((channel_group_id == -1) && (direction == BROWSE_FAVORITE))
     8653    {
     8654        direction = BROWSE_UP;
     8655    }
    85628656
    85638657    OSD *osd = GetOSDLock(ctx);
    85648658    if (ctx->paused || !osd)
     
    94639557    }
    94649558    else if (action == "GUIDE")
    94659559        EditSchedule(actx, kScheduleProgramGuide);
     9560    else if (action.left(10) == "CHANGROUP_")
     9561        processChanGroupEntry(action);
    94669562    else if (action == "FINDER")
    94679563        EditSchedule(actx, kScheduleProgramFinder);
    94689564    else if (action == "SCHEDULE")
     
    95699665    ReturnPlayerLock(actx);
    95709666}
    95719667
     9668void TV::processChanGroupEntry(QString action)
     9669{
     9670    if (action == "CHANGROUP_ALL_CHANNELS")
     9671    {
     9672        channel_group_id = -1;
     9673    }
     9674    else
     9675    {
     9676        action.remove("CHANGROUP_");
     9677        channel_group_id = action.toInt();
     9678         
     9679        if (browse_changrp)
     9680        {
     9681           m_channellist = ChannelUtil::GetChannels(0, true, "channum, callsign", channel_group_id);
     9682           ChannelUtil::SortChannels(m_channellist, "channum", true);
     9683        }
     9684    }
     9685}
     9686
    95729687void TV::ShowOSDTreeMenu(const PlayerContext *ctx)
    95739688{
    95749689    int osdMenuCount = osdMenuEntries->GetCount();
     
    96449759    }
    96459760    else if (category == "GUIDE")
    96469761        new OSDGenericTree(treeMenu, tr("Program Guide"), "GUIDE");
     9762    else if (category == "CHANGROUP")
     9763        FillMenuChanGroups(ctx, treeMenu);
    96479764    else if (category ==  "PIP")
    96489765        FillMenuPxP(ctx, treeMenu);
    96499766    else if (category == "INPUTSWITCHING")
     
    1019210309    return true;
    1019310310}
    1019410311
     10312void TV::FillMenuChanGroups(
     10313    const PlayerContext *ctx, OSDGenericTree *treeMenu) const
     10314{
     10315    OSDGenericTree *cg_item = new OSDGenericTree(treeMenu, tr("Channel Groups"),
     10316                                                 "CHANGROUP");
     10317    new OSDGenericTree(cg_item, tr("All Channels"), "CHANGROUP_ALL_CHANNELS",
     10318                                 (channel_group_id == -1) ? 1 : 0,
     10319                                 NULL, "CHANNELGROUP");
     10320
     10321    ChannelGroupList::const_iterator it;
     10322       
     10323    for (it = m_changrplist.begin(); it != m_changrplist.end(); ++it)
     10324    {
     10325        QString name = QString("CHANGROUP_%1").arg(it->grpid);
     10326        new OSDGenericTree(cg_item, it->name, name,
     10327                           ((int)(it->grpid) == channel_group_id) ? 1 : 0,
     10328                           NULL, "CHANNELGROUP");
     10329    }       
     10330}
     10331
    1019510332void TV::ToggleAutoExpire(PlayerContext *ctx)
    1019610333{
    1019710334    QString desc = QString::null;
  • mythtv/libs/libmythtv/remoteencoder.h

     
    5050        PictureAdjustType type, PictureAttribute attr, bool up);
    5151    void ChangeChannel(int channeldirection);
    5252    void ChangeDeinterlacer(int deint_mode);
    53     void ToggleChannelFavorite(void);
    5453    void SetChannel(QString channel);
    5554    int  SetSignalMonitoringRate(int msec, bool notifyFrontend = true);
    5655    uint GetSignalLockTimeout(QString input);
  • mythtv/libs/libmythtv/tvosdmenuentry.cpp

     
    192192    curMenuEntries.append(
    193193        new TVOSDMenuEntry("GUIDE",                     1,  1,  0,  0, "Program Guide"));
    194194    curMenuEntries.append(
     195        new TVOSDMenuEntry("CHANGROUP",                     1,  1,  0,  0, "Channel Groups"));
     196    curMenuEntries.append(
    195197        new TVOSDMenuEntry("PIP",                          1,  1,  1,  -1, "Picture-in-Picture"));
    196198    curMenuEntries.append(
    197199        new TVOSDMenuEntry("INPUTSWITCHING",   1,  -1,  -1,  -1, "Change TV Input"));
  • mythtv/libs/libmythtv/remoteencoder.cpp

     
    402402    return (lastinput.isEmpty()) ? "Error" : lastinput;
    403403}
    404404
    405 void RemoteEncoder::ToggleChannelFavorite(void)
    406 {
    407     QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum) );
    408     strlist << "TOGGLE_CHANNEL_FAVORITE";
    409 
    410     SendReceiveStringList(strlist);
    411 }
    412 
    413405void RemoteEncoder::ChangeChannel(int channeldirection)
    414406{
    415407    QStringList strlist( QString("QUERY_RECORDER %1").arg(recordernum) );
  • mythtv/libs/libmythtv/tv_rec.cpp

     
    29152915    }
    29162916}
    29172917
    2918 /** \fn TVRec::ToggleChannelFavorite()
    2919  *  \brief Toggles whether the current channel should be on our favorites list.
    2920  */
    2921 void TVRec::ToggleChannelFavorite(void)
    2922 {
    2923     QMutexLocker lock(&stateChangeLock);
    2924 
    2925     if (!channel)
    2926         return;
    2927 
    2928     // Get current channel id...
    2929     uint    sourceid = channel->GetCurrentSourceID();
    2930     QString channum  = channel->GetCurrentName();
    2931     uint chanid = ChannelUtil::GetChanID(sourceid, channum);
    2932 
    2933     if (!chanid)
    2934     {
    2935         VERBOSE(VB_IMPORTANT, LOC_ERR + QString(
    2936                 "Channel: \'%1\' was not found in the database.\n"
    2937                 "\t\t\tMost likely, your DefaultTVChannel setting is wrong.\n"
    2938                 "\t\t\tCould not toggle favorite.").arg(channum));
    2939         return;
    2940     }
    2941 
    2942     // Check if favorite exists for that chanid...
    2943     MSqlQuery query(MSqlQuery::InitCon());
    2944     query.prepare(
    2945         "SELECT favorites.favid "
    2946         "FROM favorites "
    2947         "WHERE favorites.chanid = :CHANID "
    2948         "LIMIT 1");
    2949     query.bindValue(":CHANID", chanid);
    2950 
    2951     if (!query.exec() || !query.isActive())
    2952     {
    2953         MythDB::DBError("togglechannelfavorite", query);
    2954     }
    2955     else if (query.size() > 0)
    2956     {
    2957         // We have a favorites record...Remove it to toggle...
    2958         query.next();
    2959         QString favid = query.value(0).toString();
    2960         query.prepare(
    2961             QString("DELETE FROM favorites "
    2962                     "WHERE favid = '%1'").arg(favid));
    2963         query.exec();
    2964         VERBOSE(VB_RECORD, LOC + "Removing Favorite.");
    2965     }
    2966     else
    2967     {
    2968         // We have no favorites record...Add one to toggle...
    2969         query.prepare(
    2970             QString("INSERT INTO favorites (chanid) "
    2971                     "VALUES ('%1')").arg(chanid));
    2972         query.exec();
    2973         VERBOSE(VB_RECORD, LOC + "Adding Favorite.");
    2974     }
    2975 }
    2976 
    29772918/** \fn TVRec::ChangePictureAttribute(PictureAdjustType,PictureAttribute,bool)
    29782919 *  \brief Returns current value [0,100] if it succeeds, -1 otherwise.
    29792920 *
  • mythtv/programs/mythfrontend/globalsettings.cpp

     
    31473147    return gc;
    31483148}
    31493149
    3150 static HostCheckBox *EPGShowFavorites()
    3151 {
    3152     HostCheckBox *gc = new HostCheckBox("EPGShowFavorites");
    3153     gc->setLabel(QObject::tr("Only display 'favorite' channels"));
    3154     gc->setHelpText(QObject::tr("If enabled, the EPG will initially display "
    3155                     "only the channels marked as favorites. Pressing "
    3156                     "\"4\" will toggle between displaying favorites and all "
    3157                     "channels."));
    3158     gc->setValue(false);
    3159     return gc;
    3160 }
    31613150
    31623151static HostSpinBox *EPGChanDisplay()
    31633152{
     
    31853174    return gc;
    31863175}
    31873176
     3177static HostCheckBox *ChannelGroupRememberLast()
     3178{
     3179    HostCheckBox *gc = new HostCheckBox("ChannelGroupRememberLast");
     3180    gc->setLabel(QObject::tr("Remember last channel group"));
     3181    gc->setHelpText(QObject::tr("If enabled, the EPG will initially display "
     3182                    "only the channels from the last channel group selected. Pressing "
     3183                    "\"4\" will toggle channel group."));
     3184    gc->setValue(false);
     3185    return gc;
     3186}
     3187
     3188static HostComboBox *ChannelGroupDefault()
     3189{
     3190    HostComboBox *gc = new HostComboBox("ChannelGroupDefault");
     3191    gc->setLabel(QObject::tr("Default channel group"));
     3192
     3193    ChannelGroupList changrplist;
     3194
     3195    changrplist = ChannelGroup::GetChannelGroups();
     3196
     3197    gc->addSelection(QObject::tr("All Channels"), "-1");
     3198
     3199    ChannelGroupList::iterator it;
     3200
     3201    for (it = changrplist.begin(); it < changrplist.end(); ++it)
     3202       gc->addSelection(it->name, QString("%1").arg(it->grpid));
     3203
     3204    gc->setHelpText(QObject::tr("Default channel group to be shown in the the EPG"
     3205                    "Pressing "
     3206                    "\"4\" will toggle channel group."));
     3207    gc->setValue(false);
     3208    return gc;
     3209}
     3210
     3211static HostCheckBox *BrowseChannelGroup()
     3212{
     3213    HostCheckBox *gc = new HostCheckBox("BrowseChannelGroup");
     3214    gc->setLabel(QObject::tr("Browse/Change channels from Channel Group"));
     3215    gc->setHelpText(QObject::tr("If enabled, LiveTV will browse or change channels "
     3216                    "from the selected channel group. \"All Channels\" "
     3217                    "channel group may be selected to browse all channels."));
     3218    gc->setValue(false);
     3219    return gc;
     3220}
     3221
     3222// Channel Group Settings
     3223class ChannelGroupSettings : public TriggeredConfigurationGroup
     3224{
     3225  public:
     3226    ChannelGroupSettings() : TriggeredConfigurationGroup(false, true, false, false)
     3227    {
     3228         setLabel(QObject::tr("Remember last channel group"));
     3229         setUseLabel(false);
     3230
     3231         Setting* RememberChanGrpEnabled = ChannelGroupRememberLast();
     3232         addChild(RememberChanGrpEnabled);
     3233         setTrigger(RememberChanGrpEnabled);
     3234
     3235         ConfigurationGroup* settings = new VerticalConfigurationGroup(false);
     3236         settings->addChild(ChannelGroupDefault());
     3237         addTarget("0", settings);
     3238
     3239         // show nothing if RememberChanGrpEnabled is on
     3240         addTarget("1", new VerticalConfigurationGroup(true));
     3241     };
     3242};
     3243
    31883244// General RecPriorities settings
    31893245
    31903246static GlobalCheckBox *GRSchedMoveHigher()
     
    49525008    general2->addChild(CategoryOverTimeSettings());
    49535009    addChild(general2);
    49545010
     5011    VerticalConfigurationGroup* changrp = new VerticalConfigurationGroup(false);
     5012    changrp->setLabel(QObject::tr("General (Channel Groups)"));
     5013    ChannelGroupSettings *changroupsettings = new ChannelGroupSettings();
     5014    changrp->addChild(changroupsettings);
     5015    changrp->addChild(BrowseChannelGroup());
     5016    addChild(changrp);
    49555017}
    49565018
    49575019EPGSettings::EPGSettings()
    49585020{
    49595021    VerticalConfigurationGroup* epg = new VerticalConfigurationGroup(false);
    4960     epg->setLabel(QObject::tr("Program Guide") + " 1/2");
     5022    epg->setLabel(QObject::tr("Program Guide") + " 1/3");
    49615023    epg->addChild(EPGFillType());
    49625024    epg->addChild(EPGShowCategoryColors());
    49635025    epg->addChild(EPGShowCategoryText());
    49645026    epg->addChild(EPGScrollType());
    49655027    epg->addChild(EPGShowChannelIcon());
    4966     epg->addChild(EPGShowFavorites());
    49675028    epg->addChild(WatchTVGuide());
    49685029    epg->addChild(EPGChanDisplay());
    49695030    epg->addChild(EPGTimeDisplay());
    49705031    addChild(epg);
    49715032
    49725033    VerticalConfigurationGroup* gen = new VerticalConfigurationGroup(false);
    4973     gen->setLabel(QObject::tr("Program Guide") + " 2/2");
     5034    gen->setLabel(QObject::tr("Program Guide") + " 2/3");
    49745035    gen->addChild(UnknownTitle());
    49755036    gen->addChild(UnknownCategory());
    49765037    gen->addChild(DefaultTVChannel());
    49775038    gen->addChild(SelectChangesChannel());
    49785039    gen->addChild(EPGRecThreshold());
    49795040    gen->addChild(EPGEnableJumpToChannel());
    4980     addChild(gen);
     5041    addChild(gen);   
    49815042}
    49825043
    49835044GeneralRecPrioritiesSettings::GeneralRecPrioritiesSettings()
  • mythtv/programs/mythfrontend/main.cpp

     
    5151#include "lcddevice.h"
    5252#include "langsettings.h"
    5353#include "mythcommandlineparser.h"
     54#include "channelgroupsettings.h"
    5455
    5556#include "myththemedmenu.h"
    5657#include "myththemebase.h"
     
    522523        EPGSettings settings;
    523524        settings.exec();
    524525    }
     526    else if (sel == "settings channelgroups")
     527    {
     528        ChannelGroupEditor editor;
     529        editor.exec();
     530     }
    525531    else if (sel == "settings generalrecpriorities")
    526532    {
    527533        GeneralRecPrioritiesSettings settings;
  • mythtv/programs/mythbackend/encoderlink.h

     
    111111    vector<InputInfo> GetFreeInputs(const vector<uint> &excluded_cards) const;
    112112    QString GetInput(void) const;
    113113    QString SetInput(QString);
    114     void ToggleChannelFavorite(void);
    115114    void ChangeChannel(int channeldirection);
    116115    void SetChannel(const QString &name);
    117116    int  GetPictureAttribute(PictureAttribute attr);
  • mythtv/programs/mythbackend/mainserver.cpp

     
    32573257        ret = (ret.isEmpty()) ? "UNKNOWN" : ret;
    32583258        retlist << ret;
    32593259    }
    3260     else if (command == "TOGGLE_CHANNEL_FAVORITE")
    3261     {
    3262         enc->ToggleChannelFavorite();
    3263         retlist << "ok";
    3264     }
    32653260    else if (command == "CHANGE_CHANNEL")
    32663261    {
    32673262        int direction = slist[2].toInt();
  • mythtv/programs/mythbackend/encoderlink.cpp

     
    723723    return QString::null;
    724724}
    725725
    726 /** \fn EncoderLink::ToggleChannelFavorite(void)
    727  *  \brief Toggles whether the current channel should be on our favorites list.
    728  *         <b>This only works on local recorders.</b>
    729  *  \return -1 if query does not succeed, otherwise.
    730  */
    731 void EncoderLink::ToggleChannelFavorite(void)
    732 {
    733     if (local)
    734         tv->ToggleChannelFavorite();
    735     else
    736         VERBOSE(VB_IMPORTANT, "Should be local only query: ToggleChannelFavorite");
    737 }
    738 
    739726/** \fn EncoderLink::ChangeChannel(int)
    740727 *  \brief Changes to the next or previous channel.
    741728 *         <b>This only works on local recorders.</b>
  • mythtv/libs/libmythtv/channelgroupsettings.h

     
     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
  • mythtv/libs/libmythtv/channelgroup.h

     
     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
  • mythtv/libs/libmythtv/channelgroup.cpp

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

     
     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}