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
17 #include <libmythbase/mythdate.h>
18 #include <libmythbase/mythdb.h>
19 #include <libmythbase/mythdirs.h>
26 #include <libmythui/mythuiimage.h>
27 #include <libmythui/mythuitext.h>
28 
29 // MythNews headers
30 #include "mythnews.h"
31 #include "mythnewsconfig.h"
32 #include "mythnewseditor.h"
33 #include "newsdbutil.h"
34 
35 #define LOC QString("MythNews: ")
36 #define LOC_WARN QString("MythNews, Warning: ")
37 #define LOC_ERR QString("MythNews, Error: ")
38 
43 MythNews::MythNews(MythScreenStack *parent, const QString &name) :
44  MythScreenType(parent, name),
45  m_retrieveTimer(new QTimer(this)),
46  m_updateFreq(gCoreContext->GetDurSetting<std::chrono::minutes>("NewsUpdateFrequency", 30min)),
47  m_zoom(gCoreContext->GetSetting("WebBrowserZoomLevel", "1.0")),
48  m_browser(gCoreContext->GetSetting("WebBrowserCommand", ""))
49 {
50  // Setup cache directory
51 
52  QString fileprefix = GetConfDir();
53 
54  QDir dir(fileprefix);
55  if (!dir.exists())
56  dir.mkdir(fileprefix);
57  fileprefix += "/MythNews";
58  dir.setPath(fileprefix);;
59  if (!dir.exists())
60  dir.mkdir(fileprefix);
61 
64 
65  m_retrieveTimer->stop();
66  m_retrieveTimer->setSingleShot(false);
68 }
69 
71 {
72  QMutexLocker locker(&m_lock);
73 }
74 
75 bool MythNews::Create(void)
76 {
77  QMutexLocker locker(&m_lock);
78 
79  // Load the theme for this screen
80  bool foundtheme = LoadWindowFromXML("news-ui.xml", "news", this);
81  if (!foundtheme)
82  return false;
83 
84  bool err = false;
85  UIUtilE::Assign(this, m_sitesList, "siteslist", &err);
86  UIUtilE::Assign(this, m_articlesList, "articleslist", &err);
87  UIUtilE::Assign(this, m_titleText, "title", &err);
88  UIUtilE::Assign(this, m_descText, "description", &err);
89 
90  // these are all optional
91  UIUtilW::Assign(this, m_nositesText, "nosites", &err);
92  UIUtilW::Assign(this, m_updatedText, "updated", &err);
93  UIUtilW::Assign(this, m_thumbnailImage, "thumbnail", &err);
94  UIUtilW::Assign(this, m_enclosureImage, "enclosures", &err);
95  UIUtilW::Assign(this, m_downloadImage, "download", &err);
96  UIUtilW::Assign(this, m_podcastImage, "ispodcast", &err);
97 
98  if (err)
99  {
100  LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'news'");
101  return false;
102  }
103 
104  if (m_nositesText)
105  {
106  m_nositesText->SetText(tr("You haven't configured MythNews to use any sites."));
107  m_nositesText->Hide();
108  }
109 
110  BuildFocusList();
111 
113 
114  loadSites();
116 
120  this, qOverload<MythUIButtonListItem *>(&MythNews::updateInfoView));
123 
124  return true;
125 }
126 
128 {
129  m_newsSites.clear();
130  m_sitesList->Reset();
131  m_articles.clear();
133 
134  m_titleText->Reset();
135  m_descText->Reset();
136 
137  if (m_updatedText)
138  m_updatedText->Reset();
139 
140  if (m_downloadImage)
142 
143  if (m_enclosureImage)
145 
146  if (m_podcastImage)
147  m_podcastImage->Hide();
148 
149  if (m_thumbnailImage)
151 }
152 
154 {
155  QMutexLocker locker(&m_lock);
156 
157  clearSites();
158 
159  MSqlQuery query(MSqlQuery::InitCon());
160  query.prepare(
161  "SELECT name, url, ico, updated, podcast "
162  "FROM newssites "
163  "ORDER BY name");
164 
165  if (!query.exec())
166  {
167  MythDB::DBError(LOC_ERR + "Could not load sites from DB", query);
168  return;
169  }
170 
171  while (query.next())
172  {
173  QString name = query.value(0).toString();
174  QString url = query.value(1).toString();
175 // QString icon = query.value(2).toString();
176  QDateTime time = MythDate::fromSecsSinceEpoch(query.value(3).toLongLong());
177  bool podcast = query.value(4).toBool();
178  m_newsSites.push_back(new NewsSite(name, url, time, podcast));
179  }
180  std::sort(m_newsSites.begin(), m_newsSites.end(), NewsSite::sortByName);
181 
182  for (auto & site : m_newsSites)
183  {
184  auto *item = new MythUIButtonListItem(m_sitesList, site->name());
185  item->SetData(QVariant::fromValue(site));
186 
187  connect(site, &NewsSite::finished,
189  }
190 
192 
193  if (m_nositesText)
194  {
195  if (m_newsSites.empty())
196  m_nositesText->Show();
197  else
198  m_nositesText->Hide();
199  }
200 }
201 
203 {
204  QMutexLocker locker(&m_lock);
205 
206  if (!selected)
207  return;
208 
209  NewsSite *site = nullptr;
210  NewsArticle article;
211 
213  {
214  article = m_articles[selected];
216  site = m_sitesList->GetItemCurrent()->GetData().value<NewsSite*>();
217  }
218  else
219  {
220  site = selected->GetData().value<NewsSite*>();
223  }
224 
226  {
227  if (!article.title().isEmpty())
228  {
229 
230  if (m_titleText)
231  {
232  QString title = cleanText(article.title());
233  m_titleText->SetText(title);
234  }
235 
236  if (m_descText)
237  {
238  QString artText = cleanText(article.description());
239  m_descText->SetText(artText);
240  }
241 
242  if (!article.thumbnail().isEmpty())
243  {
244  if (m_thumbnailImage)
245  {
248 
249  if (!m_thumbnailImage->IsVisible())
251  }
252  }
253  else
254  {
255  if (site && !site->imageURL().isEmpty())
256  {
257  if (m_thumbnailImage)
258  {
261 
262  if (!m_thumbnailImage->IsVisible())
264  }
265  }
266  else
267  {
268  if (m_thumbnailImage)
270  }
271  }
272 
273  if (m_downloadImage)
274  {
275  if (!article.enclosure().isEmpty())
276  {
277  if (!m_downloadImage->IsVisible())
279  }
280  else
281  {
283  }
284  }
285 
286  if (m_enclosureImage)
287  {
288  if (!article.enclosure().isEmpty())
289  {
290  if (!m_enclosureImage->IsVisible())
292  }
293  else
294  {
296  }
297  }
298 
299  if (m_podcastImage)
300  m_podcastImage->Hide();
301  }
302  }
303  else
304  {
305  if (m_downloadImage)
307 
308  if (m_enclosureImage)
310 
311  if (m_podcastImage)
312  m_podcastImage->Hide();
313 
314  if (site)
315  {
316  if (m_titleText)
317  m_titleText->SetText(site->name());
318 
319  if (m_descText)
320  m_descText->SetText(site->description());
321 
324 
325  if (m_podcastImage && site->podcast())
326  m_podcastImage->Show();
327 
328  if (!site->imageURL().isEmpty())
329  {
330  if (m_thumbnailImage)
331  {
334 
335  if (!m_thumbnailImage->IsVisible())
337  }
338  }
339  }
340  }
341 
342  if (m_updatedText)
343  {
344 
345  if (site)
346  {
347  QString text(tr("Updated") + " - ");
348  QDateTime updated(site->lastUpdated());
349  if (updated.isValid()) {
350  text += MythDate::toString(site->lastUpdated(),
352  }
353  else
354  {
355  text += tr("Unknown");
356  }
357  m_updatedText->SetText(text);
358  }
359  }
360 }
361 
362 bool MythNews::keyPressEvent(QKeyEvent *event)
363 {
364  if (GetFocusWidget() && GetFocusWidget()->keyPressEvent(event))
365  return true;
366 
367  QStringList actions;
368  bool handled = GetMythMainWindow()->TranslateKeyPress("News", event, actions);
369 
370  for (int i = 0; i < actions.size() && !handled; i++)
371  {
372  const QString& action = actions[i];
373  handled = true;
374 
375  if (action == "RETRIEVENEWS")
377  else if (action == "CANCEL")
378  cancelRetrieve();
379  else if (action == "MENU")
380  ShowMenu();
381  else if (action == "EDIT")
382  ShowEditDialog(true);
383  else if (action == "DELETE")
384  deleteNewsSite();
385  else
386  handled = false;
387  }
388 
389  if (!handled && MythScreenType::keyPressEvent(event))
390  handled = true;
391 
392  return handled;
393 }
394 
396 {
397  QMutexLocker locker(&m_lock);
398 
399  if (m_newsSites.empty())
400  return;
401 
402  m_retrieveTimer->stop();
403 
404  for (auto & site : m_newsSites)
405  {
406  if (site->timeSinceLastUpdate() > m_updateFreq)
407  site->retrieve();
408  else
409  processAndShowNews(site);
410  }
411 
412  m_retrieveTimer->stop();
413  m_retrieveTimer->setSingleShot(false);
415 }
416 
418 {
419  qint64 updated = site->lastUpdated().toSecsSinceEpoch();
420 
421  MSqlQuery query(MSqlQuery::InitCon());
422  query.prepare("UPDATE newssites SET updated = :UPDATED "
423  "WHERE name = :NAME ;");
424  query.bindValue(":UPDATED", updated);
425  query.bindValue(":NAME", site->name());
426  if (!query.exec() || !query.isActive())
427  MythDB::DBError("news update time", query);
428 
429  processAndShowNews(site);
430 }
431 
433 {
434  QMutexLocker locker(&m_lock);
435 
436  for (auto & site : m_newsSites)
437  {
438  site->stop();
439  processAndShowNews(site);
440  }
441 }
442 
444 {
445  QMutexLocker locker(&m_lock);
446 
447  if (!site)
448  return;
449 
450  site->process();
451 
453  if (!siteUIItem)
454  return;
455 
456  if (site != siteUIItem->GetData().value<NewsSite*>())
457  return;
458 
459  QString currItem = m_articlesList->GetValue();
460  int topPos = m_articlesList->GetTopItemPos();
461 
463  m_articles.clear();
464 
465  NewsArticle::List articles = site->GetArticleList();
466  for (auto & article : articles)
467  {
468  auto *item =
469  new MythUIButtonListItem(m_articlesList, cleanText(article.title()));
470  m_articles[item] = article;
471  }
472 
473  if (m_articlesList->MoveToNamedPosition(currItem))
475 }
476 
478 {
479  QMutexLocker locker(&m_lock);
480 
481  if (!item || item->GetData().isNull())
482  return;
483 
484  auto *site = item->GetData().value<NewsSite*>();
485  if (!site)
486  return;
487 
489  m_articles.clear();
490 
491  NewsArticle::List articles = site->GetArticleList();
492  for (auto & article : articles)
493  {
494  auto *blitem = new MythUIButtonListItem(m_articlesList, cleanText(article.title()));
495  m_articles[blitem] = article;
496  }
497 
498  updateInfoView(item);
499 }
500 
502 {
503  QMutexLocker locker(&m_lock);
504 
505  QMap<MythUIButtonListItem*,NewsArticle>::const_iterator it =
506  m_articles.constFind(articlesListItem);
507 
508  if (it == m_articles.constEnd())
509  return;
510 
511  const NewsArticle& article = *it;
512 
513  if (article.articleURL().isEmpty())
514  return;
515 
516  if (article.enclosure().isEmpty())
517  {
518  QString cmdUrl(article.articleURL());
519 
520  if (m_browser.isEmpty())
521  {
522  ShowOkPopup(tr("No browser command set! MythNews needs MythBrowser to be installed."));
523  return;
524  }
525 
526  // display the web page
527  if (m_browser.toLower() == "internal")
528  {
529  GetMythMainWindow()->HandleMedia("WebBrowser", cmdUrl);
530  return;
531  }
532 
533  QString cmd = m_browser;
534  cmd.replace("%ZOOM%", m_zoom);
535  cmd.replace("%URL%", cmdUrl);
536  cmd.replace('\'', "%27");
537  cmd.replace("&","\\&");
538  cmd.replace(";","\\;");
539 
540  GetMythMainWindow()->AllowInput(false);
542  GetMythMainWindow()->AllowInput(true);
543  return;
544  }
545 
546  playVideo(article);
547 }
548 
550 {
551  QMutexLocker locker(&m_lock);
552 
553  NewsSite *site = nullptr;
554 
555  if (edit)
556  {
558 
559  if (!siteListItem || siteListItem->GetData().isNull())
560  return;
561 
562  site = siteListItem->GetData().value<NewsSite*>();
563  }
564 
566 
567  auto *mythnewseditor = new MythNewsEditor(site, edit, mainStack,
568  "mythnewseditor");
569 
570  if (mythnewseditor->Create())
571  {
572  connect(mythnewseditor, &MythScreenType::Exiting, this, &MythNews::loadSites);
573  mainStack->AddScreen(mythnewseditor);
574  }
575  else
576  {
577  delete mythnewseditor;
578  }
579 }
580 
582 {
584 
585  auto *mythnewsconfig = new MythNewsConfig(mainStack, "mythnewsconfig");
586 
587  if (mythnewsconfig->Create())
588  {
589  connect(mythnewsconfig, &MythScreenType::Exiting, this, &MythNews::loadSites);
590  mainStack->AddScreen(mythnewsconfig);
591  }
592  else
593  {
594  delete mythnewsconfig;
595  }
596 }
597 
599 {
600  QMutexLocker locker(&m_lock);
601 
602  QString label = tr("Options");
603 
604  MythScreenStack *popupStack =
605  GetMythMainWindow()->GetStack("popup stack");
606 
607  m_menuPopup = new MythDialogBox(label, popupStack, "mythnewsmenupopup");
608 
609  if (m_menuPopup->Create())
610  {
611  popupStack->AddScreen(m_menuPopup);
612 
613  m_menuPopup->SetReturnEvent(this, "options");
614 
615  m_menuPopup->AddButton(tr("Manage Feeds"));
616  m_menuPopup->AddButton(tr("Add Feed"));
617  if (!m_newsSites.empty())
618  {
619  m_menuPopup->AddButton(tr("Edit Feed"));
620  m_menuPopup->AddButton(tr("Delete Feed"));
621  }
622  }
623  else
624  {
625  delete m_menuPopup;
626  m_menuPopup = nullptr;
627  }
628 }
629 
631 {
632  QMutexLocker locker(&m_lock);
633 
635 
636  if (siteUIItem && !siteUIItem->GetData().isNull())
637  {
638  auto *site = siteUIItem->GetData().value<NewsSite*>();
639  if (site)
640  {
641  removeFromDB(site->name());
642  loadSites();
643  }
644  }
645 }
646 
647 // does not need locking
648 void MythNews::playVideo(const NewsArticle &article)
649 {
650  GetMythMainWindow()->HandleMedia("Internal", article.enclosure(),
651  article.description(), article.title());
652 }
653 
654 // does not need locking
655 void MythNews::customEvent(QEvent *event)
656 {
657  if (event->type() == DialogCompletionEvent::kEventType)
658  {
659  auto *dce = dynamic_cast<DialogCompletionEvent*>(event);
660  if (dce == nullptr)
661  return;
662 
663  QString resultid = dce->GetId();
664  int buttonnum = dce->GetResult();
665 
666  if (resultid == "options")
667  {
668  if (buttonnum == 0)
669  ShowFeedManager();
670  else if (buttonnum == 1)
671  ShowEditDialog(false);
672  else if (buttonnum == 2)
673  ShowEditDialog(true);
674  else if (buttonnum == 3)
675  deleteNewsSite();
676  }
677 
678  m_menuPopup = nullptr;
679  }
680 }
681 
682 QString MythNews::cleanText(const QString &text)
683 {
684  QString result = text;
685 
686  // replace a few HTML characters
687  result.replace("&#8232;", ""); // LSEP
688  result.replace("&#8233;", ""); // PSEP
689  result.replace("&#163;", u8"\u00A3"); // POUND
690  result.replace("&#173;", ""); // ?
691  result.replace("&#8211;", "-"); // EN-DASH
692  result.replace("&#8220;", """"); // LEFT-DOUBLE-QUOTE
693  result.replace("&#8221;", """"); // RIGHT-DOUBLE-QUOTE
694  result.replace("&#8216;", "'"); // LEFT-SINGLE-QUOTE
695  result.replace("&#8217;", "'"); // RIGHT-SINGLE-QUOTE
696  result.replace("&#39;", "'"); // Apostrophe
697 
698  // Replace paragraph and break HTML with newlines
699  static const QRegularExpression kHtmlParaStartRE
700  { "<p>", QRegularExpression::CaseInsensitiveOption };
701  static const QRegularExpression kHtmlParaEndRE
702  { "</p>", QRegularExpression::CaseInsensitiveOption };
703  static const QRegularExpression kHtmlBreak1RE
704  { "<(br|)>", QRegularExpression::CaseInsensitiveOption };
705  static const QRegularExpression kHtmlBreak2RE
706  { "<(br|)/>", QRegularExpression::CaseInsensitiveOption };
707  if( result.contains(kHtmlParaEndRE) )
708  {
709  result.replace( kHtmlParaStartRE, "");
710  result.replace( kHtmlParaEndRE, "\n\n");
711  }
712  else
713  {
714  result.replace( kHtmlParaStartRE, "\n\n");
715  result.replace( kHtmlParaEndRE, "");
716  }
717  result.replace( kHtmlBreak2RE, "\n");
718  result.replace( kHtmlBreak1RE, "\n");
719  // These are done instead of simplifyWhitespace
720  // because that function also strips out newlines
721  // Replace tab characters with nothing
722  static const QRegularExpression kTabRE { "\t" };
723  result.replace( kTabRE, "");
724  // Replace double space with single
725  static const QRegularExpression kTwoSpaceRE { " " };
726  result.replace( kTwoSpaceRE, "");
727  // Replace whitespace at beginning of lines with newline
728  static const QRegularExpression kStartingSpaceRE { "\n " };
729  result.replace( kStartingSpaceRE, "\n");
730  // Remove any remaining HTML tags
731  static const QRegularExpression kRemoveHtmlRE(QRegularExpression("</?.+>"));
732  result.remove(kRemoveHtmlRE);
733  result = result.trimmed();
734 
735  return result;
736 }
MythNews::ShowMenu
void ShowMenu(void) override
Definition: mythnews.cpp:598
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:93
MythUIButtonList::GetItemCurrent
MythUIButtonListItem * GetItemCurrent() const
Definition: mythuibuttonlist.cpp:1614
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:101
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:682
DialogCompletionEvent::GetId
QString GetId()
Definition: mythdialogbox.h:51
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:417
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:443
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:395
MythNews::customEvent
void customEvent(QEvent *event) override
Definition: mythnews.cpp:655
MythUIButtonList::itemSelected
void itemSelected(MythUIButtonListItem *item)
NewsSite::finished
void finished(NewsSite *item)
LOC_ERR
#define LOC_ERR
Definition: mythnews.cpp:37
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:362
MythNews::loadSites
void loadSites(void)
Definition: mythnews.cpp:153
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:501
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:43
MythScreenType::GetFocusWidget
MythUIType * GetFocusWidget(void) const
Definition: mythscreentype.cpp:111
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:81
mythnewseditor.h
MythUIType::Show
void Show(void)
Definition: mythuitype.cpp:1144
mythlogging.h
mythnews.h
GetConfDir
QString GetConfDir(void)
Definition: mythdirs.cpp:263
MythNews::m_downloadImage
MythUIImage * m_downloadImage
Definition: mythnews.h:69
MythNews::ShowFeedManager
void ShowFeedManager() const
Definition: mythnews.cpp:581
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:116
MythDialogBox::AddButton
void AddButton(const QString &title)
Definition: mythdialogbox.h:197
MythDialogBox
Basic menu dialog, message and a list of options.
Definition: mythdialogbox.h:165
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:648
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:204
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:630
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:432
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:57
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:477
MythDate::kSimplify
@ kSimplify
Do Today/Yesterday/Tomorrow transform.
Definition: mythdate.h:26
MythNews::ShowEditDialog
void ShowEditDialog(bool edit)
Definition: mythnews.cpp:549
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:402
MythNews::m_descText
MythUIText * m_descText
Definition: mythnews.h:66
mythcorecontext.h
XMLParseBase::LoadWindowFromXML
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
Definition: xmlparsebase.cpp:701
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:40
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
DialogCompletionEvent::kEventType
static const Type kEventType
Definition: mythdialogbox.h:56
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:75
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:70
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:127
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:837