00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <qapplication.h>
00013
00014 #include <unistd.h>
00015 #include <cstdlib>
00016
00017 #include <mythtv/mythcontext.h>
00018 #include <mythtv/mythdbcon.h>
00019
00020 #include "weatherScreen.h"
00021 #include "sourceManager.h"
00022 #include "weatherSetup.h"
00023 #include "weather.h"
00024
00025 Weather::Weather(MythMainWindow *parent, SourceManager *srcMan,
00026 const char *name) : MythDialog(parent, name)
00027 {
00028 allowkeys = true;
00029 paused = false;
00030
00031 firstRun = true;
00032 m_srcMan = srcMan;
00033
00034 newlocRect = QRect(0, 0, size().width(), size().height());
00035 fullRect = QRect(0, 0, size().width(), size().height());
00036
00037 nextpageInterval = gContext->GetNumSetting("weatherTimeout", 10);
00038 nextpageIntArrow = gContext->GetNumSetting("weatherHoldTimeout", 20);
00039
00040 m_startup = 0;
00041 theme = new XMLParse();
00042 theme->SetWMult(wmult);
00043 theme->SetHMult(hmult);
00044
00045 if (!theme->LoadTheme(xmldata, "weather", "weather-"))
00046 {
00047 VERBOSE(VB_IMPORTANT, QString("Weather: Couldn't find the theme."));
00048 }
00049
00050 screens.setAutoDelete(true);
00051
00052
00053
00054
00055
00056
00057
00058
00059 showtime_Timer = new QTimer(this);
00060 connect(showtime_Timer, SIGNAL(timeout()), SLOT(showtime_timeout()) );
00061 showtime_Timer->start((int)(60 * 1000));
00062
00063 nextpage_Timer = new QTimer(this);
00064 connect(nextpage_Timer, SIGNAL(timeout()), SLOT(nextpage_timeout()) );
00065 setNoErase();
00066
00067
00068
00069
00070
00071 updateBackground();
00072 setupScreens(xmldata);
00073
00074 if (!gContext->GetNumSetting("weatherbackgroundfetch", 0))
00075 showLayout(m_startup);
00076 showtime_timeout();
00077 }
00078
00079 Weather::~Weather()
00080 {
00081 delete theme;
00082 delete m_startup;
00083
00084
00085
00086
00087 }
00088
00089 void Weather::setupScreens(QDomElement &xml)
00090 {
00091
00092 screens.clear();
00093
00094 currScreen = 0;
00095 if (m_startup)
00096 {
00097 delete m_startup;
00098 m_startup = 0;
00099 }
00100
00101 QMap<QString, QDomElement> containers;
00102 for (QDomNode child = xml.firstChild(); !child.isNull();
00103 child = child.nextSibling())
00104 {
00105 QDomElement e = child.toElement();
00106 if (!e.isNull())
00107 {
00108 if (e.tagName() == "font")
00109 {
00110 if (!theme->GetFont(e.attribute("name"), false))
00111 theme->parseFont(e);
00112 }
00113 else if (e.tagName() == "container")
00114 {
00115 QRect area;
00116 QString name;
00117 int context;
00118 if (e.attribute("name") == "startup")
00119 {
00120 if (!theme->GetSet("startup"))
00121 theme->parseContainer(e, name, context, area);
00122 else
00123 name = e.attribute("name");
00124 WeatherScreen *ws = WeatherScreen::loadScreen(this, theme->GetSet(name));
00125 ws->setInUse(true);
00126 m_startup = ws;
00127 }
00128 else if (e.attribute("name") == "background")
00129 {
00130 theme->parseContainer(e, name, context, area);
00131 updateBackground();
00132 }
00133 else
00134 containers[e.attribute("name")] = e;
00135 }
00136 else
00137 {
00138 cerr << "Unknown element: " << e.tagName() << endl;
00139 exit(0);
00140 }
00141 }
00142 }
00143
00144 MSqlQuery db(MSqlQuery::InitCon());
00145 QString query =
00146 "SELECT screen_id, container, units, draworder FROM weatherscreens "
00147 " WHERE hostname = :HOST ORDER BY draworder;";
00148 db.prepare(query);
00149 db.bindValue(":HOST", gContext->GetHostName());
00150 if (!db.exec())
00151 {
00152 VERBOSE(VB_IMPORTANT, db.lastError().text());
00153 return;
00154 }
00155
00156 if (!db.size())
00157 {
00158 MythPopupBox::showOkPopup(gContext->GetMainWindow(), "no screens",
00159 tr("No Screens defined; Entering Screen Setup."));
00160
00161 m_srcMan->clearSources();
00162 m_srcMan->findScripts();
00163 ScreenSetup ssetup(gContext->GetMainWindow(), m_srcMan);
00164 ssetup.exec();
00165 m_srcMan->clearSources();
00166 m_srcMan->findScriptsDB();
00167 m_srcMan->setupSources();
00168 m_srcMan->startTimers();
00169 m_srcMan->doUpdate();
00170 }
00171
00172
00173 if (!db.exec())
00174 {
00175 VERBOSE(VB_IMPORTANT, db.lastError().text());
00176 return;
00177 }
00178
00179 while (db.next())
00180 {
00181 int id = db.value(0).toInt();
00182 QString container = db.value(1).toString();
00183 units_t units = db.value(2).toUInt();
00184 uint draworder = db.value(3).toUInt();
00185 if (!containers.contains(container))
00186 {
00187 VERBOSE(VB_IMPORTANT,
00188 container + " is in database, but not theme file");
00189 continue;
00190 }
00191 QDomElement e = containers[container];
00192 QRect area;
00193 QString name;
00194 int context;
00195 if (!theme->GetSet(e.attribute("name")))
00196 theme->parseContainer(e, name, context, area);
00197 else name = e.attribute("name");
00198 WeatherScreen *ws =
00199 WeatherScreen::loadScreen(this, theme->GetSet(name), id);
00200 ws->setUnits(units);
00201 ws->setInUse(true);
00202 screens.insert(draworder, ws);
00203 connect(this, SIGNAL(clock_tick()), ws, SLOT(clock_tick()));
00204 connect(ws, SIGNAL(screenReady(WeatherScreen *)), this,
00205 SLOT(screenReady(WeatherScreen *)));
00206 m_srcMan->connectScreen(id, ws);
00207 }
00208 }
00209
00210 void Weather::screenReady(WeatherScreen *ws)
00211 {
00212 WeatherScreen *nxt = nextScreen();
00213
00214 if (firstRun && ws == nxt)
00215 {
00216 firstRun = false;
00217 setPaletteBackgroundPixmap(realBackground);
00218 showLayout(nxt);
00219 nextpage_Timer->start((int)(1000 * nextpageInterval));
00220 }
00221 disconnect(ws, SIGNAL(screenReady(WeatherScreen *)), this,
00222 SLOT(screenReady(WeatherScreen *)));
00223 }
00224
00225 WeatherScreen *Weather::nextScreen()
00226 {
00227 WeatherScreen *ws = screens.next();
00228 if (!ws)
00229 ws = screens.first();
00230 return ws;
00231 }
00232
00233 WeatherScreen *Weather::prevScreen()
00234 {
00235 WeatherScreen *ws = screens.prev();
00236 if (!ws)
00237 ws = screens.last();
00238 return ws;
00239 }
00240
00241 void Weather::keyPressEvent(QKeyEvent *e)
00242 {
00243 if (currScreen && currScreen->usingKeys() && currScreen->handleKey(e))
00244 {
00245 return;
00246 }
00247
00248 bool handled = false;
00249 QStringList actions;
00250 gContext->GetMainWindow()->TranslateKeyPress("Weather", e, actions);
00251
00252 for (unsigned int i = 0; i < actions.size() && !handled; i++)
00253 {
00254 QString action = actions[i];
00255 handled = true;
00256
00257 if (action == "LEFT")
00258 cursorLeft();
00259 else if (action == "RIGHT")
00260 cursorRight();
00261
00262
00263 else if (action == "PAUSE")
00264 holdPage();
00265 else if (action == "MENU")
00266 setupPage();
00267 else if (action == "UPDATE")
00268 {
00269 m_srcMan->doUpdate();
00270 }
00271 else
00272 handled = false;
00273 }
00274
00275 if (!handled)
00276 MythDialog::keyPressEvent(e);
00277 }
00278
00279 void Weather::updateBackground()
00280 {
00281 QPixmap bground(size());
00282 bground.fill(this, 0, 0);
00283
00284 QPainter tmp(&bground);
00285
00286 LayerSet *container = theme->GetSet("background");
00287 if (container)
00288 {
00289 container->Draw(&tmp, 0, 0);
00290 }
00291
00292 tmp.end();
00293 realBackground = bground;
00294 setPaletteBackgroundPixmap(realBackground);
00295 }
00296
00297 void Weather::paintEvent(QPaintEvent *e)
00298 {
00299 QRect r = e->rect();
00300 QPainter p(this);
00301
00302 if (r.intersects(fullRect))
00303 updatePage(&p);
00304
00305 MythDialog::paintEvent(e);
00306 }
00307
00308 void Weather::updatePage(QPainter *dr)
00309 {
00310 QRect pr = fullRect;
00311 QPixmap pix(pr.size());
00312 pix.fill(this, pr.topLeft());
00313 QPainter tmp(&pix);
00314
00315 if (currScreen)
00316 currScreen->draw(&tmp);
00317 tmp.end();
00318 dr->drawPixmap(pr.topLeft(), pix);
00319 }
00320
00321 void Weather::showLayout(WeatherScreen *ws)
00322 {
00323 currScreen = ws;
00324 ws->showing();
00325 update();
00326 }
00327
00328 void Weather::processEvents()
00329 {
00330 qApp->processEvents();
00331 }
00332
00333 void Weather::showtime_timeout()
00334 {
00335 emit clock_tick();
00336 update();
00337 }
00338
00339 void Weather::holdPage()
00340 {
00341 if (!nextpage_Timer->isActive())
00342 nextpage_Timer->start(1000 * nextpageInterval);
00343 else nextpage_Timer->stop();
00344 paused = !paused;
00345 if (currScreen)
00346 currScreen->toggle_pause(paused);
00347 update(fullRect);
00348 }
00349
00350 void Weather::setupPage()
00351 {
00352 m_srcMan->stopTimers();
00353 nextpage_Timer->stop();
00354 m_srcMan->clearSources();
00355 m_srcMan->findScripts();
00356 ScreenSetup ssetup(gContext->GetMainWindow(), m_srcMan);
00357 ssetup.exec();
00358 firstRun = true;
00359 m_srcMan->clearSources();
00360 m_srcMan->findScriptsDB();
00361 m_srcMan->setupSources();
00362 setupScreens(xmldata);
00363 m_srcMan->startTimers();
00364 m_srcMan->doUpdate();
00365
00366 #if 0
00367 m_srcMan->stopTimers();
00368 nextpage_Timer->stop();
00369 m_srcMan->clearSources();
00370 m_srcMan->findScripts();
00371 WeatherSetup setup(gContext->GetMainWindow(), m_srcMan);
00372 setup.exec();
00373 firstRun = true;
00374 m_srcMan->setupSources();
00375 setupScreens(xmldata);
00376 nextpageInterval = gContext->GetNumSetting("weatherTimeout", 10);
00377 nextpageIntArrow = gContext->GetNumSetting("weatherHoldTimeout", 20);
00378 m_srcMan->startTimers();
00379 m_srcMan->doUpdate();
00380 #endif
00381 }
00382
00383 void Weather::cursorRight()
00384 {
00385 WeatherScreen *ws = nextScreen();
00386 if (ws->canShowScreen())
00387 {
00388 if (currScreen)
00389 currScreen->hiding();
00390 currScreen = ws;
00391 currScreen->showing();
00392 currScreen->toggle_pause(paused);
00393 update();
00394 if (!paused)
00395 nextpage_Timer->start((int)(1000 * nextpageIntArrow));
00396 }
00397 }
00398
00399 void Weather::cursorLeft()
00400 {
00401 WeatherScreen *ws = prevScreen();
00402 if (ws->canShowScreen())
00403 {
00404 if (currScreen)
00405 currScreen->hiding();
00406 currScreen = ws;
00407 currScreen->showing();
00408 currScreen->toggle_pause(paused);
00409 update();
00410 if (!paused)
00411 nextpage_Timer->start((int)(1000 * nextpageIntArrow));
00412 }
00413 }
00414
00415 void Weather::nextpage_timeout()
00416 {
00417 WeatherScreen *nxt = nextScreen();
00418
00419 if (nxt->canShowScreen())
00420 {
00421 if (currScreen)
00422 currScreen->hiding();
00423 showLayout(nxt);
00424 }
00425 else
00426 VERBOSE(VB_GENERAL, "Next screen not ready");
00427
00428 nextpage_Timer->changeInterval((int)(1000 * nextpageInterval));
00429 }