Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 1 | /*************************************************************************** |
| 2 | * Copyright (C) 2018 by Savoir-faire Linux * |
| 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" |
| 21 | #include <accountitemdelegate.h> |
| 22 | #include "pixbufmanipulator.h" |
| 23 | |
| 24 | #include "utils.h" |
| 25 | #include "ringthemeutils.h" |
| 26 | #include "lrcinstance.h" |
| 27 | #include <QPixmap> |
| 28 | |
| 29 | #include "callwidget.h" |
| 30 | #include "ui_callwidget.h" |
| 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 | |
Isa Nanic | 37ccc1c | 2018-10-26 14:16:28 -0400 | [diff] [blame] | 78 | QPoint p(12, 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 | |
| 86 | // create box in which to draw avatar and presence indicator |
| 87 | QRect avatarRect(2, 2, cellHeight_, cellHeight_); // [screen awareness] |
Isa Nanic | 1c20ef1 | 2018-10-25 11:49:30 -0400 | [diff] [blame] | 88 | QRect comboBoxRect(cellHeight_ + p.x() + 2, 4, this->width() - cellHeight_ + p.x(), cellHeight_- 10); // [screen awareness] |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 89 | |
| 90 | // define and set the two fonts |
| 91 | QFont fontPrimary = painter.font(); |
| 92 | QFont fontSecondary = painter.font(); |
| 93 | |
| 94 | fontPrimary.setPointSize(11); |
| 95 | fontPrimary.setWeight(QFont::ExtraLight); |
| 96 | fontSecondary.setPointSize(10); |
| 97 | painter.setFont(fontPrimary); |
| 98 | |
| 99 | QFontMetrics fontMetricPrimary(fontPrimary); |
| 100 | QFontMetrics fontMetricSecondary(fontSecondary); |
| 101 | |
| 102 | painter.drawPixmap(p, currentAccountAvatarImage_); |
| 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; |
Isa Nanic | 37ccc1c | 2018-10-26 14:16:28 -0400 | [diff] [blame] | 109 | QPointF presenceCenter(40.0 + p.x(), 40.0); |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 110 | qreal outerCircleRadius = cellHeight_/6.5; |
| 111 | qreal innerCircleRadius = outerCircleRadius - 1; |
| 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 | |
| 118 | // write primary and secondary account identifiers to combobox label |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 119 | QString primaryAccountID = QString::fromStdString(Utils::bestNameForAccount(LRCInstance::getCurrentAccountInfo())); |
| 120 | painter.setPen(Qt::black); |
Andreas Traczyk | fd0d7c0 | 2018-10-30 17:14:06 -0400 | [diff] [blame] | 121 | primaryAccountID = fontMetricPrimary.elidedText(primaryAccountID, Qt::ElideRight, |
| 122 | comboBoxRect.width() - elidConst - (popupPresent ? 0 : 2 * gearSize_)); |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 123 | painter.drawText(comboBoxRect, Qt::AlignLeft, primaryAccountID); |
| 124 | |
| 125 | QString secondaryAccountID = QString::fromStdString(Utils::secondBestNameForAccount(LRCInstance::getCurrentAccountInfo())); |
Andreas Traczyk | fd0d7c0 | 2018-10-30 17:14:06 -0400 | [diff] [blame] | 126 | secondaryAccountID = fontMetricSecondary.elidedText(secondaryAccountID, Qt::ElideRight, |
| 127 | comboBoxRect.width() - elidConst - 2 - (popupPresent ? 0 : 2 * gearSize_)); // [screen awareness] |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 128 | |
| 129 | if (secondaryAccountID.length()) { // if secondary accound id exists |
| 130 | painter.setFont(fontSecondary); |
| 131 | painter.setPen(Qt::lightGray); |
| 132 | painter.drawText(comboBoxRect, (Qt::AlignBottom | Qt::AlignLeft), secondaryAccountID); |
| 133 | } |
Andreas Traczyk | 6ace34f | 2018-12-14 14:31:23 -0500 | [diff] [blame] | 134 | |
| 135 | if (QWidget* popupWidget = this->findChild<QFrame*>()) { |
| 136 | popupWidget->setStyleSheet("QFrame{border: 0px;border-bottom: 1px solid #f0f0f0;}"); |
| 137 | } |
Andreas Traczyk | 43c0823 | 2018-10-31 13:42:09 -0400 | [diff] [blame] | 138 | } |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 139 | |
Isa Nanic | 6e4a39a | 2018-12-04 14:26:02 -0500 | [diff] [blame] | 140 | void CurrentAccountComboBox::resizeEvent(QResizeEvent* event) |
Andreas Traczyk | 43c0823 | 2018-10-31 13:42:09 -0400 | [diff] [blame] | 141 | { |
Isa Nanic | 6e4a39a | 2018-12-04 14:26:02 -0500 | [diff] [blame] | 142 | Q_UNUSED(event); |
Andreas Traczyk | 43c0823 | 2018-10-31 13:42:09 -0400 | [diff] [blame] | 143 | setupSettingsButton(); |
| 144 | } |
Andreas Traczyk | fd0d7c0 | 2018-10-30 17:14:06 -0400 | [diff] [blame] | 145 | |
Andreas Traczyk | 43c0823 | 2018-10-31 13:42:09 -0400 | [diff] [blame] | 146 | void |
| 147 | CurrentAccountComboBox::setupSettingsButton() |
| 148 | { |
Isa Nanic | 6e4a39a | 2018-12-04 14:26:02 -0500 | [diff] [blame] | 149 | gearPoint_.setX(this->width() - gearSize_ - 4 * gearBorder_ + 2); |
| 150 | gearPoint_.setY(this->height() / 2 - gearLabel_.height() / 2 - 2 * gearBorder_ + 4.5); |
Andreas Traczyk | 43c0823 | 2018-10-31 13:42:09 -0400 | [diff] [blame] | 151 | gearLabel_.setGeometry(gearPoint_.x() - 3, gearPoint_.y(), |
| 152 | gearSize_ + 2 * gearBorder_, gearSize_ + 2 * gearBorder_); |
| 153 | gearLabel_.setMargin(gearBorder_); |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 154 | } |
| 155 | |
| 156 | // import account background account pixmap and scale pixmap to fit in label |
| 157 | void |
Isa Nanic | 1c20ef1 | 2018-10-25 11:49:30 -0400 | [diff] [blame] | 158 | CurrentAccountComboBox::importLabelPhoto(int index) |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 159 | { |
Isa Nanic | 1c20ef1 | 2018-10-25 11:49:30 -0400 | [diff] [blame] | 160 | currentAccountAvatarImage_ = accountListModel_->data(accountListModel_->index(index, 0), // [efficiency improvement] |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 161 | AccountListModel::Role::Picture).value<QPixmap>().scaledToHeight(cellHeight_ - 4, Qt::SmoothTransformation); |
Isa Nanic | 1c20ef1 | 2018-10-25 11:49:30 -0400 | [diff] [blame] | 162 | } |
| 163 | |
| 164 | void |
| 165 | CurrentAccountComboBox::setCurrentIndex(int index) |
| 166 | { |
Andreas Traczyk | 6ace34f | 2018-12-14 14:31:23 -0500 | [diff] [blame] | 167 | auto accountListSize = LRCInstance::accountModel().getAccountList().size(); |
| 168 | if (index == accountListSize) { |
| 169 | emit newAccountClicked(); |
| 170 | } else if (index < accountListSize) { |
| 171 | importLabelPhoto(index); |
| 172 | QComboBox::setCurrentIndex(index); |
| 173 | } |
Isa Nanic | 1c20ef1 | 2018-10-25 11:49:30 -0400 | [diff] [blame] | 174 | } |
| 175 | |
| 176 | void |
| 177 | CurrentAccountComboBox::accountListUpdate() |
| 178 | { |
| 179 | accountListModel_.reset(new AccountListModel()); |
| 180 | this->setModel(accountListModel_.get()); |
| 181 | } |
Isa Nanic | 37ccc1c | 2018-10-26 14:16:28 -0400 | [diff] [blame] | 182 | |
Andreas Traczyk | fd0d7c0 | 2018-10-30 17:14:06 -0400 | [diff] [blame] | 183 | // if gearLabel is clicked |
| 184 | void |
| 185 | CurrentAccountComboBox::mousePressEvent(QMouseEvent* mouseEvent) |
| 186 | { |
| 187 | if (!gearLabel_.frameGeometry().contains(mouseEvent->localPos().toPoint())) { |
Andreas Traczyk | 6ace34f | 2018-12-14 14:31:23 -0500 | [diff] [blame] | 188 | QComboBox::mousePressEvent(mouseEvent); |
Andreas Traczyk | fd0d7c0 | 2018-10-30 17:14:06 -0400 | [diff] [blame] | 189 | } else { |
| 190 | emit settingsButtonClicked(); |
| 191 | } |
| 192 | } |
| 193 | |
| 194 | // if gear label is hovered over |
| 195 | void |
| 196 | CurrentAccountComboBox::mouseMoveEvent(QMouseEvent* mouseEvent) |
| 197 | { |
| 198 | if (gearLabel_.frameGeometry().contains(mouseEvent->x(), mouseEvent->y())) { |
| 199 | QComboBox::mouseMoveEvent(mouseEvent); |
| 200 | gearLabel_.setStyleSheet("background: rgb(237, 237, 237); border-width: 0px; border-radius: 8px;"); |
| 201 | return; |
| 202 | } |
| 203 | |
| 204 | gearLabel_.setStyleSheet("background: transparent;"); |
| 205 | } |
| 206 | |
| 207 | void |
| 208 | CurrentAccountComboBox::showPopup() |
| 209 | { |
Andreas Traczyk | 43c0823 | 2018-10-31 13:42:09 -0400 | [diff] [blame] | 210 | gearLabel_.hide(); |
Andreas Traczyk | fd0d7c0 | 2018-10-30 17:14:06 -0400 | [diff] [blame] | 211 | popupPresent = true; |
| 212 | QComboBox::showPopup(); |
| 213 | } |
| 214 | |
| 215 | void |
| 216 | CurrentAccountComboBox::hidePopup() |
| 217 | { |
Andreas Traczyk | 43c0823 | 2018-10-31 13:42:09 -0400 | [diff] [blame] | 218 | gearLabel_.show(); |
Andreas Traczyk | fd0d7c0 | 2018-10-30 17:14:06 -0400 | [diff] [blame] | 219 | popupPresent = false; |
| 220 | QComboBox::hidePopup(); |
Andreas Traczyk | fd0d7c0 | 2018-10-30 17:14:06 -0400 | [diff] [blame] | 221 | } |
| 222 | |
| 223 | void |
| 224 | CurrentAccountComboBox::leaveEvent(QEvent* event) |
| 225 | { |
| 226 | gearLabel_.setStyleSheet("background: transparent;"); |
| 227 | QComboBox::leaveEvent(event); |
Isa Nanic | 6e4a39a | 2018-12-04 14:26:02 -0500 | [diff] [blame] | 228 | } |
| 229 | |
| 230 | void |
| 231 | CurrentAccountComboBox::updateComboBoxDisplay() |
| 232 | { |
| 233 | importLabelPhoto(LRCInstance::getCurrentAccountIndex()); |
| 234 | } |