MythTV  0.26-pre
weatherSetup.cpp
Go to the documentation of this file.
00001 
00002 // QT headers
00003 #include <QApplication>
00004 #include <QSqlError>
00005 
00006 // MythTV headers
00007 //#include <mythdbcon.h>
00008 #include <mythdb.h>
00009 #include <mythprogressdialog.h>
00010 
00011 // MythWeather headers
00012 #include "weatherScreen.h"
00013 #include "weatherSource.h"
00014 #include "sourceManager.h"
00015 #include "weatherSetup.h"
00016 
00017 #define GLBL_SCREEN 0
00018 #define SCREEN_SETUP_SCREEN 1
00019 #define SRC_SCREEN 2
00020 
00021 GlobalSetup::GlobalSetup(MythScreenStack *parent, const QString &name)
00022     : MythScreenType(parent, name),
00023       m_backgroundCheckbox(NULL), m_timeoutSpinbox(NULL),
00024       m_timeout(0),               m_hold_timeout(0),
00025       m_finishButton(NULL)
00026 {
00027 }
00028 
00029 GlobalSetup::~GlobalSetup()
00030 {
00031 }
00032 
00033 bool GlobalSetup::Create()
00034 {
00035     bool foundtheme = false;
00036 
00037     // Load the theme for this screen
00038     foundtheme = LoadWindowFromXML("weather-ui.xml", "global-setup", this);
00039 
00040     if (!foundtheme)
00041         return false;
00042 
00043     m_timeoutSpinbox = dynamic_cast<MythUISpinBox *> (GetChild("timeout_spinbox"));
00044 
00045     m_backgroundCheckbox = dynamic_cast<MythUICheckBox *> (GetChild("backgroundcheck"));
00046     m_finishButton = dynamic_cast<MythUIButton *> (GetChild("finishbutton"));
00047 
00048     if (!m_timeoutSpinbox || !m_finishButton || !m_backgroundCheckbox)
00049     {
00050         LOG(VB_GENERAL, LOG_ERR, "Theme is missing required elements.");
00051         return false;
00052     }
00053 
00054     BuildFocusList();
00055 
00056     m_finishButton->SetText(tr("Finish"));
00057     connect(m_finishButton, SIGNAL(Clicked()), this, SLOT(saveData()));
00058 
00059     loadData();
00060 
00061     return true;
00062 }
00063 
00064 void GlobalSetup::loadData()
00065 {
00066     int setting = gCoreContext->GetNumSetting("weatherbackgroundfetch", 0);
00067     if (setting == 1)
00068         m_backgroundCheckbox->SetCheckState(MythUIStateType::Full);
00069 
00070     m_timeout = gCoreContext->GetNumSetting("weatherTimeout", 10);
00071     m_timeoutSpinbox->SetRange(5, 120, 5);
00072     m_timeoutSpinbox->SetValue(m_timeout);
00073 }
00074 
00075 void GlobalSetup::saveData()
00076 {
00077     int timeout = m_timeoutSpinbox->GetIntValue();
00078     gCoreContext->SaveSetting("weatherTimeout", timeout);
00079 
00080     int checkstate = 0;
00081     if (m_backgroundCheckbox->GetCheckState() == MythUIStateType::Full)
00082         checkstate = 1;
00083     gCoreContext->SaveSetting("weatherbackgroundfetch", checkstate);
00084     Close();
00085 }
00086 
00088 
00089 ScreenSetup::ScreenSetup(MythScreenStack *parent, const QString &name,
00090                          SourceManager *srcman)
00091     : MythScreenType(parent, name),
00092       m_sourceManager(srcman ? srcman : new SourceManager()),
00093       m_createdSrcMan(srcman ? false : true),
00094       m_helpText(NULL),     m_activeList(NULL),
00095       m_inactiveList(NULL), m_finishButton(NULL)
00096 {
00097     m_sourceManager->clearSources();
00098     m_sourceManager->findScripts();
00099 }
00100 
00101 ScreenSetup::~ScreenSetup()
00102 {
00103     if (m_createdSrcMan)
00104     {
00105         if (m_sourceManager)
00106             delete m_sourceManager;
00107     }
00108     else
00109     {
00110         m_sourceManager->clearSources();
00111         m_sourceManager->findScriptsDB();
00112         m_sourceManager->setupSources();
00113     }
00114 
00115     // Deallocate the ScreenListInfo objects created for the inactive screen list.
00116     for (int i=0; i < m_inactiveList->GetCount(); i++)
00117     {
00118         MythUIButtonListItem *item = m_inactiveList->GetItemAt(i);
00119         if (item->GetData().isValid())
00120             delete qVariantValue<ScreenListInfo *>(item->GetData());
00121     }
00122 
00123     // Deallocate the ScreenListInfo objects created for the active screen list.
00124     for (int i=0; i < m_activeList->GetCount(); i++)
00125     {
00126         MythUIButtonListItem *item = m_activeList->GetItemAt(i);
00127         if (item->GetData().isValid())
00128             delete qVariantValue<ScreenListInfo *>(item->GetData());
00129     }
00130 }
00131 
00132 bool ScreenSetup::Create()
00133 {
00134     bool foundtheme = false;
00135 
00136     // Load the theme for this screen
00137     foundtheme = LoadWindowFromXML("weather-ui.xml", "screen-setup", this);
00138 
00139     if (!foundtheme)
00140         return false;
00141 
00142     m_helpText = dynamic_cast<MythUIText *> (GetChild("helptxt"));
00143 
00144     m_activeList = dynamic_cast<MythUIButtonList *> (GetChild("activelist"));
00145     m_inactiveList = dynamic_cast<MythUIButtonList *> (GetChild("inactivelist"));
00146 
00147     m_finishButton = dynamic_cast<MythUIButton *> (GetChild("finishbutton"));
00148 
00149     MythUIText *activeheader = dynamic_cast<MythUIText *> (GetChild("activehdr"));
00150     if (activeheader)
00151         activeheader->SetText(tr("Active Screens"));
00152 
00153     MythUIText *inactiveheader = dynamic_cast<MythUIText *> (GetChild("inactivehdr"));
00154     if (inactiveheader)
00155         inactiveheader->SetText(tr("Inactive Screens"));
00156 
00157     if (!m_activeList || !m_inactiveList || !m_finishButton || !m_helpText)
00158     {
00159         LOG(VB_GENERAL, LOG_ERR, "Theme is missing required elements.");
00160         return false;
00161     }
00162 
00163     BuildFocusList();
00164 
00165     connect(m_activeList, SIGNAL(itemSelected(MythUIButtonListItem *)),
00166             this, SLOT(updateHelpText()));
00167     connect(m_activeList, SIGNAL(itemClicked(MythUIButtonListItem *)),
00168             this, SLOT(doListSelect(MythUIButtonListItem *)));
00169     connect(m_inactiveList, SIGNAL(itemSelected(MythUIButtonListItem *)),
00170             this, SLOT(updateHelpText()));
00171     connect(m_inactiveList, SIGNAL(itemClicked(MythUIButtonListItem *)),
00172             this, SLOT(doListSelect(MythUIButtonListItem *)));
00173 
00174     SetFocusWidget(m_inactiveList);
00175 
00176     m_finishButton->SetText(tr("Finish"));
00177     connect(m_finishButton, SIGNAL(Clicked()), this, SLOT(saveData()));
00178 
00179     loadData();
00180 
00181     return true;
00182 }
00183 
00184 bool ScreenSetup::keyPressEvent(QKeyEvent *event)
00185 {
00186     if (GetFocusWidget() && GetFocusWidget()->keyPressEvent(event))
00187         return true;
00188 
00189     bool handled = false;
00190     QStringList actions;
00191     handled = GetMythMainWindow()->TranslateKeyPress("Weather", event, actions);
00192 
00193     for (int i = 0; i < actions.size() && !handled; i++)
00194     {
00195         QString action = actions[i];
00196         handled = true;
00197 
00198         if (action == "DELETE")
00199         {
00200             if (GetFocusWidget() == m_activeList)
00201                 deleteScreen();
00202         }
00203         else
00204             handled = false;
00205     }
00206 
00207     if (!handled && MythScreenType::keyPressEvent(event))
00208         handled = true;
00209 
00210     return handled;
00211 }
00212 
00213 void ScreenSetup::updateHelpText()
00214 {
00215     MythUIType *list = GetFocusWidget();
00216     QString text;
00217     if (!list)
00218         return;
00219 
00220     if (list == m_inactiveList)
00221     {
00222 
00223         MythUIButtonListItem *item = m_inactiveList->GetItemCurrent();
00224         if (!item)
00225             return;
00226 
00227         ScreenListInfo *si = qVariantValue<ScreenListInfo *>(item->GetData());
00228         if (!si)
00229             return;
00230 
00231         QStringList sources = si->sources;
00232 
00233         text = tr("Add desired screen to the Active Screens list "
00234             "by pressing SELECT.") + "\n";
00235         text += si->title + "\n";
00236         text += QString("%1: %2").arg(tr("Sources"))
00237                                  .arg(sources.join(", "));
00238     }
00239     else if (list == m_activeList)
00240     {
00241         MythUIButtonListItem *item = m_activeList->GetItemCurrent();
00242         if (!item)
00243             return;
00244 
00245         ScreenListInfo *si = qVariantValue<ScreenListInfo *>(item->GetData());
00246         if (!si)
00247             return;
00248 
00249         text += si->title + "\n";
00250         if (si->hasUnits)
00251         {
00252             text += tr("Units: ");
00253             text += (ENG_UNITS == si->units) ?
00254                 tr("English Units") : tr("SI Units");
00255             text += "   ";
00256         }
00257         if (!si->multiLoc && !si->types.empty())
00258         {
00259             TypeListInfo ti = *si->types.begin();
00260             text += tr("Location: ");
00261             text += (ti.location.isEmpty()) ? tr("Not Defined") : ti.location;
00262             text += "\n";
00263             text += tr("Source: " );
00264             text += (ti.src) ? ti.src->name : tr("Not Defined");
00265             text += "\n";
00266         }
00267         text += "\n" + tr("Press SELECT to ");
00268         if (!si->multiLoc)
00269             text += tr("change location; ");
00270         if (si->hasUnits)
00271             text += tr("change units; ");
00272         text += tr("move screen up or down; or remove screen.");
00273     }
00274 
00275     m_helpText->SetText(text);
00276 }
00277 
00278 void ScreenSetup::loadData()
00279 {
00280     ScreenListInfo *si;
00281 
00282     QStringList types;
00283 
00284     ScreenListMap screenListMap = loadScreens();
00285 
00286     // Fill the inactive screen button list.
00287     ScreenListMap::const_iterator i = screenListMap.constBegin();
00288     while (i != screenListMap.constEnd())
00289     {
00290 
00291         si = &screenListMap[i.key()];
00292         types = si->dataTypes;
00293         si->units = ENG_UNITS;
00294 
00295         QStringList type_strs;
00296         for (int typei = 0; typei < types.size(); ++typei)
00297         {
00298             TypeListInfo ti(types[typei]);
00299             si->types.insert(types[typei], ti);
00300             type_strs << types[typei];
00301         }
00302 
00303         QList<ScriptInfo *> scriptList;
00304         // Only add a screen to the list if we have a source
00305         // available to satisfy the requirements.
00306         if (m_sourceManager->findPossibleSources(type_strs, scriptList))
00307         {
00308             ScriptInfo *script;
00309             for (int x = 0; x < scriptList.size(); x++)
00310             {
00311                 script = scriptList.at(x);
00312                 si->sources.append(script->name);
00313             }
00314             MythUIButtonListItem *item =
00315                         new MythUIButtonListItem(m_inactiveList, si->title);
00316             item->SetData(qVariantFromValue(new ScreenListInfo(*si)));
00317         }
00318 
00319         ++i;
00320     }
00321 
00322     QMap<long, ScreenListInfo*> active_screens;
00323 
00324     MSqlQuery db(MSqlQuery::InitCon());
00325     QString query = "SELECT weatherscreens.container, weatherscreens.units, "
00326         "weatherdatalayout.dataitem, weatherdatalayout.location, "
00327         "weathersourcesettings.source_name, weatherscreens.draworder "
00328         "FROM weatherscreens, weatherdatalayout, weathersourcesettings "
00329         "WHERE weatherscreens.hostname = :HOST "
00330         "AND weatherscreens.screen_id = weatherdatalayout.weatherscreens_screen_id "
00331         "AND weathersourcesettings.sourceid = weatherdatalayout.weathersourcesettings_sourceid "
00332         "ORDER BY weatherscreens.draworder;";
00333     db.prepare(query);
00334     db.bindValue(":HOST", gCoreContext->GetHostName());
00335     if (!db.exec())
00336     {
00337         LOG(VB_GENERAL, LOG_ERR, db.lastError().text());
00338         return;
00339     }
00340 
00341     // Fill the active screen button list.
00342     while (db.next())
00343     {
00344         QString name = db.value(0).toString();
00345         units_t units = db.value(1).toUInt();
00346         QString dataitem = db.value(2).toString();
00347         QString location = db.value(3).toString();
00348         QString src = db.value(4).toString();
00349         uint draworder = db.value(5).toUInt();
00350 
00351         types = screenListMap[name].dataTypes;
00352 
00353         TypeListInfo ti(dataitem, location,
00354                         m_sourceManager->getSourceByName(src));
00355 
00356         if (active_screens.find(draworder) == active_screens.end())
00357         {
00358             si = new ScreenListInfo(screenListMap[name]);
00359             // Clear types first as we will re-insert the values from the database
00360             si->types.clear();
00361             si->units = units;
00362             
00363             MythUIButtonListItem *item =
00364                 new MythUIButtonListItem(m_activeList, si->title);
00365             
00366 
00367             // Only insert types meant for this screen
00368             for (QStringList::Iterator type_i = types.begin();
00369                  type_i != types.end(); ++type_i )
00370             {
00371                 if (*type_i == dataitem)
00372                     si->types.insert(dataitem, ti);
00373             }
00374 
00375             item->SetData(qVariantFromValue(si));
00376             active_screens.insert(draworder, si);
00377         }
00378         else
00379         {
00380             si = active_screens[draworder];
00381             for (QStringList::Iterator type_i = types.begin();
00382                  type_i != types.end(); ++type_i )
00383             {
00384                 if (*type_i == dataitem)
00385                 {
00386                     si->types.insert(dataitem, ti);
00387                 }
00388             }
00389         }
00390     }
00391 }
00392 
00393 void ScreenSetup::saveData()
00394 {
00395     if (m_activeList->GetCount() <= 0)
00396     {
00397         LOG(VB_GENERAL, LOG_ERR,
00398             "No Active Screens are defined. Nothing Saved.");
00399         return;
00400     }
00401 
00402     // check if all active screens have sources/locations defined
00403     QStringList notDefined;
00404 
00405     for (int i=0; i < m_activeList->GetCount(); i++)
00406     {
00407         MythUIButtonListItem *item = m_activeList->GetItemAt(i);
00408         ScreenListInfo *si = qVariantValue<ScreenListInfo *>(item->GetData());
00409         TypeListMap::iterator it = si->types.begin();
00410         for (; it != si->types.end(); ++it)
00411         {
00412             if ((*it).src)
00413                 continue;
00414 
00415             notDefined << (*it).name;
00416             LOG(VB_GENERAL, LOG_ERR, QString("Not defined %1").arg((*it).name));
00417         }
00418     }
00419 
00420     if (!notDefined.empty())
00421     {
00422         LOG(VB_GENERAL, LOG_ERR, "A Selected screen has data items with no "
00423                                  "sources defined.");
00424         return;
00425     }
00426 
00427     MSqlQuery db(MSqlQuery::InitCon());
00428     MSqlQuery db2(MSqlQuery::InitCon());
00429     QString query = "DELETE FROM weatherscreens WHERE hostname=:HOST";
00430     db.prepare(query);
00431     db.bindValue(":HOST", gCoreContext->GetHostName());
00432     if (!db.exec())
00433         MythDB::DBError("ScreenSetup::saveData - delete weatherscreens", db);
00434 
00435     query = "INSERT into weatherscreens (draworder, container, units, hostname) "
00436             "VALUES (:DRAW, :CONT, :UNITS, :HOST);";
00437     db.prepare(query);
00438 
00439     int draworder = 0;
00440     for (int i=0; i < m_activeList->GetCount(); i++)
00441     {
00442         MythUIButtonListItem *item = m_activeList->GetItemAt(i);
00443         ScreenListInfo *si = qVariantValue<ScreenListInfo *>(item->GetData());
00444         db.bindValue(":DRAW", draworder);
00445         db.bindValue(":CONT", si->name);
00446         db.bindValue(":UNITS", si->units);
00447         db.bindValue(":HOST", gCoreContext->GetHostName());
00448         if (db.exec())
00449         {
00450             // TODO see comment in dbcheck.cpp for way to improve
00451             QString query2 = "SELECT screen_id FROM weatherscreens "
00452                     "WHERE draworder = :DRAW AND hostname = :HOST;";
00453             db2.prepare(query2);
00454             db2.bindValue(":DRAW", draworder);
00455             db2.bindValue(":HOST", gCoreContext->GetHostName());
00456             if (!db2.exec())
00457             {
00458                 LOG(VB_GENERAL, LOG_ERR, db2.executedQuery());
00459                 LOG(VB_GENERAL, LOG_ERR, db2.lastError().text());
00460                 return;
00461             }
00462 
00463             db2.next();
00464             int screen_id = db2.value(0).toInt();
00465 
00466             query2 = "INSERT INTO weatherdatalayout (location, dataitem, "
00467                     "weatherscreens_screen_id, weathersourcesettings_sourceid) "
00468                     "VALUES (:LOC, :ITEM, :SCREENID, :SRCID);";
00469             db2.prepare(query2);
00470             TypeListMap::iterator it = si->types.begin();
00471             for (; it != si->types.end(); ++it)
00472             {
00473                 db2.bindValue(":LOC",      (*it).location);
00474                 db2.bindValue(":ITEM",     (*it).name);
00475                 db2.bindValue(":SCREENID", screen_id);
00476                 db2.bindValue(":SRCID",    (*it).src->id);
00477                 if (!db2.exec())
00478                 {
00479                     LOG(VB_GENERAL, LOG_ERR, db2.executedQuery());
00480                     LOG(VB_GENERAL, LOG_ERR, db2.lastError().text());
00481                     return;
00482                 }
00483             }
00484         }
00485         else
00486         {
00487             LOG(VB_GENERAL, LOG_ERR, db.executedQuery());
00488             LOG(VB_GENERAL, LOG_ERR, db.lastError().text());
00489             return;
00490         }
00491 
00492         ++draworder;
00493     }
00494 
00495     Close();
00496 }
00497 
00498 void ScreenSetup::doListSelect(MythUIButtonListItem *selected)
00499 {
00500     if (!selected)
00501         return;
00502 
00503     QString txt = selected->GetText();
00504     if (GetFocusWidget() == m_activeList)
00505     {
00506         ScreenListInfo *si = qVariantValue<ScreenListInfo *>(selected->GetData());
00507 
00508         QString label = tr("Manipulate Screen");
00509 
00510         MythScreenStack *popupStack =
00511                                 GetMythMainWindow()->GetStack("popup stack");
00512 
00513         MythDialogBox *menuPopup = new MythDialogBox(label, popupStack,
00514                                                     "screensetupmenupopup");
00515 
00516         if (menuPopup->Create())
00517         {
00518             popupStack->AddScreen(menuPopup);
00519 
00520             menuPopup->SetReturnEvent(this, "options");
00521 
00522             menuPopup->AddButton(tr("Move Up"), qVariantFromValue(selected));
00523             menuPopup->AddButton(tr("Move Down"), qVariantFromValue(selected));
00524             menuPopup->AddButton(tr("Remove"), qVariantFromValue(selected));
00525             menuPopup->AddButton(tr("Change Location"), qVariantFromValue(selected));
00526             if (si->hasUnits)
00527                 menuPopup->AddButton(tr("Change Units"), qVariantFromValue(selected));
00528             menuPopup->AddButton(tr("Cancel"), qVariantFromValue(selected));
00529         }
00530         else
00531         {
00532             delete menuPopup;
00533         }
00534 
00535     }
00536     else if (GetFocusWidget() == m_inactiveList)
00537     {
00538         ScreenListInfo *si = qVariantValue<ScreenListInfo *>(selected->GetData());
00539         QStringList type_strs;
00540 
00541         TypeListMap::iterator it = si->types.begin();
00542         TypeListMap types;
00543         for (; it != si->types.end(); ++it)
00544         {
00545             types.insert(it.key(), TypeListInfo(*it));
00546             type_strs << it.key();
00547         }
00548         bool hasUnits = si->hasUnits;
00549 
00550         QList<ScriptInfo *> tmp;
00551         if (m_sourceManager->findPossibleSources(type_strs, tmp))
00552         {
00553             if (!m_inactiveList->GetCount())
00554             {
00555                 //m_inactiveList->SetActive(false);
00556                 NextPrevWidgetFocus(true);
00557             }
00558             if (hasUnits)
00559                 showUnitsPopup(selected->GetText(), si);
00560             else
00561                 doLocationDialog(si);
00562         }
00563         else
00564             LOG(VB_GENERAL, LOG_ERR, "Screen cannot be used, not all required "
00565                                      "data is supplied by existing sources");
00566     }
00567 }
00568 
00569 void ScreenSetup::doLocationDialog(ScreenListInfo *si)
00570 {
00571     MythScreenStack *mainStack =
00572                             GetMythMainWindow()->GetMainStack();
00573 
00574     LocationDialog *locdialog = new LocationDialog(mainStack, "locationdialog",
00575                                                    this, si, m_sourceManager);
00576 
00577     if (locdialog->Create())
00578         mainStack->AddScreen(locdialog);
00579     else
00580         delete locdialog;
00581 }
00582 
00583 void ScreenSetup::showUnitsPopup(const QString &name, ScreenListInfo *si)
00584 {
00585     if (!si)
00586         return;
00587 
00588     QString label = QString("%1 %2").arg(name).arg(tr("Change Units"));
00589 
00590     MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
00591 
00592     MythDialogBox *menuPopup = new MythDialogBox(label, popupStack,
00593                                                 "weatherunitspopup");
00594 
00595     if (menuPopup->Create())
00596     {
00597         popupStack->AddScreen(menuPopup);
00598 
00599         menuPopup->SetReturnEvent(this, "units");
00600 
00601         menuPopup->AddButton(tr("English Units"), qVariantFromValue(si));
00602         menuPopup->AddButton(tr("SI Units"), qVariantFromValue(si));
00603     }
00604     else
00605     {
00606         delete menuPopup;
00607     }
00608 }
00609 
00610 void ScreenSetup::deleteScreen()
00611 {
00612     MythUIButtonListItem *item = m_activeList->GetItemCurrent();
00613     if (item)
00614     {
00615         if (item->GetData().isValid())
00616             delete qVariantValue<ScreenListInfo *>(item->GetData());
00617 
00618         delete item;
00619     }
00620 
00621     if (!m_activeList->GetCount())
00622     {
00623         NextPrevWidgetFocus(false);
00624         m_activeList->SetEnabled(false);
00625     }
00626 }
00627 
00628 void ScreenSetup::customEvent(QEvent *event)
00629 {
00630     if (event->type() == DialogCompletionEvent::kEventType)
00631     {
00632         DialogCompletionEvent *dce = (DialogCompletionEvent*)(event);
00633 
00634         QString resultid  = dce->GetId();
00635         int     buttonnum = dce->GetResult();
00636 
00637         if (resultid == "options")
00638         {
00639             if (buttonnum > -1)
00640             {
00641                 MythUIButtonListItem *item =
00642                     qVariantValue<MythUIButtonListItem *>(dce->GetData());
00643                         
00644                 ScreenListInfo *si =
00645                     qVariantValue<ScreenListInfo *>(item->GetData());
00646 
00647                 if (buttonnum == 0)
00648                 {
00649                     m_activeList->MoveItemUpDown(item, true);
00650                 }
00651                 else if (buttonnum == 1)
00652                 {
00653                     m_activeList->MoveItemUpDown(item, false);
00654                 }
00655                 else if (buttonnum == 2)
00656                 {
00657                     deleteScreen();
00658                 }
00659                 else if (buttonnum == 3)
00660                 {
00661                     si->updating = true;
00662                     doLocationDialog(si);
00663                 }
00664                 else if (si->hasUnits && buttonnum == 4)
00665                 {
00666                     si->updating = true;
00667                     showUnitsPopup(item->GetText(), si);
00668                     updateHelpText();
00669                 }
00670             }
00671         }
00672         else if (resultid == "units")
00673         {
00674             if (buttonnum > -1)
00675             {
00676                 ScreenListInfo *si =
00677                     qVariantValue<ScreenListInfo *>(dce->GetData());
00678 
00679                 if (buttonnum == 0)
00680                 {
00681                     si->units = ENG_UNITS;
00682                 }
00683                 else if (buttonnum == 1)
00684                 {
00685                     si->units = SI_UNITS;
00686                 }
00687 
00688                 updateHelpText();
00689 
00690                 if (si->updating)
00691                     si->updating = false;
00692                 else
00693                     doLocationDialog(si);
00694             }
00695         }
00696         else if (resultid == "location")
00697         {
00698             ScreenListInfo *si =
00699                 qVariantValue<ScreenListInfo *>(dce->GetData());
00700 
00701             TypeListMap::iterator it = si->types.begin();
00702             for (; it != si->types.end(); ++it)
00703             {
00704                 if ((*it).location.isEmpty())
00705                     return;
00706             }
00707 
00708             if (si->updating)
00709             {
00710                 si->updating = false;
00711                 MythUIButtonListItem *item = m_activeList->GetItemCurrent();
00712                 if (item)
00713                     item->SetData(qVariantFromValue(si));
00714             }
00715             else
00716             {
00717                 QString txt = si->title; txt.detach();
00718                 MythUIButtonListItem *item = 
00719                         new MythUIButtonListItem(m_activeList, txt);
00720                 item->SetData(qVariantFromValue(si));
00721             }
00722 
00723             if (m_activeList->GetCount())
00724                 m_activeList->SetEnabled(true);
00725         }
00726     }
00727 }
00728 
00730 
00731 SourceSetup::SourceSetup(MythScreenStack *parent, const QString &name)
00732     : MythScreenType(parent, name)
00733 {
00734     m_sourceList = NULL;
00735     m_updateSpinbox = m_retrieveSpinbox = NULL;
00736     m_finishButton = NULL;
00737     m_sourceText = NULL;
00738 }
00739 
00740 SourceSetup::~SourceSetup()
00741 {
00742     for (int i=0; i < m_sourceList->GetCount(); i++)
00743     {
00744         MythUIButtonListItem *item = m_sourceList->GetItemAt(i);
00745         if (item->GetData().isValid())
00746             delete qVariantValue<SourceListInfo *>(item->GetData());
00747     }
00748 }
00749 
00750 bool SourceSetup::Create()
00751 {
00752     bool foundtheme = false;
00753 
00754     // Load the theme for this screen
00755     foundtheme = LoadWindowFromXML("weather-ui.xml", "source-setup", this);
00756 
00757     if (!foundtheme)
00758         return false;
00759 
00760     m_sourceList = dynamic_cast<MythUIButtonList *> (GetChild("srclist"));
00761     m_updateSpinbox = dynamic_cast<MythUISpinBox *> (GetChild("update_spinbox"));
00762     m_retrieveSpinbox = dynamic_cast<MythUISpinBox *> (GetChild("retrieve_spinbox"));
00763     m_finishButton = dynamic_cast<MythUIButton *> (GetChild("finishbutton"));
00764     m_sourceText = dynamic_cast<MythUIText *> (GetChild("srcinfo"));
00765 
00766     if (!m_sourceList || !m_updateSpinbox || !m_retrieveSpinbox
00767         || !m_finishButton || !m_sourceText)
00768     {
00769         LOG(VB_GENERAL, LOG_ERR, "Theme is missing required elements.");
00770         return false;
00771     }
00772 
00773     BuildFocusList();
00774     SetFocusWidget(m_sourceList);
00775 
00776     connect(m_sourceList, SIGNAL(itemSelected(MythUIButtonListItem *)),
00777             SLOT(sourceListItemSelected(MythUIButtonListItem *)));
00778 #if 0
00779     connect(m_sourceList, SIGNAL(TakingFocus()),
00780             this, SLOT(sourceListItemSelected()));
00781 #endif
00782 
00783     // 12 Hour max interval
00784     m_updateSpinbox->SetRange(10, 720, 10);
00785     connect(m_updateSpinbox, SIGNAL(LosingFocus()),
00786             SLOT(updateSpinboxUpdate()));
00787 
00788     // 2 Minute retrieval timeout max
00789     m_retrieveSpinbox->SetRange(10, 120, 5);
00790     connect(m_retrieveSpinbox, SIGNAL(LosingFocus()),
00791             SLOT(retrieveSpinboxUpdate()));
00792 
00793     m_finishButton->SetText(tr("Finish"));
00794     connect(m_finishButton, SIGNAL(Clicked()), SLOT(saveData()));
00795 
00796     loadData();
00797 
00798     return true;
00799 }
00800 
00801 bool SourceSetup::loadData()
00802 {
00803     MSqlQuery db(MSqlQuery::InitCon());
00804     QString query =
00805      "SELECT DISTINCT sourceid, source_name, update_timeout, retrieve_timeout, "
00806          "author, email, version FROM weathersourcesettings, weatherdatalayout "
00807          "WHERE weathersourcesettings.sourceid = weatherdatalayout.weathersourcesettings_sourceid "
00808          "AND hostname=:HOST;";
00809     db.prepare(query);
00810     db.bindValue(":HOST", gCoreContext->GetHostName());
00811     if (!db.exec())
00812     {
00813         LOG(VB_GENERAL, LOG_ERR, db.lastError().text());
00814         return false;
00815     }
00816 
00817     if (!db.size())
00818     {
00819         return false;
00820     }
00821 
00822     while (db.next())
00823     {
00824         SourceListInfo *si = new SourceListInfo;
00825         si->id = db.value(0).toUInt();
00826         si->name = db.value(1).toString();
00827         si->update_timeout = db.value(2).toUInt() / 60;
00828         si->retrieve_timeout = db.value(3).toUInt();
00829         si->author = db.value(4).toString();
00830         si->email = db.value(5).toString();
00831         si->version = db.value(6).toString();
00832 
00833         new MythUIButtonListItem(m_sourceList, si->name, qVariantFromValue(si));
00834     }
00835 
00836     return true;
00837 }
00838 
00839 void SourceSetup::saveData()
00840 {
00841     MythUIButtonListItem *curritem = m_sourceList->GetItemCurrent();
00842 
00843     if (curritem)
00844     {
00845         SourceListInfo *si = qVariantValue<SourceListInfo *>(curritem->GetData());
00846         si->update_timeout = m_updateSpinbox->GetIntValue();
00847         si->retrieve_timeout = m_retrieveSpinbox->GetIntValue();
00848     }
00849 
00850     MSqlQuery db(MSqlQuery::InitCon());
00851     QString query = "UPDATE weathersourcesettings "
00852             "SET update_timeout = :UPDATE, retrieve_timeout = :RETRIEVE "
00853             "WHERE sourceid = :ID;";
00854     db.prepare(query);
00855 
00856     for (int i=0; i < m_sourceList->GetCount(); i++)
00857     {
00858         MythUIButtonListItem *item = m_sourceList->GetItemAt(i);
00859         SourceListInfo *si = qVariantValue<SourceListInfo *>(item->GetData());
00860         db.bindValue(":ID", si->id);
00861         db.bindValue(":UPDATE", si->update_timeout * 60);
00862         db.bindValue(":RETRIEVE", si->retrieve_timeout);
00863         if (!db.exec())
00864         {
00865             LOG(VB_GENERAL, LOG_ERR, db.lastError().text());
00866             return;
00867         }
00868     }
00869 
00870     Close();
00871 }
00872 
00873 void SourceSetup::updateSpinboxUpdate()
00874 {
00875     if (m_sourceList->GetItemCurrent())
00876     {
00877         SourceListInfo *si = qVariantValue<SourceListInfo *>
00878                                     (m_sourceList->GetItemCurrent()->GetData());
00879         si->update_timeout = m_updateSpinbox->GetIntValue();
00880     }
00881 }
00882 
00883 void SourceSetup::retrieveSpinboxUpdate()
00884 {
00885     if (m_sourceList->GetItemCurrent())
00886     {
00887         SourceListInfo *si = qVariantValue<SourceListInfo *>
00888                                     (m_sourceList->GetItemCurrent()->GetData());
00889         si->retrieve_timeout = m_retrieveSpinbox->GetIntValue();
00890     }
00891 }
00892 
00893 void SourceSetup::sourceListItemSelected(MythUIButtonListItem *item)
00894 {
00895     if (!item)
00896         item = m_sourceList->GetItemCurrent();
00897 
00898     if (!item)
00899         return;
00900 
00901     SourceListInfo *si = qVariantValue<SourceListInfo *>(item->GetData());
00902     if (!si)
00903         return;
00904 
00905     m_updateSpinbox->SetValue(si->update_timeout);
00906     m_retrieveSpinbox->SetValue(si->retrieve_timeout);
00907     QString txt = tr("Author: ");
00908     txt += si->author;
00909     txt += "\n" + tr("Email: ") + si->email;
00910     txt += "\n" + tr("Version: ") + si->version;
00911     m_sourceText->SetText(txt);
00912 }
00913 
00915 
00916 LocationDialog::LocationDialog(MythScreenStack *parent, const QString &name,
00917                                MythScreenType *retScreen, ScreenListInfo *si,
00918                                SourceManager *srcman)
00919     : MythScreenType(parent, name),
00920       m_screenListInfo(new ScreenListInfo(*si)),   m_sourceManager(srcman),
00921       m_retScreen(retScreen), m_locationList(NULL),
00922       m_locationEdit(NULL),   m_searchButton(NULL),
00923       m_resultsText(NULL),    m_sourceText(NULL)
00924 {
00925     TypeListMap::iterator it = si->types.begin();
00926     for (; it != si->types.end(); ++it)
00927         m_types << (*it).name;
00928     m_types.detach();
00929 }
00930 
00931 LocationDialog::~LocationDialog()
00932 {
00933   if(m_locationList)
00934     clearResults();
00935     
00936   delete m_screenListInfo;
00937 }
00938 
00939 bool LocationDialog::Create()
00940 {
00941     bool foundtheme = false;
00942 
00943     // Load the theme for this screen
00944     foundtheme = LoadWindowFromXML("weather-ui.xml", "setup-location", this);
00945 
00946     if (!foundtheme)
00947         return false;
00948 
00949     m_sourceText = dynamic_cast<MythUIText *> (GetChild("source"));
00950     m_resultsText = dynamic_cast<MythUIText *> (GetChild("numresults"));
00951     m_locationEdit = dynamic_cast<MythUITextEdit *> (GetChild("loc-edit"));
00952     m_locationList = dynamic_cast<MythUIButtonList *> (GetChild("results"));
00953     m_searchButton = dynamic_cast<MythUIButton *> (GetChild("searchbtn"));
00954 
00955 
00956     if (!m_sourceText || !m_resultsText || !m_locationEdit || !m_locationList
00957         || !m_searchButton)
00958     {
00959         LOG(VB_GENERAL, LOG_ERR, "Theme is missing required elements.");
00960         return false;
00961     }
00962 
00963     BuildFocusList();
00964     SetFocusWidget(m_locationEdit);
00965 
00966     connect(m_searchButton, SIGNAL(Clicked()), this, SLOT(doSearch()));
00967     m_searchButton->SetText(tr("Search"));
00968     connect(m_locationList, SIGNAL(itemSelected(MythUIButtonListItem *)),
00969             this, SLOT(itemSelected(MythUIButtonListItem *)));
00970     connect(m_locationList, SIGNAL(itemClicked(MythUIButtonListItem *)),
00971             this, SLOT(itemClicked(MythUIButtonListItem *)));
00972 
00973     return true;
00974 }
00975 
00976 void LocationDialog::doSearch()
00977 {
00978     QString busymessage = tr("Searching...");
00979 
00980     MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
00981 
00982     MythUIBusyDialog *busyPopup = new MythUIBusyDialog(busymessage, popupStack,
00983                                                        "mythweatherbusydialog");
00984 
00985     if (busyPopup->Create())
00986     {
00987         popupStack->AddScreen(busyPopup, false);
00988     }
00989     else
00990     {
00991         delete busyPopup;
00992         busyPopup = NULL;
00993     }
00994        
00995 
00996     QMap<ScriptInfo *, QStringList> result_cache;
00997     int numresults = 0;
00998     clearResults();
00999 
01000     QString searchingresults = tr("Searching... Results: %1");
01001 
01002     m_resultsText->SetText(searchingresults.arg(0));
01003     qApp->processEvents();
01004 
01005     QList<ScriptInfo *> sources;
01006     // if a screen makes it this far, theres at least one source for it
01007     m_sourceManager->findPossibleSources(m_types, sources);
01008     QString search = m_locationEdit->GetText();
01009     ScriptInfo *si;
01010     for (int x = 0; x < sources.size(); x++)
01011     {
01012         si = sources.at(x);
01013         if (!result_cache.contains(si))
01014         {
01015             QStringList results = m_sourceManager->getLocationList(si, search);
01016             result_cache[si] = results;
01017             numresults += results.size();
01018             m_resultsText->SetText(searchingresults.arg(numresults));
01019             qApp->processEvents();
01020         }
01021     }
01022 
01023     for (int i = 0; i < result_cache.keys().size(); ++i)
01024     {
01025         si = result_cache.keys()[i];
01026         QStringList results = result_cache[si];
01027         QString name = si->name;
01028         for (int ii = 0; ii < results.size(); ++ii)
01029         {
01030             QStringList tmp = results[ii].split("::");
01031             QString resultstring = QString("%1 (%2)").arg(tmp[1]).arg(name);
01032             MythUIButtonListItem *item =
01033                 new MythUIButtonListItem(m_locationList, resultstring);
01034             ResultListInfo *ri = new ResultListInfo;
01035             ri->idstr = tmp[0];
01036             ri->src = si;
01037             item->SetData(qVariantFromValue(ri));
01038             qApp->processEvents();
01039         }
01040     }
01041 
01042     if (busyPopup)
01043     {
01044         busyPopup->Close();
01045         busyPopup = NULL;
01046     }
01047 
01048     m_resultsText->SetText(tr("Search Complete. Results: %1").arg(numresults));
01049     if (numresults)
01050         SetFocusWidget(m_locationList);
01051 }
01052 
01053 void LocationDialog::clearResults()
01054 {
01055     for (int i=0; i < m_locationList->GetCount(); i++)
01056     {
01057         MythUIButtonListItem *item = m_locationList->GetItemAt(i);
01058         if (item->GetData().isValid())
01059             delete qVariantValue<ResultListInfo *>(item->GetData());
01060     }
01061     
01062     m_locationList->Reset();
01063 }
01064 
01065 void LocationDialog::itemSelected(MythUIButtonListItem *item)
01066 {
01067     ResultListInfo *ri = qVariantValue<ResultListInfo *>(item->GetData());
01068     if (ri)
01069         m_sourceText->SetText(tr("Source: %1").arg(ri->src->name));
01070 }
01071 
01072 void LocationDialog::itemClicked(MythUIButtonListItem *item)
01073 {
01074     ResultListInfo *ri = qVariantValue<ResultListInfo *>(item->GetData());
01075 
01076     if (ri)
01077     {
01078         TypeListMap::iterator it = m_screenListInfo->types.begin();
01079         for (; it != m_screenListInfo->types.end(); ++it)
01080         {
01081             (*it).location = ri->idstr;
01082             (*it).location.detach();
01083             (*it).src      = ri->src;
01084         }
01085     }
01086 
01087     DialogCompletionEvent *dce =
01088         new DialogCompletionEvent("location", 0, "",
01089                                   qVariantFromValue(new ScreenListInfo(*m_screenListInfo)));
01090     QApplication::postEvent(m_retScreen, dce);
01091 
01092     Close();
01093 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends