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(); |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 42 | accountItemDelegate_ = new AccountItemDelegate(); |
| 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 | 43c0823 | 2018-10-31 13:42:09 -0400 | [diff] [blame] | 134 | } |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 135 | |
Isa Nanic | 6e4a39a | 2018-12-04 14:26:02 -0500 | [diff] [blame^] | 136 | void CurrentAccountComboBox::resizeEvent(QResizeEvent* event) |
Andreas Traczyk | 43c0823 | 2018-10-31 13:42:09 -0400 | [diff] [blame] | 137 | { |
Isa Nanic | 6e4a39a | 2018-12-04 14:26:02 -0500 | [diff] [blame^] | 138 | Q_UNUSED(event); |
Andreas Traczyk | 43c0823 | 2018-10-31 13:42:09 -0400 | [diff] [blame] | 139 | setupSettingsButton(); |
| 140 | } |
Andreas Traczyk | fd0d7c0 | 2018-10-30 17:14:06 -0400 | [diff] [blame] | 141 | |
Andreas Traczyk | 43c0823 | 2018-10-31 13:42:09 -0400 | [diff] [blame] | 142 | void |
| 143 | CurrentAccountComboBox::setupSettingsButton() |
| 144 | { |
Isa Nanic | 6e4a39a | 2018-12-04 14:26:02 -0500 | [diff] [blame^] | 145 | gearPoint_.setX(this->width() - gearSize_ - 4 * gearBorder_ + 2); |
| 146 | gearPoint_.setY(this->height() / 2 - gearLabel_.height() / 2 - 2 * gearBorder_ + 4.5); |
Andreas Traczyk | 43c0823 | 2018-10-31 13:42:09 -0400 | [diff] [blame] | 147 | gearLabel_.setGeometry(gearPoint_.x() - 3, gearPoint_.y(), |
| 148 | gearSize_ + 2 * gearBorder_, gearSize_ + 2 * gearBorder_); |
| 149 | gearLabel_.setMargin(gearBorder_); |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 150 | } |
| 151 | |
| 152 | // import account background account pixmap and scale pixmap to fit in label |
| 153 | void |
Isa Nanic | 1c20ef1 | 2018-10-25 11:49:30 -0400 | [diff] [blame] | 154 | CurrentAccountComboBox::importLabelPhoto(int index) |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 155 | { |
Isa Nanic | 1c20ef1 | 2018-10-25 11:49:30 -0400 | [diff] [blame] | 156 | currentAccountAvatarImage_ = accountListModel_->data(accountListModel_->index(index, 0), // [efficiency improvement] |
Isa Nanic | 601de1d | 2018-10-23 11:37:26 -0400 | [diff] [blame] | 157 | AccountListModel::Role::Picture).value<QPixmap>().scaledToHeight(cellHeight_ - 4, Qt::SmoothTransformation); |
Isa Nanic | 1c20ef1 | 2018-10-25 11:49:30 -0400 | [diff] [blame] | 158 | } |
| 159 | |
| 160 | void |
| 161 | CurrentAccountComboBox::setCurrentIndex(int index) |
| 162 | { |
| 163 | importLabelPhoto(index); |
| 164 | QComboBox::setCurrentIndex(index); |
| 165 | } |
| 166 | |
| 167 | void |
| 168 | CurrentAccountComboBox::accountListUpdate() |
| 169 | { |
| 170 | accountListModel_.reset(new AccountListModel()); |
| 171 | this->setModel(accountListModel_.get()); |
| 172 | } |
Isa Nanic | 37ccc1c | 2018-10-26 14:16:28 -0400 | [diff] [blame] | 173 | |
Andreas Traczyk | fd0d7c0 | 2018-10-30 17:14:06 -0400 | [diff] [blame] | 174 | // if gearLabel is clicked |
| 175 | void |
| 176 | CurrentAccountComboBox::mousePressEvent(QMouseEvent* mouseEvent) |
| 177 | { |
| 178 | if (!gearLabel_.frameGeometry().contains(mouseEvent->localPos().toPoint())) { |
| 179 | QComboBox::mousePressEvent(mouseEvent); |
| 180 | } else { |
| 181 | emit settingsButtonClicked(); |
| 182 | } |
| 183 | } |
| 184 | |
| 185 | // if gear label is hovered over |
| 186 | void |
| 187 | CurrentAccountComboBox::mouseMoveEvent(QMouseEvent* mouseEvent) |
| 188 | { |
| 189 | if (gearLabel_.frameGeometry().contains(mouseEvent->x(), mouseEvent->y())) { |
| 190 | QComboBox::mouseMoveEvent(mouseEvent); |
| 191 | gearLabel_.setStyleSheet("background: rgb(237, 237, 237); border-width: 0px; border-radius: 8px;"); |
| 192 | return; |
| 193 | } |
| 194 | |
| 195 | gearLabel_.setStyleSheet("background: transparent;"); |
| 196 | } |
| 197 | |
| 198 | void |
| 199 | CurrentAccountComboBox::showPopup() |
| 200 | { |
Andreas Traczyk | 43c0823 | 2018-10-31 13:42:09 -0400 | [diff] [blame] | 201 | gearLabel_.hide(); |
Andreas Traczyk | fd0d7c0 | 2018-10-30 17:14:06 -0400 | [diff] [blame] | 202 | popupPresent = true; |
| 203 | QComboBox::showPopup(); |
| 204 | } |
| 205 | |
| 206 | void |
| 207 | CurrentAccountComboBox::hidePopup() |
| 208 | { |
Andreas Traczyk | 43c0823 | 2018-10-31 13:42:09 -0400 | [diff] [blame] | 209 | gearLabel_.show(); |
Andreas Traczyk | fd0d7c0 | 2018-10-30 17:14:06 -0400 | [diff] [blame] | 210 | popupPresent = false; |
| 211 | QComboBox::hidePopup(); |
Andreas Traczyk | fd0d7c0 | 2018-10-30 17:14:06 -0400 | [diff] [blame] | 212 | } |
| 213 | |
| 214 | void |
| 215 | CurrentAccountComboBox::leaveEvent(QEvent* event) |
| 216 | { |
| 217 | gearLabel_.setStyleSheet("background: transparent;"); |
| 218 | QComboBox::leaveEvent(event); |
Isa Nanic | 6e4a39a | 2018-12-04 14:26:02 -0500 | [diff] [blame^] | 219 | } |
| 220 | |
| 221 | void |
| 222 | CurrentAccountComboBox::updateComboBoxDisplay() |
| 223 | { |
| 224 | importLabelPhoto(LRCInstance::getCurrentAccountIndex()); |
| 225 | } |