|
MythTV
0.26-pre
|
00001 00002 #include "channelrecpriority.h" 00003 00004 #include <algorithm> // For std::sort() 00005 #include <vector> // For std::vector 00006 using namespace std; 00007 00008 #include "tv.h" 00009 00010 #include "mythcorecontext.h" 00011 #include "mythdb.h" 00012 #include "mythlogging.h" 00013 #include "scheduledrecording.h" 00014 #include "proglist.h" 00015 #include "dbchannelinfo.h" 00016 00017 #include "mythuihelper.h" 00018 #include "mythuitext.h" 00019 #include "mythuiimage.h" 00020 #include "mythuibuttonlist.h" 00021 #include "mythdialogbox.h" 00022 #include "mythmainwindow.h" 00023 00024 typedef struct RecPriorityInfo 00025 { 00026 ChannelInfo *chan; 00027 int cnt; 00028 } RecPriorityInfo; 00029 00030 class channelSort 00031 { 00032 public: 00033 bool operator()(const RecPriorityInfo &a, const RecPriorityInfo &b) 00034 { 00035 if (a.chan->chanstr.toInt() == b.chan->chanstr.toInt()) 00036 return(a.chan->sourceid > b.chan->sourceid); 00037 return(a.chan->chanstr.toInt() > b.chan->chanstr.toInt()); 00038 } 00039 }; 00040 00041 class channelRecPrioritySort 00042 { 00043 public: 00044 bool operator()(const RecPriorityInfo &a, const RecPriorityInfo &b) 00045 { 00046 if (a.chan->recpriority.toInt() == b.chan->recpriority.toInt()) 00047 return (a.chan->chanstr.toInt() > b.chan->chanstr.toInt()); 00048 return (a.chan->recpriority.toInt() < b.chan->recpriority.toInt()); 00049 } 00050 }; 00051 00052 ChannelRecPriority::ChannelRecPriority(MythScreenStack *parent) 00053 : MythScreenType(parent, "ChannelRecPriority"), 00054 m_channelList(NULL), m_chanstringText(NULL), 00055 m_channameText(NULL), m_channumText(NULL), 00056 m_callsignText(NULL), m_sourcenameText(NULL), 00057 m_sourceidText(NULL), m_priorityText(NULL), 00058 m_iconImage(NULL) 00059 { 00060 m_sortType = (SortType)gCoreContext->GetNumSetting("ChannelRecPrioritySorting", 00061 (int)byChannel); 00062 00063 m_currentItem = NULL; 00064 00065 gCoreContext->addListener(this); 00066 } 00067 00068 ChannelRecPriority::~ChannelRecPriority() 00069 { 00070 saveRecPriority(); 00071 gCoreContext->SaveSetting("ChannelRecPrioritySorting", 00072 (int)m_sortType); 00073 gCoreContext->removeListener(this); 00074 } 00075 00076 bool ChannelRecPriority::Create() 00077 { 00078 if (!LoadWindowFromXML("schedule-ui.xml", "channelrecpriority", this)) 00079 return false; 00080 00081 m_channelList = dynamic_cast<MythUIButtonList *> (GetChild("channels")); 00082 00083 m_chanstringText = dynamic_cast<MythUIText *> (GetChild("chanstring")); // Deprecated, use mapped text 00084 m_priorityText = dynamic_cast<MythUIText *> (GetChild("priority")); 00085 00086 m_iconImage = dynamic_cast<MythUIImage *> (GetChild("icon")); 00087 00088 if (!m_channelList) 00089 { 00090 LOG(VB_GENERAL, LOG_ERR, "Theme is missing critical theme elements."); 00091 return false; 00092 } 00093 00094 connect(m_channelList, SIGNAL(itemSelected(MythUIButtonListItem*)), 00095 SLOT(updateInfo(MythUIButtonListItem*))); 00096 00097 FillList(); 00098 00099 BuildFocusList(); 00100 00101 return true; 00102 } 00103 00104 bool ChannelRecPriority::keyPressEvent(QKeyEvent *event) 00105 { 00106 if (GetFocusWidget()->keyPressEvent(event)) 00107 return true; 00108 00109 bool handled = false; 00110 QStringList actions; 00111 handled = GetMythMainWindow()->TranslateKeyPress("TV Frontend", event, actions); 00112 00113 for (int i = 0; i < actions.size() && !handled; i++) 00114 { 00115 QString action = actions[i]; 00116 handled = true; 00117 00118 if (action == "UPCOMING") 00119 upcoming(); 00120 else if (action == "RANKINC") 00121 changeRecPriority(1); 00122 else if (action == "RANKDEC") 00123 changeRecPriority(-1); 00124 else if (action == "1") 00125 { 00126 if (m_sortType != byChannel) 00127 { 00128 m_sortType = byChannel; 00129 SortList(); 00130 } 00131 } 00132 else if (action == "2") 00133 { 00134 if (m_sortType != byRecPriority) 00135 { 00136 m_sortType = byRecPriority; 00137 SortList(); 00138 } 00139 } 00140 else if (action == "PREVVIEW" || action == "NEXTVIEW") 00141 { 00142 if (m_sortType == byChannel) 00143 m_sortType = byRecPriority; 00144 else 00145 m_sortType = byChannel; 00146 SortList(); 00147 } 00148 else 00149 handled = false; 00150 } 00151 00152 if (!handled && MythScreenType::keyPressEvent(event)) 00153 handled = true; 00154 00155 return handled; 00156 } 00157 00158 void ChannelRecPriority::ShowMenu() 00159 { 00160 MythUIButtonListItem *item = m_channelList->GetItemCurrent(); 00161 00162 if (!item) 00163 return; 00164 00165 QString label = tr("Channel Options"); 00166 00167 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack"); 00168 00169 MythDialogBox *menuPopup = new MythDialogBox(label, popupStack, 00170 "chanrecmenupopup"); 00171 00172 if (!menuPopup->Create()) 00173 { 00174 delete menuPopup; 00175 menuPopup = NULL; 00176 return; 00177 } 00178 00179 menuPopup->SetReturnEvent(this, "options"); 00180 00181 menuPopup->AddButton(tr("Program List")); 00182 //menuPopup->AddButton(tr("Reset All Priorities")); 00183 00184 popupStack->AddScreen(menuPopup); 00185 } 00186 00187 void ChannelRecPriority::changeRecPriority(int howMuch) 00188 { 00189 MythUIButtonListItem *item = m_channelList->GetItemCurrent(); 00190 00191 if (!item) 00192 return; 00193 00194 ChannelInfo *chanInfo = qVariantValue<ChannelInfo *>(item->GetData()); 00195 00196 // inc/dec recording priority 00197 int tempRecPriority = chanInfo->recpriority.toInt() + howMuch; 00198 if (tempRecPriority > -100 && tempRecPriority < 100) 00199 { 00200 chanInfo->recpriority = QString::number(tempRecPriority); 00201 00202 // order may change if sorting by recoring priority, so resort 00203 if (m_sortType == byRecPriority) 00204 SortList(); 00205 else 00206 { 00207 item->SetText(chanInfo->recpriority, "priority"); 00208 updateInfo(item); 00209 } 00210 } 00211 } 00212 00213 void ChannelRecPriority::applyChannelRecPriorityChange(QString chanid, 00214 const QString &newrecpriority) 00215 { 00216 MSqlQuery query(MSqlQuery::InitCon()); 00217 query.prepare("UPDATE channel SET recpriority = :RECPRI " 00218 "WHERE chanid = :CHANID ;"); 00219 query.bindValue(":RECPRI", newrecpriority); 00220 query.bindValue(":CHANID", chanid); 00221 00222 if (!query.exec() || !query.isActive()) 00223 MythDB::DBError("Save recpriority update", query); 00224 } 00225 00226 void ChannelRecPriority::saveRecPriority(void) 00227 { 00228 QMap<QString, ChannelInfo>::Iterator it; 00229 00230 for (it = m_channelData.begin(); it != m_channelData.end(); ++it) 00231 { 00232 ChannelInfo *chanInfo = &(*it); 00233 QString key = QString::number(chanInfo->chanid); 00234 00235 // if this channel's recording priority changed from when we entered 00236 // save new value out to db 00237 if (chanInfo->recpriority != m_origRecPriorityData[key]) 00238 applyChannelRecPriorityChange(QString::number(chanInfo->chanid), 00239 chanInfo->recpriority); 00240 } 00241 ScheduledRecording::ReschedulePlace("SaveChannelPriority"); 00242 } 00243 00244 void ChannelRecPriority::FillList(void) 00245 { 00246 QMap<int, QString> srcMap; 00247 00248 m_channelData.clear(); 00249 m_sortedChannel.clear(); 00250 m_visMap.clear(); 00251 00252 MSqlQuery result(MSqlQuery::InitCon()); 00253 result.prepare("SELECT sourceid, name FROM videosource;"); 00254 00255 if (result.exec()) 00256 { 00257 while (result.next()) 00258 { 00259 srcMap[result.value(0).toInt()] = result.value(1).toString(); 00260 } 00261 } 00262 result.prepare("SELECT chanid, channum, sourceid, callsign, " 00263 "icon, recpriority, name, visible FROM channel;"); 00264 00265 if (result.exec()) 00266 { 00267 int cnt = 999; 00268 while (result.next()) 00269 { 00270 ChannelInfo *chaninfo = new ChannelInfo; 00271 chaninfo->chanid = result.value(0).toInt(); 00272 chaninfo->chanstr = result.value(1).toString(); 00273 chaninfo->sourceid = result.value(2).toInt(); 00274 chaninfo->callsign = result.value(3).toString(); 00275 chaninfo->iconpath = result.value(4).toString(); 00276 chaninfo->recpriority = result.value(5).toString(); 00277 chaninfo->channame = result.value(6).toString(); 00278 if (result.value(7).toInt() > 0) 00279 m_visMap[chaninfo->chanid] = true; 00280 chaninfo->sourcename = srcMap[chaninfo->sourceid]; 00281 00282 m_channelData[QString::number(cnt)] = *chaninfo; 00283 00284 // save recording priority value in map so we don't have to save 00285 // all channel's recording priority values when we exit 00286 m_origRecPriorityData[QString::number(chaninfo->chanid)] = 00287 chaninfo->recpriority; 00288 00289 cnt--; 00290 } 00291 } 00292 else if (!result.isActive()) 00293 MythDB::DBError("Get channel recording priorities query", result); 00294 00295 SortList(); 00296 } 00297 00298 void ChannelRecPriority::updateList() 00299 { 00300 m_channelList->Reset(); 00301 00302 QMap<QString, ChannelInfo*>::Iterator it; 00303 MythUIButtonListItem *item; 00304 for (it = m_sortedChannel.begin(); it != m_sortedChannel.end(); ++it) 00305 { 00306 ChannelInfo *chanInfo = *it; 00307 00308 item = new MythUIButtonListItem(m_channelList, "", 00309 qVariantFromValue(chanInfo)); 00310 00311 QString fontState = "default"; 00312 if (!m_visMap[chanInfo->chanid]) 00313 fontState = "disabled"; 00314 00315 item->SetText(chanInfo->GetFormatted(ChannelInfo::kChannelLong), 00316 fontState); 00317 00318 InfoMap infomap; 00319 chanInfo->ToMap(infomap); 00320 item->SetTextFromMap(infomap, fontState); 00321 00322 if (m_visMap[chanInfo->chanid]) 00323 item->DisplayState("normal", "status"); 00324 else 00325 item->DisplayState("disabled", "status"); 00326 00327 item->SetImage(chanInfo->iconpath, "icon"); 00328 item->SetImage(chanInfo->iconpath); 00329 00330 item->SetText(chanInfo->recpriority, "priority", fontState); 00331 00332 if (m_currentItem == chanInfo) 00333 m_channelList->SetItemCurrent(item); 00334 } 00335 00336 MythUIText *norecordingText = dynamic_cast<MythUIText*> 00337 (GetChild("norecordings_info")); 00338 00339 if (norecordingText) 00340 norecordingText->SetVisible(m_channelData.isEmpty()); 00341 } 00342 00343 00344 void ChannelRecPriority::SortList() 00345 { 00346 MythUIButtonListItem *item = m_channelList->GetItemCurrent(); 00347 00348 if (item) 00349 { 00350 ChannelInfo *channelItem = qVariantValue<ChannelInfo *>(item->GetData()); 00351 m_currentItem = channelItem; 00352 } 00353 00354 int i, j; 00355 vector<RecPriorityInfo> sortingList; 00356 QMap<QString, ChannelInfo>::iterator pit; 00357 vector<RecPriorityInfo>::iterator sit; 00358 ChannelInfo *chanInfo; 00359 RecPriorityInfo *recPriorityInfo; 00360 00361 // copy m_channelData into sortingList 00362 for (i = 0, pit = m_channelData.begin(); pit != m_channelData.end(); 00363 ++pit, ++i) 00364 { 00365 chanInfo = &(*pit); 00366 RecPriorityInfo tmp = {chanInfo, i}; 00367 sortingList.push_back(tmp); 00368 } 00369 00370 switch(m_sortType) 00371 { 00372 case byRecPriority: 00373 sort(sortingList.begin(), sortingList.end(), 00374 channelRecPrioritySort()); 00375 break; 00376 case byChannel: 00377 default: 00378 sort(sortingList.begin(), sortingList.end(), 00379 channelSort()); 00380 break; 00381 } 00382 00383 m_sortedChannel.clear(); 00384 00385 // rebuild m_channelData in sortingList order from m_sortedChannel 00386 for (i = 0, sit = sortingList.begin(); sit != sortingList.end(); i++, ++sit) 00387 { 00388 recPriorityInfo = &(*sit); 00389 00390 // find recPriorityInfo[i] in m_sortedChannel 00391 for (j = 0, pit = m_channelData.begin(); j !=recPriorityInfo->cnt; j++, ++pit); 00392 00393 m_sortedChannel[QString::number(999-i)] = &(*pit); 00394 } 00395 00396 updateList(); 00397 } 00398 00399 void ChannelRecPriority::updateInfo(MythUIButtonListItem *item) 00400 { 00401 if (!item) 00402 return; 00403 00404 ChannelInfo *channelItem = qVariantValue<ChannelInfo *>(item->GetData()); 00405 if (!m_channelData.isEmpty() && channelItem) 00406 { 00407 QString rectype; 00408 if (m_iconImage) 00409 { 00410 m_iconImage->SetFilename(channelItem->iconpath); 00411 m_iconImage->Load(); 00412 } 00413 00414 InfoMap chanmap; 00415 channelItem->ToMap(chanmap); 00416 SetTextFromMap(chanmap); 00417 00418 if (m_chanstringText) 00419 m_chanstringText->SetText(channelItem->GetFormatted(ChannelInfo::kChannelLong)); 00420 } 00421 00422 MythUIText *norecordingText = dynamic_cast<MythUIText*> 00423 (GetChild("norecordings_info")); 00424 00425 if (norecordingText) 00426 norecordingText->SetVisible(m_channelData.isEmpty()); 00427 } 00428 00429 void ChannelRecPriority::upcoming() 00430 { 00431 MythUIButtonListItem *item = m_channelList->GetItemCurrent(); 00432 00433 if (!item) 00434 return; 00435 00436 ChannelInfo *chanInfo = qVariantValue<ChannelInfo *>(item->GetData()); 00437 00438 if (!chanInfo || chanInfo->chanid < 1) 00439 return; 00440 00441 QString chanID = QString("%1").arg(chanInfo->chanid); 00442 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack(); 00443 ProgLister *pl = new ProgLister(mainStack, plChannel, chanID, ""); 00444 if (pl->Create()) 00445 mainStack->AddScreen(pl); 00446 else 00447 delete pl; 00448 } 00449 00450 00451 void ChannelRecPriority::customEvent(QEvent *event) 00452 { 00453 if (event->type() == DialogCompletionEvent::kEventType) 00454 { 00455 DialogCompletionEvent *dce = (DialogCompletionEvent*)(event); 00456 00457 QString resultid = dce->GetId(); 00458 int buttonnum = dce->GetResult(); 00459 00460 if (resultid == "options") 00461 { 00462 switch (buttonnum) 00463 { 00464 case 0: 00465 upcoming(); 00466 break; 00467 } 00468 } 00469 } 00470 } 00471
1.7.6.1