|
MythTV
0.26-pre
|
00001 #include <QDomDocument> 00002 #include <QDateTime> 00003 #include <QImageReader> 00004 00005 // MythTV headers 00006 #include <mythuibutton.h> 00007 #include <mythuibuttonlist.h> 00008 #include <mythuitextedit.h> 00009 #include <mythuicheckbox.h> 00010 #include <mythuifilebrowser.h> 00011 #include <mythmainwindow.h> 00012 #include <mythdialogbox.h> 00013 #include <mythmiscutil.h> 00014 #include <mythcontext.h> 00015 #include <mythdbcon.h> 00016 #include <httpcomms.h> 00017 #include <mythdirs.h> 00018 #include <netutils.h> 00019 #include <rssparse.h> 00020 00021 // RSS headers 00022 #include "rsseditor.h" 00023 00024 #define LOC QString("RSSEditor: ") 00025 #define LOC_WARN QString("RSSEditor, Warning: ") 00026 #define LOC_ERR QString("RSSEditor, Error: ") 00027 00028 namespace 00029 { 00030 const QString CEID_NEWIMAGE = "image"; 00031 00032 QStringList GetSupportedImageExtensionFilter() 00033 { 00034 QStringList ret; 00035 00036 QList<QByteArray> exts = QImageReader::supportedImageFormats(); 00037 for (QList<QByteArray>::iterator p = exts.begin(); p != exts.end(); ++p) 00038 { 00039 ret.append(QString("*.").append(*p)); 00040 } 00041 00042 return ret; 00043 } 00044 } 00045 00050 RSSEditPopup::RSSEditPopup( 00051 const QString &url, bool edit, 00052 MythScreenStack *parent, const QString &name) : 00053 MythScreenType(parent, name), 00054 m_site(NULL), 00055 m_urlText(url), m_editing(edit), 00056 m_thumbImage(NULL), m_thumbButton(NULL), 00057 m_urlEdit(NULL), m_titleEdit(NULL), 00058 m_descEdit(NULL), m_authorEdit(NULL), 00059 m_okButton(NULL), m_cancelButton(NULL), 00060 m_download(NULL), m_manager(NULL), 00061 m_reply(NULL) 00062 { 00063 } 00064 00065 RSSEditPopup::~RSSEditPopup() 00066 { 00067 if (m_manager) 00068 { 00069 m_manager->disconnect(); 00070 m_manager->deleteLater(); 00071 m_manager = NULL; 00072 } 00073 } 00074 00075 bool RSSEditPopup::Create(void) 00076 { 00077 // Load the theme for this screen 00078 bool foundtheme = LoadWindowFromXML("netvision-ui.xml", "rsseditpopup", this); 00079 00080 if (!foundtheme) 00081 return false; 00082 00083 bool err = false; 00084 UIUtilE::Assign(this, m_urlEdit, "url", &err); 00085 UIUtilE::Assign(this, m_titleEdit, "title", &err); 00086 UIUtilE::Assign(this, m_descEdit, "description", &err); 00087 UIUtilE::Assign(this, m_authorEdit, "author", &err); 00088 UIUtilE::Assign(this, m_download, "download", &err); 00089 UIUtilE::Assign(this, m_okButton, "ok", &err); 00090 UIUtilE::Assign(this, m_cancelButton, "cancel", &err); 00091 UIUtilE::Assign(this, m_thumbButton, "preview_browse", &err); 00092 UIUtilE::Assign(this, m_thumbImage, "preview", &err); 00093 00094 if (err) 00095 { 00096 LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'rsseditpopup'"); 00097 return false; 00098 } 00099 00100 connect(m_okButton, SIGNAL(Clicked()), this, SLOT(parseAndSave())); 00101 connect(m_cancelButton, SIGNAL(Clicked()), this, SLOT(Close())); 00102 connect(m_thumbButton, SIGNAL(Clicked()), this, SLOT(doFileBrowser())); 00103 00104 m_urlEdit->SetMaxLength(0); 00105 m_titleEdit->SetMaxLength(255); 00106 m_descEdit->SetMaxLength(0); 00107 m_authorEdit->SetMaxLength(255); 00108 00109 if (m_editing) 00110 { 00111 m_site = findByURL(m_urlText, VIDEO_PODCAST); 00112 00113 m_urlEdit->SetText(m_urlText); 00114 m_titleEdit->SetText(m_site->GetTitle()); 00115 m_descEdit->SetText(m_site->GetDescription()); 00116 m_authorEdit->SetText(m_site->GetAuthor()); 00117 00118 QString thumb = m_site->GetImage(); 00119 if (!thumb.isEmpty()) 00120 { 00121 m_thumbImage->SetFilename(thumb); 00122 m_thumbImage->Load(); 00123 } 00124 00125 if (m_site->GetDownload() == 1) 00126 m_download->SetCheckState(MythUIStateType::Full); 00127 } 00128 00129 BuildFocusList(); 00130 00131 return true; 00132 } 00133 00134 bool RSSEditPopup::keyPressEvent(QKeyEvent *event) 00135 { 00136 if (GetFocusWidget()->keyPressEvent(event)) 00137 return true; 00138 00139 bool handled = false; 00140 QStringList actions; 00141 handled = GetMythMainWindow()->TranslateKeyPress("Internet Video", event, actions); 00142 00143 if (!handled && MythScreenType::keyPressEvent(event)) 00144 handled = true; 00145 00146 return handled; 00147 } 00148 00149 void RSSEditPopup::parseAndSave(void) 00150 { 00151 if (m_editing) 00152 { 00153 QString title = m_titleEdit->GetText(); 00154 QString desc = m_descEdit->GetText(); 00155 QString author = m_authorEdit->GetText(); 00156 QString link = m_urlEdit->GetText(); 00157 QString filename = m_thumbImage->GetFilename(); 00158 00159 bool download; 00160 if (m_download->GetCheckState() == MythUIStateType::Full) 00161 download = true; 00162 else 00163 download = false; 00164 00165 removeFromDB(m_urlText, VIDEO_PODCAST); 00166 00167 if (insertInDB(new RSSSite(title, filename, VIDEO_PODCAST, 00168 desc, link, author, download, QDateTime::currentDateTime()))) 00169 emit saving(); 00170 Close(); 00171 } 00172 else 00173 { 00174 m_manager = new QNetworkAccessManager(); 00175 QUrl qurl(m_urlEdit->GetText()); 00176 00177 m_reply = m_manager->get(QNetworkRequest(qurl)); 00178 00179 connect(m_manager, SIGNAL(finished(QNetworkReply*)), this, 00180 SLOT(slotCheckRedirect(QNetworkReply*))); 00181 } 00182 } 00183 00184 QUrl RSSEditPopup::redirectUrl(const QUrl& possibleRedirectUrl, 00185 const QUrl& oldRedirectUrl) const 00186 { 00187 QUrl redirectUrl; 00188 if(!possibleRedirectUrl.isEmpty() && possibleRedirectUrl != oldRedirectUrl) 00189 redirectUrl = possibleRedirectUrl; 00190 return redirectUrl; 00191 } 00192 00193 void RSSEditPopup::slotCheckRedirect(QNetworkReply* reply) 00194 { 00195 QVariant possibleRedirectUrl = 00196 reply->attribute(QNetworkRequest::RedirectionTargetAttribute); 00197 00198 QUrl urlRedirectedTo = redirectUrl(possibleRedirectUrl.toUrl(), 00199 urlRedirectedTo); 00200 00201 if(!urlRedirectedTo.isEmpty()) 00202 { 00203 m_urlEdit->SetText(urlRedirectedTo.toString()); 00204 m_manager->get(QNetworkRequest(urlRedirectedTo)); 00205 } 00206 else 00207 { 00208 // urlRedirectedTo.clear(); 00209 slotSave(reply); 00210 } 00211 reply->deleteLater(); 00212 } 00213 00214 void RSSEditPopup::slotSave(QNetworkReply* reply) 00215 { 00216 QDomDocument document; 00217 document.setContent(reply->read(reply->bytesAvailable()), true); 00218 00219 QString text = document.toString(); 00220 00221 QString title = m_titleEdit->GetText(); 00222 QString description = m_descEdit->GetText(); 00223 QString author = m_authorEdit->GetText(); 00224 QString file = m_thumbImage->GetFilename(); 00225 00226 LOG(VB_GENERAL, LOG_DEBUG, QString("Text to Parse: %1").arg(text)); 00227 00228 QDomElement root = document.documentElement(); 00229 QDomElement channel = root.firstChildElement ("channel"); 00230 if (!channel.isNull ()) 00231 { 00232 Parse parser; 00233 if (title.isEmpty()) 00234 title = channel.firstChildElement("title").text().trimmed(); 00235 if (description.isEmpty()) 00236 description = channel.firstChildElement("description").text(); 00237 if (author.isEmpty()) 00238 author = parser.GetAuthor(channel); 00239 if (author.isEmpty()) 00240 author = channel.firstChildElement("managingEditor").text(); 00241 if (author.isEmpty()) 00242 author = channel.firstChildElement("webMaster").text(); 00243 00244 QString thumbnailURL = channel.firstChildElement("image").attribute("url"); 00245 if (thumbnailURL.isEmpty()) 00246 { 00247 QDomElement thumbElem = channel.firstChildElement("image"); 00248 if (!thumbElem.isNull()) 00249 thumbnailURL = thumbElem.firstChildElement("url").text(); 00250 } 00251 if (thumbnailURL.isEmpty()) 00252 { 00253 QDomNodeList nodes = channel.elementsByTagNameNS( 00254 "http://www.itunes.com/dtds/podcast-1.0.dtd", "image"); 00255 if (nodes.size()) 00256 { 00257 thumbnailURL = nodes.at(0).toElement().attributeNode("href").value(); 00258 if (thumbnailURL.isEmpty()) 00259 thumbnailURL = nodes.at(0).toElement().text(); 00260 } 00261 } 00262 00263 bool download; 00264 if (m_download->GetCheckState() == MythUIStateType::Full) 00265 download = true; 00266 else 00267 download = false; 00268 00269 QDateTime updated = QDateTime::currentDateTime(); 00270 QString filename(""); 00271 00272 if (file.isEmpty()) 00273 filename = file; 00274 00275 QString link = m_urlEdit->GetText(); 00276 00277 if (!thumbnailURL.isEmpty() && filename.isEmpty()) 00278 { 00279 QString fileprefix = GetConfDir(); 00280 00281 QDir dir(fileprefix); 00282 if (!dir.exists()) 00283 dir.mkdir(fileprefix); 00284 00285 fileprefix += "/MythNetvision"; 00286 00287 dir = QDir(fileprefix); 00288 if (!dir.exists()) 00289 dir.mkdir(fileprefix); 00290 00291 fileprefix += "/sitecovers"; 00292 00293 dir = QDir(fileprefix); 00294 if (!dir.exists()) 00295 dir.mkdir(fileprefix); 00296 00297 QFileInfo fi(thumbnailURL); 00298 QString rawFilename = fi.fileName(); 00299 00300 filename = QString("%1/%2").arg(fileprefix).arg(rawFilename); 00301 00302 bool exists = QFile::exists(filename); 00303 if (!exists) 00304 HttpComms::getHttpFile(filename, thumbnailURL, 20000, 1, 2); 00305 } 00306 if (insertInDB(new RSSSite(title, filename, VIDEO_PODCAST, description, link, 00307 author, download, QDateTime::currentDateTime()))) 00308 emit saving(); 00309 } 00310 Close(); 00311 } 00312 00313 void RSSEditPopup::doFileBrowser() 00314 { 00315 SelectImagePopup(GetConfDir() + "/MythNetvision" + "/sitecovers", *this, CEID_NEWIMAGE); 00316 } 00317 00318 void RSSEditPopup::SelectImagePopup(const QString &prefix, 00319 QObject &inst, const QString &returnEvent) 00320 { 00321 MythScreenStack *popupStack = 00322 GetMythMainWindow()->GetStack("popup stack"); 00323 00324 MythUIFileBrowser *fb = new MythUIFileBrowser(popupStack, prefix); 00325 fb->SetNameFilter(GetSupportedImageExtensionFilter()); 00326 if (fb->Create()) 00327 { 00328 fb->SetReturnEvent(&inst, returnEvent); 00329 popupStack->AddScreen(fb); 00330 } 00331 else 00332 delete fb; 00333 } 00334 00335 void RSSEditPopup::customEvent(QEvent *levent) 00336 { 00337 if (levent->type() == DialogCompletionEvent::kEventType) 00338 { 00339 DialogCompletionEvent *dce = (DialogCompletionEvent*)(levent); 00340 if (dce->GetId() == CEID_NEWIMAGE) 00341 { 00342 m_thumbImage->SetFilename(dce->GetResultText()); 00343 m_thumbImage->Load(); 00344 m_thumbImage->Show(); 00345 } 00346 } 00347 } 00348 00349 RSSEditor::RSSEditor(MythScreenStack *parent, const QString &name) : 00350 MythScreenType(parent, name), m_lock(QMutex::Recursive), 00351 m_changed(false), m_sites(NULL), m_new(NULL), m_delete(NULL), m_edit(NULL), 00352 m_image(NULL), m_title(NULL), m_url(NULL), m_desc(NULL), m_author(NULL) 00353 { 00354 } 00355 00356 RSSEditor::~RSSEditor() 00357 { 00358 QMutexLocker locker(&m_lock); 00359 00360 if (m_changed) 00361 emit itemsChanged(); 00362 } 00363 00364 bool RSSEditor::Create(void) 00365 { 00366 QMutexLocker locker(&m_lock); 00367 00368 // Load the theme for this screen 00369 bool foundtheme = LoadWindowFromXML("netvision-ui.xml", "rsseditor", this); 00370 00371 if (!foundtheme) 00372 return false; 00373 00374 bool err = false; 00375 UIUtilE::Assign(this, m_sites, "sites", &err); 00376 UIUtilE::Assign(this, m_new, "new", &err); 00377 UIUtilE::Assign(this, m_delete, "delete", &err); 00378 UIUtilE::Assign(this, m_edit, "edit", &err); 00379 00380 UIUtilW::Assign(this, m_image, "preview"); 00381 UIUtilW::Assign(this, m_title, "title"); 00382 UIUtilW::Assign(this, m_desc, "description"); 00383 UIUtilW::Assign(this, m_url, "url"); 00384 UIUtilW::Assign(this, m_author, "author"); 00385 00386 if (err) 00387 { 00388 LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'rsseditor'"); 00389 return false; 00390 } 00391 00392 connect(m_sites, SIGNAL(itemClicked(MythUIButtonListItem*)), 00393 this, SLOT(slotEditSite(void))); 00394 00395 connect(m_delete, SIGNAL(Clicked(void)), 00396 SLOT(slotDeleteSite(void))); 00397 connect(m_edit, SIGNAL(Clicked(void)), 00398 SLOT(slotEditSite(void))); 00399 connect(m_new, SIGNAL(Clicked(void)), 00400 SLOT(slotNewSite(void))); 00401 00402 connect(m_sites, SIGNAL(itemSelected(MythUIButtonListItem *)), 00403 SLOT(slotItemChanged(void))); 00404 00405 BuildFocusList(); 00406 00407 loadData(); 00408 00409 if (m_sites->GetCount() == 0) 00410 SetFocusWidget(m_new); 00411 else 00412 slotItemChanged(); 00413 00414 return true; 00415 } 00416 00417 void RSSEditor::loadData() 00418 { 00419 qDeleteAll(m_siteList); 00420 m_siteList = findAllDBRSS(); 00421 fillRSSButtonList(); 00422 if (m_sites->GetCount() == 0) 00423 { 00424 m_edit->SetVisible(false); 00425 m_delete->SetVisible(false); 00426 m_sites->SetVisible(false); 00427 } 00428 else 00429 { 00430 m_edit->SetVisible(true); 00431 m_delete->SetVisible(true); 00432 m_sites->SetVisible(true); 00433 } 00434 } 00435 00436 bool RSSEditor::keyPressEvent(QKeyEvent *event) 00437 { 00438 if (GetFocusWidget()->keyPressEvent(event)) 00439 return true; 00440 00441 bool handled = false; 00442 QStringList actions; 00443 handled = GetMythMainWindow()->TranslateKeyPress("Internet Video", event, actions); 00444 00445 for (int i = 0; i < actions.size() && !handled; i++) 00446 { 00447 QString action = actions[i]; 00448 handled = true; 00449 00450 if (action == "DELETE" && GetFocusWidget() == m_sites) 00451 { 00452 slotDeleteSite(); 00453 } 00454 if (action == "EDIT" && GetFocusWidget() == m_sites) 00455 { 00456 slotEditSite(); 00457 } 00458 else 00459 handled = false; 00460 } 00461 00462 00463 if (!handled && MythScreenType::keyPressEvent(event)) 00464 handled = true; 00465 00466 return handled; 00467 } 00468 00469 void RSSEditor::fillRSSButtonList() 00470 { 00471 QMutexLocker locker(&m_lock); 00472 00473 m_sites->Reset(); 00474 00475 for (RSSSite::rssList::iterator i = m_siteList.begin(); 00476 i != m_siteList.end(); ++i) 00477 { 00478 MythUIButtonListItem *item = 00479 new MythUIButtonListItem(m_sites, (*i)->GetTitle()); 00480 if (item) 00481 { 00482 item->SetText((*i)->GetTitle(), "title"); 00483 item->SetText((*i)->GetDescription(), "description"); 00484 item->SetText((*i)->GetURL(), "url"); 00485 item->SetText((*i)->GetAuthor(), "author"); 00486 item->SetData(qVariantFromValue(*i)); 00487 item->SetImage((*i)->GetImage()); 00488 } 00489 else 00490 delete item; 00491 } 00492 } 00493 00494 void RSSEditor::slotItemChanged() 00495 { 00496 RSSSite *site = qVariantValue<RSSSite *>(m_sites->GetItemCurrent()->GetData()); 00497 00498 if (site) 00499 { 00500 if (m_image) 00501 { 00502 QString thumb = site->GetImage(); 00503 00504 m_image->Reset(); 00505 00506 if (!thumb.isEmpty()) 00507 { 00508 m_image->SetFilename(site->GetImage()); 00509 m_image->Load(); 00510 } 00511 } 00512 if (m_title) 00513 m_title->SetText(site->GetTitle()); 00514 if (m_desc) 00515 m_desc->SetText(site->GetDescription()); 00516 if (m_url) 00517 m_url->SetText(site->GetURL()); 00518 if (m_author) 00519 m_author->SetText(site->GetAuthor()); 00520 } 00521 } 00522 00523 void RSSEditor::slotDeleteSite() 00524 { 00525 QMutexLocker locker(&m_lock); 00526 00527 QString message = tr("Are you sure you want to unsubscribe from this feed?"); 00528 00529 MythScreenStack *m_popupStack = GetMythMainWindow()->GetStack("popup stack"); 00530 00531 MythConfirmationDialog *confirmdialog = 00532 new MythConfirmationDialog(m_popupStack,message); 00533 00534 if (confirmdialog->Create()) 00535 { 00536 m_popupStack->AddScreen(confirmdialog); 00537 00538 connect(confirmdialog, SIGNAL(haveResult(bool)), 00539 SLOT(doDeleteSite(bool))); 00540 } 00541 else 00542 delete confirmdialog; 00543 } 00544 00545 void RSSEditor::slotEditSite() 00546 { 00547 QMutexLocker locker(&m_lock); 00548 00549 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack(); 00550 00551 RSSSite *site = qVariantValue<RSSSite *>(m_sites->GetItemCurrent()->GetData()); 00552 00553 if (site) 00554 { 00555 RSSEditPopup *rsseditpopup = new RSSEditPopup(site->GetURL(), true, mainStack, "rsseditpopup"); 00556 00557 if (rsseditpopup->Create()) 00558 { 00559 connect(rsseditpopup, SIGNAL(saving()), this, 00560 SLOT(listChanged())); 00561 00562 mainStack->AddScreen(rsseditpopup); 00563 } 00564 else 00565 { 00566 delete rsseditpopup; 00567 } 00568 } 00569 } 00570 00571 void RSSEditor::slotNewSite() 00572 { 00573 QMutexLocker locker(&m_lock); 00574 00575 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack(); 00576 00577 RSSEditPopup *rsseditpopup = new RSSEditPopup("", false, mainStack, "rsseditpopup"); 00578 00579 if (rsseditpopup->Create()) 00580 { 00581 connect(rsseditpopup, SIGNAL(saving()), this, 00582 SLOT(listChanged())); 00583 00584 mainStack->AddScreen(rsseditpopup); 00585 } 00586 else 00587 { 00588 delete rsseditpopup; 00589 } 00590 } 00591 00592 void RSSEditor::doDeleteSite(bool remove) 00593 { 00594 QMutexLocker locker(&m_lock); 00595 00596 if (!remove) 00597 return; 00598 00599 RSSSite *site = qVariantValue<RSSSite *>(m_sites->GetItemCurrent()->GetData()); 00600 00601 if (removeFromDB(site)) 00602 listChanged(); 00603 } 00604 00605 void RSSEditor::listChanged() 00606 { 00607 m_changed = true; 00608 loadData(); 00609 }
1.7.6.1