diff --git a/qtox.pro b/qtox.pro index d42fba74b..3c95c22ba 100644 --- a/qtox.pro +++ b/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 diff --git a/src/core.cpp b/src/core.cpp index 4b82a1d5a..f6fa4463c 100644 --- a/src/core.cpp +++ b/src/core.cpp @@ -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()) { diff --git a/src/main.cpp b/src/main.cpp index a1c3dbdde..8d5ba8934 100644 --- a/src/main.cpp +++ b/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,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; diff --git a/src/misc/settings.cpp b/src/misc/settings.cpp index 196202865..96b2b2c6e 100644 --- a/src/misc/settings.cpp +++ b/src/misc/settings.cpp @@ -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 #include @@ -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 Settings::searchProfiles() +{ + QList 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 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) diff --git a/src/misc/settings.h b/src/misc/settings.h index 391fe1c58..550b79840 100644 --- a/src/misc/settings.h +++ b/src/misc/settings.h @@ -33,6 +33,9 @@ public: static Settings& getInstance(); static void resetInstance(); void switchProfile(const QString& profile); + QString detectProfile(); + QList searchProfiles(); + QString askProfiles(); ~Settings() = default; void executeSettingsDialog(QWidget* parent); diff --git a/src/nexus.cpp b/src/nexus.cpp new file mode 100644 index 000000000..91b65530e --- /dev/null +++ b/src/nexus.cpp @@ -0,0 +1,121 @@ +#include "nexus.h" +#include "core.h" +#include "misc/settings.h" +#include "video/camera.h" +#include +#include + +#ifdef Q_OS_ANDROID +#include +#else +#include +#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"); + qRegisterMetaType("vpx_image"); + qRegisterMetaType("uint8_t"); + qRegisterMetaType("uint16_t"); + qRegisterMetaType("const int16_t*"); + qRegisterMetaType("int32_t"); + qRegisterMetaType("int64_t"); + qRegisterMetaType("QPixmap"); + qRegisterMetaType("ToxFile"); + qRegisterMetaType("ToxFile::FileDirection"); + qRegisterMetaType("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; +} diff --git a/src/nexus.h b/src/nexus.h new file mode 100644 index 000000000..f8b5dd4b5 --- /dev/null +++ b/src/nexus.h @@ -0,0 +1,35 @@ +#ifndef NEXUS_H +#define NEXUS_H + +#include + +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 diff --git a/src/widget/androidgui.cpp b/src/widget/androidgui.cpp new file mode 100644 index 000000000..7ae41d983 --- /dev/null +++ b/src/widget/androidgui.cpp @@ -0,0 +1,13 @@ +#include "androidgui.h" +#include + +AndroidGUI::AndroidGUI(QWidget *parent) : + QWidget(parent) +{ + l = new QLabel("qTox Android", this); +} + +AndroidGUI::~AndroidGUI() +{ + delete l; +} diff --git a/src/widget/androidgui.h b/src/widget/androidgui.h new file mode 100644 index 000000000..853483ce2 --- /dev/null +++ b/src/widget/androidgui.h @@ -0,0 +1,19 @@ +#ifndef ANDROIDGUI_H +#define ANDROIDGUI_H + +#include + +class QLabel; + +class AndroidGUI : public QWidget +{ + Q_OBJECT +public: + explicit AndroidGUI(QWidget *parent = 0); + ~AndroidGUI(); + +private: + QLabel* l; +}; + +#endif // ANDROIDGUI_H diff --git a/src/widget/form/settings/identityform.cpp b/src/widget/form/settings/identityform.cpp index 8d067b606..a856af1b5 100644 --- a/src/widget/form/settings/identityform.cpp +++ b/src/widget/form/settings/identityform.cpp @@ -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 != "") diff --git a/src/widget/gui.cpp b/src/widget/gui.cpp new file mode 100644 index 000000000..76f77e8db --- /dev/null +++ b/src/widget/gui.cpp @@ -0,0 +1,47 @@ +#include "gui.h" +#include +#include +#include + +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); +} diff --git a/src/widget/gui.h b/src/widget/gui.h new file mode 100644 index 000000000..7a7f70339 --- /dev/null +++ b/src/widget/gui.h @@ -0,0 +1,33 @@ +#ifndef GUI_H +#define GUI_H + +#include + +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 diff --git a/src/widget/widget.cpp b/src/widget/widget.cpp index cca091025..3a5d5ee5c 100644 --- a/src/widget/widget.cpp +++ b/src/widget/widget.cpp @@ -36,6 +36,7 @@ #include "src/audio.h" #include "src/platform/timer.h" #include "systemtrayicon.h" +#include "src/nexus.h" #include #include #include @@ -194,67 +195,15 @@ void Widget::init() Style::setThemeColor(Settings::getInstance().getThemeColor()); Style::applyTheme(); - - qRegisterMetaType("Status"); - qRegisterMetaType("vpx_image"); - qRegisterMetaType("uint8_t"); - qRegisterMetaType("uint16_t"); - qRegisterMetaType("const int16_t*"); - qRegisterMetaType("int32_t"); - qRegisterMetaType("int64_t"); - qRegisterMetaType("QPixmap"); - qRegisterMetaType("ToxFile"); - qRegisterMetaType("ToxFile::FileDirection"); - qRegisterMetaType("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 Widget::searchProfiles() -{ - QList 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 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(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) diff --git a/src/widget/widget.h b/src/widget/widget.h index 0a8307cbe..f43a301f7 100644 --- a/src/widget/widget.h +++ b/src/widget/widget.h @@ -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 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;