|
MythTV
0.26-pre
|
00001 // Qt 00002 #include <QCoreApplication> 00003 00004 // MythTV 00005 #include "mythprogressdialog.h" 00006 #include "mythuibuttonlist.h" 00007 #include "channelsettings.h" 00008 #include "transporteditor.h" 00009 #include "mythuicheckbox.h" 00010 #include "mythuitextedit.h" 00011 #include "channeleditor.h" 00012 #include "mythdialogbox.h" 00013 #include "mythuibutton.h" 00014 #include "channelutil.h" 00015 #include "importicons.h" 00016 #include "mythlogging.h" 00017 #include "mythuitext.h" 00018 #include "mythwizard.h" 00019 #include "scanwizard.h" 00020 #include "sourceutil.h" 00021 #include "cardutil.h" 00022 #include "settings.h" 00023 #include "mythdb.h" 00024 00025 ChannelWizard::ChannelWizard(int id, int default_sourceid) 00026 : ConfigurationWizard() 00027 { 00028 setLabel(QObject::tr("Channel Options")); 00029 00030 // Must be first. 00031 addChild(cid = new ChannelID()); 00032 cid->setValue(id); 00033 00034 ChannelOptionsCommon *common = 00035 new ChannelOptionsCommon(*cid, default_sourceid); 00036 addChild(common); 00037 00038 ChannelOptionsFilters *filters = 00039 new ChannelOptionsFilters(*cid); 00040 addChild(filters); 00041 00042 QStringList cardtypes = ChannelUtil::GetCardTypes(cid->getValue().toUInt()); 00043 bool all_v4l = !cardtypes.empty(); 00044 bool all_asi = !cardtypes.empty(); 00045 for (uint i = 0; i < (uint) cardtypes.size(); i++) 00046 { 00047 all_v4l &= CardUtil::IsV4L(cardtypes[i]); 00048 all_asi &= cardtypes[i] == "ASI"; 00049 } 00050 00051 if (all_v4l) 00052 addChild(new ChannelOptionsV4L(*cid)); 00053 else if (all_asi) 00054 addChild(new ChannelOptionsRawTS(*cid)); 00055 } 00056 00058 00059 ChannelEditor::ChannelEditor(MythScreenStack *parent) 00060 : MythScreenType(parent, "channeleditor"), 00061 m_sourceFilter(FILTER_ALL), 00062 m_currentSortMode(QObject::tr("Channel Name")), 00063 m_currentHideMode(false), 00064 m_channelList(NULL), m_sourceList(NULL), m_preview(NULL), 00065 m_channame(NULL), m_channum(NULL), m_callsign(NULL), 00066 m_chanid(NULL), m_sourcename(NULL), m_compoundname(NULL) 00067 { 00068 } 00069 00070 bool ChannelEditor::Create() 00071 { 00072 bool foundtheme = false; 00073 00074 // Load the theme for this screen 00075 foundtheme = LoadWindowFromXML("config-ui.xml", "channeloverview", this); 00076 00077 if (!foundtheme) 00078 return false; 00079 00080 MythUIButtonList *sortList = dynamic_cast<MythUIButtonList *>(GetChild("sorting")); 00081 m_sourceList = dynamic_cast<MythUIButtonList *>(GetChild("source")); 00082 m_channelList = dynamic_cast<MythUIButtonList *>(GetChild("channels")); 00083 m_preview = dynamic_cast<MythUIImage *>(GetChild("preview")); 00084 m_channame = dynamic_cast<MythUIText *>(GetChild("name")); 00085 m_channum = dynamic_cast<MythUIText *>(GetChild("channum")); 00086 m_callsign = dynamic_cast<MythUIText *>(GetChild("callsign")); 00087 m_chanid = dynamic_cast<MythUIText *>(GetChild("chanid")); 00088 m_sourcename = dynamic_cast<MythUIText *>(GetChild("sourcename")); 00089 m_compoundname = dynamic_cast<MythUIText *>(GetChild("compoundname")); 00090 00091 MythUIButton *deleteButton = dynamic_cast<MythUIButton *>(GetChild("delete")); 00092 MythUIButton *scanButton = dynamic_cast<MythUIButton *>(GetChild("scan")); 00093 MythUIButton *importIconButton = dynamic_cast<MythUIButton *>(GetChild("importicons")); 00094 MythUIButton *transportEditorButton = dynamic_cast<MythUIButton *>(GetChild("edittransport")); 00095 00096 MythUICheckBox *hideCheck = dynamic_cast<MythUICheckBox *>(GetChild("nochannum")); 00097 00098 if (!sortList || !m_sourceList || !m_channelList || !deleteButton || 00099 !scanButton || !importIconButton || !transportEditorButton || 00100 !hideCheck) 00101 { 00102 00103 return false; 00104 } 00105 00106 // Delete button help text 00107 deleteButton->SetHelpText(tr("Delete all channels on currently selected source(s).")); 00108 00109 // Sort List 00110 new MythUIButtonListItem(sortList, tr("Channel Name")); 00111 new MythUIButtonListItem(sortList, tr("Channel Number")); 00112 connect(m_sourceList, SIGNAL(itemSelected(MythUIButtonListItem *)), 00113 SLOT(setSourceID(MythUIButtonListItem *))); 00114 sortList->SetValue(m_currentSortMode); 00115 00116 00117 // Source List 00118 new MythUIButtonListItem(m_sourceList,tr("All"), 00119 qVariantFromValue((int)FILTER_ALL)); 00120 MSqlQuery query(MSqlQuery::InitCon()); 00121 query.prepare("SELECT name, sourceid FROM videosource"); 00122 if (query.exec()) 00123 { 00124 while(query.next()) 00125 { 00126 new MythUIButtonListItem(m_sourceList, query.value(0).toString(), 00127 query.value(1).toInt()); 00128 } 00129 } 00130 new MythUIButtonListItem(m_sourceList,tr("(Unassigned)"), 00131 qVariantFromValue((int)FILTER_UNASSIGNED)); 00132 connect(sortList, SIGNAL(itemSelected(MythUIButtonListItem *)), 00133 SLOT(setSortMode(MythUIButtonListItem *))); 00134 00135 // Hide/Show channels without channum checkbox 00136 hideCheck->SetCheckState(m_currentHideMode); 00137 connect(hideCheck, SIGNAL(toggled(bool)), 00138 SLOT(setHideMode(bool))); 00139 00140 // Scan Button 00141 scanButton->SetHelpText(tr("Starts the channel scanner.")); 00142 scanButton->SetEnabled(SourceUtil::IsAnySourceScanable()); 00143 00144 // Import Icons Button 00145 importIconButton->SetHelpText(tr("Starts the icon downloader")); 00146 importIconButton->SetEnabled(true); 00147 connect(importIconButton, SIGNAL(Clicked()), SLOT(channelIconImport())); 00148 00149 // Transport Editor Button 00150 transportEditorButton->SetHelpText( 00151 tr("Allows you to edit the transports directly. " 00152 "This is rarely required unless you are using " 00153 "a satellite dish and must enter an initial " 00154 "frequency to for the channel scanner to try.")); 00155 connect(transportEditorButton, SIGNAL(Clicked()), SLOT(transportEditor())); 00156 00157 // Other signals 00158 connect(m_channelList, SIGNAL(itemClicked(MythUIButtonListItem *)), 00159 SLOT(edit(MythUIButtonListItem *))); 00160 connect(m_channelList, SIGNAL(itemSelected(MythUIButtonListItem *)), 00161 SLOT(itemChanged(MythUIButtonListItem *))); 00162 connect(scanButton, SIGNAL(Clicked()), SLOT(scan())); 00163 connect(deleteButton, SIGNAL(Clicked()), SLOT(deleteChannels())); 00164 00165 fillList(); 00166 00167 BuildFocusList(); 00168 00169 return true; 00170 } 00171 00172 bool ChannelEditor::keyPressEvent(QKeyEvent *event) 00173 { 00174 if (GetFocusWidget()->keyPressEvent(event)) 00175 return true; 00176 00177 bool handled = false; 00178 QStringList actions; 00179 handled = GetMythMainWindow()->TranslateKeyPress("Global", event, actions); 00180 00181 for (int i = 0; i < actions.size() && !handled; i++) 00182 { 00183 QString action = actions[i]; 00184 handled = true; 00185 00186 if (action == "MENU") 00187 menu(); 00188 else if (action == "DELETE") 00189 del(); 00190 else if (action == "EDIT") 00191 edit(); 00192 else 00193 handled = false; 00194 } 00195 00196 if (!handled && MythScreenType::keyPressEvent(event)) 00197 handled = true; 00198 00199 return handled; 00200 } 00201 00202 void ChannelEditor::itemChanged(MythUIButtonListItem *item) 00203 { 00204 if (!item) 00205 return; 00206 00207 if (m_preview) 00208 { 00209 m_preview->Reset(); 00210 QString iconpath = item->GetImage(); 00211 if (!iconpath.isEmpty()) 00212 { 00213 m_preview->SetFilename(iconpath); 00214 m_preview->Load(); 00215 } 00216 } 00217 00218 if (m_channame) 00219 m_channame->SetText(item->GetText("name")); 00220 00221 if (m_channum) 00222 m_channum->SetText(item->GetText("channum")); 00223 00224 if (m_callsign) 00225 m_callsign->SetText(item->GetText("callsign")); 00226 00227 if (m_chanid) 00228 m_chanid->SetText(item->GetText("chanid")); 00229 00230 if (m_sourcename) 00231 m_sourcename->SetText(item->GetText("sourcename")); 00232 00233 if (m_compoundname) 00234 m_compoundname->SetText(item->GetText("compoundname")); 00235 } 00236 00237 void ChannelEditor::fillList(void) 00238 { 00239 QString currentValue = m_channelList->GetValue(); 00240 uint currentIndex = qMax(m_channelList->GetCurrentPos(), 0); 00241 m_channelList->Reset(); 00242 QString newchanlabel = tr("(Add New Channel)"); 00243 MythUIButtonListItem *item = new MythUIButtonListItem(m_channelList, ""); 00244 item->SetText(newchanlabel, "compoundname"); 00245 item->SetText(newchanlabel, "name"); 00246 00247 bool fAllSources = true; 00248 00249 QString querystr = "SELECT channel.name,channum,chanid,callsign,icon," 00250 "visible ,videosource.name FROM channel " 00251 "LEFT JOIN videosource ON " 00252 "(channel.sourceid = videosource.sourceid) "; 00253 00254 if (m_sourceFilter == FILTER_ALL) 00255 { 00256 fAllSources = true; 00257 } 00258 else 00259 { 00260 querystr += QString(" WHERE channel.sourceid='%1' ") 00261 .arg(m_sourceFilter); 00262 fAllSources = false; 00263 } 00264 00265 if (m_currentSortMode == tr("Channel Name")) 00266 { 00267 querystr += " ORDER BY channel.name"; 00268 } 00269 else if (m_currentSortMode == tr("Channel Number")) 00270 { 00271 querystr += " ORDER BY channum + 0"; 00272 } 00273 00274 MSqlQuery query(MSqlQuery::InitCon()); 00275 query.prepare(querystr); 00276 00277 uint selidx = 0, idx = 1; 00278 if (query.exec() && query.size() > 0) 00279 { 00280 for (; query.next() ; idx++) 00281 { 00282 QString name = query.value(0).toString(); 00283 QString channum = query.value(1).toString(); 00284 QString chanid = query.value(2).toString(); 00285 QString callsign = query.value(3).toString(); 00286 QString icon = query.value(4).toString(); 00287 bool visible = query.value(5).toBool(); 00288 QString sourceid = "Unassigned"; 00289 00290 QString state = "normal"; 00291 00292 if (!visible) 00293 state = "disabled"; 00294 00295 if (!query.value(6).toString().isEmpty()) 00296 { 00297 sourceid = query.value(6).toString(); 00298 if (fAllSources && m_sourceFilter == FILTER_UNASSIGNED) 00299 continue; 00300 } 00301 else 00302 state = "warning"; 00303 00304 if (channum.isEmpty() && m_currentHideMode) 00305 continue; 00306 00307 if (name.isEmpty()) 00308 name = "(Unnamed : " + chanid + ")"; 00309 00310 QString compoundname = name; 00311 00312 if (m_currentSortMode == tr("Channel Name")) 00313 { 00314 if (!channum.isEmpty()) 00315 compoundname += " (" + channum + ")"; 00316 } 00317 else if (m_currentSortMode == tr("Channel Number")) 00318 { 00319 if (!channum.isEmpty()) 00320 compoundname = channum + ". " + compoundname; 00321 else 00322 compoundname = "???. " + compoundname; 00323 } 00324 00325 if (m_sourceFilter == FILTER_ALL) 00326 compoundname += " (" + sourceid + ")"; 00327 00328 bool sel = (chanid == currentValue); 00329 selidx = (sel) ? idx : selidx; 00330 item = new MythUIButtonListItem(m_channelList, "", 00331 qVariantFromValue(chanid)); 00332 item->SetText(compoundname, "compoundname"); 00333 item->SetText(name, "name"); 00334 item->SetText(channum, "channum"); 00335 item->SetText(chanid, "chanid"); 00336 item->SetText(callsign, "callsign"); 00337 item->SetText(sourceid, "sourcename"); 00338 item->SetImage(icon); 00339 item->SetImage(icon, "icon"); 00340 item->DisplayState(state, "status"); 00341 } 00342 } 00343 00344 // Make sure we select the current item, or the following one after 00345 // deletion, with wrap around to "(New Channel)" after deleting last item. 00346 m_channelList->SetItemCurrent((!selidx && currentIndex < idx) ? currentIndex : selidx); 00347 } 00348 00349 void ChannelEditor::setSortMode(MythUIButtonListItem *item) 00350 { 00351 if (!item) 00352 return; 00353 00354 QString sortName = item->GetText(); 00355 00356 if (m_currentSortMode != sortName) 00357 { 00358 m_currentSortMode = sortName; 00359 fillList(); 00360 } 00361 } 00362 00363 void ChannelEditor::setSourceID(MythUIButtonListItem *item) 00364 { 00365 if (!item) 00366 return; 00367 00368 QString sourceName = item->GetText(); 00369 int sourceID = item->GetData().toInt(); 00370 00371 if (m_sourceFilter != sourceID) 00372 { 00373 m_sourceFilterName = sourceName; 00374 m_sourceFilter = sourceID; 00375 fillList(); 00376 } 00377 } 00378 00379 void ChannelEditor::setHideMode(bool hide) 00380 { 00381 if (m_currentHideMode != hide) 00382 { 00383 m_currentHideMode = hide; 00384 fillList(); 00385 } 00386 } 00387 00388 void ChannelEditor::del() 00389 { 00390 MythUIButtonListItem *item = m_channelList->GetItemCurrent(); 00391 00392 if (!item) 00393 return; 00394 00395 QString message = tr("Delete channel '%1'?").arg(item->GetText("name")); 00396 00397 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack"); 00398 MythConfirmationDialog *dialog = new MythConfirmationDialog(popupStack, message, true); 00399 00400 if (dialog->Create()) 00401 { 00402 dialog->SetData(qVariantFromValue(item)); 00403 dialog->SetReturnEvent(this, "delsingle"); 00404 popupStack->AddScreen(dialog); 00405 } 00406 else 00407 delete dialog; 00408 00409 } 00410 00411 void ChannelEditor::deleteChannels(void) 00412 { 00413 const QString currentLabel = m_sourceList->GetValue(); 00414 00415 bool del_all = m_sourceFilter == FILTER_ALL; 00416 bool del_nul = m_sourceFilter == FILTER_UNASSIGNED; 00417 00418 QString message = 00419 (del_all) ? tr("Delete ALL channels?") : 00420 ((del_nul) ? tr("Delete all unassigned channels?") : 00421 tr("Delete all channels on %1?").arg(currentLabel)); 00422 00423 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack"); 00424 MythConfirmationDialog *dialog = new MythConfirmationDialog(popupStack, message, true); 00425 00426 if (dialog->Create()) 00427 { 00428 dialog->SetReturnEvent(this, "delall"); 00429 popupStack->AddScreen(dialog); 00430 } 00431 else 00432 delete dialog; 00433 } 00434 00435 void ChannelEditor::edit(MythUIButtonListItem *item) 00436 { 00437 if (!item) 00438 item = m_channelList->GetItemCurrent(); 00439 00440 if (!item) 00441 return; 00442 00443 int chanid = item->GetData().toInt(); 00444 ChannelWizard cw(chanid, m_sourceFilter); 00445 cw.exec(); 00446 00447 fillList(); 00448 } 00449 00450 void ChannelEditor::menu() 00451 { 00452 MythUIButtonListItem *item = m_channelList->GetItemCurrent(); 00453 00454 if (!item) 00455 return; 00456 00457 int chanid = item->GetData().toInt(); 00458 if (chanid == 0) 00459 edit(item); 00460 else 00461 { 00462 QString label = tr("Channel Options"); 00463 00464 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack"); 00465 00466 MythDialogBox *menu = new MythDialogBox(label, popupStack, "chanoptmenu"); 00467 00468 if (menu->Create()) 00469 { 00470 menu->SetReturnEvent(this, "channelopts"); 00471 00472 menu->AddButton(tr("Edit")); 00473 // if () 00474 // menu->AddButton(tr("Set Hidden")); 00475 // else 00476 // menu->AddButton(tr("Set Visible")); 00477 menu->AddButton(tr("Delete")); 00478 00479 popupStack->AddScreen(menu); 00480 } 00481 else 00482 { 00483 delete menu; 00484 return; 00485 } 00486 } 00487 } 00488 00489 void ChannelEditor::scan(void) 00490 { 00491 #ifdef USING_BACKEND 00492 ScanWizard *scanwizard = new ScanWizard(m_sourceFilter); 00493 scanwizard->exec(false, true); 00494 scanwizard->deleteLater(); 00495 00496 fillList(); 00497 #else 00498 LOG(VB_GENERAL, LOG_ERR, 00499 "You must compile the backend to be able to scan for channels"); 00500 #endif 00501 } 00502 00503 void ChannelEditor::transportEditor(void) 00504 { 00505 TransportListEditor *editor = new TransportListEditor(m_sourceFilter); 00506 editor->exec(); 00507 editor->deleteLater(); 00508 00509 fillList(); 00510 } 00511 00512 void ChannelEditor::channelIconImport(void) 00513 { 00514 if (m_channelList->GetCount() == 0) 00515 { 00516 ShowOkPopup(tr("Add some channels first!")); 00517 return; 00518 } 00519 00520 int channelID = 0; 00521 MythUIButtonListItem *item = m_channelList->GetItemCurrent(); 00522 if (item) 00523 channelID = item->GetData().toInt(); 00524 00525 // Get selected channel name from database 00526 QString querystr = QString("SELECT channel.name FROM channel " 00527 "WHERE chanid='%1'").arg(channelID); 00528 QString channelname; 00529 MSqlQuery query(MSqlQuery::InitCon()); 00530 query.prepare(querystr); 00531 00532 if (query.exec() && query.next()) 00533 { 00534 channelname = query.value(0).toString(); 00535 } 00536 00537 QString label = tr("Icon Import Options"); 00538 00539 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack"); 00540 00541 MythDialogBox *menu = new MythDialogBox(label, popupStack, "iconoptmenu"); 00542 00543 if (menu->Create()) 00544 { 00545 menu->SetReturnEvent(this, "iconimportopt"); 00546 00547 menu->AddButton(tr("Download all icons...")); 00548 menu->AddButton(tr("Rescan for missing icons...")); 00549 if (!channelname.isEmpty()) 00550 menu->AddButton(tr("Download icon for %1").arg(channelname), 00551 channelname); 00552 00553 popupStack->AddScreen(menu); 00554 } 00555 else 00556 { 00557 delete menu; 00558 return; 00559 } 00560 } 00561 00562 void ChannelEditor::customEvent(QEvent *event) 00563 { 00564 if (event->type() == DialogCompletionEvent::kEventType) 00565 { 00566 DialogCompletionEvent *dce = (DialogCompletionEvent*)(event); 00567 00568 QString resultid= dce->GetId(); 00569 int buttonnum = dce->GetResult(); 00570 00571 if (resultid == "channelopts") 00572 { 00573 switch (buttonnum) 00574 { 00575 case 0 : 00576 edit(m_channelList->GetItemCurrent()); 00577 break; 00578 case 1 : 00579 del(); 00580 break; 00581 } 00582 } 00583 else if (resultid == "delsingle" && buttonnum == 1) 00584 { 00585 MythUIButtonListItem *item = 00586 qVariantValue<MythUIButtonListItem *>(dce->GetData()); 00587 if (!item) 00588 return; 00589 uint chanid = item->GetData().toUInt(); 00590 if (chanid && ChannelUtil::DeleteChannel(chanid)) 00591 m_channelList->RemoveItem(item); 00592 } 00593 else if (resultid == "delall" && buttonnum == 1) 00594 { 00595 bool del_all = m_sourceFilter == FILTER_ALL; 00596 bool del_nul = m_sourceFilter == FILTER_UNASSIGNED; 00597 00598 MSqlQuery query(MSqlQuery::InitCon()); 00599 if (del_all) 00600 { 00601 query.prepare("TRUNCATE TABLE channel"); 00602 } 00603 else if (del_nul) 00604 { 00605 query.prepare("SELECT sourceid " 00606 "FROM videosource " 00607 "GROUP BY sourceid"); 00608 00609 if (!query.exec() || !query.isActive()) 00610 { 00611 MythDB::DBError("ChannelEditor Delete Channels", query); 00612 return; 00613 } 00614 00615 QString tmp = ""; 00616 while (query.next()) 00617 tmp += "'" + query.value(0).toString() + "',"; 00618 00619 if (tmp.isEmpty()) 00620 { 00621 query.prepare("TRUNCATE TABLE channel"); 00622 } 00623 else 00624 { 00625 tmp = tmp.left(tmp.length() - 1); 00626 query.prepare(QString("DELETE FROM channel " 00627 "WHERE sourceid NOT IN (%1)").arg(tmp)); 00628 } 00629 } 00630 else 00631 { 00632 query.prepare("DELETE FROM channel " 00633 "WHERE sourceid = :SOURCEID"); 00634 query.bindValue(":SOURCEID", m_sourceFilter); 00635 } 00636 00637 if (!query.exec()) 00638 MythDB::DBError("ChannelEditor Delete Channels", query); 00639 00640 fillList(); 00641 } 00642 else if (resultid == "iconimportopt") 00643 { 00644 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack(); 00645 00646 ImportIconsWizard *iconwizard; 00647 00648 QString channelname = dce->GetData().toString(); 00649 00650 switch (buttonnum) 00651 { 00652 case 0 : // Import all icons 00653 iconwizard = new ImportIconsWizard(mainStack, false); 00654 break; 00655 case 1 : // Rescan for missing 00656 iconwizard = new ImportIconsWizard(mainStack, true); 00657 break; 00658 case 2 : // Import a single channel icon 00659 iconwizard = new ImportIconsWizard(mainStack, true, 00660 channelname); 00661 break; 00662 default: 00663 return; 00664 } 00665 00666 if (iconwizard->Create()) 00667 { 00668 connect(iconwizard, SIGNAL(Exiting()), SLOT(fillList())); 00669 mainStack->AddScreen(iconwizard); 00670 } 00671 else 00672 delete iconwizard; 00673 } 00674 } 00675 }
1.7.6.1