From 61b3cb528aa7e87e76951fe296e6054c49929260 Mon Sep 17 00:00:00 2001 From: Anthony Bilinski Date: Fri, 11 Mar 2022 07:50:42 -0800 Subject: [PATCH] refactor: Remove CameraSource singleton Grossly expose it publicly from Nexus for the time being since Profile is sometimes constructed from main, while Nexus is also a singleton. So CameraSource can't be constructed in main and be passed in to Nexus on construction. This should be temporary, until Nexus's singleton is removed as well. --- src/core/coreav.cpp | 15 ++++++++++----- src/core/coreav.h | 6 ++++-- src/core/toxcall.cpp | 17 ++++++++++------- src/core/toxcall.h | 4 +++- src/main.cpp | 5 ++--- src/nexus.cpp | 16 ++++++++++++---- src/nexus.h | 7 ++++++- src/persistence/profile.cpp | 12 ++++++------ src/persistence/profile.h | 7 ++++--- src/video/camerasource.cpp | 18 ------------------ src/video/camerasource.h | 8 ++------ src/video/netcamview.cpp | 5 +++-- src/video/netcamview.h | 4 +++- src/widget/form/chatform.cpp | 6 ++++-- src/widget/form/chatform.h | 4 +++- src/widget/form/settingswidget.cpp | 5 ++--- src/widget/form/settingswidget.h | 3 ++- src/widget/widget.cpp | 9 ++++++--- src/widget/widget.h | 5 ++++- 19 files changed, 86 insertions(+), 70 deletions(-) diff --git a/src/core/coreav.cpp b/src/core/coreav.cpp index 3d9b9a38c..f0326a7a0 100644 --- a/src/core/coreav.cpp +++ b/src/core/coreav.cpp @@ -71,7 +71,7 @@ */ CoreAV::CoreAV(std::unique_ptr toxav_, CompatibleRecursiveMutex& toxCoreLock, - IAudioSettings& audioSettings_, IGroupSettings& groupSettings_) + IAudioSettings& audioSettings_, IGroupSettings& groupSettings_, CameraSource& cameraSource_) : audio{nullptr} , toxav{std::move(toxav_)} , coreavThread{new QThread{this}} @@ -79,6 +79,7 @@ CoreAV::CoreAV(std::unique_ptr toxav_, CompatibleRecursiveM , coreLock{toxCoreLock} , audioSettings{audioSettings_} , groupSettings{groupSettings_} + , cameraSource{cameraSource_} { assert(coreavThread); assert(iterateTimer); @@ -111,7 +112,8 @@ void CoreAV::connectCallbacks() * @return CoreAV instance on success, {} on failure */ CoreAV::CoreAVPtr CoreAV::makeCoreAV(Tox* core, CompatibleRecursiveMutex& toxCoreLock, - IAudioSettings& audioSettings, IGroupSettings& groupSettings) + IAudioSettings& audioSettings, IGroupSettings& groupSettings, + CameraSource& cameraSource) { Toxav_Err_New err; std::unique_ptr toxav{toxav_new(core, &err)}; @@ -131,7 +133,8 @@ CoreAV::CoreAVPtr CoreAV::makeCoreAV(Tox* core, CompatibleRecursiveMutex& toxCor assert(toxav != nullptr); - return CoreAVPtr{new CoreAV{std::move(toxav), toxCoreLock, audioSettings, groupSettings}}; + return CoreAVPtr{new CoreAV{std::move(toxav), toxCoreLock, audioSettings, + groupSettings, cameraSource}}; } /** @@ -288,7 +291,8 @@ bool CoreAV::startCall(uint32_t friendNum, bool video) // Audio backend must be set before making a call assert(audio != nullptr); - ToxFriendCallPtr call = ToxFriendCallPtr(new ToxFriendCall(friendNum, video, *this, *audio)); + ToxFriendCallPtr call = ToxFriendCallPtr(new ToxFriendCall(friendNum, video, + *this, *audio, cameraSource)); // Call object must be owned by this thread or there will be locking problems with Audio call->moveToThread(thread()); assert(call != nullptr); @@ -722,7 +726,8 @@ void CoreAV::callCallback(ToxAV* toxav, uint32_t friendNum, bool audio, bool vid // Audio backend must be set before receiving a call assert(self->audio != nullptr); - ToxFriendCallPtr call = ToxFriendCallPtr(new ToxFriendCall{friendNum, video, *self, *self->audio}); + ToxFriendCallPtr call = ToxFriendCallPtr(new ToxFriendCall{friendNum, video, + *self, *self->audio, self->cameraSource}); // Call object must be owned by CoreAV thread or there will be locking problems with Audio call->moveToThread(self->thread()); assert(call != nullptr); diff --git a/src/core/coreav.h b/src/core/coreav.h index 1042f9201..ef985e6a0 100644 --- a/src/core/coreav.h +++ b/src/core/coreav.h @@ -51,7 +51,8 @@ class CoreAV : public QObject public: using CoreAVPtr = std::unique_ptr; static CoreAVPtr makeCoreAV(Tox* core, CompatibleRecursiveMutex& toxCoreLock, - IAudioSettings& audioSettings, IGroupSettings& groupSettings); + IAudioSettings& audioSettings, IGroupSettings& groupSettings, + CameraSource&); void setAudio(IAudioControl& newAudio); IAudioControl* getAudio(); @@ -118,7 +119,7 @@ private: }; CoreAV(std::unique_ptr tox_, CompatibleRecursiveMutex &toxCoreLock, - IAudioSettings& audioSettings_, IGroupSettings& groupSettings_); + IAudioSettings& audioSettings_, IGroupSettings& groupSettings_, CameraSource&); void connectCallbacks(); void process(); @@ -165,4 +166,5 @@ private: IAudioSettings& audioSettings; IGroupSettings& groupSettings; + CameraSource& cameraSource; }; diff --git a/src/core/toxcall.cpp b/src/core/toxcall.cpp index babcabd0f..13b1d31ad 100644 --- a/src/core/toxcall.cpp +++ b/src/core/toxcall.cpp @@ -59,7 +59,6 @@ ToxCall::~ToxCall() { if (videoEnabled) { QObject::disconnect(videoInConn); - CameraSource::getInstance().unsubscribe(); } } @@ -118,10 +117,12 @@ CoreVideoSource* ToxCall::getVideoSource() const return videoSource; } -ToxFriendCall::ToxFriendCall(uint32_t FriendNum, bool VideoEnabled, CoreAV& av_, IAudioControl& audio_) +ToxFriendCall::ToxFriendCall(uint32_t FriendNum, bool VideoEnabled, CoreAV& av_, + IAudioControl& audio_, CameraSource& cameraSource_) : ToxCall(VideoEnabled, av_, audio_) , sink(audio_.makeSink()) , friendId{FriendNum} + , cameraSource{cameraSource_} { connect(audioSource.get(), &IAudioSource::frameAvailable, this, [this](const int16_t* pcm, size_t samples, uint8_t chans, uint32_t rate) { @@ -137,13 +138,12 @@ ToxFriendCall::ToxFriendCall(uint32_t FriendNum, bool VideoEnabled, CoreAV& av_, // register video if (videoEnabled) { videoSource = new CoreVideoSource(); - CameraSource& source = CameraSource::getInstance(); - if (source.isNone()) { - source.setupDefault(); + if (cameraSource.isNone()) { + cameraSource.setupDefault(); } - source.subscribe(); - videoInConn = QObject::connect(&source, &VideoSource::frameAvailable, + cameraSource.subscribe(); + videoInConn = QObject::connect(&cameraSource, &VideoSource::frameAvailable, [&av_, FriendNum](std::shared_ptr frame) { av_.sendCallVideo(FriendNum, frame); }); @@ -155,6 +155,9 @@ ToxFriendCall::ToxFriendCall(uint32_t FriendNum, bool VideoEnabled, CoreAV& av_, ToxFriendCall::~ToxFriendCall() { + if (videoEnabled) { + cameraSource.unsubscribe(); + } QObject::disconnect(audioSinkInvalid); } diff --git a/src/core/toxcall.h b/src/core/toxcall.h index 102862b92..4aece0617 100644 --- a/src/core/toxcall.h +++ b/src/core/toxcall.h @@ -37,6 +37,7 @@ class AudioFilterer; class CoreVideoSource; class CoreAV; class Group; +class CameraSource; class ToxCall : public QObject { @@ -91,7 +92,7 @@ class ToxFriendCall : public ToxCall Q_OBJECT public: ToxFriendCall() = delete; - ToxFriendCall(uint32_t friendId, bool VideoEnabled, CoreAV& av_, IAudioControl& audio_); + ToxFriendCall(uint32_t friendId, bool VideoEnabled, CoreAV& av_, IAudioControl& audio_, CameraSource&); ToxFriendCall(ToxFriendCall&& other) = delete; ToxFriendCall& operator=(ToxFriendCall&& other) = delete; ~ToxFriendCall(); @@ -110,6 +111,7 @@ private: TOXAV_FRIEND_CALL_STATE state{TOXAV_FRIEND_CALL_STATE_NONE}; std::unique_ptr sink; uint32_t friendId; + CameraSource& cameraSource; }; class ToxGroupCall : public ToxCall diff --git a/src/main.cpp b/src/main.cpp index 0e19fc702..2921e37d6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -67,7 +67,6 @@ void cleanup() s.sync(); Nexus::destroyInstance(); - CameraSource::destroyInstance(); Settings::destroyInstance(); qDebug() << "Cleanup success"; @@ -400,13 +399,13 @@ int main(int argc, char* argv[]) // note: Because Settings is shouldering global settings as well as model specific ones it // cannot be integrated into a central model object yet nexus.setSettings(&settings); - + auto& cameraSource = Nexus::getCameraSource(); // Autologin // TODO (kriby): Shift responsibility of linking views to model objects from nexus // Further: generate view instances separately (loginScreen, mainGUI, audio) Profile* profile = nullptr; if (autoLogin && Profile::exists(profileName) && !Profile::isEncrypted(profileName)) { - profile = Profile::loadProfile(profileName, QString(), settings, &parser); + profile = Profile::loadProfile(profileName, QString(), settings, &parser, cameraSource); if (!profile) { QMessageBox::information(nullptr, QObject::tr("Error"), QObject::tr("Failed to load profile automatically.")); diff --git a/src/nexus.cpp b/src/nexus.cpp index 59abf367d..171cded1d 100644 --- a/src/nexus.cpp +++ b/src/nexus.cpp @@ -63,7 +63,10 @@ Nexus::Nexus(QObject* parent) : QObject(parent) , profile{nullptr} , widget{nullptr} -{} + , cameraSource(new CameraSource()) +{ + assert(cameraSource); +} Nexus::~Nexus() { @@ -228,7 +231,7 @@ void Nexus::showMainGUI() assert(profile); // Create GUI - widget = new Widget(*profile, *audioControl); + widget = new Widget(*profile, *audioControl, *cameraSource); // Start GUI widget->init(); @@ -301,7 +304,7 @@ Profile* Nexus::getProfile() */ void Nexus::onCreateNewProfile(const QString& name, const QString& pass) { - setProfile(Profile::createProfile(name, pass, *settings, parser)); + setProfile(Profile::createProfile(name, pass, *settings, parser, *cameraSource)); parser = nullptr; // only apply cmdline proxy settings once } @@ -310,7 +313,7 @@ void Nexus::onCreateNewProfile(const QString& name, const QString& pass) */ void Nexus::onLoadProfile(const QString& name, const QString& pass) { - setProfile(Profile::loadProfile(name, pass, *settings, parser)); + setProfile(Profile::loadProfile(name, pass, *settings, parser, *cameraSource)); parser = nullptr; // only apply cmdline proxy settings once } /** @@ -344,6 +347,11 @@ Widget* Nexus::getDesktopGUI() return getInstance().widget; } +CameraSource& Nexus::getCameraSource() +{ + return *getInstance().cameraSource; +} + #ifdef Q_OS_MAC void Nexus::retranslateUi() { diff --git a/src/nexus.h b/src/nexus.h index 6fa048264..bbc88dbfd 100644 --- a/src/nexus.h +++ b/src/nexus.h @@ -20,9 +20,11 @@ #pragma once +#include "audio/iaudiocontrol.h" + #include -#include "audio/iaudiocontrol.h" +#include class Widget; class Profile; @@ -30,6 +32,7 @@ class Settings; class LoginScreen; class Core; class QCommandLineParser; +class CameraSource; #ifdef Q_OS_MAC class QMenuBar; @@ -53,6 +56,7 @@ public: static Core* getCore(); static Profile* getProfile(); static Widget* getDesktopGUI(); + static CameraSource& getCameraSource(); #ifdef Q_OS_MAC @@ -104,4 +108,5 @@ private: Widget* widget; std::unique_ptr audioControl; QCommandLineParser* parser = nullptr; + std::unique_ptr cameraSource; }; diff --git a/src/persistence/profile.cpp b/src/persistence/profile.cpp index 45a8ff5d4..fe150acd9 100644 --- a/src/persistence/profile.cpp +++ b/src/persistence/profile.cpp @@ -232,7 +232,7 @@ bool logCreateToxDataError(const CreateToxDataError& error, const QString& userN QStringList Profile::profiles; -void Profile::initCore(const QByteArray& toxsave, Settings& s, bool isNewProfile) +void Profile::initCore(const QByteArray& toxsave, Settings& s, bool isNewProfile, CameraSource& cameraSource) { if (toxsave.isEmpty() && !isNewProfile) { qCritical() << "Existing toxsave is empty"; @@ -265,7 +265,7 @@ void Profile::initCore(const QByteArray& toxsave, Settings& s, bool isNewProfile return; } - coreAv = CoreAV::makeCoreAV(core->getTox(), core->getCoreLoopLock(), s, s); + coreAv = CoreAV::makeCoreAV(core->getTox(), core->getCoreLoopLock(), s, s, cameraSource); if (!coreAv) { qDebug() << "Failed to start ToxAV"; emit failedToStart(); @@ -311,7 +311,7 @@ Profile::Profile(const QString& name_, std::unique_ptr passkey_, Pat * @note If the profile is already in use return nullptr. */ Profile* Profile::loadProfile(const QString& name, const QString& password, Settings& settings, - const QCommandLineParser* parser) + const QCommandLineParser* parser, CameraSource& cameraSource) { if (ProfileLocker::hasLock()) { qCritical() << "Tried to load profile " << name << ", but another profile is already locked!"; @@ -339,7 +339,7 @@ Profile* Profile::loadProfile(const QString& name, const QString& password, Sett constexpr bool isNewProfile = false; settings.updateProfileData(p, parser, isNewProfile); - p->initCore(toxsave, settings, isNewProfile); + p->initCore(toxsave, settings, isNewProfile, cameraSource); p->loadDatabase(password); return p; @@ -354,7 +354,7 @@ Profile* Profile::loadProfile(const QString& name, const QString& password, Sett * @note If the profile is already in use return nullptr. */ Profile* Profile::createProfile(const QString& name, const QString& password, Settings& settings, - const QCommandLineParser* parser) + const QCommandLineParser* parser, CameraSource& cameraSource) { CreateToxDataError error; Paths& paths = settings.getPaths(); @@ -371,7 +371,7 @@ Profile* Profile::createProfile(const QString& name, const QString& password, Se constexpr bool isNewProfile = true; settings.updateProfileData(p, parser, isNewProfile); - p->initCore(QByteArray(), settings, isNewProfile); + p->initCore(QByteArray(), settings, isNewProfile, cameraSource); p->loadDatabase(password); return p; } diff --git a/src/persistence/profile.h b/src/persistence/profile.h index 9899d80c9..8ccef6050 100644 --- a/src/persistence/profile.h +++ b/src/persistence/profile.h @@ -38,6 +38,7 @@ class Settings; class QCommandLineParser; class ToxPk; +class CameraSource; class Profile : public QObject { @@ -45,9 +46,9 @@ class Profile : public QObject public: static Profile* loadProfile(const QString& name, const QString& password, Settings& settings, - const QCommandLineParser* parser); + const QCommandLineParser* parser, CameraSource&); static Profile* createProfile(const QString& name, const QString& password, Settings& settings, - const QCommandLineParser* parser); + const QCommandLineParser* parser, CameraSource&); ~Profile(); Core& getCore() const; @@ -108,7 +109,7 @@ private: static QStringList getFilesByExt(QString extension); QString avatarPath(const ToxPk& owner, bool forceUnencrypted = false); bool saveToxSave(QByteArray data); - void initCore(const QByteArray& toxsave, Settings &s, bool isNewProfile); + void initCore(const QByteArray& toxsave, Settings &s, bool isNewProfile, CameraSource&); private: std::unique_ptr avatarBroadcaster; diff --git a/src/video/camerasource.cpp b/src/video/camerasource.cpp index f454991f0..4e0774c90 100644 --- a/src/video/camerasource.cpp +++ b/src/video/camerasource.cpp @@ -90,8 +90,6 @@ extern "C" { * @brief Remember how many times we subscribed for RAII */ -CameraSource* CameraSource::instance{nullptr}; - CameraSource::CameraSource() : deviceThread{new QThread} , deviceName{"none"} @@ -122,22 +120,6 @@ CameraSource::CameraSource() // clang-format on -/** - * @brief Returns the singleton instance. - */ -CameraSource& CameraSource::getInstance() -{ - if (!instance) - instance = new CameraSource(); - return *instance; -} - -void CameraSource::destroyInstance() -{ - delete instance; - instance = nullptr; -} - /** * @brief Setup default device * @note If a device is already open, the source will seamlessly switch to the new device. diff --git a/src/video/camerasource.h b/src/video/camerasource.h index 5641ad033..df73fedb5 100644 --- a/src/video/camerasource.h +++ b/src/video/camerasource.h @@ -36,8 +36,8 @@ class CameraSource : public VideoSource Q_OBJECT public: - static CameraSource& getInstance(); - static void destroyInstance(); + CameraSource(); + ~CameraSource(); void setupDefault(); bool isNone() const; @@ -53,8 +53,6 @@ signals: void openFailed(); private: - CameraSource(); - ~CameraSource(); void stream(); private slots: @@ -78,6 +76,4 @@ private: std::atomic_bool isNone_; std::atomic_int subscriptions; - - static CameraSource* instance; }; diff --git a/src/video/netcamview.cpp b/src/video/netcamview.cpp index 0a94ca88a..0e9713352 100644 --- a/src/video/netcamview.cpp +++ b/src/video/netcamview.cpp @@ -47,11 +47,12 @@ const int BTN_PANEL_WIDTH = 250; const auto BTN_STYLE_SHEET_PATH = QStringLiteral("chatForm/fullScreenButtons.css"); } -NetCamView::NetCamView(ToxPk friendPk_, QWidget* parent) +NetCamView::NetCamView(ToxPk friendPk_, CameraSource& cameraSource_, QWidget* parent) : QWidget(parent) , selfFrame{nullptr} , friendPk{friendPk_} , e(false) + , cameraSource{cameraSource_} { verLayout = new QVBoxLayout(this); setWindowTitle(tr("Tox video")); @@ -167,7 +168,7 @@ NetCamView::~NetCamView() void NetCamView::show(VideoSource* source, const QString& title) { setSource(source); - selfVideoSurface->setSource(&CameraSource::getInstance()); + selfVideoSurface->setSource(&cameraSource); setTitle(title); QWidget::show(); diff --git a/src/video/netcamview.h b/src/video/netcamview.h index 847cf619f..cadd7ab6e 100644 --- a/src/video/netcamview.h +++ b/src/video/netcamview.h @@ -34,13 +34,14 @@ class QPushButton; class QKeyEvent; class QCloseEvent; class QShowEvent; +class CameraSource; class NetCamView : public QWidget { Q_OBJECT public: - NetCamView(ToxPk friendPk_, QWidget* parent = nullptr); + NetCamView(ToxPk friendPk_, CameraSource&, QWidget* parent = nullptr); ~NetCamView(); virtual void show(VideoSource* source, const QString& title); @@ -95,4 +96,5 @@ private: QPushButton* microphoneButton = nullptr; QPushButton* endVideoButton = nullptr; QPushButton* exitFullScreenButton = nullptr; + CameraSource& cameraSource; }; diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index bb3f387e7..c7736db7f 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -107,13 +107,15 @@ QString secondsToDHMS(quint32 duration) } // namespace ChatForm::ChatForm(Profile& profile, Friend* chatFriend, IChatLog& chatLog_, - IMessageDispatcher& messageDispatcher_, DocumentCache& documentCache_, SmileyPack& smileyPack_) + IMessageDispatcher& messageDispatcher_, DocumentCache& documentCache_, + SmileyPack& smileyPack_, CameraSource& cameraSource_) : GenericChatForm(profile.getCore(), chatFriend, chatLog_, messageDispatcher_, documentCache_, smileyPack_) , core{profile.getCore()} , f(chatFriend) , isTyping{false} , lastCallIsVideo{false} + , cameraSource{cameraSource_} { setName(f->getDisplayedName()); @@ -509,7 +511,7 @@ std::unique_ptr ChatForm::createNetcam() { qDebug() << "creating netcam"; uint32_t friendId = f->getId(); - std::unique_ptr view = std::unique_ptr(new NetCamView(f->getPublicKey(), this)); + std::unique_ptr view = std::unique_ptr(new NetCamView(f->getPublicKey(), cameraSource, this)); CoreAV* av = core.getAv(); VideoSource* source = av->getVideoSourceFromCall(friendId); view->show(source, f->getDisplayedName()); diff --git a/src/widget/form/chatform.h b/src/widget/form/chatform.h index 49d42aee2..1d3c5c85c 100644 --- a/src/widget/form/chatform.h +++ b/src/widget/form/chatform.h @@ -50,7 +50,8 @@ class ChatForm : public GenericChatForm Q_OBJECT public: ChatForm(Profile& profile, Friend* chatFriend, IChatLog& chatLog_, - IMessageDispatcher& messageDispatcher_, DocumentCache&, SmileyPack&); + IMessageDispatcher& messageDispatcher_, DocumentCache&, SmileyPack&, + CameraSource&); ~ChatForm() override; void setStatusMessage(const QString& newMessage); @@ -141,4 +142,5 @@ private: bool isTyping; bool lastCallIsVideo; std::unique_ptr netcam; + CameraSource& cameraSource; }; diff --git a/src/widget/form/settingswidget.cpp b/src/widget/form/settingswidget.cpp index 78f299daf..66ea14a6f 100644 --- a/src/widget/form/settingswidget.cpp +++ b/src/widget/form/settingswidget.cpp @@ -42,13 +42,12 @@ #include SettingsWidget::SettingsWidget(UpdateCheck* updateCheck, IAudioControl& audio, - Core* core, SmileyPack& smileyPack, Widget* parent) + Core* core, SmileyPack& smileyPack, CameraSource& cameraSource, Widget* parent) : QWidget(parent, Qt::Window) { CoreAV* coreAV = core->getAv(); IAudioSettings* audioSettings = &Settings::getInstance(); IVideoSettings* videoSettings = &Settings::getInstance(); - CameraSource& camera = CameraSource::getInstance(); setAttribute(Qt::WA_DeleteOnClose); @@ -65,7 +64,7 @@ SettingsWidget::SettingsWidget(UpdateCheck* updateCheck, IAudioControl& audio, std::unique_ptr pfrm(new PrivacyForm(core)); connect(pfrm.get(), &PrivacyForm::clearAllReceipts, parent, &Widget::clearAllReceipts); - AVForm* rawAvfrm = new AVForm(audio, coreAV, camera, audioSettings, videoSettings); + AVForm* rawAvfrm = new AVForm(audio, coreAV, cameraSource, audioSettings, videoSettings); std::unique_ptr avfrm(rawAvfrm); std::unique_ptr expfrm(new AdvancedForm()); std::unique_ptr abtfrm(new AboutForm(updateCheck)); diff --git a/src/widget/form/settingswidget.h b/src/widget/form/settingswidget.h index 3400f9f9a..66cbe1cb1 100644 --- a/src/widget/form/settingswidget.h +++ b/src/widget/form/settingswidget.h @@ -39,12 +39,13 @@ class ContentLayout; class UpdateCheck; class Widget; class SmileyPack; +class CameraSource; class SettingsWidget : public QWidget { Q_OBJECT public: - SettingsWidget(UpdateCheck* updateCheck, IAudioControl& audio, Core *core, SmileyPack&, Widget* parent = nullptr); + SettingsWidget(UpdateCheck* updateCheck, IAudioControl& audio, Core *core, SmileyPack&, CameraSource&, Widget* parent = nullptr); ~SettingsWidget(); bool isShown() const; diff --git a/src/widget/widget.cpp b/src/widget/widget.cpp index a842161e9..1d909a19d 100644 --- a/src/widget/widget.cpp +++ b/src/widget/widget.cpp @@ -139,7 +139,8 @@ void Widget::acceptFileTransfer(const ToxFile& file, const QString& path) Widget* Widget::instance{nullptr}; -Widget::Widget(Profile &profile_, IAudioControl& audio_, QWidget* parent) +Widget::Widget(Profile &profile_, IAudioControl& audio_, CameraSource& cameraSource_, + QWidget* parent) : QMainWindow(parent) , profile{profile_} , trayMenu{nullptr} @@ -151,6 +152,7 @@ Widget::Widget(Profile &profile_, IAudioControl& audio_, QWidget* parent) , settings(Settings::getInstance()) , smileyPack(new SmileyPack()) , documentCache(new DocumentCache(*smileyPack)) + , cameraSource{cameraSource_} { installEventFilter(this); QString locale = settings.getTranslation(); @@ -292,7 +294,8 @@ void Widget::init() updateCheck = std::unique_ptr(new UpdateCheck(settings)); connect(updateCheck.get(), &UpdateCheck::updateAvailable, this, &Widget::onUpdateAvailable); #endif - settingsWidget = new SettingsWidget(updateCheck.get(), audio, core, *smileyPack, this); + settingsWidget = new SettingsWidget(updateCheck.get(), audio, core, *smileyPack, + cameraSource, this); #if UPDATE_CHECK_ENABLED updateCheck->checkForUpdate(); #endif @@ -1190,7 +1193,7 @@ void Widget::addFriend(uint32_t friendId, const ToxPk& friendPk) std::make_shared(*newfriend, history, *core, settings, *friendMessageDispatcher); auto friendForm = new ChatForm(profile, newfriend, *chatHistory, - *friendMessageDispatcher, *documentCache, *smileyPack); + *friendMessageDispatcher, *documentCache, *smileyPack, cameraSource); connect(friendForm, &ChatForm::updateFriendActivity, this, &Widget::updateFriendActivity); friendMessageDispatchers[friendPk] = friendMessageDispatcher; diff --git a/src/widget/widget.h b/src/widget/widget.h index 131502b82..7ced61b71 100644 --- a/src/widget/widget.h +++ b/src/widget/widget.h @@ -84,6 +84,7 @@ class Settings; class IChatLog; class ChatHistory; class SmileyPack; +class CameraSource; class Widget final : public QMainWindow { Q_OBJECT @@ -117,7 +118,8 @@ private: }; public: - explicit Widget(Profile& profile_, IAudioControl& audio_, QWidget* parent = nullptr); + Widget(Profile& profile_, IAudioControl& audio_, CameraSource&, + QWidget* parent = nullptr); ~Widget() override; void init(); void setCentralWidget(QWidget* widget, const QString& widgetName); @@ -383,6 +385,7 @@ private: #endif std::unique_ptr smileyPack; std::unique_ptr documentCache; + CameraSource& cameraSource; }; bool toxActivateEventHandler(const QByteArray& data);