00001
00002
00003 #include <unistd.h>
00004 #include <cstdlib>
00005
00006
00007 #include <QApplication>
00008
00009
00010 #include <mythdb.h>
00011 #include <mythcontext.h>
00012
00013 #include <mythuitext.h>
00014 #include <mythmiscutil.h>
00015
00016
00017 #include "weatherScreen.h"
00018 #include "sourceManager.h"
00019 #include "weatherSetup.h"
00020 #include "weather.h"
00021
00022 Weather::Weather(MythScreenStack *parent, const QString &name, SourceManager *srcMan)
00023 : MythScreenType(parent, name),
00024 m_cur_screen(0)
00025 {
00026 m_weatherStack = new MythScreenStack(GetMythMainWindow(), "weather stack");
00027
00028 m_paused = false;
00029
00030 m_firstRun = true;
00031 m_firstSetup = true;
00032
00033 if (!srcMan)
00034 {
00035 m_srcMan = new SourceManager();
00036
00037
00038 #if 0
00039 m_srcMan->startTimers();
00040 m_srcMan->doUpdate();
00041 #endif
00042 m_createdSrcMan = true;
00043 }
00044 else
00045 {
00046 m_srcMan = srcMan;
00047 m_createdSrcMan = false;
00048 }
00049
00050 m_pauseText = m_headerText = m_updatedText = NULL;
00051
00052 m_nextpageInterval = gCoreContext->GetNumSetting("weatherTimeout", 10);
00053
00054 m_nextpage_Timer = new QTimer(this);
00055 connect(m_nextpage_Timer, SIGNAL(timeout()), SLOT(nextpage_timeout()) );
00056 m_allScreens = loadScreens();
00057 }
00058
00059 Weather::~Weather()
00060 {
00061 if (m_createdSrcMan)
00062 delete m_srcMan;
00063
00064 clearScreens();
00065
00066 if (m_weatherStack)
00067 GetMythMainWindow()->PopScreenStack();
00068 }
00069
00070 bool Weather::Create()
00071 {
00072 bool foundtheme = false;
00073
00074
00075 foundtheme = LoadWindowFromXML("weather-ui.xml", "weatherbase", this);
00076
00077 if (!foundtheme)
00078 {
00079 LOG(VB_GENERAL, LOG_ERR, "Missing required window - weatherbase.");
00080 return false;
00081 }
00082
00083 bool err = false;
00084
00085 UIUtilE::Assign(this, m_pauseText, "pause_text", &err);
00086 UIUtilE::Assign(this, m_headerText, "header", &err);
00087 UIUtilE::Assign(this, m_updatedText, "update_text", &err);
00088
00089 if (err)
00090 {
00091 LOG(VB_GENERAL, LOG_ERR,
00092 "Window weatherbase is missing required elements.");
00093 return false;
00094 }
00095
00096 if (m_pauseText)
00097 {
00098 m_pauseText->SetText(tr("Paused"));
00099 m_pauseText->Hide();
00100 }
00101
00102 return true;
00103 }
00104
00105 void Weather::clearScreens()
00106 {
00107 m_currScreen = NULL;
00108
00109 m_cur_screen = 0;
00110 while (!m_screens.empty())
00111 {
00112 WeatherScreen *screen = m_screens.back();
00113 m_weatherStack->PopScreen(screen, false, false);
00114 m_screens.pop_back();
00115 if (screen)
00116 delete screen;
00117 }
00118 }
00119
00120 void Weather::setupScreens()
00121 {
00122 SetupScreens();
00123 }
00124
00125 bool Weather::SetupScreens()
00126 {
00127
00128 clearScreens();
00129
00130 m_paused = false;
00131 m_pauseText->Hide();
00132
00133
00134 m_srcMan->clearSources();
00135 m_srcMan->findScriptsDB();
00136 m_srcMan->setupSources();
00137
00138 MSqlQuery db(MSqlQuery::InitCon());
00139 QString query =
00140 "SELECT screen_id, container, units, draworder FROM weatherscreens "
00141 " WHERE hostname = :HOST ORDER BY draworder;";
00142 db.prepare(query);
00143 db.bindValue(":HOST", gCoreContext->GetHostName());
00144 if (!db.exec())
00145 {
00146 MythDB::DBError("Selecting weather screens.", db);
00147 return false;
00148 }
00149
00150 if (!db.size())
00151 {
00152 if (m_firstSetup)
00153 {
00154
00155 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00156
00157 ScreenSetup *ssetup = new ScreenSetup(mainStack, "weatherscreensetup",
00158 m_srcMan);
00159
00160 connect(ssetup, SIGNAL(Exiting()), this, SLOT(setupScreens()));
00161
00162 if (ssetup->Create())
00163 {
00164 mainStack->AddScreen(ssetup);
00165 }
00166 else
00167 {
00168 delete ssetup;
00169 }
00170
00171 m_firstSetup = false;
00172 }
00173 else
00174 {
00175 Close();
00176 }
00177 }
00178 else
00179 {
00180 while (db.next())
00181 {
00182 int id = db.value(0).toInt();
00183 QString container = db.value(1).toString();
00184 units_t units = db.value(2).toUInt();
00185 uint draworder = db.value(3).toUInt();
00186
00187 ScreenListInfo &screenListInfo = m_allScreens[container];
00188
00189 WeatherScreen *ws = WeatherScreen::loadScreen(m_weatherStack, &screenListInfo, id);
00190 if (!ws->Create())
00191 {
00192 delete ws;
00193 continue;
00194 }
00195
00196 ws->setUnits(units);
00197 ws->setInUse(true);
00198 m_screens.insert(draworder, ws);
00199 connect(ws, SIGNAL(screenReady(WeatherScreen *)), this,
00200 SLOT(screenReady(WeatherScreen *)));
00201 m_srcMan->connectScreen(id, ws);
00202 }
00203
00204 if( m_screens.empty() )
00205 {
00206
00207 LOG(VB_GENERAL, LOG_ERR, "No weather screens left, aborting.");
00208 m_nextpage_Timer->stop();
00209 if( m_updatedText )
00210 {
00211 m_updatedText->SetText(tr("None of the configured screens are complete in this theme (missing copyright information)."));
00212 m_updatedText->Show();
00213 return true;
00214 }
00215 return false;
00216 }
00217
00218 m_srcMan->startTimers();
00219 m_srcMan->doUpdate(true);
00220 }
00221
00222 return true;
00223 }
00224
00225 void Weather::screenReady(WeatherScreen *ws)
00226 {
00227 if (m_firstRun && m_screens.size() && ws == m_screens[m_cur_screen])
00228 {
00229 m_firstRun = false;
00230 showScreen(ws);
00231 m_nextpage_Timer->start((int)(1000 * m_nextpageInterval));
00232 }
00233 disconnect(ws, SIGNAL(screenReady(WeatherScreen *)), this,
00234 SLOT(screenReady(WeatherScreen *)));
00235 }
00236
00237 WeatherScreen *Weather::nextScreen(void)
00238 {
00239 if (m_screens.empty())
00240 return NULL;
00241
00242 m_cur_screen = (m_cur_screen + 1) % m_screens.size();
00243 return m_screens[m_cur_screen];
00244 }
00245
00246 WeatherScreen *Weather::prevScreen(void)
00247 {
00248 if (m_screens.empty())
00249 return NULL;
00250
00251 m_cur_screen = (m_cur_screen < 0) ? 0 : m_cur_screen;
00252 m_cur_screen = (m_cur_screen + m_screens.size() - 1) % m_screens.size();
00253 return m_screens[m_cur_screen];
00254 }
00255
00256 bool Weather::keyPressEvent(QKeyEvent *event)
00257 {
00258 if (GetFocusWidget() && GetFocusWidget()->keyPressEvent(event))
00259 return true;
00260
00261 bool handled = false;
00262 QStringList actions;
00263 handled = GetMythMainWindow()->TranslateKeyPress("Weather", event, actions);
00264
00265 for (int i = 0; i < actions.size() && !handled; i++)
00266 {
00267 QString action = actions[i];
00268 handled = true;
00269
00270 if (action == "LEFT")
00271 cursorLeft();
00272 else if (action == "RIGHT")
00273 cursorRight();
00274 else if (action == "PAUSE")
00275 holdPage();
00276 else if (action == "MENU")
00277 setupPage();
00278 else if (action == "UPDATE")
00279 {
00280 m_srcMan->doUpdate();
00281 }
00282 else if (action == "ESCAPE")
00283 {
00284 m_nextpage_Timer->stop();
00285 hideScreen();
00286 Close();
00287 }
00288 else
00289 handled = false;
00290 }
00291
00292 if (!handled && MythScreenType::keyPressEvent(event))
00293 handled = true;
00294
00295 return handled;
00296 }
00297
00298 void Weather::showScreen(WeatherScreen *ws)
00299 {
00300 if (!ws)
00301 return;
00302
00303 m_currScreen = ws;
00304 m_weatherStack->AddScreen(m_currScreen, false);
00305 m_headerText->SetText(m_currScreen->objectName());
00306 m_updatedText->SetText(m_currScreen->getValue("updatetime"));
00307 }
00308
00309 void Weather::hideScreen()
00310 {
00311 if (!m_currScreen)
00312 return;
00313
00314 m_weatherStack->PopScreen(false,false);
00315 }
00316
00317 void Weather::holdPage()
00318 {
00319 if (!m_nextpage_Timer->isActive())
00320 m_nextpage_Timer->start(1000 * m_nextpageInterval);
00321 else
00322 m_nextpage_Timer->stop();
00323
00324 m_paused = !m_paused;
00325
00326 if (m_pauseText)
00327 {
00328 if (m_paused)
00329 m_pauseText->Show();
00330 else
00331 m_pauseText->Hide();
00332 }
00333 }
00334
00335 void Weather::setupPage()
00336 {
00337 m_srcMan->stopTimers();
00338 m_nextpage_Timer->stop();
00339 m_srcMan->clearSources();
00340 m_srcMan->findScripts();
00341
00342 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00343
00344 ScreenSetup *ssetup = new ScreenSetup(mainStack, "weatherscreensetup",
00345 m_srcMan);
00346
00347 connect(ssetup, SIGNAL(Exiting()), this, SLOT(setupScreens()));
00348
00349 if (ssetup->Create())
00350 {
00351 clearScreens();
00352 mainStack->AddScreen(ssetup);
00353 }
00354 else
00355 {
00356 delete ssetup;
00357 }
00358
00359 m_firstRun = true;
00360 }
00361
00362 void Weather::cursorRight()
00363 {
00364 WeatherScreen *ws = nextScreen();
00365 if (ws && ws->canShowScreen())
00366 {
00367 hideScreen();
00368 showScreen(ws);
00369 if (!m_paused)
00370 m_nextpage_Timer->start((int)(1000 * m_nextpageInterval));
00371 }
00372 }
00373
00374 void Weather::cursorLeft()
00375 {
00376 WeatherScreen *ws = prevScreen();
00377 if (ws && ws->canShowScreen())
00378 {
00379 hideScreen();
00380 showScreen(ws);
00381 if (!m_paused)
00382 m_nextpage_Timer->start((int)(1000 * m_nextpageInterval));
00383 }
00384 }
00385
00386 void Weather::nextpage_timeout()
00387 {
00388 WeatherScreen *nxt = nextScreen();
00389
00390 if (nxt && nxt->canShowScreen())
00391 {
00392 hideScreen();
00393 showScreen(nxt);
00394 }
00395 else
00396 LOG(VB_GENERAL, LOG_ERR, "Next screen not ready");
00397
00398 m_nextpage_Timer->start((int)(1000 * m_nextpageInterval));
00399 }
00400
00401
00402
00403