#include "addcitytool.h" #include "settings.h" #include "forecastprovider.h" #include "painttextitem.h" #include "pixmaploader.h" #include #include #include #include #include #include #include #define ADD_BACKGROUND (PixmapLoader::getPic("background_add_city")) #define ADD_ERROR_BACKGROUND (PixmapLoader::getPic("background_error_adding")) #define CLOSE_BUTTON_PIXMAP (PixmapLoader::getPic("button_list_delete")) #define ADD_BUTTON_PIXMAP (PixmapLoader::getPic("button_city_send")) #define BUTTON_LEFT (Settings::scaleWidth(408.0)) #define ADD_TEXT_BACKGROUND (PixmapLoader::getPic("textfield_add_city")) #define ADD_TEXT_LEFT (Settings::scaleWidth(38.0)) #define ADD_SCREEN_FONT_SIZE (Settings::scaleHeight(40.0)) #define CITY_NAME_FONT_SIZE (Settings::scaleHeight(40.0)) static inline qreal getCenterVerticalPos(QGraphicsItem *parent, QGraphicsItem *item) { const qreal top = (parent->boundingRect().height() - item->boundingRect().height()) / 2; return top - parent->boundingRect().top() - item->boundingRect().top(); } static inline qreal getCenterVerticalPos(QGraphicsItem *item) { return getCenterVerticalPos(item->parentItem(), item); } // AddCityScreen AddCityScreen::AddCityScreen(const QRectF &boundingRect, QGraphicsItem *parent) : QGraphicsItem(parent) , m_boundingRect(boundingRect) { } QRectF AddCityScreen::boundingRect () const { return m_boundingRect; } void AddCityScreen::paint(QPainter *painter, const QStyleOptionGraphicsItem *opt, QWidget *widget) { Q_UNUSED(painter); Q_UNUSED(opt); Q_UNUSED(widget); } // #define ADD_A_CITY_TEXT "Add a city" AddCityLineEdit::AddCityLineEdit(QWidget *parent) : QLineEdit(parent) , m_clean(true) { editReset(); connect(this, SIGNAL(textEdited(QString)), this, SLOT(textEditedSlot(QString))); } void AddCityLineEdit::editReset() { m_clean = true; setText(ADD_A_CITY_TEXT); } void AddCityLineEdit::focusOutEvent(QFocusEvent *event) { if (m_clean) setText(ADD_A_CITY_TEXT); QLineEdit::focusOutEvent(event); } void AddCityLineEdit::focusInEvent(QFocusEvent *event) { if (m_clean) setText(""); QLineEdit::focusInEvent(event); } void AddCityLineEdit::textEditedSlot(const QString & text) { Q_UNUSED(text); static const QString cleanText(ADD_A_CITY_TEXT); if (m_clean && text.length() >= cleanText.length() && text.left(cleanText.length()) == cleanText) setText(text.right(text.length() - cleanText.length())); m_clean = false; } // AddCityFirstScreen AddCityFirstScreen::AddCityFirstScreen(const QRectF &boundingRect, QGraphicsItem *parent) : AddCityScreen(boundingRect, parent) , m_textBackground(new QGraphicsPixmapItem(ADD_TEXT_BACKGROUND, this)) , m_button(new PixmapButton(80.0, ADD_BUTTON_PIXMAP, this)) , m_proxy(new QGraphicsProxyWidget(this)) , m_lineEdit(new AddCityLineEdit()) { setFlag(ItemHasNoContents, true); m_button->setPos(BUTTON_LEFT, getCenterVerticalPos(m_button)); m_textBackground->setPos(ADD_TEXT_LEFT, getCenterVerticalPos(m_textBackground)); QFont font; font.setFamily("Nokia Sans"); font.setPixelSize(CITY_NAME_FONT_SIZE); font.setStyleStrategy(QFont::PreferAntialias); m_lineEdit->setFont(font); m_lineEdit->setFrame(false); m_lineEdit->setTextMargins(0, 0, 0, 0); m_lineEdit->setAttribute(Qt::WA_NoSystemBackground); m_lineEdit->setStyleSheet("background: transparent; color:white"); QRect rect(0, 0, m_textBackground->pixmap().width(), m_textBackground->pixmap().height()); rect.adjust(5, 5, -5, -5); m_lineEdit->setGeometry(rect); m_proxy->setWidget(m_lineEdit); m_proxy->setParentItem(m_textBackground); m_proxy->setPos(5.0, 5.0); m_lineEdit->setFocus(); connect(m_button, SIGNAL(clicked()), this, SLOT(buttonClick())); } void AddCityFirstScreen::clean() { m_lineEdit->editReset(); } void AddCityFirstScreen::buttonClick() { if (!m_lineEdit->text().isEmpty()) emit citySelected(m_lineEdit->text()); } // AddCitySearchScreen AddCitySearchScreen::AddCitySearchScreen(const QRectF &boundingRect, QGraphicsItem *parent) : AddCityScreen(boundingRect, parent) , m_loading(new Loading(this)) { m_loading->hide(); m_loading->setPos(BUTTON_LEFT, getCenterVerticalPos(m_loading)); } void AddCitySearchScreen::forecastResponse(int reqId, const ForecastData &forecast) { if (reqId == m_reqId) { reset(); if (!forecast.isNull() && !forecast.error()) emit forecastReceived(forecast); else emit forecastRequestError(m_city); } } void AddCitySearchScreen::setCityName(const QString &name) { m_city = name; ForecastProvider::connectToResponseSignal(this, SLOT(forecastResponse(int, ForecastData))); m_reqId = ForecastProvider::getForecast(m_city, false); m_loading->start(); m_loading->show(); update(); } void AddCitySearchScreen::reset() { ForecastProvider::disconnectReceiver(this); m_loading->stop(); m_loading->hide(); } void AddCitySearchScreen::paint(QPainter *painter, const QStyleOptionGraphicsItem *opt, QWidget *widget) { Q_UNUSED(opt); Q_UNUSED(widget); TextPainter header(ADD_SCREEN_FONT_SIZE, QColor(255, 255, 255, 102), "Searching for"); TextPainter city(ADD_SCREEN_FONT_SIZE, QColor(255, 255, 255, 255), m_city); city.setQuoted(true); city.font().setBold(true); city.setMaxWidth(BUTTON_LEFT); qreal top = (boundingRect().height() - header.height() - city.height()) / 2; top += boundingRect().top(); TextPainter::locateAtCenter(&header, 0.0, top, BUTTON_LEFT); header.paint(painter); TextPainter::locateAtCenter(&city, 0.0, top + header.height(), BUTTON_LEFT); city.paint(painter); } // AddCityErrorScreen AddCityErrorScreen::AddCityErrorScreen(QGraphicsItem *parent) : QGraphicsPixmapItem(ADD_ERROR_BACKGROUND, parent) , m_button(new PixmapButton(80.0, CLOSE_BUTTON_PIXMAP, this)) { m_button->setPos(BUTTON_LEFT, getCenterVerticalPos(m_button)); connect(m_button, SIGNAL(clicked()), this, SIGNAL(closed())); } void AddCityErrorScreen::setCityName(const QString &name, ErrorType type) { m_city = name; m_type = type; update(); } void AddCityErrorScreen::paint(QPainter *painter, const QStyleOptionGraphicsItem *opt, QWidget *widget) { Q_UNUSED(opt); Q_UNUSED(widget); QGraphicsPixmapItem::paint(painter, opt, widget); if (m_type == NotFound) paintNotFound(painter); else paintAlreadyInList(painter); } void AddCityErrorScreen::paintNotFound(QPainter *painter) { TextPainter header(ADD_SCREEN_FONT_SIZE, QColor(255, 255, 255, 102), "The city"); TextPainter footer(ADD_SCREEN_FONT_SIZE, QColor(255, 255, 255, 102), "wasn't found"); TextPainter city(ADD_SCREEN_FONT_SIZE, QColor(255, 255, 255, 255), m_city); city.setQuoted(true); city.font().setBold(true); city.setMaxWidth(BUTTON_LEFT - header.width() - 5.0); qreal top = (boundingRect().height() - city.height() - footer.height()) / 2; top += boundingRect().top(); QList topLine; topLine.append(&header); topLine.append(&city); TextPainter::locateAtCenter(topLine, 0.0, top, BUTTON_LEFT); header.paint(painter); city.paint(painter); TextPainter::locateAtCenter(&footer, 0.0, top + city.height(), BUTTON_LEFT); footer.paint(painter); } void AddCityErrorScreen::paintAlreadyInList(QPainter *painter) { TextPainter header(ADD_SCREEN_FONT_SIZE, QColor(255, 255, 255, 102), "The city"); TextPainter header1(ADD_SCREEN_FONT_SIZE, QColor(255, 255, 255, 102), "is"); TextPainter footer(ADD_SCREEN_FONT_SIZE, QColor(255, 255, 255, 102), "already on your list"); TextPainter city(ADD_SCREEN_FONT_SIZE, QColor(255, 255, 255, 255), m_city); city.setQuoted(true); city.font().setBold(true); city.setMaxWidth(BUTTON_LEFT - header.width() - header1.width() - 10.0); qreal top = (boundingRect().height() - city.height() - footer.height()) / 2; top += boundingRect().top(); QList topLine; topLine.append(&header); topLine.append(&city); topLine.append(&header1); TextPainter::locateAtCenter(topLine, 0.0, top, BUTTON_LEFT); header.paint(painter); city.paint(painter); header1.paint(painter); TextPainter::locateAtCenter(&footer, 0.0, top + city.height(), BUTTON_LEFT); footer.paint(painter); } // AddCityTool AddCityTool::AddCityTool(const QList &content, QGraphicsItem *parent) : QGraphicsPixmapItem(ADD_BACKGROUND, parent) , m_content(content) , m_firstScreen(createFirstScreen()) , m_SearchScreen(createSearchScreen()) , m_ErrorScreen(createErrorScreen()) { setCurrentScreen(m_firstScreen); } AddCityTool::~AddCityTool() { } int AddCityTool::loadImages() { PixmapLoader::load("background_add_city"); PixmapLoader::load("background_error_adding"); PixmapLoader::load("button_list_delete"); PixmapLoader::load("button_city_send"); PixmapLoader::load("textfield_add_city"); return 5; } void AddCityTool::mousePressEvent(QGraphicsSceneMouseEvent *event) { Q_UNUSED(event); } void AddCityTool::cancel() { m_SearchScreen->cancel(); setCurrentScreen(m_firstScreen); } AddCityFirstScreen *AddCityTool::createFirstScreen() { AddCityFirstScreen *result = new AddCityFirstScreen(boundingRect(), this); connect(result, SIGNAL(citySelected(QString)), this, SLOT(citySelected(QString))); result->setPos(0.0, 0.0); return result; } AddCitySearchScreen *AddCityTool::createSearchScreen() { AddCitySearchScreen *result = new AddCitySearchScreen(boundingRect(), this); connect(result, SIGNAL(forecastReceived(ForecastData)), this, SLOT(forecastReceived(ForecastData))); connect(result, SIGNAL(forecastRequestError(QString)), this, SLOT(forecastRequestError(QString))); result->setPos(0.0, 0.0); return result; } AddCityErrorScreen *AddCityTool::createErrorScreen() { AddCityErrorScreen *result = new AddCityErrorScreen(this); connect(result, SIGNAL(closed()), this, SLOT(errorScreenClosed())); result->setPos(0.0, 0.0); return result; } void AddCityTool::setCurrentScreen(QGraphicsItem *screen) { m_firstScreen->clean(); m_firstScreen->setVisible(screen == m_firstScreen); m_SearchScreen->setVisible(screen == m_SearchScreen); m_ErrorScreen->setVisible(screen == m_ErrorScreen); } void AddCityTool::errorScreenClosed() { setCurrentScreen(m_firstScreen); } void AddCityTool::forecastReceived(const ForecastData &forecast) { for (int i = 0; i < m_content.count(); ++i) if (m_content[i].key() == forecast.key()) { m_ErrorScreen->setCityName(forecast.cityName(), AddCityErrorScreen::AlreadyInList); setCurrentScreen(m_ErrorScreen); return; } emit newForecast(forecast); setCurrentScreen(m_firstScreen); } void AddCityTool::forecastRequestError(const QString &name) { m_ErrorScreen->setCityName(name, AddCityErrorScreen::NotFound); setCurrentScreen(m_ErrorScreen); } void AddCityTool::citySelected(const QString &city) { QString text = city.toUpper(); for (int i = 0; i < m_content.count(); ++i) if (m_content[i].key().toUpper() == text) { m_ErrorScreen->setCityName(city, AddCityErrorScreen::AlreadyInList); setCurrentScreen(m_ErrorScreen); return; } m_SearchScreen->setCityName(city); setCurrentScreen(m_SearchScreen); }