mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
Initial Android support
We create a GUI class to abstract common GUI needs (showing a message box, asking a question, ...) from the actual GUI backend. We also create a Nexus class to manage the startup and lifetime of our main systems (Core, GUI, ...) instead of delegating that to Widget. Eventually, Widget will only be in charge of the Desktop GUI and AndroidGUI of the mobile GUI. Nexus will overview the system and GUI will provide a clean platform-independant interface.
This commit is contained in:
parent
2225fcaf9d
commit
46bba3f2f1
15
qtox.pro
15
qtox.pro
|
@ -80,7 +80,8 @@ android {
|
|||
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
|
||||
contains(ANDROID_TARGET_ARCH,armeabi) {
|
||||
ANDROID_EXTRA_LIBS = \
|
||||
$$ANDROID_TOOLCHAIN/lib/libopenal.so
|
||||
$$ANDROID_TOOLCHAIN/lib/libopenal.so \
|
||||
$$ANDROID_TOOLCHAIN/lib/libsodium.so
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,7 +107,7 @@ contains(JENKINS,YES) {
|
|||
# Rules for Windows, Mac OSX, and Linux
|
||||
win32 {
|
||||
RC_FILE = windows/qtox.rc
|
||||
LIBS += -L$$PWD/libs/lib -ltoxav -ltoxcore -ltoxencryptsave -ltoxdns -lsodium -lvpx -lpthread
|
||||
LIBS += -L$$PWD/libs/lib -ltoxav -ltoxcore -ltoxencryptsave -ltoxdns -lsodium -lvpx -lpthread
|
||||
LIBS += -L$$PWD/libs/lib -lopencv_core249 -lopencv_highgui249 -lopencv_imgproc249 -lOpenAL32 -lopus
|
||||
LIBS += -lopengl32 -lole32 -loleaut32 -luuid -lvfw32 -lws2_32 -liphlpapi -lz
|
||||
|
||||
|
@ -229,7 +230,10 @@ HEADERS += src/widget/form/addfriendform.h \
|
|||
src/audio.h \
|
||||
src/widget/callconfirmwidget.h \
|
||||
src/widget/systemtrayicon.h \
|
||||
src/widget/systemtrayicon_private.h
|
||||
src/widget/systemtrayicon_private.h \
|
||||
src/nexus.h \
|
||||
src/widget/gui.h \
|
||||
src/widget/androidgui.h
|
||||
|
||||
SOURCES += \
|
||||
src/widget/form/addfriendform.cpp \
|
||||
|
@ -298,7 +302,10 @@ SOURCES += \
|
|||
src/widget/form/settings/advancedform.cpp \
|
||||
src/audio.cpp \
|
||||
src/widget/callconfirmwidget.cpp \
|
||||
src/widget/systemtrayicon.cpp
|
||||
src/widget/systemtrayicon.cpp \
|
||||
src/nexus.cpp \
|
||||
src/widget/gui.cpp \
|
||||
src/widget/androidgui.cpp
|
||||
|
||||
contains(DEFINES, QTOX_FILTER_AUDIO) {
|
||||
HEADERS += src/audiofilterer.h
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
|
||||
#include "core.h"
|
||||
#include "nexus.h"
|
||||
#include "misc/cdata.h"
|
||||
#include "misc/cstring.h"
|
||||
#include "misc/settings.h"
|
||||
|
@ -106,6 +107,7 @@ Core::~Core()
|
|||
{
|
||||
qDebug() << "Deleting Core";
|
||||
|
||||
saveConfiguration();
|
||||
toxTimer->stop();
|
||||
coreThread->exit(0);
|
||||
while (coreThread->isRunning())
|
||||
|
@ -128,7 +130,7 @@ Core::~Core()
|
|||
|
||||
Core* Core::getInstance()
|
||||
{
|
||||
return Widget::getInstance()->getCore();
|
||||
return Nexus::getCore();
|
||||
}
|
||||
|
||||
void Core::make_tox()
|
||||
|
@ -223,6 +225,8 @@ void Core::make_tox()
|
|||
|
||||
void Core::start()
|
||||
{
|
||||
qDebug() << "Core: Starting up";
|
||||
|
||||
make_tox();
|
||||
|
||||
qsrand(time(nullptr));
|
||||
|
@ -1202,8 +1206,7 @@ bool Core::loadConfiguration(QString path)
|
|||
{
|
||||
configurationFile.close();
|
||||
|
||||
QString profile;
|
||||
QMetaObject::invokeMethod(Widget::getInstance(), "askProfiles", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QString, profile));
|
||||
QString profile = Settings::getInstance().askProfiles();
|
||||
|
||||
if (!profile.isEmpty())
|
||||
{
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "widget/widget.h"
|
||||
#include "misc/settings.h"
|
||||
#include "src/nexus.h"
|
||||
#include "src/ipc.h"
|
||||
#include "src/widget/toxuri.h"
|
||||
#include "src/widget/toxsave.h"
|
||||
|
@ -70,6 +71,7 @@ int main(int argc, char *argv[])
|
|||
parser.process(a);
|
||||
|
||||
Settings::getInstance(); // Build our Settings singleton as soon as QApplication is ready, not before
|
||||
|
||||
if (parser.isSet("p"))
|
||||
{
|
||||
QString profile = parser.value("p");
|
||||
|
@ -121,6 +123,8 @@ int main(int argc, char *argv[])
|
|||
AutoUpdater::installLocalUpdate(); ///< NORETURN
|
||||
#endif
|
||||
|
||||
Nexus::getInstance().start();
|
||||
|
||||
#ifndef Q_OS_ANDROID
|
||||
// Inter-process communication
|
||||
IPC ipc;
|
||||
|
@ -180,10 +184,8 @@ int main(int argc, char *argv[])
|
|||
|
||||
// Run
|
||||
a.setQuitOnLastWindowClosed(false);
|
||||
Widget* w = Widget::getInstance();
|
||||
int errorcode = a.exec();
|
||||
|
||||
delete w;
|
||||
#ifdef LOG_TO_FILE
|
||||
delete logFile;
|
||||
logFile = nullptr;
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include "smileypack.h"
|
||||
#include "src/corestructs.h"
|
||||
#include "src/misc/db/plaindb.h"
|
||||
#include "src/core.h"
|
||||
#include "src/widget/gui.h"
|
||||
|
||||
#include <QFont>
|
||||
#include <QApplication>
|
||||
|
@ -65,6 +67,70 @@ void Settings::switchProfile(const QString& profile)
|
|||
resetInstance();
|
||||
}
|
||||
|
||||
QString Settings::detectProfile()
|
||||
{
|
||||
QDir dir(getSettingsDirPath());
|
||||
QString path, profile = getCurrentProfile();
|
||||
path = dir.filePath(profile + Core::TOX_EXT);
|
||||
QFile file(path);
|
||||
if (profile.isEmpty() || !file.exists())
|
||||
{
|
||||
setCurrentProfile("");
|
||||
#if 1 // deprecation attempt
|
||||
// if the last profile doesn't exist, fall back to old "data"
|
||||
path = dir.filePath(Core::CONFIG_FILE_NAME);
|
||||
QFile file(path);
|
||||
if (file.exists())
|
||||
return path;
|
||||
else if (QFile(path = dir.filePath("tox_save")).exists()) // also import tox_save if no data
|
||||
return path;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
profile = askProfiles();
|
||||
if (profile.isEmpty())
|
||||
return "";
|
||||
else
|
||||
{
|
||||
switchProfile(profile);
|
||||
return dir.filePath(profile + Core::TOX_EXT);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return path;
|
||||
}
|
||||
|
||||
QList<QString> Settings::searchProfiles()
|
||||
{
|
||||
QList<QString> out;
|
||||
QDir dir(getSettingsDirPath());
|
||||
dir.setFilter(QDir::Files | QDir::NoDotAndDotDot);
|
||||
dir.setNameFilters(QStringList("*.tox"));
|
||||
for (QFileInfo file : dir.entryInfoList())
|
||||
out += file.completeBaseName();
|
||||
return out;
|
||||
}
|
||||
|
||||
QString Settings::askProfiles()
|
||||
{ // TODO: allow user to create new Tox ID, even if a profile already exists
|
||||
QList<QString> profiles = searchProfiles();
|
||||
if (profiles.empty()) return "";
|
||||
bool ok;
|
||||
QString profile = GUI::itemInputDialog(nullptr,
|
||||
tr("Choose a profile"),
|
||||
tr("Please choose which identity to use"),
|
||||
profiles,
|
||||
0, // which slot to start on
|
||||
false, // if the user can enter their own input
|
||||
&ok);
|
||||
if (!ok) // user cancelled
|
||||
return "";
|
||||
else
|
||||
return profile;
|
||||
}
|
||||
|
||||
|
||||
void Settings::load()
|
||||
{
|
||||
if (loaded)
|
||||
|
|
|
@ -33,6 +33,9 @@ public:
|
|||
static Settings& getInstance();
|
||||
static void resetInstance();
|
||||
void switchProfile(const QString& profile);
|
||||
QString detectProfile();
|
||||
QList<QString> searchProfiles();
|
||||
QString askProfiles();
|
||||
~Settings() = default;
|
||||
|
||||
void executeSettingsDialog(QWidget* parent);
|
||||
|
|
121
src/nexus.cpp
Normal file
121
src/nexus.cpp
Normal file
|
@ -0,0 +1,121 @@
|
|||
#include "nexus.h"
|
||||
#include "core.h"
|
||||
#include "misc/settings.h"
|
||||
#include "video/camera.h"
|
||||
#include <QThread>
|
||||
#include <QDebug>
|
||||
|
||||
#ifdef Q_OS_ANDROID
|
||||
#include <src/widget/androidgui.h>
|
||||
#else
|
||||
#include <src/widget/widget.h>
|
||||
#endif
|
||||
|
||||
Nexus::Nexus(QObject *parent) :
|
||||
QObject(parent),
|
||||
core{nullptr},
|
||||
coreThread{nullptr},
|
||||
widget{nullptr},
|
||||
androidgui{nullptr},
|
||||
started{false}
|
||||
{
|
||||
}
|
||||
|
||||
Nexus::~Nexus()
|
||||
{
|
||||
delete core;
|
||||
delete coreThread;
|
||||
#ifdef Q_OS_ANDROID
|
||||
delete androidgui;
|
||||
#else
|
||||
delete widget;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Nexus::start()
|
||||
{
|
||||
if (started)
|
||||
return;
|
||||
qDebug() << "Nexus: Starting up";
|
||||
|
||||
// Setup the environment
|
||||
qRegisterMetaType<Status>("Status");
|
||||
qRegisterMetaType<vpx_image>("vpx_image");
|
||||
qRegisterMetaType<uint8_t>("uint8_t");
|
||||
qRegisterMetaType<uint16_t>("uint16_t");
|
||||
qRegisterMetaType<const int16_t*>("const int16_t*");
|
||||
qRegisterMetaType<int32_t>("int32_t");
|
||||
qRegisterMetaType<int64_t>("int64_t");
|
||||
qRegisterMetaType<QPixmap>("QPixmap");
|
||||
qRegisterMetaType<ToxFile>("ToxFile");
|
||||
qRegisterMetaType<ToxFile::FileDirection>("ToxFile::FileDirection");
|
||||
qRegisterMetaType<Core::PasswordType>("Core::PasswordType");
|
||||
|
||||
// Create Core
|
||||
QString profilePath = Settings::getInstance().detectProfile();
|
||||
coreThread = new QThread(this);
|
||||
coreThread->setObjectName("qTox Core");
|
||||
core = new Core(Camera::getInstance(), coreThread, profilePath);
|
||||
core->moveToThread(coreThread);
|
||||
connect(coreThread, &QThread::started, core, &Core::start);
|
||||
|
||||
// Start GUI
|
||||
#ifdef Q_OS_ANDROID
|
||||
androidgui = new AndroidGUI;
|
||||
androidgui->show();
|
||||
#else
|
||||
widget = Widget::getInstance();
|
||||
#endif
|
||||
|
||||
// Connections
|
||||
#ifndef Q_OS_ANDROID
|
||||
connect(core, &Core::connected, widget, &Widget::onConnected);
|
||||
connect(core, &Core::disconnected, widget, &Widget::onDisconnected);
|
||||
connect(core, &Core::failedToStart, widget, &Widget::onFailedToStartCore);
|
||||
connect(core, &Core::badProxy, widget, &Widget::onBadProxyCore);
|
||||
connect(core, &Core::statusSet, widget, &Widget::onStatusSet);
|
||||
connect(core, &Core::usernameSet, widget, &Widget::setUsername);
|
||||
connect(core, &Core::statusMessageSet, widget, &Widget::setStatusMessage);
|
||||
connect(core, &Core::selfAvatarChanged, widget, &Widget::onSelfAvatarLoaded);
|
||||
connect(core, &Core::friendAdded, widget, &Widget::addFriend);
|
||||
connect(core, &Core::failedToAddFriend, widget, &Widget::addFriendFailed);
|
||||
connect(core, &Core::friendUsernameChanged, widget, &Widget::onFriendUsernameChanged);
|
||||
connect(core, &Core::friendStatusChanged, widget, &Widget::onFriendStatusChanged);
|
||||
connect(core, &Core::friendStatusMessageChanged, widget, &Widget::onFriendStatusMessageChanged);
|
||||
connect(core, &Core::friendRequestReceived, widget, &Widget::onFriendRequestReceived);
|
||||
connect(core, &Core::friendMessageReceived, widget, &Widget::onFriendMessageReceived);
|
||||
connect(core, &Core::receiptRecieved, widget, &Widget::onReceiptRecieved);
|
||||
connect(core, &Core::groupInviteReceived, widget, &Widget::onGroupInviteReceived);
|
||||
connect(core, &Core::groupMessageReceived, widget, &Widget::onGroupMessageReceived);
|
||||
connect(core, &Core::groupNamelistChanged, widget, &Widget::onGroupNamelistChanged);
|
||||
connect(core, &Core::groupTitleChanged, widget, &Widget::onGroupTitleChanged);
|
||||
connect(core, &Core::emptyGroupCreated, widget, &Widget::onEmptyGroupCreated);
|
||||
connect(core, &Core::avInvite, widget, &Widget::playRingtone);
|
||||
connect(core, &Core::blockingClearContacts, widget, &Widget::clearContactsList, Qt::BlockingQueuedConnection);
|
||||
connect(core, &Core::friendTypingChanged, widget, &Widget::onFriendTypingChanged);
|
||||
|
||||
connect(core, SIGNAL(messageSentResult(int,QString,int)), widget, SLOT(onMessageSendResult(int,QString,int)));
|
||||
connect(core, SIGNAL(groupSentResult(int,QString,int)), widget, SLOT(onGroupSendResult(int,QString,int)));
|
||||
|
||||
connect(widget, &Widget::statusSet, core, &Core::setStatus);
|
||||
connect(widget, &Widget::friendRequested, core, &Core::requestFriendship);
|
||||
connect(widget, &Widget::friendRequestAccepted, core, &Core::acceptFriendRequest);
|
||||
connect(widget, &Widget::changeProfile, core, &Core::switchConfiguration);
|
||||
#endif
|
||||
|
||||
// Start Core
|
||||
coreThread->start();
|
||||
|
||||
started = true;
|
||||
}
|
||||
|
||||
Nexus& Nexus::getInstance()
|
||||
{
|
||||
static Nexus nexus;
|
||||
return nexus;
|
||||
}
|
||||
|
||||
Core* Nexus::getCore()
|
||||
{
|
||||
return getInstance().core;
|
||||
}
|
35
src/nexus.h
Normal file
35
src/nexus.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
#ifndef NEXUS_H
|
||||
#define NEXUS_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class QThread;
|
||||
class Core;
|
||||
class Widget;
|
||||
class AndroidGUI;
|
||||
|
||||
/// This class is in charge of connecting various systems together
|
||||
/// and forwarding signals appropriately to the right objects
|
||||
/// It is in charge of starting the GUI and the Core
|
||||
class Nexus : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
void start(); ///< Will initialise the systems (GUI, Core, ...)
|
||||
|
||||
static Nexus& getInstance();
|
||||
static Core* getCore(); ///< Will return 0 if not started
|
||||
|
||||
private:
|
||||
explicit Nexus(QObject *parent = 0);
|
||||
~Nexus();
|
||||
|
||||
private:
|
||||
Core* core;
|
||||
QThread* coreThread;
|
||||
Widget* widget;
|
||||
AndroidGUI* androidgui;
|
||||
bool started;
|
||||
};
|
||||
|
||||
#endif // NEXUS_H
|
13
src/widget/androidgui.cpp
Normal file
13
src/widget/androidgui.cpp
Normal file
|
@ -0,0 +1,13 @@
|
|||
#include "androidgui.h"
|
||||
#include <QLabel>
|
||||
|
||||
AndroidGUI::AndroidGUI(QWidget *parent) :
|
||||
QWidget(parent)
|
||||
{
|
||||
l = new QLabel("qTox Android", this);
|
||||
}
|
||||
|
||||
AndroidGUI::~AndroidGUI()
|
||||
{
|
||||
delete l;
|
||||
}
|
19
src/widget/androidgui.h
Normal file
19
src/widget/androidgui.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
#ifndef ANDROIDGUI_H
|
||||
#define ANDROIDGUI_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class QLabel;
|
||||
|
||||
class AndroidGUI : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AndroidGUI(QWidget *parent = 0);
|
||||
~AndroidGUI();
|
||||
|
||||
private:
|
||||
QLabel* l;
|
||||
};
|
||||
|
||||
#endif // ANDROIDGUI_H
|
|
@ -111,7 +111,7 @@ void IdentityForm::present()
|
|||
toxId->setText(Core::getInstance()->getSelfId().toString());
|
||||
toxId->setCursorPosition(0);
|
||||
bodyUI->profiles->clear();
|
||||
for (QString profile : Widget::searchProfiles())
|
||||
for (QString profile : Settings::getInstance().searchProfiles())
|
||||
bodyUI->profiles->addItem(profile);
|
||||
QString current = Settings::getInstance().getCurrentProfile();
|
||||
if (current != "")
|
||||
|
|
47
src/widget/gui.cpp
Normal file
47
src/widget/gui.cpp
Normal file
|
@ -0,0 +1,47 @@
|
|||
#include "gui.h"
|
||||
#include <QCoreApplication>
|
||||
#include <QInputDialog>
|
||||
#include <QThread>
|
||||
|
||||
GUI::GUI(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
GUI& GUI::getInstance()
|
||||
{
|
||||
static GUI gui;
|
||||
return gui;
|
||||
}
|
||||
|
||||
QString GUI::itemInputDialog(QWidget * parent, const QString & title,
|
||||
const QString & label, const QStringList & items,
|
||||
int current, bool editable, bool * ok,
|
||||
Qt::WindowFlags flags,
|
||||
Qt::InputMethodHints hints)
|
||||
{
|
||||
if (QThread::currentThread() == qApp->thread())
|
||||
{
|
||||
return getInstance()._itemInputDialog(parent, title, label, items, current, editable, ok, flags, hints);
|
||||
}
|
||||
else
|
||||
{
|
||||
QString r;
|
||||
QMetaObject::invokeMethod(&getInstance(), "_itemInputDialog", Qt::BlockingQueuedConnection,
|
||||
Q_RETURN_ARG(QString, r),
|
||||
Q_ARG(QWidget*, parent), Q_ARG(const QString&, title),
|
||||
Q_ARG(const QString&,label), Q_ARG(const QStringList&, items),
|
||||
Q_ARG(int, current), Q_ARG(bool, editable), Q_ARG(bool*, ok),
|
||||
Q_ARG(Qt::WindowFlags, flags), Q_ARG(Qt::InputMethodHints, hints));
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
QString GUI::_itemInputDialog(QWidget * parent, const QString & title,
|
||||
const QString & label, const QStringList & items,
|
||||
int current, bool editable, bool * ok,
|
||||
Qt::WindowFlags flags,
|
||||
Qt::InputMethodHints hints)
|
||||
{
|
||||
return QInputDialog::getItem(parent, title, label, items, current, editable, ok, flags, hints);
|
||||
}
|
33
src/widget/gui.h
Normal file
33
src/widget/gui.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
#ifndef GUI_H
|
||||
#define GUI_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class QWidget;
|
||||
|
||||
/// Abstracts the GUI from the target backend (AndroidGUI, DesktopGUI, ...)
|
||||
/// All the functions exposed here are thread-safe
|
||||
/// Prefer calling this class to calling a GUI backend directly
|
||||
class GUI : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static GUI& getInstance();
|
||||
static QString itemInputDialog(QWidget * parent, const QString & title,
|
||||
const QString & label, const QStringList & items,
|
||||
int current = 0, bool editable = true, bool * ok = 0,
|
||||
Qt::WindowFlags flags = 0,
|
||||
Qt::InputMethodHints hints = Qt::ImhNone);
|
||||
|
||||
private:
|
||||
explicit GUI(QObject *parent = 0);
|
||||
|
||||
private slots:
|
||||
QString _itemInputDialog(QWidget * parent, const QString & title,
|
||||
const QString & label, const QStringList & items,
|
||||
int current = 0, bool editable = true, bool * ok = 0,
|
||||
Qt::WindowFlags flags = 0,
|
||||
Qt::InputMethodHints inputMethodHints = Qt::ImhNone);
|
||||
};
|
||||
|
||||
#endif // GUI_H
|
|
@ -36,6 +36,7 @@
|
|||
#include "src/audio.h"
|
||||
#include "src/platform/timer.h"
|
||||
#include "systemtrayicon.h"
|
||||
#include "src/nexus.h"
|
||||
#include <QMessageBox>
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
|
@ -195,66 +196,14 @@ void Widget::init()
|
|||
Style::setThemeColor(Settings::getInstance().getThemeColor());
|
||||
Style::applyTheme();
|
||||
|
||||
qRegisterMetaType<Status>("Status");
|
||||
qRegisterMetaType<vpx_image>("vpx_image");
|
||||
qRegisterMetaType<uint8_t>("uint8_t");
|
||||
qRegisterMetaType<uint16_t>("uint16_t");
|
||||
qRegisterMetaType<const int16_t*>("const int16_t*");
|
||||
qRegisterMetaType<int32_t>("int32_t");
|
||||
qRegisterMetaType<int64_t>("int64_t");
|
||||
qRegisterMetaType<QPixmap>("QPixmap");
|
||||
qRegisterMetaType<ToxFile>("ToxFile");
|
||||
qRegisterMetaType<ToxFile::FileDirection>("ToxFile::FileDirection");
|
||||
qRegisterMetaType<Core::PasswordType>("Core::PasswordType");
|
||||
|
||||
QString profilePath = detectProfile();
|
||||
coreThread = new QThread(this);
|
||||
coreThread->setObjectName("qTox Core");
|
||||
core = new Core(Camera::getInstance(), coreThread, profilePath);
|
||||
core->moveToThread(coreThread);
|
||||
connect(coreThread, &QThread::started, core, &Core::start);
|
||||
|
||||
filesForm = new FilesForm();
|
||||
addFriendForm = new AddFriendForm;
|
||||
settingsWidget = new SettingsWidget();
|
||||
|
||||
connect(settingsWidget, &SettingsWidget::setShowSystemTray, this, &Widget::onSetShowSystemTray);
|
||||
|
||||
connect(core, &Core::connected, this, &Widget::onConnected);
|
||||
connect(core, &Core::disconnected, this, &Widget::onDisconnected);
|
||||
connect(core, &Core::failedToStart, this, &Widget::onFailedToStartCore);
|
||||
connect(core, &Core::badProxy, this, &Widget::onBadProxyCore);
|
||||
connect(core, &Core::statusSet, this, &Widget::onStatusSet);
|
||||
connect(core, &Core::usernameSet, this, &Widget::setUsername);
|
||||
connect(core, &Core::statusMessageSet, this, &Widget::setStatusMessage);
|
||||
connect(core, &Core::selfAvatarChanged, this, &Widget::onSelfAvatarLoaded);
|
||||
Core* core = Nexus::getCore();
|
||||
connect(core, SIGNAL(fileDownloadFinished(const QString&)), filesForm, SLOT(onFileDownloadComplete(const QString&)));
|
||||
connect(core, SIGNAL(fileUploadFinished(const QString&)), filesForm, SLOT(onFileUploadComplete(const QString&)));
|
||||
connect(core, &Core::friendAdded, this, &Widget::addFriend);
|
||||
connect(core, &Core::failedToAddFriend, this, &Widget::addFriendFailed);
|
||||
connect(core, &Core::friendUsernameChanged, this, &Widget::onFriendUsernameChanged);
|
||||
connect(core, &Core::friendStatusChanged, this, &Widget::onFriendStatusChanged);
|
||||
connect(core, &Core::friendStatusMessageChanged, this, &Widget::onFriendStatusMessageChanged);
|
||||
connect(core, &Core::friendRequestReceived, this, &Widget::onFriendRequestReceived);
|
||||
connect(core, &Core::friendMessageReceived, this, &Widget::onFriendMessageReceived);
|
||||
connect(core, &Core::receiptRecieved, this, &Widget::onReceiptRecieved);
|
||||
connect(core, &Core::groupInviteReceived, this, &Widget::onGroupInviteReceived);
|
||||
connect(core, &Core::groupMessageReceived, this, &Widget::onGroupMessageReceived);
|
||||
connect(core, &Core::groupNamelistChanged, this, &Widget::onGroupNamelistChanged);
|
||||
connect(core, &Core::groupTitleChanged, this, &Widget::onGroupTitleChanged);
|
||||
connect(core, &Core::emptyGroupCreated, this, &Widget::onEmptyGroupCreated);
|
||||
connect(core, &Core::avInvite, this, &Widget::playRingtone);
|
||||
connect(core, &Core::blockingClearContacts, this, &Widget::clearContactsList, Qt::BlockingQueuedConnection);
|
||||
connect(core, &Core::friendTypingChanged, this, &Widget::onFriendTypingChanged);
|
||||
|
||||
connect(core, SIGNAL(messageSentResult(int,QString,int)), this, SLOT(onMessageSendResult(int,QString,int)));
|
||||
connect(core, SIGNAL(groupSentResult(int,QString,int)), this, SLOT(onGroupSendResult(int,QString,int)));
|
||||
|
||||
connect(this, &Widget::statusSet, core, &Core::setStatus);
|
||||
connect(this, &Widget::friendRequested, core, &Core::requestFriendship);
|
||||
connect(this, &Widget::friendRequestAccepted, core, &Core::acceptFriendRequest);
|
||||
connect(this, &Widget::changeProfile, core, &Core::switchConfiguration);
|
||||
|
||||
connect(settingsWidget, &SettingsWidget::setShowSystemTray, this, &Widget::onSetShowSystemTray);
|
||||
connect(ui->addButton, SIGNAL(clicked()), this, SLOT(onAddClicked()));
|
||||
connect(ui->groupButton, SIGNAL(clicked()), this, SLOT(onGroupClicked()));
|
||||
connect(ui->transferButton, SIGNAL(clicked()), this, SLOT(onTransferClicked()));
|
||||
|
@ -270,8 +219,6 @@ void Widget::init()
|
|||
connect(timer, &QTimer::timeout, this, &Widget::onUserAwayCheck);
|
||||
connect(timer, &QTimer::timeout, this, &Widget::onEventIconTick);
|
||||
|
||||
coreThread->start();
|
||||
|
||||
addFriendForm->show(*ui);
|
||||
|
||||
#if (AUTOUPDATE_ENABLED)
|
||||
|
@ -318,9 +265,7 @@ void Widget::updateTrayIcon()
|
|||
Widget::~Widget()
|
||||
{
|
||||
qDebug() << "Deleting Widget";
|
||||
core->saveConfiguration();
|
||||
AutoUpdater::abortUpdates();
|
||||
delete core;
|
||||
icon->hide();
|
||||
hideMainForms();
|
||||
delete settingsWidget;
|
||||
|
@ -346,11 +291,6 @@ Widget* Widget::getInstance()
|
|||
return instance;
|
||||
}
|
||||
|
||||
QThread* Widget::getCoreThread()
|
||||
{
|
||||
return coreThread;
|
||||
}
|
||||
|
||||
void Widget::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
if (Settings::getInstance().getShowSystemTray() && Settings::getInstance().getCloseToTray() == true)
|
||||
|
@ -386,72 +326,9 @@ void Widget::resizeEvent(QResizeEvent *event)
|
|||
emit resized();
|
||||
}
|
||||
|
||||
QString Widget::detectProfile()
|
||||
{
|
||||
QDir dir(Settings::getSettingsDirPath());
|
||||
QString path, profile = Settings::getInstance().getCurrentProfile();
|
||||
path = dir.filePath(profile + Core::TOX_EXT);
|
||||
QFile file(path);
|
||||
if (profile.isEmpty() || !file.exists())
|
||||
{
|
||||
Settings::getInstance().setCurrentProfile("");
|
||||
#if 1 // deprecation attempt
|
||||
// if the last profile doesn't exist, fall back to old "data"
|
||||
path = dir.filePath(Core::CONFIG_FILE_NAME);
|
||||
QFile file(path);
|
||||
if (file.exists())
|
||||
return path;
|
||||
else if (QFile(path = dir.filePath("tox_save")).exists()) // also import tox_save if no data
|
||||
return path;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
profile = askProfiles();
|
||||
if (profile.isEmpty())
|
||||
return "";
|
||||
else
|
||||
{
|
||||
Settings::getInstance().switchProfile(profile);
|
||||
return dir.filePath(profile + Core::TOX_EXT);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return path;
|
||||
}
|
||||
|
||||
QList<QString> Widget::searchProfiles()
|
||||
{
|
||||
QList<QString> out;
|
||||
QDir dir(Settings::getSettingsDirPath());
|
||||
dir.setFilter(QDir::Files | QDir::NoDotAndDotDot);
|
||||
dir.setNameFilters(QStringList("*.tox"));
|
||||
for (QFileInfo file : dir.entryInfoList())
|
||||
out += file.completeBaseName();
|
||||
return out;
|
||||
}
|
||||
|
||||
QString Widget::askProfiles()
|
||||
{ // TODO: allow user to create new Tox ID, even if a profile already exists
|
||||
QList<QString> profiles = searchProfiles();
|
||||
if (profiles.empty()) return "";
|
||||
bool ok;
|
||||
QString profile = QInputDialog::getItem(this,
|
||||
tr("Choose a profile"),
|
||||
tr("Please choose which identity to use"),
|
||||
profiles,
|
||||
0, // which slot to start on
|
||||
false, // if the user can enter their own input
|
||||
&ok);
|
||||
if (!ok) // user cancelled
|
||||
return "";
|
||||
else
|
||||
return profile;
|
||||
}
|
||||
|
||||
QString Widget::getUsername()
|
||||
{
|
||||
return core->getUsername();
|
||||
return Nexus::getCore()->getUsername();
|
||||
}
|
||||
|
||||
void Widget::onAvatarClicked()
|
||||
|
@ -495,7 +372,7 @@ void Widget::onAvatarClicked()
|
|||
return;
|
||||
}
|
||||
|
||||
core->setAvatar(TOX_AVATAR_FORMAT_PNG, bytes);
|
||||
Nexus::getCore()->setAvatar(TOX_AVATAR_FORMAT_PNG, bytes);
|
||||
}
|
||||
|
||||
void Widget::onSelfAvatarLoaded(const QPixmap& pic)
|
||||
|
@ -591,7 +468,7 @@ void Widget::onAddClicked()
|
|||
|
||||
void Widget::onGroupClicked()
|
||||
{
|
||||
core->createGroup();
|
||||
Nexus::getCore()->createGroup();
|
||||
}
|
||||
|
||||
void Widget::onTransferClicked()
|
||||
|
@ -664,7 +541,7 @@ void Widget::hideMainForms()
|
|||
void Widget::onUsernameChanged(const QString& newUsername, const QString& oldUsername)
|
||||
{
|
||||
setUsername(oldUsername); // restore old username until Core tells us to set it
|
||||
core->setUsername(newUsername);
|
||||
Nexus::getCore()->setUsername(newUsername);
|
||||
}
|
||||
|
||||
void Widget::setUsername(const QString& username)
|
||||
|
@ -681,7 +558,7 @@ void Widget::onStatusMessageChanged(const QString& newStatusMessage, const QStri
|
|||
{
|
||||
ui->statusLabel->setText(oldStatusMessage); // restore old status message until Core tells us to set it
|
||||
ui->statusLabel->setToolTip(oldStatusMessage); // for overlength messsages
|
||||
core->setStatusMessage(newStatusMessage);
|
||||
Nexus::getCore()->setStatusMessage(newStatusMessage);
|
||||
}
|
||||
|
||||
void Widget::setStatusMessage(const QString &statusMessage)
|
||||
|
@ -707,6 +584,7 @@ void Widget::addFriend(int friendId, const QString &userId)
|
|||
if (Settings::getInstance().getEnableLogging())
|
||||
newfriend->getChatForm()->loadHistory(QDateTime::currentDateTime().addDays(-7), true);
|
||||
|
||||
Core* core = Nexus::getCore();
|
||||
connect(settingsWidget, &SettingsWidget::compactToggled, newfriend->getFriendWidget(), &GenericChatroomWidget::onCompactChanged);
|
||||
connect(newfriend->getFriendWidget(), SIGNAL(chatroomWidgetClicked(GenericChatroomWidget*)), this, SLOT(onChatroomWidgetClicked(GenericChatroomWidget*)));
|
||||
connect(newfriend->getFriendWidget(), SIGNAL(removeFriend(int)), this, SLOT(removeFriend(int)));
|
||||
|
@ -928,7 +806,7 @@ void Widget::removeFriend(Friend* f, bool fake)
|
|||
onAddClicked();
|
||||
}
|
||||
FriendList::removeFriend(f->getFriendID(), fake);
|
||||
core->removeFriend(f->getFriendID(), fake);
|
||||
Nexus::getCore()->removeFriend(f->getFriendID(), fake);
|
||||
delete f;
|
||||
if (ui->mainHead->layout()->isEmpty())
|
||||
onAddClicked();
|
||||
|
@ -959,7 +837,7 @@ void Widget::copyFriendIdToClipboard(int friendId)
|
|||
if (f != nullptr)
|
||||
{
|
||||
QClipboard *clipboard = QApplication::clipboard();
|
||||
clipboard->setText(core->getFriendAddress(f->getFriendID()), QClipboard::Clipboard);
|
||||
clipboard->setText(Nexus::getCore()->getFriendAddress(f->getFriendID()), QClipboard::Clipboard);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -967,7 +845,7 @@ void Widget::onGroupInviteReceived(int32_t friendId, uint8_t type, QByteArray in
|
|||
{
|
||||
if (type == TOX_GROUPCHAT_TYPE_TEXT || type == TOX_GROUPCHAT_TYPE_AV)
|
||||
{
|
||||
int groupId = core->joinGroupchat(friendId, type, (uint8_t*)invite.data(), invite.length());
|
||||
int groupId = Nexus::getCore()->joinGroupchat(friendId, type, (uint8_t*)invite.data(), invite.length());
|
||||
if (groupId < 0)
|
||||
{
|
||||
qWarning() << "Widget::onGroupInviteReceived: Unable to accept group invite";
|
||||
|
@ -1014,7 +892,7 @@ void Widget::onGroupNamelistChanged(int groupnumber, int peernumber, uint8_t Cha
|
|||
g = createGroup(groupnumber);
|
||||
}
|
||||
|
||||
QString name = core->getGroupPeerName(groupnumber, peernumber);
|
||||
QString name = Nexus::getCore()->getGroupPeerName(groupnumber, peernumber);
|
||||
TOX_CHAT_CHANGE change = static_cast<TOX_CHAT_CHANGE>(Change);
|
||||
if (change == TOX_CHAT_CHANGE_PEER_ADD)
|
||||
{
|
||||
|
@ -1033,7 +911,7 @@ void Widget::onGroupNamelistChanged(int groupnumber, int peernumber, uint8_t Cha
|
|||
//g->chatForm->addSystemInfoMessage(tr("%1 has left the chat").arg(name), "silver");
|
||||
}
|
||||
else if (change == TOX_CHAT_CHANGE_PEER_NAME) // core overwrites old name before telling us it changed...
|
||||
g->updatePeer(peernumber,core->getGroupPeerName(groupnumber, peernumber));
|
||||
g->updatePeer(peernumber,Nexus::getCore()->getGroupPeerName(groupnumber, peernumber));
|
||||
}
|
||||
|
||||
void Widget::onGroupTitleChanged(int groupnumber, const QString& author, const QString& title)
|
||||
|
@ -1056,7 +934,7 @@ void Widget::removeGroup(Group* g, bool fake)
|
|||
onAddClicked();
|
||||
}
|
||||
GroupList::removeGroup(g->getGroupId(), fake);
|
||||
core->removeGroup(g->getGroupId(), fake);
|
||||
Nexus::getCore()->removeGroup(g->getGroupId(), fake);
|
||||
delete g;
|
||||
if (ui->mainHead->layout()->isEmpty())
|
||||
onAddClicked();
|
||||
|
@ -1070,11 +948,6 @@ void Widget::removeGroup(int groupId)
|
|||
removeGroup(GroupList::findGroup(groupId));
|
||||
}
|
||||
|
||||
Core *Widget::getCore()
|
||||
{
|
||||
return core;
|
||||
}
|
||||
|
||||
Group *Widget::createGroup(int groupId)
|
||||
{
|
||||
Group* g = GroupList::findGroup(groupId);
|
||||
|
@ -1090,6 +963,7 @@ Group *Widget::createGroup(int groupId)
|
|||
layout->addWidget(newgroup->getGroupWidget());
|
||||
newgroup->getGroupWidget()->updateStatusLight();
|
||||
|
||||
Core* core = Nexus::getCore();
|
||||
connect(newgroup->getGroupWidget(), SIGNAL(chatroomWidgetClicked(GenericChatroomWidget*)), this, SLOT(onChatroomWidgetClicked(GenericChatroomWidget*)));
|
||||
connect(newgroup->getGroupWidget(), SIGNAL(removeGroup(int)), this, SLOT(removeGroup(int)));
|
||||
connect(newgroup->getGroupWidget(), SIGNAL(chatroomWidgetClicked(GenericChatroomWidget*)), newgroup->getChatForm(), SLOT(focusInput()));
|
||||
|
@ -1174,17 +1048,17 @@ void Widget::onEventIconTick()
|
|||
|
||||
void Widget::setStatusOnline()
|
||||
{
|
||||
core->setStatus(Status::Online);
|
||||
Nexus::getCore()->setStatus(Status::Online);
|
||||
}
|
||||
|
||||
void Widget::setStatusAway()
|
||||
{
|
||||
core->setStatus(Status::Away);
|
||||
Nexus::getCore()->setStatus(Status::Away);
|
||||
}
|
||||
|
||||
void Widget::setStatusBusy()
|
||||
{
|
||||
core->setStatus(Status::Busy);
|
||||
Nexus::getCore()->setStatus(Status::Busy);
|
||||
}
|
||||
|
||||
void Widget::onMessageSendResult(int friendId, const QString& message, int messageId)
|
||||
|
|
|
@ -54,14 +54,11 @@ public:
|
|||
explicit Widget(QWidget *parent = 0);
|
||||
void setCentralWidget(QWidget *widget, const QString &widgetName);
|
||||
QString getUsername();
|
||||
Core* getCore();
|
||||
QThread* getCoreThread();
|
||||
Camera* getCamera();
|
||||
static Widget* getInstance();
|
||||
void newMessageAlert(GenericChatroomWidget* chat);
|
||||
bool isFriendWidgetCurActiveWidget(Friend* f);
|
||||
bool getIsWindowMinimized();
|
||||
static QList<QString> searchProfiles();
|
||||
void clearContactsList();
|
||||
void setTranslation();
|
||||
void updateTrayIcon();
|
||||
|
@ -69,7 +66,6 @@ public:
|
|||
Q_INVOKABLE void setEnabledThreadsafe(bool enabled);
|
||||
Q_INVOKABLE bool askQuestion(const QString& title, const QString& msg, bool defaultAns = false, bool warning = true);
|
||||
Q_INVOKABLE QString passwordDialog(const QString& cancel, const QString& body);
|
||||
Q_INVOKABLE QString askProfiles();
|
||||
// hooray for threading hacks
|
||||
~Widget();
|
||||
|
||||
|
@ -86,6 +82,29 @@ public slots:
|
|||
void onSettingsClicked();
|
||||
void setWindowTitle(const QString& title);
|
||||
void forceShow();
|
||||
void onConnected();
|
||||
void onDisconnected();
|
||||
void onStatusSet(Status status);
|
||||
void onFailedToStartCore();
|
||||
void onBadProxyCore();
|
||||
void onSelfAvatarLoaded(const QPixmap &pic);
|
||||
void setUsername(const QString& username);
|
||||
void setStatusMessage(const QString &statusMessage);
|
||||
void addFriend(int friendId, const QString& userId);
|
||||
void addFriendFailed(const QString& userId, const QString& errorInfo = QString());
|
||||
void onFriendStatusChanged(int friendId, Status status);
|
||||
void onFriendStatusMessageChanged(int friendId, const QString& message);
|
||||
void onFriendUsernameChanged(int friendId, const QString& username);
|
||||
void onFriendMessageReceived(int friendId, const QString& message, bool isAction);
|
||||
void onFriendRequestReceived(const QString& userId, const QString& message);
|
||||
void onReceiptRecieved(int friendId, int receipt);
|
||||
void onEmptyGroupCreated(int groupId);
|
||||
void onGroupInviteReceived(int32_t friendId, uint8_t type, QByteArray invite);
|
||||
void onGroupMessageReceived(int groupnumber, int peernumber, const QString& message, bool isAction);
|
||||
void onGroupNamelistChanged(int groupnumber, int peernumber, uint8_t change);
|
||||
void onGroupTitleChanged(int groupnumber, const QString& author, const QString& title);
|
||||
void playRingtone();
|
||||
void onFriendTypingChanged(int friendId, bool isTyping);
|
||||
|
||||
signals:
|
||||
void friendRequestAccepted(const QString& userId);
|
||||
|
@ -98,34 +117,13 @@ signals:
|
|||
void resized();
|
||||
|
||||
private slots:
|
||||
void onConnected();
|
||||
void onDisconnected();
|
||||
void onStatusSet(Status status);
|
||||
void onAddClicked();
|
||||
void onGroupClicked();
|
||||
void onTransferClicked();
|
||||
void onFailedToStartCore();
|
||||
void onBadProxyCore();
|
||||
void onAvatarClicked();
|
||||
void onSelfAvatarLoaded(const QPixmap &pic);
|
||||
void onUsernameChanged(const QString& newUsername, const QString& oldUsername);
|
||||
void onStatusMessageChanged(const QString& newStatusMessage, const QString& oldStatusMessage);
|
||||
void setUsername(const QString& username);
|
||||
void setStatusMessage(const QString &statusMessage);
|
||||
void addFriend(int friendId, const QString& userId);
|
||||
void addFriendFailed(const QString& userId, const QString& errorInfo = QString());
|
||||
void onFriendStatusChanged(int friendId, Status status);
|
||||
void onFriendStatusMessageChanged(int friendId, const QString& message);
|
||||
void onFriendUsernameChanged(int friendId, const QString& username);
|
||||
void onChatroomWidgetClicked(GenericChatroomWidget *);
|
||||
void onFriendMessageReceived(int friendId, const QString& message, bool isAction);
|
||||
void onFriendRequestReceived(const QString& userId, const QString& message);
|
||||
void onReceiptRecieved(int friendId, int receipt);
|
||||
void onEmptyGroupCreated(int groupId);
|
||||
void onGroupInviteReceived(int32_t friendId, uint8_t type, QByteArray invite);
|
||||
void onGroupMessageReceived(int groupnumber, int peernumber, const QString& message, bool isAction);
|
||||
void onGroupNamelistChanged(int groupnumber, int peernumber, uint8_t change);
|
||||
void onGroupTitleChanged(int groupnumber, const QString& author, const QString& title);
|
||||
void removeFriend(int friendId);
|
||||
void copyFriendIdToClipboard(int friendId);
|
||||
void removeGroup(int groupId);
|
||||
|
@ -134,11 +132,9 @@ private slots:
|
|||
void setStatusBusy();
|
||||
void onMessageSendResult(int friendId, const QString& message, int messageId);
|
||||
void onGroupSendResult(int groupId, const QString& message, int result);
|
||||
void playRingtone();
|
||||
void onIconClick(QSystemTrayIcon::ActivationReason);
|
||||
void onUserAwayCheck();
|
||||
void onEventIconTick();
|
||||
void onFriendTypingChanged(int friendId, bool isTyping);
|
||||
void onSetShowSystemTray(bool newValue);
|
||||
void onSplitterMoved(int pos, int index);
|
||||
|
||||
|
@ -151,7 +147,6 @@ private:
|
|||
void removeGroup(Group* g, bool fake = false);
|
||||
void saveWindowGeometry();
|
||||
void saveSplitterGeometry();
|
||||
QString detectProfile();
|
||||
SystemTrayIcon *icon;
|
||||
QMenu *trayMenu;
|
||||
QAction *statusOnline,
|
||||
|
@ -162,8 +157,6 @@ private:
|
|||
Ui::MainWindow *ui;
|
||||
QSplitter *centralLayout;
|
||||
QPoint dragPosition;
|
||||
Core* core;
|
||||
QThread* coreThread;
|
||||
AddFriendForm* addFriendForm;
|
||||
SettingsWidget* settingsWidget;
|
||||
FilesForm* filesForm;
|
||||
|
|
Loading…
Reference in New Issue
Block a user