00001 #include <vector>
00002
00003 #include <mythtv/mythcontext.h>
00004
00005 #include "weather.h"
00006 #include "weatherScreen.h"
00007 #include "defs.h"
00008
00009 WeatherScreen *WeatherScreen::loadScreen(Weather *parent, LayerSet *container,
00010 int id)
00011 {
00012 QString key = container->GetName();
00013 if (key == "Current Conditions")
00014 return new CurrCondScreen(parent, container, id);
00015 if (key == "Three Day Forecast")
00016 return new ThreeDayForecastScreen(parent, container, id);
00017 if (key == "Six Day Forecast")
00018 return new SixDayForecastScreen(parent, container, id);
00019 if (key == "Severe Weather Alerts")
00020 return new SevereWeatherScreen(parent, container, id);
00021 if (key == "Static Map")
00022 return new StaticImageScreen(parent, container, id);
00023 if (key == "Animated Map")
00024 return new AnimatedImageScreen(parent, container, id);
00025
00026 return new WeatherScreen(parent, container, id);
00027 }
00028
00029 QStringList WeatherScreen::getAllDynamicTypes(LayerSet *container)
00030 {
00031 vector<UIType *> *types = container->getAllTypes();
00032 vector<UIType *>::iterator i = types->begin();
00033 QStringList typesList;
00034 for (; i < types->end(); ++i)
00035 {
00036 UIType *t = *i;
00037 if (t->getName().startsWith("+"))
00038 typesList << t->getName().remove(0, 1);
00039 }
00040 return typesList;
00041 }
00042
00043 WeatherScreen::WeatherScreen(Weather *parent, LayerSet *container, int id)
00044 {
00045 m_container = container;
00046 m_parent = parent;
00047 m_id = id;
00048 m_prepared = false;
00049
00050 m_inuse = false;
00051 vector<UIType *> *types = m_container->getAllTypes();
00052 vector<UIType *>::iterator i = types->begin();
00053 for (; i < types->end(); ++i)
00054 {
00055 UIType *t = (UIType *) *i;
00056 if (t->getName().startsWith("*") || t->getName().startsWith("+"))
00057 addDataItem(t->getName().remove(0, 1),
00058 t->getName().startsWith("+"));
00059 }
00060 }
00061
00062 WeatherScreen::~WeatherScreen()
00063 {
00064 disconnect();
00065 }
00066
00067 bool WeatherScreen::canShowScreen()
00068 {
00069 if (!inUse())
00070 return false;
00071
00072 for (uint i = 0; i < map.size(); ++i)
00073 {
00074 if (map[map.keys()[i]] == "NEEDED")
00075 {
00076 VERBOSE(VB_GENERAL, map.keys()[i]);
00077 }
00078 }
00079
00080 return !map.values().contains("NEEDED");
00081 }
00082
00083 void WeatherScreen::setValue(const QString &key, const QString &value)
00084 {
00085 if (map.contains(key))
00086 map[key] = prepareDataItem(key, value);
00087 }
00088
00089 void WeatherScreen::newData(QString loc, units_t units, DataMap data)
00090 {
00091 (void) loc;
00092 (void) units;
00093
00094 DataMap::iterator itr = data.begin();
00095 while (itr != data.end())
00096 {
00097 setValue(itr.key(), itr.data());
00098 ++itr;
00099 }
00100
00101 if (canShowScreen())
00102 {
00103 emit screenReady(this);
00104 }
00105 }
00106
00107 void WeatherScreen::prepareScreen()
00108 {
00109 QMap<QString, QString>::iterator itr = map.begin();
00110 while (itr != map.end())
00111 {
00112 UIType *widget = getType(itr.key());
00113 if (!widget)
00114 {
00115 VERBOSE(VB_IMPORTANT, "Widget not found " + itr.key());
00116 ++itr;
00117 continue;
00118 }
00119
00120 if (dynamic_cast<UITextType *>(widget))
00121 ((UITextType *) widget)->SetText(itr.data());
00122 else if (dynamic_cast<UIImageType *>(widget))
00123 {
00124 ((UIImageType *) widget)->SetImage(itr.data());
00125 }
00126 else if (dynamic_cast<UIAnimatedImageType *>(widget))
00127 {
00128 ((UIAnimatedImageType *) widget)->SetWindow((MythDialog *) m_parent);
00129 ((UIAnimatedImageType *) widget)->Pause();
00130 ((UIAnimatedImageType *) widget)->SetFilename(itr.data());
00131 }
00132 else if (dynamic_cast<UIRichTextType *>(widget))
00133 {
00134 ((UIRichTextType *) widget)->SetText(itr.data());
00135 }
00136
00137 prepareWidget(widget);
00138 ++itr;
00139 }
00140
00141 m_prepared = true;
00142 }
00143
00144 void WeatherScreen::prepareWidget(UIType *widget)
00145 {
00146 UIImageType *img;
00147 UIAnimatedImageType *aimg;
00148
00149
00150
00151
00152 if ((img = dynamic_cast<UIImageType *>(widget)))
00153 {
00154 img->LoadImage();
00155 }
00156 else if ((aimg = dynamic_cast<UIAnimatedImageType *>(widget)))
00157 {
00158 aimg->LoadImages();
00159 }
00160 }
00161
00162 QString WeatherScreen::prepareDataItem(const QString &key, const QString &value)
00163 {
00164 (void) key;
00165 return value;
00166 }
00167
00168 void WeatherScreen::addDataItem(const QString &item, bool required)
00169 {
00170 if (!map.contains(item))
00171 map[item] = required ? "NEEDED" : "";
00172 }
00173
00174 void WeatherScreen::draw(QPainter *p)
00175 {
00176 if (m_container)
00177 {
00178 QRect area = m_container->GetAreaRect();
00179 if (area.isNull())
00180 {
00181 VERBOSE(VB_IMPORTANT, QString("Container %1 has NULL area, "
00182 "bad theme.")
00183 .arg(m_container->GetName()));
00184 area.setWidth(800);
00185 area.setHeight(600);
00186 }
00187 QPixmap pix(area.size());
00188 pix.fill(m_parent, area.topLeft());
00189 QPainter tmp(&pix);
00190 for (int i = 0; i < 9; ++i)
00191 m_container->Draw(&tmp, i, 0);
00192 tmp.end();
00193 p->drawPixmap(area.topLeft(), pix);
00194 }
00195 else
00196 {
00197 VERBOSE(VB_IMPORTANT, "NULL container in WeatherScreen");
00198 }
00199 }
00200
00201 void WeatherScreen::hiding()
00202 {
00203 pause_animation();
00204 }
00205
00206 void WeatherScreen::showing()
00207 {
00208 if (!m_prepared)
00209 prepareScreen();
00210 unpause_animation();
00211 }
00212
00213 void WeatherScreen::toggle_pause(bool paused)
00214 {
00215 UITextType *txt = (UITextType *) getType("pause_text");
00216 if (txt)
00217 {
00218 QString pausetext = QString("- %1 -").arg(tr("PAUSED"));
00219 if (paused)
00220 txt->SetText(pausetext);
00221 else
00222 txt->SetText("");
00223 }
00224 }
00225
00226 void WeatherScreen::pause_animation()
00227 {
00228 vector<UIType *> *types = m_container->getAllTypes();
00229 for (vector<UIType *>::iterator i = types->begin(); i < types->end(); ++i)
00230 {
00231 UIAnimatedImageType *t = dynamic_cast<UIAnimatedImageType *>(*i);
00232 if (t) t->Pause();
00233 }
00234 }
00235
00236 void WeatherScreen::unpause_animation()
00237 {
00238 vector<UIType *> *types = m_container->getAllTypes();
00239 for (vector<UIType *>::iterator i = types->begin(); i < types->end(); ++i)
00240 {
00241 UIAnimatedImageType *t = dynamic_cast<UIAnimatedImageType *>(*i);
00242 if (t)
00243 {
00244 t->GotoFirstImage();
00245 t->UnPause();
00246 }
00247 }
00248 }
00249
00250 UIType *WeatherScreen::getType(const QString &key)
00251 {
00252 if (!m_container)
00253 return NULL;
00254
00255 UIType *t = m_container->GetType(key);
00256 if (t)
00257 return t;
00258
00259 t = m_container->GetType("*" + key);
00260 if (t)
00261 return t;
00262
00263 t = m_container->GetType("+" + key);
00264 if (t)
00265 return t;
00266
00267 return NULL;
00268 }
00269
00270 void WeatherScreen::clock_tick()
00271 {
00272 QDateTime new_time(QDateTime::currentDateTime());
00273 QString curDate;
00274 if (QString(gContext->GetSetting("Language")) == "JA")
00275 curDate = new_time.toString("M/d (ddd) h:mm ap");
00276 else
00277 curDate = new_time.toString("MMM d h:mm ap");
00278
00279 curDate = new_time.date().toString(Qt::LocalDate);
00280 curDate += new_time.time().toString(" h:mm ap");
00281 setValue("currentdatetime", curDate);
00282 }
00283
00284 CurrCondScreen::CurrCondScreen(Weather *parent, LayerSet *container, int id)
00285 : WeatherScreen(parent, container, id)
00286 {
00287 }
00288
00289 QString CurrCondScreen::prepareDataItem(const QString &key,
00290 const QString &value)
00291 {
00292 if (key == "relative_humidity")
00293 return value + " %";
00294
00295 if (key == "pressure")
00296 return value + (m_units == ENG_UNITS ? " in" : " mb");
00297
00298 if (key == "visibility")
00299 return value + (m_units == ENG_UNITS ? " mi" : " km");
00300
00301 if (key == "appt")
00302 return value == "NA" ? value : value + (m_units == ENG_UNITS ? "°F" : "°C");
00303
00304 if (key == "temp")
00305 {
00306 if ( (value == "NA") || (value == "N/A") )
00307 return value;
00308 else
00309 return value + (m_units == ENG_UNITS ? "°F" : "°C");
00310 }
00311
00312 if (key == "wind_gust" || key == "wind_spdgst" || key == "wind_speed")
00313 return value + (m_units == ENG_UNITS ? " mph" : " kph");
00314
00315 return value;
00316 }
00317
00318 ThreeDayForecastScreen::ThreeDayForecastScreen(Weather *parent,
00319 LayerSet *container, int id) :
00320 WeatherScreen(parent, container, id)
00321 {
00322 }
00323
00324 QString ThreeDayForecastScreen::prepareDataItem(const QString &key,
00325 const QString &value)
00326 {
00327 if (key.contains("low",FALSE) || key.contains("high",FALSE) )
00328 {
00329 if ( (value == "NA") || (value == "N/A") )
00330 return value;
00331 else
00332 return value + (m_units == ENG_UNITS ? "°F" : "°C");
00333 }
00334
00335 return value;
00336 }
00337
00338 SixDayForecastScreen::SixDayForecastScreen(Weather *parent,
00339 LayerSet *container, int id) :
00340 WeatherScreen(parent, container, id)
00341 {
00342 }
00343
00344 QString SixDayForecastScreen::prepareDataItem(const QString &key,
00345 const QString &value)
00346 {
00347 if (key.contains("low",FALSE) || key.contains("high",FALSE) )
00348 {
00349 if ( (value == "NA") || (value == "N/A") )
00350 return value;
00351 else
00352 return value + (m_units == ENG_UNITS ? "°F" : "°C");
00353 }
00354
00355 return value;
00356 }
00357
00358 SevereWeatherScreen::SevereWeatherScreen(Weather *parent, LayerSet *container,
00359 int id) :
00360 WeatherScreen(parent, container, id)
00361 {
00362 m_text = (UIRichTextType *) getType("alerts");
00363 m_text->SetBackground(parent->getBackground());
00364 }
00365
00366 bool SevereWeatherScreen::handleKey(QKeyEvent *e)
00367 {
00368 bool handled = false;
00369 QStringList actions;
00370 gContext->GetMainWindow()->TranslateKeyPress("Weather", e, actions);
00371
00372 for (uint i = 0; i < actions.size() && !handled; ++i)
00373 {
00374 QString action = actions[i];
00375 handled = true;
00376
00377 if (action == "UP")
00378 m_text->ScrollUp();
00379 else if (action == "DOWN")
00380 m_text->ScrollDown();
00381 else if (action == "PAGEUP")
00382 m_text->ScrollPageUp();
00383 else if (action == "PAGEDOWN")
00384 m_text->ScrollPageDown();
00385 else handled = false;
00386 }
00387 m_parent->update();
00388
00389 return handled;
00390 }
00391
00392 StaticImageScreen::StaticImageScreen(Weather *parent, LayerSet *container,
00393 int id) :
00394 WeatherScreen(parent, container, id)
00395 {
00396 }
00397
00398 QString StaticImageScreen::prepareDataItem(const QString &key,
00399 const QString &value)
00400 {
00401 QString ret = value;
00402 if (key == "map")
00403 {
00404
00405
00406
00407
00408
00409 bool hasdim = (value.findRev('-') > value.findRev('/'));
00410 if (hasdim)
00411 {
00412 QStringList dim = QStringList::split('x',
00413 value.right(value.length() - value.findRev('-') - 1));
00414 ret = value.left(value.findRev('-'));
00415 imgsize.setWidth(dim[0].toInt());
00416 imgsize.setHeight(dim[1].toInt());
00417 }
00418 }
00419
00420 return ret;
00421 }
00422
00423 void StaticImageScreen::prepareWidget(UIType *widget)
00424 {
00425 if (widget->Name() == "+map")
00426 {
00427
00428
00429
00430 UIImageType *img = (UIImageType *) widget;
00431 QSize max = img->GetSize();
00432
00433 if (imgsize.width() > -1 && imgsize.height() > -1)
00434 {
00435 if (max.width() > -1 && max.height() > -1)
00436 {
00437 imgsize.scale(max, QSize::ScaleMin);
00438
00439 QPoint orgPos = img->DisplayPos();
00440
00441 int newx = orgPos.x() + (max.width() - imgsize.width()) / 2;
00442 int newy = orgPos.y() + (max.height() - imgsize.height()) / 2;
00443 img->SetPosition(QPoint(newx, newy));
00444 }
00445 img->SetSize(imgsize.width(), imgsize.height());
00446 }
00447 img->LoadImage();
00448 }
00449 }
00450
00451 AnimatedImageScreen::AnimatedImageScreen(Weather *parent, LayerSet *container,
00452 int id) :
00453 WeatherScreen(parent, container, id)
00454 {
00455 }
00456
00457 QString AnimatedImageScreen::prepareDataItem(const QString &key,
00458 const QString &value)
00459 {
00460 QString ret = value;
00461 if (key == "animatedimage")
00462 {
00463
00464
00465
00466
00467
00468
00469 bool hasdim = value.find(QRegExp("-[0-9]{1,}x[0-9]{1,}$"));
00470 if (hasdim)
00471 {
00472 QStringList dim = QStringList::split('x',
00473 value.right(value.length() - value.findRev('-') - 1));
00474 ret = value.left(value.findRev('-'));
00475 imgsize.setWidth(dim[0].toInt());
00476 imgsize.setHeight(dim[1].toInt());
00477 }
00478
00479 QString cnt = ret.right(ret.length() - ret.findRev('-') - 1);
00480 m_count = cnt.toInt();
00481 ret = ret.left(ret.findRev('-'));
00482 }
00483
00484 return ret;
00485 }
00486
00487 void AnimatedImageScreen::prepareWidget(UIType *widget)
00488 {
00489 if (widget->Name() == "+animatedimage")
00490 {
00491
00492
00493
00494 UIAnimatedImageType *img = (UIAnimatedImageType *) widget;
00495 QSize max = img->GetSize();
00496
00497 if (imgsize.width() > -1 && imgsize.height() > -1)
00498 {
00499 if (max.width() > -1 && max.height() > -1)
00500 {
00501 imgsize.scale(max, QSize::ScaleMin);
00502
00503 QPoint orgPos = img->DisplayPos();
00504
00505 int newx = orgPos.x() + (max.width() - imgsize.width()) / 2;
00506 int newy = orgPos.y() + (max.height() - imgsize.height()) / 2;
00507 img->SetPosition(QPoint(newx, newy));
00508 }
00509 img->SetSize(imgsize.width(), imgsize.height());
00510 }
00511
00512 img->SetImageCount(m_count);
00513
00514 img->LoadImages();
00515 }
00516 return;
00517 }