#include "CharacterListWindow.hpp" #include "ui_CharacterListWindow.h" #include #include #if defined(Q_WS_MAEMO_5) #include #include #include #include QDBusMessage *dbusMessage; QList notificationHints; #endif CharacterListWindow::CharacterListWindow(QWidget *parent) : QMainWindow(parent), EveManager(new QList(AppSettingsManager::characters()), new QList(AppSettingsManager::skillData()), false), ui(new Ui::CharacterListWindow), _listWidgetInitialized(false) { // Set up the UI setFocusPolicy(Qt::StrongFocus); ui->setupUi(this); ui->actionRemove_character->setEnabled(false); this->setFocus(); // Loading skills from resource if the setting is empty if (skills->count() == 0) { QFile file(":/SkillTree.xml"); QDomDocument document; file.open(QIODevice::ReadOnly); document.setContent(file.readAll()); skills = new QList(EveConnector::interpretSkillData(document)); AppSettingsManager::setSkillData(*skills); } // Set up the EVE API connector connector = new EveConnector(skills, characters, this); connect(connector, SIGNAL(accountReceived(QList*)), this, SLOT(accountReceived(QList*))); connect(connector, SIGNAL(characterReceived(EveCharacter*)), this, SLOT(characterReceived(EveCharacter*))); connect(connector, SIGNAL(skillQueueReceived(int, QList*)), this, SLOT(skillQueueReceived(int, QList*))); connect(connector, SIGNAL(portraitReceived(int, QPixmap*)), this, SLOT(portraitReceived(int, QPixmap*))); // Set up the dialogs waitDialog = new QeUncloseableMessageBox("Please wait", "Retrieving information...", QMessageBox::Information, this); settingsDialog = new SettingsDialog(this, connector, waitDialog); connect(settingsDialog, SIGNAL(accepted()), this, SLOT(settingsSaved())); characterCreationDialog = new CharacterCreationDialog(characters, this); connect(characterCreationDialog, SIGNAL(accepted()), this, SLOT(characterDataInput())); characterWindow = NULL; // Set up the EVE refresher refresher = new EveRefresher(AppSettingsManager::lastRefresh(), AppSettingsManager::refreshRate(), characters, skills); connect(refresher, SIGNAL(charactersAndQueuesRefreshed(bool)), this, SLOT(charactersAndQueuesRefreshed(bool))); connect(refresher, SIGNAL(portraitsRefreshed(bool)), this, SLOT(portraitsRefreshed(bool))); // Set up the timer timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(refreshUI())); // Maemo 5 specific tweaks #if defined(Q_WS_MAEMO_5) setAttribute(Qt::WA_Maemo5StackedWindow); // Setting this window as stacked window QDBusConnection::sessionBus().registerService(APP_DBUS_SERVICE); QDBusConnection::sessionBus().registerObject(APP_DBUS_PATH, this, QDBusConnection::ExportScriptableSlots); dbusMessage = new QDBusMessage(QDBusMessage::createMethodCall(APP_DBUS_SERVICE, APP_DBUS_PATH, APP_DBUS_INTERFACE, "activate_application")); notificationHints.append(StringPair("led-pattern", "PatternCommunicationEmail")); #endif // Applying the settings from last time settingsSaved(); } CharacterListWindow::~CharacterListWindow() { delete waitDialog; delete settingsDialog; delete connector; delete refresher; delete ui; } int CharacterListWindow::activate_application() { qDebug() << "Someone called us, activating window!"; if (!isVisible()) show(); activateWindow(); return 0; } void CharacterListWindow::showEvent(QShowEvent *event) { QMainWindow::showEvent(event); #if defined(Q_WS_MAEMO_5) setAttribute(Qt::WA_Maemo5ShowProgressIndicator); #endif if (!_listWidgetInitialized) { _listWidgetInitialized = true; for (int i = 0; i < characters->count(); i++) addCharacterItem(characters->operator [](i)); } if (!timer->isActive()) { QeTimerRunnable::createAndRunOnSeparateThread(timer, 1000, 0); } #if defined(Q_WS_MAEMO_5) setAttribute(Qt::WA_Maemo5ShowProgressIndicator, false); #endif } void CharacterListWindow::changeEvent(QEvent *e) { QMainWindow::changeEvent(e); switch (e->type()) { case QEvent::LanguageChange: ui->retranslateUi(this); break; default: break; } } QListWidgetItem *CharacterListWindow::addCharacterItem(const EveCharacter &character) { QListWidgetItem *item = new QListWidgetItem(character.name() + "\nLoading, please wait..."); QPair pair(item, character.id()); itemList.append(pair); ui->listWidget->addItem(item); if (AppSettingsManager::portraitsDisplayed()) { item->setIcon(QIcon(character.portrait())); } return item; } QListWidgetItem *CharacterListWindow::findItemByCharacterID(int characterID) { for (int i = 0; i < itemList.count(); i++) { if (itemList.at(i).second == characterID) { return itemList.at(i).first; } } return NULL; } void CharacterListWindow::refreshUI() { static int refresh_delay = 0; if (refresh_delay < 1) { refresh_delay++; return; } foreach (ListWidgetIdentifier item, itemList) { QString separator(isPortrait ? "\n" : " "); QListWidgetItem *listWidgetItem = item.first; EveCharacter *character = findCharacterById(item.second); if (character->_skillQueue.count() > 0) { EveTrainedSkill *skill = &(character->_skillQueue[0]); int seconds = skill->remainingSeconds(); QString eta(skill->isSkillQueueActive() ? EveTimeSpan(seconds).toString() : "Skill queue inactive"); listWidgetItem->setText(character->name() + "\n" + skill->name() + " " + QString::number(skill->completedLevel() + 1) + separator + "(" + eta + ")"); // if (skill->isSkillQueueActive() && seconds <= 1) // { // while (character->_skillQueue.count() > 0 && skill->remainingSeconds() <= 1) // { // skill = &(character->_skillQueue[0]); // showNotification(character->name() + ": " + skill->name() + " " + QString::number(skill->completedLevel() + 1) + " is complete.", "EVE: Skill training complete!"); // character->_skillQueue.removeAt(0); // EveCharacterSkill *characterSkill = findCharacterSkillById(character->id(), skill->id()); // characterSkill->setCompletedLevel(skill->completedLevel() + 1); // characterSkill->setCompletedSP(0); // TODO // } // } } if (character->_skillQueue.count() == 0) { listWidgetItem->setText(character->name() + "\nSkill queue is empty." + separator + "(No skills in training.)"); } } } void CharacterListWindow::showNotification(const QString &text, const QString &title) { #if defined(Q_WS_MAEMO_5) if (QApplication::focusWidget() != NULL) QMaemo5InformationBox::information(0, "" + title + "
" + text, QMaemo5InformationBox::NoTimeout); else QeMaemo5Notification::nonExpiringInformation(text, title, dbusMessage, notificationHints); #else QMessageBox::information(0, completed, completedInfo); #endif } void CharacterListWindow::on_btnVisitPage_clicked() { if (QMessageBox::Yes == QMessageBox::question(this, "Are you sure?", "Do you want to navigate to the EVE API web site?", QMessageBox::Yes, QMessageBox::No)) { QDesktopServices::openUrl(QUrl("http://eveonline.com/api/")); } } void CharacterListWindow::on_listWidget_itemSelectionChanged() { if (ui->listWidget->selectedItems().count() > 0) { ui->actionRemove_character->setEnabled(true); } else { ui->actionRemove_character->setEnabled(false); } } void CharacterListWindow::on_actionRemove_character_triggered() { if (QMessageBox::Yes == QMessageBox::question(this, "Are you sure?", "Do you wish to remove the selected character?", QMessageBox::Yes, QMessageBox::No)) { int index = 0; for (index = 0; index < ui->listWidget->count(); index++) { if (ui->listWidget->currentItem() == ui->listWidget->item(index)) break; } characters->removeAt(index); ui->listWidget->removeItemWidget(itemList.at(index).first); QListWidgetItem *item = itemList.at(index).first; itemList.removeAt(index); item->setHidden(true); delete item; AppSettingsManager::setCharacters(*characters); } } void CharacterListWindow::on_actionAdd_character_triggered() { if (QMessageBox::Yes == QMessageBox::question(this, "Do you agree?", "All the information displayed by EVE Watcher is displayed from the official EVE Online API.\n\nThe author of EVE watcher doesn't take ANY responsibility in case it is unaccurate or false, nor for any harm that it causes to you.", QMessageBox::Yes, QMessageBox::No)) { characterCreationDialog->show(); } } void CharacterListWindow::characterDataInput() { characterCreationDialog->hide(); if (!EveConnector::checkConnection()) return; int userId = characterCreationDialog->selectedUserID; QString apiKey = characterCreationDialog->selectedApiKey; waitDialog->show(); #if defined(Q_WS_MAEMO_5) waitDialog->setAttribute(Qt::WA_Maemo5ShowProgressIndicator); #endif connector->requestAccount(userId, apiKey); } void CharacterListWindow::accountReceived(QList *acc) { waitDialog->hide(); #if defined(Q_WS_MAEMO_5) waitDialog->setAttribute(Qt::WA_Maemo5ShowProgressIndicator, false); #endif if (acc != NULL && acc->count() > 0) { bool ok = true; QStringList list; foreach (EveCharacter ch, *acc) { list.append(ch.name()); } QString item = QInputDialog::getItem(this, "Choose character", "Please choose a character.", list, 0, false, &ok); if (ok) { ui->btnRefresh->setEnabled(false); if (findCharacterByName(item) != NULL) { QMessageBox::warning(this, "Error", "You have already added this character to your character monitoring list."); ui->btnRefresh->setEnabled(true); return; } const EveCharacter *currentCharacter; foreach (EveCharacter ch, *acc) { if (ch.name() == item) { currentCharacter = &ch; characters->append(EveCharacter(ch)); break; } } if (AppSettingsManager::portraitsDownloaded()) { connector->requestPortrait(256, currentCharacter->id()); } #if defined(Q_WS_MAEMO_5) setAttribute(Qt::WA_Maemo5ShowProgressIndicator); #endif connector->requestCharacter(currentCharacter->userId(), currentCharacter->apiKey(), currentCharacter->id()); addCharacterItem(*currentCharacter); AppSettingsManager::setCharacters(*characters); } } else if (acc != NULL && acc->count() == 0) { QMessageBox::warning(this, "Error!", "It seems that there are no characters on this account, or the given API key is incorrect.", QMessageBox::Ok, QMessageBox::NoButton); } else { QMessageBox::warning(this, "Error!", "Network-related error\nThe application couldn't receive the account information.", QMessageBox::Ok, QMessageBox::NoButton); } delete acc; } void CharacterListWindow::characterReceived(EveCharacter *character) { if (character != NULL) { int index = -1; EveCharacter *currentCharacter = findCharacterById(character->id(), &index); *currentCharacter = *character; connector->requestSkillQueue(character->userId(), character->apiKey(), character->id()); itemList[index].first->setText(character->name() + "\nRetrieving skill queue."); AppSettingsManager::setCharacters(*characters); } else { #if defined(Q_WS_MAEMO_5) setAttribute(Qt::WA_Maemo5ShowProgressIndicator, false); #endif QMessageBox::warning(this, "Error!", "Network-related error\nThe application failed to retrieve the data for a character.", QMessageBox::Ok, QMessageBox::NoButton); ui->btnRefresh->setEnabled(true); } delete character; } void CharacterListWindow::skillQueueReceived(int characterID, QList *skillQueue) { if (skillQueue != NULL) { EveCharacter *currentCharacter = findCharacterById(characterID); currentCharacter->setSkillQueue(*skillQueue); AppSettingsManager::setCharacters(*characters); } else { QMessageBox::warning(this, "Error!", "Network-related error\nThe application failed to retrieve the skill queue for a character.", QMessageBox::Ok, QMessageBox::NoButton); } ui->btnRefresh->setEnabled(true); delete skillQueue; #if defined(Q_WS_MAEMO_5) setAttribute(Qt::WA_Maemo5ShowProgressIndicator, false); #endif } void CharacterListWindow::portraitReceived(int characterID, QPixmap *portrait) { if (portrait != NULL) { EveCharacter *currentCharacter = findCharacterById(characterID); currentCharacter->setPortrait(*portrait); AppSettingsManager::setCharacters(*characters); if (AppSettingsManager::portraitsDisplayed()) { QListWidgetItem *item = findItemByCharacterID(characterID); item->setIcon(QIcon(*portrait)); } } else { QMessageBox::warning(this, "Error!", "Network-related error\nThe application failed to retrieve the portrait for character " + QString::number(characterID) + "."); } } void CharacterListWindow::on_actionSettings_triggered() { settingsDialog->exec(); } void CharacterListWindow::settingsSaved() { refresher->setInterval(AppSettingsManager::refreshRate()); ui->actionRefresh_portraits->setEnabled(AppSettingsManager::portraitsDownloaded()); if (!AppSettingsManager::portraitsDisplayed()) { for (int i = 0; i < itemList.count(); i++) { itemList.at(i).first->setIcon(QIcon()); } } else { for (int i = 0; i < itemList.count(); i++) { itemList.at(i).first->setIcon(QIcon(findCharacterById(itemList.at(i).second)->portrait())); } } *skills = AppSettingsManager::skillData(); } void CharacterListWindow::on_actionHelp_triggered() { int x = QMessageBox::information(this, "EVE Watcher - Help", "This software displays information of an EVE Online character through the official EVE Online API." + QString("\n\n") + "To add a character, select 'Add character' from the menu. To remove a character, select it from the list, and choose the 'Remove character' menu item.", "Close", "About"); if (x > 0) { QMessageBox::about(this, "About EVE Watcher", "Created by Timur Kristóf\n(Venemo)\n\nContact me on http://talk.maemo.org"); } } void CharacterListWindow::on_btnRefresh_clicked() { #if defined(Q_WS_MAEMO_5) setAttribute(Qt::WA_Maemo5ShowProgressIndicator); #endif ui->btnRefresh->setEnabled(false); refresher->refreshCharactersAndQueues(); } void CharacterListWindow::charactersAndQueuesRefreshed(bool successful) { if (successful) { refreshUI(); AppSettingsManager::setCharacters(*characters); } else { if (EveConnector::checkConnection(false)) QMessageBox::warning(this, "Error", "The application couldn't refresh the data due to a network error."); } ui->btnRefresh->setEnabled(true); #if defined(Q_WS_MAEMO_5) setAttribute(Qt::WA_Maemo5ShowProgressIndicator, false); #endif } void CharacterListWindow::on_actionRefresh_portraits_triggered() { if (( AppSettingsManager::portraitsDownloaded() || QMessageBox::Yes == QMessageBox::question(this, "Are you sure?", "The portraits are set NOT to be downloaded. Do you want to download them anyway?", QMessageBox::Yes, QMessageBox::No) ) && ( AppSettingsManager::portraitsDisplayed() || QMessageBox::Yes == QMessageBox::question(this, "Are you sure?", "The portraits are set NOT to be displayed. Do you still want to refresh them?", QMessageBox::Yes, QMessageBox::No) )) { #if defined(Q_WS_MAEMO_5) setAttribute(Qt::WA_Maemo5ShowProgressIndicator); #endif refresher->refreshPortraits(); } } void CharacterListWindow::portraitsRefreshed(bool successful) { if (!successful) QMessageBox::warning(this, "Error", "The application couldn't refresh the portraits due to a network error."); if (AppSettingsManager::portraitsDisplayed()) { for (int i = 0; i < itemList.count(); i++) { itemList.at(i).first->setIcon(QIcon(findCharacterById(itemList.at(i).second)->portrait())); } } AppSettingsManager::setCharacters(*characters); #if defined(Q_WS_MAEMO_5) setAttribute(Qt::WA_Maemo5ShowProgressIndicator, false); #endif } void CharacterListWindow::on_listWidget_clicked(QModelIndex index) { if (characterWindow != NULL) { delete characterWindow; } characterWindow = new CharacterDetailsWindow(characters->at(index.row()), this); characterWindow->show(); }