MythTV  master
weather.cpp
Go to the documentation of this file.
1 
2 // C headers
3 #include <unistd.h>
4 #include <cstdlib>
5 
6 // QT headers
7 #include <QApplication>
8 
9 // MythTV headers
10 #include <mythdb.h>
11 #include <mythcontext.h>
12 
13 #include <mythuitext.h>
14 #include <mythdate.h>
15 
16 // MythWeather headers
17 #include "weatherScreen.h"
18 #include "sourceManager.h"
19 #include "weatherSetup.h"
20 #include "weather.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->GetNumSetting("weatherTimeout", 10)),
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);
217  m_nextPageTimer->start(1000 * m_nextpageInterval);
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  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  handled = false;
274  }
275 
276  if (!handled && MythScreenType::keyPressEvent(event))
277  handled = true;
278 
279  return handled;
280 }
281 
283 {
284  if (!ws)
285  return;
286 
287  m_currScreen = ws;
289  m_headerText->SetText(m_currScreen->objectName());
290  m_updatedText->SetText(m_currScreen->getValue("updatetime"));
291 }
292 
294 {
295  if (!m_currScreen)
296  return;
297 
298  m_weatherStack->PopScreen(nullptr, false,false);
299 }
300 
302 {
303  if (!m_nextPageTimer->isActive())
304  m_nextPageTimer->start(1000 * m_nextpageInterval);
305  else
306  m_nextPageTimer->stop();
307 
308  m_paused = !m_paused;
309 
310  if (m_pauseText)
311  {
312  if (m_paused)
313  m_pauseText->Show();
314  else
315  m_pauseText->Hide();
316  }
317 }
318 
320 {
321  m_srcMan->stopTimers();
322  m_nextPageTimer->stop();
325 
327 
328  auto *ssetup = new ScreenSetup(mainStack, "weatherscreensetup", m_srcMan);
329 
330  connect(ssetup, &MythScreenType::Exiting, this, &Weather::setupScreens);
331 
332  if (ssetup->Create())
333  {
334  clearScreens();
335  mainStack->AddScreen(ssetup);
336  }
337  else
338  {
339  delete ssetup;
340  }
341 
342  m_firstRun = true;
343 }
344 
346 {
347  WeatherScreen *ws = nextScreen();
348  if (ws && ws->canShowScreen())
349  {
350  hideScreen();
351  showScreen(ws);
352  if (!m_paused)
353  m_nextPageTimer->start(1000 * m_nextpageInterval);
354  }
355 }
356 
358 {
359  WeatherScreen *ws = prevScreen();
360  if (ws && ws->canShowScreen())
361  {
362  hideScreen();
363  showScreen(ws);
364  if (!m_paused)
365  m_nextPageTimer->start(1000 * m_nextpageInterval);
366  }
367 }
368 
370 {
371  WeatherScreen *nxt = nextScreen();
372 
373  if (nxt && nxt->canShowScreen())
374  {
375  hideScreen();
376  showScreen(nxt);
377  }
378  else
379  LOG(VB_GENERAL, LOG_ERR, "Next screen not ready");
380 
381  m_nextPageTimer->start(1000 * m_nextpageInterval);
382 }
383 
384 /*
385  * vim:ts=4:sw=4:ai:et:si:sts=4
386  */
Weather::hideScreen
void hideScreen(void)
Definition: weather.cpp:293
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:783
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:126
MythMainWindow::GetMainStack
MythScreenStack * GetMainStack()
Definition: mythmainwindow.cpp:324
MSqlQuery::size
int size(void) const
Definition: mythdbcon.h:203
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:103
sourceManager.h
mythuitext.h
mythdb.h
MythScreenType::Close
virtual void Close()
Definition: mythscreentype.cpp:402
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
MythMainWindow::TranslateKeyPress
bool TranslateKeyPress(const QString &context, QKeyEvent *e, QStringList &actions, bool allowJumps=true)
Get a list of actions for a keypress in the given context.
Definition: mythmainwindow.cpp:1142
Weather::nextpage_timeout
void nextpage_timeout()
Definition: weather.cpp:369
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:282
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:198
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:603
Weather::m_weatherStack
MythScreenStack * m_weatherStack
Definition: weather.h:54
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
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:310
SourceManager::startTimers
void startTimers()
Definition: sourceManager.cpp:260
Weather::m_updatedText
MythUIText * m_updatedText
Definition: weather.h:74
Weather::m_nextpageInterval
int m_nextpageInterval
Definition: weather.h:57
MythScreenType::GetFocusWidget
MythUIType * GetFocusWidget(void) const
Definition: mythscreentype.cpp:112
Weather::m_srcMan
SourceManager * m_srcMan
Definition: weather.h:64
ScreenSetup
Definition: weatherSetup.h:65
Weather::m_curScreenNum
int m_curScreenNum
Definition: weather.h:66
loadScreens
ScreenListMap loadScreens()
Definition: weatherUtils.cpp:40
Weather::holdPage
void holdPage()
Definition: weather.cpp:301
weatherSetup.h
mythdate.h
SourceManager::stopTimers
void stopTimers()
Definition: sourceManager.cpp:266
SourceManager::findScripts
bool findScripts()
Definition: sourceManager.cpp:81
MythUIType::Show
void Show(void)
Definition: mythuitype.cpp:1125
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:535
Weather::cursorLeft
void cursorLeft()
Definition: weather.cpp:357
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:178
Weather::setupPage
void setupPage()
Definition: weather.cpp:319
Weather::m_firstSetup
bool m_firstSetup
Definition: weather.h:61
SourceManager::doUpdate
void doUpdate(bool forceUpdate=false)
Definition: sourceManager.cpp:272
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:299
ScreenListInfo
Definition: weatherUtils.h:48
SourceManager::findScriptsDB
bool findScriptsDB()
Definition: sourceManager.cpp:35
Weather::m_allScreens
ScreenListMap m_allScreens
Definition: weather.h:68
SourceManager::clearSources
void clearSources()
Definition: sourceManager.cpp:154
WeatherScreen
Weather screen.
Definition: weatherScreen.h:27
Weather::setupScreens
void setupScreens()
Definition: weather.cpp:107
uint
unsigned int uint
Definition: compat.h:141
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:60
SourceManager::setupSources
void setupSources()
Definition: sourceManager.cpp:165
units_t
unsigned char units_t
Definition: weatherUtils.h:24
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:1120
MythScreenType::keyPressEvent
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
Definition: mythscreentype.cpp:414
Weather::cursorRight
void cursorRight()
Definition: weather.cpp:345
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:692
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:864
Weather::Create
bool Create(void) override
Definition: weather.cpp:61
MythUIText::SetText
virtual void SetText(const QString &text)
Definition: mythuitext.cpp:134
mythcontext.h
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:108
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:859
weatherScreen.h
WeatherScreen::Create
bool Create(void) override
Definition: weatherScreen.cpp:33
srcMan
SourceManager * srcMan
Definition: mythplugins/mythweather/mythweather/main.cpp:20
Weather::m_pauseText
MythUIText * m_pauseText
Definition: weather.h:72
MythScreenStack::AddScreen
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Definition: mythscreenstack.cpp:52
query
MSqlQuery query(MSqlQuery::InitCon())
Weather::m_createdSrcMan
bool m_createdSrcMan
Definition: weather.h:63
SourceManager
Definition: sourceManager.h:19
Weather::clearScreens
void clearScreens()
Definition: weather.cpp:93
Weather::prevScreen
WeatherScreen * prevScreen()
Definition: weather.cpp:231
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:808