1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00
qTox/widget/widget.cpp

719 lines
24 KiB
C++
Raw Normal View History

2014-07-07 00:19:45 +08:00
/*
Copyright (C) 2014 by Project Tox <https://tox.im>
This file is part of qTox, a Qt-based graphical interface for Tox.
This program is libre software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the COPYING file for more details.
*/
2014-06-25 04:11:11 +08:00
#include "widget.h"
#include "ui_mainwindow.h"
2014-09-11 21:44:34 +08:00
#include "core.h"
2014-09-30 02:28:59 +08:00
#include "misc/settings.h"
2014-06-25 04:11:11 +08:00
#include "friend.h"
#include "friendlist.h"
#include "widget/tool/friendrequestdialog.h"
#include "widget/friendwidget.h"
2014-06-25 04:11:11 +08:00
#include "grouplist.h"
#include "group.h"
#include "widget/groupwidget.h"
#include "widget/form/groupchatform.h"
2014-09-30 02:28:59 +08:00
#include "misc/style.h"
2014-09-11 21:44:34 +08:00
#include "widget/friendlistwidget.h"
#include "camera.h"
#include "widget/form/chatform.h"
#include "widget/maskablepixmapwidget.h"
2014-06-25 04:11:11 +08:00
#include <QMessageBox>
#include <QDebug>
#include <QFile>
#include <QString>
2014-09-24 22:51:16 +08:00
#include <QBuffer>
#include <QPainter>
#include <QMouseEvent>
#include <QClipboard>
2014-09-11 21:44:34 +08:00
#include <QThread>
2014-09-24 22:51:16 +08:00
#include <QFileDialog>
2014-09-11 21:44:34 +08:00
#include <tox/tox.h>
2014-06-25 04:11:11 +08:00
Widget *Widget::instance{nullptr};
Widget::Widget(QWidget *parent)
: QMainWindow(parent),
ui(new Ui::MainWindow),
activeChatroomWidget{nullptr}
2014-06-25 04:11:11 +08:00
{
ui->setupUi(this);
ui->statusbar->hide();
ui->menubar->hide();
//restore window state
restoreGeometry(Settings::getInstance().getWindowGeometry());
restoreState(Settings::getInstance().getWindowState());
2014-08-11 20:07:27 +08:00
ui->mainSplitter->restoreState(Settings::getInstance().getSplitterState());
layout()->setContentsMargins(0, 0, 0, 0);
ui->friendList->setStyleSheet(Style::getStylesheet(":ui/friendList/friendList.css"));
profilePicture = new MaskablePixmapWidget(this, QSize(40,40), ":/img/avatar_mask.png");
profilePicture->setPixmap(QPixmap(":/img/contact_dark.png"));
2014-09-28 01:13:46 +08:00
profilePicture->setClickable(true);
ui->horizontalLayout_3->insertWidget(0,profilePicture);
ui->horizontalLayout_3->insertSpacing(1, 7);
2014-06-25 04:11:11 +08:00
ui->mainContent->setLayout(new QVBoxLayout());
ui->mainHead->setLayout(new QVBoxLayout());
2014-06-26 04:43:28 +08:00
ui->mainHead->layout()->setMargin(0);
ui->mainHead->layout()->setSpacing(0);
2014-08-22 23:19:16 +08:00
contactListWidget = new FriendListWidget();
ui->friendList->setWidget(contactListWidget);
2014-08-12 01:46:14 +08:00
ui->friendList->setLayoutDirection(Qt::RightToLeft);
2014-06-25 04:11:11 +08:00
ui->nameLabel->setEditable(true);
ui->statusLabel->setEditable(true);
2014-10-04 16:24:20 +08:00
ui->statusPanel->setStyleSheet(Style::getStylesheet(":/ui/window/statusPanel.css"));
2014-07-06 04:54:27 +08:00
QMenu *statusButtonMenu = new QMenu(ui->statusButton);
2014-08-29 17:56:42 +08:00
QAction* setStatusOnline = statusButtonMenu->addAction(Widget::tr("Online","Button to set your status to 'Online'"));
2014-07-06 04:54:27 +08:00
setStatusOnline->setIcon(QIcon(":ui/statusButton/dot_online.png"));
2014-08-29 17:56:42 +08:00
QAction* setStatusAway = statusButtonMenu->addAction(Widget::tr("Away","Button to set your status to 'Away'"));
2014-07-06 04:54:27 +08:00
setStatusAway->setIcon(QIcon(":ui/statusButton/dot_idle.png"));
2014-08-29 17:56:42 +08:00
QAction* setStatusBusy = statusButtonMenu->addAction(Widget::tr("Busy","Button to set your status to 'Busy'"));
2014-07-06 04:54:27 +08:00
setStatusBusy->setIcon(QIcon(":ui/statusButton/dot_busy.png"));
ui->statusButton->setMenu(statusButtonMenu);
// disable proportional scaling
2014-08-11 20:07:27 +08:00
ui->mainSplitter->setStretchFactor(0,0);
ui->mainSplitter->setStretchFactor(1,1);
2014-06-25 04:11:11 +08:00
2014-10-04 16:24:20 +08:00
ui->statusButton->setProperty("status", "offline");
Style::repolish(ui->statusButton);
2014-07-06 21:51:24 +08:00
2014-10-08 20:25:32 +08:00
settingsWidget = new SettingsWidget();
2014-06-30 05:38:48 +08:00
// Disable some widgets until we're connected to the DHT
ui->statusButton->setEnabled(false);
2014-06-25 04:11:11 +08:00
qRegisterMetaType<Status>("Status");
2014-07-12 16:54:52 +08:00
qRegisterMetaType<vpx_image>("vpx_image");
2014-06-25 04:11:11 +08:00
qRegisterMetaType<uint8_t>("uint8_t");
2014-10-03 07:53:44 +08:00
qRegisterMetaType<uint16_t>("uint16_t");
2014-06-26 04:43:28 +08:00
qRegisterMetaType<int32_t>("int32_t");
2014-07-13 00:40:01 +08:00
qRegisterMetaType<int64_t>("int64_t");
2014-09-24 23:28:38 +08:00
qRegisterMetaType<QPixmap>("QPixmap");
qRegisterMetaType<ToxFile>("ToxFile");
qRegisterMetaType<ToxFile::FileDirection>("ToxFile::FileDirection");
2014-06-25 04:11:11 +08:00
coreThread = new QThread(this);
2014-10-08 20:25:32 +08:00
core = new Core(Camera::getInstance(), coreThread);
2014-06-25 04:11:11 +08:00
core->moveToThread(coreThread);
connect(coreThread, &QThread::started, core, &Core::start);
connect(core, &Core::connected, this, &Widget::onConnected);
connect(core, &Core::disconnected, this, &Widget::onDisconnected);
connect(core, &Core::failedToStart, this, &Widget::onFailedToStartCore);
2014-10-06 04:49:44 +08:00
connect(core, &Core::badProxy, this, &Widget::onBadProxyCore);
2014-06-25 04:11:11 +08:00
connect(core, &Core::statusSet, this, &Widget::onStatusSet);
connect(core, &Core::usernameSet, this, &Widget::setUsername);
connect(core, &Core::statusMessageSet, this, &Widget::setStatusMessage);
2014-09-24 22:51:16 +08:00
connect(core, &Core::selfAvatarChanged, this, &Widget::onSelfAvatarLoaded);
connect(core, SIGNAL(fileDownloadFinished(const QString&)), &filesForm, SLOT(onFileDownloadComplete(const QString&)));
connect(core, SIGNAL(fileUploadFinished(const QString&)), &filesForm, SLOT(onFileUploadComplete(const QString&)));
2014-06-25 04:11:11 +08:00
connect(core, &Core::friendAdded, this, &Widget::addFriend);
connect(core, &Core::failedToAddFriend, this, &Widget::addFriendFailed);
2014-06-25 04:11:11 +08:00
connect(core, &Core::friendStatusChanged, this, &Widget::onFriendStatusChanged);
connect(core, &Core::friendUsernameChanged, this, &Widget::onFriendUsernameChanged);
connect(core, &Core::friendStatusChanged, this, &Widget::onFriendStatusChanged);
connect(core, &Core::friendStatusMessageChanged, this, &Widget::onFriendStatusMessageChanged);
connect(core, &Core::friendRequestReceived, this, &Widget::onFriendRequestReceived);
connect(core, &Core::friendMessageReceived, this, &Widget::onFriendMessageReceived);
connect(core, &Core::groupInviteReceived, this, &Widget::onGroupInviteReceived);
connect(core, &Core::groupMessageReceived, this, &Widget::onGroupMessageReceived);
connect(core, &Core::groupNamelistChanged, this, &Widget::onGroupNamelistChanged);
2014-06-30 05:38:48 +08:00
connect(core, &Core::emptyGroupCreated, this, &Widget::onEmptyGroupCreated);
2014-06-25 04:11:11 +08:00
connect(core, SIGNAL(messageSentResult(int,QString,int)), this, SLOT(onMessageSendResult(int,QString,int)));
connect(core, SIGNAL(groupSentResult(int,QString,int)), this, SLOT(onGroupSendResult(int,QString,int)));
2014-06-25 04:11:11 +08:00
connect(this, &Widget::statusSet, core, &Core::setStatus);
connect(this, &Widget::friendRequested, core, &Core::requestFriendship);
connect(this, &Widget::friendRequestAccepted, core, &Core::acceptFriendRequest);
connect(ui->addButton, SIGNAL(clicked()), this, SLOT(onAddClicked()));
connect(ui->groupButton, SIGNAL(clicked()), this, SLOT(onGroupClicked()));
connect(ui->transferButton, SIGNAL(clicked()), this, SLOT(onTransferClicked()));
connect(ui->settingsButton, SIGNAL(clicked()), this, SLOT(onSettingsClicked()));
connect(ui->nameLabel, SIGNAL(textChanged(QString,QString)), this, SLOT(onUsernameChanged(QString,QString)));
connect(ui->statusLabel, SIGNAL(textChanged(QString,QString)), this, SLOT(onStatusMessageChanged(QString,QString)));
connect(profilePicture, SIGNAL(clicked()), this, SLOT(onAvatarClicked()));
2014-07-06 04:54:27 +08:00
connect(setStatusOnline, SIGNAL(triggered()), this, SLOT(setStatusOnline()));
2014-10-06 00:17:01 +08:00
// connect(settingsWidget->getIdentityForm(), &IdentityForm::userNameChanged, Core::getInstance(), &Core::setUsername);
// connect(settingsWidget->getIdentityForm(), &IdentityForm::statusMessageChanged, Core::getInstance(), &Core::setStatusMessage);
2014-07-06 04:54:27 +08:00
connect(setStatusAway, SIGNAL(triggered()), this, SLOT(setStatusAway()));
connect(setStatusBusy, SIGNAL(triggered()), this, SLOT(setStatusBusy()));
2014-06-25 04:11:11 +08:00
connect(&friendForm, SIGNAL(friendRequested(QString,QString)), this, SIGNAL(friendRequested(QString,QString)));
coreThread->start();
friendForm.show(*ui);
}
Widget::~Widget()
{
2014-07-04 01:38:30 +08:00
core->saveConfiguration();
2014-06-25 04:11:11 +08:00
coreThread->exit();
coreThread->wait(500); // In case of deadlock (can happen with QtAudio/PA bugs)
if (!coreThread->isFinished())
coreThread->terminate();
2014-06-25 04:11:11 +08:00
delete core;
delete settingsWidget;
2014-06-25 04:11:11 +08:00
for (Friend* f : FriendList::friendList)
delete f;
FriendList::friendList.clear();
for (Group* g : GroupList::groupList)
delete g;
GroupList::groupList.clear();
delete ui;
instance = nullptr;
2014-06-25 04:11:11 +08:00
}
Widget* Widget::getInstance()
{
if (!instance)
instance = new Widget();
return instance;
}
QThread* Widget::getCoreThread()
{
return coreThread;
}
void Widget::closeEvent(QCloseEvent *event)
{
Settings::getInstance().setWindowGeometry(saveGeometry());
Settings::getInstance().setWindowState(saveState());
2014-08-11 20:07:27 +08:00
Settings::getInstance().setSplitterState(ui->mainSplitter->saveState());
QWidget::closeEvent(event);
}
2014-06-25 04:11:11 +08:00
QString Widget::getUsername()
{
return core->getUsername();
2014-06-25 04:11:11 +08:00
}
2014-09-24 22:51:16 +08:00
void Widget::onAvatarClicked()
{
QString filename = QFileDialog::getOpenFileName(this, tr("Choose a profile picture"), QDir::homePath());
2014-09-25 23:16:36 +08:00
if (filename == "")
return;
2014-09-24 22:51:16 +08:00
QFile file(filename);
file.open(QIODevice::ReadOnly);
if (!file.isOpen())
{
2014-09-25 23:16:36 +08:00
QMessageBox::critical(this, tr("Error"), tr("Unable to open this file"));
2014-09-24 22:51:16 +08:00
return;
}
QPixmap pic;
if (!pic.loadFromData(file.readAll()))
{
2014-09-25 23:16:36 +08:00
QMessageBox::critical(this, tr("Error"), tr("Unable to read this image"));
2014-09-24 22:51:16 +08:00
return;
}
QByteArray bytes;
QBuffer buffer(&bytes);
buffer.open(QIODevice::WriteOnly);
pic.save(&buffer, "PNG");
buffer.close();
2014-09-25 22:55:36 +08:00
if (bytes.size() >= TOX_AVATAR_MAX_DATA_LENGTH)
2014-09-24 22:51:16 +08:00
{
2014-09-25 00:40:40 +08:00
pic = pic.scaled(64,64, Qt::KeepAspectRatio, Qt::SmoothTransformation);
2014-09-24 22:51:16 +08:00
bytes.clear();
buffer.open(QIODevice::WriteOnly);
pic.save(&buffer, "PNG");
buffer.close();
}
2014-09-25 22:55:36 +08:00
if (bytes.size() >= TOX_AVATAR_MAX_DATA_LENGTH)
2014-09-24 22:51:16 +08:00
{
2014-09-25 23:16:36 +08:00
QMessageBox::critical(this, tr("Error"), tr("This image is too big"));
2014-09-24 22:51:16 +08:00
return;
}
2014-09-25 22:55:36 +08:00
core->setAvatar(TOX_AVATAR_FORMAT_PNG, bytes);
2014-09-24 22:51:16 +08:00
}
void Widget::onSelfAvatarLoaded(const QPixmap& pic)
{
profilePicture->setPixmap(pic);
2014-09-24 22:51:16 +08:00
}
2014-06-25 04:11:11 +08:00
void Widget::onConnected()
{
ui->statusButton->setEnabled(true);
2014-06-25 04:11:11 +08:00
emit statusSet(Status::Online);
}
void Widget::onDisconnected()
{
ui->statusButton->setEnabled(false);
2014-06-25 04:11:11 +08:00
emit statusSet(Status::Offline);
}
void Widget::onFailedToStartCore()
{
QMessageBox critical(this);
2014-10-06 04:49:44 +08:00
critical.setText(tr("Toxcore failed to start, the application will terminate after you close this message."));
2014-06-25 04:11:11 +08:00
critical.setIcon(QMessageBox::Critical);
critical.exec();
qApp->quit();
}
2014-10-06 04:49:44 +08:00
void Widget::onBadProxyCore()
{
QMessageBox critical(this);
critical.setText(tr("toxcore failed to start with your proxy settings. qTox cannot run; please modify your "
"settings and restart.", "popup text"));
critical.setIcon(QMessageBox::Critical);
critical.exec();
onSettingsClicked();
}
2014-06-25 04:11:11 +08:00
void Widget::onStatusSet(Status status)
{
2014-07-06 06:03:53 +08:00
//We have to use stylesheets here, there's no way to
//prevent the button icon from moving when pressed otherwise
2014-10-04 16:24:20 +08:00
switch (status)
2014-07-06 06:03:53 +08:00
{
2014-10-04 16:24:20 +08:00
case Status::Online:
ui->statusButton->setProperty("status" ,"online");
break;
case Status::Away:
ui->statusButton->setProperty("status" ,"away");
break;
case Status::Busy:
ui->statusButton->setProperty("status" ,"busy");
break;
case Status::Offline:
ui->statusButton->setProperty("status" ,"offline");
break;
2014-07-06 06:03:53 +08:00
}
2014-10-04 16:24:20 +08:00
Style::repolish(ui->statusButton);
2014-06-25 04:11:11 +08:00
}
void Widget::onAddClicked()
{
hideMainForms();
friendForm.show(*ui);
}
void Widget::onGroupClicked()
{
2014-06-30 05:38:48 +08:00
core->createGroup();
2014-06-25 04:11:11 +08:00
}
void Widget::onTransferClicked()
{
hideMainForms();
filesForm.show(*ui);
activeChatroomWidget = nullptr;
2014-06-25 04:11:11 +08:00
}
void Widget::onSettingsClicked()
{
hideMainForms();
settingsWidget->show(*ui);
activeChatroomWidget = nullptr;
2014-06-25 04:11:11 +08:00
}
void Widget::hideMainForms()
{
QLayoutItem* item;
while ((item = ui->mainHead->layout()->takeAt(0)) != 0)
item->widget()->hide();
while ((item = ui->mainContent->layout()->takeAt(0)) != 0)
item->widget()->hide();
if (activeChatroomWidget != nullptr)
2014-06-27 09:47:16 +08:00
{
activeChatroomWidget->setAsInactiveChatroom();
2014-06-27 09:47:16 +08:00
}
2014-06-25 04:11:11 +08:00
}
void Widget::onUsernameChanged(const QString& newUsername, const QString& oldUsername)
{
ui->nameLabel->setText(oldUsername); // restore old username until Core tells us to set it
ui->nameLabel->setToolTip(oldUsername); // for overlength names
2014-06-25 04:11:11 +08:00
core->setUsername(newUsername);
}
void Widget::setUsername(const QString& username)
{
ui->nameLabel->setText(username);
ui->nameLabel->setToolTip(username); // for overlength names
2014-10-06 00:17:01 +08:00
settingsWidget->getIdentityForm()->setUserName(username);
2014-06-25 04:11:11 +08:00
}
void Widget::onStatusMessageChanged(const QString& newStatusMessage, const QString& oldStatusMessage)
{
ui->statusLabel->setText(oldStatusMessage); // restore old status message until Core tells us to set it
ui->statusLabel->setToolTip(oldStatusMessage); // for overlength messsages
2014-06-25 04:11:11 +08:00
core->setStatusMessage(newStatusMessage);
}
void Widget::setStatusMessage(const QString &statusMessage)
{
ui->statusLabel->setText(statusMessage);
ui->statusLabel->setToolTip(statusMessage); // for overlength messsages
2014-10-06 00:17:01 +08:00
settingsWidget->getIdentityForm()->setStatusMessage(statusMessage);
2014-06-25 04:11:11 +08:00
}
void Widget::addFriend(int friendId, const QString &userId)
{
2014-09-28 05:44:08 +08:00
qDebug() << "Widget: Adding friend with id" << userId;
2014-06-25 04:11:11 +08:00
Friend* newfriend = FriendList::addFriend(friendId, userId);
2014-08-22 23:19:16 +08:00
QLayout* layout = contactListWidget->getFriendLayout(Status::Offline);
2014-06-25 04:11:11 +08:00
layout->addWidget(newfriend->widget);
connect(newfriend->widget, SIGNAL(chatroomWidgetClicked(GenericChatroomWidget*)), this, SLOT(onChatroomWidgetClicked(GenericChatroomWidget*)));
2014-06-25 04:11:11 +08:00
connect(newfriend->widget, SIGNAL(removeFriend(int)), this, SLOT(removeFriend(int)));
connect(newfriend->widget, SIGNAL(copyFriendIdToClipboard(int)), this, SLOT(copyFriendIdToClipboard(int)));
2014-09-11 04:53:02 +08:00
connect(newfriend->widget, SIGNAL(chatroomWidgetClicked(GenericChatroomWidget*)), newfriend->chatForm, SLOT(focusInput()));
2014-06-25 04:11:11 +08:00
connect(newfriend->chatForm, SIGNAL(sendMessage(int,QString)), core, SLOT(sendMessage(int,QString)));
connect(newfriend->chatForm, &GenericChatForm::sendAction, core, &Core::sendAction);
2014-07-13 00:40:01 +08:00
connect(newfriend->chatForm, SIGNAL(sendFile(int32_t, QString, QString, long long)), core, SLOT(sendFile(int32_t, QString, QString, long long)));
connect(newfriend->chatForm, SIGNAL(answerCall(int)), core, SLOT(answerCall(int)));
connect(newfriend->chatForm, SIGNAL(hangupCall(int)), core, SLOT(hangupCall(int)));
2014-06-27 09:06:56 +08:00
connect(newfriend->chatForm, SIGNAL(startCall(int)), core, SLOT(startCall(int)));
connect(newfriend->chatForm, SIGNAL(startVideoCall(int,bool)), core, SLOT(startCall(int,bool)));
2014-06-27 09:06:56 +08:00
connect(newfriend->chatForm, SIGNAL(cancelCall(int,int)), core, SLOT(cancelCall(int,int)));
2014-08-19 23:20:20 +08:00
connect(newfriend->chatForm, SIGNAL(micMuteToggle(int)), core, SLOT(micMuteToggle(int)));
connect(core, &Core::fileReceiveRequested, newfriend->chatForm, &ChatForm::onFileRecvRequest);
connect(core, &Core::avInvite, newfriend->chatForm, &ChatForm::onAvInvite);
connect(core, &Core::avStart, newfriend->chatForm, &ChatForm::onAvStart);
connect(core, &Core::avCancel, newfriend->chatForm, &ChatForm::onAvCancel);
connect(core, &Core::avEnd, newfriend->chatForm, &ChatForm::onAvEnd);
2014-06-27 09:06:56 +08:00
connect(core, &Core::avRinging, newfriend->chatForm, &ChatForm::onAvRinging);
connect(core, &Core::avStarting, newfriend->chatForm, &ChatForm::onAvStarting);
connect(core, &Core::avEnding, newfriend->chatForm, &ChatForm::onAvEnding);
2014-06-27 09:06:56 +08:00
connect(core, &Core::avRequestTimeout, newfriend->chatForm, &ChatForm::onAvRequestTimeout);
2014-06-28 03:59:25 +08:00
connect(core, &Core::avPeerTimeout, newfriend->chatForm, &ChatForm::onAvPeerTimeout);
connect(core, &Core::avMediaChange, newfriend->chatForm, &ChatForm::onAvMediaChange);
2014-09-24 23:28:38 +08:00
connect(core, &Core::friendAvatarChanged, newfriend->chatForm, &ChatForm::onAvatarChange);
connect(core, &Core::friendAvatarChanged, newfriend->widget, &FriendWidget::onAvatarChange);
2014-09-27 03:23:20 +08:00
connect(core, &Core::friendAvatarRemoved, newfriend->chatForm, &ChatForm::onAvatarRemoved);
connect(core, &Core::friendAvatarRemoved, newfriend->widget, &FriendWidget::onAvatarRemoved);
2014-09-24 23:55:54 +08:00
// Try to get the avatar from the cache
2014-09-28 06:19:30 +08:00
QPixmap avatar = Settings::getInstance().getSavedAvatar(userId);
2014-09-24 23:55:54 +08:00
if (!avatar.isNull())
{
2014-09-28 05:44:08 +08:00
qWarning() << "Widget: loadded avatar for id" << userId;
2014-09-24 23:55:54 +08:00
newfriend->chatForm->onAvatarChange(friendId, avatar);
newfriend->widget->onAvatarChange(friendId, avatar);
}
}
void Widget::addFriendFailed(const QString&)
{
QMessageBox::critical(0,"Error","Couldn't request friendship");
2014-06-25 04:11:11 +08:00
}
void Widget::onFriendStatusChanged(int friendId, Status status)
{
Friend* f = FriendList::findFriend(friendId);
if (!f)
return;
2014-08-22 23:19:16 +08:00
contactListWidget->moveWidget(f->widget, status);
f->friendStatus = status;
f->widget->updateStatusLight();
2014-06-25 04:11:11 +08:00
}
void Widget::onFriendStatusMessageChanged(int friendId, const QString& message)
{
Friend* f = FriendList::findFriend(friendId);
if (!f)
return;
2014-09-29 02:09:10 +08:00
QString str = message; str.replace('\n', ' ');
str.remove('\r'); str.remove(QChar((char)0)); // null terminator...
f->setStatusMessage(str);
2014-06-25 04:11:11 +08:00
}
void Widget::onFriendUsernameChanged(int friendId, const QString& username)
{
Friend* f = FriendList::findFriend(friendId);
if (!f)
return;
2014-09-29 02:09:10 +08:00
QString str = username; str.replace('\n', ' ');
str.remove('\r'); str.remove(QChar((char)0)); // null terminator...
f->setName(str);
2014-06-25 04:11:11 +08:00
}
void Widget::onChatroomWidgetClicked(GenericChatroomWidget *widget)
2014-06-25 04:11:11 +08:00
{
hideMainForms();
widget->setChatForm(*ui);
if (activeChatroomWidget != nullptr)
2014-06-27 09:47:16 +08:00
{
activeChatroomWidget->setAsInactiveChatroom();
2014-06-27 09:47:16 +08:00
}
activeChatroomWidget = widget;
2014-06-27 09:47:16 +08:00
widget->setAsActiveChatroom();
widget->resetEventFlags();
widget->updateStatusLight();
2014-06-25 04:11:11 +08:00
}
void Widget::onFriendMessageReceived(int friendId, const QString& message, bool isAction)
2014-06-25 04:11:11 +08:00
{
Friend* f = FriendList::findFriend(friendId);
if (!f)
return;
f->chatForm->addMessage(f->getName(), message, isAction);
if (activeChatroomWidget != nullptr)
{
if ((static_cast<GenericChatroomWidget*>(f->widget) != activeChatroomWidget) || isMinimized() || !isActiveWindow())
2014-06-28 05:36:44 +08:00
{
f->hasNewEvents = 1;
newMessageAlert();
2014-06-28 05:36:44 +08:00
}
}
else
2014-06-28 05:36:44 +08:00
{
f->hasNewEvents = 1;
newMessageAlert();
2014-06-28 05:36:44 +08:00
}
f->widget->updateStatusLight();
2014-06-25 04:11:11 +08:00
}
void Widget::newMessageAlert()
2014-06-28 05:36:44 +08:00
{
QApplication::alert(this);
static QFile sndFile(":audio/notification.pcm");
static QByteArray sndData;
if (sndData.isEmpty())
{
sndFile.open(QIODevice::ReadOnly);
sndData = sndFile.readAll();
sndFile.close();
}
ALuint buffer;
alGenBuffers(1, &buffer);
alBufferData(buffer, AL_FORMAT_MONO16, sndData.data(), sndData.size(), 44100);
alSourcei(core->alMainSource, AL_BUFFER, buffer);
alSourcePlay(core->alMainSource);
2014-06-28 05:36:44 +08:00
}
2014-06-25 04:11:11 +08:00
void Widget::onFriendRequestReceived(const QString& userId, const QString& message)
{
FriendRequestDialog dialog(this, userId, message);
if (dialog.exec() == QDialog::Accepted)
emit friendRequestAccepted(userId);
}
void Widget::removeFriend(int friendId)
{
Friend* f = FriendList::findFriend(friendId);
f->widget->setAsInactiveChatroom();
if (static_cast<GenericChatroomWidget*>(f->widget) == activeChatroomWidget)
activeChatroomWidget = nullptr;
2014-06-25 04:11:11 +08:00
FriendList::removeFriend(friendId);
core->removeFriend(friendId);
delete f;
if (ui->mainHead->layout()->isEmpty())
onAddClicked();
}
void Widget::copyFriendIdToClipboard(int friendId)
{
Friend* f = FriendList::findFriend(friendId);
if (f != nullptr)
{
QClipboard *clipboard = QApplication::clipboard();
2014-09-01 04:26:45 +08:00
clipboard->setText(core->getFriendAddress(f->friendId), QClipboard::Clipboard);
}
}
2014-09-28 16:56:02 +08:00
void Widget::onGroupInviteReceived(int32_t friendId, const uint8_t* publicKey,uint16_t length)
2014-06-25 04:11:11 +08:00
{
2014-09-28 16:56:02 +08:00
int groupId = core->joinGroupchat(friendId, publicKey,length);
2014-06-25 04:11:11 +08:00
if (groupId == -1)
{
qWarning() << "Widget::onGroupInviteReceived: Unable to accept invitation";
return;
}
}
void Widget::onGroupMessageReceived(int groupnumber, const QString& message, const QString& author)
2014-06-25 04:11:11 +08:00
{
Group* g = GroupList::findGroup(groupnumber);
if (!g)
return;
g->chatForm->addMessage(author, message);
2014-06-28 07:10:02 +08:00
if ((static_cast<GenericChatroomWidget*>(g->widget) != activeChatroomWidget) || isMinimized() || !isActiveWindow())
2014-06-28 07:10:02 +08:00
{
g->hasNewMessages = 1;
newMessageAlert(); // sound alert on any message, not just naming user
if (message.contains(core->getUsername(), Qt::CaseInsensitive))
2014-06-28 07:10:02 +08:00
{
g->userWasMentioned = 1; // useful for highlighting line or desktop notifications
2014-06-28 07:10:02 +08:00
}
g->widget->updateStatusLight();
2014-06-28 07:10:02 +08:00
}
2014-06-25 04:11:11 +08:00
}
void Widget::onGroupNamelistChanged(int groupnumber, int peernumber, uint8_t Change)
{
Group* g = GroupList::findGroup(groupnumber);
if (!g)
{
qDebug() << "Widget::onGroupNamelistChanged: Group not found, creating it";
g = createGroup(groupnumber);
}
TOX_CHAT_CHANGE change = static_cast<TOX_CHAT_CHANGE>(Change);
if (change == TOX_CHAT_CHANGE_PEER_ADD)
2014-09-12 00:05:02 +08:00
{
QString name = core->getGroupPeerName(groupnumber, peernumber);
if (name.isEmpty())
name = tr("<Unknown>", "Placeholder when we don't know someone's name in a group chat");
g->addPeer(peernumber,name);
}
2014-06-25 04:11:11 +08:00
else if (change == TOX_CHAT_CHANGE_PEER_DEL)
g->removePeer(peernumber);
else if (change == TOX_CHAT_CHANGE_PEER_NAME)
g->updatePeer(peernumber,core->getGroupPeerName(groupnumber, peernumber));
}
void Widget::removeGroup(int groupId)
{
Group* g = GroupList::findGroup(groupId);
g->widget->setAsInactiveChatroom();
if (static_cast<GenericChatroomWidget*>(g->widget) == activeChatroomWidget)
activeChatroomWidget = nullptr;
2014-06-25 04:11:11 +08:00
GroupList::removeGroup(groupId);
core->removeGroup(groupId);
delete g;
if (ui->mainHead->layout()->isEmpty())
onAddClicked();
}
2014-06-26 07:48:20 +08:00
Core *Widget::getCore()
2014-06-25 04:11:11 +08:00
{
return core;
}
Group *Widget::createGroup(int groupId)
{
Group* g = GroupList::findGroup(groupId);
if (g)
{
qWarning() << "Widget::createGroup: Group already exists";
return g;
}
QString groupName = QString("Groupchat #%1").arg(groupId);
Group* newgroup = GroupList::addGroup(groupId, groupName);
2014-08-22 23:19:16 +08:00
QLayout* layout = contactListWidget->getGroupLayout();
2014-06-25 04:11:11 +08:00
layout->addWidget(newgroup->widget);
newgroup->widget->updateStatusLight();
connect(newgroup->widget, SIGNAL(chatroomWidgetClicked(GenericChatroomWidget*)), this, SLOT(onChatroomWidgetClicked(GenericChatroomWidget*)));
2014-06-25 04:11:11 +08:00
connect(newgroup->widget, SIGNAL(removeGroup(int)), this, SLOT(removeGroup(int)));
2014-09-11 05:00:45 +08:00
connect(newgroup->widget, SIGNAL(chatroomWidgetClicked(GenericChatroomWidget*)), newgroup->chatForm, SLOT(focusInput()));
2014-06-25 04:11:11 +08:00
connect(newgroup->chatForm, SIGNAL(sendMessage(int,QString)), core, SLOT(sendGroupMessage(int,QString)));
return newgroup;
}
2014-06-30 05:38:48 +08:00
void Widget::onEmptyGroupCreated(int groupId)
{
createGroup(groupId);
}
2014-07-01 03:14:51 +08:00
bool Widget::isFriendWidgetCurActiveWidget(Friend* f)
{
if (!f)
return false;
if (activeChatroomWidget == static_cast<GenericChatroomWidget*>(f->widget))
return true;
2014-07-01 03:14:51 +08:00
else
return false;
}
2014-07-03 06:27:30 +08:00
bool Widget::event(QEvent * e)
{
if (e->type() == QEvent::WindowActivate)
2014-07-03 06:27:30 +08:00
{
if (activeChatroomWidget != nullptr)
2014-07-03 06:27:30 +08:00
{
activeChatroomWidget->resetEventFlags();
activeChatroomWidget->updateStatusLight();
2014-07-03 06:27:30 +08:00
}
}
return QWidget::event(e);
}
2014-07-06 04:54:27 +08:00
void Widget::setStatusOnline()
{
core->setStatus(Status::Online);
}
void Widget::setStatusAway()
{
core->setStatus(Status::Away);
}
void Widget::setStatusBusy()
2014-07-04 01:33:08 +08:00
{
2014-07-06 04:54:27 +08:00
core->setStatus(Status::Busy);
2014-07-04 01:33:08 +08:00
}
2014-07-21 02:17:06 +08:00
void Widget::onMessageSendResult(int friendId, const QString& message, int messageId)
{
Q_UNUSED(message)
Friend* f = FriendList::findFriend(friendId);
if (!f)
return;
if (!messageId)
f->chatForm->addSystemInfoMessage("Message failed to send", "red");
}
void Widget::onGroupSendResult(int groupId, const QString& message, int result)
{
Q_UNUSED(message)
Group* g = GroupList::findGroup(groupId);
if (!g)
return;
if (result == -1)
g->chatForm->addSystemInfoMessage("Message failed to send", "red");
}