feat/tray_pictogram #70

Open
pavanvo wants to merge 30 commits from pavanvo/squawk:feat/tray_pictogram into settings
13 changed files with 263 additions and 61 deletions
Showing only changes of commit 2c26c7e264 - Show all commits

View File

@ -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
View 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
View 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

View File

@ -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)
{ {

View File

@ -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);
}; };

View File

@ -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)

View File

@ -0,0 +1,8 @@
target_sources(squawk PRIVATE
account.cpp
account.h
account.ui
accounts.cpp
accounts.h
accounts.ui
)

View File

@ -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
{ {