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
280  {
282  }
283  }
284 
285  if (m_enclosureImage)
286  {
287  if (!article.enclosure().isEmpty())
288  {
289  if (!m_enclosureImage->IsVisible())
291  }
292  else
293  {
295  }
296  }
297 
298  if (m_podcastImage)
299  m_podcastImage->Hide();
300  }
301  }
302  else
303  {
304  if (m_downloadImage)
306 
307  if (m_enclosureImage)
309 
310  if (m_podcastImage)
311  m_podcastImage->Hide();
312 
313  if (site)
314  {
315  if (m_titleText)
316  m_titleText->SetText(site->name());
317 
318  if (m_descText)
319  m_descText->SetText(site->description());
320 
323 
324  if (m_podcastImage && site->podcast())
325  m_podcastImage->Show();
326 
327  if (!site->imageURL().isEmpty())
328  {
329  if (m_thumbnailImage)
330  {
333 
334  if (!m_thumbnailImage->IsVisible())
336  }
337  }
338  }
339  }
340 
341  if (m_updatedText)
342  {
343 
344  if (site)
345  {
346  QString text(tr("Updated") + " - ");
347  QDateTime updated(site->lastUpdated());
348  if (updated.isValid()) {
349  text += MythDate::toString(site->lastUpdated(),
351  }
352  else
353  {
354  text += tr("Unknown");
355  }
356  m_updatedText->SetText(text);
357  }
358  }
359 }
360 
361 bool MythNews::keyPressEvent(QKeyEvent *event)
362 {
363  if (GetFocusWidget() && GetFocusWidget()->keyPressEvent(event))
364  return true;
365 
366  QStringList actions;
367  bool handled = GetMythMainWindow()->TranslateKeyPress("News", event, actions);
368 
369  for (int i = 0; i < actions.size() && !handled; i++)
370  {
371  const QString& action = actions[i];
372  handled = true;
373 
374  if (action == "RETRIEVENEWS")
376  else if (action == "CANCEL")
377  cancelRetrieve();
378  else if (action == "MENU")
379  ShowMenu();
380  else if (action == "EDIT")
381  ShowEditDialog(true);
382  else if (action == "DELETE")
383  deleteNewsSite();
384  else
385  handled = false;
386  }
387 
388  if (!handled && MythScreenType::keyPressEvent(event))
389  handled = true;
390 
391  return handled;
392 }
393 
395 {
396  QMutexLocker locker(&m_lock);
397 
398  if (m_newsSites.empty())
399  return;
400 
401  m_retrieveTimer->stop();
402 
403  for (auto & site : m_newsSites)
404  {
405  if (site->timeSinceLastUpdate() > m_updateFreq)
406  site->retrieve();
407  else
408  processAndShowNews(site);
409  }
410 
411  m_retrieveTimer->stop();
412  m_retrieveTimer->setSingleShot(false);
414 }
415 
417 {
418  qint64 updated = site->lastUpdated().toSecsSinceEpoch();
419 
420  MSqlQuery query(MSqlQuery::InitCon());
421  query.prepare("UPDATE newssites SET updated = :UPDATED "
422  "WHERE name = :NAME ;");
423  query.bindValue(":UPDATED", updated);
424  query.bindValue(":NAME", site->name());
425  if (!query.exec() || !query.isActive())
426  MythDB::DBError("news update time", query);
427 
428  processAndShowNews(site);
429 }
430 
432 {
433  QMutexLocker locker(&m_lock);
434 
435  for (auto & site : m_newsSites)
436  {
437  site->stop();
438  processAndShowNews(site);
439  }
440 }
441 
443 {
444  QMutexLocker locker(&m_lock);
445 
446  if (!site)
447  return;
448 
449  site->process();
450 
452  if (!siteUIItem)
453  return;
454 
455  if (site != siteUIItem->GetData().value<NewsSite*>())
456  return;
457 
458  QString currItem = m_articlesList->GetValue();
459  int topPos = m_articlesList->GetTopItemPos();
460 
462  m_articles.clear();
463 
464  NewsArticle::List articles = site->GetArticleList();
465  for (auto & article : articles)
466  {
467  auto *item =
468  new MythUIButtonListItem(m_articlesList, cleanText(article.title()));
469  m_articles[item] = article;
470  }
471 
472  if (m_articlesList->MoveToNamedPosition(currItem))
474 }
475 
477 {
478  QMutexLocker locker(&m_lock);
479 
480  if (!item || item->GetData().isNull())
481  return;
482 
483  auto *site = item->GetData().value<NewsSite*>();
484  if (!site)
485  return;
486 
488  m_articles.clear();
489 
490  NewsArticle::List articles = site->GetArticleList();
491  for (auto & article : articles)
492  {
493  auto *blitem = new MythUIButtonListItem(m_articlesList, cleanText(article.title()));
494  m_articles[blitem] = article;
495  }
496 
497  updateInfoView(item);
498 }
499 
501 {
502  QMutexLocker locker(&m_lock);
503 
504  QMap<MythUIButtonListItem*,NewsArticle>::const_iterator it =
505  m_articles.constFind(articlesListItem);
506 
507  if (it == m_articles.constEnd())
508  return;
509 
510  const NewsArticle& article = *it;
511 
512  if (article.articleURL().isEmpty())
513  return;
514 
515  if (article.enclosure().isEmpty())
516  {
517  QString cmdUrl(article.articleURL());
518 
519  if (m_browser.isEmpty())
520  {
521  ShowOkPopup(tr("No browser command set! MythNews needs MythBrowser to be installed."));
522  return;
523  }
524 
525  // display the web page
526  if (m_browser.toLower() == "internal")
527  {
528  GetMythMainWindow()->HandleMedia("WebBrowser", cmdUrl);
529  return;
530  }
531 
532  QString cmd = m_browser;
533  cmd.replace("%ZOOM%", m_zoom);
534  cmd.replace("%URL%", cmdUrl);
535  cmd.replace('\'', "%27");
536  cmd.replace("&","\\&");
537  cmd.replace(";","\\;");
538 
539  GetMythMainWindow()->AllowInput(false);
541  GetMythMainWindow()->AllowInput(true);
542  return;
543  }
544 
545  playVideo(article);
546 }
547 
549 {
550  QMutexLocker locker(&m_lock);
551 
552  NewsSite *site = nullptr;
553 
554  if (edit)
555  {
557 
558  if (!siteListItem || siteListItem->GetData().isNull())
559  return;
560 
561  site = siteListItem->GetData().value<NewsSite*>();
562  }
563 
565 
566  auto *mythnewseditor = new MythNewsEditor(site, edit, mainStack,
567  "mythnewseditor");
568 
569  if (mythnewseditor->Create())
570  {
571  connect(mythnewseditor, &MythScreenType::Exiting, this, &MythNews::loadSites);
572  mainStack->AddScreen(mythnewseditor);
573  }
574  else
575  {
576  delete mythnewseditor;
577  }
578 }
579 
581 {
583 
584  auto *mythnewsconfig = new MythNewsConfig(mainStack, "mythnewsconfig");
585 
586  if (mythnewsconfig->Create())
587  {
588  connect(mythnewsconfig, &MythScreenType::Exiting, this, &MythNews::loadSites);
589  mainStack->AddScreen(mythnewsconfig);
590  }
591  else
592  {
593  delete mythnewsconfig;
594  }
595 }
596 
598 {
599  QMutexLocker locker(&m_lock);
600 
601  QString label = tr("Options");
602 
603  MythScreenStack *popupStack =
604  GetMythMainWindow()->GetStack("popup stack");
605 
606  m_menuPopup = new MythDialogBox(label, popupStack, "mythnewsmenupopup");
607 
608  if (m_menuPopup->Create())
609  {
610  popupStack->AddScreen(m_menuPopup);
611 
612  m_menuPopup->SetReturnEvent(this, "options");
613 
614  m_menuPopup->AddButton(tr("Manage Feeds"));
615  m_menuPopup->AddButton(tr("Add Feed"));
616  if (!m_newsSites.empty())
617  {
618  m_menuPopup->AddButton(tr("Edit Feed"));
619  m_menuPopup->AddButton(tr("Delete Feed"));
620  }
621  }
622  else
623  {
624  delete m_menuPopup;
625  m_menuPopup = nullptr;
626  }
627 }
628 
630 {
631  QMutexLocker locker(&m_lock);
632 
634 
635  if (siteUIItem && !siteUIItem->GetData().isNull())
636  {
637  auto *site = siteUIItem->GetData().value<NewsSite*>();
638  if (site)
639  {
640  removeFromDB(site->name());
641  loadSites();
642  }
643  }
644 }
645 
646 // does not need locking
647 void MythNews::playVideo(const NewsArticle &article)
648 {
649  GetMythMainWindow()->HandleMedia("Internal", article.enclosure(),
650  article.description(), article.title());
651 }
652 
653 // does not need locking
654 void MythNews::customEvent(QEvent *event)
655 {
656  if (event->type() == DialogCompletionEvent::kEventType)
657  {
658  auto *dce = dynamic_cast<DialogCompletionEvent*>(event);
659  if (dce == nullptr)
660  return;
661 
662  QString resultid = dce->GetId();
663  int buttonnum = dce->GetResult();
664 
665  if (resultid == "options")
666  {
667  if (buttonnum == 0)
668  ShowFeedManager();
669  else if (buttonnum == 1)
670  ShowEditDialog(false);
671  else if (buttonnum == 2)
672  ShowEditDialog(true);
673  else if (buttonnum == 3)
674  deleteNewsSite();
675  }
676 
677  m_menuPopup = nullptr;
678  }
679 }
680 
681 QString MythNews::cleanText(const QString &text)
682 {
683  QString result = text;
684 
685  // replace a few HTML characters
686  result.replace("&#8232;", ""); // LSEP
687  result.replace("&#8233;", ""); // PSEP
688  result.replace("&#163;", u8"\u00A3"); // POUND
689  result.replace("&#173;", ""); // ?
690  result.replace("&#8211;", "-"); // EN-DASH
691  result.replace("&#8220;", """"); // LEFT-DOUBLE-QUOTE
692  result.replace("&#8221;", """"); // RIGHT-DOUBLE-QUOTE
693  result.replace("&#8216;", "'"); // LEFT-SINGLE-QUOTE
694  result.replace("&#8217;", "'"); // RIGHT-SINGLE-QUOTE
695  result.replace("&#39;", "'"); // Apostrophe
696 
697  // Replace paragraph and break HTML with newlines
698  static const QRegularExpression kHtmlParaStartRE
699  { "<p>", QRegularExpression::CaseInsensitiveOption };
700  static const QRegularExpression kHtmlParaEndRE
701  { "</p>", QRegularExpression::CaseInsensitiveOption };
702  static const QRegularExpression kHtmlBreak1RE
703  { "<(br|)>", QRegularExpression::CaseInsensitiveOption };
704  static const QRegularExpression kHtmlBreak2RE
705  { "<(br|)/>", QRegularExpression::CaseInsensitiveOption };
706  if( result.contains(kHtmlParaEndRE) )
707  {
708  result.replace( kHtmlParaStartRE, "");
709  result.replace( kHtmlParaEndRE, "\n\n");
710  }
711  else
712  {
713  result.replace( kHtmlParaStartRE, "\n\n");
714  result.replace( kHtmlParaEndRE, "");
715  }
716  result.replace( kHtmlBreak2RE, "\n");
717  result.replace( kHtmlBreak1RE, "\n");
718  // These are done instead of simplifyWhitespace
719  // because that function also strips out newlines
720  // Replace tab characters with nothing
721  static const QRegularExpression kTabRE { "\t" };
722  result.replace( kTabRE, "");
723  // Replace double space with single
724  static const QRegularExpression kTwoSpaceRE { " " };
725  result.replace( kTwoSpaceRE, "");
726  // Replace whitespace at beginning of lines with newline
727  static const QRegularExpression kStartingSpaceRE { "\n " };
728  result.replace( kStartingSpaceRE, "\n");
729  // Remove any remaining HTML tags
730  static const QRegularExpression kRemoveHtmlRE(QRegularExpression("</?.+>"));
731  result.remove(kRemoveHtmlRE);
732  result = result.trimmed();
733 
734  return result;
735 }
MythNews::ShowMenu
void ShowMenu(void) override
Definition: mythnews.cpp:597
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:812
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:317
MythUIButtonList::GetTopItemPos
int GetTopItemPos(void) const
Definition: mythuibuttonlist.h:242
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:303
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:1614
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:681
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:65
MythNews::slotNewsRetrieved
void slotNewsRetrieved(NewsSite *site)
Definition: mythnews.cpp:416
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:442
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:971
MythNews::slotRetrieveNews
void slotRetrieveNews(void)
Definition: mythnews.cpp:394
MythNews::customEvent
void customEvent(QEvent *event) override
Definition: mythnews.cpp:654
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:361
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:618
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:500
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:1496
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:110
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:1144
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:580
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:1111
MythNews::m_zoom
QString m_zoom
Definition: mythnews.h:55
MythUIButtonList::GetCurrentPos
int GetCurrentPos() const
Definition: mythuibuttonlist.h:240
NewsArticle
Definition: newsarticle.h:10
MythScreenType::SetFocusWidget
bool SetFocusWidget(MythUIType *widget=nullptr)
Definition: mythscreentype.cpp:115
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:550
MythNews::playVideo
static void playVideo(const NewsArticle &article)
Definition: mythnews.cpp:647
MythDialogBox::Create
bool Create(void) override
Definition: mythdialogbox.cpp:127
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:225
MythNews::m_lock
QRecursiveMutex m_lock
Definition: mythnews.h:48
MythScreenType::BuildFocusList
void BuildFocusList(void)
Definition: mythscreentype.cpp:203
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:629
NewsSite::GetArticleList
NewsArticle::List GetArticleList(void) const
Definition: newssite.cpp:134
MythNews::updateInfoView
void updateInfoView(void)
MythUIButtonListItem::GetData
QVariant GetData()
Definition: mythuibuttonlist.cpp:3715
MythNews::cancelRetrieve
void cancelRetrieve(void)
Definition: mythnews.cpp:431
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:1139
MythNews::slotSiteSelected
void slotSiteSelected(MythUIButtonListItem *item)
Definition: mythnews.cpp:476
MythDate::kSimplify
@ kSimplify
Do Today/Yesterday/Tomorrow transform.
Definition: mythdate.h:26
MythNews::ShowEditDialog
void ShowEditDialog(bool edit)
Definition: mythnews.cpp:548
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:401
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:888
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:1633
MythUIText::SetText
virtual void SetText(const QString &text)
Definition: mythuitext.cpp:115
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:2318
MythUIButtonList::SetItemCurrent
void SetItemCurrent(MythUIButtonListItem *item)
Definition: mythuibuttonlist.cpp:1581
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:322
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:1526
MythUIImage::SetFilename
void SetFilename(const QString &filename)
Must be followed by a call to Load() to load the image.
Definition: mythuiimage.cpp:677
mythdownloadmanager.h
MythUIButtonList::GetItemFirst
MythUIButtonListItem * GetItemFirst() const
Definition: mythuibuttonlist.cpp:1660
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:566
MythUIType::IsVisible
bool IsVisible(bool recurse=false) const
Definition: mythuitype.cpp:903
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:837