feat/tray_pictogram #70
@ -1,4 +1,10 @@
|
|||||||
target_sources(squawk PRIVATE squawk.cpp squawk.h squawk.ui)
|
target_sources(squawk PRIVATE
|
||||||
|
squawk.cpp
|
||||||
|
squawk.h
|
||||||
|
squawk.ui
|
||||||
|
dialogqueue.cpp
|
||||||
|
dialogqueue.h
|
||||||
|
)
|
||||||
|
|
||||||
add_subdirectory(models)
|
add_subdirectory(models)
|
||||||
add_subdirectory(utils)
|
add_subdirectory(utils)
|
||||||
|
148
ui/dialogqueue.cpp
Normal file
148
ui/dialogqueue.cpp
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
// Squawk messenger.
|
||||||
|
// Copyright (C) 2019 Yury Gubich <blue@macaw.me>
|
||||||
|
//
|
||||||
|
// 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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "dialogqueue.h"
|
||||||
|
#include "squawk.h"
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
DialogQueue::DialogQueue(Squawk* p_squawk):
|
||||||
|
QObject(),
|
||||||
|
currentSource(),
|
||||||
|
currentAction(none),
|
||||||
|
queue(),
|
||||||
|
collection(queue.get<0>()),
|
||||||
|
sequence(queue.get<1>()),
|
||||||
|
prompt(nullptr),
|
||||||
|
squawk(p_squawk)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
DialogQueue::~DialogQueue()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
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<Queue::iterator, bool> 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:
|
||||||
|
prompt = new QInputDialog(squawk);
|
||||||
|
connect(prompt, &QDialog::accepted, this, &DialogQueue::onPropmtAccepted);
|
||||||
|
connect(prompt, &QDialog::rejected, this, &DialogQueue::onPropmtRejected);
|
||||||
|
prompt->setInputMode(QInputDialog::TextInput);
|
||||||
|
prompt->setTextEchoMode(QLineEdit::Password);
|
||||||
|
prompt->setLabelText(tr("Input the password for account %1").arg(currentSource));
|
||||||
|
prompt->setWindowTitle(tr("Password for account %1").arg(currentSource));
|
||||||
|
prompt->setTextValue("");
|
||||||
|
prompt->exec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogQueue::onPropmtAccepted()
|
||||||
|
{
|
||||||
|
switch (currentAction) {
|
||||||
|
case none:
|
||||||
|
break;
|
||||||
|
case askPassword:
|
||||||
|
emit squawk->responsePassword(currentSource, prompt->textValue());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
actionDone();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogQueue::onPropmtRejected()
|
||||||
|
{
|
||||||
|
switch (currentAction) {
|
||||||
|
case none:
|
||||||
|
break;
|
||||||
|
case askPassword:
|
||||||
|
emit squawk->responsePassword(currentSource, prompt->textValue());
|
||||||
|
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) {}
|
92
ui/dialogqueue.h
Normal file
92
ui/dialogqueue.h
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
// Squawk messenger.
|
||||||
|
// Copyright (C) 2019 Yury Gubich <blue@macaw.me>
|
||||||
|
//
|
||||||
|
// 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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef DIALOGQUEUE_H
|
||||||
|
#define DIALOGQUEUE_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QInputDialog>
|
||||||
|
|
||||||
|
#include <boost/multi_index_container.hpp>
|
||||||
|
#include <boost/multi_index/ordered_index.hpp>
|
||||||
|
#include <boost/multi_index/sequenced_index.hpp>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @todo write docs
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Squawk;
|
||||||
|
|
||||||
|
class DialogQueue : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
enum Action {
|
||||||
|
none,
|
||||||
|
askPassword
|
||||||
|
};
|
||||||
|
|
||||||
|
DialogQueue(Squawk* squawk);
|
||||||
|
~DialogQueue();
|
||||||
|
|
||||||
|
bool addAction(const QString& source, Action action);
|
||||||
|
bool cancelAction(const QString& source, Action action);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void performNextAction();
|
||||||
|
void actionDone();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onPropmtAccepted();
|
||||||
|
void onPropmtRejected();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString currentSource;
|
||||||
|
Action currentAction;
|
||||||
|
|
||||||
|
struct ActionId {
|
||||||
|
public:
|
||||||
|
ActionId(const QString& p_source, Action p_action);
|
||||||
|
ActionId(const ActionId& other);
|
||||||
|
|
||||||
|
const QString source;
|
||||||
|
const Action action;
|
||||||
|
|
||||||
|
bool operator < (const ActionId& other) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef boost::multi_index_container <
|
||||||
|
ActionId,
|
||||||
|
boost::multi_index::indexed_by <
|
||||||
|
boost::multi_index::ordered_unique <
|
||||||
|
boost::multi_index::identity <ActionId>
|
||||||
|
>,
|
||||||
|
boost::multi_index::sequenced<>
|
||||||
|
>
|
||||||
|
> Queue;
|
||||||
|
|
||||||
|
typedef Queue::nth_index<0>::type Collection;
|
||||||
|
typedef Queue::nth_index<1>::type Sequence;
|
||||||
|
|
||||||
|
Queue queue;
|
||||||
|
Collection& collection;
|
||||||
|
Sequence& sequence;
|
||||||
|
|
||||||
|
QInputDialog* prompt;
|
||||||
|
Squawk* squawk;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DIALOGQUEUE_H
|
@ -27,13 +27,12 @@ Squawk::Squawk(QWidget *parent) :
|
|||||||
accounts(nullptr),
|
accounts(nullptr),
|
||||||
preferences(nullptr),
|
preferences(nullptr),
|
||||||
about(nullptr),
|
about(nullptr),
|
||||||
|
dialogueQueue(this),
|
||||||
rosterModel(),
|
rosterModel(),
|
||||||
conversations(),
|
conversations(),
|
||||||
contextMenu(new QMenu()),
|
contextMenu(new QMenu()),
|
||||||
dbus("org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications", QDBusConnection::sessionBus()),
|
dbus("org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications", QDBusConnection::sessionBus()),
|
||||||
vCards(),
|
vCards(),
|
||||||
requestedAccountsForPasswords(),
|
|
||||||
prompt(nullptr),
|
|
||||||
currentConversation(nullptr),
|
currentConversation(nullptr),
|
||||||
restoreSelection(),
|
restoreSelection(),
|
||||||
needToRestore(false)
|
needToRestore(false)
|
||||||
@ -925,50 +924,8 @@ void Squawk::onItemCollepsed(const QModelIndex& index)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Squawk::requestPassword(const QString& account)
|
void Squawk::requestPassword(const QString& account) {
|
||||||
{
|
dialogueQueue.addAction(account, DialogQueue::askPassword);}
|
||||||
requestedAccountsForPasswords.push_back(account);
|
|
||||||
checkNextAccountForPassword();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::checkNextAccountForPassword()
|
|
||||||
{
|
|
||||||
if (prompt == nullptr && requestedAccountsForPasswords.size() > 0) {
|
|
||||||
prompt = new QInputDialog(this);
|
|
||||||
QString accName = requestedAccountsForPasswords.front();
|
|
||||||
connect(prompt, &QDialog::accepted, this, &Squawk::onPasswordPromptAccepted);
|
|
||||||
connect(prompt, &QDialog::rejected, this, &Squawk::onPasswordPromptRejected);
|
|
||||||
prompt->setInputMode(QInputDialog::TextInput);
|
|
||||||
prompt->setTextEchoMode(QLineEdit::Password);
|
|
||||||
prompt->setLabelText(tr("Input the password for account %1").arg(accName));
|
|
||||||
prompt->setWindowTitle(tr("Password for account %1").arg(accName));
|
|
||||||
prompt->setTextValue("");
|
|
||||||
prompt->exec();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::onPasswordPromptAccepted()
|
|
||||||
{
|
|
||||||
emit responsePassword(requestedAccountsForPasswords.front(), prompt->textValue());
|
|
||||||
onPasswordPromptDone();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::onPasswordPromptDone()
|
|
||||||
{
|
|
||||||
prompt->deleteLater();
|
|
||||||
prompt = nullptr;
|
|
||||||
requestedAccountsForPasswords.pop_front();
|
|
||||||
checkNextAccountForPassword();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::onPasswordPromptRejected()
|
|
||||||
{
|
|
||||||
//for now it's the same on reject and on accept, but one day I'm gonna make
|
|
||||||
//"Asking for the password again on the authentication failure" feature
|
|
||||||
//and here I'll be able to break the circle of password requests
|
|
||||||
emit responsePassword(requestedAccountsForPasswords.front(), prompt->textValue());
|
|
||||||
onPasswordPromptDone();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Squawk::subscribeConversation(Conversation* conv)
|
void Squawk::subscribeConversation(Conversation* conv)
|
||||||
{
|
{
|
||||||
|
10
ui/squawk.h
10
ui/squawk.h
@ -31,7 +31,7 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
#include "widgets/accounts.h"
|
#include "widgets/accounts/accounts.h"
|
||||||
#include "widgets/chat.h"
|
#include "widgets/chat.h"
|
||||||
#include "widgets/room.h"
|
#include "widgets/room.h"
|
||||||
#include "widgets/newcontact.h"
|
#include "widgets/newcontact.h"
|
||||||
@ -40,6 +40,7 @@
|
|||||||
#include "widgets/vcard/vcard.h"
|
#include "widgets/vcard/vcard.h"
|
||||||
#include "widgets/settings/settings.h"
|
#include "widgets/settings/settings.h"
|
||||||
#include "widgets/about.h"
|
#include "widgets/about.h"
|
||||||
|
#include "dialogqueue.h"
|
||||||
|
|
||||||
#include "shared/shared.h"
|
#include "shared/shared.h"
|
||||||
|
|
||||||
@ -122,13 +123,12 @@ private:
|
|||||||
Accounts* accounts;
|
Accounts* accounts;
|
||||||
Settings* preferences;
|
Settings* preferences;
|
||||||
About* about;
|
About* about;
|
||||||
|
DialogQueue dialogueQueue;
|
||||||
Models::Roster rosterModel;
|
Models::Roster rosterModel;
|
||||||
Conversations conversations;
|
Conversations conversations;
|
||||||
QMenu* contextMenu;
|
QMenu* contextMenu;
|
||||||
QDBusInterface dbus;
|
QDBusInterface dbus;
|
||||||
std::map<QString, VCard*> vCards;
|
std::map<QString, VCard*> vCards;
|
||||||
std::deque<QString> requestedAccountsForPasswords;
|
|
||||||
QInputDialog* prompt;
|
|
||||||
Conversation* currentConversation;
|
Conversation* currentConversation;
|
||||||
QModelIndex restoreSelection;
|
QModelIndex restoreSelection;
|
||||||
bool needToRestore;
|
bool needToRestore;
|
||||||
@ -161,8 +161,6 @@ private slots:
|
|||||||
void onRequestArchive(const QString& account, const QString& jid, const QString& before);
|
void onRequestArchive(const QString& account, const QString& jid, const QString& before);
|
||||||
void onRosterContextMenu(const QPoint& point);
|
void onRosterContextMenu(const QPoint& point);
|
||||||
void onItemCollepsed(const QModelIndex& index);
|
void onItemCollepsed(const QModelIndex& index);
|
||||||
void onPasswordPromptAccepted();
|
|
||||||
void onPasswordPromptRejected();
|
|
||||||
void onRosterSelectionChanged(const QModelIndex& current, const QModelIndex& previous);
|
void onRosterSelectionChanged(const QModelIndex& current, const QModelIndex& previous);
|
||||||
void onContextAboutToHide();
|
void onContextAboutToHide();
|
||||||
void onAboutSquawkCalled();
|
void onAboutSquawkCalled();
|
||||||
@ -171,8 +169,6 @@ private slots:
|
|||||||
void onUnnoticedMessage(const QString& account, const Shared::Message& msg);
|
void onUnnoticedMessage(const QString& account, const Shared::Message& msg);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void checkNextAccountForPassword();
|
|
||||||
void onPasswordPromptDone();
|
|
||||||
void subscribeConversation(Conversation* conv);
|
void subscribeConversation(Conversation* conv);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,10 +1,4 @@
|
|||||||
target_sources(squawk PRIVATE
|
target_sources(squawk PRIVATE
|
||||||
account.cpp
|
|
||||||
account.h
|
|
||||||
account.ui
|
|
||||||
accounts.cpp
|
|
||||||
accounts.h
|
|
||||||
accounts.ui
|
|
||||||
chat.cpp
|
chat.cpp
|
||||||
chat.h
|
chat.h
|
||||||
conversation.cpp
|
conversation.cpp
|
||||||
@ -26,3 +20,4 @@ target_sources(squawk PRIVATE
|
|||||||
add_subdirectory(vcard)
|
add_subdirectory(vcard)
|
||||||
add_subdirectory(messageline)
|
add_subdirectory(messageline)
|
||||||
add_subdirectory(settings)
|
add_subdirectory(settings)
|
||||||
|
add_subdirectory(accounts)
|
||||||
|
8
ui/widgets/accounts/CMakeLists.txt
Normal file
8
ui/widgets/accounts/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
target_sources(squawk PRIVATE
|
||||||
|
account.cpp
|
||||||
|
account.h
|
||||||
|
account.ui
|
||||||
|
accounts.cpp
|
||||||
|
accounts.h
|
||||||
|
accounts.ui
|
||||||
|
)
|
@ -24,7 +24,7 @@
|
|||||||
#include <QItemSelection>
|
#include <QItemSelection>
|
||||||
|
|
||||||
#include "account.h"
|
#include "account.h"
|
||||||
#include "../models/accounts.h"
|
#include "ui/models/accounts.h"
|
||||||
|
|
||||||
namespace Ui
|
namespace Ui
|
||||||
{
|
{
|
Loading…
Reference in New Issue
Block a user