forked from blue/squawk
basic context menu, subscribing unsubscribing to contacts
This commit is contained in:
parent
b845518ced
commit
ee59d92cdc
@ -23,6 +23,7 @@ Account::Account(const QString& p_login, const QString& p_server, const QString&
|
|||||||
config.setUser(p_login);
|
config.setUser(p_login);
|
||||||
config.setDomain(p_server);
|
config.setDomain(p_server);
|
||||||
config.setPassword(p_password);
|
config.setPassword(p_password);
|
||||||
|
config.setAutoAcceptSubscriptions(true);
|
||||||
|
|
||||||
QObject::connect(&client, SIGNAL(connected()), this, SLOT(onClientConnected()));
|
QObject::connect(&client, SIGNAL(connected()), this, SLOT(onClientConnected()));
|
||||||
QObject::connect(&client, SIGNAL(disconnected()), this, SLOT(onClientDisconnected()));
|
QObject::connect(&client, SIGNAL(disconnected()), this, SLOT(onClientDisconnected()));
|
||||||
@ -183,7 +184,7 @@ void Core::Account::onRosterItemChanged(const QString& bareJid)
|
|||||||
|
|
||||||
contact->setGroups(re.groups());
|
contact->setGroups(re.groups());
|
||||||
contact->setSubscriptionState(state);
|
contact->setSubscriptionState(state);
|
||||||
contact->setName(name);
|
contact->setName(re.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::Account::onRosterItemRemoved(const QString& bareJid)
|
void Core::Account::onRosterItemRemoved(const QString& bareJid)
|
||||||
@ -738,3 +739,25 @@ void Core::Account::onClientError(QXmppClient::Error err)
|
|||||||
qDebug() << errorType << errorText;
|
qDebug() << errorType << errorText;
|
||||||
emit error(errorText);
|
emit error(errorText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Core::Account::subscribeToContact(const QString& jid, const QString& reason)
|
||||||
|
{
|
||||||
|
if (state == Shared::connected) {
|
||||||
|
QXmppRosterManager& rm = client.rosterManager();
|
||||||
|
rm.subscribe(jid, reason);
|
||||||
|
} else {
|
||||||
|
qDebug() << "An attempt to subscribe an account " << name << " to jid " << jid << " but the account is not in the connected state, skipping";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Core::Account::unsubscribeFromContact(const QString& jid, const QString& reason)
|
||||||
|
{
|
||||||
|
if (state == Shared::connected) {
|
||||||
|
QXmppRosterManager& rm = client.rosterManager();
|
||||||
|
rm.unsubscribe(jid, reason);
|
||||||
|
} else {
|
||||||
|
qDebug() << "An attempt to unsubscribe an account " << name << " from jid " << jid << " but the account is not in the connected state, skipping";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -44,6 +44,8 @@ public:
|
|||||||
void sendMessage(const Shared::Message& data);
|
void sendMessage(const Shared::Message& data);
|
||||||
void requestArchive(const QString& jid, int count, const QString& before);
|
void requestArchive(const QString& jid, int count, const QString& before);
|
||||||
void setReconnectTimes(unsigned int times);
|
void setReconnectTimes(unsigned int times);
|
||||||
|
void subscribeToContact(const QString& jid, const QString& reason);
|
||||||
|
void unsubscribeFromContact(const QString& jid, const QString& reason);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void connectionStateChanged(int);
|
void connectionStateChanged(int);
|
||||||
|
@ -331,3 +331,26 @@ void Core::Squawk::removeAccountRequest(const QString& name)
|
|||||||
emit removeAccount(name);
|
emit removeAccount(name);
|
||||||
acc->deleteLater();
|
acc->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Core::Squawk::subscribeContact(const QString& account, const QString& jid, const QString& reason)
|
||||||
|
{
|
||||||
|
AccountsMap::const_iterator itr = amap.find(account);
|
||||||
|
if (itr == amap.end()) {
|
||||||
|
qDebug("An attempt to subscribe to the contact with non existing account, skipping");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
itr->second->subscribeToContact(jid, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Core::Squawk::unsubscribeContact(const QString& account, const QString& jid, const QString& reason)
|
||||||
|
{
|
||||||
|
AccountsMap::const_iterator itr = amap.find(account);
|
||||||
|
if (itr == amap.end()) {
|
||||||
|
qDebug("An attempt to subscribe to the contact with non existing account, skipping");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
itr->second->unsubscribeFromContact(jid, reason);
|
||||||
|
}
|
||||||
|
@ -49,6 +49,8 @@ public slots:
|
|||||||
void changeState(int state);
|
void changeState(int state);
|
||||||
void sendMessage(const QString& account, const Shared::Message& data);
|
void sendMessage(const QString& account, const Shared::Message& data);
|
||||||
void requestArchive(const QString& account, const QString& jid, int count, const QString& before);
|
void requestArchive(const QString& account, const QString& jid, int count, const QString& before);
|
||||||
|
void subscribeContact(const QString& account, const QString& jid, const QString& reason);
|
||||||
|
void unsubscribeContact(const QString& account, const QString& jid, const QString& reason);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::deque<Account*> Accounts;
|
typedef std::deque<Account*> Accounts;
|
||||||
|
4
main.cpp
4
main.cpp
@ -41,6 +41,10 @@ int main(int argc, char *argv[])
|
|||||||
QObject::connect(&w, SIGNAL(sendMessage(const QString&, const Shared::Message&)), squawk, SLOT(sendMessage(const QString&, const Shared::Message&)));
|
QObject::connect(&w, SIGNAL(sendMessage(const QString&, const Shared::Message&)), squawk, SLOT(sendMessage(const QString&, const Shared::Message&)));
|
||||||
QObject::connect(&w, SIGNAL(requestArchive(const QString&, const QString&, int, const QString&)),
|
QObject::connect(&w, SIGNAL(requestArchive(const QString&, const QString&, int, const QString&)),
|
||||||
squawk, SLOT(requestArchive(const QString&, const QString&, int, const QString&)));
|
squawk, SLOT(requestArchive(const QString&, const QString&, int, const QString&)));
|
||||||
|
QObject::connect(&w, SIGNAL(subscribeContact(const QString&, const QString&, const QString&)),
|
||||||
|
squawk, SLOT(subscribeContact(const QString&, const QString&, const QString&)));
|
||||||
|
QObject::connect(&w, SIGNAL(unsubscribeContact(const QString&, const QString&, const QString&)),
|
||||||
|
squawk, SLOT(unsubscribeContact(const QString&, const QString&, const QString&)));
|
||||||
|
|
||||||
QObject::connect(squawk, SIGNAL(newAccount(const QMap<QString, QVariant>&)), &w, SLOT(newAccount(const QMap<QString, QVariant>&)));
|
QObject::connect(squawk, SIGNAL(newAccount(const QMap<QString, QVariant>&)), &w, SLOT(newAccount(const QMap<QString, QVariant>&)));
|
||||||
QObject::connect(squawk, SIGNAL(addContact(const QString&, const QString&, const QString&, const QMap<QString, QVariant>&)),
|
QObject::connect(squawk, SIGNAL(addContact(const QString&, const QString&, const QString&, const QMap<QString, QVariant>&)),
|
||||||
|
@ -455,7 +455,6 @@ void Models::Roster::onChildIsAboutToBeRemoved(Models::Item* parent, int first,
|
|||||||
if (parent != root) {
|
if (parent != root) {
|
||||||
row = parent->row();
|
row = parent->row();
|
||||||
}
|
}
|
||||||
qDebug() << "Removing row" << parent->child(first)->getName() << "from" << parent->getName() << "index is" << first;
|
|
||||||
beginRemoveRows(createIndex(row, 0, parent), first, last);
|
beginRemoveRows(createIndex(row, 0, parent), first, last);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,10 +8,12 @@ Squawk::Squawk(QWidget *parent) :
|
|||||||
m_ui(new Ui::Squawk),
|
m_ui(new Ui::Squawk),
|
||||||
accounts(0),
|
accounts(0),
|
||||||
rosterModel(),
|
rosterModel(),
|
||||||
conversations()
|
conversations(),
|
||||||
|
contextMenu(new QMenu())
|
||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
m_ui->roster->setModel(&rosterModel);
|
m_ui->roster->setModel(&rosterModel);
|
||||||
|
m_ui->roster->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
|
||||||
for (int i = 0; i < Shared::availabilityNames.size(); ++i) {
|
for (int i = 0; i < Shared::availabilityNames.size(); ++i) {
|
||||||
m_ui->comboBox->addItem(QIcon::fromTheme(Shared::availabilityThemeIcons[i]), Shared::availabilityNames[i]);
|
m_ui->comboBox->addItem(QIcon::fromTheme(Shared::availabilityThemeIcons[i]), Shared::availabilityNames[i]);
|
||||||
@ -21,11 +23,12 @@ Squawk::Squawk(QWidget *parent) :
|
|||||||
connect(m_ui->actionAccounts, SIGNAL(triggered()), this, SLOT(onAccounts()));
|
connect(m_ui->actionAccounts, SIGNAL(triggered()), this, SLOT(onAccounts()));
|
||||||
connect(m_ui->comboBox, SIGNAL(activated(int)), this, SLOT(onComboboxActivated(int)));
|
connect(m_ui->comboBox, SIGNAL(activated(int)), this, SLOT(onComboboxActivated(int)));
|
||||||
connect(m_ui->roster, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(onRosterItemDoubleClicked(const QModelIndex&)));
|
connect(m_ui->roster, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(onRosterItemDoubleClicked(const QModelIndex&)));
|
||||||
|
connect(m_ui->roster, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(onRosterContextMenu(const QPoint&)));
|
||||||
//m_ui->mainToolBar->addWidget(m_ui->comboBox);
|
//m_ui->mainToolBar->addWidget(m_ui->comboBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
Squawk::~Squawk() {
|
Squawk::~Squawk() {
|
||||||
|
delete contextMenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Squawk::onAccounts()
|
void Squawk::onAccounts()
|
||||||
@ -272,3 +275,76 @@ void Squawk::removeAccount(const QString& account)
|
|||||||
}
|
}
|
||||||
rosterModel.removeAccount(account);
|
rosterModel.removeAccount(account);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Squawk::onRosterContextMenu(const QPoint& point)
|
||||||
|
{
|
||||||
|
QModelIndex index = m_ui->roster->indexAt(point);
|
||||||
|
if (index.isValid()) {
|
||||||
|
Models::Item* item = static_cast<Models::Item*>(index.internalPointer());
|
||||||
|
|
||||||
|
contextMenu->clear();
|
||||||
|
bool hasMenu = false;
|
||||||
|
switch (item->type) {
|
||||||
|
case Models::Item::account: {
|
||||||
|
Models::Account* acc = static_cast<Models::Account*>(item);
|
||||||
|
hasMenu = true;
|
||||||
|
QString name = acc->getName();
|
||||||
|
|
||||||
|
if (acc->getState() != Shared::disconnected) {
|
||||||
|
QAction* con = contextMenu->addAction(QIcon::fromTheme("network-disconnect"), "Disconnect");
|
||||||
|
connect(con, &QAction::triggered, [this, name]() {
|
||||||
|
emit disconnectAccount(name);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
QAction* con = contextMenu->addAction(QIcon::fromTheme("network-connect"), "Connect");
|
||||||
|
connect(con, &QAction::triggered, [this, name]() {
|
||||||
|
emit connectAccount(name);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QAction* remove = contextMenu->addAction(QIcon::fromTheme("edit-delete"), "Remove");
|
||||||
|
connect(remove, &QAction::triggered, [this, name]() {
|
||||||
|
emit removeAccount(name);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Models::Item::contact: {
|
||||||
|
Models::Contact* cnt = static_cast<Models::Contact*>(item);
|
||||||
|
hasMenu = true;
|
||||||
|
|
||||||
|
QAction* remove = contextMenu->addAction(QIcon::fromTheme("mail-message"), "Open dialog");
|
||||||
|
connect(remove, &QAction::triggered, [this, index]() {
|
||||||
|
onRosterItemDoubleClicked(index);
|
||||||
|
});
|
||||||
|
|
||||||
|
Shared::SubscriptionState state = cnt->getState();
|
||||||
|
switch (state) {
|
||||||
|
case Shared::both:
|
||||||
|
case Shared::to: {
|
||||||
|
QAction* remove = contextMenu->addAction(QIcon::fromTheme("news-unsubscribe"), "Unsubscribe");
|
||||||
|
connect(remove, &QAction::triggered, [this, cnt]() {
|
||||||
|
emit unsubscribeContact(cnt->getAccountName(), cnt->getJid(), "");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Shared::from:
|
||||||
|
case Shared::unknown:
|
||||||
|
case Shared::none: {
|
||||||
|
QAction* remove = contextMenu->addAction(QIcon::fromTheme("news-subscribe"), "Subscribe");
|
||||||
|
connect(remove, &QAction::triggered, [this, cnt]() {
|
||||||
|
emit subscribeContact(cnt->getAccountName(), cnt->getJid(), "");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (hasMenu) {
|
||||||
|
contextMenu->popup(m_ui->roster->viewport()->mapToGlobal(point));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -35,6 +35,8 @@ signals:
|
|||||||
void changeState(int state);
|
void changeState(int state);
|
||||||
void sendMessage(const QString& account, const Shared::Message& data);
|
void sendMessage(const QString& account, const Shared::Message& data);
|
||||||
void requestArchive(const QString& account, const QString& jid, int count, const QString& before);
|
void requestArchive(const QString& account, const QString& jid, int count, const QString& before);
|
||||||
|
void subscribeContact(const QString& account, const QString& jid, const QString& reason);
|
||||||
|
void unsubscribeContact(const QString& account, const QString& jid, const QString& reason);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void newAccount(const QMap<QString, QVariant>& account);
|
void newAccount(const QMap<QString, QVariant>& account);
|
||||||
@ -59,6 +61,7 @@ private:
|
|||||||
Accounts* accounts;
|
Accounts* accounts;
|
||||||
Models::Roster rosterModel;
|
Models::Roster rosterModel;
|
||||||
Conversations conversations;
|
Conversations conversations;
|
||||||
|
QMenu* contextMenu;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void closeEvent(QCloseEvent * event) override;
|
void closeEvent(QCloseEvent * event) override;
|
||||||
@ -71,6 +74,7 @@ private slots:
|
|||||||
void onRosterItemDoubleClicked(const QModelIndex& item);
|
void onRosterItemDoubleClicked(const QModelIndex& item);
|
||||||
void onConversationMessage(const Shared::Message& msg);
|
void onConversationMessage(const Shared::Message& msg);
|
||||||
void onConversationRequestArchive(const QString& before);
|
void onConversationRequestArchive(const QString& before);
|
||||||
|
void onRosterContextMenu(const QPoint& point);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user