MythTV  0.26-pre
guide.cpp
Go to the documentation of this file.
00001 
00002 // Program Name: guide.cpp
00003 // Created     : Mar. 7, 2011
00004 //
00005 // Copyright (c) 2011 David Blain <dblain@mythtv.org>
00006 //                                          
00007 // This library is free software; you can redistribute it and/or 
00008 // modify it under the terms of the GNU Lesser General Public
00009 // License as published by the Free Software Foundation; either
00010 // version 2.1 of the License, or at your option any later version of the LGPL.
00011 //
00012 // This library is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015 // Lesser General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU Lesser General Public
00018 // License along with this library.  If not, see <http://www.gnu.org/licenses/>.
00019 //
00021 
00022 #include <math.h>
00023 
00024 #include "guide.h"
00025 
00026 #include "compat.h"
00027 #include "mythversion.h"
00028 #include "mythcorecontext.h"
00029 #include "scheduler.h"
00030 #include "autoexpire.h"
00031 #include "channelutil.h"
00032 
00033 extern AutoExpire  *expirer;
00034 extern Scheduler   *sched;
00035 
00037 //
00039 
00040 DTC::ProgramGuide *Guide::GetProgramGuide( const QDateTime &dtStartTime ,
00041                                            const QDateTime &dtEndTime   ,
00042                                            int              nStartChanId,
00043                                            int              nNumChannels,
00044                                            bool             bDetails      )
00045 {     
00046 
00047     if (!dtStartTime.isValid())
00048         throw( "StartTime is invalid" );
00049 
00050     if (!dtEndTime.isValid())
00051         throw( "EndTime is invalid" );
00052 
00053     if (dtEndTime < dtStartTime)
00054         throw( "EndTime is before StartTime");
00055 
00056     if (nNumChannels == 0)
00057         nNumChannels = SHRT_MAX;
00058 
00059     // ----------------------------------------------------------------------
00060     // Find the ending channel Id
00061     // ----------------------------------------------------------------------
00062 
00063     int nEndChanId = nStartChanId;
00064 
00065     MSqlQuery query(MSqlQuery::InitCon());
00066 
00067     query.prepare( "SELECT chanid FROM channel WHERE (chanid >= :STARTCHANID )"
00068                    " ORDER BY chanid LIMIT :NUMCHAN" );
00069 
00070     query.bindValue(":STARTCHANID", nStartChanId );
00071     query.bindValue(":NUMCHAN"    , nNumChannels );
00072 
00073     if (!query.exec())
00074         MythDB::DBError("Select ChanId", query);
00075 
00076     query.first();  nStartChanId = query.value(0).toInt();
00077     query.last();   nEndChanId   = query.value(0).toInt();
00078 
00079     // ----------------------------------------------------------------------
00080     // Build SQL statement for Program Listing
00081     // ----------------------------------------------------------------------
00082 
00083     ProgramList  progList;
00084     ProgramList  schedList;
00085     MSqlBindings bindings;
00086 
00087     QString      sSQL = "WHERE program.chanid >= :StartChanId "
00088                          "AND program.chanid <= :EndChanId "
00089                          "AND program.endtime >= :StartDate "
00090                          "AND program.starttime <= :EndDate "
00091                         "GROUP BY program.starttime, channel.channum, "
00092                          "channel.callsign, program.title "
00093                         "ORDER BY program.chanid ";
00094 
00095     bindings[":StartChanId"] = nStartChanId;
00096     bindings[":EndChanId"  ] = nEndChanId;
00097     bindings[":StartDate"  ] = dtStartTime;
00098     bindings[":EndDate"    ] = dtEndTime;
00099 
00100     // ----------------------------------------------------------------------
00101     // Get all Pending Scheduled Programs
00102     // ----------------------------------------------------------------------
00103 
00104     bool hasConflicts;
00105     LoadFromScheduler(schedList, hasConflicts);
00106 
00107     // ----------------------------------------------------------------------
00108 
00109     LoadFromProgram( progList, sSQL, bindings, schedList );
00110 
00111     // ----------------------------------------------------------------------
00112     // Build Response
00113     // ----------------------------------------------------------------------
00114 
00115     DTC::ProgramGuide *pGuide = new DTC::ProgramGuide();
00116 
00117     int               nChanCount = 0;
00118     uint              nCurChanId = 0;
00119     DTC::ChannelInfo *pChannel   = NULL;
00120 
00121     for( uint n = 0; n < progList.size(); n++)
00122     {
00123         ProgramInfo *pInfo = progList[ n ];
00124 
00125         if ( nCurChanId != pInfo->GetChanID() )
00126         {
00127             nChanCount++;
00128 
00129             nCurChanId = pInfo->GetChanID();
00130 
00131             pChannel = pGuide->AddNewChannel();
00132 
00133             FillChannelInfo( pChannel, pInfo, bDetails );
00134         }
00135 
00136         
00137         DTC::Program *pProgram = pChannel->AddNewProgram();
00138 
00139         FillProgramInfo( pProgram, pInfo, false, bDetails );
00140     }
00141 
00142     // ----------------------------------------------------------------------
00143 
00144     pGuide->setStartTime    ( dtStartTime   );
00145     pGuide->setEndTime      ( dtEndTime     );
00146     pGuide->setStartChanId  ( nStartChanId  );
00147     pGuide->setEndChanId    ( nEndChanId    );
00148     pGuide->setNumOfChannels( nChanCount    );
00149     pGuide->setDetails      ( bDetails      );
00150     
00151     pGuide->setCount        ( progList.size());
00152     pGuide->setAsOf         ( QDateTime::currentDateTime() );
00153     
00154     pGuide->setVersion      ( MYTH_BINARY_VERSION );
00155     pGuide->setProtoVer     ( MYTH_PROTO_VERSION  );
00156     
00157     return pGuide;
00158 }
00159  
00161 //
00163 
00164 DTC::Program* Guide::GetProgramDetails( int              nChanId,
00165                                         const QDateTime &dtStartTime )
00166                                           
00167 {
00168     if (!dtStartTime.isValid())
00169         throw( "StartTime is invalid" );
00170 
00171     // ----------------------------------------------------------------------
00172     // -=>TODO: Add support for getting Recorded Program Info
00173     // ----------------------------------------------------------------------
00174 
00175     // Build add'l SQL statement for Program Listing
00176 
00177     MSqlBindings bindings;
00178     QString      sSQL = "WHERE program.chanid = :ChanId "
00179                           "AND program.starttime = :StartTime ";
00180 
00181     bindings[":ChanId"   ] = nChanId;
00182     bindings[":StartTime"] = dtStartTime;
00183 
00184     // Get all Pending Scheduled Programs
00185 
00186     ProgramList  schedList;
00187     bool hasConflicts;
00188     LoadFromScheduler(schedList, hasConflicts);
00189 
00190     // ----------------------------------------------------------------------
00191 
00192     ProgramList progList;
00193 
00194     LoadFromProgram( progList, sSQL, bindings, schedList );
00195 
00196     if ( progList.size() == 0)
00197         throw( "Error Reading Program Info" );
00198 
00199     // Build Response
00200 
00201     DTC::Program *pProgram = new DTC::Program();
00202     ProgramInfo  *pInfo    = progList[ 0 ];
00203 
00204     FillProgramInfo( pProgram, pInfo, true );
00205 
00206     return pProgram;
00207 }
00208 
00210 //
00212 
00213 QFileInfo Guide::GetChannelIcon( int nChanId,
00214                                  int nWidth  /* = 0 */,
00215                                  int nHeight /* = 0 */ )
00216 {
00217     // Get Icon file path
00218 
00219     QString sFileName = ChannelUtil::GetIcon( nChanId );
00220 
00221     if (sFileName.isEmpty())
00222         return QFileInfo();
00223 
00224     if ((nWidth <= 0) && (nHeight <= 0))
00225     {
00226         // Use default pixmap
00227         return QFileInfo( sFileName );  
00228     }
00229 
00230 
00231     QString sNewFileName = QString( "%1.%2x%3.png" )
00232                               .arg( sFileName )
00233                               .arg( nWidth    )
00234                               .arg( nHeight   );
00235 
00236     // ----------------------------------------------------------------------
00237     // check to see if image is already created.
00238     // ----------------------------------------------------------------------
00239 
00240     if (QFile::exists( sNewFileName ))
00241         return QFileInfo( sNewFileName );
00242 
00243     // ----------------------------------------------------------------------
00244     // We need to create it...
00245     // ----------------------------------------------------------------------
00246 
00247     float fAspect = 0.0;
00248 
00249     QImage *pImage = new QImage( sFileName );
00250 
00251     if (!pImage)
00252         return QFileInfo();
00253 
00254     if (fAspect <= 0)
00255            fAspect = (float)(pImage->width()) / pImage->height();
00256 
00257     if (fAspect == 0)
00258     {
00259         delete pImage;
00260         return QFileInfo();
00261     }
00262 
00263     if ( nWidth == 0 )
00264         nWidth = (int)rint(nHeight * fAspect);
00265 
00266     if ( nHeight == 0 )
00267         nHeight = (int)rint(nWidth / fAspect);
00268 
00269     QImage img = pImage->scaled( nWidth, nHeight, Qt::IgnoreAspectRatio,
00270                                 Qt::SmoothTransformation);
00271 
00272     img.save( sNewFileName, "PNG" );
00273 
00274     delete pImage;
00275 
00276     return QFileInfo( sNewFileName );
00277 }
00278 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends