File indexing completed on 2024-05-19 04:58:06

0001 /*
0002     This file is part of Choqok, the KDE micro-blogging client
0003 
0004     SPDX-FileCopyrightText: 2008-2012 Mehrdad Momeny <mehrdad.momeny@gmail.com>
0005 
0006     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0007 */
0008 
0009 #include "accountswidget.h"
0010 
0011 #include <QAction>
0012 #include <QCheckBox>
0013 #include <QMenu>
0014 
0015 #include <KAboutData>
0016 #include <KMessageBox>
0017 #include <KPluginFactory>
0018 
0019 #include "accountmanager.h"
0020 #include "accountsdebug.h"
0021 #include "addaccountdialog.h"
0022 #include "choqokuiglobal.h"
0023 #include "editaccountwidget.h"
0024 #include "editaccountdialog.h"
0025 #include "microblog.h"
0026 #include "pluginmanager.h"
0027 
0028 K_PLUGIN_FACTORY_WITH_JSON(ChoqokAccountsConfigFactory, "choqok_accountsconfig.json",
0029                            registerPlugin<AccountsWidget>();)
0030 
0031 AccountsWidget::AccountsWidget(QWidget *parent, const QVariantList &args)
0032     : KCModule(parent, args)
0033 {
0034     qCDebug(CHOQOK);
0035     setAttribute(Qt::WA_DeleteOnClose);
0036     setupUi(this);
0037     connect(accountsTable, &QTableWidget::cellDoubleClicked,this, &AccountsWidget::accountsTableCellDoubleClicked);
0038     connect(accountsTable, &QTableWidget::cellClicked,      this, &AccountsWidget::accountsTableCellClicked);
0039     accountsTable->horizontalHeader()->setStretchLastSection(true);
0040     connect(btnUp,     &QPushButton::clicked, this, &AccountsWidget::moveCurrentRowUp);
0041     connect(btnDown,   &QPushButton::clicked, this, &AccountsWidget::moveCurrentRowDown);
0042     connect(btnEdit, SIGNAL(clicked()), this, SLOT(editAccount()));
0043     connect(btnRemove, SIGNAL(clicked()), this, SLOT(removeAccount()));
0044     connect(accountsTable, &QTableWidget::currentItemChanged, this, &AccountsWidget::accountsTablestateChanged);
0045 
0046     connect(Choqok::AccountManager::self(), &Choqok::AccountManager::accountAdded,   this, &AccountsWidget::slotAccountAdded);
0047     connect(Choqok::AccountManager::self(), &Choqok::AccountManager::accountRemoved, this, &AccountsWidget::slotAccountRemoved);
0048 
0049     btnAdd->setMenu(createAddAccountMenu());
0050 //     load();
0051 }
0052 
0053 AccountsWidget::~AccountsWidget()
0054 {
0055     qCDebug(CHOQOK);
0056 }
0057 
0058 void AccountsWidget::addAccount()
0059 {
0060     qCDebug(CHOQOK);
0061     QAction *act = qobject_cast<QAction *>(sender());
0062     if (act) {
0063         QString name = act->data().toString();
0064         Choqok::MicroBlog *blog = qobject_cast<Choqok::MicroBlog *>(Choqok::PluginManager::self()->loadPlugin(name));
0065         if (blog) {
0066             QPointer<AddAccountDialog> d = new AddAccountDialog(
0067                 blog->createEditAccountWidget(nullptr, Choqok::UI::Global::mainWindow()),
0068                 Choqok::UI::Global::mainWindow());
0069             d->setModal(true);
0070             d->exec();
0071         } else {
0072           KMessageBox::error(
0073               this,
0074               i18n("Cannot load the %1 plugin. Please check your installation.",
0075                    name));
0076         }
0077     }
0078 }
0079 
0080 void AccountsWidget::editAccount(QString alias)
0081 {
0082     qCDebug(CHOQOK);
0083     int currentRow = accountsTable->currentRow();
0084     if (alias.isEmpty()) {
0085         alias = accountsTable->item(currentRow, 0)->text();
0086     }
0087 
0088     QPointer<Choqok::Account> currentAccount = Choqok::AccountManager::self()->findAccount(alias);
0089     if (!currentAccount) {
0090       KMessageBox::detailedError(this, i18n("Cannot find the desired account."),
0091                                  Choqok::AccountManager::self()->lastError());
0092       return;
0093     } else {
0094         ChoqokEditAccountWidget *eaw = currentAccount->microblog()->createEditAccountWidget(currentAccount,
0095                                        this);
0096         QPointer<EditAccountDialog> d = new EditAccountDialog(eaw, this);
0097         d->setModal(true);
0098         d->exec();
0099 
0100         emitChanged();
0101 
0102         // Needs for update alias after editing account
0103         accountsTable->setItem(currentRow, 0, new QTableWidgetItem(currentAccount->alias()));
0104     }
0105 }
0106 
0107 void AccountsWidget::removeAccount(QString alias)
0108 {
0109     qCDebug(CHOQOK) << alias;
0110     if (KMessageBox::warningYesNoCancel(this, i18n("Are you sure you want to remove the selected account?"))
0111             == KMessageBox::Yes) {
0112         if (alias.isEmpty()) {
0113             alias = accountsTable->item(accountsTable->currentRow(), 0)->text();
0114         }
0115         if (!Choqok::AccountManager::self()->removeAccount(alias)) {
0116           KMessageBox::detailedError(
0117               this, i18n("Cannot remove the account."),
0118               Choqok::AccountManager::self()->lastError());
0119         }
0120     }
0121 }
0122 
0123 void AccountsWidget::slotAccountAdded(Choqok::Account *account)
0124 {
0125     qCDebug(CHOQOK);
0126     addAccountToTable(account);
0127     emitChanged();
0128 }
0129 
0130 void AccountsWidget::slotAccountRemoved(const QString alias)
0131 {
0132     qCDebug(CHOQOK);
0133     int count = accountsTable->rowCount();
0134     for (int i = 0; i < count; ++i) {
0135         if (accountsTable->item(i, 0)->text() == alias) {
0136             accountsTable->removeRow(i);
0137             emitChanged();
0138             break;
0139         }
0140     }
0141 }
0142 
0143 void AccountsWidget::addAccountToTable(Choqok::Account *account)
0144 {
0145     qCDebug(CHOQOK);
0146     int row = accountsTable->rowCount();
0147     accountsTable->setRowCount(row + 1);
0148 //   accountsTable->insertRow(row);
0149 //     QCheckBox *enable = new QCheckBox ( accountsTable );
0150 //     enable->setChecked ( account->isEnabled() );
0151 //     accountsTable->setCellWidget ( row, 0, enable );
0152     accountsTable->setItem(row, 0, new QTableWidgetItem(account->alias()));
0153     accountsTable->setItem(row, 1, new QTableWidgetItem(QIcon::fromTheme(account->microblog()->pluginIcon()), account->microblog()->serviceName()));
0154     QCheckBox *enabled = new QCheckBox(accountsTable);
0155     enabled->setChecked(account->isEnabled());
0156     accountsTable->setCellWidget(row, 2, enabled);
0157     QCheckBox *readOnly = new QCheckBox(accountsTable);
0158     readOnly->setChecked(account->isReadOnly());
0159     accountsTable->setCellWidget(row, 3, readOnly);
0160     QCheckBox *quick = new QCheckBox(accountsTable);
0161     quick->setChecked(account->showInQuickPost());
0162     accountsTable->setCellWidget(row, 4, quick);
0163     connect(enabled, &QCheckBox::toggled, this, &AccountsWidget::emitChanged);
0164     connect(readOnly, &QCheckBox::toggled, this, &AccountsWidget::emitChanged);
0165     connect(quick, &QCheckBox::toggled, this, &AccountsWidget::emitChanged);
0166 }
0167 
0168 void AccountsWidget::accountsTablestateChanged()
0169 {
0170     qCDebug(CHOQOK);
0171     int current = accountsTable->currentRow();
0172     qCDebug(CHOQOK) << current;
0173     if (current >= 0 && accountsTable->selectedItems().count() > 0) {
0174         btnEdit->setEnabled(true);
0175         btnRemove->setEnabled(true);
0176         btnUp->setEnabled(current != 0);
0177         btnDown->setEnabled(current != accountsTable->rowCount() - 1);
0178     } else {
0179         btnEdit->setEnabled(false);
0180         btnRemove->setEnabled(false);
0181         btnUp->setEnabled(false);
0182         btnDown->setEnabled(false);
0183     }
0184 }
0185 
0186 void AccountsWidget::load()
0187 {
0188     qCDebug(CHOQOK);
0189 
0190     accountsTable->clearContents();
0191     accountsTable->setRowCount(0);
0192 
0193     for (Choqok::Account *ac: Choqok::AccountManager::self()->accounts()) {
0194        addAccountToTable(ac);
0195     }
0196     accountsTable->resizeColumnsToContents();
0197 }
0198 
0199 void AccountsWidget::save()
0200 {
0201     qCDebug(CHOQOK);
0202 
0203     const int rowCount = accountsTable->rowCount();
0204     bool changed;
0205     for (int i = 0; i < rowCount; ++i) {
0206         changed = false;
0207         Choqok::Account *acc = Choqok::AccountManager::self()->findAccount(accountsTable->item(i, 0)->text());
0208         if (!acc) {
0209             continue;
0210         }
0211         if (acc->priority() != (uint)i) {
0212             acc->setPriority((uint)i);
0213             changed = true;
0214         }
0215         QCheckBox *enabled = qobject_cast<QCheckBox *>(accountsTable->cellWidget(i, 2));
0216         if (enabled && acc->isEnabled() != enabled->isChecked()) {
0217             acc->setEnabled(enabled->isChecked());
0218             changed = true;
0219         }
0220         QCheckBox *readOnly = qobject_cast<QCheckBox *>(accountsTable->cellWidget(i, 3));
0221         if (readOnly && acc->isReadOnly() != readOnly->isChecked()) {
0222             acc->setReadOnly(readOnly->isChecked());
0223             changed = true;
0224         }
0225         QCheckBox *showOnQuick = qobject_cast<QCheckBox *>(accountsTable->cellWidget(i, 4));
0226         if (showOnQuick && acc->showInQuickPost() != showOnQuick->isChecked()) {
0227             acc->setShowInQuickPost(showOnQuick->isChecked());
0228             changed = true;
0229         }
0230         if (changed) { //Maybe we should call writeConfig() from setShowInQuickPost(), setReadOnly() and setPriority() -Mehrdad
0231             acc->writeConfig();
0232         }
0233     }
0234 }
0235 
0236 QMenu *AccountsWidget::createAddAccountMenu()
0237 {
0238     mBlogMenu = new QMenu(i18n("Select Micro-Blogging Service"), this);
0239     for (const auto &metaData : Choqok::PluginManager::self()->availablePlugins(QLatin1String("MicroBlogs"))) {
0240         QAction *act = new QAction(mBlogMenu);
0241         act->setText(metaData.name());
0242         act->setIcon(QIcon::fromTheme(metaData.iconName()));
0243         act->setData(metaData.pluginId());
0244         connect(act, &QAction::triggered, this, &AccountsWidget::addAccount);
0245         mBlogMenu->addAction(act);
0246     }
0247     return mBlogMenu;
0248 }
0249 
0250 void AccountsWidget::moveCurrentRowUp()
0251 {
0252     move(true);
0253 }
0254 
0255 void AccountsWidget::moveCurrentRowDown()
0256 {
0257     move(false);
0258 }
0259 
0260 void AccountsWidget::move(bool up)
0261 {
0262     if (accountsTable->selectedItems().count() <= 0) {
0263         return;
0264     }
0265     emitChanged();
0266     const int sourceRow = accountsTable->row(accountsTable->selectedItems().at(0));
0267     bool sourceEnabled = qobject_cast<QCheckBox *>(accountsTable->cellWidget(sourceRow, 2))->isChecked();
0268     bool sourceReadOnly = qobject_cast<QCheckBox *>(accountsTable->cellWidget(sourceRow, 3))->isChecked();
0269     bool sourceQuickPost = qobject_cast<QCheckBox *>(accountsTable->cellWidget(sourceRow, 4))->isChecked();
0270     const int destRow = (up ? sourceRow - 1 : sourceRow + 1);
0271 
0272     if (destRow < 0  || (destRow >= accountsTable->rowCount())) {
0273         return;
0274     }
0275 
0276     bool destEnabled = qobject_cast<QCheckBox *>(accountsTable->cellWidget(destRow, 2))->isChecked();
0277     bool destReadOnly = qobject_cast<QCheckBox *>(accountsTable->cellWidget(destRow, 3))->isChecked();
0278     bool destQuickPost = qobject_cast<QCheckBox *>(accountsTable->cellWidget(destRow, 4))->isChecked();
0279 
0280     // take whole rows
0281     QList<QTableWidgetItem *> sourceItems = takeRow(sourceRow);
0282     QList<QTableWidgetItem *> destItems = takeRow(destRow);
0283 
0284     // set back in reverse order
0285     setRow(sourceRow, destItems);
0286     setRow(destRow, sourceItems);
0287 
0288     // taking whole row doesn't work! so changing value of checkBoxes take place here.
0289     qobject_cast<QCheckBox *>(accountsTable->cellWidget(sourceRow, 2))->setChecked(destEnabled);
0290     qobject_cast<QCheckBox *>(accountsTable->cellWidget(sourceRow, 3))->setChecked(destReadOnly);
0291     qobject_cast<QCheckBox *>(accountsTable->cellWidget(sourceRow, 4))->setChecked(destQuickPost);
0292 
0293     qobject_cast<QCheckBox *>(accountsTable->cellWidget(destRow, 2))->setChecked(sourceEnabled);
0294     qobject_cast<QCheckBox *>(accountsTable->cellWidget(destRow, 3))->setChecked(sourceReadOnly);
0295     qobject_cast<QCheckBox *>(accountsTable->cellWidget(destRow, 4))->setChecked(sourceQuickPost);
0296 
0297     accountsTable->setCurrentCell(destRow, 0);
0298     KMessageBox::information(this, i18n("You need to restart Choqok for the accounts priority changes to take effect."),
0299                              QString(), QLatin1String("ChangeAccountsPriority"));
0300 }
0301 
0302 // takes and returns the whole row
0303 QList<QTableWidgetItem *> AccountsWidget::takeRow(int row)
0304 {
0305     QList<QTableWidgetItem *> rowItems;
0306     for (int col = 0; col < accountsTable->columnCount(); ++col) {
0307         rowItems << accountsTable->takeItem(row, col);
0308     }
0309     return rowItems;
0310 }
0311 
0312 // sets the whole row
0313 void AccountsWidget::setRow(int row, const QList<QTableWidgetItem *> &rowItems)
0314 {
0315     for (int col = 0; col < accountsTable->columnCount(); ++col) {
0316         accountsTable->setItem(row, col, rowItems.at(col));
0317     }
0318 }
0319 
0320 void AccountsWidget::emitChanged()
0321 {
0322     Q_EMIT changed(true);
0323 }
0324 
0325 void AccountsWidget::accountsTableCellDoubleClicked(int row, int column)
0326 {
0327     Q_UNUSED(row);
0328     Q_UNUSED(column);
0329     editAccount();
0330 }
0331 
0332 void AccountsWidget::accountsTableCellClicked(int row, int column)
0333 {
0334     Q_UNUSED(column);
0335     accountsTable->selectRow(row);
0336     accountsTablestateChanged();
0337 }
0338 
0339 #include "accountswidget.moc"
0340 #include "moc_accountswidget.cpp"