File indexing completed on 2023-11-26 08:16:46
0001 /* 0002 * Add contact dialog 0003 * 0004 * Copyright (C) 2011 David Edmundson <kde@davidedmundson.co.uk> 0005 * Copyright (C) 2012 George Kiagiadakis <kiagiadakis.george@gmail.com> 0006 * 0007 * This library is free software; you can redistribute it and/or 0008 * modify it under the terms of the GNU Lesser General Public 0009 * License as published by the Free Software Foundation; either 0010 * version 2.1 of the License, or (at your option) any later version. 0011 * 0012 * This library is distributed in the hope that it will be useful, 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0015 * Lesser General Public License for more details. 0016 * 0017 * You should have received a copy of the GNU Lesser General Public 0018 * License along with this library; if not, write to the Free Software 0019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 0020 */ 0021 0022 #include "add-contact-dialog.h" 0023 #include "ui_add-contact-dialog.h" 0024 #include "debug.h" 0025 0026 #include <KTp/types.h> 0027 0028 #include <QObject> 0029 #include <QCloseEvent> 0030 #include <QDialogButtonBox> 0031 0032 #include <KMessageBox> 0033 #include <KLocalizedString> 0034 0035 #include <TelepathyQt/AccountManager> 0036 #include <TelepathyQt/Account> 0037 #include <TelepathyQt/Connection> 0038 #include <TelepathyQt/ContactManager> 0039 #include <TelepathyQt/PendingContacts> 0040 #include <TelepathyQt/Filter> 0041 #include <TelepathyQt/AccountSet> 0042 #include <TelepathyQt/PendingReady> 0043 0044 namespace KTp { 0045 0046 class KTPCOMMONINTERNALS_NO_EXPORT SubscribableAccountFilter : public Tp::AccountFilter 0047 { 0048 public: 0049 SubscribableAccountFilter() : Tp::AccountFilter() 0050 { 0051 } 0052 0053 bool isValid() const override 0054 { 0055 //return whether the filter is valid which is always true as this filter is hardcoded 0056 return true; 0057 } 0058 0059 bool matches(const Tp::AccountPtr &account) const override 0060 { 0061 //if there's no connection we can't add contacts as we have no contactmanager 0062 if (! account->connection()) { 0063 return false; 0064 } 0065 0066 //only show items which can add a contact (i.e hide accounts like IRC which are online but there's no point listing) 0067 if (! account->connection()->contactManager()->canRequestPresenceSubscription()){ 0068 return false; 0069 } 0070 return true; 0071 } 0072 }; 0073 0074 0075 struct KTPCOMMONINTERNALS_NO_EXPORT AddContactDialog::Private 0076 { 0077 Private() : 0078 ui(new Ui::AddContactDialog), 0079 acceptInProgress(false) 0080 {} 0081 0082 Ui::AddContactDialog *ui; 0083 bool acceptInProgress; 0084 QDialogButtonBox *buttonBox; 0085 }; 0086 0087 AddContactDialog::AddContactDialog(const Tp::AccountManagerPtr &accountManager, QWidget *parent) : 0088 QDialog(parent), 0089 d(new Private) 0090 { 0091 setWindowTitle(i18n("Add new contact")); 0092 setWindowIcon(QIcon::fromTheme(QLatin1String("list-add-user"))); 0093 0094 QWidget *widget = new QWidget(this); 0095 d->ui->setupUi(widget); 0096 0097 d->buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); 0098 connect(d->buttonBox, SIGNAL(accepted()), this, SLOT(accept())); 0099 connect(d->buttonBox, SIGNAL(rejected()), this, SLOT(reject())); 0100 0101 0102 QVBoxLayout *mainLayout = new QVBoxLayout(this); 0103 mainLayout->addWidget(widget); 0104 mainLayout->addWidget(d->buttonBox); 0105 0106 setLayout(mainLayout); 0107 0108 Tp::AccountFilterPtr filter = Tp::AccountFilterPtr(new KTp::SubscribableAccountFilter()); 0109 Tp::AccountSetPtr accountSet = accountManager->filterAccounts(filter); 0110 0111 d->ui->accountCombo->setAccountSet(accountSet); 0112 updateSubscriptionMessageVisibility(); 0113 0114 connect(d->ui->accountCombo, SIGNAL(currentIndexChanged(int)), SLOT(updateSubscriptionMessageVisibility())); 0115 0116 //bodge. 0117 //Wtih KPeople support we don't enable FeatureRoster 0118 //We need FeatureRoster in order to determine canRequestPresenceSubscription(); 0119 //so we upgrade any accounts here 0120 0121 //See https://bugs.kde.org/show_bug.cgi?id=324698 0122 Q_FOREACH(const Tp::AccountPtr &account, accountManager->allAccounts()) { 0123 if (account->connection()) { 0124 Tp::PendingOperation *op = account->connection()->becomeReady(Tp::Connection::FeatureRoster); 0125 op->setProperty("account", QVariant::fromValue<Tp::AccountPtr>(account)); 0126 connect(op, SIGNAL(finished(Tp::PendingOperation*)), SLOT(_k_onAccountUpgraded(Tp::PendingOperation*))); 0127 } 0128 } 0129 //end bodge 0130 0131 d->ui->screenNameLineEdit->setFocus(); 0132 } 0133 0134 AddContactDialog::~AddContactDialog() 0135 { 0136 delete d->ui; 0137 delete d; 0138 } 0139 0140 //bodge 0141 void AddContactDialog::_k_onAccountUpgraded(Tp::PendingOperation* op) 0142 { 0143 const Tp::AccountPtr &account = op->property("account").value<Tp::AccountPtr>(); 0144 //pretend the account changed. 0145 //emit that the account properties have changed to invalidate the filter 0146 QMetaObject::invokeMethod(account.data(), "propertyChanged", Q_ARG(QString, QString())); 0147 } 0148 //end bodge 0149 0150 void AddContactDialog::accept() 0151 { 0152 Tp::AccountPtr account = d->ui->accountCombo->currentAccount(); 0153 0154 if (account.isNull()) { 0155 KMessageBox::sorry(this, i18n("No account selected.")); 0156 } else if (account->connection().isNull()) { 0157 KMessageBox::sorry(this, i18n("The requested account has been disconnected " 0158 "and so the contact could not be added.")); 0159 } else if (d->ui->screenNameLineEdit->text().isEmpty()) { 0160 KMessageBox::sorry(this, i18n("You did not specify the name of the contact to add.")); 0161 } else { 0162 QStringList identifiers = QStringList() << d->ui->screenNameLineEdit->text(); 0163 qCDebug(KTP_WIDGETS) << "Requesting contacts for identifiers:" << identifiers; 0164 0165 Tp::PendingContacts *pendingContacts = account->connection()->contactManager()->contactsForIdentifiers(identifiers); 0166 connect(pendingContacts, SIGNAL(finished(Tp::PendingOperation*)), 0167 this, SLOT(_k_onContactsForIdentifiersFinished(Tp::PendingOperation*))); 0168 0169 setInProgress(true); 0170 } 0171 } 0172 0173 void AddContactDialog::closeEvent(QCloseEvent *e) 0174 { 0175 // ignore close event if we are in the middle of an operation 0176 if (!d->acceptInProgress) { 0177 QDialog::closeEvent(e); 0178 } 0179 } 0180 0181 void AddContactDialog::_k_onContactsForIdentifiersFinished(Tp::PendingOperation *op) 0182 { 0183 if (op->isError()) { 0184 qWarning() << "Failed to retrieve a contact for the given identifier" 0185 << op->errorName() << op->errorMessage(); 0186 KMessageBox::sorry(this, i18n("Failed to create new contact.")); 0187 setInProgress(false); 0188 } else { 0189 qCDebug(KTP_WIDGETS) << "Requesting presence subscription"; 0190 0191 Tp::PendingContacts *pc = qobject_cast<Tp::PendingContacts*>(op); 0192 connect(pc->manager()->requestPresenceSubscription(pc->contacts(), d->ui->messageLineEdit->text()), 0193 SIGNAL(finished(Tp::PendingOperation*)), 0194 SLOT(_k_onRequestPresenceSubscriptionFinished(Tp::PendingOperation*))); 0195 } 0196 } 0197 0198 void AddContactDialog::_k_onRequestPresenceSubscriptionFinished(Tp::PendingOperation *op) 0199 { 0200 if (op->isError()) { 0201 qWarning() << "Failed to request presence subscription" 0202 << op->errorName() << op->errorMessage(); 0203 KMessageBox::sorry(this, i18n("Failed to request presence subscription " 0204 "from the requested contact.")); 0205 setInProgress(false); 0206 } else { 0207 QDialog::accept(); 0208 } 0209 } 0210 0211 void AddContactDialog::updateSubscriptionMessageVisibility() 0212 { 0213 Tp::AccountPtr account = d->ui->accountCombo->currentAccount(); 0214 if (account && account->connection()->contactManager()->subscriptionRequestHasMessage()) { 0215 d->ui->messageLineEdit->show(); 0216 d->ui->messageLineLabel->show(); 0217 } else { 0218 d->ui->messageLineEdit->hide(); 0219 d->ui->messageLineLabel->hide(); 0220 } 0221 } 0222 0223 void AddContactDialog::setInProgress(bool inProgress) 0224 { 0225 d->acceptInProgress = inProgress; 0226 layout()->parentWidget()->setEnabled(!inProgress); 0227 d->buttonBox->setEnabled(!inProgress); 0228 } 0229 0230 } //namespace KTp