MythTV  master
weather.cpp
Go to the documentation of this file.
1 
2 // C headers
3 #include <cstdlib>
4 #include <unistd.h>
5 
6 // QT headers
7 #include <QApplication>
8 
9 // MythTV headers
11 #include <libmythbase/mythdate.h>
12 #include <libmythbase/mythdb.h>
14 #include <libmythui/mythuitext.h>
15 
16 // MythWeather headers
17 #include "sourceManager.h"
18 #include "weather.h"
19 #include "weatherScreen.h"
20 #include "weatherSetup.h"
21 
22 Weather::Weather(MythScreenStack *parent, const QString &name, SourceManager *srcMan)
23  : MythScreenType(parent, name),
24  m_weatherStack(new MythScreenStack(GetMythMainWindow(), "weather stack")),
25  m_nextpageInterval(gCoreContext->GetDurSetting<std::chrono::seconds>("weatherTimeout", 10s)),
26  m_nextPageTimer(new QTimer(this))
27 {
28  if (!srcMan)
29  {
30  m_srcMan = new SourceManager();
31  // No point in doing this as the very first thing we are going to do
32  // is destroy the sources and reload them.
33 #if 0
35  m_srcMan->doUpdate();
36 #endif
37  m_createdSrcMan = true;
38  }
39  else
40  {
41  m_srcMan = srcMan;
42  m_createdSrcMan = false;
43  }
44 
46 
48 }
49 
51 {
52  if (m_createdSrcMan)
53  delete m_srcMan;
54 
55  clearScreens();
56 
57  if (m_weatherStack)
59 }
60 
62 {
63  // Load the theme for this screen
64  bool foundtheme = LoadWindowFromXML("weather-ui.xml", "weatherbase", this);
65  if (!foundtheme)
66  {
67  LOG(VB_GENERAL, LOG_ERR, "Missing required window - weatherbase.");
68  return false;
69  }
70 
71  bool err = false;
72 
73  UIUtilE::Assign(this, m_pauseText, "pause_text", &err);
74  UIUtilE::Assign(this, m_headerText, "header", &err);
75  UIUtilE::Assign(this, m_updatedText, "update_text", &err);
76 
77  if (err)
78  {
79  LOG(VB_GENERAL, LOG_ERR,
80  "Window weatherbase is missing required elements.");
81  return false;
82  }
83 
84  if (m_pauseText)
85  {
86  m_pauseText->SetText(tr("Paused"));
87  m_pauseText->Hide();
88  }
89 
90  return true;
91 }
92 
94 {
95  m_currScreen = nullptr;
96 
97  m_curScreenNum = 0;
98  while (!m_screens.empty())
99  {
100  WeatherScreen *screen = m_screens.back();
101  m_weatherStack->PopScreen(screen, false, false);
102  m_screens.pop_back();
103  delete screen;
104  }
105 }
106 
108 {
109  SetupScreens();
110 }
111 
113 {
114  // Delete any existing screens
115  clearScreens();
116 
117  m_paused = false;
118  m_pauseText->Hide();
119 
120  // Refresh sources
124 
126  QString query =
127  "SELECT screen_id, container, units, draworder FROM weatherscreens "
128  " WHERE hostname = :HOST ORDER BY draworder;";
129  db.prepare(query);
130  db.bindValue(":HOST", gCoreContext->GetHostName());
131  if (!db.exec())
132  {
133  MythDB::DBError("Selecting weather screens.", db);
134  return false;
135  }
136 
137  if (!db.size())
138  {
139  if (m_firstSetup)
140  {
141  m_firstSetup = false;
142  // If no screens exist, run the setup
144 
145  auto *ssetup = new ScreenSetup(mainStack, "weatherscreensetup",
146  m_srcMan);
147 
148  connect(ssetup, &MythScreenType::Exiting, this, &Weather::setupScreens);
149 
150  if (ssetup->Create())
151  {
152  mainStack->AddScreen(ssetup);
153  }
154  else
155  {
156  delete ssetup;
157  }
158  }
159  else
160  {
161  Close();
162  }
163  }
164  else
165  {
166  while (db.next())
167  {
168  int id = db.value(0).toInt();
169  QString container = db.value(1).toString();
170  units_t units = db.value(2).toUInt();
171  uint draworder = db.value(3).toUInt();
172 
173  ScreenListInfo &screenListInfo = m_allScreens[container];
174 
175  WeatherScreen *ws = WeatherScreen::loadScreen(m_weatherStack, &screenListInfo, id);
176  if (!ws->Create())
177  {
178  delete ws;
179  continue;
180  }
181 
182  ws->setUnits(units);
183  ws->setInUse(true);
184  m_screens.insert(draworder, ws);
185  connect(ws, &WeatherScreen::screenReady, this,
187  m_srcMan->connectScreen(id, ws);
188  }
189 
190  if( m_screens.empty() )
191  {
192  // We rejected every screen... sit on this and rotate.
193  LOG(VB_GENERAL, LOG_ERR, "No weather screens left, aborting.");
194  m_nextPageTimer->stop();
195  if( m_updatedText )
196  {
197  m_updatedText->SetText(tr("None of the configured screens are complete in this theme (missing copyright information)."));
198  m_updatedText->Show();
199  return true;
200  }
201  return false;
202  }
203 
205  m_srcMan->doUpdate(true);
206  }
207 
208  return true;
209 }
210 
212 {
213  if (m_firstRun && !m_screens.empty() && ws == m_screens[m_curScreenNum])
214  {
215  m_firstRun = false;
216  showScreen(ws);
218  }
219  disconnect(ws, &WeatherScreen::screenReady, this, &Weather::screenReady);
220 }
221 
223 {
224  if (m_screens.empty())
225  return nullptr;
226 
227  m_curScreenNum = (m_curScreenNum + 1) % m_screens.size();
228  return m_screens[m_curScreenNum];
229 }
230 
232 {
233  if (m_screens.empty())
234  return nullptr;
235 
237  m_curScreenNum = (m_curScreenNum + m_screens.size() - 1) % m_screens.size();
238  return m_screens[m_curScreenNum];
239 }
240 
241 bool Weather::keyPressEvent(QKeyEvent *event)
242 {
243  if (GetFocusWidget() && GetFocusWidget()->keyPressEvent(event))
244  return true;
245 
246  QStringList actions;
247  bool handled = GetMythMainWindow()->TranslateKeyPress("Weather", event, actions);
248 
249  for (int i = 0; i < actions.size() && !handled; i++)
250  {
251  const QString& action = actions[i];
252  handled = true;
253 
254  if (action == "LEFT")
255  cursorLeft();
256  else if (action == "RIGHT")
257  cursorRight();
258  else if (action == "PAUSE")
259  holdPage();
260  else if (action == "MENU")
261  setupPage();
262  else if (action == "UPDATE")
263  {
264  m_srcMan->doUpdate();
265  }
266  else if (action == "ESCAPE")
267  {
268  m_nextPageTimer->stop();
269  hideScreen();
270  Close();
271  }
272  else
273  {
274  handled = false;
275  }
276  }
277 
278  if (!handled && MythScreenType::keyPressEvent(event))
279  handled = true;
280 
281  return handled;
282 }
283 
285 {
286  if (!ws)
287  return;
288 
289  m_currScreen = ws;
291  m_headerText->SetText(m_currScreen->objectName());
292  m_updatedText->SetText(m_currScreen->getValue("updatetime"));
293 }
294 
296 {
297  if (!m_currScreen)
298  return;
299 
300  m_weatherStack->PopScreen(nullptr, false,false);
301 }
302 
304 {
305  if (!m_nextPageTimer->isActive())
307  else
308  m_nextPageTimer->stop();
309 
310  m_paused = !m_paused;
311 
312  if (m_pauseText)
313  {
314  if (m_paused)
315  m_pauseText->Show();
316  else
317  m_pauseText->Hide();
318  }
319 }
320 
322 {
323  m_srcMan->stopTimers();
324  m_nextPageTimer->stop();
327 
329 
330  auto *ssetup = new ScreenSetup(mainStack, "weatherscreensetup", m_srcMan);
331 
332  connect(ssetup, &MythScreenType::Exiting, this, &Weather::setupScreens);
333 
334  if (ssetup->Create())
335  {
336  clearScreens();
337  mainStack->AddScreen(ssetup);
338  }
339  else
340  {
341  delete ssetup;
342  }
343 
344  m_firstRun = true;
345 }
346 
348 {
349  WeatherScreen *ws = nextScreen();
350  if (ws && ws->canShowScreen())
351  {
352  hideScreen();
353  showScreen(ws);
354  if (!m_paused)
356  }
357 }
358 
360 {
361  WeatherScreen *ws = prevScreen();
362  if (ws && ws->canShowScreen())
363  {
364  hideScreen();
365  showScreen(ws);
366  if (!m_paused)
368  }
369 }
370 
372 {
373  WeatherScreen *nxt = nextScreen();
374 
375  if (nxt && nxt->canShowScreen())
376  {
377  hideScreen();
378  showScreen(nxt);
379  }
380  else
381  {
382  LOG(VB_GENERAL, LOG_ERR, "Next screen not ready");
383  }
384 
386 }
387 
388 /*
389  * vim:ts=4:sw=4:ai:et:si:sts=4
390  */
Weather::hideScreen
void hideScreen(void)
Definition: weather.cpp:295
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:812
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:127
MythMainWindow::GetMainStack
MythScreenStack * GetMainStack()
Definition: mythmainwindow.cpp:317
MSqlQuery::size
int size(void) const
Definition: mythdbcon.h:214
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:101
sourceManager.h
mythuitext.h
mythdb.h
MythScreenType::Close
virtual void Close()
Definition: mythscreentype.cpp:384
Weather::keyPressEvent
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
Definition: weather.cpp:241
WeatherScreen::loadScreen
static WeatherScreen * loadScreen(MythScreenStack *parent, ScreenListInfo *screenDefn, int id)
Definition: weatherScreen.cpp:11
Weather::nextpage_timeout
void nextpage_timeout()
Definition: weather.cpp:371
Weather::m_screens
ScreenList m_screens
Definition: weather.h:65
Weather::Weather
Weather(MythScreenStack *parent, const QString &name, SourceManager *srcMan)
Definition: weather.cpp:22
Weather::nextScreen
WeatherScreen * nextScreen()
Definition: weather.cpp:222
Weather::showScreen
void showScreen(WeatherScreen *ws)
Definition: weather.cpp:284
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:204
MythScreenStack
Definition: mythscreenstack.h:16
Weather::~Weather
~Weather() override
Definition: weather.cpp:50
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:618
Weather::m_weatherStack
MythScreenStack * m_weatherStack
Definition: weather.h:54
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
WeatherScreen::setUnits
void setUnits(units_t units)
Definition: weatherScreen.h:44
weather.h
MythMainWindow::PopScreenStack
void PopScreenStack()
Definition: mythmainwindow.cpp:303
SourceManager::startTimers
void startTimers()
Definition: sourceManager.cpp:261
Weather::m_updatedText
MythUIText * m_updatedText
Definition: weather.h:74
MythScreenType::GetFocusWidget
MythUIType * GetFocusWidget(void) const
Definition: mythscreentype.cpp:111
Weather::m_srcMan
SourceManager * m_srcMan
Definition: weather.h:64
ScreenSetup
Definition: weatherSetup.h:63
Weather::m_curScreenNum
int m_curScreenNum
Definition: weather.h:66
loadScreens
ScreenListMap loadScreens()
Definition: weatherUtils.cpp:42
Weather::holdPage
void holdPage()
Definition: weather.cpp:303
weatherSetup.h
mythdate.h
SourceManager::stopTimers
void stopTimers()
Definition: sourceManager.cpp:267
SourceManager::findScripts
bool findScripts()
Definition: sourceManager.cpp:82
MythUIType::Show
void Show(void)
Definition: mythuitype.cpp:1144
mythlogging.h
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
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:550
Weather::cursorLeft
void cursorLeft()
Definition: weather.cpp:359
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:226
Weather::setupPage
void setupPage()
Definition: weather.cpp:321
Weather::m_firstSetup
bool m_firstSetup
Definition: weather.h:61
SourceManager::doUpdate
void doUpdate(bool forceUpdate=false)
Definition: sourceManager.cpp:273
Weather::m_firstRun
bool m_firstRun
Definition: weather.h:56
Weather::m_paused
bool m_paused
Definition: weather.h:70
Weather::m_currScreen
WeatherScreen * m_currScreen
Definition: weather.h:69
SourceManager::connectScreen
bool connectScreen(uint id, WeatherScreen *screen)
Definition: sourceManager.cpp:300
ScreenListInfo
Definition: weatherUtils.h:48
SourceManager::findScriptsDB
bool findScriptsDB()
Definition: sourceManager.cpp:36
Weather::m_allScreens
ScreenListMap m_allScreens
Definition: weather.h:68
SourceManager::clearSources
void clearSources()
Definition: sourceManager.cpp:155
WeatherScreen
Weather screen.
Definition: weatherScreen.h:26
Weather::setupScreens
void setupScreens()
Definition: weather.cpp:107
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:57
SourceManager::setupSources
void setupSources()
Definition: sourceManager.cpp:166
units_t
unsigned char units_t
Definition: weatherUtils.h:25
WeatherScreen::canShowScreen
virtual bool canShowScreen()
Definition: weatherScreen.cpp:46
UIUtilDisp::Assign
static bool Assign(ContainerType *container, UIType *&item, const QString &name, bool *err=nullptr)
Definition: mythuiutils.h:27
MythUIType::Hide
void Hide(void)
Definition: mythuitype.cpp:1139
MythScreenType::keyPressEvent
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
Definition: mythscreentype.cpp:402
Weather::cursorRight
void cursorRight()
Definition: weather.cpp:347
mythcorecontext.h
Weather::m_nextPageTimer
QTimer * m_nextPageTimer
Definition: weather.h:59
XMLParseBase::LoadWindowFromXML
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
Definition: xmlparsebase.cpp:701
WeatherScreen::setInUse
void setInUse(bool inuse)
Definition: weatherScreen.h:48
WeatherScreen::getValue
QString getValue(const QString &key)
Definition: weatherScreen.h:41
Weather::SetupScreens
bool SetupScreens()
Definition: weather.cpp:112
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:888
Weather::Create
bool Create(void) override
Definition: weather.cpp:61
MythUIText::SetText
virtual void SetText(const QString &text)
Definition: mythuitext.cpp:115
MythScreenStack::PopScreen
virtual void PopScreen(MythScreenType *screen=nullptr, bool allowFade=true, bool deleteScreen=true)
Definition: mythscreenstack.cpp:86
GetMythMainWindow
MythMainWindow * GetMythMainWindow(void)
Definition: mythmainwindow.cpp:104
Weather::screenReady
void screenReady(WeatherScreen *ws)
Definition: weather.cpp:211
build_compdb.action
action
Definition: build_compdb.py:9
Weather::m_headerText
MythUIText * m_headerText
Definition: weather.h:73
MythScreenType::Exiting
void Exiting()
WeatherScreen::screenReady
void screenReady(WeatherScreen *)
MythCoreContext::GetHostName
QString GetHostName(void)
Definition: mythcorecontext.cpp:844
weatherScreen.h
WeatherScreen::Create
bool Create(void) override
Definition: weatherScreen.cpp:33
srcMan
SourceManager * srcMan
Definition: mythweather.cpp:21
Weather::m_nextpageInterval
std::chrono::seconds m_nextpageInterval
Definition: weather.h:57
Weather::m_pauseText
MythUIText * m_pauseText
Definition: weather.h:72
MythScreenStack::AddScreen
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Definition: mythscreenstack.cpp:52
Weather::m_createdSrcMan
bool m_createdSrcMan
Definition: weather.h:63
SourceManager
Definition: sourceManager.h:18
Weather::clearScreens
void clearScreens()
Definition: weather.cpp:93
Weather::prevScreen
WeatherScreen * prevScreen()
Definition: weather.cpp:231
uint
unsigned int uint
Definition: freesurround.h:24
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:837