File indexing completed on 2023-12-03 05:01:48
0001 /* 0002 Class that auto configures link-local xmpp account 0003 Copyright (C) 2011 Martin Klapetek <martin.klapetek@gmail.com> 0004 Copyright (C) 2012 Daniele E. Domenichelli <daniele.domenichelli@gmail.com> 0005 0006 This library is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU Lesser General Public 0008 License as published by the Free Software Foundation; either 0009 version 2.1 of the License, or (at your option) any later version. 0010 0011 This library is distributed in the hope that it will be useful, 0012 but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0014 Lesser General Public License for more details. 0015 0016 You should have received a copy of the GNU Lesser General Public 0017 License along with this library; if not, write to the Free Software 0018 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 0019 */ 0020 0021 0022 #include "salut-enabler.h" 0023 0024 #include <TelepathyQt/ConnectionManager> 0025 #include <TelepathyQt/ProfileManager> 0026 #include <TelepathyQt/AccountManager> 0027 #include <TelepathyQt/PendingOperation> 0028 #include <TelepathyQt/PendingReady> 0029 #include <TelepathyQt/PendingAccount> 0030 0031 #include <KDebug> 0032 #include <KUser> 0033 #include <KLocalizedString> 0034 0035 #include <QtGui/QFrame> 0036 #include <KTp/global-presence.h> 0037 0038 #include "salut-details-dialog.h" 0039 #include "salut-message-widget.h" 0040 0041 #define TP_PROP_ACCOUNT_ENABLED (QLatin1String("org.freedesktop.Telepathy.Account.Enabled")) 0042 #define TP_PROP_ACCOUNT_SERVICE (QLatin1String("org.freedesktop.Telepathy.Account.Service")) 0043 0044 const QLatin1String salutConnManager("salut"); 0045 const QLatin1String localXmppProtocol("local-xmpp"); 0046 const QLatin1String firstNamePar("first-name"); 0047 const QLatin1String lastNamePar("last-name"); 0048 const QLatin1String nickNamePar("nickname"); 0049 0050 class SalutEnabler::Private 0051 { 0052 public: 0053 Private(SalutEnabler* parent) 0054 : q(parent), 0055 detailsDialog(0), 0056 messageWidget(0) 0057 { 0058 } 0059 0060 SalutEnabler *q; 0061 0062 Tp::ConnectionManagerPtr connectionManager; 0063 Tp::ProfileManagerPtr profileManager; 0064 Tp::AccountManagerPtr accountManager; 0065 Tp::ProfilePtr profile; 0066 QVariantMap values; 0067 SalutDetailsDialog *detailsDialog; 0068 SalutMessageWidget *messageWidget; 0069 QWeakPointer<QFrame> salutMessageFrame; 0070 QString displayName; 0071 KTp::GlobalPresence *globalPresence; 0072 }; 0073 0074 SalutEnabler::SalutEnabler(const Tp::AccountManagerPtr accountManager, QObject *parent) 0075 : QObject(parent), 0076 d(new Private(this)) 0077 { 0078 d->accountManager = accountManager; 0079 0080 d->globalPresence = new KTp::GlobalPresence(this); 0081 d->globalPresence->setAccountManager(accountManager); 0082 0083 d->connectionManager = Tp::ConnectionManager::create(salutConnManager); 0084 connect(d->connectionManager->becomeReady(), 0085 SIGNAL(finished(Tp::PendingOperation*)), 0086 SLOT(onConnectionManagerReady(Tp::PendingOperation*))); 0087 } 0088 0089 SalutEnabler::~SalutEnabler() 0090 { 0091 delete d; 0092 } 0093 0094 void SalutEnabler::onConnectionManagerReady(Tp::PendingOperation* op) 0095 { 0096 if (op->isError()) { 0097 kWarning() << "Creating ConnectionManager failed:" << op->errorName() << op->errorMessage(); 0098 } 0099 0100 if (!d->connectionManager->isValid()) { 0101 kWarning() << "Invalid ConnectionManager"; 0102 } 0103 0104 d->profileManager = Tp::ProfileManager::create(QDBusConnection::sessionBus()); 0105 0106 // FIXME: Until all distros ship correct profile files, we should fake them 0107 connect(d->profileManager->becomeReady(Tp::Features() << Tp::ProfileManager::FeatureFakeProfiles), 0108 SIGNAL(finished(Tp::PendingOperation*)), 0109 SLOT(onProfileManagerReady(Tp::PendingOperation*))); 0110 } 0111 0112 void SalutEnabler::onProfileManagerReady(Tp::PendingOperation* op) 0113 { 0114 if (op->isError()) { 0115 kWarning() << "Creating ProfileManager failed:" << op->errorName() << op->errorMessage(); 0116 } 0117 0118 // Get the protocol's parameters and values. 0119 Tp::ProtocolInfo protocolInfo = d->connectionManager->protocol(localXmppProtocol); 0120 Tp::ProtocolParameterList parameters = protocolInfo.parameters(); 0121 0122 d->profile = d->profileManager->profilesForCM(salutConnManager).first(); 0123 0124 Q_ASSERT(!d->profile.isNull()); 0125 Q_ASSERT(d->profile->isValid()); 0126 Q_ASSERT(d->profile->protocolName() == localXmppProtocol); 0127 if (d->profile.isNull() || !d->profile->isValid() || d->profile->protocolName() != localXmppProtocol) { 0128 kWarning() << "Something went wrong with telepathy salut"; 0129 } 0130 0131 KUser user = KUser(); 0132 QString name = user.property(KUser::FullName).toString(); 0133 QString nick = user.loginName(); 0134 int lastSpacePosition = name.lastIndexOf(QLatin1Char(' ')); 0135 QString lastname = name.mid(lastSpacePosition + 1); 0136 QString firstName = name.left(lastSpacePosition); 0137 0138 d->values.insert(firstNamePar, firstName); 0139 d->values.insert(lastNamePar, lastname); 0140 d->values.insert(nickNamePar, nick); 0141 0142 Q_EMIT userInfoReady(); 0143 } 0144 0145 QFrame* SalutEnabler::frameWidget(QWidget* parent) 0146 { 0147 if (d->salutMessageFrame.isNull()) { 0148 d->salutMessageFrame = new QFrame(parent); 0149 } 0150 d->salutMessageFrame.data()->setMinimumWidth(parent->width()); 0151 d->salutMessageFrame.data()->setFrameShape(QFrame::StyledPanel); 0152 0153 d->messageWidget = new SalutMessageWidget(d->salutMessageFrame.data()); 0154 d->messageWidget->setParams(d->values[firstNamePar].toString(), 0155 d->values[lastNamePar].toString(), 0156 d->values[nickNamePar].toString()); 0157 d->messageWidget->hide(); 0158 0159 QPropertyAnimation *animation = new QPropertyAnimation(d->salutMessageFrame.data(), "minimumHeight", d->messageWidget); 0160 animation->setDuration(150); 0161 animation->setStartValue(0); 0162 animation->setEndValue(d->messageWidget->sizeHint().height()); 0163 animation->start(); 0164 0165 connect(animation, SIGNAL(finished()), 0166 d->messageWidget, SLOT(animatedShow())); 0167 0168 connect(d->messageWidget, SIGNAL(timeout()), 0169 this, SLOT(onUserAccepted())); 0170 0171 connect(d->messageWidget, SIGNAL(configPressed()), 0172 this, SLOT(onUserWantingChanges())); 0173 0174 connect(d->messageWidget, SIGNAL(cancelPressed()), 0175 this, SLOT(onUserCancelled())); 0176 0177 return d->salutMessageFrame.data(); 0178 } 0179 0180 void SalutEnabler::onUserAccepted() 0181 { 0182 // FIXME: In some next version of tp-qt4 there should be a convenience class for this 0183 // https://bugs.freedesktop.org/show_bug.cgi?id=33153 0184 QVariantMap properties; 0185 0186 if (d->accountManager->supportedAccountProperties().contains(TP_PROP_ACCOUNT_SERVICE)) { 0187 properties.insert(TP_PROP_ACCOUNT_SERVICE, d->profile->serviceName()); 0188 } 0189 if (d->accountManager->supportedAccountProperties().contains(TP_PROP_ACCOUNT_ENABLED)) { 0190 properties.insert(TP_PROP_ACCOUNT_ENABLED, true); 0191 } 0192 0193 if (d->displayName.isEmpty()) 0194 { 0195 QString lastname = d->values[lastNamePar].toString(); 0196 QString firstname = d->values[firstNamePar].toString(); 0197 QString nickname = d->values[nickNamePar].toString(); 0198 0199 if (!firstname.isEmpty()) { 0200 d->displayName = firstname; 0201 } 0202 0203 if (!lastname.isEmpty()) { 0204 if (!d->displayName.isEmpty()) { 0205 d->displayName.append(QString::fromLatin1(" %1").arg(lastname)); 0206 } else { 0207 d->displayName = lastname; 0208 } 0209 } 0210 0211 if (!nickname.isEmpty()) { 0212 if (!d->displayName.isEmpty()) { 0213 d->displayName.append(QString::fromLatin1(" (%1)").arg(nickname)); 0214 } else { 0215 d->displayName = nickname; 0216 } 0217 } 0218 if (d->displayName.isEmpty()) { 0219 //FIXME: let the user know that he reached a very strange situation 0220 kWarning() << "All fields are empty"; 0221 } 0222 } 0223 0224 Tp::PendingAccount *pa = d->accountManager->createAccount(d->profile->cmName(), 0225 d->profile->protocolName(), 0226 d->displayName, 0227 d->values, 0228 properties); 0229 0230 connect(pa, 0231 SIGNAL(finished(Tp::PendingOperation*)), 0232 SLOT(onAccountCreated(Tp::PendingOperation*))); 0233 } 0234 0235 void SalutEnabler::onAccountCreated(Tp::PendingOperation* op) 0236 { 0237 kDebug() << "Account created"; 0238 if (op->isError()) { 0239 kWarning() << "Creating Account failed:" << op->errorName() << op->errorMessage(); 0240 } 0241 0242 if (op->isError()) { 0243 Q_EMIT feedbackMessage(i18n("Failed to create account"), 0244 i18n("Possibly not all required fields are valid"), 0245 KMessageWidget::Error); 0246 kWarning() << "Adding Account failed:" << op->errorName() << op->errorMessage(); 0247 return; 0248 } 0249 0250 // Get the PendingAccount. 0251 Tp::PendingAccount *pendingAccount = qobject_cast<Tp::PendingAccount*>(op); 0252 if (!pendingAccount) { 0253 Q_EMIT feedbackMessage(i18n("Something went wrong with Telepathy"), 0254 QString(), 0255 KMessageWidget::Error); 0256 kWarning() << "Method called with wrong type."; 0257 return; 0258 } 0259 0260 pendingAccount->account()->setRequestedPresence(d->globalPresence->requestedPresence()); 0261 pendingAccount->account()->setServiceName(d->profile->serviceName()); 0262 0263 d->salutMessageFrame.data()->deleteLater();; 0264 0265 Q_EMIT done(); 0266 } 0267 0268 void SalutEnabler::onUserWantingChanges() 0269 { 0270 d->detailsDialog = new SalutDetailsDialog(d->profileManager, d->connectionManager, 0); 0271 0272 connect(d->detailsDialog, SIGNAL(dialogAccepted(QString,QVariantMap)), 0273 this, SLOT(onDialogAccepted(QString,QVariantMap))); 0274 0275 connect(d->detailsDialog, SIGNAL(rejected()), 0276 this, SLOT(onUserCancelled())); 0277 0278 connect(d->detailsDialog, SIGNAL(feedbackMessage(QString,QString,KMessageWidget::MessageType)), 0279 this, SIGNAL(feedbackMessage(QString,QString,KMessageWidget::MessageType))); 0280 0281 d->detailsDialog->exec(); 0282 } 0283 0284 void SalutEnabler::onDialogAccepted(const QString &displayName, const QVariantMap &values) 0285 { 0286 kDebug() << values; 0287 d->displayName = displayName; 0288 d->values.insert(firstNamePar, values[firstNamePar].toString()); 0289 d->values.insert(lastNamePar, values[lastNamePar].toString()); 0290 d->values.insert(nickNamePar, values[nickNamePar].toString()); 0291 onUserAccepted(); 0292 } 0293 0294 void SalutEnabler::onUserCancelled() 0295 { 0296 d->messageWidget->animatedHide(); 0297 0298 QPropertyAnimation *animation = new QPropertyAnimation(d->salutMessageFrame.data(), "maximumHeight", d->messageWidget); 0299 animation->setDuration(150); 0300 animation->setStartValue(d->messageWidget->sizeHint().height()); 0301 animation->setEndValue(0); 0302 0303 QTimer::singleShot(300, animation, SLOT(start())); 0304 0305 connect(animation, SIGNAL(finished()), 0306 d->salutMessageFrame.data(), SLOT(deleteLater())); 0307 0308 connect(animation, SIGNAL(finished()), 0309 this, SIGNAL(cancelled())); 0310 }