File indexing completed on 2023-12-03 05:01:47
0001 /* 0002 * This file is part of telepathy-accounts-kcm 0003 * 0004 * Copyright (C) 2009 Collabora Ltd. <info@collabora.com> 0005 * Copyright (C) 2011 Daniele E. Domenichelli <daniele.domenichelli@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 "kcm-telepathy-accounts.h" 0023 #include "version.h" 0024 0025 #include "ui_main-widget.h" 0026 0027 #include "add-account-assistant.h" 0028 #include "edit-account-dialog.h" 0029 #include "accounts-list-delegate.h" 0030 #include "account-identity-dialog.h" 0031 #include "salut-enabler.h" 0032 0033 #include <QtGui/QLabel> 0034 #include <QtGui/QSortFilterProxyModel> 0035 #include <QtGui/QProgressBar> 0036 #include <QtCore/QPointer> 0037 0038 #include <KPluginFactory> 0039 #include <KIcon> 0040 #include <KLocale> 0041 #include <KMessageBox> 0042 #include <KAboutData> 0043 #include <KMessageWidget> 0044 #include <KPixmapSequenceOverlayPainter> 0045 #include <KDebug> 0046 #include <KPixmapSequence> 0047 #include <KProgressDialog> 0048 0049 #include <KTp/wallet-utils.h> 0050 #include <KTp/Models/accounts-list-model.h> 0051 #include <KTp/logs-importer.h> 0052 #include <KTp/global-presence.h> 0053 0054 #include <TelepathyQt/Account> 0055 #include <TelepathyQt/AccountSet> 0056 #include <TelepathyQt/AccountFactory> 0057 #include <TelepathyQt/PendingOperation> 0058 #include <TelepathyQt/PendingReady> 0059 #include <TelepathyQt/Types> 0060 #include <TelepathyQt/PendingComposite> 0061 #include <TelepathyQt/ConnectionManager> 0062 0063 #include <KTp/Logger/log-manager.h> 0064 0065 K_PLUGIN_FACTORY(KCMTelepathyAccountsFactory, registerPlugin<KCMTelepathyAccounts>();) 0066 K_EXPORT_PLUGIN(KCMTelepathyAccountsFactory("kcm_ktp_accounts", "kcm_ktp_accounts")) 0067 0068 0069 KCMTelepathyAccounts::KCMTelepathyAccounts(QWidget *parent, const QVariantList& args) 0070 : KCModule(KCMTelepathyAccountsFactory::componentData(), parent, args), 0071 m_accountsListModel(new KTp::AccountsListModel(this)), 0072 m_currentModel(0), 0073 m_currentListView(0) 0074 { 0075 //set up component data. 0076 KAboutData *aboutData = new KAboutData(I18N_NOOP("telepathy_accounts"), 0, ki18n("Instant Messaging and VOIP Accounts"), KTP_ACCOUNTS_KCM_VERSION, KLocalizedString(), KAboutData::License_GPL); 0077 0078 aboutData->addAuthor(ki18n("George Goldberg"), ki18n("Developer"),"grundleborg@googlemail.com"); 0079 aboutData->addAuthor(ki18n("David Edmundson"), ki18n("Developer"), "david@davidedmundson.co.uk"); 0080 aboutData->addAuthor(ki18n("Dominik Schmidt"), ki18n("Developer"), "kde@dominik-schmidt.de"); 0081 aboutData->addAuthor(ki18n("Thomas Richard"), ki18n("Developer"), "thomas.richard@proan.be"); 0082 aboutData->addAuthor(ki18n("Florian Reinhard"), ki18n("Developer"), "florian.reinhard@googlemail.com"); 0083 aboutData->addAuthor(ki18n("Daniele E. Domenichelli"), ki18n("Developer"), "daniele.domenichelli@gmail.com"); 0084 aboutData->addAuthor(ki18n("Martin Klapetek"), ki18n("Developer"), "martin.klapetek@gmail.com"); 0085 0086 setAboutData(aboutData); 0087 0088 // The first thing we must do is register Telepathy DBus Types. 0089 Tp::registerTypes(); 0090 0091 // Start setting up the Telepathy AccountManager. 0092 Tp::AccountFactoryPtr accountFactory = Tp::AccountFactory::create(QDBusConnection::sessionBus(), 0093 Tp::Features() << Tp::Account::FeatureCore 0094 << Tp::Account::FeatureAvatar 0095 << Tp::Account::FeatureCapabilities 0096 << Tp::Account::FeatureProtocolInfo 0097 << Tp::Account::FeatureProfile); 0098 0099 m_accountManager = Tp::AccountManager::create(accountFactory); 0100 m_globalPresence = new KTp::GlobalPresence(this); 0101 0102 connect(m_accountManager->becomeReady(), 0103 SIGNAL(finished(Tp::PendingOperation*)), 0104 SLOT(onAccountManagerReady(Tp::PendingOperation*))); 0105 connect(m_accountManager.constData(), 0106 SIGNAL(newAccount(Tp::AccountPtr)), 0107 SLOT(onNewAccountAdded(Tp::AccountPtr))); 0108 0109 // Set up the UI stuff. 0110 m_ui = new Ui::MainWidget; 0111 m_ui->setupUi(this); 0112 m_ui->salutListView->setHidden(true); 0113 m_ui->salutEnableFrame->setHidden(true); 0114 m_ui->salutEnableCheckbox->setIcon(KIcon(QLatin1String("im-local-xmpp"))); 0115 m_ui->salutEnableCheckbox->setIconSize(QSize(32, 32)); 0116 0117 // On the kcm_telepathy_account we filter using "local-xmpp" and not using 0118 // "salut" because in this way we can see on top also local-xmpp accounts 0119 // configured using haze 0120 m_salutFilterModel = new QSortFilterProxyModel(this); 0121 m_salutFilterModel->setSourceModel(m_accountsListModel); 0122 m_salutFilterModel->setFilterRole(KTp::AccountsListModel::ConnectionProtocolNameRole); 0123 m_salutFilterModel->setFilterFixedString(QLatin1String("local-xmpp")); 0124 m_ui->salutListView->setModel(m_salutFilterModel); 0125 0126 m_accountsFilterModel = new QSortFilterProxyModel(this); 0127 m_accountsFilterModel->setSourceModel(m_accountsListModel); 0128 m_accountsFilterModel->setFilterRole(KTp::AccountsListModel::ConnectionProtocolNameRole); 0129 m_accountsFilterModel->setFilterRegExp(QLatin1String("^((?!local-xmpp).)*$")); 0130 m_accountsFilterModel->setSortRole(Qt::DisplayRole); 0131 m_accountsFilterModel->setSortCaseSensitivity(Qt::CaseInsensitive); 0132 m_accountsFilterModel->setDynamicSortFilter(true); 0133 m_accountsFilterModel->sort(0); 0134 m_ui->accountsListView->setModel(m_accountsFilterModel); 0135 0136 m_ui->addAccountButton->setIcon(KIcon(QLatin1String("list-add"))); 0137 m_ui->editAccountButton->setIcon(KIcon(QLatin1String("configure"))); 0138 m_ui->removeAccountButton->setIcon(KIcon(QLatin1String("edit-delete"))); 0139 m_ui->editAccountIdentityButton->setIcon(KIcon(QLatin1String("user-identity"))); 0140 0141 m_salutBusyWheel = new KPixmapSequenceOverlayPainter(this); 0142 m_salutBusyWheel->setSequence(KPixmapSequence(QLatin1String("process-working"), 22)); 0143 m_salutBusyWheel->setWidget(m_ui->salutWidget); 0144 m_salutBusyWheel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); 0145 0146 // parent the delegates to the layout, because KWidgetItemDelegate doesn't like it if the view 0147 // is deleted before the delegate 0148 AccountsListDelegate* accountsDelegate = new AccountsListDelegate(m_ui->accountsListView, layout()); 0149 m_ui->accountsListView->setItemDelegate(accountsDelegate); 0150 0151 AccountsListDelegate* salutDelegate = new AccountsListDelegate(m_ui->salutListView, layout()); 0152 m_ui->salutListView->setItemDelegate(salutDelegate); 0153 0154 int height = salutDelegate->sizeHint(QStyleOptionViewItem(), m_salutFilterModel->index(0,0)).height() + 3*2; 0155 m_ui->salutListView->setMinimumHeight(height); 0156 m_ui->salutListView->setMaximumHeight(height); 0157 m_ui->salutEnableFrame->setMinimumHeight(height); 0158 0159 connect(accountsDelegate, 0160 SIGNAL(itemChecked(QModelIndex,bool)), 0161 SLOT(onAccountEnabledChanged(QModelIndex,bool))); 0162 connect(salutDelegate, 0163 SIGNAL(itemChecked(QModelIndex,bool)), 0164 SLOT(onAccountEnabledChanged(QModelIndex,bool))); 0165 connect(m_ui->addAccountButton, 0166 SIGNAL(clicked()), 0167 SLOT(onAddAccountClicked())); 0168 connect(m_ui->editAccountButton, 0169 SIGNAL(clicked()), 0170 SLOT(onEditAccountClicked())); 0171 connect(m_ui->editAccountIdentityButton, 0172 SIGNAL(clicked()), 0173 SLOT(onEditIdentityClicked())); 0174 connect(m_ui->accountsListView, 0175 SIGNAL(doubleClicked(QModelIndex)), 0176 SLOT(onEditAccountClicked())); 0177 connect(m_ui->salutListView, 0178 SIGNAL(doubleClicked(QModelIndex)), 0179 SLOT(onEditAccountClicked())); 0180 connect(m_ui->removeAccountButton, 0181 SIGNAL(clicked()), 0182 SLOT(onRemoveAccountClicked())); 0183 connect(m_ui->accountsListView->selectionModel(), 0184 SIGNAL(currentChanged(QModelIndex,QModelIndex)), 0185 SLOT(onSelectedItemChanged(QModelIndex,QModelIndex))); 0186 connect(m_ui->salutListView->selectionModel(), 0187 SIGNAL(currentChanged(QModelIndex,QModelIndex)), 0188 SLOT(onSelectedItemChanged(QModelIndex,QModelIndex))); 0189 connect(m_accountsListModel, 0190 SIGNAL(rowsInserted(QModelIndex,int,int)), 0191 SLOT(onModelDataChanged(QModelIndex))); 0192 connect(m_accountsListModel, 0193 SIGNAL(rowsRemoved(QModelIndex,int,int)), 0194 SLOT(onModelDataChanged(QModelIndex))); 0195 connect(m_ui->salutEnableCheckbox, 0196 SIGNAL(toggled(bool)), 0197 SLOT(onSalutEnableButtonToggled(bool))); 0198 connect(m_accountsListModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), 0199 SLOT(onModelDataChanged(QModelIndex))); 0200 0201 // Check if salut is enabled 0202 Tp::ConnectionManagerPtr cm = Tp::ConnectionManager::create(QLatin1String("salut")); 0203 Tp::PendingReady *op = cm->becomeReady(Tp::Features() << Tp::ConnectionManager::FeatureCore); 0204 connect(op, 0205 SIGNAL(finished(Tp::PendingOperation*)), 0206 SLOT(onSalutConnectionManagerReady(Tp::PendingOperation*))); 0207 } 0208 0209 KCMTelepathyAccounts::~KCMTelepathyAccounts() 0210 { 0211 delete m_ui; 0212 } 0213 0214 void KCMTelepathyAccounts::load() 0215 { 0216 // This slot is called whenever the configuration data in this KCM should 0217 // be reloaded from the store. We will not actually do anything here since 0218 // all changes that are made in this KCM are, at the moment, saved 0219 // immediately and cannot be reverted programatically. 0220 return; 0221 } 0222 0223 void KCMTelepathyAccounts::onAccountEnabledChanged(const QModelIndex &index, bool enabled) 0224 { 0225 QVariant value; 0226 if (enabled) { 0227 value = QVariant(Qt::Checked); 0228 } 0229 else { 0230 value = QVariant(Qt::Unchecked); 0231 } 0232 m_accountsListModel->setData(index, value, KTp::AccountsListModel::EnabledRole); 0233 0234 if (enabled) { 0235 // connect the account 0236 Tp::AccountPtr account = index.data(KTp::AccountsListModel::AccountRole).value<Tp::AccountPtr>(); 0237 if (!account.isNull()) { 0238 account->setRequestedPresence(m_globalPresence->requestedPresence()); 0239 } 0240 } 0241 } 0242 0243 void KCMTelepathyAccounts::onAccountManagerReady(Tp::PendingOperation *op) 0244 { 0245 // Check the pending operation completed successfully. 0246 if (op->isError()) { 0247 kDebug() << "becomeReady() failed:" << op->errorName() << op->errorMessage(); 0248 new ErrorOverlay(this, op->errorMessage(), this); 0249 return; 0250 } 0251 0252 m_accountsListModel->setAccountSet(m_accountManager->validAccounts()); 0253 m_globalPresence->setAccountManager(m_accountManager); 0254 0255 } 0256 0257 void KCMTelepathyAccounts::onNewAccountAdded(const Tp::AccountPtr& account) 0258 { 0259 QScopedPointer<KTp::LogsImporter> logsImporter(new KTp::LogsImporter(this)); 0260 if (!logsImporter->hasKopeteLogs(account)) { 0261 kDebug() << "No Kopete logs for" << account->uniqueIdentifier() << "found"; 0262 return; 0263 } 0264 0265 int ret = KMessageBox::questionYesNo(this, 0266 i18n("We have found Kopete logs for this account. Do you want to import the logs to KDE Telepathy?"), 0267 i18n("Import Logs?"), 0268 KGuiItem(i18n("Import Logs"), QLatin1String("document-import")), 0269 KGuiItem(i18n("Close"), QLatin1String("dialog-close"))); 0270 0271 if (ret == KMessageBox::No) { 0272 return; 0273 } 0274 0275 m_importProgressDialog = new KProgressDialog(this); 0276 m_importProgressDialog->setLabelText(i18n("Importing logs...")); 0277 m_importProgressDialog->setAllowCancel(false); 0278 m_importProgressDialog->progressBar()->setMinimum(0); 0279 m_importProgressDialog->progressBar()->setMaximum(0); 0280 m_importProgressDialog->setButtons(KDialog::Close); 0281 m_importProgressDialog->enableButton(KDialog::Close, false); 0282 0283 connect(logsImporter.data(), SIGNAL(logsImported()), SLOT(onLogsImportDone())); 0284 connect(logsImporter.data(), SIGNAL(error(QString)), SLOT(onLogsImportError(QString))); 0285 0286 logsImporter->startLogImport(account); 0287 m_importProgressDialog->exec(); 0288 0289 delete m_importProgressDialog; 0290 } 0291 0292 void KCMTelepathyAccounts::onLogsImportError(const QString &error) 0293 { 0294 KMessageBox::error(this, error, i18n("Kopete Logs Import")); 0295 } 0296 0297 void KCMTelepathyAccounts::onLogsImportDone() 0298 { 0299 if (m_importProgressDialog) { 0300 m_importProgressDialog->close(); 0301 } 0302 0303 KMessageBox::information(this, i18n("Kopete logs successfully imported"), i18n("Kopete Logs Import")); 0304 } 0305 0306 void KCMTelepathyAccounts::onSelectedItemChanged(const QModelIndex ¤t, const QModelIndex &previous) 0307 { 0308 Q_UNUSED(previous); 0309 0310 /* Only change m_currentModel and "Edit Identity" button state when 0311 * "current" is a selected item, not deselected */ 0312 if (current.isValid()) { 0313 m_currentModel = qobject_cast<const QSortFilterProxyModel*>(current.model()); 0314 0315 if (current.data(KTp::AccountsListModel::ConnectionStateRole).toInt() == Tp::ConnectionStatusConnected) { 0316 m_ui->editAccountIdentityButton->setEnabled(true); 0317 } else { 0318 m_ui->editAccountIdentityButton->setEnabled(false); 0319 } 0320 } 0321 0322 if (m_currentModel == m_salutFilterModel) { 0323 m_currentListView = m_ui->salutListView; 0324 m_ui->accountsListView->clearSelection(); 0325 m_ui->accountsListView->setCurrentIndex(QModelIndex()); 0326 } else { 0327 m_currentListView = m_ui->accountsListView; 0328 m_ui->salutListView->clearSelection(); 0329 m_ui->salutListView->setCurrentIndex(QModelIndex()); 0330 } 0331 0332 m_ui->removeAccountButton->setEnabled(m_currentListView->currentIndex().isValid()); 0333 m_ui->editAccountButton->setEnabled(m_currentListView->currentIndex().isValid()); 0334 0335 bool isAccount = (m_currentListView->currentIndex().isValid() || m_ui->salutListView->currentIndex().isValid()); 0336 m_ui->removeAccountButton->setEnabled(isAccount); 0337 m_ui->editAccountButton->setEnabled(isAccount); 0338 } 0339 0340 void KCMTelepathyAccounts::onAddAccountClicked() 0341 { 0342 // Wizard only works if the AccountManager is ready. 0343 if (!m_accountManager->isReady()) { 0344 return; 0345 } 0346 0347 // ...and finally exec it. 0348 AddAccountAssistant assistant(m_accountManager, this); 0349 assistant.exec(); 0350 } 0351 0352 void KCMTelepathyAccounts::onEditAccountClicked() 0353 { 0354 // Editing accounts is only possible if the Account Manager is ready. 0355 if (!m_accountManager->isReady()) { 0356 return; 0357 } 0358 0359 QModelIndex index = m_currentListView->currentIndex(); 0360 if (!index.isValid()) { 0361 return; 0362 } 0363 Tp::AccountPtr account = index.data(KTp::AccountsListModel::AccountRole).value<Tp::AccountPtr>(); 0364 0365 if (account.isNull()) { 0366 return; 0367 } 0368 0369 // Item is OK. Edit the item. 0370 QWeakPointer<EditAccountDialog> dialog = new EditAccountDialog(account, this); 0371 dialog.data()->exec(); 0372 delete dialog.data(); 0373 } 0374 0375 void KCMTelepathyAccounts::onEditIdentityClicked() 0376 { 0377 if (!m_accountManager->isReady()) { 0378 return; 0379 } 0380 0381 QModelIndex index = m_currentListView->currentIndex(); 0382 if (!index.isValid()) { 0383 return; 0384 } 0385 0386 Tp::AccountPtr account = index.data(KTp::AccountsListModel::AccountRole).value<Tp::AccountPtr>(); 0387 0388 if (account.isNull()) { 0389 return; 0390 } 0391 0392 AccountIdentityDialog dialog(account,this); 0393 dialog.exec(); 0394 } 0395 0396 0397 void KCMTelepathyAccounts::onRemoveAccountClicked() 0398 { 0399 QModelIndex index = m_currentListView->currentIndex(); 0400 0401 QString accountName = index.data(Qt::DisplayRole).toString(); 0402 0403 KDialog *dialog = new KDialog(this); /* will be deleted by KMessageBox::createKMessageBox */ 0404 dialog->setButtons(KDialog::Yes | KDialog::Cancel); 0405 dialog->setWindowTitle(i18n("Remove Account")); 0406 dialog->setButtonGuiItem(KDialog::Yes, KGuiItem(i18n("Remove Account"), QLatin1String("edit-delete"))); 0407 bool removeLogs = false; 0408 0409 const QString msg = i18n("Remove conversations logs"); 0410 if (KMessageBox::createKMessageBox(dialog, QMessageBox::Warning, i18n("Are you sure you want to remove the account \"%1\"?", accountName), 0411 QStringList(), msg , &removeLogs, 0412 KMessageBox::Dangerous | KMessageBox::Notify) == KDialog::Yes) { 0413 0414 Tp::AccountPtr account = index.data(KTp::AccountsListModel::AccountRole).value<Tp::AccountPtr>(); 0415 if (account.isNull()) { 0416 return; 0417 } 0418 0419 if (removeLogs) { 0420 KTp::LogManager *logManager = KTp::LogManager::instance(); 0421 logManager->clearAccountLogs(account); 0422 } 0423 0424 QList<Tp::PendingOperation*> ops; 0425 ops.append(KTp::WalletUtils::removeAccountPassword(account)); 0426 ops.append(account->remove()); 0427 connect(new Tp::PendingComposite(ops, account), SIGNAL(finished(Tp::PendingOperation*)), SLOT(onOperationFinished(Tp::PendingOperation*))); 0428 } 0429 } 0430 0431 void KCMTelepathyAccounts::onModelDataChanged(const QModelIndex &index) 0432 { 0433 bool salutEnabled = m_salutFilterModel->rowCount() == 0; 0434 m_ui->salutListView->setHidden(salutEnabled); 0435 m_ui->salutEnableFrame->setHidden(!salutEnabled); 0436 0437 /* When model changes and the change is the currently selected row, update 0438 * state of buttons */ 0439 if (m_currentListView && m_currentModel && (index == m_currentModel->mapToSource(m_currentListView->currentIndex()))) { 0440 onSelectedItemChanged(m_currentListView->currentIndex(), m_currentListView->currentIndex()); 0441 } 0442 } 0443 0444 void KCMTelepathyAccounts::onSalutEnableButtonToggled(bool checked) 0445 { 0446 if (checked) { 0447 if (m_salutEnabler.isNull()) { 0448 m_salutEnabler = new SalutEnabler(m_accountManager, this); 0449 } 0450 0451 connect(m_salutEnabler.data(), SIGNAL(userInfoReady()), 0452 this, SLOT(onSalutInfoReady())); 0453 0454 connect(m_salutEnabler.data(), SIGNAL(cancelled()), 0455 this, SLOT(onSalutSetupDone())); 0456 0457 connect(m_salutEnabler.data(), SIGNAL(done()), 0458 this, SLOT(onSalutSetupDone())); 0459 0460 //FIXME there is no slot to connect feedbackMessage to 0461 // connect(m_salutEnabler, SIGNAL(feedbackMessage(QString,QString,KTitleWidget::MessageType)), 0462 // this, SLOT()); 0463 0464 m_ui->accountsListView->clearSelection(); 0465 m_ui->accountsListView->setCurrentIndex(QModelIndex()); 0466 m_ui->salutListView->clearSelection(); 0467 m_ui->salutListView->setCurrentIndex(QModelIndex()); 0468 } 0469 } 0470 0471 void KCMTelepathyAccounts::onSalutConnectionManagerReady(Tp::PendingOperation* op) 0472 { 0473 bool error = false; 0474 if (op->isError()) { 0475 kWarning() << "Creating salut ConnectionManager failed:" << op->errorName() << op->errorMessage(); 0476 error = true; 0477 } else { 0478 Tp::ConnectionManagerPtr cm = Tp::ConnectionManagerPtr::qObjectCast(qobject_cast<Tp::PendingReady*>(op)->proxy()); 0479 0480 if (!cm->isValid()) { 0481 kWarning() << "Invalid salut ConnectionManager"; 0482 error = true; 0483 } else if (!cm->supportedProtocols().contains(QLatin1String("local-xmpp"))) { 0484 kWarning() << "salut ConnectionManager doesn't support local-xmpp... this is weird"; 0485 error = true; 0486 } 0487 } 0488 0489 // Salut is not installed or has some problem 0490 if (error) { 0491 m_ui->salutEnableFrame->setDisabled(true); 0492 m_ui->salutEnableStatusLabel->setText(i18n("Install telepathy-salut to enable")); 0493 } 0494 } 0495 0496 void KCMTelepathyAccounts::onSalutInfoReady() 0497 { 0498 qobject_cast<QVBoxLayout*>(m_ui->salutEnableFrame->layout())->insertWidget(0, m_salutEnabler.data()->frameWidget(m_ui->salutEnableFrame)); 0499 m_salutBusyWheel->start(); 0500 m_ui->salutWidget->setDisabled(true); 0501 } 0502 0503 void KCMTelepathyAccounts::onSalutSetupDone() 0504 { 0505 m_salutEnabler.data()->deleteLater(); 0506 0507 m_salutBusyWheel->stop(); 0508 m_ui->salutEnableCheckbox->setChecked(false); 0509 m_ui->salutWidget->setEnabled(true); 0510 } 0511 0512 void KCMTelepathyAccounts::onOperationFinished(Tp::PendingOperation *op) 0513 { 0514 if (op->isError()) { 0515 kDebug() << "operation failed " << op->errorName() << op->errorMessage(); 0516 } 0517 } 0518 0519 ///// 0520 0521 ErrorOverlay::ErrorOverlay(QWidget *baseWidget, const QString &details, QWidget *parent) : 0522 QWidget(parent ? parent : baseWidget->window()), 0523 m_BaseWidget(baseWidget) 0524 { 0525 Q_UNUSED(details) 0526 0527 // Build the UI 0528 QVBoxLayout *layout = new QVBoxLayout; 0529 layout->setSpacing(10); 0530 0531 QLabel *pixmap = new QLabel(); 0532 pixmap->setPixmap(KIcon(QLatin1String("dialog-error")).pixmap(64)); 0533 0534 QLabel *message = new QLabel(i18n("Something went terribly wrong and the IM system could not be initialized.\n" 0535 "It is likely your system is missing Telepathy Mission Control package.\n" 0536 "Please install it and restart this module.")); 0537 0538 pixmap->setAlignment(Qt::AlignHCenter); 0539 message->setAlignment(Qt::AlignHCenter); 0540 0541 layout->addStretch(); 0542 layout->addWidget(pixmap); 0543 layout->addWidget(message); 0544 layout->addStretch(); 0545 0546 setLayout(layout); 0547 0548 // Draw the transparent overlay background 0549 QPalette p = palette(); 0550 p.setColor(backgroundRole(), QColor(0, 0, 0, 128)); 0551 p.setColor(foregroundRole(), Qt::white); 0552 setPalette(p); 0553 setAutoFillBackground(true); 0554 0555 m_BaseWidget->installEventFilter(this); 0556 0557 reposition(); 0558 } 0559 0560 ErrorOverlay::~ErrorOverlay() 0561 { 0562 } 0563 0564 void ErrorOverlay::reposition() 0565 { 0566 if (!m_BaseWidget) { 0567 return; 0568 } 0569 0570 // reparent to the current top level widget of the base widget if needed 0571 // needed eg. in dock widgets 0572 if (parentWidget() != m_BaseWidget->window()) { 0573 setParent(m_BaseWidget->window()); 0574 } 0575 0576 // follow base widget visibility 0577 // needed eg. in tab widgets 0578 if (!m_BaseWidget->isVisible()) { 0579 hide(); 0580 return; 0581 } 0582 0583 show(); 0584 0585 // follow position changes 0586 const QPoint topLevelPos = m_BaseWidget->mapTo(window(), QPoint(0, 0)); 0587 const QPoint parentPos = parentWidget()->mapFrom(window(), topLevelPos); 0588 move(parentPos); 0589 0590 // follow size changes 0591 // TODO: hide/scale icon if we don't have enough space 0592 resize(m_BaseWidget->size()); 0593 } 0594 0595 bool ErrorOverlay::eventFilter(QObject * object, QEvent * event) 0596 { 0597 if (object == m_BaseWidget && 0598 (event->type() == QEvent::Move || event->type() == QEvent::Resize || 0599 event->type() == QEvent::Show || event->type() == QEvent::Hide || 0600 event->type() == QEvent::ParentChange)) { 0601 reposition(); 0602 } 0603 return QWidget::eventFilter(object, event); 0604 } 0605 0606 #include "kcm-telepathy-accounts.moc"