#pragma once #include #include #include #include "LocalSendCore/DiscoveryManager.h" #include "LocalSendCore/HttpServer.h" #include "LocalSendCore/HttpClient.h" #include "LocalSendCore/SessionManager.h" #include "LocalSendCore/SecurityContext.h" #include "LocalSendCore/Settings.h" class AppController : public QObject { Q_OBJECT Q_PROPERTY(QString alias READ alias WRITE setAlias NOTIFY aliasChanged) Q_PROPERTY(quint16 port READ port WRITE setPort NOTIFY portChanged) Q_PROPERTY(QVariantList devices READ devices NOTIFY devicesChanged) Q_PROPERTY(bool serverRunning READ serverRunning NOTIFY serverRunningChanged) Q_PROPERTY(QString downloadPath READ downloadPath WRITE setDownloadPath NOTIFY downloadPathChanged) Q_PROPERTY(bool quickSave READ quickSave WRITE setQuickSave NOTIFY quickSaveChanged) Q_PROPERTY(bool autoFinish READ autoFinish WRITE setAutoFinish NOTIFY autoFinishChanged) Q_PROPERTY(bool sending READ sending NOTIFY sendingChanged) Q_PROPERTY(double sendProgress READ sendProgress NOTIFY sendProgressChanged) Q_PROPERTY(QString currentSendFileName READ currentSendFileName NOTIFY sendProgressChanged) Q_PROPERTY(int currentSendFileIndex READ currentSendFileIndex NOTIFY sendProgressChanged) Q_PROPERTY(int totalSendFiles READ totalSendFiles NOTIFY sendingChanged) Q_PROPERTY(QVariantList pendingFiles READ pendingFiles NOTIFY pendingFilesChanged) Q_PROPERTY(bool hasPendingFiles READ hasPendingFiles NOTIFY pendingFilesChanged) Q_PROPERTY(QString receivePin READ receivePin WRITE setReceivePin NOTIFY receivePinChanged) Q_PROPERTY(bool receiving READ receiving NOTIFY receivingChanged) Q_PROPERTY(double receiveProgress READ receiveProgress NOTIFY receiveProgressChanged) Q_PROPERTY(QString currentReceiveFileName READ currentReceiveFileName NOTIFY receiveProgressChanged) Q_PROPERTY(int currentReceiveFileIndex READ currentReceiveFileIndex NOTIFY receiveProgressChanged) Q_PROPERTY(int totalReceiveFiles READ totalReceiveFiles NOTIFY receivingChanged) Q_PROPERTY(QString currentReceiveSenderAlias READ currentReceiveSenderAlias NOTIFY receivingChanged) Q_PROPERTY(QString deviceType READ deviceType WRITE setDeviceType NOTIFY deviceTypeChanged) Q_PROPERTY(bool https READ https WRITE setHttps NOTIFY httpsChanged) public: explicit AppController(QObject* parent = nullptr); ~AppController() override; void initialize(); QString alias() const; void setAlias(const QString& alias); quint16 port() const; void setPort(quint16 port); QString downloadPath() const; void setDownloadPath(const QString& path); bool quickSave() const; void setQuickSave(bool enabled); bool autoFinish() const; void setAutoFinish(bool enabled); QVariantList devices() const; bool serverRunning() const; bool sending() const; double sendProgress() const; QString currentSendFileName() const; int currentSendFileIndex() const; int totalSendFiles() const; QVariantList pendingFiles() const; bool hasPendingFiles() const; QString receivePin() const; void setReceivePin(const QString& pin); bool receiving() const; double receiveProgress() const; QString currentReceiveFileName() const; int currentReceiveFileIndex() const; int totalReceiveFiles() const; QString currentReceiveSenderAlias() const; QString deviceType() const; void setDeviceType(const QString& type); bool https() const; void setHttps(bool enabled); Q_INVOKABLE void startDiscovery(); Q_INVOKABLE void stopDiscovery(); Q_INVOKABLE void refreshDevices(); Q_INVOKABLE void acceptReceive(const QString& sessionId); Q_INVOKABLE void declineReceive(const QString& sessionId); Q_INVOKABLE void cancelReceive(); Q_INVOKABLE void sendFiles(const QString& deviceFingerprint, const QStringList& filePaths); Q_INVOKABLE void sendTo(const QString& deviceFingerprint); Q_INVOKABLE void sendToAddress(const QString& address); Q_INVOKABLE void cancelSend(); Q_INVOKABLE void addFiles(const QStringList& filePaths); Q_INVOKABLE void removePendingFile(int index); Q_INVOKABLE void clearPendingFiles(); Q_INVOKABLE void retryWithPin(const QString& pin); Q_INVOKABLE void copyToClipboard(const QString& text); Q_INVOKABLE void openLink(const QString& url); signals: void aliasChanged(); void portChanged(); void downloadPathChanged(); void quickSaveChanged(); void devicesChanged(); void serverRunningChanged(); void autoFinishChanged(); void sendingChanged(); void sendProgressChanged(); void pendingFilesChanged(); void receiveRequest(const QString& sessionId, const QString& senderAlias, const QString& senderIp, const QVariantList& files, const QString& message); void receiveProgress(const QString& sessionId, const QString& fileId, double progress); void receiveCompleted(const QString& sessionId); void receiveError(const QString& sessionId, const QString& error); void sendCompleted(const QString& sessionId); void sendError(const QString& error); void sendCanceled(); void pinRequired(bool firstAttempt); void receivePinChanged(); void receivingChanged(); void receiveProgressChanged(); void deviceTypeChanged(); void httpsChanged(); private slots: void onDeviceDiscovered(const LocalSend::Device& device); void onDeviceLost(const QString& fingerprint); void onRegisterRequest(const LocalSend::RegisterDto& dto, const QHostAddress& sender); void onPrepareUploadRequest(const QString& httpSessionId, const LocalSend::PrepareUploadRequestDto& dto, const QHostAddress& sender); void onUploadRequest(const QString& sessionId, const QString& fileId, const QString& token, const QByteArray& data); void onSessionAccepted(const QString& sessionId, const QMap& tokens); void onSessionDeclined(const QString& sessionId); void onReceiveProgress(const QString& sessionId, const QString& fileId, double progress); void onReceiveCompleted(const QString& sessionId); void onPrepareUploadResponse(const LocalSend::PrepareUploadResponseDto& response); void onPrepareUploadError(const QString& error); void onPrepareUploadPinRequired(); void onPrepareUploadTooManyAttempts(); void onUploadProgress(qint64 sent, qint64 total); void onUploadCompleted(); void onUploadError(const QString& error); void onManualRegisterCompleted(const LocalSend::InfoDto& peerInfo); void onManualRegisterError(const QString& error); void onCancelRequest(const QString& sessionId); private: LocalSend::Settings* m_settings = nullptr; LocalSend::SecurityContext* m_security = nullptr; LocalSend::DiscoveryManager* m_discovery = nullptr; LocalSend::HttpServer* m_server = nullptr; LocalSend::SessionManager* m_sessions = nullptr; LocalSend::HttpClient* m_httpClient = nullptr; QMap m_devices; QString m_currentSendSessionId; QString m_currentSendFileId; QString m_currentSendDeviceFingerprint; QStringList m_pendingSendPaths; QVariantList m_pendingFilesList; int m_currentFileIndex = 0; double m_sendProgress = 0.0; bool m_pinFirstAttempt = true; QString m_currentReceiveSessionId; double m_receiveProgressValue = 0.0; QString m_currentReceiveFileName; int m_currentReceiveFileIndex = 0; int m_totalReceiveFiles = 0; qint64 m_totalReceiveSize = 0; qint64 m_receivedSize = 0; QString m_currentReceiveSenderAlias; QMap m_receiveFileNames; LocalSend::InfoDto buildInfoDto() const; QString generateUniqueFilePath(const QString& baseDir, const QString& fileName) const; void sendNextFile(); LocalSend::RegisterDto buildRegisterDto() const; void resetSendState(); void resetReceiveState(); bool m_manualSendPending = false; LocalSend::Device m_manualSendDevice; };