00001
00002 #include <unistd.h>
00003
00004
00005 #include <cmath>
00006
00007
00008 #include <QApplication>
00009 #include <QDateTime>
00010 #include <QDir>
00011 #include <QTimer>
00012 #include <QRegExp>
00013 #include <QUrl>
00014
00015
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
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
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
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
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
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
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
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
00269
00270
00271 artText.replace( QRegExp("\t"), "");
00272
00273 artText.replace( QRegExp(" "), "");
00274
00275 artText.replace( QRegExp("\n "), "\n");
00276
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)
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)
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)
00496 {
00497 double sizeMB = sizeKB/1024.0;
00498 return QString("%1 MB").arg(sizeMB, 0, 'f', (sizeMB>10)?0:prec);
00499 }
00500
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();
00709
00710 if (qurl.host().isEmpty())
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))
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
00745 if (!m_httpGrabber->getRedirectedURL().isEmpty())
00746 {
00747 if (redirectCount++ < 3)
00748 fileUrl = m_httpGrabber->getRedirectedURL();
00749
00750
00751 continue;
00752 }
00753
00754 if (m_httpGrabber->getStatusCode() > 400)
00755 {
00756
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
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
00933 void MythNews::playVideo(const NewsArticle &article)
00934 {
00935 GetMythMainWindow()->HandleMedia("Internal", article.enclosure(),
00936 article.description(), article.title());
00937 }
00938
00939
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 }