1
0
forked from blue/squawk

basic context menu, subscribing unsubscribing to contacts

This commit is contained in:
Blue 2019-06-12 20:18:18 +03:00
parent b845518ced
commit ee59d92cdc
8 changed files with 137 additions and 4 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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