MythTV  master
guide.cpp
Go to the documentation of this file.
1 // Program Name: guide.cpp
3 // Created : Mar. 7, 2011
4 //
5 // Copyright (c) 2011 David Blain <dblain@mythtv.org>
6 //
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 //
25 
26 #include <cmath>
27 
28 #include "guide.h"
29 
30 #include "compat.h"
31 #include "mythversion.h"
32 #include "mythcorecontext.h"
33 #include "scheduler.h"
34 #include "autoexpire.h"
35 #include "channelutil.h"
36 #include "channelgroup.h"
37 #include "storagegroup.h"
38 
39 #include "mythlogging.h"
40 
41 extern AutoExpire *expirer;
42 extern Scheduler *sched;
43 
45 //
47 
48 DTC::ProgramGuide *Guide::GetProgramGuide( const QDateTime &rawStartTime,
49  const QDateTime &rawEndTime,
50  bool bDetails,
51  int nChannelGroupId,
52  int nStartIndex,
53  int nCount,
54  bool bWithInvisible)
55 {
56  if (!rawStartTime.isValid())
57  throw QString( "StartTime is invalid" );
58 
59  if (!rawEndTime.isValid())
60  throw QString( "EndTime is invalid" );
61 
62  QDateTime dtStartTime = rawStartTime.toUTC();
63  QDateTime dtEndTime = rawEndTime.toUTC();
64 
65  if (dtEndTime < dtStartTime)
66  throw QString( "EndTime is before StartTime");
67 
68  if (nStartIndex <= 0)
69  nStartIndex = 0;
70 
71  if (nCount <= 0)
72  nCount = 20000;
73 
74  // ----------------------------------------------------------------------
75  // Load the channel list
76  // ----------------------------------------------------------------------
77 
78  uint nTotalAvailable = 0;
79  ChannelInfoList chanList = ChannelUtil::LoadChannels(nStartIndex, nCount,
80  nTotalAvailable,
81  !bWithInvisible,
84  0,
85  nChannelGroupId);
86 
87  // ----------------------------------------------------------------------
88  // Build SQL statement for Program Listing
89  // ----------------------------------------------------------------------
90 
91  ProgramList schedList;
92  MSqlBindings bindings;
93 
94  QString sWhere = "program.chanid = :CHANID "
95  "AND program.endtime >= :STARTDATE "
96  "AND program.starttime < :ENDDATE "
97  "AND program.starttime >= :STARTDATELIMIT "
98  "AND program.manualid = 0"; // Omit 'manual' recordings scheds
99 
100 #if 0
101  QString sGroupBy = "program.starttime, channel.channum,"
102  "channel.callsign, program.title";
103 #endif
104 
105  QString sOrderBy = "program.starttime";
106 
107  bindings[":STARTDATE" ] = dtStartTime;
108  bindings[":STARTDATELIMIT"] = dtStartTime.addDays(-1);
109  bindings[":ENDDATE" ] = dtEndTime;
110 
111  // ----------------------------------------------------------------------
112  // Get all Pending Scheduled Programs
113  // ----------------------------------------------------------------------
114 
115  // NOTE: Fetching this information directly from the schedule is
116  // significantly faster than using ProgramInfo::LoadFromScheduler()
117  auto *scheduler = dynamic_cast<Scheduler*>(gCoreContext->GetScheduler());
118  if (scheduler)
119  scheduler->GetAllPending(schedList);
120 
121  // ----------------------------------------------------------------------
122  // Build Response
123  // ----------------------------------------------------------------------
124 
125  auto *pGuide = new DTC::ProgramGuide();
126 
127  ChannelInfoList::iterator chan_it;
128  for (chan_it = chanList.begin(); chan_it != chanList.end(); ++chan_it)
129  {
130  // Create ChannelInfo Object
131  DTC::ChannelInfo *pChannel = pGuide->AddNewChannel();
132  FillChannelInfo( pChannel, (*chan_it), bDetails );
133 
134  // Load the list of programmes for this channel
135  ProgramList progList;
136  bindings[":CHANID"] = (*chan_it).m_chanId;
137  LoadFromProgram( progList, sWhere, sOrderBy, sOrderBy, bindings,
138  schedList );
139 
140  // Create Program objects and add them to the channel object
141  ProgramList::iterator progIt;
142  for( progIt = progList.begin(); progIt != progList.end(); ++progIt)
143  {
144  DTC::Program *pProgram = pChannel->AddNewProgram();
145  FillProgramInfo( pProgram, *progIt, false, bDetails, false ); // No cast info
146  }
147  }
148 
149  // ----------------------------------------------------------------------
150 
151  pGuide->setStartTime ( dtStartTime );
152  pGuide->setEndTime ( dtEndTime );
153  pGuide->setDetails ( bDetails );
154 
155  pGuide->setStartIndex ( nStartIndex );
156  pGuide->setCount ( chanList.size() );
157  pGuide->setTotalAvailable( nTotalAvailable );
158  pGuide->setAsOf ( MythDate::current() );
159 
160  pGuide->setVersion ( MYTH_BINARY_VERSION );
161  pGuide->setProtoVer ( MYTH_PROTO_VERSION );
162 
163  return pGuide;
164 }
165 
167 //
169 
171  int nCount,
172  const QDateTime& rawStartTime,
173  const QDateTime& rawEndTime,
174  int nChanId,
175  const QString& sTitleFilter,
176  const QString& sCategoryFilter,
177  const QString& sPersonFilter,
178  const QString& sKeywordFilter,
179  bool bOnlyNew,
180  bool bDetails,
181  const QString &sSort,
182  bool bDescending,
183  bool bWithInvisible)
184 {
185  if (!rawStartTime.isNull() && !rawStartTime.isValid())
186  throw QString( "StartTime is invalid" );
187 
188  if (!rawEndTime.isNull() && !rawEndTime.isValid())
189  throw QString( "EndTime is invalid" );
190 
191  QDateTime dtStartTime = rawStartTime;
192  const QDateTime& dtEndTime = rawEndTime;
193 
194  if (!rawEndTime.isNull() && dtEndTime < dtStartTime)
195  throw QString( "EndTime is before StartTime");
196 
198 
199 
200  // ----------------------------------------------------------------------
201  // Build SQL statement for Program Listing
202  // ----------------------------------------------------------------------
203 
204  ProgramList progList;
205  ProgramList schedList;
206  MSqlBindings bindings;
207 
208  QString sSQL;
209 
210  if (!sPersonFilter.isEmpty())
211  {
212  sSQL = ", people, credits " // LEFT JOIN
213  "WHERE people.name LIKE :PersonFilter "
214  "AND credits.person = people.person "
215  "AND program.chanid = credits.chanid "
216  "AND program.starttime = credits.starttime AND ";
217  bindings[":PersonFilter"] = QString("%%1%").arg(sPersonFilter);
218  }
219  else
220  sSQL = "WHERE ";
221 
222  if (bOnlyNew)
223  {
224  sSQL = "LEFT JOIN oldprogram ON oldprogram.oldtitle = program.title "
225  + sSQL
226  + "oldprogram.oldtitle IS NULL AND ";
227  }
228 
229  sSQL += "deleted IS NULL AND ";
230 
231  if (!bWithInvisible)
232  sSQL += "visible > 0 AND ";
233 
234  sSQL += "program.manualid = 0 "; // Exclude programmes created purely for 'manual' recording schedules
235 
236  if (nChanId < 0)
237  nChanId = 0;
238 
239  if (nChanId > 0)
240  {
241  sSQL += "AND program.chanid = :ChanId ";
242  bindings[":ChanId"] = nChanId;
243  }
244 
245  if (dtStartTime.isNull())
246  dtStartTime = QDateTime::currentDateTimeUtc();
247 
248  sSQL += " AND program.endtime >= :StartDate ";
249  bindings[":StartDate"] = dtStartTime;
250 
251  if (!dtEndTime.isNull())
252  {
253  sSQL += "AND program.starttime <= :EndDate ";
254  bindings[":EndDate"] = dtEndTime;
255  }
256 
257  if (!sTitleFilter.isEmpty())
258  {
259  sSQL += "AND program.title LIKE :Title ";
260  bindings[":Title"] = QString("%%1%").arg(sTitleFilter);
261  }
262 
263  if (!sCategoryFilter.isEmpty())
264  {
265  sSQL += "AND program.category LIKE :Category ";
266  bindings[":Category"] = sCategoryFilter;
267  }
268 
269  if (!sKeywordFilter.isEmpty())
270  {
271  sSQL += "AND (program.title LIKE :Keyword1 "
272  "OR program.subtitle LIKE :Keyword2 "
273  "OR program.description LIKE :Keyword3) ";
274 
275  QString filter = QString("%%1%").arg(sKeywordFilter);
276  bindings[":Keyword1"] = filter;
277  bindings[":Keyword2"] = filter;
278  bindings[":Keyword3"] = filter;
279  }
280 
281  if (sSort == "starttime")
282  sSQL += "ORDER BY program.starttime "; // NOLINT(bugprone-branch-clone)
283  else if (sSort == "title")
284  sSQL += "ORDER BY program.title ";
285  else if (sSort == "channel")
286  sSQL += "ORDER BY channel.channum ";
287  else if (sSort == "duration")
288  sSQL += "ORDER BY (program.endtime - program.starttime) ";
289  else
290  sSQL += "ORDER BY program.starttime ";
291 
292  if (bDescending)
293  sSQL += "DESC ";
294  else
295  sSQL += "ASC ";
296 
297  // ----------------------------------------------------------------------
298  // Get all Pending Scheduled Programs
299  // ----------------------------------------------------------------------
300 
301  // NOTE: Fetching this information directly from the schedule is
302  // significantly faster than using ProgramInfo::LoadFromScheduler()
303  auto *scheduler = dynamic_cast<Scheduler*>(gCoreContext->GetScheduler());
304  if (scheduler)
305  scheduler->GetAllPending(schedList);
306 
307  // ----------------------------------------------------------------------
308 
309  uint nTotalAvailable = 0;
310  LoadFromProgram( progList, sSQL, bindings, schedList,
311  (uint)nStartIndex, (uint)nCount, nTotalAvailable);
312 
313  // ----------------------------------------------------------------------
314  // Build Response
315  // ----------------------------------------------------------------------
316 
317  auto *pPrograms = new DTC::ProgramList();
318 
319  nCount = (int)progList.size();
320  int nEndIndex = (int)progList.size();
321 
322  for( int n = 0; n < nEndIndex; n++)
323  {
324  ProgramInfo *pInfo = progList[ n ];
325 
326  DTC::Program *pProgram = pPrograms->AddNewProgram();
327 
328  FillProgramInfo( pProgram, pInfo, true, bDetails, false ); // No cast info, loading this takes far too long
329  }
330 
331  // ----------------------------------------------------------------------
332 
333  pPrograms->setStartIndex ( nStartIndex );
334  pPrograms->setCount ( nCount );
335  pPrograms->setTotalAvailable( nTotalAvailable );
336  pPrograms->setAsOf ( MythDate::current() );
337  pPrograms->setVersion ( MYTH_BINARY_VERSION );
338  pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
339 
340  return pPrograms;
341 }
342 
344 //
346 
348  const QDateTime &rawStartTime )
349 
350 {
351  if (!(nChanId > 0))
352  throw QString( "Channel ID is invalid" );
353  if (!rawStartTime.isValid())
354  throw QString( "StartTime is invalid" );
355 
356  QDateTime dtStartTime = rawStartTime.toUTC();
357 
358  // ----------------------------------------------------------------------
359  // -=>TODO: Add support for getting Recorded Program Info
360  // ----------------------------------------------------------------------
361 
362  // Build Response
363 
364  auto *pProgram = new DTC::Program();
365  ProgramInfo *pInfo = LoadProgramFromProgram(nChanId, dtStartTime);
366 
367  FillProgramInfo( pProgram, pInfo, true, true, true );
368 
369  delete pInfo;
370 
371  return pProgram;
372 }
373 
375 //
377 
378 QFileInfo Guide::GetChannelIcon( int nChanId,
379  int nWidth /* = 0 */,
380  int nHeight /* = 0 */ )
381 {
382  // Get Icon file path
383 
384  QString sFileName = ChannelUtil::GetIcon( nChanId );
385 
386  if (sFileName.isEmpty())
387  {
388  LOG(VB_UPNP, LOG_ERR,
389  QString("GetImageFile - ChanId %1 doesn't exist or isn't visible")
390  .arg(nChanId));
391  return QFileInfo();
392  }
393 
394  // ------------------------------------------------------------------
395  // Search for the filename
396  // ------------------------------------------------------------------
397 
398  StorageGroup storage( "ChannelIcons" );
399  QString sFullFileName = storage.FindFile( sFileName );
400 
401  if (sFullFileName.isEmpty())
402  {
403  LOG(VB_UPNP, LOG_ERR,
404  QString("GetImageFile - Unable to find %1.").arg(sFileName));
405 
406  return QFileInfo();
407  }
408 
409  // ----------------------------------------------------------------------
410  // check to see if the file (still) exists
411  // ----------------------------------------------------------------------
412 
413  if ((nWidth == 0) && (nHeight == 0))
414  {
415  if (QFile::exists( sFullFileName ))
416  {
417  return QFileInfo( sFullFileName );
418  }
419 
420  LOG(VB_UPNP, LOG_ERR,
421  QString("GetImageFile - File Does not exist %1.").arg(sFullFileName));
422 
423  return QFileInfo();
424  }
425  // -------------------------------------------------------------------
426 
427  QString sNewFileName = QString( "%1.%2x%3.png" )
428  .arg( sFullFileName )
429  .arg( nWidth )
430  .arg( nHeight );
431 
432  // ----------------------------------------------------------------------
433  // check to see if image is already created.
434  // ----------------------------------------------------------------------
435 
436  if (QFile::exists( sNewFileName ))
437  return QFileInfo( sNewFileName );
438 
439  // ----------------------------------------------------------------------
440  // We need to create it...
441  // ----------------------------------------------------------------------
442 
443  QString sChannelsDirectory = QFileInfo( sNewFileName ).absolutePath();
444 
445  if (!QFileInfo( sChannelsDirectory ).isWritable())
446  {
447  LOG(VB_UPNP, LOG_ERR, QString("GetImageFile - no write access to: %1")
448  .arg( sChannelsDirectory ));
449  return QFileInfo();
450  }
451 
452  auto *pImage = new QImage( sFullFileName );
453 
454  if (!pImage)
455  {
456  LOG(VB_UPNP, LOG_ERR, QString("GetImageFile - can't create image: %1")
457  .arg( sFullFileName ));
458  return QFileInfo();
459  }
460 
461  float fAspect = (float)(pImage->width()) / pImage->height();
462  if (fAspect == 0)
463  {
464  LOG(VB_UPNP, LOG_ERR, QString("GetImageFile - zero aspect"));
465  delete pImage;
466  return QFileInfo();
467  }
468 
469  if ( nWidth == 0 )
470  nWidth = (int)rint(nHeight * fAspect);
471 
472  if ( nHeight == 0 )
473  nHeight = (int)rint(nWidth / fAspect);
474 
475  QImage img = pImage->scaled( nWidth, nHeight, Qt::IgnoreAspectRatio,
476  Qt::SmoothTransformation);
477 
478  if (img.isNull())
479  {
480  LOG(VB_UPNP, LOG_ERR, QString("SaveImageFile - unable to scale. "
481  "See if %1 is really an image.").arg( sFullFileName ));
482  delete pImage;
483  return QFileInfo();
484  }
485 
486  if (!img.save( sNewFileName, "PNG" ))
487  {
488  LOG(VB_UPNP, LOG_ERR, QString("SaveImageFile - failed, %1")
489  .arg( sNewFileName ));
490  delete pImage;
491  return QFileInfo();
492  }
493 
494  delete pImage;
495 
496  return QFileInfo( sNewFileName );
497 }
498 
500 //
502 
504 {
505  ChannelGroupList list = ChannelGroup::GetChannelGroups(bIncludeEmpty);
506  auto *pGroupList = new DTC::ChannelGroupList();
507 
508  ChannelGroupList::iterator it;
509  for (it = list.begin(); it < list.end(); ++it)
510  {
511  DTC::ChannelGroup *pGroup = pGroupList->AddNewChannelGroup();
512  FillChannelGroup(pGroup, (*it));
513  }
514 
515  return pGroupList;
516 }
517 
519 //
521 
522 QStringList Guide::GetCategoryList( ) //int nStartIndex, int nCount)
523 {
524  QStringList catList;
526 
527  query.prepare("SELECT DISTINCT category FROM program WHERE category != '' "
528  "ORDER BY category");
529 
530  if (!query.exec())
531  return catList;
532 
533  while (query.next())
534  {
535  catList << query.value(0).toString();
536  }
537 
538  return catList;
539 }
540 
542 //
544 
545 QStringList Guide::GetStoredSearches( const QString& sType )
546 {
547  QStringList keywordList;
549 
550  RecSearchType iType = searchTypeFromString(sType);
551 
552  if (iType == kNoSearch)
553  {
554  //throw QString( "Invalid Type" );
555  return keywordList;
556  }
557 
558  query.prepare("SELECT DISTINCT phrase FROM keyword "
559  "WHERE searchtype = :TYPE "
560  "ORDER BY phrase");
561  query.bindValue(":TYPE", static_cast<int>(iType));
562 
563  if (!query.exec())
564  return keywordList;
565 
566  while (query.next())
567  {
568  keywordList << query.value(0).toString();
569  }
570 
571  return keywordList;
572 }
573 
575 //
577 
578 bool Guide::AddToChannelGroup ( int nChannelGroupId,
579  int nChanId )
580 {
581  bool bResult = false;
582 
583  if (!(nChanId > 0))
584  throw QString( "Channel ID is invalid" );
585 
586  bResult = ChannelGroup::AddChannel(nChanId, nChannelGroupId);
587 
588  return bResult;
589 }
590 
592 //
594 
595 bool Guide::RemoveFromChannelGroup ( int nChannelGroupId,
596  int nChanId )
597 {
598  bool bResult = false;
599 
600  if (!(nChanId > 0))
601  throw QString( "Channel ID is invalid" );
602 
603  bResult = ChannelGroup::DeleteChannel(nChanId, nChannelGroupId);
604 
605  return bResult;
606 }
MSqlBindings
QMap< QString, QVariant > MSqlBindings
typedef for a map of string -> string bindings for generic queries.
Definition: mythdbcon.h:98
DTC::ChannelInfo::AddNewProgram
Program * AddNewProgram()
Definition: programAndChannel.h:308
Scheduler
Definition: scheduler.h:47
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:783
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:126
FillProgramInfo
void FillProgramInfo(DTC::Program *pProgram, ProgramInfo *pInfo, bool bIncChannel, bool bDetails, bool bIncCast)
Definition: serviceUtil.cpp:44
expirer
AutoExpire * expirer
Definition: backendcontext.cpp:8
MythCoreContext::GetScheduler
MythScheduler * GetScheduler(void)
Definition: mythcorecontext.cpp:1883
LoadProgramFromProgram
ProgramInfo * LoadProgramFromProgram(const uint chanid, const QDateTime &starttime)
Definition: programinfo.cpp:5610
DTC::Program
Definition: programAndChannel.h:146
ChannelUtil::LoadChannels
static ChannelInfoList LoadChannels(uint startIndex, uint count, uint &totalAvailable, bool ignoreHidden=true, OrderBy orderBy=kChanOrderByChanNum, GroupBy groupBy=kChanGroupByChanid, uint sourceID=0, uint channelGroupID=0, bool liveTVOnly=false, const QString &callsign="", const QString &channum="", bool ignoreUntunable=true)
Load channels from database into a list of ChannelInfo objects.
Definition: channelutil.cpp:2405
Guide::GetChannelIcon
QFileInfo GetChannelIcon(int ChanId, int Width, int Height) override
Definition: guide.cpp:378
searchTypeFromString
RecSearchType searchTypeFromString(const QString &type)
Definition: recordingtypes.cpp:329
Guide::GetChannelGroupList
DTC::ChannelGroupList * GetChannelGroupList(bool IncludeEmpty) override
Definition: guide.cpp:503
Guide::RemoveFromChannelGroup
bool RemoveFromChannelGroup(int ChannelGroupId, int ChanId) override
Definition: guide.cpp:595
StorageGroup::FindFile
QString FindFile(const QString &filename)
Definition: storagegroup.cpp:602
FillChannelGroup
void FillChannelGroup(DTC::ChannelGroup *pGroup, const ChannelGroupItem &pGroupItem)
Definition: serviceUtil.cpp:254
ChannelGroup::AddChannel
static bool AddChannel(uint chanid, int changrpid)
Definition: channelgroup.cpp:62
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:198
arg
arg(title).arg(filename).arg(doDelete))
AutoExpire
Used to expire recordings to make space for new recordings.
Definition: autoexpire.h:62
FillChannelInfo
bool FillChannelInfo(DTC::ChannelInfo *pChannel, uint nChanID, bool bDetails)
Definition: serviceUtil.cpp:168
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:603
ChannelGroupList
vector< ChannelGroupItem > ChannelGroupList
Definition: channelgroup.h:32
DTC::ChannelGroupList
Definition: channelGroupList.h:17
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
guide.h
ChannelGroup::GetChannelGroups
static ChannelGroupList GetChannelGroups(bool includeEmpty=true)
Definition: channelgroup.cpp:172
scheduler.h
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:10
Guide::AddToChannelGroup
bool AddToChannelGroup(int ChannelGroupId, int ChanId) override
Definition: guide.cpp:578
mythversion.h
Guide::GetCategoryList
QStringList GetCategoryList() override
Definition: guide.cpp:522
AutoDeleteDeque::begin
iterator begin(void)
Definition: autodeletedeque.h:50
autoexpire.h
mythlogging.h
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:535
compat.h
Guide::GetProgramList
DTC::ProgramList * GetProgramList(int StartIndex, int Count, const QDateTime &StartTime, const QDateTime &EndTime, int ChanId, const QString &TitleFilter, const QString &CategoryFilter, const QString &PersonFilter, const QString &KeywordFilter, bool OnlyNew, bool Details, const QString &Sort, bool Descending, bool WithInvisible) override
Definition: guide.cpp:170
RecSearchType
RecSearchType
Definition: recordingtypes.h:72
storagegroup.h
kNoSearch
@ kNoSearch
Definition: recordingtypes.h:73
ChannelInfoList
vector< ChannelInfo > ChannelInfoList
Definition: channelinfo.h:133
uint
unsigned int uint
Definition: compat.h:140
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:57
AutoDeleteDeque::end
iterator end(void)
Definition: autodeletedeque.h:51
channelutil.h
AutoDeleteDeque< ProgramInfo * >
DTC::ChannelGroup
Definition: channelGroup.h:24
MYTH_BINARY_VERSION
#define MYTH_BINARY_VERSION
Update this whenever the plug-in ABI changes.
Definition: mythversion.h:15
ProgramList
AutoDeleteDeque< ProgramInfo * > ProgramList
Definition: programinfo.h:31
sched
Scheduler * sched
MYTH_PROTO_VERSION
#define MYTH_PROTO_VERSION
Increment this whenever the MythTV network protocol changes.
Definition: mythversion.h:47
ChannelUtil::GetIcon
static QString GetIcon(uint chanid)
Definition: channelutil.cpp:1245
ProgramInfo
Holds information on recordings and videos.
Definition: programinfo.h:68
channelgroup.h
mythcorecontext.h
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:864
LoadFromProgram
bool LoadFromProgram(ProgramList &destination, const QString &where, const QString &groupBy, const QString &orderBy, const MSqlBindings &bindings, const ProgramList &schedList)
Definition: programinfo.cpp:5458
StorageGroup
Definition: storagegroup.h:12
Scheduler::GetAllPending
bool GetAllPending(RecList &retList, int recRuleId=0) const
Definition: scheduler.cpp:1733
DTC::ProgramList
Definition: programList.h:27
Guide::GetProgramGuide
DTC::ProgramGuide * GetProgramGuide(const QDateTime &StartTime, const QDateTime &EndTime, bool Details, int ChannelGroupId, int StartIndex, int Count, bool WithInvisible) override
Definition: guide.cpp:48
DTC::ChannelInfo
Definition: programAndChannel.h:31
Guide::GetStoredSearches
QStringList GetStoredSearches(const QString &Type) override
Definition: guide.cpp:545
AutoDeleteDeque< ProgramInfo * >::iterator
typename List::iterator iterator
Definition: autodeletedeque.h:15
DTC::ProgramGuide
Definition: programGuide.h:36
query
MSqlQuery query(MSqlQuery::InitCon())
Guide::GetProgramDetails
DTC::Program * GetProgramDetails(int ChanId, const QDateTime &StartTime) override
Definition: guide.cpp:347
AutoDeleteDeque::size
size_t size(void) const
Definition: autodeletedeque.h:67
ChannelUtil::kChanOrderByChanNum
@ kChanOrderByChanNum
Definition: channelutil.h:198
ChannelUtil::kChanGroupByCallsign
@ kChanGroupByCallsign
Definition: channelutil.h:205
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:808
ChannelGroup::DeleteChannel
static bool DeleteChannel(uint chanid, int changrpid)
Definition: channelgroup.cpp:139