// Squawk messenger. // Copyright (C) 2019 Yury Gubich // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "dialogqueue.h" #include DialogQueue::DialogQueue(const Models::Roster& p_roster): QObject(), currentSource(), currentAction(none), queue(), collection(queue.get<0>()), sequence(queue.get<1>()), prompt(nullptr), parent(nullptr), roster(p_roster) { } DialogQueue::~DialogQueue() { } void DialogQueue::quit() { queue.clear(); if (currentAction != none) { actionDone(); } } void DialogQueue::setParentWidnow(QMainWindow* p_parent) { parent = p_parent; } bool DialogQueue::addAction(const QString& source, DialogQueue::Action action) { if (action == none) { return false; } if (currentAction == none) { currentAction = action; currentSource = source; performNextAction(); return true; } else { if (currentAction != action || currentSource != source) { std::pair result = queue.emplace(source, action); return result.second; } else { return false; } } } bool DialogQueue::cancelAction(const QString& source, DialogQueue::Action action) { if (source == currentSource && action == currentAction) { actionDone(); return true; } else { Collection::iterator itr = collection.find(ActionId{source, action}); if (itr != collection.end()) { collection.erase(itr); return true; } else { return false; } } } void DialogQueue::performNextAction() { switch (currentAction) { case none: actionDone(); break; case askPassword: { QInputDialog* dialog = new QInputDialog(parent); prompt = dialog; connect(dialog, &QDialog::accepted, this, &DialogQueue::onPropmtAccepted); connect(dialog, &QDialog::rejected, this, &DialogQueue::onPropmtRejected); dialog->setInputMode(QInputDialog::TextInput); dialog->setTextEchoMode(QLineEdit::Password); dialog->setLabelText(tr("Input the password for account %1").arg(currentSource)); dialog->setWindowTitle(tr("Password for account %1").arg(currentSource)); dialog->setTextValue(""); dialog->exec(); } break; case askCredentials: { CredentialsPrompt* dialog = new CredentialsPrompt(parent); prompt = dialog; connect(dialog, &QDialog::accepted, this, &DialogQueue::onPropmtAccepted); connect(dialog, &QDialog::rejected, this, &DialogQueue::onPropmtRejected); const Models::Account* acc = roster.getAccountConst(currentSource); dialog->setAccount(currentSource); dialog->setLogin(acc->getLogin()); dialog->setPassword(acc->getPassword()); dialog->exec(); } break; } } void DialogQueue::onPropmtAccepted() { switch (currentAction) { case none: break; case askPassword: { QInputDialog* dialog = static_cast(prompt); emit responsePassword(currentSource, dialog->textValue()); } break; case askCredentials: { CredentialsPrompt* dialog = static_cast(prompt); emit modifyAccountRequest(currentSource, { {"login", dialog->getLogin()}, {"password", dialog->getPassword()} }); } break; } actionDone(); } void DialogQueue::onPropmtRejected() { switch (currentAction) { case none: break; case askPassword: case askCredentials: emit disconnectAccount(currentSource); break; } actionDone(); } void DialogQueue::actionDone() { prompt->deleteLater(); prompt = nullptr; if (queue.empty()) { currentAction = none; currentSource = ""; } else { Sequence::iterator itr = sequence.begin(); currentAction = itr->action; currentSource = itr->source; sequence.erase(itr); performNextAction(); } } DialogQueue::ActionId::ActionId(const QString& p_source, DialogQueue::Action p_action): source(p_source), action(p_action) {} bool DialogQueue::ActionId::operator < (const DialogQueue::ActionId& other) const { if (action == other.action) { return source < other.source; } else { return action < other.action; } } DialogQueue::ActionId::ActionId(const DialogQueue::ActionId& other): source(other.source), action(other.action) {}