MythTV  master
mythnews.cpp
Go to the documentation of this file.
1 // POSIX headers
2 #include <unistd.h>
3 
4 // C headers
5 #include <cmath>
6 
7 // QT headers
8 #include <QCoreApplication>
9 #include <QDateTime>
10 #include <QDir>
11 #include <QRegularExpression>
12 #include <QTimer>
13 #include <QUrl>
14 
15 // MythTV headers
16 #include <libmyth/mythcontext.h>
17 #include <libmythbase/mythdate.h>
18 #include <libmythbase/mythdb.h>
19 #include <libmythbase/mythdirs.h>
25 #include <libmythui/mythuiimage.h>
26 #include <libmythui/mythuitext.h>
27 
28 // MythNews headers
29 #include "mythnews.h"
30 #include "mythnewsconfig.h"
31 #include "mythnewseditor.h"
32 #include "newsdbutil.h"
33 
34 #define LOC QString("MythNews: ")
35 #define LOC_WARN QString("MythNews, Warning: ")
36 #define LOC_ERR QString("MythNews, Error: ")
37 
42 MythNews::MythNews(MythScreenStack *parent, const QString &name) :
43  MythScreenType(parent, name),
44  m_retrieveTimer(new QTimer(this)),
45  m_updateFreq(gCoreContext->GetDurSetting<std::chrono::minutes>("NewsUpdateFrequency", 30min)),
46  m_zoom(gCoreContext->GetSetting("WebBrowserZoomLevel", "1.0")),
47  m_browser(gCoreContext->GetSetting("WebBrowserCommand", ""))
48 {
49  // Setup cache directory
50 
51  QString fileprefix = GetConfDir();
52 
53  QDir dir(fileprefix);
54  if (!dir.exists())
55  dir.mkdir(fileprefix);
56  fileprefix += "/MythNews";
57  dir.setPath(fileprefix);;
58  if (!dir.exists())
59  dir.mkdir(fileprefix);
60 
63 
64  m_retrieveTimer->stop();
65  m_retrieveTimer->setSingleShot(false);
67 }
68 
70 {
71  QMutexLocker locker(&m_lock);
72 }
73 
74 bool MythNews::Create(void)
75 {
76  QMutexLocker locker(&m_lock);
77 
78  // Load the theme for this screen
79  bool foundtheme = LoadWindowFromXML("news-ui.xml", "news", this);
80  if (!foundtheme)
81  return false;
82 
83  bool err = false;
84  UIUtilE::Assign(this, m_sitesList, "siteslist", &err);
85  UIUtilE::Assign(this, m_articlesList, "articleslist", &err);
86  UIUtilE::Assign(this, m_titleText, "title", &err);
87  UIUtilE::Assign(this, m_descText, "description", &err);
88 
89  // these are all optional
90  UIUtilW::Assign(this, m_nositesText, "nosites", &err);
91  UIUtilW::Assign(this, m_updatedText, "updated", &err);
92  UIUtilW::Assign(this, m_thumbnailImage, "thumbnail", &err);
93  UIUtilW::Assign(this, m_enclosureImage, "enclosures", &err);
94  UIUtilW::Assign(this, m_downloadImage, "download", &err);
95  UIUtilW::Assign(this, m_podcastImage, "ispodcast", &err);
96 
97  if (err)
98  {
99  LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'news'");
100  return false;
101  }
102 
103  if (m_nositesText)
104  {
105  m_nositesText->SetText(tr("You haven't configured MythNews to use any sites."));
106  m_nositesText->Hide();
107  }
108 
109  BuildFocusList();
110 
112 
113  loadSites();
115 
119  this, qOverload<MythUIButtonListItem *>(&MythNews::updateInfoView));
122 
123  return true;
124 }
125 
127 {
128  m_newsSites.clear();
129  m_sitesList->Reset();
130  m_articles.clear();
132 
133  m_titleText->Reset();
134  m_descText->Reset();
135 
136  if (m_updatedText)
137  m_updatedText->Reset();
138 
139  if (m_downloadImage)
141 
142  if (m_enclosureImage)
144 
145  if (m_podcastImage)
146  m_podcastImage->Hide();
147 
148  if (m_thumbnailImage)
150 }
151 
153 {
154  QMutexLocker locker(&m_lock);
155 
156  clearSites();
157 
158  MSqlQuery query(MSqlQuery::InitCon());
159  query.prepare(
160  "SELECT name, url, ico, updated, podcast "
161  "FROM newssites "
162  "ORDER BY name");
163 
164  if (!query.exec())
165  {
166  MythDB::DBError(LOC_ERR + "Could not load sites from DB", query);
167  return;
168  }
169 
170  while (query.next())
171  {
172  QString name = query.value(0).toString();
173  QString url = query.value(1).toString();
174 // QString icon = query.value(2).toString();
175  QDateTime time = MythDate::fromSecsSinceEpoch(query.value(3).toLongLong());
176  bool podcast = query.value(4).toBool();
177  m_newsSites.push_back(new NewsSite(name, url, time, podcast));
178  }
179  std::sort(m_newsSites.begin(), m_newsSites.end(), NewsSite::sortByName);
180 
181  for (auto & site : m_newsSites)
182  {
183  auto *item = new MythUIButtonListItem(m_sitesList, site->name());
184  item->SetData(QVariant::fromValue(site));
185 
186  connect(site, &NewsSite::finished,
188  }
189 
191 
192  if (m_nositesText)
193  {
194  if (m_newsSites.empty())
195  m_nositesText->Show();
196  else
197  m_nositesText->Hide();
198  }
199 }
200 
202 {
203  QMutexLocker locker(&m_lock);
204 
205  if (!selected)
206  return;
207 
208  NewsSite *site = nullptr;
209  NewsArticle article;
210 
212  {
213  article = m_articles[selected];
215  site = m_sitesList->GetItemCurrent()->GetData().value<NewsSite*>();
216  }
217  else
218  {
219  site = selected->GetData().value<NewsSite*>();
222  }
223 
225  {
226  if (!article.title().isEmpty())
227  {
228 
229  if (m_titleText)
230  {
231  QString title = cleanText(article.title());
232  m_titleText->SetText(title);
233  }
234 
235  if (m_descText)
236  {
237  QString artText = cleanText(article.description());
238  m_descText->SetText(artText);
239  }
240 
241  if (!article.thumbnail().isEmpty())
242  {
243  if (m_thumbnailImage)
244  {
247 
248  if (!m_thumbnailImage->IsVisible())
250  }
251  }
252  else
253  {
254  if (site && !site->imageURL().isEmpty())
255  {
256  if (m_thumbnailImage)
257  {
260 
261  if (!m_thumbnailImage->IsVisible())
263  }
264  }
265  else
266  {
267  if (m_thumbnailImage)
269  }
270  }
271 
272  if (m_downloadImage)
273  {
274  if (!article.enclosure().isEmpty())
275  {
276  if (!m_downloadImage->IsVisible())
278  }
279  else
281  }
282 
283  if (m_enclosureImage)
284  {
285  if (!article.enclosure().isEmpty())
286  {
287  if (!m_enclosureImage->IsVisible())
289  }
290  else
292  }
293 
294  if (m_podcastImage)
295  m_podcastImage->Hide();
296  }
297  }
298  else
299  {
300  if (m_downloadImage)
302 
303  if (m_enclosureImage)
305 
306  if (m_podcastImage)
307  m_podcastImage->Hide();
308 
309  if (site)
310  {
311  if (m_titleText)
312  m_titleText->SetText(site->name());
313 
314  if (m_descText)
315  m_descText->SetText(site->description());
316 
319 
320  if (m_podcastImage && site->podcast())
321  m_podcastImage->Show();
322 
323  if (!site->imageURL().isEmpty())
324  {
325  if (m_thumbnailImage)
326  {
329 
330  if (!m_thumbnailImage->IsVisible())
332  }
333  }
334  }
335  }
336 
337  if (m_updatedText)
338  {
339 
340  if (site)
341  {
342  QString text(tr("Updated") + " - ");
343  QDateTime updated(site->lastUpdated());
344  if (updated.isValid()) {
345  text += MythDate::toString(site->lastUpdated(),
347  }
348  else
349  text += tr("Unknown");
350  m_updatedText->SetText(text);
351  }
352  }
353 }
354 
355 bool MythNews::keyPressEvent(QKeyEvent *event)
356 {
357  if (GetFocusWidget() && GetFocusWidget()->keyPressEvent(event))
358  return true;
359 
360  QStringList actions;
361  bool handled = GetMythMainWindow()->TranslateKeyPress("News", event, actions);
362 
363  for (int i = 0; i < actions.size() && !handled; i++)
364  {
365  QString action = actions[i];
366  handled = true;
367 
368  if (action == "RETRIEVENEWS")
370  else if (action == "CANCEL")
371  cancelRetrieve();
372  else if (action == "MENU")
373  ShowMenu();
374  else if (action == "EDIT")
375  ShowEditDialog(true);
376  else if (action == "DELETE")
377  deleteNewsSite();
378  else
379  handled = false;
380  }
381 
382  if (!handled && MythScreenType::keyPressEvent(event))
383  handled = true;
384 
385  return handled;
386 }
387 
389 {
390  QMutexLocker locker(&m_lock);
391 
392  if (m_newsSites.empty())
393  return;
394 
395  m_retrieveTimer->stop();
396 
397  for (auto & site : m_newsSites)
398  {
399  if (site->timeSinceLastUpdate() > m_updateFreq)
400  site->retrieve();
401  else
402  processAndShowNews(site);
403  }
404 
405  m_retrieveTimer->stop();
406  m_retrieveTimer->setSingleShot(false);
408 }
409 
411 {
412  qint64 updated = site->lastUpdated().toSecsSinceEpoch();
413 
414  MSqlQuery query(MSqlQuery::InitCon());
415  query.prepare("UPDATE newssites SET updated = :UPDATED "
416  "WHERE name = :NAME ;");
417  query.bindValue(":UPDATED", updated);
418  query.bindValue(":NAME", site->name());
419  if (!query.exec() || !query.isActive())
420  MythDB::DBError("news update time", query);
421 
422  processAndShowNews(site);
423 }
424 
426 {
427  QMutexLocker locker(&m_lock);
428 
429  for (auto & site : m_newsSites)
430  {
431  site->stop();
432  processAndShowNews(site);
433  }
434 }
435 
437 {
438  QMutexLocker locker(&m_lock);
439 
440  if (!site)
441  return;
442 
443  site->process();
444 
446  if (!siteUIItem)
447  return;
448 
449  if (site != siteUIItem->GetData().value<NewsSite*>())
450  return;
451 
452  QString currItem = m_articlesList->GetValue();
453  int topPos = m_articlesList->GetTopItemPos();
454 
456  m_articles.clear();
457 
458  NewsArticle::List articles = site->GetArticleList();
459  for (auto & article : articles)
460  {
461  auto *item =
462  new MythUIButtonListItem(m_articlesList, cleanText(article.title()));
463  m_articles[item] = article;
464  }
465 
466  if (m_articlesList->MoveToNamedPosition(currItem))
468 }
469 
471 {
472  QMutexLocker locker(&m_lock);
473 
474  if (!item || item->GetData().isNull())
475  return;
476 
477  auto *site = item->GetData().value<NewsSite*>();
478  if (!site)
479  return;
480 
482  m_articles.clear();
483 
484  NewsArticle::List articles = site->GetArticleList();
485  for (auto & article : articles)
486  {
487  auto *blitem = new MythUIButtonListItem(m_articlesList, cleanText(article.title()));
488  m_articles[blitem] = article;
489  }
490 
491  updateInfoView(item);
492 }
493 
495 {
496  QMutexLocker locker(&m_lock);
497 
498  QMap<MythUIButtonListItem*,NewsArticle>::const_iterator it =
499  m_articles.constFind(articlesListItem);
500 
501  if (it == m_articles.constEnd())
502  return;
503 
504  const NewsArticle& article = *it;
505 
506  if (article.articleURL().isEmpty())
507  return;
508 
509  if (article.enclosure().isEmpty())
510  {
511  QString cmdUrl(article.articleURL());
512 
513  if (m_browser.isEmpty())
514  {
515  ShowOkPopup(tr("No browser command set! MythNews needs MythBrowser to be installed."));
516  return;
517  }
518 
519  // display the web page
520  if (m_browser.toLower() == "internal")
521  {
522  GetMythMainWindow()->HandleMedia("WebBrowser", cmdUrl);
523  return;
524  }
525 
526  QString cmd = m_browser;
527  cmd.replace("%ZOOM%", m_zoom);
528  cmd.replace("%URL%", cmdUrl);
529  cmd.replace('\'', "%27");
530  cmd.replace("&","\\&");
531  cmd.replace(";","\\;");
532 
533  GetMythMainWindow()->AllowInput(false);
535  GetMythMainWindow()->AllowInput(true);
536  return;
537  }
538 
539  playVideo(article);
540 }
541 
543 {
544  QMutexLocker locker(&m_lock);
545 
546  NewsSite *site = nullptr;
547 
548  if (edit)
549  {
551 
552  if (!siteListItem || siteListItem->GetData().isNull())
553  return;
554 
555  site = siteListItem->GetData().value<NewsSite*>();
556  }
557 
559 
560  auto *mythnewseditor = new MythNewsEditor(site, edit, mainStack,
561  "mythnewseditor");
562 
563  if (mythnewseditor->Create())
564  {
565  connect(mythnewseditor, &MythScreenType::Exiting, this, &MythNews::loadSites);
566  mainStack->AddScreen(mythnewseditor);
567  }
568  else
569  delete mythnewseditor;
570 }
571 
573 {
575 
576  auto *mythnewsconfig = new MythNewsConfig(mainStack, "mythnewsconfig");
577 
578  if (mythnewsconfig->Create())
579  {
580  connect(mythnewsconfig, &MythScreenType::Exiting, this, &MythNews::loadSites);
581  mainStack->AddScreen(mythnewsconfig);
582  }
583  else
584  delete mythnewsconfig;
585 }
586 
588 {
589  QMutexLocker locker(&m_lock);
590 
591  QString label = tr("Options");
592 
593  MythScreenStack *popupStack =
594  GetMythMainWindow()->GetStack("popup stack");
595 
596  m_menuPopup = new MythDialogBox(label, popupStack, "mythnewsmenupopup");
597 
598  if (m_menuPopup->Create())
599  {
600  popupStack->AddScreen(m_menuPopup);
601 
602  m_menuPopup->SetReturnEvent(this, "options");
603 
604  m_menuPopup->AddButton(tr("Manage Feeds"));
605  m_menuPopup->AddButton(tr("Add Feed"));
606  if (!m_newsSites.empty())
607  {
608  m_menuPopup->AddButton(tr("Edit Feed"));
609  m_menuPopup->AddButton(tr("Delete Feed"));
610  }
611  }
612  else
613  {
614  delete m_menuPopup;
615  m_menuPopup = nullptr;
616  }
617 }
618 
620 {
621  QMutexLocker locker(&m_lock);
622 
624 
625  if (siteUIItem && !siteUIItem->GetData().isNull())
626  {
627  auto *site = siteUIItem->GetData().value<NewsSite*>();
628  if (site)
629  {
630  removeFromDB(site->name());
631  loadSites();
632  }
633  }
634 }
635 
636 // does not need locking
637 void MythNews::playVideo(const NewsArticle &article)
638 {
639  GetMythMainWindow()->HandleMedia("Internal", article.enclosure(),
640  article.description(), article.title());
641 }
642 
643 // does not need locking
644 void MythNews::customEvent(QEvent *event)
645 {
646  if (event->type() == DialogCompletionEvent::kEventType)
647  {
648  auto *dce = dynamic_cast<DialogCompletionEvent*>(event);
649  if (dce == nullptr)
650  return;
651 
652  QString resultid = dce->GetId();
653  int buttonnum = dce->GetResult();
654 
655  if (resultid == "options")
656  {
657  if (buttonnum == 0)
658  ShowFeedManager();
659  else if (buttonnum == 1)
660  ShowEditDialog(false);
661  else if (buttonnum == 2)
662  ShowEditDialog(true);
663  else if (buttonnum == 3)
664  deleteNewsSite();
665  }
666 
667  m_menuPopup = nullptr;
668  }
669 }
670 
671 QString MythNews::cleanText(const QString &text)
672 {
673  QString result = text;
674 
675  // replace a few HTML characters
676  result.replace("&#8232;", ""); // LSEP
677  result.replace("&#8233;", ""); // PSEP
678  result.replace("&#163;", u8"\u00A3"); // POUND
679  result.replace("&#173;", ""); // ?
680  result.replace("&#8211;", "-"); // EN-DASH
681  result.replace("&#8220;", """"); // LEFT-DOUBLE-QUOTE
682  result.replace("&#8221;", """"); // RIGHT-DOUBLE-QUOTE
683  result.replace("&#8216;", "'"); // LEFT-SINGLE-QUOTE
684  result.replace("&#8217;", "'"); // RIGHT-SINGLE-QUOTE
685  result.replace("&#39;", "'"); // Apostrophe
686 
687  // Replace paragraph and break HTML with newlines
688  static const QRegularExpression kHtmlParaStartRE
689  { "<p>", QRegularExpression::CaseInsensitiveOption };
690  static const QRegularExpression kHtmlParaEndRE
691  { "</p>", QRegularExpression::CaseInsensitiveOption };
692  static const QRegularExpression kHtmlBreak1RE
693  { "<(br|)>", QRegularExpression::CaseInsensitiveOption };
694  static const QRegularExpression kHtmlBreak2RE
695  { "<(br|)/>", QRegularExpression::CaseInsensitiveOption };
696  if( result.contains(kHtmlParaEndRE) )
697  {
698  result.replace( kHtmlParaStartRE, "");
699  result.replace( kHtmlParaEndRE, "\n\n");
700  }
701  else
702  {
703  result.replace( kHtmlParaStartRE, "\n\n");
704  result.replace( kHtmlParaEndRE, "");
705  }
706  result.replace( kHtmlBreak2RE, "\n");
707  result.replace( kHtmlBreak1RE, "\n");
708  // These are done instead of simplifyWhitespace
709  // because that function also strips out newlines
710  // Replace tab characters with nothing
711  static const QRegularExpression kTabRE { "\t" };
712  result.replace( kTabRE, "");
713  // Replace double space with single
714  static const QRegularExpression kTwoSpaceRE { " " };
715  result.replace( kTwoSpaceRE, "");
716  // Replace whitespace at beginning of lines with newline
717  static const QRegularExpression kStartingSpaceRE { "\n " };
718  result.replace( kStartingSpaceRE, "\n");
719  // Remove any remaining HTML tags
720  static const QRegularExpression kRemoveHtmlRE(QRegularExpression("</?.+>"));
721  result.remove(kRemoveHtmlRE);
722  result = result.trimmed();
723 
724  return result;
725 }
MythNews::ShowMenu
void ShowMenu(void) override
Definition: mythnews.cpp:587
MSqlQuery::isActive
bool isActive(void) const
Definition: mythdbcon.h:215
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:813
newsdbutil.h
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:127
MythMainWindow::GetMainStack
MythScreenStack * GetMainStack()
Definition: mythmainwindow.cpp:318
MythUIButtonList::GetTopItemPos
int GetTopItemPos(void) const
Definition: mythuibuttonlist.h:240
MythNewsEditor
Definition: mythnewseditor.h:21
NewsSite::imageURL
QString imageURL(void) const
Definition: newssite.cpp:128
MythDialogBox::SetReturnEvent
void SetReturnEvent(QObject *retobject, const QString &resultid)
Definition: mythdialogbox.cpp:301
MythNews::m_updatedText
MythUIText * m_updatedText
Definition: mythnews.h:64
MythDate::toString
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
Definition: mythdate.cpp:84
MythUIButtonList::GetItemCurrent
MythUIButtonListItem * GetItemCurrent() const
Definition: mythuibuttonlist.cpp:1591
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:102
MythNews::m_newsSites
NewsSite::List m_newsSites
Definition: mythnews.h:49
mythuitext.h
NewsArticle::articleURL
QString articleURL(void) const
Definition: newsarticle.h:24
MythNews::cleanText
static QString cleanText(const QString &text)
Definition: mythnews.cpp:671
DialogCompletionEvent::GetId
QString GetId()
Definition: mythdialogbox.h:52
MythNews::m_nositesText
MythUIText * m_nositesText
Definition: mythnews.h:63
MythUIText::Reset
void Reset(void) override
Reset the widget to it's original state, should not reset changes made by the theme.
Definition: mythuitext.cpp:82
MythNews::slotNewsRetrieved
void slotNewsRetrieved(NewsSite *site)
Definition: mythnews.cpp:410
NewsSite::podcast
bool podcast(void) const
Definition: newssite.cpp:108
mythdb.h
NewsSite::List::clear
void clear(void)
Definition: newssite.h:66
NewsArticle::title
QString title(void) const
Definition: newsarticle.h:22
MythNews::m_menuPopup
MythDialogBox * m_menuPopup
Definition: mythnews.h:57
MythNews::processAndShowNews
void processAndShowNews(NewsSite *site)
Definition: mythnews.cpp:436
mythnewsconfig.h
NewsArticle::thumbnail
QString thumbnail(void) const
Definition: newsarticle.h:25
MythUIImage::Load
bool Load(bool allowLoadInBackground=true, bool forceStat=false)
Load the image(s), wraps ImageLoader::LoadImage()
Definition: mythuiimage.cpp:966
MythNews::slotRetrieveNews
void slotRetrieveNews(void)
Definition: mythnews.cpp:388
MythNews::customEvent
void customEvent(QEvent *event) override
Definition: mythnews.cpp:644
MythUIButtonList::itemSelected
void itemSelected(MythUIButtonListItem *item)
NewsSite::finished
void finished(NewsSite *item)
LOC_ERR
#define LOC_ERR
Definition: mythnews.cpp:36
mythdialogbox.h
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:204
MythScreenStack
Definition: mythscreenstack.h:16
MythNews::keyPressEvent
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
Definition: mythnews.cpp:355
MythNews::loadSites
void loadSites(void)
Definition: mythnews.cpp:152
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:619
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MythScreenType
Screen in which all other widgets are contained and rendered.
Definition: mythscreentype.h:45
NewsSite::description
QString description(void) const
Definition: newssite.cpp:114
MythNews::m_articles
QMap< MythUIButtonListItem *, NewsArticle > m_articles
Definition: mythnews.h:61
mythdirs.h
myth_system
uint myth_system(const QString &command, uint flags, std::chrono::seconds timeout)
Definition: mythsystemlegacy.cpp:506
mythuibuttonlist.h
MythNews::slotViewArticle
void slotViewArticle(MythUIButtonListItem *articlesListItem)
Definition: mythnews.cpp:494
mythuiimage.h
MythMainWindow::HandleMedia
bool HandleMedia(const QString &Handler, const QString &Mrl, const QString &Plot="", const QString &Title="", const QString &Subtitle="", const QString &Director="", int Season=0, int Episode=0, const QString &Inetref="", std::chrono::minutes LenMins=2h, const QString &Year="1895", const QString &Id="", bool UseBookmarks=false)
Definition: mythmainwindow.cpp:1497
NewsSite::sortByName
static bool sortByName(NewsSite *a, NewsSite *b)
Definition: newssite.h:102
MythNews::MythNews
MythNews(MythScreenStack *parent, const QString &name)
Creates a new MythNews Screen.
Definition: mythnews.cpp:42
MythScreenType::GetFocusWidget
MythUIType * GetFocusWidget(void) const
Definition: mythscreentype.cpp:113
mythsystemlegacy.h
MythUIButtonListItem
Definition: mythuibuttonlist.h:41
MythNews::m_browser
QString m_browser
Definition: mythnews.h:56
mythdate.h
MythDate::fromSecsSinceEpoch
MBASE_PUBLIC QDateTime fromSecsSinceEpoch(int64_t seconds)
This function takes the number of seconds since the start of the epoch and returns a QDateTime with t...
Definition: mythdate.cpp:72
mythnewseditor.h
MythUIType::Show
void Show(void)
Definition: mythuitype.cpp:1149
mythnews.h
GetConfDir
QString GetConfDir(void)
Definition: mythdirs.cpp:256
MythNews::m_downloadImage
MythUIImage * m_downloadImage
Definition: mythnews.h:69
MythNews::ShowFeedManager
void ShowFeedManager() const
Definition: mythnews.cpp:572
MythUIButtonList::itemClicked
void itemClicked(MythUIButtonListItem *item)
MythMainWindow::TranslateKeyPress
bool TranslateKeyPress(const QString &Context, QKeyEvent *Event, QStringList &Actions, bool AllowJumps=true)
Get a list of actions for a keypress in the given context.
Definition: mythmainwindow.cpp:1112
MythNews::m_zoom
QString m_zoom
Definition: mythnews.h:55
MythUIButtonList::GetCurrentPos
int GetCurrentPos() const
Definition: mythuibuttonlist.h:238
NewsArticle
Definition: newsarticle.h:10
MythScreenType::SetFocusWidget
bool SetFocusWidget(MythUIType *widget=nullptr)
Definition: mythscreentype.cpp:118
MythDialogBox::AddButton
void AddButton(const QString &title)
Definition: mythdialogbox.h:198
MythDialogBox
Basic menu dialog, message and a list of options.
Definition: mythdialogbox.h:166
removeFromDB
bool removeFromDB(RSSSite *site)
Definition: netutils.cpp:686
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:551
MythNews::playVideo
static void playVideo(const NewsArticle &article)
Definition: mythnews.cpp:637
MythDialogBox::Create
bool Create(void) override
Definition: mythdialogbox.cpp:127
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:226
MythNews::m_lock
QRecursiveMutex m_lock
Definition: mythnews.h:48
MythScreenType::BuildFocusList
void BuildFocusList(void)
Definition: mythscreentype.cpp:206
NewsSite::name
QString name(void) const
Definition: newssite.cpp:96
NewsSite::lastUpdated
QDateTime lastUpdated(void) const
Definition: newssite.cpp:140
MythNews::deleteNewsSite
void deleteNewsSite(void)
Definition: mythnews.cpp:619
NewsSite::GetArticleList
NewsArticle::List GetArticleList(void) const
Definition: newssite.cpp:134
MythNews::updateInfoView
void updateInfoView(void)
MythUIButtonListItem::GetData
QVariant GetData()
Definition: mythuibuttonlist.cpp:3660
MythNews::cancelRetrieve
void cancelRetrieve(void)
Definition: mythnews.cpp:425
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:55
NewsSite
Definition: newssite.h:50
MythNews::m_podcastImage
MythUIImage * m_podcastImage
Definition: mythnews.h:71
NewsSite::process
void process(void)
Definition: newssite.cpp:221
UIUtilDisp::Assign
static bool Assign(ContainerType *container, UIType *&item, const QString &name, bool *err=nullptr)
Definition: mythuiutils.h:27
MythNews::m_titleText
MythUIText * m_titleText
Definition: mythnews.h:65
MythNews::m_articlesList
MythUIButtonList * m_articlesList
Definition: mythnews.h:60
NewsArticle::description
QString description(void) const
Definition: newsarticle.h:23
MythUIType::Hide
void Hide(void)
Definition: mythuitype.cpp:1144
MythNews::slotSiteSelected
void slotSiteSelected(MythUIButtonListItem *item)
Definition: mythnews.cpp:470
MythDate::kSimplify
@ kSimplify
Do Today/Yesterday/Tomorrow transform.
Definition: mythdate.h:26
MythNews::ShowEditDialog
void ShowEditDialog(bool edit)
Definition: mythnews.cpp:542
MythNews::m_retrieveTimer
QTimer * m_retrieveTimer
Definition: mythnews.h:51
NewsArticle::List
std::vector< NewsArticle > List
Definition: newsarticle.h:13
MythScreenType::keyPressEvent
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
Definition: mythscreentype.cpp:404
MythNews::m_descText
MythUIText * m_descText
Definition: mythnews.h:66
XMLParseBase::LoadWindowFromXML
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
Definition: xmlparsebase.cpp:687
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:889
std
Definition: mythchrono.h:23
DialogCompletionEvent
Event dispatched from MythUI modal dialogs to a listening class containing a result of some form.
Definition: mythdialogbox.h:41
MythNews::m_thumbnailImage
MythUIImage * m_thumbnailImage
Definition: mythnews.h:68
MythUIButtonList::GetValue
virtual QString GetValue() const
Definition: mythuibuttonlist.cpp:1610
MythUIText::SetText
virtual void SetText(const QString &text)
Definition: mythuitext.cpp:132
mythcontext.h
DialogCompletionEvent::kEventType
static const Type kEventType
Definition: mythdialogbox.h:57
MythUIButtonList::Reset
void Reset() override
Reset the widget to it's original state, should not reset changes made by the theme.
Definition: mythuibuttonlist.cpp:116
GetMythMainWindow
MythMainWindow * GetMythMainWindow(void)
Definition: mythmainwindow.cpp:104
MythUIButtonList::MoveToNamedPosition
bool MoveToNamedPosition(const QString &position_name)
Definition: mythuibuttonlist.cpp:2283
MythUIButtonList::SetItemCurrent
void SetItemCurrent(MythUIButtonListItem *item)
Definition: mythuibuttonlist.cpp:1558
MythNews::Create
bool Create(void) override
Definition: mythnews.cpp:74
build_compdb.action
action
Definition: build_compdb.py:9
MythNews::m_updateFreq
std::chrono::minutes m_updateFreq
Definition: mythnews.h:53
MythScreenType::Exiting
void Exiting()
MythMainWindow::GetStack
MythScreenStack * GetStack(const QString &Stackname)
Definition: mythmainwindow.cpp:323
MythNews::~MythNews
~MythNews() override
Definition: mythnews.cpp:69
NewsArticle::enclosure
QString enclosure(void) const
Definition: newsarticle.h:27
MythNews::m_timerTimeout
std::chrono::minutes m_timerTimeout
Definition: mythnews.h:52
MythDate::kDateTimeFull
@ kDateTimeFull
Default local time.
Definition: mythdate.h:23
MythNews::m_sitesList
MythUIButtonList * m_sitesList
Definition: mythnews.h:59
kMSDontDisableDrawing
@ kMSDontDisableDrawing
avoid disabling UI drawing
Definition: mythsystem.h:37
MythMainWindow::AllowInput
void AllowInput(bool Allow)
Definition: mythmainwindow.cpp:1527
MythUIImage::SetFilename
void SetFilename(const QString &filename)
Must be followed by a call to Load() to load the image.
Definition: mythuiimage.cpp:674
mythdownloadmanager.h
MythUIButtonList::GetItemFirst
MythUIButtonListItem * GetItemFirst() const
Definition: mythuibuttonlist.cpp:1637
MythNewsConfig
Definition: mythnewsconfig.h:16
mythmainwindow.h
MythScreenStack::AddScreen
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Definition: mythscreenstack.cpp:52
ShowOkPopup
MythConfirmationDialog * ShowOkPopup(const QString &message, bool showCancel)
Non-blocking version of MythPopupBox::showOkPopup()
Definition: mythdialogbox.cpp:562
MythUIType::IsVisible
bool IsVisible(bool recurse=false) const
Definition: mythuitype.cpp:904
MythNews::m_enclosureImage
MythUIImage * m_enclosureImage
Definition: mythnews.h:70
MythNews::clearSites
void clearSites(void)
Definition: mythnews.cpp:126
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:838