mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
Merge branch 'android'
This commit is contained in:
commit
6286e4a11f
56
android/AndroidManifest.xml
Normal file
56
android/AndroidManifest.xml
Normal file
|
@ -0,0 +1,56 @@
|
|||
<?xml version="1.0"?>
|
||||
<manifest package="im.tox.qtox" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0" android:versionCode="1" android:installLocation="auto">
|
||||
<application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="qtox">
|
||||
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|locale|fontScale|keyboard|keyboardHidden|navigation" android:name="org.qtproject.qt5.android.bindings.QtActivity" android:label="qTox" android:screenOrientation="unspecified" android:launchMode="singleTop">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
<meta-data android:name="android.app.lib_name" android:value="qtox"/>
|
||||
<meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
|
||||
<meta-data android:name="android.app.repository" android:value="default"/>
|
||||
<meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
|
||||
<meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
|
||||
<!-- Deploy Qt libs as part of package -->
|
||||
<meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/>
|
||||
<meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/>
|
||||
<meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/>
|
||||
<!-- Run with local libs -->
|
||||
<meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
|
||||
<meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
|
||||
<meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --"/>
|
||||
<meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
|
||||
<meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
|
||||
<!-- Messages maps -->
|
||||
<meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/>
|
||||
<meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
|
||||
<meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
|
||||
<!-- Messages maps -->
|
||||
|
||||
<!-- Splash screen -->
|
||||
<!--
|
||||
<meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/logo"/>
|
||||
-->
|
||||
<!-- Splash screen -->
|
||||
|
||||
<!-- Background running -->
|
||||
<!-- Warning: changing this value to true may cause unexpected crashes if the
|
||||
application still try to draw after
|
||||
"applicationStateChanged(Qt::ApplicationSuspended)"
|
||||
signal is sent! -->
|
||||
<meta-data android:name="android.app.background_running" android:value="false"/>
|
||||
<!-- Background running -->
|
||||
</activity>
|
||||
</application>
|
||||
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="20"/>
|
||||
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
|
||||
|
||||
<!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application.
|
||||
Remove the comment if you do not require these default permissions. -->
|
||||
<!-- %%INSERT_PERMISSIONS -->
|
||||
|
||||
<!-- The following comment will be replaced upon deployment with default features based on the dependencies of the application.
|
||||
Remove the comment if you do not require these default features. -->
|
||||
<!-- %%INSERT_FEATURES -->
|
||||
|
||||
</manifest>
|
76
qtox.pro
76
qtox.pro
|
@ -69,6 +69,23 @@ contains(ENABLE_SYSTRAY_UNITY_BACKEND, YES) {
|
|||
LIBS += -lgobject-2.0 -lappindicator -lgtk-x11-2.0
|
||||
}
|
||||
|
||||
android {
|
||||
ANDROID_TOOLCHAIN=/opt/android/toolchain-r9d-17/
|
||||
INCLUDEPATH += $$ANDROID_TOOLCHAIN/include/
|
||||
LIBS += -L$$ANDROID_TOOLCHAIN/lib
|
||||
|
||||
DISABLE_PLATFORM_EXT=YES
|
||||
DISABLE_FILTER_AUDIO=YES
|
||||
|
||||
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
|
||||
contains(ANDROID_TARGET_ARCH,armeabi) {
|
||||
ANDROID_EXTRA_LIBS = \
|
||||
$$ANDROID_TOOLCHAIN/lib/libopenal.so \
|
||||
$$ANDROID_TOOLCHAIN/lib/libsodium.so
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
contains(DISABLE_PLATFORM_EXT, YES) {
|
||||
|
||||
} else {
|
||||
|
@ -90,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
|
||||
|
||||
|
@ -110,31 +127,38 @@ win32 {
|
|||
contains(DEFINES, QTOX_PLATFORM_EXT) { LIBS += -framework IOKit -framework CoreFoundation }
|
||||
contains(DEFINES, QTOX_FILTER_AUDIO) { LIBS += -lfilteraudio }
|
||||
} else {
|
||||
# If we're building a package, static link libtox[core,av] and libsodium, since they are not provided by any package
|
||||
contains(STATICPKG, YES) {
|
||||
target.path = /usr/bin
|
||||
INSTALLS += target
|
||||
LIBS += -L$$PWD/libs/lib/ -lopus -lvpx -lopenal -Wl,-Bstatic -ltoxcore -ltoxav -ltoxencryptsave -ltoxdns -lsodium -lopencv_highgui -lopencv_imgproc -lopencv_core -lz -Wl,-Bdynamic
|
||||
LIBS += -Wl,-Bstatic -ljpeg -ltiff -lpng -ljasper -lIlmImf -lIlmThread -lIex -ldc1394 -lraw1394 -lHalf -lz -llzma -ljbig
|
||||
LIBS += -Wl,-Bdynamic -lv4l1 -lv4l2 -lavformat -lavcodec -lavutil -lswscale -lusb-1.0
|
||||
android {
|
||||
LIBS += -ltoxcore -ltoxav -ltoxencryptsave -ltoxdns
|
||||
LIBS += -lopencv_videoio -lopencv_imgcodecs -lopencv_highgui -lopencv_imgproc -lopencv_androidcamera
|
||||
LIBS += -llibjpeg -llibwebp -llibpng -llibtiff -llibjasper -lIlmImf -lopencv_core
|
||||
LIBS += -lopus -lvpx -lsodium -lopenal
|
||||
} else {
|
||||
LIBS += -L$$PWD/libs/lib/ -ltoxcore -ltoxav -ltoxencryptsave -ltoxdns -lvpx -lsodium -lopenal -lopencv_core -lopencv_highgui -lopencv_imgproc
|
||||
}
|
||||
|
||||
contains(DEFINES, QTOX_PLATFORM_EXT) {
|
||||
LIBS += -lX11 -lXss
|
||||
}
|
||||
|
||||
contains(DEFINES, QTOX_FILTER_AUDIO) {
|
||||
# If we're building a package, static link libtox[core,av] and libsodium, since they are not provided by any package
|
||||
contains(STATICPKG, YES) {
|
||||
LIBS += -Wl,-Bstatic -lfilteraudio
|
||||
target.path = /usr/bin
|
||||
INSTALLS += target
|
||||
LIBS += -L$$PWD/libs/lib/ -lopus -lvpx -lopenal -Wl,-Bstatic -ltoxcore -ltoxav -ltoxencryptsave -ltoxdns -lsodium -lopencv_highgui -lopencv_imgproc -lopencv_core -lz -Wl,-Bdynamic
|
||||
LIBS += -Wl,-Bstatic -ljpeg -ltiff -lpng -ljasper -lIlmImf -lIlmThread -lIex -ldc1394 -lraw1394 -lHalf -lz -llzma -ljbig
|
||||
LIBS += -Wl,-Bdynamic -lv4l1 -lv4l2 -lavformat -lavcodec -lavutil -lswscale -lusb-1.0
|
||||
} else {
|
||||
LIBS += -lfilteraudio
|
||||
LIBS += -L$$PWD/libs/lib/ -ltoxcore -ltoxav -ltoxencryptsave -ltoxdns -lvpx -lsodium -lopenal -lopencv_core -lopencv_highgui -lopencv_imgproc
|
||||
}
|
||||
}
|
||||
|
||||
contains(JENKINS, YES) {
|
||||
LIBS = ./libs/lib/libtoxav.a ./libs/lib/libvpx.a ./libs/lib/libopus.a ./libs/lib/libtoxdns.a ./libs/lib/libtoxencryptsave.a ./libs/lib/libtoxcore.a ./libs/lib/libsodium.a ./libs/lib/libfilteraudio.a /usr/lib/libopencv_core.so /usr/lib/libopencv_highgui.so /usr/lib/libopencv_imgproc.so -lopenal -lX11 -lXss -s
|
||||
contains(DEFINES, QTOX_PLATFORM_EXT) {
|
||||
LIBS += -lX11 -lXss
|
||||
}
|
||||
|
||||
contains(DEFINES, QTOX_FILTER_AUDIO) {
|
||||
contains(STATICPKG, YES) {
|
||||
LIBS += -Wl,-Bstatic -lfilteraudio
|
||||
} else {
|
||||
LIBS += -lfilteraudio
|
||||
}
|
||||
}
|
||||
|
||||
contains(JENKINS, YES) {
|
||||
LIBS = ./libs/lib/libtoxav.a ./libs/lib/libvpx.a ./libs/lib/libopus.a ./libs/lib/libtoxdns.a ./libs/lib/libtoxencryptsave.a ./libs/lib/libtoxcore.a ./libs/lib/libsodium.a ./libs/lib/libfilteraudio.a /usr/lib/libopencv_core.so /usr/lib/libopencv_highgui.so /usr/lib/libopencv_imgproc.so -lopenal -lX11 -lXss -s
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -206,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 \
|
||||
|
@ -275,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
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "src/misc/serialize.h"
|
||||
#include "src/misc/settings.h"
|
||||
#include "src/widget/widget.h"
|
||||
#include "src/widget/gui.h"
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QCoreApplication>
|
||||
|
@ -490,7 +491,7 @@ void AutoUpdater::checkUpdatesAsyncInteractiveWorker()
|
|||
QDir updateDir(updateDirStr);
|
||||
|
||||
if ((updateDir.exists() && QFile(updateDirStr+"flist").exists())
|
||||
|| Widget::getInstance()->askQuestion(QObject::tr("Update", "The title of a message box"),
|
||||
|| GUI::askQuestion(QObject::tr("Update", "The title of a message box"),
|
||||
QObject::tr("An update is available, do you want to download it now?\nIt will be installed when qTox restarts."), true, false))
|
||||
{
|
||||
downloadUpdate();
|
||||
|
|
16
src/core.cpp
16
src/core.cpp
|
@ -15,10 +15,11 @@
|
|||
*/
|
||||
|
||||
#include "core.h"
|
||||
#include "nexus.h"
|
||||
#include "misc/cdata.h"
|
||||
#include "misc/cstring.h"
|
||||
#include "misc/settings.h"
|
||||
#include "widget/widget.h"
|
||||
#include "widget/gui.h"
|
||||
#include "historykeeper.h"
|
||||
#include "src/audio.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));
|
||||
|
@ -255,7 +259,6 @@ void Core::start()
|
|||
{
|
||||
setStatusMessage(tr("Toxing on qTox")); // this also solves the not updating issue
|
||||
setUsername(tr("qTox User"));
|
||||
QMetaObject::invokeMethod(Widget::getInstance(), "onSettingsClicked"); // update ui with new profile
|
||||
}
|
||||
|
||||
tox_callback_friend_request(tox, onFriendRequest, this);
|
||||
|
@ -1202,8 +1205,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())
|
||||
{
|
||||
|
@ -1281,7 +1283,7 @@ void Core::switchConfiguration(const QString& profile)
|
|||
saveCurrentInformation(); // part of a hack, see core.h
|
||||
|
||||
ready = false;
|
||||
Widget::getInstance()->setEnabledThreadsafe(false);
|
||||
GUI::setEnabled(false);
|
||||
clearPassword(ptMain);
|
||||
clearPassword(ptHistory);
|
||||
|
||||
|
@ -1301,7 +1303,7 @@ void Core::switchConfiguration(const QString& profile)
|
|||
|
||||
start();
|
||||
if (isReady())
|
||||
Widget::getInstance()->setEnabledThreadsafe(true);
|
||||
GUI::setEnabled(true);
|
||||
}
|
||||
|
||||
void Core::loadFriends()
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
/* was permanently moved here to handle encryption */
|
||||
|
||||
#include "core.h"
|
||||
#include "src/widget/widget.h"
|
||||
#include "src/widget/gui.h"
|
||||
#include <tox/tox.h>
|
||||
#include <tox/toxencryptsave.h>
|
||||
#include "src/misc/settings.h"
|
||||
|
@ -165,7 +165,7 @@ QByteArray Core::getSaltFromFile(QString filename)
|
|||
bool Core::loadEncryptedSave(QByteArray& data)
|
||||
{
|
||||
if (!Settings::getInstance().getEncryptTox())
|
||||
Widget::getInstance()->showWarningMsgBox(tr("Encryption error"), tr("The .tox file is encrypted, but encryption was not checked, continuing regardless."));
|
||||
GUI::showWarning(tr("Encryption error"), tr("The .tox file is encrypted, but encryption was not checked, continuing regardless."));
|
||||
|
||||
int error = -1;
|
||||
QString a(tr("Please enter the password for the %1 profile.", "used in load() when no pw is already set").arg(Settings::getInstance().getCurrentProfile()));
|
||||
|
@ -190,7 +190,7 @@ bool Core::loadEncryptedSave(QByteArray& data)
|
|||
|
||||
do
|
||||
{
|
||||
QString pw = Widget::getInstance()->passwordDialog(tr("Change profile"), dialogtxt);
|
||||
QString pw = GUI::passwordDialog(tr("Change profile"), dialogtxt);
|
||||
|
||||
if (pw.isEmpty())
|
||||
{
|
||||
|
@ -216,7 +216,7 @@ void Core::checkEncryptedHistory()
|
|||
QByteArray salt = getSaltFromFile(path);
|
||||
if (exists && salt.size() == 0)
|
||||
{ // maybe we should handle this better
|
||||
Widget::getInstance()->showWarningMsgBox(tr("Encrypted chat history"), tr("No encrypted chat history file found, or it was corrupted.\nHistory will be disabled!"));
|
||||
GUI::showWarning(tr("Encrypted chat history"), tr("No encrypted chat history file found, or it was corrupted.\nHistory will be disabled!"));
|
||||
Settings::getInstance().setEncryptLogs(false);
|
||||
Settings::getInstance().setEnableLogging(false);
|
||||
HistoryKeeper::resetInstance();
|
||||
|
@ -252,7 +252,7 @@ void Core::checkEncryptedHistory()
|
|||
bool error = true;
|
||||
do
|
||||
{
|
||||
QString pw = Widget::getInstance()->passwordDialog(tr("Disable chat history"), dialogtxt);
|
||||
QString pw = GUI::passwordDialog(tr("Disable chat history"), dialogtxt);
|
||||
|
||||
if (pw.isEmpty())
|
||||
{
|
||||
|
@ -295,7 +295,7 @@ void Core::saveConfiguration(const QString& path)
|
|||
else
|
||||
fileSize = tox_size(tox);
|
||||
|
||||
if (fileSize > 0 && fileSize <= INT32_MAX) {
|
||||
if (fileSize > 0 && fileSize <= std::numeric_limits<int32_t>::max()) {
|
||||
uint8_t *data = new uint8_t[fileSize];
|
||||
|
||||
if (encrypt)
|
||||
|
@ -303,7 +303,7 @@ void Core::saveConfiguration(const QString& path)
|
|||
if (!pwsaltedkeys[ptMain])
|
||||
{
|
||||
// probably zero chance event
|
||||
Widget::getInstance()->showWarningMsgBox(tr("NO Password"), tr("Encryption is enabled, but there is no password! Encryption will be disabled."));
|
||||
GUI::showWarning(tr("NO Password"), tr("Encryption is enabled, but there is no password! Encryption will be disabled."));
|
||||
Settings::getInstance().setEncryptTox(false);
|
||||
tox_save(tox, data);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "friendlist.h"
|
||||
#include "widget/friendwidget.h"
|
||||
#include "widget/form/chatform.h"
|
||||
#include "widget/widget.h"
|
||||
#include "widget/gui.h"
|
||||
#include "src/core.h"
|
||||
#include "src/misc/settings.h"
|
||||
|
||||
|
@ -52,7 +52,7 @@ void Friend::setName(QString name)
|
|||
chatForm->setName(name);
|
||||
|
||||
if (widget->isActive())
|
||||
Widget::getInstance()->setWindowTitle(name);
|
||||
GUI::setWindowTitle(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@ void Friend::setAlias(QString name)
|
|||
chatForm->setName(dispName);
|
||||
|
||||
if (widget->isActive())
|
||||
Widget::getInstance()->setWindowTitle(dispName);
|
||||
GUI::setWindowTitle(dispName);
|
||||
}
|
||||
|
||||
void Friend::setStatusMessage(QString message)
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "friendlist.h"
|
||||
#include "friend.h"
|
||||
#include "core.h"
|
||||
#include "widget/widget.h"
|
||||
#include "widget/gui.h"
|
||||
#include <QDebug>
|
||||
#include <QTimer>
|
||||
|
||||
|
@ -90,7 +90,7 @@ void Group::setName(const QString& name)
|
|||
chatForm->setName(name);
|
||||
|
||||
if (widget->isActive())
|
||||
Widget::getInstance()->setWindowTitle(name);
|
||||
GUI::setWindowTitle(name);
|
||||
}
|
||||
|
||||
void Group::regeneratePeerList()
|
||||
|
|
10
src/main.cpp
10
src/main.cpp
|
@ -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,9 @@ int main(int argc, char *argv[])
|
|||
AutoUpdater::installLocalUpdate(); ///< NORETURN
|
||||
#endif
|
||||
|
||||
Nexus::getInstance().start();
|
||||
|
||||
#ifndef Q_OS_ANDROID
|
||||
// Inter-process communication
|
||||
IPC ipc;
|
||||
ipc.registerEventHandler(&toxURIEventHandler);
|
||||
|
@ -175,17 +180,18 @@ int main(int argc, char *argv[])
|
|||
if (!ipc.isCurrentOwner())
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Run
|
||||
a.setQuitOnLastWindowClosed(false);
|
||||
Widget* w = Widget::getInstance();
|
||||
int errorcode = a.exec();
|
||||
|
||||
delete w;
|
||||
#ifdef LOG_TO_FILE
|
||||
delete logFile;
|
||||
logFile = nullptr;
|
||||
#endif
|
||||
|
||||
Nexus::destroyInstance();
|
||||
|
||||
return errorcode;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -16,10 +16,7 @@
|
|||
|
||||
#include "style.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include "src/widget/widget.h"
|
||||
#include "ui_mainwindow.h"
|
||||
#include "src/widget/genericchatroomwidget.h"
|
||||
#include "src/widget/gui.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QDebug>
|
||||
|
@ -198,11 +195,9 @@ void Style::setThemeColor(QColor color)
|
|||
dict["@themeMediumDark"] = getColor(ThemeMediumDark).name();
|
||||
dict["@themeMedium"] = getColor(ThemeMedium).name();
|
||||
dict["@themeLight"] = getColor(ThemeLight).name();
|
||||
|
||||
applyTheme();
|
||||
}
|
||||
|
||||
void Style::applyTheme()
|
||||
{
|
||||
Widget::getInstance()->reloadTheme();
|
||||
GUI::reloadTheme();
|
||||
}
|
||||
|
|
142
src/nexus.cpp
Normal file
142
src/nexus.cpp
Normal file
|
@ -0,0 +1,142 @@
|
|||
#include "nexus.h"
|
||||
#include "core.h"
|
||||
#include "misc/settings.h"
|
||||
#include "video/camera.h"
|
||||
#include "widget/gui.h"
|
||||
#include <QThread>
|
||||
#include <QDebug>
|
||||
|
||||
#ifdef Q_OS_ANDROID
|
||||
#include <src/widget/androidgui.h>
|
||||
#else
|
||||
#include <src/widget/widget.h>
|
||||
#endif
|
||||
|
||||
static Nexus* nexus{nullptr};
|
||||
|
||||
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
|
||||
GUI::getInstance();
|
||||
|
||||
// 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()
|
||||
{
|
||||
if (!nexus)
|
||||
nexus = new Nexus;
|
||||
return *nexus;
|
||||
}
|
||||
|
||||
void Nexus::destroyInstance()
|
||||
{
|
||||
delete nexus;
|
||||
nexus = nullptr;
|
||||
}
|
||||
|
||||
Core* Nexus::getCore()
|
||||
{
|
||||
return getInstance().core;
|
||||
}
|
||||
|
||||
AndroidGUI* Nexus::getAndroidGUI()
|
||||
{
|
||||
return getInstance().androidgui;
|
||||
}
|
||||
|
||||
Widget* Nexus::getDesktopGUI()
|
||||
{
|
||||
return getInstance().widget;
|
||||
}
|
38
src/nexus.h
Normal file
38
src/nexus.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
#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 void destroyInstance();
|
||||
static Core* getCore(); ///< Will return 0 if not started
|
||||
static AndroidGUI* getAndroidGUI(); ///< Will return 0 if not started
|
||||
static Widget* getDesktopGUI(); ///< 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
|
|
@ -1,5 +1,6 @@
|
|||
#include "callconfirmwidget.h"
|
||||
#include "widget.h"
|
||||
#include "gui.h"
|
||||
#include <assert.h>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
|
@ -11,7 +12,7 @@
|
|||
#include <QPalette>
|
||||
|
||||
CallConfirmWidget::CallConfirmWidget(const QWidget *Anchor) :
|
||||
QWidget(Widget::getInstance()), anchor(Anchor),
|
||||
QWidget(GUI::getMainWidget()), anchor(Anchor),
|
||||
rectW{120}, rectH{85},
|
||||
spikeW{30}, spikeH{15},
|
||||
roundedFactor{20},
|
||||
|
@ -43,7 +44,7 @@ CallConfirmWidget::CallConfirmWidget(const QWidget *Anchor) :
|
|||
connect(buttonBox, &QDialogButtonBox::accepted, this, &CallConfirmWidget::accepted);
|
||||
connect(buttonBox, &QDialogButtonBox::rejected, this, &CallConfirmWidget::rejected);
|
||||
|
||||
connect(Widget::getInstance(), &Widget::resized, this, &CallConfirmWidget::reposition);
|
||||
connect(&GUI::getInstance(), &GUI::resized, this, &CallConfirmWidget::reposition);
|
||||
|
||||
layout->setMargin(12);
|
||||
layout->addSpacing(spikeH);
|
||||
|
@ -56,7 +57,7 @@ CallConfirmWidget::CallConfirmWidget(const QWidget *Anchor) :
|
|||
|
||||
void CallConfirmWidget::reposition()
|
||||
{
|
||||
Widget* w = Widget::getInstance();
|
||||
QWidget* w = GUI::getMainWidget();
|
||||
QPoint pos = anchor->mapToGlobal({(anchor->width()-rectW)/2,anchor->height()})-w->mapToGlobal({0,0});
|
||||
|
||||
// We don't want the widget to overflow past the right of the screen
|
||||
|
|
|
@ -27,6 +27,10 @@
|
|||
#include <AL/al.h>
|
||||
#endif
|
||||
|
||||
#ifndef ALC_ALL_DEVICES_SPECIFIER
|
||||
#define ALC_ALL_DEVICES_SPECIFIER ALC_DEVICE_SPECIFIER
|
||||
#endif
|
||||
|
||||
AVForm::AVForm() :
|
||||
GenericForm(tr("Audio/Video"), QPixmap(":/img/settings/av.png"))
|
||||
{
|
||||
|
|
|
@ -359,4 +359,5 @@ void GeneralForm::onThemeColorChanged(int)
|
|||
int index = bodyUI->themeColorCBox->currentIndex();
|
||||
Settings::getInstance().setThemeColor(index);
|
||||
Style::setThemeColor(index);
|
||||
Style::applyTheme();
|
||||
}
|
||||
|
|
|
@ -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 != "")
|
||||
|
|
290
src/widget/gui.cpp
Normal file
290
src/widget/gui.cpp
Normal file
|
@ -0,0 +1,290 @@
|
|||
#include "gui.h"
|
||||
#include "src/nexus.h"
|
||||
#include <assert.h>
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QInputDialog>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QThread>
|
||||
|
||||
#ifdef Q_OS_ANDROID
|
||||
#include "androidgui.h"
|
||||
#else
|
||||
#include "widget.h"
|
||||
#endif
|
||||
|
||||
GUI::GUI(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
assert(QThread::currentThread() == qApp->thread());
|
||||
|
||||
#ifndef Q_OS_ANDROID
|
||||
assert(Nexus::getDesktopGUI());
|
||||
connect(Nexus::getDesktopGUI(), &Widget::resized, this, &GUI::resized);
|
||||
#endif
|
||||
}
|
||||
|
||||
GUI& GUI::getInstance()
|
||||
{
|
||||
static GUI gui;
|
||||
return gui;
|
||||
}
|
||||
|
||||
// Implementation of the public clean interface
|
||||
|
||||
void GUI::setEnabled(bool state)
|
||||
{
|
||||
if (QThread::currentThread() == qApp->thread())
|
||||
{
|
||||
getInstance()._setEnabled(state);
|
||||
}
|
||||
else
|
||||
{
|
||||
QMetaObject::invokeMethod(&getInstance(), "_setEnabled", Qt::BlockingQueuedConnection,
|
||||
Q_ARG(bool, state));
|
||||
}
|
||||
}
|
||||
|
||||
void GUI::setWindowTitle(const QString& title)
|
||||
{
|
||||
if (QThread::currentThread() == qApp->thread())
|
||||
{
|
||||
getInstance()._setWindowTitle(title);
|
||||
}
|
||||
else
|
||||
{
|
||||
QMetaObject::invokeMethod(&getInstance(), "_setWindowTitle", Qt::BlockingQueuedConnection,
|
||||
Q_ARG(const QString&, title));
|
||||
}
|
||||
}
|
||||
|
||||
void GUI::reloadTheme()
|
||||
{
|
||||
if (QThread::currentThread() == qApp->thread())
|
||||
{
|
||||
getInstance()._reloadTheme();
|
||||
}
|
||||
else
|
||||
{
|
||||
QMetaObject::invokeMethod(&getInstance(), "_reloadTheme", Qt::BlockingQueuedConnection);
|
||||
}
|
||||
}
|
||||
|
||||
void GUI::showWarning(const QString& title, const QString& msg)
|
||||
{
|
||||
if (QThread::currentThread() == qApp->thread())
|
||||
{
|
||||
getInstance()._showWarning(title, msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
QMetaObject::invokeMethod(&getInstance(), "_showWarning", Qt::BlockingQueuedConnection,
|
||||
Q_ARG(const QString&, title), Q_ARG(const QString&, msg));
|
||||
}
|
||||
}
|
||||
|
||||
void GUI::showInfo(const QString& title, const QString& msg)
|
||||
{
|
||||
if (QThread::currentThread() == qApp->thread())
|
||||
{
|
||||
getInstance()._showInfo(title, msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
QMetaObject::invokeMethod(&getInstance(), "_showInfo", Qt::BlockingQueuedConnection,
|
||||
Q_ARG(const QString&, title), Q_ARG(const QString&, msg));
|
||||
}
|
||||
}
|
||||
|
||||
bool GUI::askQuestion(const QString& title, const QString& msg,
|
||||
bool defaultAns, bool warning)
|
||||
{
|
||||
if (QThread::currentThread() == qApp->thread())
|
||||
{
|
||||
return getInstance()._askQuestion(title, msg, defaultAns, warning);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool ret;
|
||||
QMetaObject::invokeMethod(&getInstance(), "_askQuestion", Qt::BlockingQueuedConnection,
|
||||
Q_RETURN_ARG(bool, ret),
|
||||
Q_ARG(const QString&, title), Q_ARG(const QString&, msg),
|
||||
Q_ARG(bool, defaultAns), Q_ARG(bool, warning));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
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::passwordDialog(const QString& cancel, const QString& body)
|
||||
{
|
||||
if (QThread::currentThread() == qApp->thread())
|
||||
{
|
||||
return getInstance()._passwordDialog(cancel, body);
|
||||
}
|
||||
else
|
||||
{
|
||||
QString r;
|
||||
QMetaObject::invokeMethod(&getInstance(), "_passwordDialog", Qt::BlockingQueuedConnection,
|
||||
Q_RETURN_ARG(QString, r),
|
||||
Q_ARG(const QString&, cancel), Q_ARG(const QString&, body));
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
// Private implementations
|
||||
|
||||
void GUI::_setEnabled(bool state)
|
||||
{
|
||||
#ifdef Q_OS_ANDROID
|
||||
Nexus::getAndroidGUI()->setEnabled(state);
|
||||
#else
|
||||
Nexus::getDesktopGUI()->setEnabled(state);
|
||||
#endif
|
||||
}
|
||||
|
||||
void GUI::_setWindowTitle(const QString& title)
|
||||
{
|
||||
if (title.isEmpty())
|
||||
getMainWidget()->setWindowTitle("qTox");
|
||||
else
|
||||
getMainWidget()->setWindowTitle("qTox - " +title);
|
||||
}
|
||||
|
||||
void GUI::_reloadTheme()
|
||||
{
|
||||
#ifndef Q_OS_ANDROID
|
||||
Nexus::getDesktopGUI()->reloadTheme();
|
||||
#endif
|
||||
}
|
||||
|
||||
void GUI::_showWarning(const QString& title, const QString& msg)
|
||||
{
|
||||
QMessageBox::warning(getMainWidget(), title, msg);
|
||||
}
|
||||
|
||||
void GUI::_showInfo(const QString& title, const QString& msg)
|
||||
{
|
||||
QMessageBox::information(getMainWidget(), title, msg);
|
||||
}
|
||||
|
||||
bool GUI::_askQuestion(const QString& title, const QString& msg,
|
||||
bool defaultAns, bool warning)
|
||||
{
|
||||
if (warning)
|
||||
{
|
||||
QMessageBox::StandardButton def = QMessageBox::Cancel;
|
||||
if (defaultAns)
|
||||
def = QMessageBox::Ok;
|
||||
return QMessageBox::warning(getMainWidget(), title, msg, QMessageBox::Ok | QMessageBox::Cancel, def) == QMessageBox::Ok;
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::StandardButton def = QMessageBox::No;
|
||||
if (defaultAns)
|
||||
def = QMessageBox::Yes;
|
||||
return QMessageBox::question(getMainWidget(), title, msg, QMessageBox::Yes | QMessageBox::No, def) == QMessageBox::Yes;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
QString GUI::_passwordDialog(const QString& cancel, const QString& body)
|
||||
{
|
||||
// we use a hack. It is considered that closing the dialog without explicitly clicking
|
||||
// disable history is confusing. But we can't distinguish between clicking the cancel
|
||||
// button and closing the dialog. So instead, we reverse the Ok and Cancel roles,
|
||||
// so that nothing but explicitly clicking disable history closes the dialog
|
||||
QString ret;
|
||||
QInputDialog dialog;
|
||||
dialog.setWindowTitle(tr("Enter your password"));
|
||||
dialog.setOkButtonText(cancel);
|
||||
dialog.setCancelButtonText(tr("Decrypt"));
|
||||
dialog.setInputMode(QInputDialog::TextInput);
|
||||
dialog.setTextEchoMode(QLineEdit::Password);
|
||||
dialog.setLabelText(body);
|
||||
|
||||
// problem with previous hack: the default button is disable history, not decrypt.
|
||||
// use another hack to reverse the default buttons.
|
||||
// http://www.qtcentre.org/threads/49924-Change-property-of-QInputDialog-button
|
||||
QList<QDialogButtonBox*> l = dialog.findChildren<QDialogButtonBox*>();
|
||||
if (!l.isEmpty())
|
||||
{
|
||||
QPushButton* ok = l.first()->button(QDialogButtonBox::Ok);
|
||||
QPushButton* cancel = l.first()->button(QDialogButtonBox::Cancel);
|
||||
if (ok && cancel)
|
||||
{
|
||||
ok->setAutoDefault(false);
|
||||
ok->setDefault(false);
|
||||
cancel->setAutoDefault(true);
|
||||
cancel->setDefault(true);
|
||||
}
|
||||
else
|
||||
qWarning() << "PasswordDialog: Missing button!";
|
||||
}
|
||||
else
|
||||
qWarning() << "PasswordDialog: No QDialogButtonBox!";
|
||||
|
||||
// using similar code, set QLabels to wrap
|
||||
for (auto* label : dialog.findChildren<QLabel*>())
|
||||
label->setWordWrap(true);
|
||||
|
||||
while (true)
|
||||
{
|
||||
int val = dialog.exec();
|
||||
if (val == QDialog::Accepted)
|
||||
return QString();
|
||||
else
|
||||
{
|
||||
ret = dialog.textValue();
|
||||
if (!ret.isEmpty())
|
||||
return ret;
|
||||
}
|
||||
dialog.setTextValue("");
|
||||
dialog.setLabelText(body + "\n\n" + tr("You must enter a non-empty password:"));
|
||||
}
|
||||
}
|
||||
|
||||
// Other
|
||||
|
||||
QWidget* GUI::getMainWidget()
|
||||
{
|
||||
QWidget* maingui{nullptr};
|
||||
#ifdef Q_OS_ANDROID
|
||||
maingui = Nexus::getAndroidGUI();
|
||||
#else
|
||||
maingui = Nexus::getDesktopGUI();
|
||||
#endif
|
||||
return maingui;
|
||||
}
|
72
src/widget/gui.h
Normal file
72
src/widget/gui.h
Normal file
|
@ -0,0 +1,72 @@
|
|||
#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();
|
||||
/// Returns the main QWidget* of the application
|
||||
static QWidget* getMainWidget();
|
||||
/// Will enable or disable the GUI.
|
||||
/// A disabled GUI can't be interacted with by the user
|
||||
static void setEnabled(bool state);
|
||||
/// Change the title of the main window
|
||||
/// This is usually always visible to the user
|
||||
static void setWindowTitle(const QString& title);
|
||||
/// Reloads the application theme and redraw the window
|
||||
static void reloadTheme();
|
||||
/// Show a warning to the user, for example in a message box
|
||||
static void showWarning(const QString& title, const QString& msg);
|
||||
/// Show some text to the user, for example in a message box
|
||||
static void showInfo(const QString& title, const QString& msg);
|
||||
/// Asks the user a question, for example in a message box.
|
||||
/// If warning is true, we will use a special warning style.
|
||||
/// Returns the answer.
|
||||
static bool askQuestion(const QString& title, const QString& msg,
|
||||
bool defaultAns = false, bool warning = true);
|
||||
/// Asks the user to input text and returns the answer.
|
||||
/// The interface is equivalent to QInputDialog::getItem()
|
||||
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);
|
||||
/// Asks the user to answer a password
|
||||
/// cancel is the text on the cancel button and body
|
||||
/// is descriptive text that will be shown to the user
|
||||
static QString passwordDialog(const QString& cancel, const QString& body);
|
||||
|
||||
signals:
|
||||
/// Emitted when the GUI is resized on supported platforms
|
||||
/// Guaranteed to work on desktop platforms
|
||||
void resized();
|
||||
|
||||
private:
|
||||
explicit GUI(QObject *parent = 0);
|
||||
|
||||
// Private implementation, those must be called from the GUI thread
|
||||
private slots:
|
||||
void _setEnabled(bool state);
|
||||
void _setWindowTitle(const QString& title);
|
||||
void _reloadTheme();
|
||||
void _showWarning(const QString& title, const QString& msg);
|
||||
void _showInfo(const QString& title, const QString& msg);
|
||||
bool _askQuestion(const QString& title, const QString& msg,
|
||||
bool defaultAns = false, bool warning = true);
|
||||
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);
|
||||
QString _passwordDialog(const QString& cancel, const QString& body);
|
||||
};
|
||||
|
||||
#endif // GUI_H
|
|
@ -42,6 +42,11 @@ SystemTrayIcon::SystemTrayIcon()
|
|||
}
|
||||
}
|
||||
|
||||
SystemTrayIcon::~SystemTrayIcon()
|
||||
{
|
||||
qDebug() << "Deleting SystemTrayIcon";
|
||||
}
|
||||
|
||||
QString SystemTrayIcon::extractIconToFile(QIcon icon, QString name)
|
||||
{
|
||||
QString iconPath;
|
||||
|
|
|
@ -12,6 +12,7 @@ class SystemTrayIcon : public QObject
|
|||
Q_OBJECT
|
||||
public:
|
||||
SystemTrayIcon();
|
||||
~SystemTrayIcon();
|
||||
void setContextMenu(QMenu* menu);
|
||||
void show();
|
||||
void hide();
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
|
||||
#include "toxsave.h"
|
||||
#include "widget.h"
|
||||
#include "gui.h"
|
||||
#include "src/core.h"
|
||||
#include "src/misc/settings.h"
|
||||
#include <QCoreApplication>
|
||||
|
@ -53,20 +53,19 @@ void handleToxSave(const QString& path)
|
|||
|
||||
if (info.suffix() != "tox")
|
||||
{
|
||||
QMessageBox::warning(Widget::getInstance(),
|
||||
QObject::tr("Ignoring non-Tox file", "popup title"),
|
||||
QObject::tr("Warning: you've chosen a file that is not a Tox save file; ignoring.", "popup text"));
|
||||
GUI::showWarning(QObject::tr("Ignoring non-Tox file", "popup title"),
|
||||
QObject::tr("Warning: you've chosen a file that is not a Tox save file; ignoring.", "popup text"));
|
||||
return;
|
||||
}
|
||||
|
||||
QString profilePath = QDir(Settings::getSettingsDirPath()).filePath(profile + Core::TOX_EXT);
|
||||
|
||||
if (QFileInfo(profilePath).exists() && !Widget::getInstance()->askQuestion(QObject::tr("Profile already exists", "import confirm title"),
|
||||
if (QFileInfo(profilePath).exists() && !GUI::askQuestion(QObject::tr("Profile already exists", "import confirm title"),
|
||||
QObject::tr("A profile named \"%1\" already exists. Do you want to erase it?", "import confirm text").arg(profile)))
|
||||
return;
|
||||
|
||||
QFile::copy(path, profilePath);
|
||||
// no good way to update the ui from here... maybe we need a Widget:refreshUi() function...
|
||||
// such a thing would simplify other code as well I believe
|
||||
QMessageBox::information(Widget::getInstance(), QObject::tr("Profile imported"), QObject::tr("%1.tox was successfully imported").arg(profile));
|
||||
GUI::showInfo(QObject::tr("Profile imported"), QObject::tr("%1.tox was successfully imported").arg(profile));
|
||||
}
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
#include "src/audio.h"
|
||||
#include "src/platform/timer.h"
|
||||
#include "systemtrayicon.h"
|
||||
#include "src/nexus.h"
|
||||
#include <cassert>
|
||||
#include <QMessageBox>
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
|
@ -53,6 +55,12 @@
|
|||
#include <QTranslator>
|
||||
#include <tox/tox.h>
|
||||
|
||||
#ifdef Q_OS_ANDROID
|
||||
#define IS_ON_DESKTOP_GUI 0
|
||||
#else
|
||||
#define IS_ON_DESKTOP_GUI 1
|
||||
#endif
|
||||
|
||||
void toxActivateEventHandler(const QByteArray& data)
|
||||
{
|
||||
if (data != "$activate")
|
||||
|
@ -64,11 +72,11 @@ Widget *Widget::instance{nullptr};
|
|||
|
||||
Widget::Widget(QWidget *parent)
|
||||
: QMainWindow(parent),
|
||||
icon{nullptr},
|
||||
ui(new Ui::MainWindow),
|
||||
activeChatroomWidget{nullptr},
|
||||
eventFlag(false),
|
||||
eventIcon(false),
|
||||
icon{nullptr}
|
||||
eventIcon(false)
|
||||
{
|
||||
translator = new QTranslator;
|
||||
setTranslation();
|
||||
|
@ -116,6 +124,9 @@ void Widget::init()
|
|||
this,
|
||||
SLOT(onIconClick(QSystemTrayIcon::ActivationReason)));
|
||||
|
||||
icon->show();
|
||||
icon->hide();
|
||||
|
||||
if (Settings::getInstance().getShowSystemTray())
|
||||
{
|
||||
icon->show();
|
||||
|
@ -124,7 +135,6 @@ void Widget::init()
|
|||
}
|
||||
else
|
||||
this->show();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -193,68 +203,16 @@ void Widget::init()
|
|||
ui->statusButton->setEnabled(false);
|
||||
|
||||
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);
|
||||
reloadTheme();
|
||||
|
||||
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 +228,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)
|
||||
|
@ -317,10 +273,8 @@ void Widget::updateTrayIcon()
|
|||
|
||||
Widget::~Widget()
|
||||
{
|
||||
qDebug() << "Deleting Widget";
|
||||
core->saveConfiguration();
|
||||
qDebug() << "Widget: Deleting Widget";
|
||||
AutoUpdater::abortUpdates();
|
||||
delete core;
|
||||
icon->hide();
|
||||
hideMainForms();
|
||||
delete settingsWidget;
|
||||
|
@ -338,6 +292,8 @@ Widget::~Widget()
|
|||
|
||||
Widget* Widget::getInstance()
|
||||
{
|
||||
assert(IS_ON_DESKTOP_GUI); // Widget must only be used on Desktop platforms
|
||||
|
||||
if (!instance)
|
||||
{
|
||||
instance = new Widget();
|
||||
|
@ -346,11 +302,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 +337,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 +383,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 +479,7 @@ void Widget::onAddClicked()
|
|||
|
||||
void Widget::onGroupClicked()
|
||||
{
|
||||
core->createGroup();
|
||||
Nexus::getCore()->createGroup();
|
||||
}
|
||||
|
||||
void Widget::onTransferClicked()
|
||||
|
@ -664,7 +552,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 +569,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 +595,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 +817,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 +848,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 +856,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 +903,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 +922,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 +945,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 +959,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 +974,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 +1059,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