qTox  Version: nightly | Commit: bc751c8e1cac455f9690654fcfe0f560d2d7dfdd
chatformheader.cpp
Go to the documentation of this file.
1 /*
2  Copyright © 2017-2019 by The qTox Project Contributors
3 
4  This file is part of qTox, a Qt-based graphical interface for Tox.
5 
6  qTox is libre 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  qTox 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 qTox. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "chatformheader.h"
21 #include "extensionstatus.h"
22 
23 #include "src/model/status.h"
24 
25 #include "src/widget/gui.h"
27 #include "src/widget/style.h"
30 #include "src/widget/translator.h"
31 
32 #include <QDebug>
33 #include <QHBoxLayout>
34 #include <QPushButton>
35 #include <QStyle>
36 #include <QTextDocument>
37 #include <QToolButton>
38 
39 static const QSize AVATAR_SIZE{40, 40};
40 static const short HEAD_LAYOUT_SPACING = 5;
41 static const short MIC_BUTTONS_LAYOUT_SPACING = 4;
42 static const short BUTTONS_LAYOUT_HOR_SPACING = 4;
43 
44 namespace {
45 const QString STYLE_PATH = QStringLiteral("chatForm/buttons.css");
46 
47 const QString STATE_NAME[] = {
48  QString{},
49  QStringLiteral("green"),
50  QStringLiteral("red"),
51  QStringLiteral("yellow"),
52  QStringLiteral("yellow"),
53 };
54 
55 const QString CALL_TOOL_TIP[] = {
56  ChatFormHeader::tr("Can't start audio call"),
57  ChatFormHeader::tr("Start audio call"),
58  ChatFormHeader::tr("End audio call"),
59  ChatFormHeader::tr("Cancel audio call"),
60  ChatFormHeader::tr("Accept audio call"),
61 };
62 
63 const QString VIDEO_TOOL_TIP[] = {
64  ChatFormHeader::tr("Can't start video call"),
65  ChatFormHeader::tr("Start video call"),
66  ChatFormHeader::tr("End video call"),
67  ChatFormHeader::tr("Cancel video call"),
68  ChatFormHeader::tr("Accept video call"),
69 };
70 
71 const QString VOL_TOOL_TIP[] = {
72  ChatFormHeader::tr("Sound can be disabled only during a call"),
73  ChatFormHeader::tr("Mute call"),
74  ChatFormHeader::tr("Unmute call"),
75 };
76 
77 const QString MIC_TOOL_TIP[] = {
78  ChatFormHeader::tr("Microphone can be muted only during a call"),
79  ChatFormHeader::tr("Mute microphone"),
80  ChatFormHeader::tr("Unmute microphone"),
81 };
82 
83 template <class T, class Fun>
84 QPushButton* createButton(const QString& name, T* self, Fun onClickSlot)
85 {
86  QPushButton* btn = new QPushButton();
87  btn->setAttribute(Qt::WA_LayoutUsesWidgetRect);
88  btn->setObjectName(name);
89  btn->setStyleSheet(Style::getStylesheet(STYLE_PATH));
90  QObject::connect(btn, &QPushButton::clicked, self, onClickSlot);
91  return btn;
92 }
93 
94 template<class State>
95 void setStateToolTip(QAbstractButton* btn, State state, const QString toolTip[])
96 {
97  const int index = static_cast<int>(state);
98  btn->setToolTip(toolTip[index]);
99 }
100 
101 template<class State>
102 void setStateName(QAbstractButton* btn, State state)
103 {
104  const int index = static_cast<int>(state);
105  btn->setProperty("state", STATE_NAME[index]);
106  btn->setEnabled(index != 0);
107 }
108 
109 }
110 
112  : QWidget(parent)
113  , mode{Mode::AV}
114  , callState{CallButtonState::Disabled}
115  , videoState{CallButtonState::Disabled}
116  , volState{ToolButtonState::Disabled}
117  , micState{ToolButtonState::Disabled}
118 {
119  QHBoxLayout* headLayout = new QHBoxLayout();
120  avatar = new MaskablePixmapWidget(this, AVATAR_SIZE, ":/img/avatar_mask.svg");
121  avatar->setObjectName("avatar");
122 
123  nameLine = new QHBoxLayout();
124  nameLine->setSpacing(3);
125 
126  extensionStatus = new ExtensionStatus();
127 
128  nameLabel = new CroppingLabel();
129  nameLabel->setObjectName("nameLabel");
130  nameLabel->setMinimumHeight(Style::getFont(Style::Medium).pixelSize());
131  nameLabel->setEditable(true);
132  nameLabel->setTextFormat(Qt::PlainText);
133  connect(nameLabel, &CroppingLabel::editFinished, this, &ChatFormHeader::nameChanged);
134 
135  nameLine->addWidget(extensionStatus);
136  nameLine->addWidget(nameLabel);
137 
138  headTextLayout = new QVBoxLayout();
139  headTextLayout->addStretch();
140  headTextLayout->addLayout(nameLine);
141  headTextLayout->addStretch();
142 
143  micButton = createButton("micButton", this, &ChatFormHeader::micMuteToggle);
144  volButton = createButton("volButton", this, &ChatFormHeader::volMuteToggle);
145  callButton = createButton("callButton", this, &ChatFormHeader::callTriggered);
146  videoButton = createButton("videoButton", this, &ChatFormHeader::videoCallTriggered);
147 
148  QVBoxLayout* micButtonsLayout = new QVBoxLayout();
149  micButtonsLayout->setSpacing(MIC_BUTTONS_LAYOUT_SPACING);
150  micButtonsLayout->addWidget(micButton, Qt::AlignTop | Qt::AlignRight);
151  micButtonsLayout->addWidget(volButton, Qt::AlignTop | Qt::AlignRight);
152 
153  QGridLayout* buttonsLayout = new QGridLayout();
154  buttonsLayout->addLayout(micButtonsLayout, 0, 0, 2, 1, Qt::AlignTop | Qt::AlignRight);
155  buttonsLayout->addWidget(callButton, 0, 1, 2, 1, Qt::AlignTop);
156  buttonsLayout->addWidget(videoButton, 0, 2, 2, 1, Qt::AlignTop);
157  buttonsLayout->setVerticalSpacing(0);
158  buttonsLayout->setHorizontalSpacing(BUTTONS_LAYOUT_HOR_SPACING);
159 
160  headLayout->addWidget(avatar);
161  headLayout->addSpacing(HEAD_LAYOUT_SPACING);
162  headLayout->addLayout(headTextLayout);
163  headLayout->addLayout(buttonsLayout);
164 
165  setLayout(headLayout);
166 
167  updateButtonsView();
169 
171 }
172 
174 
175 void ChatFormHeader::setName(const QString& newName)
176 {
177  nameLabel->setText(newName);
178  // for overlength names
179  nameLabel->setToolTip(Qt::convertFromPlainText(newName, Qt::WhiteSpaceNormal));
180 }
181 
183 {
184  this->mode = mode;
185  if (mode == Mode::None) {
186  callButton->hide();
187  videoButton->hide();
188  volButton->hide();
189  micButton->hide();
190  }
191 }
192 
194 {
195  setStateToolTip(callButton, callState, CALL_TOOL_TIP);
196  setStateToolTip(videoButton, videoState, VIDEO_TOOL_TIP);
197  setStateToolTip(micButton, micState, MIC_TOOL_TIP);
198  setStateToolTip(volButton, volState, VOL_TOOL_TIP);
199 }
200 
202 {
203  setStateName(callButton, callState);
204  setStateName(videoButton, videoState);
205  setStateName(micButton, micState);
206  setStateName(volButton, volState);
207  retranslateUi();
208  Style::repolish(this);
209 }
210 
212 {
213  CallButtonState& state = video ? videoState : callState;
216 }
217 
219 {
220  QWidget* btn = video ? videoButton : callButton;
221  callConfirm = std::unique_ptr<CallConfirmWidget>(new CallConfirmWidget(btn));
224 }
225 
227 {
228  if (callConfirm && !callConfirm->isVisible())
229  callConfirm->show();
230 }
231 
233 {
234  callConfirm.reset(nullptr);
235 }
236 
238 {
240 }
241 
242 void ChatFormHeader::updateCallButtons(bool online, bool audio, bool video)
243 {
244  const bool audioAvaliable = online && (mode & Mode::Audio);
245  const bool videoAvaliable = online && (mode & Mode::Video);
246  if (!audioAvaliable) {
248  } else if (video) {
250  } else if (audio) {
252  } else {
254  }
255 
256  if (!videoAvaliable) {
258  } else if (video) {
260  } else if (audio) {
262  } else {
264  }
265 
267 }
268 
269 void ChatFormHeader::updateMuteMicButton(bool active, bool inputMuted)
270 {
271  micButton->setEnabled(active);
272  if (active) {
274  } else {
276  }
277 
279 }
280 
281 void ChatFormHeader::updateMuteVolButton(bool active, bool outputMuted)
282 {
283  volButton->setEnabled(active);
284  if (active) {
286  } else {
288  }
289 
291 }
292 
293 void ChatFormHeader::setAvatar(const QPixmap &img)
294 {
295  avatar->setPixmap(img);
296 }
297 
299 {
300  return QSize{avatar->width(), avatar->height()};
301 }
302 
304 {
305  setStyleSheet(Style::getStylesheet("chatArea/chatHead.css"));
306  callButton->setStyleSheet(Style::getStylesheet(STYLE_PATH));
307  videoButton->setStyleSheet(Style::getStylesheet(STYLE_PATH));
308  volButton->setStyleSheet(Style::getStylesheet(STYLE_PATH));
309  micButton->setStyleSheet(Style::getStylesheet(STYLE_PATH));
310 }
311 
312 void ChatFormHeader::addWidget(QWidget* widget, int stretch, Qt::Alignment alignment)
313 {
314  headTextLayout->addWidget(widget, stretch, alignment);
315 }
316 
317 void ChatFormHeader::addLayout(QLayout* layout)
318 {
319  headTextLayout->addLayout(layout);
320 }
321 
323 {
324  headTextLayout->addStretch();
325 }
Style::getFont
static QFont getFont(Font font)
Definition: style.cpp:214
ChatFormHeader::videoCallTriggered
void videoCallTriggered()
ChatFormHeader::Mode
Mode
Definition: chatformheader.h:54
CallConfirmWidget
This is a widget with dialog buttons to accept/reject a call.
Definition: callconfirmwidget.h:31
ChatFormHeader::CallButtonState::Disabled
@ Disabled
style.h
ChatFormHeader::volState
ToolButtonState volState
Definition: chatformheader.h:118
CallConfirmWidget::rejected
void rejected()
ChatFormHeader::updateExtensionSupport
void updateExtensionSupport(ExtensionSet extensions)
Definition: chatformheader.cpp:237
extensionstatus.h
ChatFormHeader::nameLabel
CroppingLabel * nameLabel
Definition: chatformheader.h:109
ChatFormHeader::removeCallConfirm
void removeCallConfirm()
Definition: chatformheader.cpp:232
CroppingLabel::editFinished
void editFinished(const QString &newText)
CroppingLabel
Definition: croppinglabel.h:26
ChatFormHeader::showOutgoingCall
void showOutgoingCall(bool video)
Definition: chatformheader.cpp:211
ChatFormHeader::volMuteToggle
void volMuteToggle()
CallConfirmWidget::accepted
void accepted()
ChatFormHeader::ToolButtonState::On
@ On
ChatFormHeader::~ChatFormHeader
~ChatFormHeader()
CroppingLabel::setText
void setText(const QString &text)
Definition: croppinglabel.cpp:81
callconfirmwidget.h
ChatFormHeader::CallButtonState::InCall
@ InCall
MaskablePixmapWidget::setPixmap
void setPixmap(const QPixmap &pmap)
Definition: maskablepixmapwidget.cpp:54
ChatFormHeader::micMuteToggle
void micMuteToggle()
ChatFormHeader::videoState
CallButtonState videoState
Definition: chatformheader.h:117
ChatFormHeader::updateMuteMicButton
void updateMuteMicButton(bool active, bool inputMuted)
Definition: chatformheader.cpp:269
ChatFormHeader::updateMuteVolButton
void updateMuteVolButton(bool active, bool outputMuted)
Definition: chatformheader.cpp:281
ExtensionStatus::onExtensionSetUpdate
void onExtensionSetUpdate(ExtensionSet extensionSet)
Definition: extensionstatus.cpp:31
ChatFormHeader::callRejected
void callRejected()
ChatFormHeader::mode
Mode mode
Definition: chatformheader.h:104
ChatFormHeader::videoButton
QPushButton * videoButton
Definition: chatformheader.h:112
ChatFormHeader::ChatFormHeader
ChatFormHeader(QWidget *parent=nullptr)
Definition: chatformheader.cpp:111
ChatFormHeader::retranslateUi
void retranslateUi()
Definition: chatformheader.cpp:193
ChatFormHeader::volButton
QPushButton * volButton
Definition: chatformheader.h:113
ChatFormHeader::CallButtonState::Avaliable
@ Avaliable
croppinglabel.h
ChatFormHeader::callConfirm
std::unique_ptr< CallConfirmWidget > callConfirm
Definition: chatformheader.h:121
GUI::getInstance
static GUI & getInstance()
Returns the singleton instance.
Definition: gui.cpp:56
ChatFormHeader::callState
CallButtonState callState
Definition: chatformheader.h:116
ChatFormHeader::getAvatarSize
QSize getAvatarSize() const
Definition: chatformheader.cpp:298
ChatFormHeader::CallButtonState
CallButtonState
Definition: chatformheader.h:42
ChatFormHeader::setAvatar
void setAvatar(const QPixmap &img)
Definition: chatformheader.cpp:293
ChatFormHeader::callAccepted
void callAccepted()
MaskablePixmapWidget
Definition: maskablepixmapwidget.h:24
ChatFormHeader::updateCallButtons
void updateCallButtons(bool online, bool audio, bool video=false)
Definition: chatformheader.cpp:242
ChatFormHeader::addStretch
void addStretch()
Definition: chatformheader.cpp:322
ChatFormHeader::addLayout
void addLayout(QLayout *layout)
Definition: chatformheader.cpp:317
ChatFormHeader::extensionStatus
ExtensionStatus * extensionStatus
Definition: chatformheader.h:108
ChatFormHeader::headTextLayout
QVBoxLayout * headTextLayout
Definition: chatformheader.h:106
maskablepixmapwidget.h
GUI::themeReload
void themeReload()
ChatFormHeader::reloadTheme
void reloadTheme()
Definition: chatformheader.cpp:303
Style::repolish
static void repolish(QWidget *w)
Definition: style.cpp:319
ChatFormHeader::createCallConfirm
void createCallConfirm(bool video)
Definition: chatformheader.cpp:218
Translator::registerHandler
static void registerHandler(const std::function< void()> &, void *owner)
Register a function to be called when the UI needs to be retranslated.
Definition: translator.cpp:93
ChatFormHeader::micState
ToolButtonState micState
Definition: chatformheader.h:119
ExtensionSet
std::bitset< ExtensionType::max > ExtensionSet
Definition: extension.h:32
ExtensionStatus
Definition: extensionstatus.h:26
Style::getStylesheet
static const QString getStylesheet(const QString &filename, const QFont &baseFont=QFont())
Definition: style.cpp:165
ChatFormHeader::showCallConfirm
void showCallConfirm()
Definition: chatformheader.cpp:226
ChatFormHeader::callTriggered
void callTriggered()
ChatFormHeader::CallButtonState::Outgoing
@ Outgoing
gui.h
ChatFormHeader::nameChanged
void nameChanged(const QString &name)
ChatFormHeader::setMode
void setMode(Mode mode)
Definition: chatformheader.cpp:182
translator.h
ChatFormHeader::updateButtonsView
void updateButtonsView()
Definition: chatformheader.cpp:201
ChatFormHeader::ToolButtonState::Disabled
@ Disabled
ChatFormHeader::micButton
QPushButton * micButton
Definition: chatformheader.h:114
Style::Medium
@ Medium
Definition: style.h:59
ChatFormHeader::addWidget
void addWidget(QWidget *widget, int stretch=0, Qt::Alignment alignment=Qt::Alignment())
Definition: chatformheader.cpp:312
chatformheader.h
ChatFormHeader::callButton
QPushButton * callButton
Definition: chatformheader.h:111
status.h
ChatFormHeader::avatar
MaskablePixmapWidget * avatar
Definition: chatformheader.h:105
ChatFormHeader::ToolButtonState::Off
@ Off
ChatFormHeader::setName
void setName(const QString &newName)
Definition: chatformheader.cpp:175