MythTV master
mythnewsconfig.cpp
Go to the documentation of this file.
1// QT Headers
2#include <QFile>
3#include <QStringList>
4
5// MythTV headers
13
14// MythNews headers
15#include "mythnewsconfig.h"
16#include "newsdbutil.h"
17#include "newssite.h"
18
19#define LOC QString("MythNewsConfig: ")
20#define LOC_WARN QString("MythNewsConfig, Warning: ")
21#define LOC_ERR QString("MythNewsConfig, Error: ")
22
23// ---------------------------------------------------
24
26{
27 public:
30};
31
32// ---------------------------------------------------
33
35 : MythScreenType(parent, name),
36 m_priv(new MythNewsConfigPriv),
37 m_updateFreq(gCoreContext->GetNumSetting("NewsUpdateFrequency", 30))
38{
40}
41
43{
44 delete m_priv;
45}
46
48{
49 QMutexLocker locker(&m_lock);
50
51 QString filename = QString("%1%2")
52 .arg(GetShareDir(), "mythnews/news-sites.xml");
53
54 QFile xmlFile(filename);
55
56 if (!xmlFile.exists() || !xmlFile.open(QIODevice::ReadOnly))
57 {
58 LOG(VB_GENERAL, LOG_ERR, LOC + "Cannot open news-sites.xml");
59 return;
60 }
61
62 QDomDocument domDoc;
63
64#if QT_VERSION < QT_VERSION_CHECK(6,5,0)
65 QString errorMsg;
66 int errorLine = 0;
67 int errorColumn = 0;
68
69 if (!domDoc.setContent(&xmlFile, false, &errorMsg,
70 &errorLine, &errorColumn))
71 {
72 LOG(VB_GENERAL, LOG_ERR, LOC +
73 "Could not read content of news-sites.xml" +
74 QString("\n\t\t\tError parsing %1").arg(filename) +
75 QString("\n\t\t\tat line: %1 column: %2 msg: %3")
76 .arg(errorLine).arg(errorColumn).arg(errorMsg));
77 return;
78 }
79#else
80 auto parseResult = domDoc.setContent(&xmlFile);
81 if (!parseResult)
82 {
83 LOG(VB_GENERAL, LOG_ERR, LOC +
84 "Could not read content of news-sites.xml" +
85 QString("\n\t\t\tError parsing %1").arg(filename) +
86 QString("\n\t\t\tat line: %1 column: %2 msg: %3")
87 .arg(parseResult.errorLine).arg(parseResult.errorColumn)
88 .arg(parseResult.errorMessage));
89 return;
90 }
91#endif
92
93 m_priv->m_categoryList.clear();
94
95 QDomNodeList catList =
96 domDoc.elementsByTagName(QString::fromUtf8("category"));
97
98 QDomNode catNode;
99 QDomNode siteNode;
100 for (int i = 0; i < catList.count(); i++)
101 {
102 catNode = catList.item(i);
103
105 cat.m_name = catNode.toElement().attribute("name");
106
107 QDomNodeList siteList = catNode.childNodes();
108
109 for (int j = 0; j < siteList.count(); j++)
110 {
111 siteNode = siteList.item(j);
112
113 NewsSiteItem site = NewsSiteItem();
114 site.m_name = siteNode.namedItem(QString("title")).toElement().text();
115 site.m_category = cat.m_name;
116 site.m_url = siteNode.namedItem(QString("url")).toElement().text();
117 site.m_ico = siteNode.namedItem(QString("ico")).toElement().text();
118 site.m_podcast = false;
119 site.m_inDB = findInDB(site.m_name);
120
121 cat.m_siteList.push_back(site);
122 }
123
124 m_priv->m_categoryList.push_back(cat);
125 }
126
127 xmlFile.close();
128}
129
131{
132 QMutexLocker locker(&m_lock);
133
134 // Load the theme for this screen
135 bool foundtheme = LoadWindowFromXML("news-ui.xml", "config", this);
136
137 if (!foundtheme)
138 return false;
139
140 bool err = false;
141 UIUtilE::Assign(this, m_categoriesList, "category", &err);
142 UIUtilE::Assign(this, m_siteList, "sites", &err);
143 UIUtilW::Assign(this, m_helpText, "help", &err);
144
145 if (err)
146 {
147 LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'config'");
148 return false;
149 }
150
155
157
159
160 loadData();
161
162 return true;
163}
164
166{
167 QMutexLocker locker(&m_lock);
168
169 for (auto & category : m_priv->m_categoryList)
170 {
171 auto *item = new MythUIButtonListItem(m_categoriesList,category.m_name);
172 item->SetData(QVariant::fromValue(&category));
173 if (!category.m_siteList.empty())
174 item->setDrawArrow(true);
175 }
177}
178
180{
181 QMutexLocker locker(&m_lock);
182
183 if (!item )
184 return;
185
186 auto *site = item->GetData().value<NewsSiteItem*>();
187 if (!site)
188 return;
189
190 bool checked = (item->state() == MythUIButtonListItem::FullChecked);
191
192 if (!checked)
193 {
194 if (insertInDB(site))
195 {
196 site->m_inDB = true;
198 }
199 }
200 else
201 {
202 if (removeFromDB(site))
203 {
204 site->m_inDB = false;
206 }
207 }
208}
209
211{
212 QMutexLocker locker(&m_lock);
213
214 if (!item)
215 return;
216
217 m_siteList->Reset();
218
219 auto *cat = item->GetData().value<NewsCategory*>();
220 if (!cat)
221 return;
222
223 for (auto & site : cat->m_siteList)
224 {
225 auto *newitem =
226 new MythUIButtonListItem(m_siteList, site.m_name, nullptr, true,
227 site.m_inDB ?
230 newitem->SetData(QVariant::fromValue(&site));
231 }
232}
233
234bool MythNewsConfig::keyPressEvent(QKeyEvent *event)
235{
236 if (GetFocusWidget()->keyPressEvent(event))
237 return true;
238
239 QStringList actions;
240 bool handled = GetMythMainWindow()->TranslateKeyPress("News", event, actions);
241
242 if (!handled && MythScreenType::keyPressEvent(event))
243 handled = true;
244
245 return handled;
246}
bool TranslateKeyPress(const QString &Context, QKeyEvent *Event, QStringList &Actions, bool AllowJumps=true)
Get a list of actions for a keypress in the given context.
NewsCategory::List m_categoryList
QStringList m_selectedSitesList
~MythNewsConfig() override
void slotCategoryChanged(MythUIButtonListItem *item)
void populateSites(void)
bool Create(void) override
void toggleItem(MythUIButtonListItem *item)
MythNewsConfigPriv * m_priv
MythUIText * m_helpText
MythUIButtonList * m_categoriesList
QRecursiveMutex m_lock
MythUIButtonList * m_siteList
void loadData(void)
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
MythNewsConfig(MythScreenStack *parent, const QString &name)
Screen in which all other widgets are contained and rendered.
void BuildFocusList(void)
MythUIType * GetFocusWidget(void) const
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
bool SetFocusWidget(MythUIType *widget=nullptr)
CheckState state() const
void setChecked(CheckState state)
MythUIButtonListItem * GetItemFirst() const
void Reset() override
Reset the widget to it's original state, should not reset changes made by the theme.
void itemClicked(MythUIButtonListItem *item)
void itemSelected(MythUIButtonListItem *item)
std::vector< NewsCategory > List
Definition: newssite.h:40
bool m_podcast
Definition: newssite.h:33
QString m_category
Definition: newssite.h:29
bool m_inDB
Definition: newssite.h:32
QString m_name
Definition: newssite.h:28
QString m_ico
Definition: newssite.h:31
QString m_url
Definition: newssite.h:30
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
QString GetShareDir(void)
Definition: mythdirs.cpp:261
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MythMainWindow * GetMythMainWindow(void)
#define LOC
bool removeFromDB(RSSSite *site)
Definition: netutils.cpp:686
bool findInDB(const QString &url, ArticleType type)
Definition: netutils.cpp:527
bool insertInDB(RSSSite *site)
Definition: netutils.cpp:643
static bool Assign(ContainerType *container, UIType *&item, const QString &name, bool *err=nullptr)
Definition: mythuiutils.h:27