mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
Merge commit '5a005a1aafe96061301a4e113cb5450770009b88' into profiles
Conflicts: core.cpp widget/form/settingsform.cpp widget/form/settingsform.h
This commit is contained in:
commit
d16b6cd283
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -1,2 +1,8 @@
|
||||||
*.pro.user*
|
*.pro.user*
|
||||||
libs
|
libs
|
||||||
|
*.o
|
||||||
|
moc_*
|
||||||
|
ui_*
|
||||||
|
qrc_*
|
||||||
|
Makefile
|
||||||
|
qtox
|
||||||
|
|
|
@ -131,17 +131,17 @@ First of all install the dependencies of Tox Core.
|
||||||
|
|
||||||
Debian:
|
Debian:
|
||||||
```bash
|
```bash
|
||||||
sudo apt-get install libtool autotools-dev automake checkinstall check yasm libopus-dev libvpx-dev
|
sudo apt-get install libtool autotools-dev automake checkinstall check libopus-dev libvpx-dev
|
||||||
```
|
```
|
||||||
|
|
||||||
Ubuntu:
|
Ubuntu:
|
||||||
```bash
|
```bash
|
||||||
sudo apt-get install libtool autotools-dev automake checkinstall check yasm libopus-dev libvpx-dev
|
sudo apt-get install libtool autotools-dev automake checkinstall check libopus-dev libvpx-dev
|
||||||
```
|
```
|
||||||
|
|
||||||
Arch Linux: (Arch Linux provides the package "tox-git" in AUR)
|
Arch Linux: (Arch Linux provides the package "tox-git" in AUR)
|
||||||
```bash
|
```bash
|
||||||
sudo pacman -S --needed yasm opus vpx
|
sudo pacman -S --needed opus vpx
|
||||||
```
|
```
|
||||||
|
|
||||||
Fedora:
|
Fedora:
|
||||||
|
|
|
@ -25,8 +25,7 @@ This client runs on Windows, Linux and Mac natively.<br/>
|
||||||
|
|
||||||
<h3>Screenshots</h3>
|
<h3>Screenshots</h3>
|
||||||
<h5>Note: The screenshots may not always be up to date, but they should give a good idea of the general look and features</h5>
|
<h5>Note: The screenshots may not always be up to date, but they should give a good idea of the general look and features</h5>
|
||||||
<img src="http://i.imgur.com/mMUdr6u.png"/>
|
<img src="https://i.imgur.com/7Jg5tQa.png">/
|
||||||
<img src="http://i.imgur.com/66ARBGC.png"/>
|
|
||||||
|
|
||||||
##Documentation:
|
##Documentation:
|
||||||
|
|
||||||
|
|
BIN
audio/notification.pcm
Normal file
BIN
audio/notification.pcm
Normal file
Binary file not shown.
Binary file not shown.
14
bootstrap.sh
14
bootstrap.sh
|
@ -21,7 +21,7 @@ TOX_CORE_DIR=libtoxcore-latest
|
||||||
# the default value is 'false' and will be set to 'true'
|
# the default value is 'false' and will be set to 'true'
|
||||||
# if this script gets the parameter -t or --tox
|
# if this script gets the parameter -t or --tox
|
||||||
TOX_ONLY=false
|
TOX_ONLY=false
|
||||||
GLOBAL=false
|
GLOBAL=true
|
||||||
KEEP=false
|
KEEP=false
|
||||||
|
|
||||||
if [ -z "$BASE_DIR" ]; then
|
if [ -z "$BASE_DIR" ]; then
|
||||||
|
@ -49,8 +49,8 @@ while [ $# -ge 1 ] ; do
|
||||||
if [ ${1} = "-t" -o ${1} = "--tox" ] ; then
|
if [ ${1} = "-t" -o ${1} = "--tox" ] ; then
|
||||||
TOX_ONLY=true
|
TOX_ONLY=true
|
||||||
shift
|
shift
|
||||||
elif [ ${1} = "-g" -o ${1} = "--global" ] ; then
|
elif [ ${1} = "-l" -o ${1} = "--local" ] ; then
|
||||||
GLOBAL=true
|
GLOBAL=false
|
||||||
shift
|
shift
|
||||||
elif [ ${1} = "-k" -o ${1} = "--keep" ]; then
|
elif [ ${1} = "-k" -o ${1} = "--keep" ]; then
|
||||||
KEEP=true
|
KEEP=true
|
||||||
|
@ -71,8 +71,8 @@ while [ $# -ge 1 ] ; do
|
||||||
echo " -h|--help : displays this help"
|
echo " -h|--help : displays this help"
|
||||||
echo " -t|--tox : only install/update libtoxcore"
|
echo " -t|--tox : only install/update libtoxcore"
|
||||||
echo " requires an already installed libsodium"
|
echo " requires an already installed libsodium"
|
||||||
echo " -g|--global: installs libtox* and libsodium globally"
|
echo " -l|--local : installs libtox* and libsodium in the current directory,"
|
||||||
echo " (also disables local configure prefixes)"
|
echo " as opposed to the system directories"
|
||||||
echo " -k|--keep : does not delete the build directories afterwards"
|
echo " -k|--keep : does not delete the build directories afterwards"
|
||||||
echo ""
|
echo ""
|
||||||
echo "example usages:"
|
echo "example usages:"
|
||||||
|
@ -147,6 +147,10 @@ fi
|
||||||
|
|
||||||
popd
|
popd
|
||||||
|
|
||||||
|
if [[ $GLOBAL = "true" ]]; then
|
||||||
|
sudo ldconfig
|
||||||
|
fi
|
||||||
|
|
||||||
############### cleanup step ###############
|
############### cleanup step ###############
|
||||||
# remove cloned repositories
|
# remove cloned repositories
|
||||||
if [[ $KEEP = "false" ]]; then
|
if [[ $KEEP = "false" ]]; then
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cdata.h"
|
#include "cdata.h"
|
||||||
|
#include <QString>
|
||||||
|
#include <tox/tox.h>
|
||||||
|
|
||||||
// CData
|
// CData
|
||||||
|
|
||||||
|
@ -54,6 +56,8 @@ uint16_t CData::fromString(const QString& data, uint8_t* cData)
|
||||||
|
|
||||||
// CUserId
|
// CUserId
|
||||||
|
|
||||||
|
const uint16_t CUserId::SIZE{TOX_CLIENT_ID_SIZE};
|
||||||
|
|
||||||
CUserId::CUserId(const QString &userId) :
|
CUserId::CUserId(const QString &userId) :
|
||||||
CData(userId, SIZE)
|
CData(userId, SIZE)
|
||||||
{
|
{
|
||||||
|
@ -68,6 +72,8 @@ QString CUserId::toString(const uint8_t* cUserId)
|
||||||
|
|
||||||
// CFriendAddress
|
// CFriendAddress
|
||||||
|
|
||||||
|
const uint16_t CFriendAddress::SIZE{TOX_FRIEND_ADDRESS_SIZE};
|
||||||
|
|
||||||
CFriendAddress::CFriendAddress(const QString &friendAddress) :
|
CFriendAddress::CFriendAddress(const QString &friendAddress) :
|
||||||
CData(friendAddress, SIZE)
|
CData(friendAddress, SIZE)
|
||||||
{
|
{
|
||||||
|
|
7
cdata.h
7
cdata.h
|
@ -18,9 +18,8 @@
|
||||||
#define CDATA_H
|
#define CDATA_H
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <QString>
|
|
||||||
#include "tox/tox.h"
|
|
||||||
|
|
||||||
|
class QString;
|
||||||
class CData
|
class CData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -48,7 +47,7 @@ public:
|
||||||
static QString toString(const uint8_t *cUserId);
|
static QString toString(const uint8_t *cUserId);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const uint16_t SIZE = TOX_CLIENT_ID_SIZE;
|
static const uint16_t SIZE;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -60,7 +59,7 @@ public:
|
||||||
static QString toString(const uint8_t* cFriendAddress);
|
static QString toString(const uint8_t* cFriendAddress);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const uint16_t SIZE = TOX_FRIEND_ADDRESS_SIZE;
|
static const uint16_t SIZE;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
44
core.cpp
44
core.cpp
|
@ -20,6 +20,8 @@
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "widget/widget.h"
|
#include "widget/widget.h"
|
||||||
|
|
||||||
|
#include <tox/tox.h>
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
|
@ -28,9 +30,10 @@
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QSaveFile>
|
#include <QSaveFile>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
#include <QtEndian>
|
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QtConcurrent/QtConcurrent>
|
#include <QTimer>
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QDateTime>
|
||||||
|
|
||||||
const QString Core::CONFIG_FILE_NAME = "data";
|
const QString Core::CONFIG_FILE_NAME = "data";
|
||||||
const QString Core::TOX_EXT = ".tox";
|
const QString Core::TOX_EXT = ".tox";
|
||||||
|
@ -113,6 +116,11 @@ Core::~Core()
|
||||||
alcCaptureCloseDevice(alInDev);
|
alcCaptureCloseDevice(alInDev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Core* Core::getInstance()
|
||||||
|
{
|
||||||
|
return Widget::getInstance()->getCore();
|
||||||
|
}
|
||||||
|
|
||||||
void Core::get_tox()
|
void Core::get_tox()
|
||||||
{
|
{
|
||||||
// IPv6 needed for LAN discovery, but can crash some weird routers. On by default, can be disabled in options.
|
// IPv6 needed for LAN discovery, but can crash some weird routers. On by default, can be disabled in options.
|
||||||
|
@ -406,6 +414,14 @@ void Core::onFileControlCallback(Tox* tox, int32_t friendnumber, uint8_t receive
|
||||||
tox_file_send_control(tox, file->friendId, 1, file->fileNum, TOX_FILECONTROL_FINISHED, nullptr, 0);
|
tox_file_send_control(tox, file->friendId, 1, file->fileNum, TOX_FILECONTROL_FINISHED, nullptr, 0);
|
||||||
removeFileFromQueue((bool)receive_send, file->friendId, file->fileNum);
|
removeFileFromQueue((bool)receive_send, file->friendId, file->fileNum);
|
||||||
}
|
}
|
||||||
|
else if (receive_send == 0 && control_type == TOX_FILECONTROL_ACCEPT)
|
||||||
|
{
|
||||||
|
emit static_cast<Core*>(core)->fileTransferRemotePausedUnpaused(*file, false);
|
||||||
|
}
|
||||||
|
else if ((receive_send == 0 || receive_send == 1) && control_type == TOX_FILECONTROL_PAUSE)
|
||||||
|
{
|
||||||
|
emit static_cast<Core*>(core)->fileTransferRemotePausedUnpaused(*file, true);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qDebug() << QString("Core: File control callback, receive_send=%1, control_type=%2")
|
qDebug() << QString("Core: File control callback, receive_send=%1, control_type=%2")
|
||||||
|
@ -702,15 +718,6 @@ void Core::removeGroup(int groupId)
|
||||||
tox_del_groupchat(tox, groupId);
|
tox_del_groupchat(tox, groupId);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Core::getIDString()
|
|
||||||
{
|
|
||||||
uint8_t friendAddress[TOX_FRIEND_ADDRESS_SIZE];
|
|
||||||
tox_get_address(tox, friendAddress);
|
|
||||||
return CFriendAddress::toString(friendAddress).left(12);
|
|
||||||
// 12 is the smallest multiple of four such that
|
|
||||||
// 16^n > 10^10 (which is roughly the planet's population)
|
|
||||||
}
|
|
||||||
|
|
||||||
QString Core::getUsername()
|
QString Core::getUsername()
|
||||||
{
|
{
|
||||||
int size = tox_get_self_name_size(tox);
|
int size = tox_get_self_name_size(tox);
|
||||||
|
@ -734,6 +741,21 @@ void Core::setUsername(const QString& username)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString Core::getSelfId()
|
||||||
|
{
|
||||||
|
uint8_t friendAddress[TOX_FRIEND_ADDRESS_SIZE];
|
||||||
|
tox_get_address(tox, friendAddress);
|
||||||
|
|
||||||
|
return CFriendAddress::toString(friendAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Core::getIDString()
|
||||||
|
{
|
||||||
|
return getSelfId().left(12);
|
||||||
|
// 12 is the smallest multiple of four such that
|
||||||
|
// 16^n > 10^10 (which is roughly the planet's population)
|
||||||
|
}
|
||||||
|
|
||||||
QString Core::getStatusMessage()
|
QString Core::getStatusMessage()
|
||||||
{
|
{
|
||||||
int size = tox_get_self_status_message_size(tox);
|
int size = tox_get_self_status_message_size(tox);
|
||||||
|
|
96
core.h
96
core.h
|
@ -17,102 +17,24 @@
|
||||||
#ifndef CORE_HPP
|
#ifndef CORE_HPP
|
||||||
#define CORE_HPP
|
#define CORE_HPP
|
||||||
|
|
||||||
#include <tox/tox.h>
|
|
||||||
#include <tox/toxav.h>
|
|
||||||
|
|
||||||
#if defined(__APPLE__) && defined(__MACH__)
|
|
||||||
#include <OpenAL/al.h>
|
|
||||||
#include <OpenAL/alc.h>
|
|
||||||
#else
|
|
||||||
#include <AL/al.h>
|
|
||||||
#include <AL/alc.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <QDateTime>
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QTimer>
|
|
||||||
#include <QString>
|
|
||||||
#include <QFile>
|
|
||||||
#include <QList>
|
|
||||||
#include <QByteArray>
|
|
||||||
|
|
||||||
#define TOXAV_MAX_CALLS 16
|
#include "corestructs.h"
|
||||||
#define GROUPCHAT_MAX_SIZE 32
|
#include "coreav.h"
|
||||||
#define TOX_SAVE_INTERVAL 30*1000
|
#include "coredefines.h"
|
||||||
#define TOX_FILE_INTERVAL 0
|
|
||||||
#define TOX_BOOTSTRAP_INTERVAL 5*1000
|
|
||||||
#define TOXAV_RINGING_TIME 15
|
|
||||||
|
|
||||||
// TODO: Put that in the settings
|
|
||||||
#define TOXAV_MAX_VIDEO_WIDTH 1600
|
|
||||||
#define TOXAV_MAX_VIDEO_HEIGHT 1200
|
|
||||||
|
|
||||||
|
template <typename T> class QList;
|
||||||
class Camera;
|
class Camera;
|
||||||
|
class QTimer;
|
||||||
enum class Status : int {Online = 0, Away, Busy, Offline};
|
class QString;
|
||||||
|
|
||||||
struct DhtServer
|
|
||||||
{
|
|
||||||
QString name;
|
|
||||||
QString userId;
|
|
||||||
QString address;
|
|
||||||
int port;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ToxFile
|
|
||||||
{
|
|
||||||
enum FileStatus
|
|
||||||
{
|
|
||||||
STOPPED,
|
|
||||||
PAUSED,
|
|
||||||
TRANSMITTING
|
|
||||||
};
|
|
||||||
|
|
||||||
enum FileDirection : bool
|
|
||||||
{
|
|
||||||
SENDING,
|
|
||||||
RECEIVING
|
|
||||||
};
|
|
||||||
|
|
||||||
ToxFile()=default;
|
|
||||||
ToxFile(int FileNum, int FriendId, QByteArray FileName, QString FilePath, FileDirection Direction)
|
|
||||||
: fileNum(FileNum), friendId(FriendId), fileName{FileName}, filePath{FilePath}, file{new QFile(filePath)},
|
|
||||||
bytesSent{0}, filesize{0}, status{STOPPED}, direction{Direction}, sendTimer{nullptr} {}
|
|
||||||
~ToxFile(){}
|
|
||||||
void setFilePath(QString path) {filePath=path; file->setFileName(path);}
|
|
||||||
bool open(bool write) {return write?file->open(QIODevice::ReadWrite):file->open(QIODevice::ReadOnly);}
|
|
||||||
|
|
||||||
int fileNum;
|
|
||||||
int friendId;
|
|
||||||
QByteArray fileName;
|
|
||||||
QString filePath;
|
|
||||||
QFile* file;
|
|
||||||
long long bytesSent;
|
|
||||||
long long filesize;
|
|
||||||
FileStatus status;
|
|
||||||
FileDirection direction;
|
|
||||||
QTimer* sendTimer;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ToxCall
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ToxAvCSettings codecSettings;
|
|
||||||
QTimer *sendAudioTimer, *sendVideoTimer;
|
|
||||||
int callId;
|
|
||||||
int friendId;
|
|
||||||
bool videoEnabled;
|
|
||||||
bool active;
|
|
||||||
bool muteMic;
|
|
||||||
ALuint alSource;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Core : public QObject
|
class Core : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit Core(Camera* cam, QThread* coreThread);
|
explicit Core(Camera* cam, QThread* coreThread);
|
||||||
|
static Core* getInstance(); ///< Returns the global widget's Core instance
|
||||||
~Core();
|
~Core();
|
||||||
|
|
||||||
static const QString TOX_EXT;
|
static const QString TOX_EXT;
|
||||||
|
@ -133,6 +55,7 @@ public:
|
||||||
|
|
||||||
QString getUsername();
|
QString getUsername();
|
||||||
QString getStatusMessage();
|
QString getStatusMessage();
|
||||||
|
QString getSelfId();
|
||||||
|
|
||||||
void increaseVideoBusyness();
|
void increaseVideoBusyness();
|
||||||
void decreaseVideoBusyness();
|
void decreaseVideoBusyness();
|
||||||
|
@ -230,6 +153,7 @@ signals:
|
||||||
void fileDownloadFinished(const QString& path);
|
void fileDownloadFinished(const QString& path);
|
||||||
void fileTransferPaused(int FriendId, int FileNum, ToxFile::FileDirection direction);
|
void fileTransferPaused(int FriendId, int FileNum, ToxFile::FileDirection direction);
|
||||||
void fileTransferInfo(int FriendId, int FileNum, int64_t Filesize, int64_t BytesSent, ToxFile::FileDirection direction);
|
void fileTransferInfo(int FriendId, int FileNum, int64_t Filesize, int64_t BytesSent, ToxFile::FileDirection direction);
|
||||||
|
void fileTransferRemotePausedUnpaused(ToxFile file, bool paused);
|
||||||
|
|
||||||
void avInvite(int friendId, int callIndex, bool video);
|
void avInvite(int friendId, int callIndex, bool video);
|
||||||
void avStart(int friendId, int callIndex, bool video);
|
void avStart(int friendId, int callIndex, bool video);
|
||||||
|
@ -308,7 +232,7 @@ private:
|
||||||
QList<DhtServer> dhtServerList;
|
QList<DhtServer> dhtServerList;
|
||||||
int dhtServerId;
|
int dhtServerId;
|
||||||
static QList<ToxFile> fileSendQueue, fileRecvQueue;
|
static QList<ToxFile> fileSendQueue, fileRecvQueue;
|
||||||
static ToxCall calls[TOXAV_MAX_CALLS];
|
static ToxCall calls[];
|
||||||
|
|
||||||
static const QString CONFIG_FILE_NAME;
|
static const QString CONFIG_FILE_NAME;
|
||||||
static const int videobufsize;
|
static const int videobufsize;
|
||||||
|
|
14
coreav.cpp
14
coreav.cpp
|
@ -15,7 +15,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
#include "widget/widget.h"
|
#include "widget/camera.h"
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
ToxCall Core::calls[TOXAV_MAX_CALLS];
|
ToxCall Core::calls[TOXAV_MAX_CALLS];
|
||||||
const int Core::videobufsize{TOXAV_MAX_VIDEO_WIDTH * TOXAV_MAX_VIDEO_HEIGHT * 4};
|
const int Core::videobufsize{TOXAV_MAX_VIDEO_WIDTH * TOXAV_MAX_VIDEO_HEIGHT * 4};
|
||||||
|
@ -55,7 +57,7 @@ void Core::prepareCall(int friendId, int callId, ToxAv* toxav, bool videoEnabled
|
||||||
if (calls[callId].videoEnabled)
|
if (calls[callId].videoEnabled)
|
||||||
{
|
{
|
||||||
calls[callId].sendVideoTimer->start();
|
calls[callId].sendVideoTimer->start();
|
||||||
Widget::getInstance()->getCamera()->suscribe();
|
Camera::getInstance()->suscribe();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,12 +73,12 @@ void Core::onAvMediaChange(void* toxav, int32_t callId, void* core)
|
||||||
{
|
{
|
||||||
calls[callId].videoEnabled = false;
|
calls[callId].videoEnabled = false;
|
||||||
calls[callId].sendVideoTimer->stop();
|
calls[callId].sendVideoTimer->stop();
|
||||||
Widget::getInstance()->getCamera()->unsuscribe();
|
Camera::getInstance()->unsuscribe();
|
||||||
emit ((Core*)core)->avMediaChange(friendId, callId, false);
|
emit ((Core*)core)->avMediaChange(friendId, callId, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Widget::getInstance()->getCamera()->suscribe();
|
Camera::getInstance()->suscribe();
|
||||||
calls[callId].videoEnabled = true;
|
calls[callId].videoEnabled = true;
|
||||||
calls[callId].sendVideoTimer->start();
|
calls[callId].sendVideoTimer->start();
|
||||||
emit ((Core*)core)->avMediaChange(friendId, callId, true);
|
emit ((Core*)core)->avMediaChange(friendId, callId, true);
|
||||||
|
@ -159,7 +161,7 @@ void Core::cleanupCall(int callId)
|
||||||
calls[callId].sendAudioTimer->stop();
|
calls[callId].sendAudioTimer->stop();
|
||||||
calls[callId].sendVideoTimer->stop();
|
calls[callId].sendVideoTimer->stop();
|
||||||
if (calls[callId].videoEnabled)
|
if (calls[callId].videoEnabled)
|
||||||
Widget::getInstance()->getCamera()->unsuscribe();
|
Camera::getInstance()->unsuscribe();
|
||||||
alcCaptureStop(alInDev);
|
alcCaptureStop(alInDev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,7 +226,7 @@ void Core::playCallVideo(ToxAv*, int32_t callId, vpx_image_t* img, void *user_da
|
||||||
if (videoBusyness >= 1)
|
if (videoBusyness >= 1)
|
||||||
qWarning() << "Core: playCallVideo: Busy, dropping current frame";
|
qWarning() << "Core: playCallVideo: Busy, dropping current frame";
|
||||||
else
|
else
|
||||||
emit Widget::getInstance()->getCore()->videoFrameReceived(img);
|
emit Core::getInstance()->videoFrameReceived(img);
|
||||||
vpx_img_free(img);
|
vpx_img_free(img);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
29
coreav.h
Normal file
29
coreav.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#ifndef COREAV_H
|
||||||
|
#define COREAV_H
|
||||||
|
|
||||||
|
#include <tox/toxav.h>
|
||||||
|
|
||||||
|
#if defined(__APPLE__) && defined(__MACH__)
|
||||||
|
#include <OpenAL/al.h>
|
||||||
|
#include <OpenAL/alc.h>
|
||||||
|
#else
|
||||||
|
#include <AL/al.h>
|
||||||
|
#include <AL/alc.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class QTimer;
|
||||||
|
|
||||||
|
struct ToxCall
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ToxAvCSettings codecSettings;
|
||||||
|
QTimer *sendAudioTimer, *sendVideoTimer;
|
||||||
|
int callId;
|
||||||
|
int friendId;
|
||||||
|
bool videoEnabled;
|
||||||
|
bool active;
|
||||||
|
bool muteMic;
|
||||||
|
ALuint alSource;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // COREAV_H
|
15
coredefines.h
Normal file
15
coredefines.h
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef COREDEFINES_H
|
||||||
|
#define COREDEFINES_H
|
||||||
|
|
||||||
|
#define TOXAV_MAX_CALLS 16
|
||||||
|
#define GROUPCHAT_MAX_SIZE 32
|
||||||
|
#define TOX_SAVE_INTERVAL 30*1000
|
||||||
|
#define TOX_FILE_INTERVAL 0
|
||||||
|
#define TOX_BOOTSTRAP_INTERVAL 5*1000
|
||||||
|
#define TOXAV_RINGING_TIME 15
|
||||||
|
|
||||||
|
// TODO: Put that in the settings
|
||||||
|
#define TOXAV_MAX_VIDEO_WIDTH 1600
|
||||||
|
#define TOXAV_MAX_VIDEO_HEIGHT 1200
|
||||||
|
|
||||||
|
#endif // COREDEFINES_H
|
19
corestructs.cpp
Normal file
19
corestructs.cpp
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#include "corestructs.h"
|
||||||
|
#include <QFile>
|
||||||
|
|
||||||
|
ToxFile::ToxFile(int FileNum, int FriendId, QByteArray FileName, QString FilePath, FileDirection Direction)
|
||||||
|
: fileNum(FileNum), friendId(FriendId), fileName{FileName}, filePath{FilePath}, file{new QFile(filePath)},
|
||||||
|
bytesSent{0}, filesize{0}, status{STOPPED}, direction{Direction}, sendTimer{nullptr}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToxFile::setFilePath(QString path)
|
||||||
|
{
|
||||||
|
filePath=path;
|
||||||
|
file->setFileName(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ToxFile::open(bool write)
|
||||||
|
{
|
||||||
|
return write ? file->open(QIODevice::ReadWrite) : file->open(QIODevice::ReadOnly);
|
||||||
|
}
|
54
corestructs.h
Normal file
54
corestructs.h
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#ifndef CORESTRUCTS_H
|
||||||
|
#define CORESTRUCTS_H
|
||||||
|
|
||||||
|
// Some headers use Core structs but don't need to include all of core.h
|
||||||
|
// They should include this file directly instead to reduce compilation times
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
class QFile;
|
||||||
|
class QTimer;
|
||||||
|
|
||||||
|
enum class Status : int {Online = 0, Away, Busy, Offline};
|
||||||
|
|
||||||
|
struct DhtServer
|
||||||
|
{
|
||||||
|
QString name;
|
||||||
|
QString userId;
|
||||||
|
QString address;
|
||||||
|
int port;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ToxFile
|
||||||
|
{
|
||||||
|
enum FileStatus
|
||||||
|
{
|
||||||
|
STOPPED,
|
||||||
|
PAUSED,
|
||||||
|
TRANSMITTING
|
||||||
|
};
|
||||||
|
|
||||||
|
enum FileDirection : bool
|
||||||
|
{
|
||||||
|
SENDING,
|
||||||
|
RECEIVING
|
||||||
|
};
|
||||||
|
|
||||||
|
ToxFile()=default;
|
||||||
|
ToxFile(int FileNum, int FriendId, QByteArray FileName, QString FilePath, FileDirection Direction);
|
||||||
|
~ToxFile(){}
|
||||||
|
void setFilePath(QString path);
|
||||||
|
bool open(bool write);
|
||||||
|
|
||||||
|
int fileNum;
|
||||||
|
int friendId;
|
||||||
|
QByteArray fileName;
|
||||||
|
QString filePath;
|
||||||
|
QFile* file;
|
||||||
|
long long bytesSent;
|
||||||
|
long long filesize;
|
||||||
|
FileStatus status;
|
||||||
|
FileDirection direction;
|
||||||
|
QTimer* sendTimer;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CORESTRUCTS_H
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cstring.h"
|
#include "cstring.h"
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
CString::CString(const QString& string)
|
CString::CString(const QString& string)
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,7 +18,8 @@
|
||||||
#define CSTRING_H
|
#define CSTRING_H
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <QString>
|
|
||||||
|
class QString;
|
||||||
|
|
||||||
class CString
|
class CString
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,15 +15,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "filetransferinstance.h"
|
#include "filetransferinstance.h"
|
||||||
#include "widget/widget.h"
|
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
#include "math.h"
|
#include <math.h>
|
||||||
#include "style.h"
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QPixmap>
|
|
||||||
#include <QPainter>
|
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QBuffer>
|
#include <QBuffer>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
uint FileTransferInstance::Idconter = 0;
|
uint FileTransferInstance::Idconter = 0;
|
||||||
|
|
||||||
|
@ -33,6 +30,7 @@ FileTransferInstance::FileTransferInstance(ToxFile File)
|
||||||
{
|
{
|
||||||
id = Idconter++;
|
id = Idconter++;
|
||||||
state = tsPending;
|
state = tsPending;
|
||||||
|
remotePaused = false;
|
||||||
|
|
||||||
filename = File.fileName;
|
filename = File.fileName;
|
||||||
size = getHumanReadableSize(File.filesize);
|
size = getHumanReadableSize(File.filesize);
|
||||||
|
@ -64,7 +62,7 @@ void FileTransferInstance::onFileTransferInfo(int FriendId, int FileNum, int64_t
|
||||||
if (FileNum != fileNum || FriendId != friendId || Direction != direction)
|
if (FileNum != fileNum || FriendId != friendId || Direction != direction)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
state = tsProcessing;
|
// state = tsProcessing;
|
||||||
QDateTime newtime = QDateTime::currentDateTime();
|
QDateTime newtime = QDateTime::currentDateTime();
|
||||||
int timediff = lastUpdate.secsTo(newtime);
|
int timediff = lastUpdate.secsTo(newtime);
|
||||||
if (timediff <= 0)
|
if (timediff <= 0)
|
||||||
|
@ -93,7 +91,7 @@ void FileTransferInstance::onFileTransferCancelled(int FriendId, int FileNum, To
|
||||||
{
|
{
|
||||||
if (FileNum != fileNum || FriendId != friendId || Direction != direction)
|
if (FileNum != fileNum || FriendId != friendId || Direction != direction)
|
||||||
return;
|
return;
|
||||||
disconnect(Widget::getInstance()->getCore(),0,this,0);
|
disconnect(Core::getInstance(),0,this,0);
|
||||||
state = tsCanceled;
|
state = tsCanceled;
|
||||||
|
|
||||||
emit stateUpdated();
|
emit stateUpdated();
|
||||||
|
@ -103,7 +101,7 @@ void FileTransferInstance::onFileTransferFinished(ToxFile File)
|
||||||
{
|
{
|
||||||
if (File.fileNum != fileNum || File.friendId != friendId || File.direction != direction)
|
if (File.fileNum != fileNum || File.friendId != friendId || File.direction != direction)
|
||||||
return;
|
return;
|
||||||
disconnect(Widget::getInstance()->getCore(),0,this,0);
|
disconnect(Core::getInstance(),0,this,0);
|
||||||
|
|
||||||
if (File.direction == ToxFile::RECEIVING)
|
if (File.direction == ToxFile::RECEIVING)
|
||||||
{
|
{
|
||||||
|
@ -124,16 +122,47 @@ void FileTransferInstance::onFileTransferFinished(ToxFile File)
|
||||||
emit stateUpdated();
|
emit stateUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileTransferInstance::onFileTransferAccepted(ToxFile File)
|
||||||
|
{
|
||||||
|
if (File.fileNum != fileNum || File.friendId != friendId || File.direction != direction)
|
||||||
|
return;
|
||||||
|
|
||||||
|
remotePaused = false;
|
||||||
|
state = tsProcessing;
|
||||||
|
|
||||||
|
emit stateUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileTransferInstance::onFileTransferRemotePausedUnpaused(ToxFile File, bool paused)
|
||||||
|
{
|
||||||
|
if (File.fileNum != fileNum || File.friendId != friendId || File.direction != direction)
|
||||||
|
return;
|
||||||
|
|
||||||
|
remotePaused = paused;
|
||||||
|
|
||||||
|
emit stateUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileTransferInstance::onFileTransferPaused(int FriendId, int FileNum, ToxFile::FileDirection Direction)
|
||||||
|
{
|
||||||
|
if (FileNum != fileNum || FriendId != friendId || Direction != direction)
|
||||||
|
return;
|
||||||
|
|
||||||
|
state = tsPaused;
|
||||||
|
|
||||||
|
emit stateUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
void FileTransferInstance::cancelTransfer()
|
void FileTransferInstance::cancelTransfer()
|
||||||
{
|
{
|
||||||
Widget::getInstance()->getCore()->cancelFileSend(friendId, fileNum);
|
Core::getInstance()->cancelFileSend(friendId, fileNum);
|
||||||
state = tsCanceled;
|
state = tsCanceled;
|
||||||
emit stateUpdated();
|
emit stateUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileTransferInstance::rejectRecvRequest()
|
void FileTransferInstance::rejectRecvRequest()
|
||||||
{
|
{
|
||||||
Widget::getInstance()->getCore()->rejectFileRecvRequest(friendId, fileNum);
|
Core::getInstance()->rejectFileRecvRequest(friendId, fileNum);
|
||||||
onFileTransferCancelled(friendId, fileNum, direction);
|
onFileTransferCancelled(friendId, fileNum, direction);
|
||||||
state = tsCanceled;
|
state = tsCanceled;
|
||||||
emit stateUpdated();
|
emit stateUpdated();
|
||||||
|
@ -159,7 +188,7 @@ void FileTransferInstance::acceptRecvRequest()
|
||||||
QString path;
|
QString path;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
path = QFileDialog::getSaveFileName(Widget::getInstance(), tr("Save a file","Title of the file saving dialog"), QDir::current().filePath(filename));
|
path = QFileDialog::getSaveFileName(0, tr("Save a file","Title of the file saving dialog"), QDir::current().filePath(filename));
|
||||||
if (path.isEmpty())
|
if (path.isEmpty())
|
||||||
return;
|
return;
|
||||||
else
|
else
|
||||||
|
@ -170,13 +199,13 @@ void FileTransferInstance::acceptRecvRequest()
|
||||||
if (isFileWritable(path))
|
if (isFileWritable(path))
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
QMessageBox::warning(Widget::getInstance(), tr("Location not writable","Title of permissions popup"), tr("You do not have permission to write that location. Choose another, or cancel the save dialog.", "text of permissions popup"));
|
QMessageBox::warning(0, tr("Location not writable","Title of permissions popup"), tr("You do not have permission to write that location. Choose another, or cancel the save dialog.", "text of permissions popup"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
savePath = path;
|
savePath = path;
|
||||||
|
|
||||||
Widget::getInstance()->getCore()->acceptFileRecvRequest(friendId, fileNum, path);
|
Core::getInstance()->acceptFileRecvRequest(friendId, fileNum, path);
|
||||||
state = tsProcessing;
|
state = tsProcessing;
|
||||||
|
|
||||||
emit stateUpdated();
|
emit stateUpdated();
|
||||||
|
@ -184,19 +213,33 @@ void FileTransferInstance::acceptRecvRequest()
|
||||||
|
|
||||||
void FileTransferInstance::pauseResumeRecv()
|
void FileTransferInstance::pauseResumeRecv()
|
||||||
{
|
{
|
||||||
Widget::getInstance()->getCore()->pauseResumeFileRecv(friendId, fileNum);
|
if (!(state == tsProcessing || state == tsPaused))
|
||||||
if (state == tsProcessing)
|
return;
|
||||||
state = tsPaused;
|
|
||||||
else state = tsProcessing;
|
if (remotePaused)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Core::getInstance()->pauseResumeFileRecv(friendId, fileNum);
|
||||||
|
// if (state == tsProcessing)
|
||||||
|
// state = tsPaused;
|
||||||
|
// else state = tsProcessing;
|
||||||
|
|
||||||
emit stateUpdated();
|
emit stateUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileTransferInstance::pauseResumeSend()
|
void FileTransferInstance::pauseResumeSend()
|
||||||
{
|
{
|
||||||
Widget::getInstance()->getCore()->pauseResumeFileSend(friendId, fileNum);
|
if (!(state == tsProcessing || state == tsPaused))
|
||||||
if (state == tsProcessing)
|
return;
|
||||||
state = tsPaused;
|
|
||||||
else state = tsProcessing;
|
if (remotePaused)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Core::getInstance()->pauseResumeFileSend(friendId, fileNum);
|
||||||
|
// if (state == tsProcessing)
|
||||||
|
// state = tsPaused;
|
||||||
|
// else state = tsProcessing;
|
||||||
|
|
||||||
emit stateUpdated();
|
emit stateUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,7 +266,15 @@ QString FileTransferInstance::getHtmlImage()
|
||||||
else if (state == tsPaused)
|
else if (state == tsPaused)
|
||||||
rightBtnImg = QImage(":/ui/fileTransferInstance/resumeFileButton.png");
|
rightBtnImg = QImage(":/ui/fileTransferInstance/resumeFileButton.png");
|
||||||
else
|
else
|
||||||
rightBtnImg = QImage(":/ui/fileTransferInstance/acceptFileButton.png");
|
{
|
||||||
|
if (direction == ToxFile::SENDING)
|
||||||
|
rightBtnImg = QImage(":/ui/fileTransferInstance/pauseGreyFileButton.png");
|
||||||
|
else
|
||||||
|
rightBtnImg = QImage(":/ui/fileTransferInstance/acceptFileButton.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remotePaused)
|
||||||
|
rightBtnImg = QImage(":/ui/fileTransferInstance/pauseGreyFileButton.png");
|
||||||
|
|
||||||
res = draw2ButtonsForm("silver", leftBtnImg, rightBtnImg);
|
res = draw2ButtonsForm("silver", leftBtnImg, rightBtnImg);
|
||||||
} else if (state == tsCanceled)
|
} else if (state == tsCanceled)
|
||||||
|
|
|
@ -17,29 +17,32 @@
|
||||||
#define FILETRANSFERINSTANCE_H
|
#define FILETRANSFERINSTANCE_H
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QLabel>
|
|
||||||
#include <QPushButton>
|
|
||||||
#include <QProgressBar>
|
|
||||||
#include <QHBoxLayout>
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
#include <QImage>
|
||||||
|
|
||||||
#include "core.h"
|
#include "corestructs.h"
|
||||||
|
|
||||||
struct ToxFile;
|
struct ToxFile;
|
||||||
|
|
||||||
class FileTransferInstance : public QObject
|
class FileTransferInstance : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
enum TransfState {tsPending, tsProcessing, tsPaused, tsFinished, tsCanceled};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit FileTransferInstance(ToxFile File);
|
explicit FileTransferInstance(ToxFile File);
|
||||||
QString getHtmlImage();
|
QString getHtmlImage();
|
||||||
uint getId(){return id;}
|
uint getId(){return id;}
|
||||||
|
TransfState getState() {return state;}
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void onFileTransferInfo(int FriendId, int FileNum, int64_t Filesize, int64_t BytesSent, ToxFile::FileDirection Direction);
|
void onFileTransferInfo(int FriendId, int FileNum, int64_t Filesize, int64_t BytesSent, ToxFile::FileDirection Direction);
|
||||||
void onFileTransferCancelled(int FriendId, int FileNum, ToxFile::FileDirection Direction);
|
void onFileTransferCancelled(int FriendId, int FileNum, ToxFile::FileDirection Direction);
|
||||||
void onFileTransferFinished(ToxFile File);
|
void onFileTransferFinished(ToxFile File);
|
||||||
|
void onFileTransferAccepted(ToxFile File);
|
||||||
|
void onFileTransferPaused(int FriendId, int FileNum, ToxFile::FileDirection Direction);
|
||||||
|
void onFileTransferRemotePausedUnpaused(ToxFile File, bool paused);
|
||||||
void pressFromHtml(QString);
|
void pressFromHtml(QString);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
@ -61,12 +64,11 @@ private:
|
||||||
QString wrapIntoForm(const QString &content, const QString &type, const QString &imgAstr, const QString &imgBstr);
|
QString wrapIntoForm(const QString &content, const QString &type, const QString &imgAstr, const QString &imgBstr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum TransfState {tsPending, tsProcessing, tsPaused, tsFinished, tsCanceled};
|
|
||||||
|
|
||||||
static uint Idconter;
|
static uint Idconter;
|
||||||
uint id;
|
uint id;
|
||||||
|
|
||||||
TransfState state;
|
TransfState state;
|
||||||
|
bool remotePaused;
|
||||||
QImage pic;
|
QImage pic;
|
||||||
QString filename, size, speed, eta;
|
QString filename, size, speed, eta;
|
||||||
QDateTime lastUpdate;
|
QDateTime lastUpdate;
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "friend.h"
|
#include "friend.h"
|
||||||
#include "friendlist.h"
|
#include "friendlist.h"
|
||||||
#include "widget/friendwidget.h"
|
#include "widget/friendwidget.h"
|
||||||
|
#include "widget/form/chatform.h"
|
||||||
|
|
||||||
Friend::Friend(int FriendId, QString UserId)
|
Friend::Friend(int FriendId, QString UserId)
|
||||||
: friendId(FriendId), userId(UserId)
|
: friendId(FriendId), userId(UserId)
|
||||||
|
|
4
friend.h
4
friend.h
|
@ -18,9 +18,10 @@
|
||||||
#define FRIEND_H
|
#define FRIEND_H
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include "widget/form/chatform.h"
|
#include "corestructs.h"
|
||||||
|
|
||||||
struct FriendWidget;
|
struct FriendWidget;
|
||||||
|
class ChatForm;
|
||||||
|
|
||||||
struct Friend
|
struct Friend
|
||||||
{
|
{
|
||||||
|
@ -38,7 +39,6 @@ public:
|
||||||
ChatForm* chatForm;
|
ChatForm* chatForm;
|
||||||
int hasNewEvents;
|
int hasNewEvents;
|
||||||
Status friendStatus;
|
Status friendStatus;
|
||||||
QPixmap avatar;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FRIEND_H
|
#endif // FRIEND_H
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
QList<Friend*> FriendList::friendList;
|
QList<Friend*> FriendList::friendList;
|
||||||
|
|
||||||
Friend* FriendList::addFriend(int friendId, QString userId)
|
Friend* FriendList::addFriend(int friendId, const QString& userId)
|
||||||
{
|
{
|
||||||
for (Friend* f : friendList)
|
for (Friend* f : friendList)
|
||||||
if (f->friendId == friendId)
|
if (f->friendId == friendId)
|
||||||
|
|
|
@ -17,16 +17,15 @@
|
||||||
#ifndef FRIENDLIST_H
|
#ifndef FRIENDLIST_H
|
||||||
#define FRIENDLIST_H
|
#define FRIENDLIST_H
|
||||||
|
|
||||||
#include <QString>
|
template <class T> class QList;
|
||||||
#include <QList>
|
|
||||||
|
|
||||||
struct Friend;
|
struct Friend;
|
||||||
|
class QString;
|
||||||
|
|
||||||
class FriendList
|
class FriendList
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FriendList();
|
FriendList();
|
||||||
static Friend* addFriend(int friendId, QString userId);
|
static Friend* addFriend(int friendId, const QString& userId);
|
||||||
static Friend* findFriend(int friendId);
|
static Friend* findFriend(int friendId);
|
||||||
static void removeFriend(int friendId);
|
static void removeFriend(int friendId);
|
||||||
|
|
||||||
|
|
15
group.cpp
15
group.cpp
|
@ -19,18 +19,18 @@
|
||||||
#include "widget/form/groupchatform.h"
|
#include "widget/form/groupchatform.h"
|
||||||
#include "friendlist.h"
|
#include "friendlist.h"
|
||||||
#include "friend.h"
|
#include "friend.h"
|
||||||
#include "widget/widget.h"
|
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
Group::Group(int GroupId, QString Name)
|
Group::Group(int GroupId, QString Name)
|
||||||
: groupId(GroupId), nPeers{0}, hasPeerInfo{false}
|
: groupId(GroupId), nPeers{0}, hasPeerInfo{false}, peerInfoTimer{new QTimer}
|
||||||
{
|
{
|
||||||
widget = new GroupWidget(groupId, Name);
|
widget = new GroupWidget(groupId, Name);
|
||||||
chatForm = new GroupChatForm(this);
|
chatForm = new GroupChatForm(this);
|
||||||
connect(&peerInfoTimer, SIGNAL(timeout()), this, SLOT(queryPeerInfo()));
|
connect(peerInfoTimer, SIGNAL(timeout()), this, SLOT(queryPeerInfo()));
|
||||||
peerInfoTimer.setInterval(500);
|
peerInfoTimer->setInterval(500);
|
||||||
peerInfoTimer.setSingleShot(false);
|
peerInfoTimer->setSingleShot(false);
|
||||||
//peerInfoTimer.start();
|
//peerInfoTimer.start();
|
||||||
|
|
||||||
//in groupchats, we only notify on messages containing your name
|
//in groupchats, we only notify on messages containing your name
|
||||||
|
@ -42,11 +42,12 @@ Group::~Group()
|
||||||
{
|
{
|
||||||
delete chatForm;
|
delete chatForm;
|
||||||
delete widget;
|
delete widget;
|
||||||
|
delete peerInfoTimer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Group::queryPeerInfo()
|
void Group::queryPeerInfo()
|
||||||
{
|
{
|
||||||
const Core* core = Widget::getInstance()->getCore();
|
const Core* core = Core::getInstance();
|
||||||
int nPeersResult = core->getGroupNumberPeers(groupId);
|
int nPeersResult = core->getGroupNumberPeers(groupId);
|
||||||
if (nPeersResult == -1)
|
if (nPeersResult == -1)
|
||||||
{
|
{
|
||||||
|
@ -86,7 +87,7 @@ void Group::queryPeerInfo()
|
||||||
{
|
{
|
||||||
qDebug() << "Group::queryPeerInfo: Successfully loaded names";
|
qDebug() << "Group::queryPeerInfo: Successfully loaded names";
|
||||||
hasPeerInfo = true;
|
hasPeerInfo = true;
|
||||||
peerInfoTimer.stop();
|
peerInfoTimer->stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
6
group.h
6
group.h
|
@ -17,15 +17,15 @@
|
||||||
#ifndef GROUP_H
|
#ifndef GROUP_H
|
||||||
#define GROUP_H
|
#define GROUP_H
|
||||||
|
|
||||||
#include <QList>
|
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QTimer>
|
#include <QObject>
|
||||||
|
|
||||||
#define RETRY_PEER_INFO_INTERVAL 500
|
#define RETRY_PEER_INFO_INTERVAL 500
|
||||||
|
|
||||||
struct Friend;
|
struct Friend;
|
||||||
class GroupWidget;
|
class GroupWidget;
|
||||||
class GroupChatForm;
|
class GroupChatForm;
|
||||||
|
class QTimer;
|
||||||
|
|
||||||
class Group : public QObject
|
class Group : public QObject
|
||||||
{
|
{
|
||||||
|
@ -47,7 +47,7 @@ public:
|
||||||
GroupWidget* widget;
|
GroupWidget* widget;
|
||||||
GroupChatForm* chatForm;
|
GroupChatForm* chatForm;
|
||||||
bool hasPeerInfo;
|
bool hasPeerInfo;
|
||||||
QTimer peerInfoTimer;
|
QTimer* peerInfoTimer;
|
||||||
int hasNewMessages, userWasMentioned;
|
int hasNewMessages, userWasMentioned;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
QList<Group*> GroupList::groupList;
|
QList<Group*> GroupList::groupList;
|
||||||
|
|
||||||
Group* GroupList::addGroup(int groupId, QString name)
|
Group* GroupList::addGroup(int groupId, const QString& name)
|
||||||
{
|
{
|
||||||
Group* newGroup = new Group(groupId, name);
|
Group* newGroup = new Group(groupId, name);
|
||||||
groupList.append(newGroup);
|
groupList.append(newGroup);
|
||||||
|
|
|
@ -17,17 +17,16 @@
|
||||||
#ifndef GROUPLIST_H
|
#ifndef GROUPLIST_H
|
||||||
#define GROUPLIST_H
|
#define GROUPLIST_H
|
||||||
|
|
||||||
#include <QString>
|
template <typename T>
|
||||||
#include <QList>
|
class QList;
|
||||||
#include <QMap>
|
|
||||||
|
|
||||||
class Group;
|
class Group;
|
||||||
|
class QString;
|
||||||
|
|
||||||
class GroupList
|
class GroupList
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GroupList();
|
GroupList();
|
||||||
static Group* addGroup(int groupId, QString name);
|
static Group* addGroup(int groupId, const QString& name);
|
||||||
static Group* findGroup(int groupId);
|
static Group* findGroup(int groupId);
|
||||||
static void removeGroup(int groupId);
|
static void removeGroup(int groupId);
|
||||||
|
|
||||||
|
|
45
main.cpp
45
main.cpp
|
@ -19,6 +19,7 @@
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QFontDatabase>
|
#include <QFontDatabase>
|
||||||
#include <QTranslator>
|
#include <QTranslator>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
@ -31,7 +32,7 @@ int main(int argc, char *argv[])
|
||||||
if (Settings::getInstance().getUseTranslations())
|
if (Settings::getInstance().getUseTranslations())
|
||||||
{
|
{
|
||||||
QString locale = QLocale::system().name().section('_', 0, 0);
|
QString locale = QLocale::system().name().section('_', 0, 0);
|
||||||
if (translator.load(locale,":translations/"))
|
if (locale=="en" || translator.load(locale,":translations/"))
|
||||||
qDebug() << "Loaded translation "+locale;
|
qDebug() << "Loaded translation "+locale;
|
||||||
else
|
else
|
||||||
qDebug() << "Error loading translation "+locale;
|
qDebug() << "Error loading translation "+locale;
|
||||||
|
@ -50,45 +51,3 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
return errorcode;
|
return errorcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** TODO
|
|
||||||
* ">using a dedicated tool to maintain a TODO list" edition
|
|
||||||
*
|
|
||||||
* QRC FILES DO YOU EVEN INTO THEM ? Fix it soon for packaging and Urras.
|
|
||||||
* Most cameras use YUYV, implement YUYV -> YUV240
|
|
||||||
* Sending large files (~380MB) "restarts" after ~10MB. Goes back to 0%, consumes twice as much ram (reloads the file?)
|
|
||||||
* => Don't load the whole file at once, load small chunks (25MB?) when needed, then free them and load the next
|
|
||||||
* Don't do anything if a friend is disconnected, don't print to the chat
|
|
||||||
* Changing online/away/busy/offline by clicking the bubble
|
|
||||||
* /me action messages
|
|
||||||
* Popup windows for adding friends and changing settings
|
|
||||||
* And logging of the chat
|
|
||||||
* Show the picture's size between name and size after transfer completion if it's a pic
|
|
||||||
* Adjust all status icons to match the mockup, including scooting the friendslist ones to the left and making the user one the same size
|
|
||||||
* Sidepanel (friendlist) should be resizeable
|
|
||||||
* An extra side panel for groupchats, like Venom does (?)
|
|
||||||
*
|
|
||||||
* In the file transfer widget:
|
|
||||||
* >There is more padding on the left side compared to the right.
|
|
||||||
* >Maybe put the file size should be in the same row as the name.
|
|
||||||
* >Right-align the ETA.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** NAMES :
|
|
||||||
Botox
|
|
||||||
Ricin
|
|
||||||
Anthrax
|
|
||||||
Sarin
|
|
||||||
Cyanide
|
|
||||||
Polonium
|
|
||||||
Mercury
|
|
||||||
Arsenic
|
|
||||||
qTox
|
|
||||||
plague
|
|
||||||
Britney
|
|
||||||
Nightshade
|
|
||||||
Belladonna
|
|
||||||
toxer
|
|
||||||
GoyIM
|
|
||||||
*/
|
|
||||||
|
|
8
qtox.pro
8
qtox.pro
|
@ -107,7 +107,10 @@ HEADERS += widget/form/addfriendform.h \
|
||||||
widget/form/genericchatform.h \
|
widget/form/genericchatform.h \
|
||||||
widget/tool/chataction.h \
|
widget/tool/chataction.h \
|
||||||
widget/chatareawidget.h \
|
widget/chatareawidget.h \
|
||||||
filetransferinstance.h
|
filetransferinstance.h \
|
||||||
|
corestructs.h \
|
||||||
|
coredefines.h \
|
||||||
|
coreav.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
widget/form/addfriendform.cpp \
|
widget/form/addfriendform.cpp \
|
||||||
|
@ -143,4 +146,5 @@ SOURCES += \
|
||||||
widget/form/genericchatform.cpp \
|
widget/form/genericchatform.cpp \
|
||||||
widget/tool/chataction.cpp \
|
widget/tool/chataction.cpp \
|
||||||
widget/chatareawidget.cpp \
|
widget/chatareawidget.cpp \
|
||||||
filetransferinstance.cpp
|
filetransferinstance.cpp \
|
||||||
|
corestructs.cpp
|
||||||
|
|
3
res.qrc
3
res.qrc
|
@ -6,7 +6,6 @@
|
||||||
<file alias="DejaVuSans.ttf">res/DejaVuSans.ttf</file>
|
<file alias="DejaVuSans.ttf">res/DejaVuSans.ttf</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
<qresource prefix="/">
|
<qresource prefix="/">
|
||||||
<file>audio/notification.wav</file>
|
|
||||||
<file>img/icon.png</file>
|
<file>img/icon.png</file>
|
||||||
<file>img/contact.png</file>
|
<file>img/contact.png</file>
|
||||||
<file>img/contact_dark.png</file>
|
<file>img/contact_dark.png</file>
|
||||||
|
@ -128,11 +127,13 @@
|
||||||
<file>ui/volButton/volButton.css</file>
|
<file>ui/volButton/volButton.css</file>
|
||||||
<file>ui/fileTransferInstance/acceptFileButton.png</file>
|
<file>ui/fileTransferInstance/acceptFileButton.png</file>
|
||||||
<file>ui/fileTransferInstance/pauseFileButton.png</file>
|
<file>ui/fileTransferInstance/pauseFileButton.png</file>
|
||||||
|
<file>ui/fileTransferInstance/pauseGreyFileButton.png</file>
|
||||||
<file>ui/fileTransferInstance/resumeFileButton.png</file>
|
<file>ui/fileTransferInstance/resumeFileButton.png</file>
|
||||||
<file>ui/fileTransferInstance/stopFileButton.png</file>
|
<file>ui/fileTransferInstance/stopFileButton.png</file>
|
||||||
<file>ui/fileTransferInstance/emptyLGreenFileButton.png</file>
|
<file>ui/fileTransferInstance/emptyLGreenFileButton.png</file>
|
||||||
<file>ui/fileTransferInstance/emptyLRedFileButton.png</file>
|
<file>ui/fileTransferInstance/emptyLRedFileButton.png</file>
|
||||||
<file>ui/fileTransferInstance/emptyRGreenFileButton.png</file>
|
<file>ui/fileTransferInstance/emptyRGreenFileButton.png</file>
|
||||||
<file>ui/fileTransferInstance/emptyRRedFileButton.png</file>
|
<file>ui/fileTransferInstance/emptyRRedFileButton.png</file>
|
||||||
|
<file>audio/notification.pcm</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
|
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "smileypack.h"
|
#include "smileypack.h"
|
||||||
#include "widget/widget.h"
|
|
||||||
|
|
||||||
|
#include <QFont>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
|
|
@ -18,8 +18,7 @@
|
||||||
#define SETTINGS_HPP
|
#define SETTINGS_HPP
|
||||||
|
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QMainWindow>
|
#include <QObject>
|
||||||
#include <QSplitter>
|
|
||||||
|
|
||||||
class Settings : public QObject
|
class Settings : public QObject
|
||||||
{
|
{
|
||||||
|
|
17
simple_make.sh
Executable file
17
simple_make.sh
Executable file
|
@ -0,0 +1,17 @@
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
if which apt-get; then
|
||||||
|
sudo apt-get install build-essential qt5-qmake qt5-default libopenal-dev libopencv-dev \
|
||||||
|
libtool autotools-dev automake checkinstall check libopus-dev libvpx-dev
|
||||||
|
elif which pacman; then
|
||||||
|
sudo pacman -S --needed base-devel qt5 opencv openal opus vpx
|
||||||
|
elif which yum; then
|
||||||
|
yum groupinstall "Development Tools"
|
||||||
|
yum install qt-devel qt-doc qt-creator opencv-devel openal-soft-devel libtool autoconf automake check check-devel
|
||||||
|
else
|
||||||
|
echo "Unknown package manager, attempting to compile anyways"
|
||||||
|
fi
|
||||||
|
|
||||||
|
./bootstrap.sh
|
||||||
|
qmake
|
||||||
|
make
|
|
@ -19,8 +19,14 @@
|
||||||
|
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QtXml>
|
#include <QIcon>
|
||||||
#include <QDebug>
|
#include <QPixmap>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QDomDocument>
|
||||||
|
#include <QDomElement>
|
||||||
|
#include <QBuffer>
|
||||||
|
#include <QStringBuilder>
|
||||||
|
|
||||||
SmileyPack::SmileyPack()
|
SmileyPack::SmileyPack()
|
||||||
{
|
{
|
||||||
|
|
2
style.h
2
style.h
|
@ -17,7 +17,7 @@
|
||||||
#ifndef STYLE_H
|
#ifndef STYLE_H
|
||||||
#define STYLE_H
|
#define STYLE_H
|
||||||
|
|
||||||
#include <QString>
|
class QString;
|
||||||
|
|
||||||
class Style
|
class Style
|
||||||
{
|
{
|
||||||
|
|
BIN
ui/fileTransferInstance/pauseGreyFileButton.png
Normal file
BIN
ui/fileTransferInstance/pauseGreyFileButton.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 244 B |
Binary file not shown.
Before Width: | Height: | Size: 244 B After Width: | Height: | Size: 403 B |
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include <QMessageBox>
|
#include "widget.h"
|
||||||
|
|
||||||
using namespace cv;
|
using namespace cv;
|
||||||
|
|
||||||
|
@ -114,3 +114,8 @@ vpx_image Camera::getLastVPXImage()
|
||||||
}
|
}
|
||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Camera* Camera::getInstance()
|
||||||
|
{
|
||||||
|
return Widget::getInstance()->getCamera();
|
||||||
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ class Camera
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Camera();
|
Camera();
|
||||||
|
static Camera* getInstance(); ///< Returns the global widget's Camera instance
|
||||||
void suscribe(); ///< Call this once before trying to get frames
|
void suscribe(); ///< Call this once before trying to get frames
|
||||||
void unsuscribe(); ///< Call this once when you don't need frames anymore
|
void unsuscribe(); ///< Call this once when you don't need frames anymore
|
||||||
cv::Mat getLastFrame(); ///< Get the last captured frame
|
cv::Mat getLastFrame(); ///< Get the last captured frame
|
||||||
|
|
|
@ -15,23 +15,49 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "chatareawidget.h"
|
#include "chatareawidget.h"
|
||||||
#include <QAbstractTextDocumentLayout>
|
#include "widget/tool/chataction.h"
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
|
#include <QDesktopServices>
|
||||||
|
#include <QTextTable>
|
||||||
|
#include <QAbstractTextDocumentLayout>
|
||||||
|
|
||||||
ChatAreaWidget::ChatAreaWidget(QWidget *parent) :
|
ChatAreaWidget::ChatAreaWidget(QWidget *parent) :
|
||||||
QTextEdit(parent)
|
QTextBrowser(parent)
|
||||||
{
|
{
|
||||||
setReadOnly(true);
|
setReadOnly(true);
|
||||||
viewport()->setCursor(Qt::ArrowCursor);
|
viewport()->setCursor(Qt::ArrowCursor);
|
||||||
setContextMenuPolicy(Qt::CustomContextMenu);
|
setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
setUndoRedoEnabled(false);
|
setUndoRedoEnabled(false);
|
||||||
|
|
||||||
|
setOpenExternalLinks(false);
|
||||||
|
setOpenLinks(false);
|
||||||
|
setAcceptRichText(false);
|
||||||
|
|
||||||
|
chatTextTable = textCursor().insertTable(1,3);
|
||||||
|
|
||||||
|
QTextTableFormat tableFormat;
|
||||||
|
tableFormat.setColumnWidthConstraints({QTextLength(QTextLength::VariableLength,0),
|
||||||
|
QTextLength(QTextLength::PercentageLength,100),
|
||||||
|
QTextLength(QTextLength::VariableLength,0)});
|
||||||
|
tableFormat.setBorderStyle(QTextFrameFormat::BorderStyle_None);
|
||||||
|
chatTextTable->setFormat(tableFormat);
|
||||||
|
chatTextTable->format().setCellSpacing(2);
|
||||||
|
chatTextTable->format().setWidth(QTextLength(QTextLength::PercentageLength,100));
|
||||||
|
|
||||||
|
nameFormat.setAlignment(Qt::AlignRight);
|
||||||
|
nameFormat.setNonBreakableLines(true);
|
||||||
|
dateFormat.setAlignment(Qt::AlignLeft);
|
||||||
|
dateFormat.setNonBreakableLines(true);
|
||||||
|
|
||||||
|
connect(this, &ChatAreaWidget::anchorClicked, this, &ChatAreaWidget::onAnchorClicked);
|
||||||
|
connect(verticalScrollBar(), SIGNAL(rangeChanged(int,int)), this, SLOT(onSliderRangeChanged()));
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatAreaWidget::~ChatAreaWidget()
|
ChatAreaWidget::~ChatAreaWidget()
|
||||||
{
|
{
|
||||||
for (ChatAction *it : messages)
|
for (ChatAction* action : messages)
|
||||||
delete it;
|
delete action;
|
||||||
|
messages.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatAreaWidget::mouseReleaseEvent(QMouseEvent * event)
|
void ChatAreaWidget::mouseReleaseEvent(QMouseEvent * event)
|
||||||
|
@ -65,16 +91,9 @@ void ChatAreaWidget::mouseReleaseEvent(QMouseEvent * event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ChatAreaWidget::getHtmledMessages()
|
void ChatAreaWidget::onAnchorClicked(const QUrl &url)
|
||||||
{
|
{
|
||||||
QString res("<table width=100%>\n");
|
QDesktopServices::openUrl(url);
|
||||||
|
|
||||||
for (ChatAction *it : messages)
|
|
||||||
{
|
|
||||||
res += it->getHtml();
|
|
||||||
}
|
|
||||||
res += "</table>";
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatAreaWidget::insertMessage(ChatAction *msgAction)
|
void ChatAreaWidget::insertMessage(ChatAction *msgAction)
|
||||||
|
@ -82,31 +101,33 @@ void ChatAreaWidget::insertMessage(ChatAction *msgAction)
|
||||||
if (msgAction == nullptr)
|
if (msgAction == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
messages.append(msgAction);
|
checkSlider();
|
||||||
//updateChatContent();
|
|
||||||
|
|
||||||
moveCursor(QTextCursor::End);
|
int row = chatTextTable->rows() - 1;
|
||||||
moveCursor(QTextCursor::PreviousCell);
|
chatTextTable->cellAt(row,0).firstCursorPosition().setBlockFormat(nameFormat);
|
||||||
insertHtml(msgAction->getHtml());
|
chatTextTable->cellAt(row,2).firstCursorPosition().setBlockFormat(dateFormat);
|
||||||
|
QTextCursor cur = chatTextTable->cellAt(row,1).firstCursorPosition();
|
||||||
|
cur.clearSelection();
|
||||||
|
cur.setKeepPositionOnInsert(true);
|
||||||
|
chatTextTable->cellAt(row,0).firstCursorPosition().insertHtml(msgAction->getName());
|
||||||
|
chatTextTable->cellAt(row,1).firstCursorPosition().insertHtml(msgAction->getMessage());
|
||||||
|
chatTextTable->cellAt(row,2).firstCursorPosition().insertHtml(msgAction->getDate());
|
||||||
|
chatTextTable->appendRows(1);
|
||||||
|
|
||||||
|
msgAction->setTextCursor(cur);
|
||||||
|
|
||||||
|
messages.append(msgAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatAreaWidget::updateChatContent()
|
void ChatAreaWidget::onSliderRangeChanged()
|
||||||
|
{
|
||||||
|
QScrollBar* scroll = verticalScrollBar();
|
||||||
|
if (lockSliderToBottom)
|
||||||
|
scroll->setValue(scroll->maximum());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatAreaWidget::checkSlider()
|
||||||
{
|
{
|
||||||
QScrollBar* scroll = verticalScrollBar();
|
QScrollBar* scroll = verticalScrollBar();
|
||||||
lockSliderToBottom = scroll && scroll->value() == scroll->maximum();
|
lockSliderToBottom = scroll && scroll->value() == scroll->maximum();
|
||||||
|
|
||||||
setUpdatesEnabled(false);
|
|
||||||
setHtml(getHtmledMessages());
|
|
||||||
setUpdatesEnabled(true);
|
|
||||||
if (lockSliderToBottom)
|
|
||||||
sliderPosition = scroll->maximum();
|
|
||||||
|
|
||||||
scroll->setValue(sliderPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChatAreaWidget::clearMessages()
|
|
||||||
{
|
|
||||||
for (ChatAction *it : messages)
|
|
||||||
delete it;
|
|
||||||
updateChatContent();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,18 +17,19 @@
|
||||||
#ifndef CHATAREAWIDGET_H
|
#ifndef CHATAREAWIDGET_H
|
||||||
#define CHATAREAWIDGET_H
|
#define CHATAREAWIDGET_H
|
||||||
|
|
||||||
#include <QTextEdit>
|
#include <QTextBrowser>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include "widget/tool/chataction.h"
|
|
||||||
|
|
||||||
class ChatAreaWidget : public QTextEdit
|
class ChatAction;
|
||||||
|
class QTextTable;
|
||||||
|
|
||||||
|
class ChatAreaWidget : public QTextBrowser
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit ChatAreaWidget(QWidget *parent = 0);
|
explicit ChatAreaWidget(QWidget *parent = 0);
|
||||||
virtual ~ChatAreaWidget();
|
virtual ~ChatAreaWidget();
|
||||||
void insertMessage(ChatAction *msgAction);
|
void insertMessage(ChatAction *msgAction);
|
||||||
void clearMessages();
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void onFileTranfertInterract(QString widgetName, QString buttonName);
|
void onFileTranfertInterract(QString widgetName, QString buttonName);
|
||||||
|
@ -36,14 +37,18 @@ signals:
|
||||||
protected:
|
protected:
|
||||||
void mouseReleaseEvent(QMouseEvent * event);
|
void mouseReleaseEvent(QMouseEvent * event);
|
||||||
|
|
||||||
public slots:
|
private slots:
|
||||||
void updateChatContent();
|
void onAnchorClicked(const QUrl& url);
|
||||||
|
void onSliderRangeChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString getHtmledMessages();
|
void checkSlider();
|
||||||
|
|
||||||
QList<ChatAction*> messages;
|
QList<ChatAction*> messages;
|
||||||
bool lockSliderToBottom;
|
bool lockSliderToBottom;
|
||||||
int sliderPosition;
|
int sliderPosition;
|
||||||
|
QTextTable *chatTextTable;
|
||||||
|
QTextBlockFormat nameFormat, dateFormat;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CHATAREAWIDGET_H
|
#endif // CHATAREAWIDGET_H
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include "croppinglabel.h"
|
#include "croppinglabel.h"
|
||||||
#include <QResizeEvent>
|
#include <QResizeEvent>
|
||||||
|
#include <QLineEdit>
|
||||||
|
|
||||||
CroppingLabel::CroppingLabel(QWidget* parent)
|
CroppingLabel::CroppingLabel(QWidget* parent)
|
||||||
: QLabel(parent)
|
: QLabel(parent)
|
||||||
|
|
|
@ -18,7 +18,8 @@
|
||||||
#define CROPPINGLABEL_H
|
#define CROPPINGLABEL_H
|
||||||
|
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QLineEdit>
|
|
||||||
|
class QLineEdit;
|
||||||
|
|
||||||
class CroppingLabel : public QLabel
|
class CroppingLabel : public QLabel
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
#include <QFont>
|
#include <QFont>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <tox/tox.h>
|
#include <tox/tox.h>
|
||||||
|
#include "ui_mainwindow.h"
|
||||||
|
#include "core.h"
|
||||||
|
|
||||||
#define TOX_ID_LENGTH 2*TOX_FRIEND_ADDRESS_SIZE
|
#define TOX_ID_LENGTH 2*TOX_FRIEND_ADDRESS_SIZE
|
||||||
|
|
||||||
|
@ -74,6 +76,7 @@ bool AddFriendForm::isToxId(const QString &value) const
|
||||||
void AddFriendForm::showWarning(const QString &message) const
|
void AddFriendForm::showWarning(const QString &message) const
|
||||||
{
|
{
|
||||||
QMessageBox warning(main);
|
QMessageBox warning(main);
|
||||||
|
warning.setWindowTitle("Tox");
|
||||||
warning.setText(message);
|
warning.setText(message);
|
||||||
warning.setIcon(QMessageBox::Warning);
|
warning.setIcon(QMessageBox::Warning);
|
||||||
warning.exec();
|
warning.exec();
|
||||||
|
@ -92,7 +95,10 @@ void AddFriendForm::onSendTriggered()
|
||||||
if (id.isEmpty()) {
|
if (id.isEmpty()) {
|
||||||
showWarning(tr("Please fill in a valid Tox ID","Tox ID of the friend you're sending a friend request to"));
|
showWarning(tr("Please fill in a valid Tox ID","Tox ID of the friend you're sending a friend request to"));
|
||||||
} else if (isToxId(id)) {
|
} else if (isToxId(id)) {
|
||||||
emit friendRequested(id, getMessage());
|
if (id.toUpper() == Core::getInstance()->getSelfId().toUpper())
|
||||||
|
showWarning(tr("You can't add yourself as a friend !","When trying to add your own Tox ID as friend"));
|
||||||
|
else
|
||||||
|
emit friendRequested(id, getMessage());
|
||||||
this->toxId.setText("");
|
this->toxId.setText("");
|
||||||
this->message.setText("");
|
this->message.setText("");
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
#ifndef ADDFRIENDFORM_H
|
#ifndef ADDFRIENDFORM_H
|
||||||
#define ADDFRIENDFORM_H
|
#define ADDFRIENDFORM_H
|
||||||
|
|
||||||
#include "ui_mainwindow.h"
|
|
||||||
|
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
|
@ -26,6 +24,8 @@
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QDnsLookup>
|
#include <QDnsLookup>
|
||||||
|
|
||||||
|
namespace Ui {class MainWindow;}
|
||||||
|
|
||||||
class AddFriendForm : public QObject
|
class AddFriendForm : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -42,8 +42,8 @@ signals:
|
||||||
void friendRequested(const QString& friendAddress, const QString& message);
|
void friendRequested(const QString& friendAddress, const QString& message);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onSendTriggered();
|
void onSendTriggered();
|
||||||
void handleDnsLookup();
|
void handleDnsLookup();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QLabel headLabel, toxIdLabel, messageLabel;
|
QLabel headLabel, toxIdLabel, messageLabel;
|
||||||
|
|
|
@ -14,14 +14,21 @@
|
||||||
See the COPYING file for more details.
|
See the COPYING file for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QScrollBar>
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QPushButton>
|
||||||
#include "chatform.h"
|
#include "chatform.h"
|
||||||
#include "friend.h"
|
#include "friend.h"
|
||||||
#include "widget/friendwidget.h"
|
#include "widget/friendwidget.h"
|
||||||
#include "filetransferinstance.h"
|
#include "filetransferinstance.h"
|
||||||
|
#include "widget/tool/chataction.h"
|
||||||
|
#include "widget/netcamview.h"
|
||||||
|
#include "widget/chatareawidget.h"
|
||||||
|
#include "widget/tool/chattextedit.h"
|
||||||
|
#include "core.h"
|
||||||
#include "widget/widget.h"
|
#include "widget/widget.h"
|
||||||
#include <QScrollBar>
|
|
||||||
#include <QFileDialog>
|
|
||||||
#include <QMessageBox>
|
|
||||||
|
|
||||||
ChatForm::ChatForm(Friend* chatFriend)
|
ChatForm::ChatForm(Friend* chatFriend)
|
||||||
: f(chatFriend)
|
: f(chatFriend)
|
||||||
|
@ -35,15 +42,15 @@ ChatForm::ChatForm(Friend* chatFriend)
|
||||||
headTextLayout->addWidget(statusMessageLabel);
|
headTextLayout->addWidget(statusMessageLabel);
|
||||||
headTextLayout->addStretch();
|
headTextLayout->addStretch();
|
||||||
|
|
||||||
connect(Widget::getInstance()->getCore(), &Core::fileSendStarted, this, &ChatForm::startFileSend);
|
connect(Core::getInstance(), &Core::fileSendStarted, this, &ChatForm::startFileSend);
|
||||||
connect(Widget::getInstance()->getCore(), &Core::videoFrameReceived, netcam, &NetCamView::updateDisplay);
|
connect(Core::getInstance(), &Core::videoFrameReceived, netcam, &NetCamView::updateDisplay);
|
||||||
connect(sendButton, &QPushButton::clicked, this, &ChatForm::onSendTriggered);
|
connect(sendButton, &QPushButton::clicked, this, &ChatForm::onSendTriggered);
|
||||||
connect(fileButton, &QPushButton::clicked, this, &ChatForm::onAttachClicked);
|
connect(fileButton, &QPushButton::clicked, this, &ChatForm::onAttachClicked);
|
||||||
connect(callButton, &QPushButton::clicked, this, &ChatForm::onCallTriggered);
|
connect(callButton, &QPushButton::clicked, this, &ChatForm::onCallTriggered);
|
||||||
connect(videoButton, &QPushButton::clicked, this, &ChatForm::onVideoCallTriggered);
|
connect(videoButton, &QPushButton::clicked, this, &ChatForm::onVideoCallTriggered);
|
||||||
connect(msgEdit, &ChatTextEdit::enterPressed, this, &ChatForm::onSendTriggered);
|
connect(msgEdit, &ChatTextEdit::enterPressed, this, &ChatForm::onSendTriggered);
|
||||||
connect(micButton, SIGNAL(clicked()), this, SLOT(onMicMuteToggle()));
|
connect(micButton, SIGNAL(clicked()), this, SLOT(onMicMuteToggle()));
|
||||||
connect(chatWidget, SIGNAL(onFileTranfertInterract(QString,QString)), this, SLOT(onFileTansBtnClicked(QString,QString)));
|
connect(chatWidget, &ChatAreaWidget::onFileTranfertInterract, this, &ChatForm::onFileTansBtnClicked);
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatForm::~ChatForm()
|
ChatForm::~ChatForm()
|
||||||
|
@ -98,10 +105,12 @@ void ChatForm::startFileSend(ToxFile file)
|
||||||
FileTransferInstance* fileTrans = new FileTransferInstance(file);
|
FileTransferInstance* fileTrans = new FileTransferInstance(file);
|
||||||
ftransWidgets.insert(fileTrans->getId(), fileTrans);
|
ftransWidgets.insert(fileTrans->getId(), fileTrans);
|
||||||
|
|
||||||
connect(Widget::getInstance()->getCore(), &Core::fileTransferInfo, fileTrans, &FileTransferInstance::onFileTransferInfo);
|
connect(Core::getInstance(), &Core::fileTransferInfo, fileTrans, &FileTransferInstance::onFileTransferInfo);
|
||||||
connect(Widget::getInstance()->getCore(), &Core::fileTransferCancelled, fileTrans, &FileTransferInstance::onFileTransferCancelled);
|
connect(Core::getInstance(), &Core::fileTransferCancelled, fileTrans, &FileTransferInstance::onFileTransferCancelled);
|
||||||
connect(Widget::getInstance()->getCore(), &Core::fileTransferFinished, fileTrans, &FileTransferInstance::onFileTransferFinished);
|
connect(Core::getInstance(), &Core::fileTransferFinished, fileTrans, &FileTransferInstance::onFileTransferFinished);
|
||||||
connect(fileTrans, SIGNAL(stateUpdated()), chatWidget, SLOT(updateChatContent()));
|
connect(Core::getInstance(), SIGNAL(fileTransferAccepted(ToxFile)), fileTrans, SLOT(onFileTransferAccepted(ToxFile)));
|
||||||
|
connect(Core::getInstance(), SIGNAL(fileTransferPaused(int,int,ToxFile::FileDirection)), fileTrans, SLOT(onFileTransferPaused(int,int,ToxFile::FileDirection)));
|
||||||
|
connect(Core::getInstance(), SIGNAL(fileTransferRemotePausedUnpaused(ToxFile,bool)), fileTrans, SLOT(onFileTransferRemotePausedUnpaused(ToxFile,bool)));
|
||||||
|
|
||||||
QString name = Widget::getInstance()->getUsername();
|
QString name = Widget::getInstance()->getUsername();
|
||||||
if (name == previousName)
|
if (name == previousName)
|
||||||
|
@ -119,10 +128,12 @@ void ChatForm::onFileRecvRequest(ToxFile file)
|
||||||
FileTransferInstance* fileTrans = new FileTransferInstance(file);
|
FileTransferInstance* fileTrans = new FileTransferInstance(file);
|
||||||
ftransWidgets.insert(fileTrans->getId(), fileTrans);
|
ftransWidgets.insert(fileTrans->getId(), fileTrans);
|
||||||
|
|
||||||
connect(Widget::getInstance()->getCore(), &Core::fileTransferInfo, fileTrans, &FileTransferInstance::onFileTransferInfo);
|
connect(Core::getInstance(), &Core::fileTransferInfo, fileTrans, &FileTransferInstance::onFileTransferInfo);
|
||||||
connect(Widget::getInstance()->getCore(), &Core::fileTransferCancelled, fileTrans, &FileTransferInstance::onFileTransferCancelled);
|
connect(Core::getInstance(), &Core::fileTransferCancelled, fileTrans, &FileTransferInstance::onFileTransferCancelled);
|
||||||
connect(Widget::getInstance()->getCore(), &Core::fileTransferFinished, fileTrans, &FileTransferInstance::onFileTransferFinished);
|
connect(Core::getInstance(), &Core::fileTransferFinished, fileTrans, &FileTransferInstance::onFileTransferFinished);
|
||||||
connect(fileTrans, SIGNAL(stateUpdated()), chatWidget, SLOT(updateChatContent()));
|
connect(Core::getInstance(), SIGNAL(fileTransferAccepted(ToxFile)), fileTrans, SLOT(onFileTransferAccepted(ToxFile)));
|
||||||
|
connect(Core::getInstance(), SIGNAL(fileTransferPaused(int,int,ToxFile::FileDirection)), fileTrans, SLOT(onFileTransferPaused(int,int,ToxFile::FileDirection)));
|
||||||
|
connect(Core::getInstance(), SIGNAL(fileTransferRemotePausedUnpaused(ToxFile,bool)), fileTrans, SLOT(onFileTransferRemotePausedUnpaused(ToxFile,bool)));
|
||||||
|
|
||||||
Widget* w = Widget::getInstance();
|
Widget* w = Widget::getInstance();
|
||||||
if (!w->isFriendWidgetCurActiveWidget(f)|| w->getIsWindowMinimized() || !w->isActiveWindow())
|
if (!w->isFriendWidgetCurActiveWidget(f)|| w->getIsWindowMinimized() || !w->isActiveWindow())
|
||||||
|
|
|
@ -18,11 +18,11 @@
|
||||||
#define CHATFORM_H
|
#define CHATFORM_H
|
||||||
|
|
||||||
#include "genericchatform.h"
|
#include "genericchatform.h"
|
||||||
#include "core.h"
|
#include "corestructs.h"
|
||||||
#include "widget/netcamview.h"
|
|
||||||
|
|
||||||
struct Friend;
|
struct Friend;
|
||||||
class FileTransferInstance;
|
class FileTransferInstance;
|
||||||
|
class NetCamView;
|
||||||
|
|
||||||
class ChatForm : public GenericChatForm
|
class ChatForm : public GenericChatForm
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,6 +15,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "filesform.h"
|
#include "filesform.h"
|
||||||
|
#include "ui_mainwindow.h"
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QUrl>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QDesktopServices>
|
||||||
|
|
||||||
FilesForm::FilesForm()
|
FilesForm::FilesForm()
|
||||||
: QObject()
|
: QObject()
|
||||||
|
|
|
@ -17,17 +17,14 @@
|
||||||
#ifndef FILESFORM_H
|
#ifndef FILESFORM_H
|
||||||
#define FILESFORM_H
|
#define FILESFORM_H
|
||||||
|
|
||||||
#include "ui_mainwindow.h"
|
#include <QListWidgetItem>
|
||||||
|
|
||||||
#include <QListWidget>
|
|
||||||
#include <QTabWidget>
|
#include <QTabWidget>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QDesktopServices>
|
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <QUrl>
|
|
||||||
#include <QDebug>
|
namespace Ui {class MainWindow;}
|
||||||
#include <QFileInfo>
|
class QListWidget;
|
||||||
|
|
||||||
class FilesForm : public QObject
|
class FilesForm : public QObject
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
#include "style.h"
|
#include "style.h"
|
||||||
#include "widget/widget.h"
|
#include "widget/widget.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
#include "widget/tool/chataction.h"
|
||||||
|
#include "widget/chatareawidget.h"
|
||||||
|
#include "widget/tool/chattextedit.h"
|
||||||
|
|
||||||
GenericChatForm::GenericChatForm(QObject *parent) :
|
GenericChatForm::GenericChatForm(QObject *parent) :
|
||||||
QObject(parent)
|
QObject(parent)
|
||||||
|
@ -200,3 +203,8 @@ void GenericChatForm::onEmoteInsertRequested(QString str)
|
||||||
|
|
||||||
msgEdit->setFocus(); // refocus so that we can continue typing
|
msgEdit->setFocus(); // refocus so that we can continue typing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GenericChatForm::focusInput()
|
||||||
|
{
|
||||||
|
msgEdit->setFocus();
|
||||||
|
}
|
||||||
|
|
|
@ -19,19 +19,18 @@
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QPoint>
|
#include <QPoint>
|
||||||
#include <QTime>
|
#include <QDateTime>
|
||||||
#include <QLabel>
|
|
||||||
#include <QHBoxLayout>
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
#include <QPushButton>
|
|
||||||
|
|
||||||
#include "widget/croppinglabel.h"
|
|
||||||
#include "widget/chatareawidget.h"
|
|
||||||
#include "widget/tool/chattextedit.h"
|
|
||||||
|
|
||||||
// Spacing in px inserted when the author of the last message changes
|
// Spacing in px inserted when the author of the last message changes
|
||||||
#define AUTHOR_CHANGE_SPACING 5
|
#define AUTHOR_CHANGE_SPACING 5
|
||||||
|
|
||||||
|
class QLabel;
|
||||||
|
class QVBoxLayout;
|
||||||
|
class QPushButton;
|
||||||
|
class CroppingLabel;
|
||||||
|
class ChatTextEdit;
|
||||||
|
class ChatAreaWidget;
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class MainWindow;
|
class MainWindow;
|
||||||
}
|
}
|
||||||
|
@ -51,6 +50,7 @@ signals:
|
||||||
void sendMessage(int, QString);
|
void sendMessage(int, QString);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
void focusInput();
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void onChatContextMenuRequested(QPoint pos);
|
void onChatContextMenuRequested(QPoint pos);
|
||||||
|
|
|
@ -17,7 +17,9 @@
|
||||||
#include "groupchatform.h"
|
#include "groupchatform.h"
|
||||||
#include "group.h"
|
#include "group.h"
|
||||||
#include "widget/groupwidget.h"
|
#include "widget/groupwidget.h"
|
||||||
#include "widget/widget.h"
|
#include "widget/tool/chattextedit.h"
|
||||||
|
#include "widget/croppinglabel.h"
|
||||||
|
#include <QPushButton>
|
||||||
|
|
||||||
GroupChatForm::GroupChatForm(Group* chatGroup)
|
GroupChatForm::GroupChatForm(Group* chatGroup)
|
||||||
: group(chatGroup)
|
: group(chatGroup)
|
||||||
|
|
|
@ -18,9 +18,8 @@
|
||||||
#define GROUPCHATFORM_H
|
#define GROUPCHATFORM_H
|
||||||
|
|
||||||
#include "genericchatform.h"
|
#include "genericchatform.h"
|
||||||
#include "widget/tool/chattextedit.h"
|
|
||||||
#include "ui_mainwindow.h"
|
|
||||||
|
|
||||||
|
namespace Ui {class MainWindow;}
|
||||||
class Group;
|
class Group;
|
||||||
|
|
||||||
class GroupChatForm : public GenericChatForm
|
class GroupChatForm : public GenericChatForm
|
||||||
|
|
|
@ -18,11 +18,14 @@
|
||||||
#include "widget/widget.h"
|
#include "widget/widget.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "smileypack.h"
|
#include "smileypack.h"
|
||||||
|
#include "ui_mainwindow.h"
|
||||||
#include <QFont>
|
#include <QFont>
|
||||||
#include <QClipboard>
|
#include <QClipboard>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include "core.h"
|
||||||
|
|
||||||
SettingsForm::SettingsForm()
|
SettingsForm::SettingsForm()
|
||||||
: QObject()
|
: QObject()
|
||||||
|
@ -32,6 +35,7 @@ SettingsForm::SettingsForm()
|
||||||
QFont bold, small;
|
QFont bold, small;
|
||||||
bold.setBold(true);
|
bold.setBold(true);
|
||||||
small.setPixelSize(13);
|
small.setPixelSize(13);
|
||||||
|
small.setKerning(false);
|
||||||
headLabel.setText(tr("User Settings","\"Headline\" of the window"));
|
headLabel.setText(tr("User Settings","\"Headline\" of the window"));
|
||||||
headLabel.setFont(bold);
|
headLabel.setFont(bold);
|
||||||
|
|
||||||
|
@ -41,7 +45,7 @@ SettingsForm::SettingsForm()
|
||||||
id.setReadOnly(true);
|
id.setReadOnly(true);
|
||||||
id.setFrameStyle(QFrame::NoFrame);
|
id.setFrameStyle(QFrame::NoFrame);
|
||||||
id.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
id.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
id.setFixedHeight(id.document()->size().height());
|
id.setFixedHeight(id.document()->size().height()*2);
|
||||||
|
|
||||||
profilesLabel.setText(tr("Available profiles:", "Labels the profile selection box"));
|
profilesLabel.setText(tr("Available profiles:", "Labels the profile selection box"));
|
||||||
loadConf.setText(tr("Load profile", "button to load selected profile"));
|
loadConf.setText(tr("Load profile", "button to load selected profile"));
|
||||||
|
@ -120,12 +124,14 @@ QList<QString> SettingsForm::searchProfiles()
|
||||||
|
|
||||||
QString SettingsForm::getSelectedSavePath()
|
QString SettingsForm::getSelectedSavePath()
|
||||||
{
|
{
|
||||||
return Settings::getSettingsDirPath() + QDir::separator() + profiles.currentText() + Widget::getInstance()->getCore()->TOX_EXT;
|
return Settings::getSettingsDirPath() + QDir::separator() + profiles.currentText() + Core::getInstance()->TOX_EXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsForm::setFriendAddress(const QString& friendAddress)
|
void SettingsForm::setFriendAddress(const QString& friendAddress)
|
||||||
{
|
{
|
||||||
id.setText(friendAddress);
|
QString txt{friendAddress};
|
||||||
|
txt.insert(38,'\n');
|
||||||
|
id.setText(txt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsForm::show(Ui::MainWindow &ui)
|
void SettingsForm::show(Ui::MainWindow &ui)
|
||||||
|
@ -143,13 +149,13 @@ void SettingsForm::show(Ui::MainWindow &ui)
|
||||||
|
|
||||||
void SettingsForm::onLoadClicked()
|
void SettingsForm::onLoadClicked()
|
||||||
{
|
{
|
||||||
Widget::getInstance()->getCore()->switchConfiguration(profiles.currentText());
|
Core::getInstance()->switchConfiguration(profiles.currentText());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsForm::onExportClicked()
|
void SettingsForm::onExportClicked()
|
||||||
{
|
{
|
||||||
QString current = getSelectedSavePath();
|
QString current = getSelectedSavePath();
|
||||||
QString path = QFileDialog::getSaveFileName(0, tr("Export profile", "save dialog title"), QDir::homePath() + QDir::separator() + profiles.currentText() + Widget::getInstance()->getCore()->TOX_EXT, tr("Tox save file (*.tox)", "save dialog filter"));
|
QString path = QFileDialog::getSaveFileName(0, tr("Export profile", "save dialog title"), QDir::homePath() + QDir::separator() + profiles.currentText() + Core::getInstance()->TOX_EXT, tr("Tox save file (*.tox)", "save dialog filter"));
|
||||||
QFile::copy(getSelectedSavePath(), path);
|
QFile::copy(getSelectedSavePath(), path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,11 +182,11 @@ void SettingsForm::onImportClicked()
|
||||||
QString path = QFileDialog::getOpenFileName(0, tr("Import profile", "import dialog title"), QDir::homePath(), tr("Tox save file (*.tox)", "import dialog filter"));
|
QString path = QFileDialog::getOpenFileName(0, tr("Import profile", "import dialog title"), QDir::homePath(), tr("Tox save file (*.tox)", "import dialog filter"));
|
||||||
QFileInfo info(path);
|
QFileInfo info(path);
|
||||||
QString profile = info.completeBaseName();
|
QString profile = info.completeBaseName();
|
||||||
QString profilePath = Settings::getSettingsDirPath() + profile + Widget::getInstance()->getCore()->TOX_EXT;
|
QString profilePath = Settings::getSettingsDirPath() + profile + Core::getInstance()->TOX_EXT;
|
||||||
Settings::getInstance().setCurrentProfile(profile);
|
Settings::getInstance().setCurrentProfile(profile);
|
||||||
QFile::copy(path, profilePath);
|
QFile::copy(path, profilePath);
|
||||||
profiles.addItem(profile);
|
profiles.addItem(profile);
|
||||||
Widget::getInstance()->getCore()->switchConfiguration(profile);
|
Core::getInstance()->switchConfiguration(profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsForm::onTestVideoClicked()
|
void SettingsForm::onTestVideoClicked()
|
||||||
|
@ -195,8 +201,10 @@ void SettingsForm::onEnableIPv6Updated()
|
||||||
|
|
||||||
void SettingsForm::copyIdClicked()
|
void SettingsForm::copyIdClicked()
|
||||||
{
|
{
|
||||||
id.selectAll();;
|
id.selectAll();
|
||||||
QApplication::clipboard()->setText(id.toPlainText());
|
QString txt = id.toPlainText();
|
||||||
|
txt.replace('\n',"");
|
||||||
|
QApplication::clipboard()->setText(txt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsForm::onUseTranslationUpdated()
|
void SettingsForm::onUseTranslationUpdated()
|
||||||
|
|
|
@ -20,21 +20,16 @@
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
#include <QString>
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QSpacerItem>
|
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QTextEdit>
|
#include <QTextEdit>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include <QDir>
|
|
||||||
#include <QFileInfo>
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QMessageBox>
|
|
||||||
#include "ui_mainwindow.h"
|
|
||||||
#include "widget/selfcamview.h"
|
|
||||||
#include "widget/croppinglabel.h"
|
#include "widget/croppinglabel.h"
|
||||||
#include "core.h"
|
|
||||||
|
namespace Ui {class MainWindow;}
|
||||||
|
class QString;
|
||||||
|
|
||||||
class SettingsForm : public QObject
|
class SettingsForm : public QObject
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
#include "friendlistwidget.h"
|
#include "friendlistwidget.h"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QGridLayout>
|
||||||
|
|
||||||
FriendListWidget::FriendListWidget(QWidget *parent) :
|
FriendListWidget::FriendListWidget(QWidget *parent) :
|
||||||
QWidget(parent)
|
QWidget(parent)
|
||||||
|
|
|
@ -18,8 +18,11 @@
|
||||||
#define FRIENDLISTWIDGET_H
|
#define FRIENDLISTWIDGET_H
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QGridLayout>
|
#include <QHash>
|
||||||
#include "core.h"
|
#include "corestructs.h"
|
||||||
|
|
||||||
|
class QLayout;
|
||||||
|
class QGridLayout;
|
||||||
|
|
||||||
class FriendListWidget : public QWidget
|
class FriendListWidget : public QWidget
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,9 +18,10 @@
|
||||||
#include "group.h"
|
#include "group.h"
|
||||||
#include "grouplist.h"
|
#include "grouplist.h"
|
||||||
#include "groupwidget.h"
|
#include "groupwidget.h"
|
||||||
#include "widget.h"
|
|
||||||
#include "friendlist.h"
|
#include "friendlist.h"
|
||||||
#include "friend.h"
|
#include "friend.h"
|
||||||
|
#include "core.h"
|
||||||
|
#include "widget/form/chatform.h"
|
||||||
#include <QContextMenuEvent>
|
#include <QContextMenuEvent>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
|
|
||||||
|
@ -112,7 +113,7 @@ void FriendWidget::contextMenuEvent(QContextMenuEvent * event)
|
||||||
else if (groupActions.contains(selectedItem))
|
else if (groupActions.contains(selectedItem))
|
||||||
{
|
{
|
||||||
Group* group = groupActions[selectedItem];
|
Group* group = groupActions[selectedItem];
|
||||||
Widget::getInstance()->getCore()->groupInviteFriend(friendId, group->groupId);
|
Core::getInstance()->groupInviteFriend(friendId, group->groupId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,10 +17,7 @@
|
||||||
#ifndef FRIENDWIDGET_H
|
#ifndef FRIENDWIDGET_H
|
||||||
#define FRIENDWIDGET_H
|
#define FRIENDWIDGET_H
|
||||||
|
|
||||||
#include <QWidget>
|
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QVBoxLayout>
|
|
||||||
#include <QHBoxLayout>
|
|
||||||
|
|
||||||
#include "genericchatroomwidget.h"
|
#include "genericchatroomwidget.h"
|
||||||
#include "croppinglabel.h"
|
#include "croppinglabel.h"
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
#ifndef GROUPWIDGET_H
|
#ifndef GROUPWIDGET_H
|
||||||
#define GROUPWIDGET_H
|
#define GROUPWIDGET_H
|
||||||
|
|
||||||
#include <QWidget>
|
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include "genericchatroomwidget.h"
|
#include "genericchatroomwidget.h"
|
||||||
|
|
||||||
|
|
|
@ -16,9 +16,8 @@
|
||||||
|
|
||||||
#include "netcamview.h"
|
#include "netcamview.h"
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
#include "widget.h"
|
#include <QLabel>
|
||||||
#include <QApplication>
|
#include <QHBoxLayout>
|
||||||
#include <QtConcurrent/QtConcurrent>
|
|
||||||
|
|
||||||
static inline void fromYCbCrToRGB(
|
static inline void fromYCbCrToRGB(
|
||||||
uint8_t Y, uint8_t Cb, uint8_t Cr,
|
uint8_t Y, uint8_t Cb, uint8_t Cr,
|
||||||
|
@ -70,7 +69,7 @@ void NetCamView::updateDisplay(vpx_image* frame)
|
||||||
if (!frame->w || !frame->h)
|
if (!frame->w || !frame->h)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Core* core = Widget::getInstance()->getCore();
|
Core* core = Core::getInstance();
|
||||||
|
|
||||||
core->increaseVideoBusyness();
|
core->increaseVideoBusyness();
|
||||||
|
|
||||||
|
|
|
@ -18,14 +18,13 @@
|
||||||
#define NETCAMVIEW_H
|
#define NETCAMVIEW_H
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QHBoxLayout>
|
|
||||||
#include <QTimer>
|
|
||||||
#include <QLabel>
|
|
||||||
#include <vpx/vpx_image.h>
|
|
||||||
|
|
||||||
class QCloseEvent;
|
class QCloseEvent;
|
||||||
class QShowEvent;
|
class QShowEvent;
|
||||||
class QPainter;
|
class QPainter;
|
||||||
|
class QLabel;
|
||||||
|
class QHBoxLayout;
|
||||||
|
class vpx_image;
|
||||||
|
|
||||||
class NetCamView : public QWidget
|
class NetCamView : public QWidget
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,46 +15,45 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "selfcamview.h"
|
#include "selfcamview.h"
|
||||||
|
#include "camera.h"
|
||||||
#include <QCloseEvent>
|
#include <QCloseEvent>
|
||||||
#include <QShowEvent>
|
#include <QShowEvent>
|
||||||
|
#include <QTimer>
|
||||||
#include "widget.h"
|
#include <QLabel>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
|
||||||
using namespace cv;
|
using namespace cv;
|
||||||
|
|
||||||
SelfCamView::SelfCamView(Camera* Cam, QWidget* parent)
|
SelfCamView::SelfCamView(Camera* Cam, QWidget* parent)
|
||||||
: QWidget(parent), displayLabel{new QLabel},
|
: QWidget(parent), displayLabel{new QLabel},
|
||||||
mainLayout{new QHBoxLayout()}, cam(Cam)
|
mainLayout{new QHBoxLayout()}, cam(Cam), updateDisplayTimer{new QTimer}
|
||||||
{
|
{
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
setWindowTitle(SelfCamView::tr("Tox video test","Title of the window to test the video/webcam"));
|
setWindowTitle(SelfCamView::tr("Tox video test","Title of the window to test the video/webcam"));
|
||||||
setMinimumSize(320,240);
|
setMinimumSize(320,240);
|
||||||
|
|
||||||
updateDisplayTimer.setInterval(5);
|
updateDisplayTimer->setInterval(5);
|
||||||
updateDisplayTimer.setSingleShot(false);
|
updateDisplayTimer->setSingleShot(false);
|
||||||
|
|
||||||
displayLabel->setScaledContents(true);
|
displayLabel->setScaledContents(true);
|
||||||
|
|
||||||
mainLayout->addWidget(displayLabel);
|
mainLayout->addWidget(displayLabel);
|
||||||
|
|
||||||
connect(&updateDisplayTimer, SIGNAL(timeout()), this, SLOT(updateDisplay()));
|
connect(updateDisplayTimer, SIGNAL(timeout()), this, SLOT(updateDisplay()));
|
||||||
}
|
|
||||||
|
|
||||||
SelfCamView::~SelfCamView()
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelfCamView::closeEvent(QCloseEvent* event)
|
void SelfCamView::closeEvent(QCloseEvent* event)
|
||||||
{
|
{
|
||||||
cam->unsuscribe();
|
cam->unsuscribe();
|
||||||
updateDisplayTimer.stop();
|
updateDisplayTimer->stop();
|
||||||
event->accept();
|
event->accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelfCamView::showEvent(QShowEvent* event)
|
void SelfCamView::showEvent(QShowEvent* event)
|
||||||
{
|
{
|
||||||
cam->suscribe();
|
cam->suscribe();
|
||||||
updateDisplayTimer.start();
|
updateDisplayTimer->start();
|
||||||
event->accept();
|
event->accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,14 +18,14 @@
|
||||||
#define SELFCAMVIEW_H
|
#define SELFCAMVIEW_H
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QHBoxLayout>
|
|
||||||
#include <QTimer>
|
|
||||||
#include <QLabel>
|
|
||||||
#include "camera.h"
|
|
||||||
|
|
||||||
class QCloseEvent;
|
class QCloseEvent;
|
||||||
class QShowEvent;
|
class QShowEvent;
|
||||||
class QPainter;
|
class QPainter;
|
||||||
|
class Camera;
|
||||||
|
class QLabel;
|
||||||
|
class QHBoxLayout;
|
||||||
|
class QTimer;
|
||||||
|
|
||||||
class SelfCamView : public QWidget
|
class SelfCamView : public QWidget
|
||||||
{
|
{
|
||||||
|
@ -33,7 +33,6 @@ class SelfCamView : public QWidget
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SelfCamView(Camera* Cam, QWidget *parent=0);
|
SelfCamView(Camera* Cam, QWidget *parent=0);
|
||||||
~SelfCamView();
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void updateDisplay();
|
void updateDisplay();
|
||||||
|
@ -47,7 +46,7 @@ private:
|
||||||
QLabel *displayLabel;
|
QLabel *displayLabel;
|
||||||
QHBoxLayout* mainLayout;
|
QHBoxLayout* mainLayout;
|
||||||
Camera* cam;
|
Camera* cam;
|
||||||
QTimer updateDisplayTimer;
|
QTimer* updateDisplayTimer;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SELFCAMVIEW_H
|
#endif // SELFCAMVIEW_H
|
||||||
|
|
|
@ -18,10 +18,11 @@
|
||||||
#include "smileypack.h"
|
#include "smileypack.h"
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QBuffer>
|
#include <QBuffer>
|
||||||
|
#include "filetransferinstance.h"
|
||||||
|
|
||||||
QString ChatAction::toHtmlChars(const QString &str)
|
QString ChatAction::toHtmlChars(const QString &str)
|
||||||
{
|
{
|
||||||
static QList<QPair<QString, QString>> replaceList = {{"&","&"}, {" "," "}, {">",">"}, {"<","<"}};
|
static QList<QPair<QString, QString>> replaceList = {{"&","&"}, {">",">"}, {"<","<"}};
|
||||||
QString res = str;
|
QString res = str;
|
||||||
|
|
||||||
for (auto &it : replaceList)
|
for (auto &it : replaceList)
|
||||||
|
@ -39,37 +40,63 @@ QString ChatAction::QImage2base64(const QImage &img)
|
||||||
return ba.toBase64();
|
return ba.toBase64();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ChatAction::wrapName(const QString &name)
|
QString ChatAction::getName()
|
||||||
{
|
{
|
||||||
if (isMe)
|
if (isMe)
|
||||||
return QString("<td><div class=name_me>" + name + "</div></td>\n");
|
return QString("<div class=name_me>" + toHtmlChars(name) + "</div>");
|
||||||
else
|
else
|
||||||
return QString("<td><div class=name>" + name + "</div></td>\n");
|
return QString("<div class=name>" + toHtmlChars(name) + "</div>");
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ChatAction::wrapDate(const QString &date)
|
QString ChatAction::getDate()
|
||||||
{
|
{
|
||||||
QString res = "<td align=right><div class=date>" + date + "</div></td>\n";
|
QString res = "<div class=date>" + date + "</div>";
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ChatAction::wrapMessage(const QString &message)
|
|
||||||
{
|
|
||||||
QString res = "<td width=100%><div class=message>" + message + "</div></td>\n";
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ChatAction::wrapWholeLine(const QString &line)
|
|
||||||
{
|
|
||||||
QString res = "<tr>\n" + line + "</tr>\n";
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageAction::MessageAction(const QString &author, const QString &message, const QString &date, const bool &me) :
|
MessageAction::MessageAction(const QString &author, const QString &message, const QString &date, const bool &me) :
|
||||||
ChatAction(me)
|
ChatAction(me, author, date),
|
||||||
|
message(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageAction::setTextCursor(QTextCursor cursor)
|
||||||
|
{
|
||||||
|
// When this function is called, we're supposed to only update ourselve when needed
|
||||||
|
// Nobody should ask us to do anything with our content, we're on our own
|
||||||
|
// Except we never udpate on our own, so we can safely free our resources
|
||||||
|
|
||||||
|
(void) cursor;
|
||||||
|
message.clear();
|
||||||
|
message.squeeze();
|
||||||
|
name.clear();
|
||||||
|
name.squeeze();
|
||||||
|
date.clear();
|
||||||
|
date.squeeze();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString MessageAction::getMessage()
|
||||||
{
|
{
|
||||||
QString message_ = SmileyPack::getInstance().smileyfied(toHtmlChars(message));
|
QString message_ = SmileyPack::getInstance().smileyfied(toHtmlChars(message));
|
||||||
|
|
||||||
|
// detect urls
|
||||||
|
QRegExp exp("(www\\.|http[s]?:\\/\\/|ftp:\\/\\/)\\S+");
|
||||||
|
int offset = 0;
|
||||||
|
while ((offset = exp.indexIn(message_, offset)) != -1)
|
||||||
|
{
|
||||||
|
QString url = exp.cap();
|
||||||
|
|
||||||
|
// add scheme if not specified
|
||||||
|
if (exp.cap(1) == "www.")
|
||||||
|
url.prepend("http://");
|
||||||
|
|
||||||
|
QString htmledUrl = QString("<a href=\"%1\">%1</a>").arg(url);
|
||||||
|
message_.replace(offset, exp.cap().length(), htmledUrl);
|
||||||
|
|
||||||
|
offset += htmledUrl.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
// detect text quotes
|
||||||
QStringList messageLines = message_.split("\n");
|
QStringList messageLines = message_.split("\n");
|
||||||
message_ = "";
|
message_ = "";
|
||||||
for (QString& s : messageLines)
|
for (QString& s : messageLines)
|
||||||
|
@ -81,40 +108,62 @@ MessageAction::MessageAction(const QString &author, const QString &message, cons
|
||||||
}
|
}
|
||||||
message_ = message_.left(message_.length()-4);
|
message_ = message_.left(message_.length()-4);
|
||||||
|
|
||||||
content = wrapWholeLine(wrapName(author) + wrapMessage(message_) + wrapDate(date));
|
return QString("<div class=message>" + message_ + "</div>");
|
||||||
}
|
|
||||||
|
|
||||||
QString MessageAction::getHtml()
|
|
||||||
{
|
|
||||||
return content;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FileTransferAction::FileTransferAction(FileTransferInstance *widget, const QString &author, const QString &date, const bool &me) :
|
FileTransferAction::FileTransferAction(FileTransferInstance *widget, const QString &author, const QString &date, const bool &me) :
|
||||||
ChatAction(me),
|
ChatAction(me, author, date)
|
||||||
sender(author),
|
|
||||||
timestamp(date)
|
|
||||||
{
|
{
|
||||||
w = widget;
|
w = widget;
|
||||||
|
|
||||||
|
connect(w, &FileTransferInstance::stateUpdated, this, &FileTransferAction::updateHtml);
|
||||||
}
|
}
|
||||||
|
|
||||||
FileTransferAction::~FileTransferAction()
|
FileTransferAction::~FileTransferAction()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString FileTransferAction::getHtml()
|
QString FileTransferAction::getMessage()
|
||||||
{
|
{
|
||||||
QString widgetHtml;
|
QString widgetHtml;
|
||||||
if (w != nullptr)
|
if (w != nullptr)
|
||||||
widgetHtml = w->getHtmlImage();
|
widgetHtml = w->getHtmlImage();
|
||||||
else
|
else
|
||||||
widgetHtml = "<div class=quote>EMPTY CONTENT</div>";
|
widgetHtml = "<div class=quote>EMPTY CONTENT</div>";
|
||||||
QString res = wrapWholeLine(wrapName(sender) + wrapMessage(widgetHtml) + wrapDate(timestamp));;
|
return widgetHtml;
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString FileTransferAction::wrapMessage(const QString &message)
|
void FileTransferAction::setTextCursor(QTextCursor cursor)
|
||||||
{
|
{
|
||||||
QString res = "<td width=100%>" + message + "</td>\n";
|
cur = cursor;
|
||||||
return res;
|
cur.setKeepPositionOnInsert(true);
|
||||||
|
int end=cur.selectionEnd();
|
||||||
|
cur.setPosition(cur.position());
|
||||||
|
cur.setPosition(end, QTextCursor::KeepAnchor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileTransferAction::updateHtml()
|
||||||
|
{
|
||||||
|
if (cur.isNull())
|
||||||
|
return;
|
||||||
|
|
||||||
|
int pos = cur.selectionStart();
|
||||||
|
cur.removeSelectedText();
|
||||||
|
cur.setKeepPositionOnInsert(false);
|
||||||
|
cur.insertHtml(getMessage());
|
||||||
|
cur.setKeepPositionOnInsert(true);
|
||||||
|
int end = cur.position();
|
||||||
|
cur.setPosition(pos);
|
||||||
|
cur.setPosition(end, QTextCursor::KeepAnchor);
|
||||||
|
|
||||||
|
// Free our ressources if we'll never need to update again
|
||||||
|
if (w->getState() == FileTransferInstance::TransfState::tsCanceled
|
||||||
|
|| w->getState() == FileTransferInstance::TransfState::tsFinished)
|
||||||
|
{
|
||||||
|
name.clear();
|
||||||
|
name.squeeze();
|
||||||
|
date.clear();
|
||||||
|
date.squeeze();
|
||||||
|
cur = QTextCursor();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,26 +18,28 @@
|
||||||
#define CHATACTION_H
|
#define CHATACTION_H
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include "filetransferinstance.h"
|
#include <QTextCursor>
|
||||||
|
|
||||||
class ChatAction
|
class FileTransferInstance;
|
||||||
|
|
||||||
|
class ChatAction : public QObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ChatAction(const bool &me) : isMe(me) {;}
|
ChatAction(const bool &me, const QString &author, const QString &date) : isMe(me), name(author), date(date) {;}
|
||||||
virtual ~ChatAction(){;}
|
virtual ~ChatAction(){;}
|
||||||
virtual QString getHtml() = 0;
|
virtual void setTextCursor(QTextCursor cursor){(void)cursor;} ///< Call once, and then you MUST let the object update itself
|
||||||
|
|
||||||
|
virtual QString getName();
|
||||||
|
virtual QString getMessage() = 0;
|
||||||
|
virtual QString getDate();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QString toHtmlChars(const QString &str);
|
QString toHtmlChars(const QString &str);
|
||||||
QString QImage2base64(const QImage &img);
|
QString QImage2base64(const QImage &img);
|
||||||
|
|
||||||
virtual QString wrapName(const QString &name);
|
protected:
|
||||||
virtual QString wrapDate(const QString &date);
|
|
||||||
virtual QString wrapMessage(const QString &message);
|
|
||||||
virtual QString wrapWholeLine(const QString &line);
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool isMe;
|
bool isMe;
|
||||||
|
QString name, date;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MessageAction : public ChatAction
|
class MessageAction : public ChatAction
|
||||||
|
@ -45,23 +47,28 @@ class MessageAction : public ChatAction
|
||||||
public:
|
public:
|
||||||
MessageAction(const QString &author, const QString &message, const QString &date, const bool &me);
|
MessageAction(const QString &author, const QString &message, const QString &date, const bool &me);
|
||||||
virtual ~MessageAction(){;}
|
virtual ~MessageAction(){;}
|
||||||
virtual QString getHtml();
|
virtual QString getMessage();
|
||||||
|
virtual void setTextCursor(QTextCursor cursor) final;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString content;
|
QString message;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FileTransferAction : public ChatAction
|
class FileTransferAction : public ChatAction
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
FileTransferAction(FileTransferInstance *widget, const QString &author, const QString &date, const bool &me);
|
FileTransferAction(FileTransferInstance *widget, const QString &author, const QString &date, const bool &me);
|
||||||
virtual ~FileTransferAction();
|
virtual ~FileTransferAction();
|
||||||
virtual QString getHtml();
|
virtual QString getMessage();
|
||||||
virtual QString wrapMessage(const QString &message);
|
virtual void setTextCursor(QTextCursor cursor) final;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void updateHtml();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FileTransferInstance *w;
|
FileTransferInstance *w;
|
||||||
QString sender, timestamp;
|
QTextCursor cur;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CHATACTION_H
|
#endif // CHATACTION_H
|
||||||
|
|
|
@ -21,6 +21,7 @@ ChatTextEdit::ChatTextEdit(QWidget *parent) :
|
||||||
QTextEdit(parent)
|
QTextEdit(parent)
|
||||||
{
|
{
|
||||||
setPlaceholderText("Type your message here...");
|
setPlaceholderText("Type your message here...");
|
||||||
|
setAcceptRichText(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatTextEdit::keyPressEvent(QKeyEvent * event)
|
void ChatTextEdit::keyPressEvent(QKeyEvent * event)
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include "widget.h"
|
#include "widget.h"
|
||||||
#include "ui_mainwindow.h"
|
#include "ui_mainwindow.h"
|
||||||
|
#include "core.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "friend.h"
|
#include "friend.h"
|
||||||
#include "friendlist.h"
|
#include "friendlist.h"
|
||||||
|
@ -26,17 +27,19 @@
|
||||||
#include "widget/groupwidget.h"
|
#include "widget/groupwidget.h"
|
||||||
#include "widget/form/groupchatform.h"
|
#include "widget/form/groupchatform.h"
|
||||||
#include "style.h"
|
#include "style.h"
|
||||||
|
#include "selfcamview.h"
|
||||||
|
#include "widget/friendlistwidget.h"
|
||||||
|
#include "camera.h"
|
||||||
|
#include "widget/form/chatform.h"
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QTextStream>
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
#include <QDesktopWidget>
|
|
||||||
#include <QCursor>
|
|
||||||
#include <QSettings>
|
|
||||||
#include <QClipboard>
|
#include <QClipboard>
|
||||||
|
#include <QThread>
|
||||||
|
#include <tox/tox.h>
|
||||||
|
|
||||||
Widget *Widget::instance{nullptr};
|
Widget *Widget::instance{nullptr};
|
||||||
|
|
||||||
|
@ -382,13 +385,15 @@ void Widget::setStatusMessage(const QString &statusMessage)
|
||||||
|
|
||||||
void Widget::addFriend(int friendId, const QString &userId)
|
void Widget::addFriend(int friendId, const QString &userId)
|
||||||
{
|
{
|
||||||
qDebug() << "Adding friend with id "+userId;
|
|
||||||
|
qDebug() << "Widget: Adding friend with id "+userId;
|
||||||
Friend* newfriend = FriendList::addFriend(friendId, userId);
|
Friend* newfriend = FriendList::addFriend(friendId, userId);
|
||||||
QLayout* layout = contactListWidget->getFriendLayout(Status::Offline);
|
QLayout* layout = contactListWidget->getFriendLayout(Status::Offline);
|
||||||
layout->addWidget(newfriend->widget);
|
layout->addWidget(newfriend->widget);
|
||||||
connect(newfriend->widget, SIGNAL(chatroomWidgetClicked(GenericChatroomWidget*)), this, SLOT(onChatroomWidgetClicked(GenericChatroomWidget*)));
|
connect(newfriend->widget, SIGNAL(chatroomWidgetClicked(GenericChatroomWidget*)), this, SLOT(onChatroomWidgetClicked(GenericChatroomWidget*)));
|
||||||
connect(newfriend->widget, SIGNAL(removeFriend(int)), this, SLOT(removeFriend(int)));
|
connect(newfriend->widget, SIGNAL(removeFriend(int)), this, SLOT(removeFriend(int)));
|
||||||
connect(newfriend->widget, SIGNAL(copyFriendIdToClipboard(int)), this, SLOT(copyFriendIdToClipboard(int)));
|
connect(newfriend->widget, SIGNAL(copyFriendIdToClipboard(int)), this, SLOT(copyFriendIdToClipboard(int)));
|
||||||
|
connect(newfriend->widget, SIGNAL(chatroomWidgetClicked(GenericChatroomWidget*)), newfriend->chatForm, SLOT(focusInput()));
|
||||||
connect(newfriend->chatForm, SIGNAL(sendMessage(int,QString)), core, SLOT(sendMessage(int,QString)));
|
connect(newfriend->chatForm, SIGNAL(sendMessage(int,QString)), core, SLOT(sendMessage(int,QString)));
|
||||||
connect(newfriend->chatForm, SIGNAL(sendFile(int32_t, QString, QString, long long)), core, SLOT(sendFile(int32_t, QString, QString, long long)));
|
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(answerCall(int)), core, SLOT(answerCall(int)));
|
||||||
|
@ -510,7 +515,7 @@ void Widget::newMessageAlert()
|
||||||
{
|
{
|
||||||
QApplication::alert(this);
|
QApplication::alert(this);
|
||||||
|
|
||||||
static QFile sndFile(":audio/notification.wav");
|
static QFile sndFile(":audio/notification.pcm");
|
||||||
static QByteArray sndData;
|
static QByteArray sndData;
|
||||||
if (sndData.isEmpty())
|
if (sndData.isEmpty())
|
||||||
{
|
{
|
||||||
|
@ -521,7 +526,7 @@ void Widget::newMessageAlert()
|
||||||
|
|
||||||
ALuint buffer;
|
ALuint buffer;
|
||||||
alGenBuffers(1, &buffer);
|
alGenBuffers(1, &buffer);
|
||||||
alBufferData(buffer, AL_FORMAT_STEREO16, sndData.data(), sndData.size(), 44100);
|
alBufferData(buffer, AL_FORMAT_MONO16, sndData.data(), sndData.size(), 44100);
|
||||||
alSourcei(core->alMainSource, AL_BUFFER, buffer);
|
alSourcei(core->alMainSource, AL_BUFFER, buffer);
|
||||||
alSourcePlay(core->alMainSource);
|
alSourcePlay(core->alMainSource);
|
||||||
}
|
}
|
||||||
|
@ -608,7 +613,12 @@ void Widget::onGroupNamelistChanged(int groupnumber, int peernumber, uint8_t Cha
|
||||||
|
|
||||||
TOX_CHAT_CHANGE change = static_cast<TOX_CHAT_CHANGE>(Change);
|
TOX_CHAT_CHANGE change = static_cast<TOX_CHAT_CHANGE>(Change);
|
||||||
if (change == TOX_CHAT_CHANGE_PEER_ADD)
|
if (change == TOX_CHAT_CHANGE_PEER_ADD)
|
||||||
g->addPeer(peernumber,"<Unknown>");
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
else if (change == TOX_CHAT_CHANGE_PEER_DEL)
|
else if (change == TOX_CHAT_CHANGE_PEER_DEL)
|
||||||
g->removePeer(peernumber);
|
g->removePeer(peernumber);
|
||||||
else if (change == TOX_CHAT_CHANGE_PEER_NAME)
|
else if (change == TOX_CHAT_CHANGE_PEER_NAME)
|
||||||
|
@ -650,6 +660,7 @@ Group *Widget::createGroup(int groupId)
|
||||||
|
|
||||||
connect(newgroup->widget, SIGNAL(chatroomWidgetClicked(GenericChatroomWidget*)), this, SLOT(onChatroomWidgetClicked(GenericChatroomWidget*)));
|
connect(newgroup->widget, SIGNAL(chatroomWidgetClicked(GenericChatroomWidget*)), this, SLOT(onChatroomWidgetClicked(GenericChatroomWidget*)));
|
||||||
connect(newgroup->widget, SIGNAL(removeGroup(int)), this, SLOT(removeGroup(int)));
|
connect(newgroup->widget, SIGNAL(removeGroup(int)), this, SLOT(removeGroup(int)));
|
||||||
|
connect(newgroup->widget, SIGNAL(chatroomWidgetClicked(GenericChatroomWidget*)), newgroup->chatForm, SLOT(focusInput()));
|
||||||
connect(newgroup->chatForm, SIGNAL(sendMessage(int,QString)), core, SLOT(sendGroupMessage(int,QString)));
|
connect(newgroup->chatForm, SIGNAL(sendMessage(int,QString)), core, SLOT(sendGroupMessage(int,QString)));
|
||||||
return newgroup;
|
return newgroup;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,17 +17,11 @@
|
||||||
#ifndef WIDGET_H
|
#ifndef WIDGET_H
|
||||||
#define WIDGET_H
|
#define WIDGET_H
|
||||||
|
|
||||||
#include <QThread>
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QString>
|
|
||||||
#include <QHBoxLayout>
|
|
||||||
#include <QMenu>
|
|
||||||
#include "core.h"
|
|
||||||
#include "widget/form/addfriendform.h"
|
#include "widget/form/addfriendform.h"
|
||||||
#include "widget/form/settingsform.h"
|
#include "widget/form/settingsform.h"
|
||||||
#include "widget/form/filesform.h"
|
#include "widget/form/filesform.h"
|
||||||
#include "camera.h"
|
#include "corestructs.h"
|
||||||
#include "friendlistwidget.h"
|
|
||||||
|
|
||||||
#define PIXELS_TO_ACT 7
|
#define PIXELS_TO_ACT 7
|
||||||
|
|
||||||
|
@ -38,6 +32,12 @@ class MainWindow;
|
||||||
class GenericChatroomWidget;
|
class GenericChatroomWidget;
|
||||||
class Group;
|
class Group;
|
||||||
struct Friend;
|
struct Friend;
|
||||||
|
class QSplitter;
|
||||||
|
class SelfCamView;
|
||||||
|
class QMenu;
|
||||||
|
class Core;
|
||||||
|
class Camera;
|
||||||
|
class FriendListWidget;
|
||||||
|
|
||||||
class Widget : public QMainWindow
|
class Widget : public QMainWindow
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user