diff --git a/src/widgets/misc/accountsoverviewwidget.cpp b/src/widgets/misc/accountsoverviewwidget.cpp index 9d326ca6..07949b18 100644 --- a/src/widgets/misc/accountsoverviewwidget.cpp +++ b/src/widgets/misc/accountsoverviewwidget.cpp @@ -1,236 +1,236 @@ /* * Copyright 2020 Olivier de Gaalon * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License or (at your option) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include "accountsoverviewwidget.h" #include "accountmanager.h" #include "model/rocketchataccountmodel.h" #include "rocketchataccount.h" #include "ruqola.h" #include #include #include #include #include #include #include constexpr const double PAD = 0.2; class AccountButton : public QAbstractButton { struct UnreadAlert { int unread; bool alert; }; public: explicit AccountButton(QWidget *parent = nullptr) : QAbstractButton(parent) , mAccount(nullptr) { connect(Ruqola::self()->accountManager(), &AccountManager::currentAccountChanged, this, QOverload<>::of(&AccountButton::update)); setMouseTracking(true); setFocusPolicy(Qt::NoFocus); setAttribute(Qt::WA_Hover); } void setAccount(RocketChatAccount *acct) { if (mAccount) { mAccount->disconnect(this); mAccount->roomModel()->disconnect(this); this->disconnect(acct); } mAccount = acct; if (mAccount) { auto updateFont = [this] { QFont f = font(); f.setBold(currentUnreadAlert().alert); setFont(f); updateGeometry(); }; connect(acct, &RocketChatAccount::accountNameChanged, this, &AccountButton::updateGeometry); connect(acct, &RocketChatAccount::loginStatusChanged, this, &AccountButton::updateGeometry); connect(acct, &RocketChatAccount::loginStatusChanged, this, &AccountButton::updateTooltip); connect(acct->roomModel(), &RoomModel::needToUpdateNotification, this, updateFont); connect(this, &AccountButton::clicked, acct, [acct] { Ruqola::self()->accountManager()->setCurrentAccount(acct->accountName()); }); updateFont(); } update(); } QSize sizeHint() const override { const auto mngr = Ruqola::self()->accountManager(); const bool singleAccount = mngr->rocketChatAccountModel()->rowCount() == 1; const double height = fontMetrics().height(); const double padding = singleAccount ? 0 : height * PAD; const QSize textSize = fontMetrics().size(Qt::TextSingleLine, currentText()); return QSize(textSize.width() + padding * 2, height + padding * 2); } protected: void enterEvent(QEvent *event) override { if (isEnabled()) { update(); } QAbstractButton::enterEvent(event); } void leaveEvent(QEvent *event) override { if (isEnabled()) { update(); } QAbstractButton::leaveEvent(event); } void paintEvent(QPaintEvent *) override { if (!mAccount) { return; } QPainter p(this); const auto mngr = Ruqola::self()->accountManager(); if (mngr->rocketChatAccountModel()->rowCount() > 1) { const bool isCurrent = mngr->currentAccount() == mAccount->accountName(); QStyleOption opt; opt.init(this); if (isDown() || isCurrent) { opt.state |= QStyle::State_Sunken; } style()->drawPrimitive(QStyle::PE_PanelButtonTool, &opt, &p, this); } p.setPen(palette().color(QPalette::WindowText)); p.setFont(font()); p.drawText(rect(), Qt::AlignCenter, currentText()); } private: Q_REQUIRED_RESULT QString currentText() const { QString text = mAccount ? mAccount->accountName() : QString(); if (text.isEmpty()) { text = i18n("(Unnamed)"); } if (mAccount) { if (mAccount->loginStatus() != DDPAuthenticationManager::LoggedIn) { text += QStringLiteral(": %1").arg(currentLoginStatusText()); } else if (int unread = currentUnreadAlert().unread) { text += QStringLiteral(" (%1)").arg(unread); } } return text; } Q_REQUIRED_RESULT UnreadAlert currentUnreadAlert() const { UnreadAlert ua = {0, false}; mAccount->roomModel()->getUnreadAlertFromAccount(ua.alert, ua.unread); return ua; } Q_REQUIRED_RESULT QString currentLoginStatusText() const { if (mAccount) { if (!mAccount->ddp()->isConnected()) { return i18n("Not connected"); } switch (mAccount->loginStatus()) { case DDPAuthenticationManager::LoginOtpAuthOngoing: return i18n("Login OTP code required"); case DDPAuthenticationManager::LoginFailedInvalidUserOrPassword: return i18n("Login failed: invalid username or password"); case DDPAuthenticationManager::LoginOngoing: return i18n("Logging in"); case DDPAuthenticationManager::LoggedIn: return i18n("Logged in"); case DDPAuthenticationManager::LoggedOut: return i18n("Logged out"); case DDPAuthenticationManager::FailedToLoginPluginProblem: return i18n("Failed to login due to plugin problem"); case DDPAuthenticationManager::GenericError: return i18n("Login failed: generic error"); case DDPAuthenticationManager::LoginOtpRequired: case DDPAuthenticationManager::LoginFailedInvalidOtp: case DDPAuthenticationManager::LogoutOngoing: case DDPAuthenticationManager::LogoutCleanUpOngoing: case DDPAuthenticationManager::LoggedOutAndCleanedUp: break; } } return i18n("Unknown state"); } void updateTooltip() { setToolTip(currentLoginStatusText()); } QPointer mAccount; }; AccountsOverviewWidget::AccountsOverviewWidget(QWidget *parent) : QWidget(parent) { setLayout(new QHBoxLayout); const auto model = Ruqola::self()->accountManager()->rocketChatAccountModel(); connect(model, &RocketChatAccountModel::accountNumberChanged, this, &AccountsOverviewWidget::updateButtons); updateButtons(); } void AccountsOverviewWidget::updateButtons() { const auto model = Ruqola::self()->accountManager()->rocketChatAccountModel(); const auto count = model->rowCount(); for (int i = 0; i < count; ++i) { RocketChatAccount *account = model->account(i); if (i >= mAccounts.size()) { auto *button = new AccountButton(this); mAccounts.append(button); layout()->addWidget(mAccounts.last()); } mAccounts[i]->setVisible(account->accountEnabled()); mAccounts[i]->setAccount(model->account(i)); } - for (int i = count; i < mAccounts.size(); ++i) { + for (int i = count, total = mAccounts.size(); i < total; ++i) { mAccounts[i]->deleteLater(); } mAccounts.resize(count); }