|
MythTV
0.26-pre
|
00001 // POSIX headers 00002 #include <unistd.h> 00003 00004 // C headers 00005 #include <cmath> 00006 00007 // QT headers 00008 #include <QApplication> 00009 #include <QDateTime> 00010 #include <QDir> 00011 #include <QTimer> 00012 #include <QRegExp> 00013 #include <QUrl> 00014 00015 // MythTV headers 00016 #include <mythuitext.h> 00017 #include <mythuiimage.h> 00018 #include <mythdialogbox.h> 00019 #include <mythuibuttonlist.h> 00020 #include <mythprogressdialog.h> 00021 00022 #include <mythmainwindow.h> 00023 #include <mythmiscutil.h> 00024 #include <httpcomms.h> 00025 #include <mythcontext.h> 00026 #include <mythdb.h> 00027 #include <mythdirs.h> 00028 00029 // MythNews headers 00030 #include "mythnews.h" 00031 #include "mythnewseditor.h" 00032 #include "newsdbutil.h" 00033 #include "mythnewsconfig.h" 00034 00035 #define LOC QString("MythNews: ") 00036 #define LOC_WARN QString("MythNews, Warning: ") 00037 #define LOC_ERR QString("MythNews, Error: ") 00038 00043 MythNews::MythNews(MythScreenStack *parent, const QString &name) : 00044 MythScreenType(parent, name), 00045 m_lock(QMutex::Recursive) 00046 { 00047 // Setup cache directory 00048 00049 QString fileprefix = GetConfDir(); 00050 00051 QDir dir(fileprefix); 00052 if (!dir.exists()) 00053 dir.mkdir(fileprefix); 00054 fileprefix += "/MythNews"; 00055 dir = QDir(fileprefix); 00056 if (!dir.exists()) 00057 dir.mkdir(fileprefix); 00058 00059 m_zoom = gCoreContext->GetSetting("WebBrowserZoomLevel", "1.4"); 00060 m_browser = gCoreContext->GetSetting("WebBrowserCommand", ""); 00061 00062 // Initialize variables 00063 00064 m_sitesList = m_articlesList = NULL; 00065 m_updatedText = m_titleText = m_descText = NULL; 00066 m_thumbnailImage = m_downloadImage = m_enclosureImage = NULL; 00067 m_menuPopup = NULL; 00068 m_progressPopup = NULL; 00069 00070 m_TimerTimeout = 10*60*1000; 00071 m_httpGrabber = NULL; 00072 00073 // Now do the actual work 00074 m_RetrieveTimer = new QTimer(this); 00075 connect(m_RetrieveTimer, SIGNAL(timeout()), 00076 this, SLOT(slotRetrieveNews())); 00077 m_UpdateFreq = gCoreContext->GetNumSetting("NewsUpdateFrequency", 30); 00078 00079 m_RetrieveTimer->stop(); 00080 m_RetrieveTimer->setSingleShot(false); 00081 m_RetrieveTimer->start(m_TimerTimeout); 00082 } 00083 00084 MythNews::~MythNews() 00085 { 00086 QMutexLocker locker(&m_lock); 00087 } 00088 00089 bool MythNews::Create(void) 00090 { 00091 QMutexLocker locker(&m_lock); 00092 00093 bool foundtheme = false; 00094 00095 // Load the theme for this screen 00096 foundtheme = LoadWindowFromXML("news-ui.xml", "news", this); 00097 00098 if (!foundtheme) 00099 return false; 00100 00101 bool err = false; 00102 UIUtilE::Assign(this, m_sitesList, "siteslist", &err); 00103 UIUtilE::Assign(this, m_articlesList, "articleslist", &err); 00104 UIUtilE::Assign(this, m_titleText, "title", &err); 00105 UIUtilE::Assign(this, m_descText, "description", &err); 00106 00107 // these are all optional 00108 UIUtilW::Assign(this, m_nositesText, "nosites", &err); 00109 UIUtilW::Assign(this, m_updatedText, "updated", &err); 00110 UIUtilW::Assign(this, m_thumbnailImage, "thumbnail", &err); 00111 UIUtilW::Assign(this, m_enclosureImage, "enclosures", &err); 00112 UIUtilW::Assign(this, m_downloadImage, "download", &err); 00113 UIUtilW::Assign(this, m_podcastImage, "ispodcast", &err); 00114 00115 if (err) 00116 { 00117 LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'news'"); 00118 return false; 00119 } 00120 00121 if (m_nositesText) 00122 { 00123 m_nositesText->SetText(tr("You haven't configured MythNews to use any sites.")); 00124 m_nositesText->Hide(); 00125 } 00126 00127 BuildFocusList(); 00128 00129 SetFocusWidget(m_sitesList); 00130 00131 loadSites(); 00132 updateInfoView(m_sitesList->GetItemFirst()); 00133 00134 connect(m_sitesList, SIGNAL(itemSelected(MythUIButtonListItem*)), 00135 this, SLOT( slotSiteSelected(MythUIButtonListItem*))); 00136 connect(m_articlesList, SIGNAL(itemSelected( MythUIButtonListItem*)), 00137 this, SLOT( updateInfoView(MythUIButtonListItem*))); 00138 connect(m_articlesList, SIGNAL(itemClicked( MythUIButtonListItem*)), 00139 this, SLOT( slotViewArticle(MythUIButtonListItem*))); 00140 00141 return true; 00142 } 00143 00144 void MythNews::clearSites(void) 00145 { 00146 m_NewsSites.clear(); 00147 m_sitesList->Reset(); 00148 m_articles.clear(); 00149 m_articlesList->Reset(); 00150 00151 m_titleText->Reset(); 00152 m_descText->Reset(); 00153 00154 if (m_updatedText) 00155 m_updatedText->Reset(); 00156 00157 if (m_downloadImage) 00158 m_downloadImage->Hide(); 00159 00160 if (m_enclosureImage) 00161 m_enclosureImage->Hide(); 00162 00163 if (m_podcastImage) 00164 m_podcastImage->Hide(); 00165 00166 if (m_thumbnailImage) 00167 m_thumbnailImage->Hide(); 00168 } 00169 00170 void MythNews::loadSites(void) 00171 { 00172 QMutexLocker locker(&m_lock); 00173 00174 clearSites(); 00175 00176 MSqlQuery query(MSqlQuery::InitCon()); 00177 query.prepare( 00178 "SELECT name, url, ico, updated, podcast " 00179 "FROM newssites " 00180 "ORDER BY name"); 00181 00182 if (!query.exec()) 00183 { 00184 MythDB::DBError(LOC_ERR + "Could not load sites from DB", query); 00185 return; 00186 } 00187 00188 while (query.next()) 00189 { 00190 QString name = query.value(0).toString(); 00191 QString url = query.value(1).toString(); 00192 QString icon = query.value(2).toString(); 00193 QDateTime time; time.setTime_t(query.value(3).toUInt()); 00194 bool podcast = query.value(4).toInt(); 00195 m_NewsSites.push_back(new NewsSite(name, url, time, podcast)); 00196 } 00197 00198 NewsSite::List::iterator it = m_NewsSites.begin(); 00199 for (; it != m_NewsSites.end(); ++it) 00200 { 00201 MythUIButtonListItem *item = 00202 new MythUIButtonListItem(m_sitesList, (*it)->name()); 00203 item->SetData(qVariantFromValue(*it)); 00204 00205 connect(*it, SIGNAL(finished(NewsSite*)), 00206 this, SLOT(slotNewsRetrieved(NewsSite*))); 00207 } 00208 00209 slotRetrieveNews(); 00210 00211 if (m_nositesText) 00212 { 00213 if (m_NewsSites.size() == 0) 00214 m_nositesText->Show(); 00215 else 00216 m_nositesText->Hide(); 00217 } 00218 } 00219 00220 void MythNews::updateInfoView(MythUIButtonListItem *selected) 00221 { 00222 QMutexLocker locker(&m_lock); 00223 00224 if (!selected) 00225 return; 00226 00227 NewsSite *site = NULL; 00228 NewsArticle article; 00229 00230 if (GetFocusWidget() == m_articlesList) 00231 { 00232 article = m_articles[selected]; 00233 if (m_sitesList->GetItemCurrent()) 00234 site = qVariantValue<NewsSite*> 00235 (m_sitesList->GetItemCurrent()->GetData()); 00236 } 00237 else 00238 { 00239 site = qVariantValue<NewsSite*>(selected->GetData()); 00240 if (m_articlesList->GetItemCurrent()) 00241 article = m_articles[m_articlesList->GetItemCurrent()]; 00242 } 00243 00244 if (GetFocusWidget() == m_articlesList) 00245 { 00246 if (!article.title().isEmpty()) 00247 { 00248 00249 if (m_titleText) 00250 m_titleText->SetText(article.title()); 00251 00252 if (m_descText) 00253 { 00254 QString artText = article.description(); 00255 // Replace paragraph and break HTML with newlines 00256 if( artText.indexOf(QRegExp("</(p|P)>")) ) 00257 { 00258 artText.replace( QRegExp("<(p|P)>"), ""); 00259 artText.replace( QRegExp("</(p|P)>"), "\n\n"); 00260 } 00261 else 00262 { 00263 artText.replace( QRegExp("<(p|P)>"), "\n\n"); 00264 artText.replace( QRegExp("</(p|P)>"), ""); 00265 } 00266 artText.replace( QRegExp("<(br|BR|)/>"), "\n"); 00267 artText.replace( QRegExp("<(br|BR|)>"), "\n"); 00268 // These are done instead of simplifyWhitespace 00269 // because that function also strips out newlines 00270 // Replace tab characters with nothing 00271 artText.replace( QRegExp("\t"), ""); 00272 // Replace double space with single 00273 artText.replace( QRegExp(" "), ""); 00274 // Replace whitespace at beginning of lines with newline 00275 artText.replace( QRegExp("\n "), "\n"); 00276 // Remove any remaining HTML tags 00277 QRegExp removeHTML(QRegExp("</?.+>")); 00278 removeHTML.setMinimal(true); 00279 artText.remove((const QRegExp&) removeHTML); 00280 artText = artText.trimmed(); 00281 m_descText->SetText(artText); 00282 } 00283 00284 if (!article.thumbnail().isEmpty()) 00285 { 00286 QString fileprefix = GetConfDir(); 00287 00288 QDir dir(fileprefix); 00289 if (!dir.exists()) 00290 dir.mkdir(fileprefix); 00291 00292 fileprefix += "/MythNews/tcache"; 00293 00294 dir = QDir(fileprefix); 00295 if (!dir.exists()) 00296 dir.mkdir(fileprefix); 00297 00298 QString url = article.thumbnail(); 00299 QString sFilename = QString("%1/%2") 00300 .arg(fileprefix) 00301 .arg(qChecksum(url.toLocal8Bit().constData(), 00302 url.toLocal8Bit().size())); 00303 00304 bool exists = QFile::exists(sFilename); 00305 if (!exists) 00306 HttpComms::getHttpFile(sFilename, url, 20000, 1, 2); 00307 00308 if (m_thumbnailImage) 00309 { 00310 m_thumbnailImage->SetFilename(sFilename); 00311 m_thumbnailImage->Load(); 00312 00313 if (!m_thumbnailImage->IsVisible()) 00314 m_thumbnailImage->Show(); 00315 } 00316 } 00317 else 00318 { 00319 if (m_thumbnailImage) 00320 m_thumbnailImage->Hide(); 00321 00322 if (!site->imageURL().isEmpty()) 00323 { 00324 QString fileprefix = GetConfDir(); 00325 00326 QDir dir(fileprefix); 00327 if (!dir.exists()) 00328 dir.mkdir(fileprefix); 00329 00330 fileprefix += "/MythNews/scache"; 00331 00332 dir = QDir(fileprefix); 00333 if (!dir.exists()) 00334 dir.mkdir(fileprefix); 00335 00336 QString url = site->imageURL(); 00337 QString extension = url.section('.', -1); 00338 00339 QString sitename = site->name(); 00340 QString sFilename = QString("%1/%2.%3").arg(fileprefix) 00341 .arg(sitename) 00342 .arg(extension); 00343 00344 bool exists = QFile::exists(sFilename); 00345 if (!exists) 00346 HttpComms::getHttpFile(sFilename, url, 20000, 1, 2); 00347 00348 if (m_thumbnailImage) 00349 { 00350 m_thumbnailImage->SetFilename(sFilename); 00351 m_thumbnailImage->Load(); 00352 00353 if (!m_thumbnailImage->IsVisible()) 00354 m_thumbnailImage->Show(); 00355 } 00356 } 00357 } 00358 00359 if (m_downloadImage) 00360 { 00361 if (!article.enclosure().isEmpty()) 00362 { 00363 if (!m_downloadImage->IsVisible()) 00364 m_downloadImage->Show(); 00365 } 00366 else 00367 m_downloadImage->Hide(); 00368 } 00369 00370 if (m_enclosureImage) 00371 { 00372 if (!article.enclosure().isEmpty()) 00373 { 00374 if (!m_enclosureImage->IsVisible()) 00375 m_enclosureImage->Show(); 00376 } 00377 else 00378 m_enclosureImage->Hide(); 00379 } 00380 00381 if (m_podcastImage) 00382 m_podcastImage->Hide(); 00383 } 00384 } 00385 else 00386 { 00387 if (m_downloadImage) 00388 m_downloadImage->Hide(); 00389 00390 if (m_enclosureImage) 00391 m_enclosureImage->Hide(); 00392 00393 if (m_podcastImage) 00394 m_podcastImage->Hide(); 00395 00396 if (site) 00397 { 00398 if (m_titleText) 00399 m_titleText->SetText(site->name()); 00400 00401 if (m_descText) 00402 m_descText->SetText(site->description()); 00403 00404 if (m_thumbnailImage && m_thumbnailImage->IsVisible()) 00405 m_thumbnailImage->Hide(); 00406 00407 if (m_podcastImage && site->podcast() == 1) 00408 m_podcastImage->Show(); 00409 00410 if (!site->imageURL().isEmpty()) 00411 { 00412 QString fileprefix = GetConfDir(); 00413 00414 QDir dir(fileprefix); 00415 if (!dir.exists()) 00416 dir.mkdir(fileprefix); 00417 00418 fileprefix += "/MythNews/scache"; 00419 00420 dir = QDir(fileprefix); 00421 if (!dir.exists()) 00422 dir.mkdir(fileprefix); 00423 00424 QString url = site->imageURL(); 00425 QString extension = url.section('.', -1); 00426 00427 QString sitename = site->name(); 00428 QString sFilename = QString("%1/%2.%3").arg(fileprefix) 00429 .arg(sitename) 00430 .arg(extension); 00431 00432 bool exists = QFile::exists(sFilename); 00433 if (!exists) 00434 HttpComms::getHttpFile(sFilename, url, 20000, 1, 2); 00435 00436 if (m_thumbnailImage) 00437 { 00438 m_thumbnailImage->SetFilename(sFilename); 00439 m_thumbnailImage->Load(); 00440 00441 if (!m_thumbnailImage->IsVisible()) 00442 m_thumbnailImage->Show(); 00443 } 00444 } 00445 } 00446 } 00447 00448 if (m_updatedText) 00449 { 00450 00451 if (site) 00452 { 00453 QString text(tr("Updated") + " - "); 00454 QDateTime updated(site->lastUpdated()); 00455 if (updated.toTime_t() != 0) { 00456 text += MythDateTimeToString(site->lastUpdated(), 00457 kDateTimeFull | kSimplify); 00458 } 00459 else 00460 text += tr("Unknown"); 00461 m_updatedText->SetText(text); 00462 } 00463 00464 if (m_httpGrabber != NULL) 00465 { 00466 int progress = m_httpGrabber->getProgress(); 00467 int total = m_httpGrabber->getTotal(); 00468 if ((progress > 0) && (total > 0) && (progress < total)) 00469 { 00470 float fProgress = (float)progress/total; 00471 QString text = tr("%1 of %2 (%3 percent)") 00472 .arg(formatSize(progress, 2)) 00473 .arg(formatSize(total, 2)) 00474 .arg(floor(fProgress*100)); 00475 m_updatedText->SetText(text); 00476 } 00477 } 00478 } 00479 } 00480 00481 QString MythNews::formatSize(long long bytes, int prec) 00482 { 00483 long long sizeKB = bytes / 1024; 00484 00485 if (sizeKB>1024*1024*1024) // Terabytes 00486 { 00487 double sizeGB = sizeKB/(1024*1024*1024.0); 00488 return QString("%1 TB").arg(sizeGB, 0, 'f', (sizeGB>10)?0:prec); 00489 } 00490 else if (sizeKB>1024*1024) // Gigabytes 00491 { 00492 double sizeGB = sizeKB/(1024*1024.0); 00493 return QString("%1 GB").arg(sizeGB, 0, 'f', (sizeGB>10)?0:prec); 00494 } 00495 else if (sizeKB>1024) // Megabytes 00496 { 00497 double sizeMB = sizeKB/1024.0; 00498 return QString("%1 MB").arg(sizeMB, 0, 'f', (sizeMB>10)?0:prec); 00499 } 00500 // Kilobytes 00501 return QString("%1 KB").arg(sizeKB); 00502 } 00503 00504 bool MythNews::keyPressEvent(QKeyEvent *event) 00505 { 00506 if (GetFocusWidget() && GetFocusWidget()->keyPressEvent(event)) 00507 return true; 00508 00509 bool handled = false; 00510 QStringList actions; 00511 handled = GetMythMainWindow()->TranslateKeyPress("News", event, actions); 00512 00513 for (int i = 0; i < actions.size() && !handled; i++) 00514 { 00515 QString action = actions[i]; 00516 handled = true; 00517 00518 if (action == "RETRIEVENEWS") 00519 slotRetrieveNews(); 00520 else if (action == "CANCEL") 00521 cancelRetrieve(); 00522 else if (action == "MENU") 00523 ShowMenu(); 00524 else if (action == "EDIT") 00525 ShowEditDialog(true); 00526 else if (action == "DELETE") 00527 deleteNewsSite(); 00528 else if (action == "ESCAPE") 00529 { 00530 { 00531 QMutexLocker locker(&m_lock); 00532 00533 if (m_progressPopup) 00534 { 00535 m_progressPopup->Close(); 00536 m_progressPopup = NULL; 00537 } 00538 00539 m_RetrieveTimer->stop(); 00540 00541 if (m_httpGrabber) 00542 m_abortHttp = true; 00543 } 00544 00545 Close(); 00546 } 00547 else 00548 handled = false; 00549 } 00550 00551 if (!handled && MythScreenType::keyPressEvent(event)) 00552 handled = true; 00553 00554 return handled; 00555 } 00556 00557 void MythNews::slotRetrieveNews(void) 00558 { 00559 QMutexLocker locker(&m_lock); 00560 00561 if (m_NewsSites.empty()) 00562 return; 00563 00564 m_RetrieveTimer->stop(); 00565 00566 NewsSite::List::iterator it = m_NewsSites.begin(); 00567 for (; it != m_NewsSites.end(); ++it) 00568 { 00569 if ((*it)->timeSinceLastUpdate() > m_UpdateFreq) 00570 (*it)->retrieve(); 00571 else 00572 processAndShowNews(*it); 00573 } 00574 00575 m_RetrieveTimer->stop(); 00576 m_RetrieveTimer->setSingleShot(false); 00577 m_RetrieveTimer->start(m_TimerTimeout); 00578 } 00579 00580 void MythNews::slotNewsRetrieved(NewsSite *site) 00581 { 00582 unsigned int updated = site->lastUpdated().toTime_t(); 00583 00584 MSqlQuery query(MSqlQuery::InitCon()); 00585 query.prepare("UPDATE newssites SET updated = :UPDATED " 00586 "WHERE name = :NAME ;"); 00587 query.bindValue(":UPDATED", updated); 00588 query.bindValue(":NAME", site->name()); 00589 if (!query.exec() || !query.isActive()) 00590 MythDB::DBError("news update time", query); 00591 00592 processAndShowNews(site); 00593 } 00594 00595 void MythNews::cancelRetrieve(void) 00596 { 00597 QMutexLocker locker(&m_lock); 00598 00599 NewsSite::List::iterator it = m_NewsSites.begin(); 00600 for (; it != m_NewsSites.end(); ++it) 00601 { 00602 (*it)->stop(); 00603 processAndShowNews(*it); 00604 } 00605 } 00606 00607 void MythNews::processAndShowNews(NewsSite *site) 00608 { 00609 QMutexLocker locker(&m_lock); 00610 00611 if (!site) 00612 return; 00613 00614 site->process(); 00615 00616 MythUIButtonListItem *siteUIItem = m_sitesList->GetItemCurrent(); 00617 if (!siteUIItem) 00618 return; 00619 00620 if (site != qVariantValue<NewsSite*>(siteUIItem->GetData())) 00621 return; 00622 00623 m_articlesList->Reset(); 00624 m_articles.clear(); 00625 00626 NewsArticle::List articles = site->GetArticleList(); 00627 NewsArticle::List::iterator it = articles.begin(); 00628 for (; it != articles.end(); ++it) 00629 { 00630 MythUIButtonListItem *item = 00631 new MythUIButtonListItem(m_articlesList, (*it).title()); 00632 m_articles[item] = *it; 00633 } 00634 } 00635 00636 void MythNews::slotSiteSelected(MythUIButtonListItem *item) 00637 { 00638 QMutexLocker locker(&m_lock); 00639 00640 if (!item || item->GetData().isNull()) 00641 return; 00642 00643 NewsSite *site = qVariantValue<NewsSite*>(item->GetData()); 00644 if (!site) 00645 return; 00646 00647 m_articlesList->Reset(); 00648 m_articles.clear(); 00649 00650 NewsArticle::List articles = site->GetArticleList(); 00651 NewsArticle::List::iterator it = articles.begin(); 00652 for (; it != articles.end(); ++it) 00653 { 00654 MythUIButtonListItem *item = 00655 new MythUIButtonListItem(m_articlesList, (*it).title()); 00656 m_articles[item] = *it; 00657 } 00658 00659 updateInfoView(item); 00660 } 00661 00662 void MythNews::slotProgressCancelled(void) 00663 { 00664 QMutexLocker locker(&m_lock); 00665 00666 m_abortHttp = true; 00667 } 00668 00669 void MythNews::createProgress(const QString &title) 00670 { 00671 QMutexLocker locker(&m_lock); 00672 00673 if (m_progressPopup) 00674 return; 00675 00676 QString message = title; 00677 00678 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack"); 00679 00680 m_progressPopup = new MythUIProgressDialog(message, popupStack, 00681 "mythnewsprogressdialog"); 00682 00683 if (m_progressPopup->Create()) 00684 popupStack->AddScreen(m_progressPopup, false); 00685 else 00686 { 00687 delete m_progressPopup; 00688 m_progressPopup = NULL; 00689 } 00690 } 00691 00692 bool MythNews::getHttpFile(const QString &sFilename, const QString &cmdURL) 00693 { 00694 QMutexLocker locker(&m_lock); 00695 00696 int redirectCount = 0; 00697 QByteArray data(0); 00698 bool res = false; 00699 m_httpGrabber = NULL; 00700 QString hostname; 00701 QString fileUrl = cmdURL; 00702 00703 createProgress(QObject::tr("Downloading media...")); 00704 while (1) 00705 { 00706 QUrl qurl(fileUrl); 00707 if (hostname.isEmpty()) 00708 hostname = qurl.host(); // hold onto original host 00709 00710 if (qurl.host().isEmpty()) // can occur on redirects to partial paths 00711 qurl.setHost(hostname); 00712 00713 if (m_httpGrabber != NULL) 00714 delete m_httpGrabber; 00715 00716 m_httpGrabber = new HttpComms; 00717 m_abortHttp = false; 00718 00719 m_httpGrabber->request(qurl, -1, true); 00720 00721 while ((!m_httpGrabber->isDone()) && (!m_abortHttp)) 00722 { 00723 int progress = m_httpGrabber->getProgress(); 00724 int total = m_httpGrabber->getTotal(); 00725 if ((progress > 0) && (total > 5120) && (progress < total)) // Ignore total less than 5kb as we're probably looking at a redirect page or similar 00726 { 00727 m_progressPopup->SetTotal(total); 00728 m_progressPopup->SetProgress(progress); 00729 float fProgress = (float)progress/total; 00730 QString text = tr("%1 of %2 (%3 percent)") 00731 .arg(formatSize(progress, 2)) 00732 .arg(formatSize(total, 2)) 00733 .arg(floor(fProgress*100)); 00734 if (m_updatedText) 00735 m_updatedText->SetText(text); 00736 } 00737 qApp->processEvents(); 00738 usleep(100000); 00739 } 00740 00741 if (m_abortHttp) 00742 break; 00743 00744 // Check for redirection 00745 if (!m_httpGrabber->getRedirectedURL().isEmpty()) 00746 { 00747 if (redirectCount++ < 3) 00748 fileUrl = m_httpGrabber->getRedirectedURL(); 00749 00750 // Try again 00751 continue; 00752 } 00753 00754 if (m_httpGrabber->getStatusCode() > 400) 00755 { 00756 // Error, request failed 00757 break; 00758 } 00759 00760 data = m_httpGrabber->getRawData(); 00761 00762 if (data.size() > 0) 00763 { 00764 QFile file(sFilename); 00765 if (file.open(QIODevice::WriteOnly)) 00766 { 00767 file.write(data); 00768 file.close(); 00769 res = true; 00770 } 00771 } 00772 break; 00773 } 00774 00775 if (m_progressPopup) 00776 { 00777 m_progressPopup->Close(); 00778 m_progressPopup = NULL; 00779 } 00780 00781 delete m_httpGrabber; 00782 m_httpGrabber = NULL; 00783 return res; 00784 00785 } 00786 00787 void MythNews::slotViewArticle(MythUIButtonListItem *articlesListItem) 00788 { 00789 QMutexLocker locker(&m_lock); 00790 00791 QMap<MythUIButtonListItem*,NewsArticle>::const_iterator it = 00792 m_articles.find(articlesListItem); 00793 00794 if (it == m_articles.end()) 00795 return; 00796 00797 const NewsArticle article = *it; 00798 00799 if (article.articleURL().isEmpty()) 00800 return; 00801 00802 if (article.enclosure().isEmpty()) 00803 { 00804 QString cmdUrl(article.articleURL()); 00805 00806 if (m_browser.isEmpty()) 00807 { 00808 ShowOkPopup(tr("No browser command set! MythNews needs MythBrowser to be installed.")); 00809 return; 00810 } 00811 00812 // display the web page 00813 if (m_browser.toLower() == "internal") 00814 { 00815 GetMythMainWindow()->HandleMedia("WebBrowser", cmdUrl); 00816 return; 00817 } 00818 else 00819 { 00820 QString cmd = m_browser; 00821 cmd.replace("%ZOOM%", m_zoom); 00822 cmd.replace("%URL%", cmdUrl); 00823 cmd.replace('\'', "%27"); 00824 cmd.replace("&","\\&"); 00825 cmd.replace(";","\\;"); 00826 00827 GetMythMainWindow()->AllowInput(false); 00828 myth_system(cmd, kMSDontDisableDrawing); 00829 GetMythMainWindow()->AllowInput(true); 00830 return; 00831 } 00832 } 00833 00834 playVideo(article); 00835 } 00836 00837 void MythNews::ShowEditDialog(bool edit) 00838 { 00839 QMutexLocker locker(&m_lock); 00840 00841 NewsSite *site = NULL; 00842 00843 if (edit) 00844 { 00845 MythUIButtonListItem *siteListItem = m_sitesList->GetItemCurrent(); 00846 00847 if (!siteListItem || siteListItem->GetData().isNull()) 00848 return; 00849 00850 site = qVariantValue<NewsSite*>(siteListItem->GetData()); 00851 } 00852 00853 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack(); 00854 00855 MythNewsEditor *mythnewseditor = new MythNewsEditor(site, edit, mainStack, 00856 "mythnewseditor"); 00857 00858 if (mythnewseditor->Create()) 00859 { 00860 connect(mythnewseditor, SIGNAL(Exiting()), SLOT(loadSites())); 00861 mainStack->AddScreen(mythnewseditor); 00862 } 00863 else 00864 delete mythnewseditor; 00865 } 00866 00867 void MythNews::ShowFeedManager() 00868 { 00869 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack(); 00870 00871 MythNewsConfig *mythnewsconfig = new MythNewsConfig(mainStack, 00872 "mythnewsconfig"); 00873 00874 if (mythnewsconfig->Create()) 00875 { 00876 connect(mythnewsconfig, SIGNAL(Exiting()), SLOT(loadSites())); 00877 mainStack->AddScreen(mythnewsconfig); 00878 } 00879 else 00880 delete mythnewsconfig; 00881 } 00882 00883 void MythNews::ShowMenu(void) 00884 { 00885 QMutexLocker locker(&m_lock); 00886 00887 QString label = tr("Options"); 00888 00889 MythScreenStack *popupStack = 00890 GetMythMainWindow()->GetStack("popup stack"); 00891 00892 m_menuPopup = new MythDialogBox(label, popupStack, "mythnewsmenupopup"); 00893 00894 if (m_menuPopup->Create()) 00895 { 00896 popupStack->AddScreen(m_menuPopup); 00897 00898 m_menuPopup->SetReturnEvent(this, "options"); 00899 00900 m_menuPopup->AddButton(tr("Manage Feeds")); 00901 m_menuPopup->AddButton(tr("Add Feed")); 00902 if (m_NewsSites.size() > 0) 00903 { 00904 m_menuPopup->AddButton(tr("Edit Feed")); 00905 m_menuPopup->AddButton(tr("Delete Feed")); 00906 } 00907 } 00908 else 00909 { 00910 delete m_menuPopup; 00911 m_menuPopup = NULL; 00912 } 00913 } 00914 00915 void MythNews::deleteNewsSite(void) 00916 { 00917 QMutexLocker locker(&m_lock); 00918 00919 MythUIButtonListItem *siteUIItem = m_sitesList->GetItemCurrent(); 00920 00921 if (siteUIItem && !siteUIItem->GetData().isNull()) 00922 { 00923 NewsSite *site = qVariantValue<NewsSite*>(siteUIItem->GetData()); 00924 if (site) 00925 { 00926 removeFromDB(site->name()); 00927 loadSites(); 00928 } 00929 } 00930 } 00931 00932 // does not need locking 00933 void MythNews::playVideo(const NewsArticle &article) 00934 { 00935 GetMythMainWindow()->HandleMedia("Internal", article.enclosure(), 00936 article.description(), article.title()); 00937 } 00938 00939 // does not need locking 00940 void MythNews::customEvent(QEvent *event) 00941 { 00942 if (event->type() == DialogCompletionEvent::kEventType) 00943 { 00944 DialogCompletionEvent *dce = (DialogCompletionEvent*)(event); 00945 00946 QString resultid = dce->GetId(); 00947 int buttonnum = dce->GetResult(); 00948 00949 if (resultid == "options") 00950 { 00951 if (m_NewsSites.size() > 0) 00952 { 00953 if (buttonnum == 0) 00954 ShowFeedManager(); 00955 else if (buttonnum == 1) 00956 ShowEditDialog(false); 00957 else if (buttonnum == 2) 00958 ShowEditDialog(true); 00959 else if (buttonnum == 3) 00960 deleteNewsSite(); 00961 } 00962 else 00963 if (buttonnum == 0) 00964 ShowEditDialog(false); 00965 } 00966 00967 m_menuPopup = NULL; 00968 } 00969 }
1.7.6.1