File indexing completed on 2023-11-26 04:55:35

0001 /*
0002  * This file is part of telepathy-accounts-kcm
0003  *
0004  * Copyright (C) 2009 Collabora Ltd. <info@collabora.com>
0005  * Copyright (C) 2011 Dominik Schmidt <kde@dominik-schmidt.de>
0006  * Copyright (C) 2011 Thomas Richard <thomas.richard@proan.be>
0007  *
0008  * This library is free software; you can redistribute it and/or
0009  * modify it under the terms of the GNU Lesser General Public
0010  * License as published by the Free Software Foundation; either
0011  * version 2.1 of the License, or (at your option) any later version.
0012  *
0013  * This library is distributed in the hope that it will be useful,
0014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0016  * Lesser General Public License for more details.
0017  *
0018  * You should have received a copy of the GNU Lesser General Public
0019  * License along with this library; if not, write to the Free Software
0020  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
0021  */
0022 
0023 #include "add-account-assistant.h"
0024 
0025 #include <KTp/wallet-utils.h>
0026 #include <KTp/global-presence.h>
0027 
0028 #include "KCMTelepathyAccounts/abstract-account-parameters-widget.h"
0029 #include "KCMTelepathyAccounts/abstract-account-ui.h"
0030 #include "KCMTelepathyAccounts/account-edit-widget.h"
0031 #include "KCMTelepathyAccounts/plugin-manager.h"
0032 #include "KCMTelepathyAccounts/profile-item.h"
0033 #include "KCMTelepathyAccounts/profile-list-model.h"
0034 #include "KCMTelepathyAccounts/profile-select-widget.h"
0035 #include "KCMTelepathyAccounts/simple-profile-select-widget.h"
0036 
0037 #include <KDebug>
0038 #include <KLocale>
0039 #include <KMessageBox>
0040 #include <KPageWidgetItem>
0041 
0042 #include <QtCore/QList>
0043 #include <QtGui/QHBoxLayout>
0044 #include <QtGui/QCheckBox>
0045 
0046 #include <TelepathyQt/PendingReady>
0047 #include <TelepathyQt/PendingAccount>
0048 #include <TelepathyQt/PendingOperation>
0049 
0050 class AddAccountAssistant::Private
0051 {
0052 public:
0053     Private()
0054      : currentProfileItem(0),
0055        profileListModel(0),
0056        profileSelectWidget(0),
0057        simpleProfileSelectWidget(0),
0058        accountEditWidget(0),
0059        pageOne(0),
0060        pageTwo(0),
0061        pageThree(0)
0062     {
0063     }
0064 
0065     Tp::AccountManagerPtr accountManager;
0066     Tp::ConnectionManagerPtr connectionManager;
0067     ProfileItem *currentProfileItem;
0068     ProfileListModel *profileListModel;
0069     ProfileSelectWidget *profileSelectWidget;
0070     SimpleProfileSelectWidget *simpleProfileSelectWidget;
0071     AccountEditWidget *accountEditWidget;
0072     QWidget *pageThreeWidget;
0073     KPageWidgetItem *pageOne;
0074     KPageWidgetItem *pageTwo;
0075     KPageWidgetItem *pageThree;
0076     KTp::GlobalPresence *globalPresence;
0077 };
0078 
0079 AddAccountAssistant::AddAccountAssistant(Tp::AccountManagerPtr accountManager, QWidget *parent)
0080     : KAssistantDialog(parent),
0081     d(new Private)
0082 {
0083     d->accountManager = accountManager;
0084 
0085     d->globalPresence = new KTp::GlobalPresence(this);
0086     d->globalPresence->setAccountManager(accountManager);
0087 
0088     // Set up the pages of the Assistant.
0089     d->profileListModel          = new ProfileListModel(this);
0090     d->profileSelectWidget       = new ProfileSelectWidget(d->profileListModel, this, true);
0091     d->simpleProfileSelectWidget = new SimpleProfileSelectWidget(d->profileListModel, this);
0092     d->pageOne = new KPageWidgetItem(d->simpleProfileSelectWidget);
0093     d->pageTwo = new KPageWidgetItem(d->profileSelectWidget);
0094 
0095     d->pageOne->setHeader(i18n("Step 1: Select an Instant Messaging Network."));
0096     d->pageTwo->setHeader(i18n("Step 1: Select an Instant Messaging Network."));
0097 
0098     setValid(d->pageOne, false);
0099     setValid(d->pageTwo, false);
0100 
0101     connect(d->profileSelectWidget,
0102             SIGNAL(profileSelected(bool)),
0103             SLOT(onProfileSelected(bool)));
0104     connect(d->profileSelectWidget,
0105             SIGNAL(profileChosen()),
0106             SLOT(goToPageThree()));
0107 
0108     connect(d->simpleProfileSelectWidget,
0109             SIGNAL(profileChosen()),
0110             SLOT(goToPageThree()));
0111     connect(d->simpleProfileSelectWidget,
0112             SIGNAL(othersChosen()),
0113             SLOT(goToPageTwo()));
0114 
0115     // we will build the page widget later, but the constructor of
0116     // KPageWidgetItem requires the widget at this point, so...
0117     d->pageThreeWidget = new QWidget(this);
0118     new QHBoxLayout(d->pageThreeWidget);
0119     d->pageThree = new KPageWidgetItem(d->pageThreeWidget);
0120     d->pageThree->setHeader(i18n("Step 2: Fill in the required Parameters."));
0121 
0122     addPage(d->pageOne);
0123     addPage(d->pageTwo);
0124     addPage(d->pageThree);
0125 
0126     setAppropriate(d->pageTwo, false);
0127 
0128     // TODO re-enable the help when we will have one
0129     showButton(KDialog::Help, false);
0130 }
0131 
0132 AddAccountAssistant::~AddAccountAssistant()
0133 {
0134     delete d;
0135 }
0136 
0137 void AddAccountAssistant::goToPageTwo()
0138 {
0139     KAssistantDialog::setAppropriate(d->pageTwo, true);
0140     KAssistantDialog::next();
0141 }
0142 
0143 void AddAccountAssistant::goToPageThree()
0144 {
0145     ProfileItem *selectedItem;
0146 
0147     if (currentPage() == d->pageTwo) {
0148         kDebug() << "Current Page seems to be page two";
0149         selectedItem = d->profileSelectWidget->selectedProfile();
0150     }
0151     else {
0152         kDebug() << "Current Page seems to be page one";
0153         selectedItem = d->simpleProfileSelectWidget->selectedProfile();
0154     }
0155 
0156     // FIXME: untill packages for missing profiles aren't installed this needs to stay here
0157     if (selectedItem != 0) {
0158         // Set up the next page.
0159         if (d->currentProfileItem != selectedItem) {
0160             d->currentProfileItem = selectedItem;
0161 
0162             d->connectionManager = Tp::ConnectionManager::create(selectedItem->cmName());
0163             connect(d->connectionManager->becomeReady(),
0164                     SIGNAL(finished(Tp::PendingOperation*)),
0165                     SLOT(onConnectionManagerReady(Tp::PendingOperation*)));
0166         }
0167         else {
0168             pageThree();
0169         }
0170     }
0171     else {
0172         KMessageBox::error(this, i18n("To connect to this IM network, you need to install additional plugins. Please install the telepathy-haze and telepathy-gabble packages using your package manager."),i18n("Missing Telepathy Connection Manager"));
0173     }
0174 }
0175 
0176 void AddAccountAssistant::next()
0177 {
0178     // the next button is disabled on the first page
0179     // so ::next is called from the second page
0180     // so we go to page three now
0181     goToPageThree();
0182 }
0183 
0184 void AddAccountAssistant::back()
0185 {
0186     // Disable pageTwo once we're going back to pageOne
0187     if (currentPage() == d->pageTwo) {
0188         KAssistantDialog::setAppropriate(d->pageTwo, false);
0189     }
0190 
0191     KAssistantDialog::back();
0192 }
0193 
0194 void AddAccountAssistant::accept()
0195 {
0196     // Check we are being called from page 3.
0197     if (currentPage() != d->pageThree) {
0198         kWarning() << "Called accept() from a non-final page :(.";
0199         return;
0200     }
0201 
0202     // Get the parameter values.
0203     QVariantMap values  = d->accountEditWidget->parametersSet();
0204 
0205     // Check all pages of parameters pass validation.
0206     if (!d->accountEditWidget->validateParameterValues()) {
0207         kDebug() << "A widget failed parameter validation. Not accepting wizard.";
0208         Q_EMIT feedbackMessage(i18n("Failed to create account"),
0209                                d->accountEditWidget->errorMessage(),
0210                                KMessageWidget::Error);
0211         return;
0212     }
0213 
0214     // FIXME: In some next version of tp-qt4 there should be a convenience class for this
0215     // https://bugs.freedesktop.org/show_bug.cgi?id=33153
0216     QVariantMap properties;
0217 
0218     if (d->accountManager->supportedAccountProperties().contains(QLatin1String("org.freedesktop.Telepathy.Account.Service"))) {
0219       properties.insert(QLatin1String("org.freedesktop.Telepathy.Account.Service"), d->currentProfileItem->serviceName());
0220     }
0221     if (d->accountManager->supportedAccountProperties().contains(QLatin1String("org.freedesktop.Telepathy.Account.Enabled"))) {
0222       properties.insert(QLatin1String("org.freedesktop.Telepathy.Account.Enabled"), true);
0223     }
0224 
0225     //remove password values from being sent. These are stored by KWallet instead
0226 
0227     //FIXME: This is a hack for jabber registration, we don't remove passwords - see Telepathy ML thread "Storing passwords in MC and regsitering new accounts"
0228     //http://lists.freedesktop.org/archives/telepathy/2011-September/005747.html
0229     if (!values.contains(QLatin1String("register"))) {
0230         values.remove(QLatin1String("password"));
0231     }
0232 
0233     d->accountEditWidget->updateDisplayName();
0234     Tp::PendingAccount *pa = d->accountManager->createAccount(d->currentProfileItem->cmName(),
0235                                                               d->currentProfileItem->protocolName(),
0236                                                               d->accountEditWidget->displayName(),
0237                                                               values,
0238                                                               properties);
0239 
0240     connect(pa,
0241             SIGNAL(finished(Tp::PendingOperation*)),
0242             SLOT(onAccountCreated(Tp::PendingOperation*)));
0243 }
0244 
0245 void AddAccountAssistant::reject()
0246 {
0247     // Emit a signal to tell the assistant launcher that it was cancelled.
0248     Q_EMIT cancelled();
0249 
0250     // Close the assistant
0251     KAssistantDialog::reject();
0252 }
0253 
0254 void AddAccountAssistant::onAccountCreated(Tp::PendingOperation *op)
0255 {
0256     if (op->isError()) {
0257         Q_EMIT feedbackMessage(i18n("Failed to create account"),
0258                                i18n("Possibly not all required fields are valid"),
0259                                KMessageWidget::Error);
0260         kWarning() << "Adding Account failed:" << op->errorName() << op->errorMessage();
0261         return;
0262     }
0263 
0264     // Get the PendingAccount.
0265     Tp::PendingAccount *pendingAccount = qobject_cast<Tp::PendingAccount*>(op);
0266     if (!pendingAccount) {
0267         Q_EMIT feedbackMessage(i18n("Something went wrong with Telepathy"),
0268                                QString(),
0269                                KMessageWidget::Error);
0270         kWarning() << "Method called with wrong type.";
0271         return;
0272     }
0273 
0274     Tp::AccountPtr account = pendingAccount->account();
0275 
0276     //save password to KWallet if needed
0277     QVariantMap values  = d->accountEditWidget->parametersSet();
0278     if (values.contains(QLatin1String("password"))) {
0279         KTp::WalletUtils::setAccountPassword(account, values[QLatin1String("password")].toString());
0280     }
0281 
0282     if (d->accountEditWidget->connectOnAdd()) {
0283         account->setRequestedPresence(d->globalPresence->requestedPresence());
0284     }
0285     account->setServiceName(d->currentProfileItem->serviceName());
0286     KAssistantDialog::accept();
0287 }
0288 
0289 void AddAccountAssistant::onConnectionManagerReady(Tp::PendingOperation *op)
0290 {
0291     if (op->isError()) {
0292         kWarning() << "Creating ConnectionManager failed:" << op->errorName() << op->errorMessage();
0293     }
0294 
0295     if (!d->connectionManager->isValid()) {
0296         kWarning() << "Invalid ConnectionManager";
0297     }
0298 
0299     pageThree();
0300 }
0301 
0302 void AddAccountAssistant::onProfileSelected(bool value)
0303 {
0304     //if a protocol is selected, enable the next button on the first page
0305     setValid(d->pageTwo, value);
0306 }
0307 
0308 void AddAccountAssistant::pageThree()
0309 {
0310     // Get the protocol's parameters and values.
0311     Tp::ProtocolInfo protocolInfo = d->connectionManager->protocol(d->currentProfileItem->protocolName());
0312     Tp::ProtocolParameterList parameters = protocolInfo.parameters();
0313 
0314     // Add the parameters to the model.
0315     ParameterEditModel *parameterModel = new ParameterEditModel(this);
0316     parameterModel->addItems(parameters, d->currentProfileItem->profile()->parameters());
0317 
0318     // Delete account previous widget if it already existed.
0319     if (d->accountEditWidget) {
0320         d->accountEditWidget->deleteLater();
0321         d->accountEditWidget = 0;
0322     }
0323 
0324     // Set up the account edit widget.
0325     d->accountEditWidget = new AccountEditWidget(d->currentProfileItem->profile(),
0326                                                  QString(),
0327                                                  parameterModel,
0328                                                  doConnectOnAdd,
0329                                                  d->pageThreeWidget);
0330     connect(this,
0331             SIGNAL(feedbackMessage(QString,QString,KMessageWidget::MessageType)),
0332             d->accountEditWidget,
0333             SIGNAL(feedbackMessage(QString,QString,KMessageWidget::MessageType)));
0334     d->pageThreeWidget->layout()->addWidget(d->accountEditWidget);
0335 
0336     KAssistantDialog::next();
0337 }
0338 
0339 #include "add-account-assistant.moc"