Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 1 | /*************************************************************************** |
Sébastien Blin | 68abac9 | 2019-01-02 17:41:31 -0500 | [diff] [blame] | 2 | * Copyright (C) 2019-2019 by Savoir-faire Linux * |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 3 | * Author: Isa Nanic <isa.nanic@savoirfairelinux.com> * |
| 4 | * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com> * |
| 5 | * * |
| 6 | * This program is free software; you can redistribute it and/or modify * |
| 7 | * it under the terms of the GNU General Public License as published by * |
| 8 | * the Free Software Foundation; either version 3 of the License, or * |
| 9 | * (at your option) any later version. * |
| 10 | * * |
| 11 | * This program is distributed in the hope that it will be useful, * |
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * |
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
| 14 | * GNU General Public License for more details. * |
| 15 | * * |
| 16 | * You should have received a copy of the GNU General Public License * |
| 17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. * |
| 18 | **************************************************************************/ |
| 19 | |
| 20 | #include "currentaccountcombobox.h" |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 21 | |
Andreas Traczyk | 46508b5 | 2019-01-04 11:49:24 -0500 | [diff] [blame] | 22 | #include <QPixmap> |
| 23 | #include <QMouseEvent> |
| 24 | |
| 25 | #include "accountitemdelegate.h" |
| 26 | #include "pixbufmanipulator.h" |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 27 | #include "utils.h" |
| 28 | #include "ringthemeutils.h" |
| 29 | #include "lrcinstance.h" |
Andreas Traczyk | 46508b5 | 2019-01-04 11:49:24 -0500 | [diff] [blame] | 30 | #include "mainwindow.h" |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 31 | |
| 32 | #undef REGISTERED |
| 33 | |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 34 | CurrentAccountComboBox::CurrentAccountComboBox(QWidget* parent) |
| 35 | { |
| 36 | Q_UNUSED(parent); |
| 37 | |
Isa Nanic | 37ccc1c | 2018-10-26 14:16:28 -0400 | [diff] [blame] | 38 | setMouseTracking(true); |
| 39 | gearLabel_.setMouseTracking(true); |
| 40 | |
Isa Nanic | 1c20ef1 | 2018-10-25 11:49:30 -0400 | [diff] [blame] | 41 | accountListUpdate(); |
Andreas Traczyk | 6ace34f | 2018-12-14 14:31:23 -0500 | [diff] [blame] | 42 | accountItemDelegate_ = new AccountItemDelegate(this); |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 43 | this->setItemDelegate(accountItemDelegate_); |
| 44 | |
| 45 | // combobox index changed and so must the avatar |
| 46 | connect(this, QOverload<int>::of(&QComboBox::currentIndexChanged), |
| 47 | [=](const int& index) { |
Isa Nanic | 1c20ef1 | 2018-10-25 11:49:30 -0400 | [diff] [blame] | 48 | setCurrentIndex(index); |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 49 | }); |
| 50 | |
| 51 | // account added to combobox |
| 52 | connect(&LRCInstance::accountModel(), |
| 53 | &lrc::api::NewAccountModel::accountAdded, |
| 54 | [this](const std::string& accountId) { |
| 55 | auto accountList = LRCInstance::accountModel().getAccountList(); |
| 56 | auto it = std::find(accountList.begin(), accountList.end(), accountId); |
| 57 | if (it != accountList.end()) { |
| 58 | this->setCurrentIndex(std::distance(accountList.begin(), it)); |
| 59 | } |
| 60 | }); |
Isa Nanic | 37ccc1c | 2018-10-26 14:16:28 -0400 | [diff] [blame] | 61 | |
Isa Nanic | 6e4a39a | 2018-12-04 14:26:02 -0500 | [diff] [blame] | 62 | gearLabel_.setPixmap(QPixmap(":/images/icons/round-settings-24px.svg")); |
Isa Nanic | 37ccc1c | 2018-10-26 14:16:28 -0400 | [diff] [blame] | 63 | gearLabel_.setParent(this); |
| 64 | gearLabel_.setStyleSheet("background: transparent;"); |
Andreas Traczyk | 43c0823 | 2018-10-31 13:42:09 -0400 | [diff] [blame] | 65 | setupSettingsButton(); |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 66 | } |
| 67 | |
| 68 | CurrentAccountComboBox::~CurrentAccountComboBox() |
| 69 | { |
| 70 | delete accountItemDelegate_; |
| 71 | } |
| 72 | |
| 73 | void |
| 74 | CurrentAccountComboBox::paintEvent(QPaintEvent* e) |
| 75 | { |
| 76 | Q_UNUSED(e); |
| 77 | |
Andreas Traczyk | 2965014 | 2019-01-03 20:33:56 -0500 | [diff] [blame] | 78 | QPoint avatarTopLeft(16, 2); |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 79 | QPainter painter(this); |
Isa Nanic | 1c20ef1 | 2018-10-25 11:49:30 -0400 | [diff] [blame] | 80 | painter.setRenderHints((QPainter::Antialiasing | QPainter::TextAntialiasing), true); |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 81 | |
| 82 | QStyleOption opt; |
| 83 | opt.init(this); |
Andreas Traczyk | 43c0823 | 2018-10-31 13:42:09 -0400 | [diff] [blame] | 84 | style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter); |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 85 | |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 86 | // define and set the two fonts |
| 87 | QFont fontPrimary = painter.font(); |
| 88 | QFont fontSecondary = painter.font(); |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 89 | fontPrimary.setWeight(QFont::ExtraLight); |
Andreas Traczyk | 46508b5 | 2019-01-04 11:49:24 -0500 | [diff] [blame] | 90 | auto scalingRatio = MainWindow::instance().getCurrentScalingRatio(); |
| 91 | if (scalingRatio > 1.0) { |
| 92 | fontPrimary.setPointSize(10); |
| 93 | fontSecondary.setPointSize(9); |
| 94 | } else { |
| 95 | fontPrimary.setPointSize(11); |
| 96 | fontSecondary.setPointSize(10); |
| 97 | } |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 98 | |
| 99 | QFontMetrics fontMetricPrimary(fontPrimary); |
| 100 | QFontMetrics fontMetricSecondary(fontSecondary); |
| 101 | |
Andreas Traczyk | 2965014 | 2019-01-03 20:33:56 -0500 | [diff] [blame] | 102 | painter.drawPixmap(avatarTopLeft, currentAccountAvatarImage_); |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 103 | |
| 104 | // fill in presence indicator if account is registered |
| 105 | auto accountStatus = LRCInstance::getCurrentAccountInfo().status; |
| 106 | if (accountStatus == lrc::api::account::Status::REGISTERED) { |
| 107 | // paint the presence indicator circle |
| 108 | QPainterPath outerCircle, innerCircle; |
Andreas Traczyk | 2965014 | 2019-01-03 20:33:56 -0500 | [diff] [blame] | 109 | QPointF presenceCenter(40.0 + avatarTopLeft.x(), 40.0); |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 110 | qreal outerCircleRadius = cellHeight_/6.5; |
Andreas Traczyk | 1c1302c | 2018-12-31 12:28:16 -0500 | [diff] [blame] | 111 | qreal innerCircleRadius = outerCircleRadius * 0.75; |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 112 | outerCircle.addEllipse(presenceCenter, outerCircleRadius, outerCircleRadius); |
| 113 | innerCircle.addEllipse(presenceCenter, innerCircleRadius, innerCircleRadius); |
| 114 | painter.fillPath(outerCircle, Qt::white); |
| 115 | painter.fillPath(innerCircle, RingTheme::presenceGreen_); |
| 116 | } |
| 117 | |
Andreas Traczyk | 2965014 | 2019-01-03 20:33:56 -0500 | [diff] [blame] | 118 | QRect comboBoxRect( |
| 119 | cellHeight_ + avatarTopLeft.x() + 10 + 2, |
| 120 | 6, |
| 121 | this->width() - cellHeight_, |
| 122 | cellHeight_ - 10); // [screen awareness] |
| 123 | |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 124 | // write primary and secondary account identifiers to combobox label |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 125 | QString primaryAccountID = QString::fromStdString(Utils::bestNameForAccount(LRCInstance::getCurrentAccountInfo())); |
Andreas Traczyk | 2965014 | 2019-01-03 20:33:56 -0500 | [diff] [blame] | 126 | painter.setFont(fontPrimary); |
| 127 | painter.setPen(RingTheme::lightBlack_); |
Andreas Traczyk | fd0d7c0 | 2018-10-30 17:14:06 -0400 | [diff] [blame] | 128 | primaryAccountID = fontMetricPrimary.elidedText(primaryAccountID, Qt::ElideRight, |
| 129 | comboBoxRect.width() - elidConst - (popupPresent ? 0 : 2 * gearSize_)); |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 130 | painter.drawText(comboBoxRect, Qt::AlignLeft, primaryAccountID); |
| 131 | |
| 132 | QString secondaryAccountID = QString::fromStdString(Utils::secondBestNameForAccount(LRCInstance::getCurrentAccountInfo())); |
Andreas Traczyk | fd0d7c0 | 2018-10-30 17:14:06 -0400 | [diff] [blame] | 133 | secondaryAccountID = fontMetricSecondary.elidedText(secondaryAccountID, Qt::ElideRight, |
| 134 | comboBoxRect.width() - elidConst - 2 - (popupPresent ? 0 : 2 * gearSize_)); // [screen awareness] |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 135 | |
| 136 | if (secondaryAccountID.length()) { // if secondary accound id exists |
| 137 | painter.setFont(fontSecondary); |
| 138 | painter.setPen(Qt::lightGray); |
| 139 | painter.drawText(comboBoxRect, (Qt::AlignBottom | Qt::AlignLeft), secondaryAccountID); |
| 140 | } |
Andreas Traczyk | 6ace34f | 2018-12-14 14:31:23 -0500 | [diff] [blame] | 141 | |
| 142 | if (QWidget* popupWidget = this->findChild<QFrame*>()) { |
Andreas Traczyk | 2771e2e | 2019-01-08 17:44:33 -0500 | [diff] [blame] | 143 | popupWidget->setStyleSheet("QFrame{border: 0px;border-bottom: 1px solid #f0f0f0;border-right: 1px solid #f0f0f0; }"); |
Andreas Traczyk | 6ace34f | 2018-12-14 14:31:23 -0500 | [diff] [blame] | 144 | } |
Andreas Traczyk | 43c0823 | 2018-10-31 13:42:09 -0400 | [diff] [blame] | 145 | } |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 146 | |
Isa Nanic | 6e4a39a | 2018-12-04 14:26:02 -0500 | [diff] [blame] | 147 | void CurrentAccountComboBox::resizeEvent(QResizeEvent* event) |
Andreas Traczyk | 43c0823 | 2018-10-31 13:42:09 -0400 | [diff] [blame] | 148 | { |
Isa Nanic | 6e4a39a | 2018-12-04 14:26:02 -0500 | [diff] [blame] | 149 | Q_UNUSED(event); |
Andreas Traczyk | 43c0823 | 2018-10-31 13:42:09 -0400 | [diff] [blame] | 150 | setupSettingsButton(); |
| 151 | } |
Andreas Traczyk | fd0d7c0 | 2018-10-30 17:14:06 -0400 | [diff] [blame] | 152 | |
Andreas Traczyk | 43c0823 | 2018-10-31 13:42:09 -0400 | [diff] [blame] | 153 | void |
| 154 | CurrentAccountComboBox::setupSettingsButton() |
| 155 | { |
Andreas Traczyk | 59ba48a | 2019-01-04 16:12:03 -0500 | [diff] [blame] | 156 | gearPoint_.setX(this->width() - gearSize_ - 5 * gearBorder_ - 1); |
Isa Nanic | 6e4a39a | 2018-12-04 14:26:02 -0500 | [diff] [blame] | 157 | gearPoint_.setY(this->height() / 2 - gearLabel_.height() / 2 - 2 * gearBorder_ + 4.5); |
Andreas Traczyk | 59ba48a | 2019-01-04 16:12:03 -0500 | [diff] [blame] | 158 | gearLabel_.setGeometry( |
| 159 | gearPoint_.x(), gearPoint_.y(), |
| 160 | gearSize_ + 2 * gearBorder_, |
| 161 | gearSize_ + 2 * gearBorder_); |
Andreas Traczyk | 43c0823 | 2018-10-31 13:42:09 -0400 | [diff] [blame] | 162 | gearLabel_.setMargin(gearBorder_); |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 163 | } |
| 164 | |
| 165 | // import account background account pixmap and scale pixmap to fit in label |
| 166 | void |
Isa Nanic | 1c20ef1 | 2018-10-25 11:49:30 -0400 | [diff] [blame] | 167 | CurrentAccountComboBox::importLabelPhoto(int index) |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 168 | { |
Isa Nanic | 1c20ef1 | 2018-10-25 11:49:30 -0400 | [diff] [blame] | 169 | currentAccountAvatarImage_ = accountListModel_->data(accountListModel_->index(index, 0), // [efficiency improvement] |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 170 | AccountListModel::Role::Picture).value<QPixmap>().scaledToHeight(cellHeight_ - 4, Qt::SmoothTransformation); |
Isa Nanic | 1c20ef1 | 2018-10-25 11:49:30 -0400 | [diff] [blame] | 171 | } |
| 172 | |
| 173 | void |
| 174 | CurrentAccountComboBox::setCurrentIndex(int index) |
| 175 | { |
Andreas Traczyk | 6ace34f | 2018-12-14 14:31:23 -0500 | [diff] [blame] | 176 | auto accountListSize = LRCInstance::accountModel().getAccountList().size(); |
| 177 | if (index == accountListSize) { |
| 178 | emit newAccountClicked(); |
| 179 | } else if (index < accountListSize) { |
| 180 | importLabelPhoto(index); |
| 181 | QComboBox::setCurrentIndex(index); |
| 182 | } |
Isa Nanic | 1c20ef1 | 2018-10-25 11:49:30 -0400 | [diff] [blame] | 183 | } |
| 184 | |
| 185 | void |
| 186 | CurrentAccountComboBox::accountListUpdate() |
| 187 | { |
| 188 | accountListModel_.reset(new AccountListModel()); |
| 189 | this->setModel(accountListModel_.get()); |
| 190 | } |
Isa Nanic | 37ccc1c | 2018-10-26 14:16:28 -0400 | [diff] [blame] | 191 | |
Andreas Traczyk | fd0d7c0 | 2018-10-30 17:14:06 -0400 | [diff] [blame] | 192 | // if gearLabel is clicked |
| 193 | void |
| 194 | CurrentAccountComboBox::mousePressEvent(QMouseEvent* mouseEvent) |
| 195 | { |
| 196 | if (!gearLabel_.frameGeometry().contains(mouseEvent->localPos().toPoint())) { |
Andreas Traczyk | 6ace34f | 2018-12-14 14:31:23 -0500 | [diff] [blame] | 197 | QComboBox::mousePressEvent(mouseEvent); |
Andreas Traczyk | fd0d7c0 | 2018-10-30 17:14:06 -0400 | [diff] [blame] | 198 | } else { |
| 199 | emit settingsButtonClicked(); |
| 200 | } |
| 201 | } |
| 202 | |
| 203 | // if gear label is hovered over |
| 204 | void |
| 205 | CurrentAccountComboBox::mouseMoveEvent(QMouseEvent* mouseEvent) |
| 206 | { |
| 207 | if (gearLabel_.frameGeometry().contains(mouseEvent->x(), mouseEvent->y())) { |
| 208 | QComboBox::mouseMoveEvent(mouseEvent); |
| 209 | gearLabel_.setStyleSheet("background: rgb(237, 237, 237); border-width: 0px; border-radius: 8px;"); |
| 210 | return; |
| 211 | } |
| 212 | |
| 213 | gearLabel_.setStyleSheet("background: transparent;"); |
| 214 | } |
| 215 | |
| 216 | void |
| 217 | CurrentAccountComboBox::showPopup() |
| 218 | { |
Andreas Traczyk | 43c0823 | 2018-10-31 13:42:09 -0400 | [diff] [blame] | 219 | gearLabel_.hide(); |
Andreas Traczyk | fd0d7c0 | 2018-10-30 17:14:06 -0400 | [diff] [blame] | 220 | popupPresent = true; |
| 221 | QComboBox::showPopup(); |
| 222 | } |
| 223 | |
| 224 | void |
| 225 | CurrentAccountComboBox::hidePopup() |
| 226 | { |
Andreas Traczyk | 43c0823 | 2018-10-31 13:42:09 -0400 | [diff] [blame] | 227 | gearLabel_.show(); |
Andreas Traczyk | fd0d7c0 | 2018-10-30 17:14:06 -0400 | [diff] [blame] | 228 | popupPresent = false; |
| 229 | QComboBox::hidePopup(); |
Andreas Traczyk | fd0d7c0 | 2018-10-30 17:14:06 -0400 | [diff] [blame] | 230 | } |
| 231 | |
| 232 | void |
| 233 | CurrentAccountComboBox::leaveEvent(QEvent* event) |
| 234 | { |
| 235 | gearLabel_.setStyleSheet("background: transparent;"); |
| 236 | QComboBox::leaveEvent(event); |
Isa Nanic | 6e4a39a | 2018-12-04 14:26:02 -0500 | [diff] [blame] | 237 | } |
| 238 | |
| 239 | void |
| 240 | CurrentAccountComboBox::updateComboBoxDisplay() |
| 241 | { |
Andreas Traczyk | 10523bf | 2018-12-31 16:49:03 -0500 | [diff] [blame] | 242 | auto currAccIndex = LRCInstance::getCurrentAccountIndex(); |
| 243 | if (currAccIndex != currentIndex()) |
| 244 | setCurrentIndex(currAccIndex); |
| 245 | importLabelPhoto(currAccIndex); |
Isa Nanic | 6e4a39a | 2018-12-04 14:26:02 -0500 | [diff] [blame] | 246 | } |