qTox
Version: nightly | Commit: bc751c8e1cac455f9690654fcfe0f560d2d7dfdd
|
Go to the documentation of this file.
51 #include <QApplication>
53 #include <QFileDialog>
55 #include <QMessageBox>
57 #include <QPushButton>
60 #include <QStringBuilder>
73 static constexpr
int CHAT_WIDGET_MIN_HEIGHT = 50;
74 static constexpr
int SCREENSHOT_GRABBER_OPENING_DELAY = 500;
75 static constexpr
int TYPING_NOTIFICATION_DURATION = 3000;
80 QString secondsToDHMS(quint32 duration)
83 QString cD = ChatForm::tr(
"Call duration: ");
84 quint32 seconds = duration % 60;
86 quint32 minutes = duration % 60;
88 quint32 hours = duration % 24;
89 quint32 days = duration / 24;
93 return cD + res.asprintf(
"%dd%02dh %02dm %02ds", days, hours, minutes, seconds);
97 return cD + res.asprintf(
"%02dh %02dm %02ds", hours, minutes, seconds);
101 return cD + res.asprintf(
"%02dm %02ds", minutes, seconds);
104 return cD + res.asprintf(
"%02ds", seconds);
109 :
GenericChatForm(profile.getCore(), chatFriend, chatLog, messageDispatcher)
113 , lastCallIsVideo{
false}
115 setName(f->getDisplayedName());
117 headWidget->setAvatar(QPixmap(
":/img/contact_dark.svg"));
120 statusMessageLabel->setObjectName(
"statusLabel");
123 statusMessageLabel->setTextFormat(Qt::PlainText);
124 statusMessageLabel->setContextMenuPolicy(Qt::CustomContextMenu);
126 typingTimer.setSingleShot(
true);
128 callDurationTimer =
nullptr;
130 chatWidget->setMinimumHeight(CHAT_WIDGET_MIN_HEIGHT);
132 callDuration =
new QLabel();
133 headWidget->addWidget(statusMessageLabel);
134 headWidget->addStretch();
135 headWidget->addWidget(callDuration, 1, Qt::AlignCenter);
136 callDuration->hide();
139 imagePreview->setFixedSize(100, 100);
140 imagePreview->setFlat(
true);
141 imagePreview->setStyleSheet(
"QPushButton { border: 0px }");
142 imagePreview->hide();
145 QPushButton* cancelButton =
new QPushButton(imagePreview);
146 cancelButton->setFixedSize(20, 20);
147 cancelButton->move(QPoint(80, 0));
148 cancelButton->setIcon(cancelIcon);
149 cancelButton->setFlat(
true);
153 contentLayout->insertWidget(3, imagePreview);
155 copyStatusAction = statusMessageMenu.addAction(QString(),
this, SLOT(onCopyStatusMessage()));
157 const CoreFile* coreFile = core.getCoreFile();
166 const CoreAV* av = core.getAv();
182 connect(statusMessageLabel, &CroppingLabel::customContextMenuRequested,
this,
183 [&](
const QPoint& pos) {
184 if (!statusMessageLabel->text().isEmpty()) {
185 QWidget* sender = static_cast<QWidget*>(this->sender());
186 statusMessageMenu.exec(sender->mapToGlobal(pos));
190 connect(&typingTimer, &QTimer::timeout,
this, [&] {
191 core.sendTyping(f->getId(),
false);
197 [=](
const QString& newName) { f->setAlias(newName); });
199 [
this] { onAnswerCallTriggered(lastCallIsVideo); });
208 setAcceptDrops(
true);
222 statusMessageLabel->setToolTip(Qt::convertFromPlainText(newMessage, Qt::WhiteSpaceNormal));
244 QMessageBox::warning(
this, tr(
"Filename contained illegal characters"),
245 tr(
"Illegal characters have been changed to _ \n"
246 "so you can save the file on Windows."));
264 bool isTypingNow = !
msgEdit->toPlainText().isEmpty();
277 QStringList paths = QFileDialog::getOpenFileNames(Q_NULLPTR, tr(
"Send a file"),
278 QDir::homePath(),
nullptr,
nullptr);
280 if (paths.isEmpty()) {
284 for (QString path : paths) {
286 QString fileName = QFileInfo(path).fileName();
287 if (!
file.exists() || !
file.open(QIODevice::ReadOnly)) {
288 QMessageBox::warning(
this, tr(
"Unable to open"),
289 tr(
"qTox wasn't able to open %1").arg(fileName));
294 if (
file.isSequential()) {
295 QMessageBox::critical(
this, tr(
"Bad idea"),
296 tr(
"You're trying to send a sequential file, "
297 "which is not going to work!"));
301 qint64 filesize =
file.size();
308 if (friendId !=
f->
getId()) {
316 systemMessage.
args = {displayedName};
322 uint32_t friendId =
f->
getId();
323 qDebug() <<
"automatic call answer";
325 QMetaObject::invokeMethod(coreav,
"answerCall", Qt::QueuedConnection,
326 Q_ARG(uint32_t, friendId), Q_ARG(
bool, video));
338 if (friendId !=
f->
getId()) {
355 if (friendId !=
f->
getId()) {
384 uint32_t friendId =
f->
getId();
409 uint32_t friendId =
f->
getId();
412 }
else if (av->
startCall(friendId,
false)) {
420 uint32_t friendId =
f->
getId();
426 }
else if (av->
startCall(friendId,
true)) {
477 if (friendId ==
f->
getId()) {
507 qDebug() <<
"creating netcam";
508 uint32_t friendId =
f->
getId();
521 if (ev->mimeData()->hasUrls()) {
522 ev->acceptProposedAction();
528 if (!ev->mimeData()->hasUrls()) {
532 for (
const QUrl& url : ev->mimeData()->urls()) {
533 QFileInfo info(url.path());
534 QFile
file(info.absoluteFilePath());
536 QString urlString = url.toString();
537 if (url.isValid() && !url.isLocalFile()
538 && urlString.length() <
static_cast<int>(tox_max_message_length())) {
544 QString fileName = info.fileName();
545 if (!
file.exists() || !
file.open(QIODevice::ReadOnly)) {
546 info.setFile(url.toLocalFile());
547 file.setFileName(info.absoluteFilePath());
548 if (!
file.exists() || !
file.open(QIODevice::ReadOnly)) {
549 QMessageBox::warning(
this, tr(
"Unable to open"),
550 tr(
"qTox wasn't able to open %1").arg(fileName));
556 if (
file.isSequential()) {
557 QMessageBox::critical(
nullptr, tr(
"Bad idea"),
558 tr(
"You're trying to send a sequential file, "
559 "which is not going to work!"));
578 QTimer::singleShot(SCREENSHOT_GRABBER_OPENING_DELAY,
this, SLOT(
hideFileMenu()));
614 QString filepath = QString(
"%1images%2qTox_Image_%3.png")
616 .arg(QDir::separator())
617 .arg(QDateTime::currentDateTime().toString(
"yyyy-MM-dd HH-mm-ss.zzz"));
618 QFile
file(filepath);
620 if (
file.open(QFile::ReadWrite)) {
622 qint64 filesize =
file.size();
628 coreFile->
sendFile(
f->
getId(), fi.fileName(), fi.filePath(), filesize);
630 QMessageBox::warning(
this,
631 tr(
"Failed to open temporary file",
"Temporary file for screenshot"),
632 tr(
"qTox wasn't able to save the screenshot"));
640 QClipboard* clipboard = QApplication::clipboard();
642 clipboard->setText(text, QClipboard::Clipboard);
653 netcam->updateMuteMicButton(inputMuted);
664 netcam->updateMuteVolButton(outputMuted);
685 QString dhms = secondsToDHMS(
timeElapsed.elapsed() / 1000);
755 QSize minSize =
netcam->getSurfaceMinSize();
static QFont getFont(Font font)
void avInvite(uint32_t friendId, bool video)
Sent when a friend calls us.
void onVideoShow(QSize size)
An abstract source of video frames.
bool isCallVideoEnabled(const Friend *f) const
Handles all qTox internal paths.
virtual void addSystemMessage(const SystemMessage &message)=0
Inserts a system message at the end of the chat.
void avStart(uint32_t friendId, bool video)
Sent when a call we initiated has started.
void setText(const QString &text)
virtual std::pair< DispatchedMessageId, DispatchedMessageId > sendMessage(bool isAction, const QString &content)=0
Sends message to associated chat.
static void unregister(void *owner)
Unregisters all handlers of an owner.
bool isCallOutputMuted(const Friend *f) const
Returns the calls output (speaker) mute state.
bool isCallActive(const Friend *f) const
Checks the call status for a Tox friend.
bool answerCall(uint32_t friendNum, bool video)
static ContentDialogManager * getInstance()
static const QString getImagePath(const QString &filename)
ContentDialog * current()
CoreFile * getCoreFile() const
bool cancelCall(uint32_t friendNum)
VideoSource * getVideoSourceFromCall(int callNumber) const
Get a call's video source.
const CoreAV * getAv() const
bool startCall(uint32_t friendNum, bool video)
Status::Status getStatus() const
This class represents a Tox Public Key, which is a part of Tox ID.
void toggleMuteCallInput(const Friend *f)
Toggles the mute state of the call's input (microphone).
void fileReceiveRequested(ToxFile file)
void friendAvatarChanged(const ToxPk &friendPk, const QPixmap &pixmap)
void fileNameChanged(const ToxPk &friendPk)
SystemMessageType messageType
void sendFile(uint32_t friendId, QString filename, QString filePath, long long filesize)
static void registerHandler(const std::function< void()> &, void *owner)
Register a function to be called when the UI needs to be retranslated.
void screenshotTaken(const QPixmap &pixmap)
QString getDisplayedName() const override
Friend::getDisplayedName Gets the name that should be displayed for a user.
void extensionSupportChanged(ExtensionSet extensions)
static Settings & getInstance()
Returns the singleton instance.
QString getTitle(Status status)
bool isCallStarted(const Friend *f) const
Checks the call status for a Tox friend.
bool isCallInputMuted(const Friend *f) const
Returns the calls input (microphone) mute state.
std::bitset< ExtensionType::max > ExtensionSet
const ToxPk & getPublicKey() const
void fileSendStarted(ToxFile file)
QString getStatusMessage() const
void pasteImage(const QPixmap &pixmap)
void friendTypingChanged(uint32_t friendId, bool isTyping)
void showMessageClicked()
void statusChanged(const ToxPk &friendId, Status::Status status)
void toggleMuteCallOutput(const Friend *f)
Toggles the mute state of the call's output (speaker).
uint32_t getId() const override
bool isOnline(Status status)
Manages the file transfer service of toxcore.
void avEnd(uint32_t friendId, bool error=false)
Sent when a call was ended by the peer.
void sendTyping(uint32_t friendId, bool typing)