MythTV  0.26-pre
weather.cpp
Go to the documentation of this file.
00001 
00002 // C headers
00003 #include <unistd.h>
00004 #include <cstdlib>
00005 
00006 // QT headers
00007 #include <QApplication>
00008 
00009 // MythTV headers
00010 #include <mythdb.h>
00011 #include <mythcontext.h>
00012 
00013 #include <mythuitext.h>
00014 #include <mythmiscutil.h>
00015 
00016 // MythWeather headers
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         // No point in doing this as the very first thing we are going to do
00037         // is destroy the sources and reload them.
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     // Load the theme for this screen
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     // Delete any existing screens
00128     clearScreens();
00129 
00130     m_paused = false;
00131     m_pauseText->Hide();
00132 
00133     // Refresh sources
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             // If no screens exist, run the setup
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             // We rejected every screen...  sit on this and rotate.
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  * vim:ts=4:sw=4:ai:et:si:sts=4
00403  */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends