| 
    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)