diff --git a/.clang-format b/.clang-format index 40c750ac..5bbb13aa 100644 --- a/.clang-format +++ b/.clang-format @@ -1,193 +1,195 @@ --- +# Typical usage is to apply this to the lines you've modified in a local +# change. Stage your changes with "git add" and then run: +# $ git clang-format +# You can optionally use the "--" file filter to restrict formatting to certain +# files or directories. The tool will display the list of files that were +# modified. These have been modified without being staged. You can review the +# modifications using "git diff". +# +# IF YOU UPDATE THE CPP SECTION ALSO UPDATE THE OBJECTIVE-C SECTION. IF YOU +# KNOW HOW TO SHARE SETTINGS BETWEEN THE TWO YOU'RE A TRUE HERO. + Language: Cpp -# BasedOnStyle: LLVM -AccessModifierOffset: -2 +# BasedOnStyle: Google +AccessModifierOffset: -4 AlignAfterOpenBracket: Align -AlignArrayOfStructures: None -AlignConsecutiveMacros: None -AlignConsecutiveAssignments: None -AlignConsecutiveBitFields: None -AlignConsecutiveDeclarations: None -AlignEscapedNewlines: Right -AlignOperands: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlinesLeft: true +AlignOperands: true AlignTrailingComments: true -AllowAllArgumentsOnNextLine: true AllowAllParametersOfDeclarationOnNextLine: true -AllowShortEnumsOnASingleLine: true -AllowShortBlocksOnASingleLine: Never +AllowShortBlocksOnASingleLine: false AllowShortCaseLabelsOnASingleLine: false AllowShortFunctionsOnASingleLine: All -AllowShortLambdasOnASingleLine: All -AllowShortIfStatementsOnASingleLine: Never -AllowShortLoopsOnASingleLine: false +AllowShortIfStatementsOnASingleLine: true +AllowShortLoopsOnASingleLine: true AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakAfterReturnType: None -AlwaysBreakBeforeMultilineStrings: false -AlwaysBreakTemplateDeclarations: MultiLine -AttributeMacros: - - __capability +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: false BinPackArguments: true BinPackParameters: true BraceWrapping: - AfterCaseLabel: false AfterClass: false - AfterControlStatement: Never + AfterControlStatement: false AfterEnum: false AfterFunction: false AfterNamespace: false AfterObjCDeclaration: false AfterStruct: false AfterUnion: false - AfterExternBlock: false BeforeCatch: false BeforeElse: false - BeforeLambdaBody: false - BeforeWhile: false IndentBraces: false - SplitEmptyFunction: true - SplitEmptyRecord: true - SplitEmptyNamespace: true BreakBeforeBinaryOperators: None -BreakBeforeConceptDeclarations: true -BreakBeforeBraces: Attach -BreakBeforeInheritanceComma: false -BreakInheritanceList: BeforeColon +BreakBeforeBraces: Custom BreakBeforeTernaryOperators: true -BreakConstructorInitializersBeforeComma: false -BreakConstructorInitializers: BeforeColon +BreakConstructorInitializersBeforeComma: true BreakAfterJavaFieldAnnotations: false BreakStringLiterals: true -ColumnLimit: 180 +ColumnLimit: 100 CommentPragmas: '^ IWYU pragma:' -QualifierAlignment: Leave -CompactNamespaces: false -ConstructorInitializerIndentWidth: 4 -ContinuationIndentWidth: 4 +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 8 +ContinuationIndentWidth: 8 Cpp11BracedListStyle: true -DeriveLineEnding: true DerivePointerAlignment: false DisableFormat: false -EmptyLineAfterAccessModifier: Never -EmptyLineBeforeAccessModifier: LogicalBlock -ExperimentalAutoDetectBinPacking: false -PackConstructorInitializers: BinPack -BasedOnStyle: '' -ConstructorInitializerAllOnOneLineOrOnePerLine: false -AllowAllConstructorInitializersOnNextLine: true -FixNamespaceComments: true -ForEachMacros: - - foreach - - Q_FOREACH - - BOOST_FOREACH -IfMacros: - - KJ_IF_MAYBE -IncludeBlocks: Preserve +ExperimentalAutoDetectBinPacking: true +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] IncludeCategories: - - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + - Regex: '^<.*\.h>' + Priority: 1 + - Regex: '^<.*' Priority: 2 - SortPriority: 0 - CaseSensitive: false - - Regex: '^(<|"(gtest|gmock|isl|json)/)' - Priority: 3 - SortPriority: 0 - CaseSensitive: false - Regex: '.*' + Priority: 3 +IncludeIsMainRegex: '([-_](test|unittest))?$' +IndentCaseLabels: true +IndentWidth: 4 +IndentWrappedFunctionNames: false +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: false +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Left +ReflowComments: true +SortIncludes: true +SpaceAfterCStyleCast: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Auto +TabWidth: 4 +UseTab: Never +--- +Language: ObjC +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlinesLeft: true +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: true +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: false +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Custom +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: true +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 100 +CommentPragmas: '^ IWYU pragma:' +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 8 +ContinuationIndentWidth: 8 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: true +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] +IncludeCategories: + - Regex: '^<.*\.h>' Priority: 1 - SortPriority: 0 - CaseSensitive: false -IncludeIsMainRegex: '(Test)?$' -IncludeIsMainSourceRegex: '' -IndentAccessModifiers: false -IndentCaseLabels: false -IndentCaseBlocks: false -IndentGotoLabels: true -IndentPPDirectives: None -IndentExternBlock: AfterExternBlock -IndentRequires: false -IndentWidth: 2 -TabWidth: 2 + - Regex: '^<.*' + Priority: 2 + - Regex: '.*' + Priority: 3 +IncludeIsMainRegex: '([-_](test|unittest))?$' +IndentCaseLabels: true +IndentWidth: 4 IndentWrappedFunctionNames: false -InsertTrailingCommas: None JavaScriptQuotes: Leave JavaScriptWrapImports: true -KeepEmptyLinesAtTheStartOfBlocks: true -LambdaBodyIndentation: Signature -MacroBlockBegin: '' -MacroBlockEnd: '' +KeepEmptyLinesAtTheStartOfBlocks: false MaxEmptyLinesToKeep: 1 NamespaceIndentation: None -ObjCBinPackProtocolList: Auto ObjCBlockIndentWidth: 2 -ObjCBreakBeforeNestedBlockParam: true ObjCSpaceAfterProperty: false -ObjCSpaceBeforeProtocolList: true -PenaltyBreakAssignment: 2 -PenaltyBreakBeforeFirstCallParameter: 19 +ObjCSpaceBeforeProtocolList: false +PenaltyBreakBeforeFirstCallParameter: 1 PenaltyBreakComment: 300 PenaltyBreakFirstLessLess: 120 -PenaltyBreakOpenParenthesis: 0 PenaltyBreakString: 1000 -PenaltyBreakTemplateDeclaration: 10 PenaltyExcessCharacter: 1000000 -PenaltyReturnTypeOnItsOwnLine: 60 -PenaltyIndentedWhitespace: 0 -PointerAlignment: Right -PPIndentWidth: -1 -ReferenceAlignment: Pointer +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Left ReflowComments: true -RemoveBracesLLVM: false -SeparateDefinitionBlocks: Leave -ShortNamespaceLines: 1 -SortIncludes: CaseSensitive -SortJavaStaticImport: Before -SortUsingDeclarations: true +SortIncludes: true SpaceAfterCStyleCast: false -SpaceAfterLogicalNot: false SpaceAfterTemplateKeyword: true SpaceBeforeAssignmentOperators: true -SpaceBeforeCaseColon: false -SpaceBeforeCpp11BracedList: false -SpaceBeforeCtorInitializerColon: true -SpaceBeforeInheritanceColon: true SpaceBeforeParens: ControlStatements -SpaceBeforeParensOptions: - AfterControlStatements: true - AfterForeachMacros: true - AfterFunctionDefinitionName: false - AfterFunctionDeclarationName: false - AfterIfMacros: true - AfterOverloadedOperator: false - BeforeNonEmptyParentheses: false -SpaceAroundPointerQualifiers: Default -SpaceBeforeRangeBasedForLoopColon: true -SpaceInEmptyBlock: false SpaceInEmptyParentheses: false -SpacesBeforeTrailingComments: 1 -SpacesInAngles: Never -SpacesInConditionalStatement: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: false SpacesInContainerLiterals: true SpacesInCStyleCastParentheses: false -SpacesInLineCommentPrefix: - Minimum: 1 - Maximum: -1 SpacesInParentheses: false SpacesInSquareBrackets: false -SpaceBeforeSquareBrackets: false -BitFieldColonSpacing: Both -Standard: Latest -StatementAttributeLikeMacros: - - Q_EMIT -StatementMacros: - - Q_UNUSED - - QT_REQUIRE_VERSION - -UseCRLF: false +Standard: Auto +TabWidth: 4 UseTab: Never -WhitespaceSensitiveMacros: - - STRINGIZE - - PP_STRINGIZE - - BOOST_PP_STRINGIZE - - NS_SWIFT_NAME - - CF_SWIFT_NAME ... - diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml new file mode 100644 index 00000000..63bfffde --- /dev/null +++ b/.github/workflows/clang-format.yml @@ -0,0 +1,26 @@ +name: Clang Format Diff + +on: [ push, pull_request ] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: install clang-format + run : sudo apt install clang-format + + - name: check-diff + run : | + diff=`git-clang-format --diff HEAD^` + if ! [[ "$diff" = "no modified files to format" || "$diff" = "clang-format did not modify any files" ]]; then + echo "The diff you sent is not formatted correctly." + echo "The suggested format is" + echo "$diff" + exit 1 + fi \ No newline at end of file diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 190ef8e3..af617970 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -44,12 +44,14 @@ parts: - build-essential - qtbase5-dev - qtmultimedia5-dev - - libqt5svg5-dev + - qttools5-dev + - qttools5-dev-tools + - qtwebengine5-dev + - qtwebengine5-dev-tools - libqt5xml5 + - libqt5svg5-dev - libqt5xmlpatterns5-dev - libqt5opengl5-dev - - qttools5-dev - - qttools5-dev-tools - libqt5x11extras5-dev stage-packages: - libxkbcommon0 diff --git a/src/Bus.cpp b/src/Bus.cpp index 5c2268c6..07e8391e 100644 --- a/src/Bus.cpp +++ b/src/Bus.cpp @@ -16,13 +16,9 @@ #include "Bus.h" -namespace ok{ -Bus::Bus(QObject *parent): QObject(parent) { +namespace ok { +Bus::Bus(QObject* parent) : QObject(parent) {} -} +Bus::~Bus() {} -Bus::~Bus(){ - -} - -} \ No newline at end of file +} // namespace ok \ No newline at end of file diff --git a/src/Bus.h b/src/Bus.h index 26bad99b..e05c2e0c 100644 --- a/src/Bus.h +++ b/src/Bus.h @@ -18,18 +18,22 @@ #include +class Module; +class Core; namespace ok { /** * 全局系统总线,负责多模块直接交互事件 */ class Bus : public QObject { - Q_OBJECT + Q_OBJECT public: - Bus(QObject *parent = nullptr); - ~Bus(); + Bus(QObject* parent = nullptr); + ~Bus(); signals: - void languageChanged(QString locale); + void languageChanged(QString locale); + void moduleCreated(Module* module); + void coreChanged(Core* core); }; -} // namespace ok +} // namespace ok diff --git a/src/UI/core/ControllerManager.cpp b/src/UI/core/ControllerManager.cpp index 52770709..bb742094 100644 --- a/src/UI/core/ControllerManager.cpp +++ b/src/UI/core/ControllerManager.cpp @@ -15,12 +15,7 @@ namespace ok { +ControllerManager::ControllerManager(QObject* parent) : QObject(parent) {} - ControllerManager::ControllerManager(QObject *parent) : QObject(parent) - { - } - - ControllerManager::~ControllerManager() - { - } -} +ControllerManager::~ControllerManager() {} +} // namespace ok diff --git a/src/UI/core/ControllerManager.h b/src/UI/core/ControllerManager.h index 388bc93d..e186bc22 100644 --- a/src/UI/core/ControllerManager.h +++ b/src/UI/core/ControllerManager.h @@ -15,19 +15,16 @@ // #include - - namespace ok { // using namespace painter; -class ControllerManager : public QObject -{ +class ControllerManager : public QObject { Q_OBJECT public: - ControllerManager(QObject *parent); + ControllerManager(QObject* parent); ~ControllerManager(); }; -} +} // namespace ok diff --git a/src/UI/core/FontManager.cpp b/src/UI/core/FontManager.cpp index 3ddb4d64..ab999a61 100644 --- a/src/UI/core/FontManager.cpp +++ b/src/UI/core/FontManager.cpp @@ -12,19 +12,19 @@ #include "FontManager.h" #include -FontManager::FontManager(QObject *parent) : QObject(parent) {} +FontManager::FontManager(QObject* parent) : QObject(parent) {} FontManager::~FontManager() {} void FontManager::loadFonts() { - // QFontDatabase::addApplicationFont(":/font/resources/fonts/PingFang/PingFang_SC_Regular.ttf"); - // QFontDatabase::addApplicationFont(":/font/resources/fonts/PingFang/PingFang_SC_Light.ttf"); - /*QFontDatabase::addApplicationFont(":/font/resources/fonts/PingFang/PingFang_SC_Medium.ttf"); - QFontDatabase::addApplicationFont(":/font/resources/fonts/PingFang/PingFang_SC_Thin.ttf"); - QFontDatabase::addApplicationFont(":/font/resources/fonts/PingFang/PingFang_SC_Semibold.ttf"); - QFontDatabase::addApplicationFont(":/font/resources/fonts/PingFang/PingFang_SC_UltraLight.ttf");*/ + // QFontDatabase::addApplicationFont(":/font/resources/fonts/PingFang/PingFang_SC_Regular.ttf"); + // QFontDatabase::addApplicationFont(":/font/resources/fonts/PingFang/PingFang_SC_Light.ttf"); + /*QFontDatabase::addApplicationFont(":/font/resources/fonts/PingFang/PingFang_SC_Medium.ttf"); + QFontDatabase::addApplicationFont(":/font/resources/fonts/PingFang/PingFang_SC_Thin.ttf"); + QFontDatabase::addApplicationFont(":/font/resources/fonts/PingFang/PingFang_SC_Semibold.ttf"); + QFontDatabase::addApplicationFont(":/font/resources/fonts/PingFang/PingFang_SC_UltraLight.ttf");*/ - // QFont f("Microsoft Yahei", 10, QFont::Normal); - // - // qApp->setFont(f); + // QFont f("Microsoft Yahei", 10, QFont::Normal); + // + // qApp->setFont(f); } diff --git a/src/UI/core/FontManager.h b/src/UI/core/FontManager.h index 4a6f1c3d..cfb0ea29 100644 --- a/src/UI/core/FontManager.h +++ b/src/UI/core/FontManager.h @@ -16,11 +16,11 @@ #include class FontManager : public QObject { - Q_OBJECT + Q_OBJECT public: - FontManager(QObject *parent = nullptr); - ~FontManager(); + FontManager(QObject* parent = nullptr); + ~FontManager(); - void loadFonts(); + void loadFonts(); }; diff --git a/src/UI/core/I18N.cpp b/src/UI/core/I18N.cpp index 6aa1f720..2ea7b1e6 100644 --- a/src/UI/core/I18N.cpp +++ b/src/UI/core/I18N.cpp @@ -12,56 +12,52 @@ #include "I18N.h" #include +#include #include -#include #include -#include +#include #include -namespace core -{ - - const QString APPLICATION_ENCODING = "UTF-8"; - const QString TRANSLATIONS_PATH = "translations"; +namespace core { - I18N::I18N(const QString &path, const QString &encoding) - { - m_path = path; - m_encoding = encoding; - } +const QString APPLICATION_ENCODING = "UTF-8"; +const QString TRANSLATIONS_PATH = "translations"; - void I18N::Init() - { - - I18N *i18n = new I18N(TRANSLATIONS_PATH, APPLICATION_ENCODING); - i18n->translate(); +I18N::I18N(const QString& path, const QString& encoding) { + m_path = path; + m_encoding = encoding; +} - self = i18n; - } +void I18N::Init() { + I18N* i18n = new I18N(TRANSLATIONS_PATH, APPLICATION_ENCODING); + i18n->translate(); - QString I18N::getEncoding() const { return m_encoding; } + self = i18n; +} - void I18N::setEncoding(const QString &encoding) { m_encoding = encoding; } +QString I18N::getEncoding() const { return m_encoding; } - QString I18N::getPath() const { return m_path; } +void I18N::setEncoding(const QString& encoding) { m_encoding = encoding; } - void I18N::setPath(const QString &path) { m_path = path; } +QString I18N::getPath() const { return m_path; } - void I18N::translate() - { - QLocale::setDefault(QLocale::Chinese); +void I18N::setPath(const QString& path) { m_path = path; } - QTranslator m_apTranslator, m_qtTranslator; - m_qtTranslator.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath)); - qApp->installTranslator(&m_qtTranslator); +void I18N::translate() { + QLocale::setDefault(QLocale::Chinese); - QString classroomQM(":/" + m_path + "/classroom_zh.qm"); + QTranslator m_apTranslator, m_qtTranslator; + m_qtTranslator.load("qt_" + QLocale::system().name(), + QLibraryInfo::location(QLibraryInfo::TranslationsPath)); + qApp->installTranslator(&m_qtTranslator); - qDebug() << "load qm file:" << classroomQM; + QString classroomQM(":/" + m_path + "/classroom_zh.qm"); - m_apTranslator.load(classroomQM); - qApp->installTranslator(&m_apTranslator); - } + qDebug() << "load qm file:" << classroomQM; + m_apTranslator.load(classroomQM); + qApp->installTranslator(&m_apTranslator); } + +} // namespace core diff --git a/src/UI/core/I18N.h b/src/UI/core/I18N.h index 7a2be011..6d8d002e 100644 --- a/src/UI/core/I18N.h +++ b/src/UI/core/I18N.h @@ -13,35 +13,31 @@ #ifndef I18N_H #define I18N_H - #include - namespace core { class I18N; -static I18N *self = nullptr; +static I18N* self = nullptr; -class I18N -{ +class I18N { public: - I18N(const QString & path, const QString & encoding); + I18N(const QString& path, const QString& encoding); static void Init(); QString getPath() const; - void setPath(const QString & path); + void setPath(const QString& path); QString getEncoding() const; - void setEncoding(const QString & encoding); + void setEncoding(const QString& encoding); - void translate( ); + void translate(); private: QString m_path, m_encoding; - }; -} +} // namespace core -#endif // I18N_H +#endif // I18N_H diff --git a/src/UI/core/SettingManager.cpp b/src/UI/core/SettingManager.cpp index 4b8b5723..0d7b7def 100644 --- a/src/UI/core/SettingManager.cpp +++ b/src/UI/core/SettingManager.cpp @@ -20,33 +20,28 @@ namespace ok { -SettingManager::SettingManager(QObject *parent) : QObject(parent), - settings{std::make_unique(ORGANIZATION_NAME, ORGANIZATION_DOMAIN)} -{ - qDebug() << __func__; -} - -SettingManager::~SettingManager() { - qDebug() << __func__; +SettingManager::SettingManager(QObject* parent) + : QObject(parent) + , settings{std::make_unique(ORGANIZATION_NAME, ORGANIZATION_DOMAIN)} { + qDebug() << __func__; } +SettingManager::~SettingManager() { qDebug() << __func__; } -void SettingManager::saveAccount(QString &account, QString &password) { - settings->setValue(LOGIN_ACCOUNT_KEY, QVariant(account)); - settings->setValue(LOGIN_PASSWORD_KEY, QVariant(password)); +void SettingManager::saveAccount(QString& account, QString& password) { + settings->setValue(LOGIN_ACCOUNT_KEY, QVariant(account)); + settings->setValue(LOGIN_PASSWORD_KEY, QVariant(password)); } -void SettingManager::getAccount( - Fn callback) { - - QString a = settings->value(LOGIN_ACCOUNT_KEY, QVariant("")).toString(); - QString p = settings->value(LOGIN_PASSWORD_KEY, QVariant("")).toString(); +void SettingManager::getAccount(Fn callback) { + QString a = settings->value(LOGIN_ACCOUNT_KEY, QVariant("")).toString(); + QString p = settings->value(LOGIN_PASSWORD_KEY, QVariant("")).toString(); - callback(a, p); + callback(a, p); } void SettingManager::clearAccount() { - settings->setValue(LOGIN_ACCOUNT_KEY, QVariant("")); - settings->setValue(LOGIN_PASSWORD_KEY, QVariant("")); + settings->setValue(LOGIN_ACCOUNT_KEY, QVariant("")); + settings->setValue(LOGIN_PASSWORD_KEY, QVariant("")); } -} // namespace core +} // namespace ok diff --git a/src/UI/core/SettingManager.h b/src/UI/core/SettingManager.h index 1bcf29ad..f3937f6c 100644 --- a/src/UI/core/SettingManager.h +++ b/src/UI/core/SettingManager.h @@ -16,23 +16,22 @@ #include #include - #include namespace ok { class SettingManager : public QObject { - Q_OBJECT + Q_OBJECT public: - SettingManager(QObject *parent = nullptr); - ~SettingManager(); + SettingManager(QObject* parent = nullptr); + ~SettingManager(); - void saveAccount(QString &account, QString &password); - void getAccount(Fn callback); - void clearAccount(); + void saveAccount(QString& account, QString& password); + void getAccount(Fn callback); + void clearAccount(); private: - std::unique_ptr settings; + std::unique_ptr settings; }; -} // namespace core +} // namespace ok diff --git a/src/UI/core/ui.h b/src/UI/core/ui.h index f30f7021..3a1df810 100644 --- a/src/UI/core/ui.h +++ b/src/UI/core/ui.h @@ -14,8 +14,5 @@ #include -namespace UI -{ - -} -#endif // UI_H +namespace UI {} +#endif // UI_H diff --git a/src/UI/layout/FlowLayout.cpp b/src/UI/layout/FlowLayout.cpp index fcd47572..bd3bd55e 100644 --- a/src/UI/layout/FlowLayout.cpp +++ b/src/UI/layout/FlowLayout.cpp @@ -12,157 +12,123 @@ #include "FlowLayout.h" #include -#include #include #include #include +#include #include -FlowLayout::FlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing) - : QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing) -{ - setContentsMargins(margin, margin, margin, margin); +FlowLayout::FlowLayout(QWidget* parent, int margin, int hSpacing, int vSpacing) + : QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing) { + setContentsMargins(margin, margin, margin, margin); } FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing) - : m_hSpace(hSpacing), m_vSpace(vSpacing) -{ - setContentsMargins(margin, margin, margin, margin); + : m_hSpace(hSpacing), m_vSpace(vSpacing) { + setContentsMargins(margin, margin, margin, margin); } -FlowLayout::~FlowLayout() -{ - QLayoutItem *item; - while ((item = takeAt(0))) - delete item; +FlowLayout::~FlowLayout() { + QLayoutItem* item; + while ((item = takeAt(0))) delete item; } -void FlowLayout::addItem(QLayoutItem *item) -{ - itemList.append(item); -} +void FlowLayout::addItem(QLayoutItem* item) { itemList.append(item); } -int FlowLayout::horizontalSpacing() const -{ - if (m_hSpace >= 0) { - return m_hSpace; - } - else { - return smartSpacing(QStyle::PM_LayoutHorizontalSpacing); - } +int FlowLayout::horizontalSpacing() const { + if (m_hSpace >= 0) { + return m_hSpace; + } else { + return smartSpacing(QStyle::PM_LayoutHorizontalSpacing); + } } -int FlowLayout::verticalSpacing() const -{ - if (m_vSpace >= 0) { - return m_vSpace; - } - else { - return smartSpacing(QStyle::PM_LayoutVerticalSpacing); - } +int FlowLayout::verticalSpacing() const { + if (m_vSpace >= 0) { + return m_vSpace; + } else { + return smartSpacing(QStyle::PM_LayoutVerticalSpacing); + } } -int FlowLayout::count() const -{ - return itemList.size(); -} +int FlowLayout::count() const { return itemList.size(); } -QLayoutItem *FlowLayout::itemAt(int index) const -{ - return itemList.value(index); -} +QLayoutItem* FlowLayout::itemAt(int index) const { return itemList.value(index); } -QLayoutItem *FlowLayout::takeAt(int index) -{ - if (index >= 0 && index < itemList.size()) - return itemList.takeAt(index); - else - return 0; +QLayoutItem* FlowLayout::takeAt(int index) { + if (index >= 0 && index < itemList.size()) + return itemList.takeAt(index); + else + return 0; } -Qt::Orientations FlowLayout::expandingDirections() const -{ - return 0; -} +Qt::Orientations FlowLayout::expandingDirections() const { return 0; } -bool FlowLayout::hasHeightForWidth() const -{ - return true; -} +bool FlowLayout::hasHeightForWidth() const { return true; } -int FlowLayout::heightForWidth(int width) const -{ - int height = doLayout(QRect(0, 0, width, 0), true); - return height; +int FlowLayout::heightForWidth(int width) const { + int height = doLayout(QRect(0, 0, width, 0), true); + return height; } -void FlowLayout::setGeometry(const QRect &rect) -{ - QLayout::setGeometry(rect); - doLayout(rect, false); +void FlowLayout::setGeometry(const QRect& rect) { + QLayout::setGeometry(rect); + doLayout(rect, false); } -QSize FlowLayout::sizeHint() const -{ - return minimumSize(); -} +QSize FlowLayout::sizeHint() const { return minimumSize(); } -QSize FlowLayout::minimumSize() const -{ - QSize size; - QLayoutItem *item; - foreach(item, itemList) - size = size.expandedTo(item->minimumSize()); +QSize FlowLayout::minimumSize() const { + QSize size; + QLayoutItem* item; + foreach (item, itemList) size = size.expandedTo(item->minimumSize()); - size += QSize(2 * margin(), 2 * margin()); - return size; + size += QSize(2 * margin(), 2 * margin()); + return size; } -int FlowLayout::doLayout(const QRect &rect, bool testOnly) const -{ - int left, top, right, bottom; - getContentsMargins(&left, &top, &right, &bottom); - QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom); - int x = effectiveRect.x(); - int y = effectiveRect.y(); - int lineHeight = 0; - - QLayoutItem *item; - foreach(item, itemList) { - QWidget *wid = item->widget(); - int spaceX = horizontalSpacing(); - if (spaceX == -1) - spaceX = wid->style()->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal); - int spaceY = verticalSpacing(); - if (spaceY == -1) - spaceY = wid->style()->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical); - int nextX = x + item->sizeHint().width() + spaceX; - if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) { - x = effectiveRect.x(); - y = y + lineHeight + spaceY; - nextX = x + item->sizeHint().width() + spaceX; - lineHeight = 0; - } - - if (!testOnly) - item->setGeometry(QRect(QPoint(x, y), item->sizeHint())); - - x = nextX; - lineHeight = qMax(lineHeight, item->sizeHint().height()); - } - return y + lineHeight - rect.y() + bottom; +int FlowLayout::doLayout(const QRect& rect, bool testOnly) const { + int left, top, right, bottom; + getContentsMargins(&left, &top, &right, &bottom); + QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom); + int x = effectiveRect.x(); + int y = effectiveRect.y(); + int lineHeight = 0; + + QLayoutItem* item; + foreach (item, itemList) { + QWidget* wid = item->widget(); + int spaceX = horizontalSpacing(); + if (spaceX == -1) + spaceX = wid->style()->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, + Qt::Horizontal); + int spaceY = verticalSpacing(); + if (spaceY == -1) + spaceY = wid->style()->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, + Qt::Vertical); + int nextX = x + item->sizeHint().width() + spaceX; + if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) { + x = effectiveRect.x(); + y = y + lineHeight + spaceY; + nextX = x + item->sizeHint().width() + spaceX; + lineHeight = 0; + } + + if (!testOnly) item->setGeometry(QRect(QPoint(x, y), item->sizeHint())); + + x = nextX; + lineHeight = qMax(lineHeight, item->sizeHint().height()); + } + return y + lineHeight - rect.y() + bottom; } -int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const -{ - QObject *parent = this->parent(); - if (!parent) { - return -1; - } - else if (parent->isWidgetType()) { - QWidget *pw = static_cast(parent); - return pw->style()->pixelMetric(pm, 0, pw); - } - else { - return static_cast(parent)->spacing(); - } +int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const { + QObject* parent = this->parent(); + if (!parent) { + return -1; + } else if (parent->isWidgetType()) { + QWidget* pw = static_cast(parent); + return pw->style()->pixelMetric(pm, 0, pw); + } else { + return static_cast(parent)->spacing(); + } } diff --git a/src/UI/layout/FlowLayout.h b/src/UI/layout/FlowLayout.h index 6c4eb442..16b0894b 100644 --- a/src/UI/layout/FlowLayout.h +++ b/src/UI/layout/FlowLayout.h @@ -18,32 +18,30 @@ #include #include - class FlowLayout : public QLayout { public: - explicit FlowLayout(QWidget *parent, int margin = -1, int hSpacing = -1, - int vSpacing = -1); - explicit FlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1); - virtual ~FlowLayout() override; + explicit FlowLayout(QWidget* parent, int margin = -1, int hSpacing = -1, int vSpacing = -1); + explicit FlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1); + virtual ~FlowLayout() override; - void addItem(QLayoutItem *item) override; - int horizontalSpacing() const; - int verticalSpacing() const; - Qt::Orientations expandingDirections() const override; - bool hasHeightForWidth() const override; - int heightForWidth(int) const override; - int count() const override; - QLayoutItem *itemAt(int index) const override; - QSize minimumSize() const override; - void setGeometry(const QRect &rect) override; - QSize sizeHint() const override; - QLayoutItem *takeAt(int index) override; + void addItem(QLayoutItem* item) override; + int horizontalSpacing() const; + int verticalSpacing() const; + Qt::Orientations expandingDirections() const override; + bool hasHeightForWidth() const override; + int heightForWidth(int) const override; + int count() const override; + QLayoutItem* itemAt(int index) const override; + QSize minimumSize() const override; + void setGeometry(const QRect& rect) override; + QSize sizeHint() const override; + QLayoutItem* takeAt(int index) override; private: - int doLayout(const QRect &rect, bool testOnly) const; - int smartSpacing(QStyle::PixelMetric pm) const; + int doLayout(const QRect& rect, bool testOnly) const; + int smartSpacing(QStyle::PixelMetric pm) const; - QList itemList; - int m_hSpace; - int m_vSpace; + QList itemList; + int m_hSpace; + int m_vSpace; }; diff --git a/src/UI/tool/activatedialog.cpp b/src/UI/tool/activatedialog.cpp index 4e007ae0..70444eca 100644 --- a/src/UI/tool/activatedialog.cpp +++ b/src/UI/tool/activatedialog.cpp @@ -10,17 +10,12 @@ * See the Mulan PubL v2 for more details. */ - #include "activatedialog.h" #include -ActivateDialog::ActivateDialog(QWidget* parent, Qt::WindowFlags f) - : QDialog(parent, f) -{ -} +ActivateDialog::ActivateDialog(QWidget* parent, Qt::WindowFlags f) : QDialog(parent, f) {} -bool ActivateDialog::event(QEvent* event) -{ +bool ActivateDialog::event(QEvent* event) { if (event->type() == QEvent::WindowActivate || event->type() == QEvent::WindowStateChange) emit windowStateChanged(windowState()); diff --git a/src/UI/tool/activatedialog.h b/src/UI/tool/activatedialog.h index ec315516..0c4a6f12 100644 --- a/src/UI/tool/activatedialog.h +++ b/src/UI/tool/activatedialog.h @@ -15,8 +15,7 @@ #include -class ActivateDialog : public QDialog -{ +class ActivateDialog : public QDialog { Q_OBJECT public: #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) @@ -30,4 +29,4 @@ class ActivateDialog : public QDialog void windowStateChanged(Qt::WindowStates state); }; -#endif // ACTIVATEDIALOG_H +#endif // ACTIVATEDIALOG_H diff --git a/src/UI/tool/adjustingscrollarea.cpp b/src/UI/tool/adjustingscrollarea.cpp index 4ac4ba8c..6a26efe2 100644 --- a/src/UI/tool/adjustingscrollarea.cpp +++ b/src/UI/tool/adjustingscrollarea.cpp @@ -17,25 +17,19 @@ #include #include -AdjustingScrollArea::AdjustingScrollArea(QWidget* parent) - : QScrollArea(parent) -{ -} +AdjustingScrollArea::AdjustingScrollArea(QWidget* parent) : QScrollArea(parent) {} -void AdjustingScrollArea::resizeEvent(QResizeEvent* ev) -{ +void AdjustingScrollArea::resizeEvent(QResizeEvent* ev) { int scrollBarWidth = - verticalScrollBar()->isVisible() ? verticalScrollBar()->sizeHint().width() : 0; + verticalScrollBar()->isVisible() ? verticalScrollBar()->sizeHint().width() : 0; - if (layoutDirection() == Qt::RightToLeft) - setViewportMargins(-scrollBarWidth, 0, 0, 0); + if (layoutDirection() == Qt::RightToLeft) setViewportMargins(-scrollBarWidth, 0, 0, 0); updateGeometry(); QScrollArea::resizeEvent(ev); } -QSize AdjustingScrollArea::sizeHint() const -{ +QSize AdjustingScrollArea::sizeHint() const { if (widget()) { int scrollbarWidth = verticalScrollBar()->isVisible() ? verticalScrollBar()->width() : 0; return widget()->sizeHint() + QSize(scrollbarWidth, 0); diff --git a/src/UI/tool/adjustingscrollarea.h b/src/UI/tool/adjustingscrollarea.h index 787edb58..19f5a038 100644 --- a/src/UI/tool/adjustingscrollarea.h +++ b/src/UI/tool/adjustingscrollarea.h @@ -15,8 +15,7 @@ #include -class AdjustingScrollArea : public QScrollArea -{ +class AdjustingScrollArea : public QScrollArea { Q_OBJECT public: explicit AdjustingScrollArea(QWidget* parent = nullptr); @@ -27,4 +26,4 @@ class AdjustingScrollArea : public QScrollArea virtual QSize sizeHint() const final override; }; -#endif // ADJUSTINGSCROLLAREA_H +#endif // ADJUSTINGSCROLLAREA_H diff --git a/src/UI/tool/callconfirmwidget.cpp b/src/UI/tool/callconfirmwidget.cpp index 92a39835..907e1498 100644 --- a/src/UI/tool/callconfirmwidget.cpp +++ b/src/UI/tool/callconfirmwidget.cpp @@ -11,8 +11,7 @@ */ #include "callconfirmwidget.h" -#include "widget/im/style.h" -#include "widget/im/widget.h" +#include #include #include #include @@ -24,7 +23,8 @@ #include #include #include -#include +#include "widget/im/style.h" +#include "widget/im/widget.h" /** * @class CallConfirmWidget @@ -44,15 +44,14 @@ */ CallConfirmWidget::CallConfirmWidget(const QWidget* anchor) - : QWidget() - , anchor(anchor) - , rectW{120} - , rectH{85} - , spikeW{30} - , spikeH{15} - , roundedFactor{20} - , rectRatio(static_cast(rectH) / static_cast(rectW)) -{ + : QWidget() + , anchor(anchor) + , rectW{120} + , rectH{85} + , spikeW{30} + , spikeH{15} + , roundedFactor{20} + , rectRatio(static_cast(rectH) / static_cast(rectW)) { setWindowFlags(Qt::SubWindow); setAttribute(Qt::WA_DeleteOnClose); @@ -69,12 +68,13 @@ CallConfirmWidget::CallConfirmWidget(const QWidget* anchor) // Note: At the moment this may not work properly. For languages written // from right to left, there is no translation for the phrase "Incoming call...". // In this situation, the phrase "Incoming call..." looks as "...oming call..." - Qt::TextElideMode elideMode = - (QGuiApplication::layoutDirection() == Qt::LeftToRight) ? Qt::ElideRight : Qt::ElideLeft; + Qt::TextElideMode elideMode = (QGuiApplication::layoutDirection() == Qt::LeftToRight) + ? Qt::ElideRight + : Qt::ElideLeft; int marginSize = 12; QFontMetrics fontMetrics(callLabel->font()); QString elidedText = - fontMetrics.elidedText(callLabel->text(), elideMode, rectW - marginSize * 2 - 4); + fontMetrics.elidedText(callLabel->text(), elideMode, rectW - marginSize * 2 - 4); callLabel->setText(elidedText); QDialogButtonBox* buttonBox = new QDialogButtonBox(Qt::Horizontal, this); @@ -106,22 +106,19 @@ CallConfirmWidget::CallConfirmWidget(const QWidget* anchor) /** * @brief Recalculate our positions to track the anchor */ -void CallConfirmWidget::reposition() -{ - if (parentWidget()) - parentWidget()->removeEventFilter(this); +void CallConfirmWidget::reposition() { + if (parentWidget()) parentWidget()->removeEventFilter(this); setParent(anchor->window()); parentWidget()->installEventFilter(this); QWidget* w = anchor->window(); - QPoint pos = anchor->mapToGlobal({(anchor->width() - rectW) / 2, anchor->height()}) - - w->mapToGlobal({0, 0}); + 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 int xOverflow = 0; - if (pos.x() + rectW > w->width()) - xOverflow = pos.x() + rectW - w->width(); + if (pos.x() + rectW > w->width()) xOverflow = pos.x() + rectW - w->width(); pos.rx() -= xOverflow; mainRect = {0, spikeH, rectW, rectH}; @@ -134,8 +131,7 @@ void CallConfirmWidget::reposition() update(); } -void CallConfirmWidget::paintEvent(QPaintEvent*) -{ +void CallConfirmWidget::paintEvent(QPaintEvent*) { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); painter.setBrush(brush); @@ -145,8 +141,7 @@ void CallConfirmWidget::paintEvent(QPaintEvent*) painter.drawPolygon(spikePoly); } -void CallConfirmWidget::showEvent(QShowEvent*) -{ +void CallConfirmWidget::showEvent(QShowEvent*) { // Kriby: Legacy comment, is this still true? // If someone does show() from Widget or lower, the event will reach us // because it's our parent, and we could show up in the wrong form. @@ -156,18 +151,14 @@ void CallConfirmWidget::showEvent(QShowEvent*) update(); } -void CallConfirmWidget::hideEvent(QHideEvent*) -{ - if (parentWidget()) - parentWidget()->removeEventFilter(this); +void CallConfirmWidget::hideEvent(QHideEvent*) { + if (parentWidget()) parentWidget()->removeEventFilter(this); setParent(nullptr); } -bool CallConfirmWidget::eventFilter(QObject*, QEvent* event) -{ - if (event->type() == QEvent::Resize) - reposition(); +bool CallConfirmWidget::eventFilter(QObject*, QEvent* event) { + if (event->type() == QEvent::Resize) reposition(); return false; } diff --git a/src/UI/tool/callconfirmwidget.h b/src/UI/tool/callconfirmwidget.h index 206cbf91..b651d682 100644 --- a/src/UI/tool/callconfirmwidget.h +++ b/src/UI/tool/callconfirmwidget.h @@ -10,7 +10,6 @@ * See the Mulan PubL v2 for more details. */ - #ifndef CALLCONFIRMWIDGET_H #define CALLCONFIRMWIDGET_H @@ -22,8 +21,7 @@ class QPaintEvent; class QShowEvent; -class CallConfirmWidget final : public QWidget -{ +class CallConfirmWidget final : public QWidget { Q_OBJECT public: explicit CallConfirmWidget(const QWidget* anchor); @@ -54,4 +52,4 @@ public slots: const qreal rectRatio; }; -#endif // CALLCONFIRMWIDGET_H +#endif // CALLCONFIRMWIDGET_H diff --git a/src/UI/tool/chattextedit.cpp b/src/UI/tool/chattextedit.cpp index b2ca64fa..1342290d 100644 --- a/src/UI/tool/chattextedit.cpp +++ b/src/UI/tool/chattextedit.cpp @@ -19,71 +19,67 @@ #include #include -ChatTextEdit::ChatTextEdit(QWidget *parent) : QTextEdit(parent) { - retranslateUi(); - setAcceptRichText(false); - setAcceptDrops(false); +ChatTextEdit::ChatTextEdit(QWidget* parent) : QTextEdit(parent) { + retranslateUi(); + setAcceptRichText(false); + setAcceptDrops(false); - settings::Translator::registerHandler(std::bind(&ChatTextEdit::retranslateUi, this), - this); + settings::Translator::registerHandler(std::bind(&ChatTextEdit::retranslateUi, this), this); } ChatTextEdit::~ChatTextEdit() { Translator::unregister(this); } -void ChatTextEdit::keyPressEvent(QKeyEvent *event) { - int key = event->key(); - if ((key == Qt::Key_Enter || key == Qt::Key_Return) && - !(event->modifiers() & Qt::ShiftModifier)) { - emit enterPressed(); - return; - } - if (key == Qt::Key_Tab) { - if (event->modifiers()) - event->ignore(); - else { - emit tabPressed(); - event->ignore(); +void ChatTextEdit::keyPressEvent(QKeyEvent* event) { + int key = event->key(); + if ((key == Qt::Key_Enter || key == Qt::Key_Return) && + !(event->modifiers() & Qt::ShiftModifier)) { + emit enterPressed(); + return; } - return; - } - if (key == Qt::Key_Up && this->toPlainText().isEmpty()) { - this->setPlainText(lastMessage); - this->setFocus(); - this->moveCursor(QTextCursor::MoveOperation::End, - QTextCursor::MoveMode::MoveAnchor); - return; - } - if (event->matches(QKeySequence::Paste) && pasteIfImage(event)) { - return; - } - emit keyPressed(); - QTextEdit::keyPressEvent(event); + if (key == Qt::Key_Tab) { + if (event->modifiers()) + event->ignore(); + else { + emit tabPressed(); + event->ignore(); + } + return; + } + if (key == Qt::Key_Up && this->toPlainText().isEmpty()) { + this->setPlainText(lastMessage); + this->setFocus(); + this->moveCursor(QTextCursor::MoveOperation::End, QTextCursor::MoveMode::MoveAnchor); + return; + } + if (event->matches(QKeySequence::Paste) && pasteIfImage(event)) { + return; + } + emit keyPressed(); + QTextEdit::keyPressEvent(event); } void ChatTextEdit::setLastMessage(QString lm) { lastMessage = lm; } -void ChatTextEdit::retranslateUi() { - setPlaceholderText(tr("Type your message here...")); -} +void ChatTextEdit::retranslateUi() { setPlaceholderText(tr("Type your message here...")); } -void ChatTextEdit::sendKeyEvent(QKeyEvent *event) { emit keyPressEvent(event); } +void ChatTextEdit::sendKeyEvent(QKeyEvent* event) { emit keyPressEvent(event); } -bool ChatTextEdit::pasteIfImage(QKeyEvent *event) { - const QClipboard *const clipboard = QApplication::clipboard(); - if (!clipboard) { - return false; - } +bool ChatTextEdit::pasteIfImage(QKeyEvent* event) { + const QClipboard* const clipboard = QApplication::clipboard(); + if (!clipboard) { + return false; + } - const QMimeData *const mimeData = clipboard->mimeData(); - if (!mimeData || !mimeData->hasImage()) { - return false; - } + const QMimeData* const mimeData = clipboard->mimeData(); + if (!mimeData || !mimeData->hasImage()) { + return false; + } - const QPixmap pixmap(clipboard->pixmap()); - if (pixmap.isNull()) { - return false; - } + const QPixmap pixmap(clipboard->pixmap()); + if (pixmap.isNull()) { + return false; + } - emit pasteImage(pixmap); - return true; + emit pasteImage(pixmap); + return true; } diff --git a/src/UI/tool/chattextedit.h b/src/UI/tool/chattextedit.h index b9d40568..5970389c 100644 --- a/src/UI/tool/chattextedit.h +++ b/src/UI/tool/chattextedit.h @@ -15,8 +15,7 @@ #include -class ChatTextEdit final : public QTextEdit -{ +class ChatTextEdit final : public QTextEdit { Q_OBJECT public: explicit ChatTextEdit(QWidget* parent = nullptr); @@ -41,4 +40,4 @@ class ChatTextEdit final : public QTextEdit QString lastMessage; }; -#endif // CHATTEXTEDIT_H +#endif // CHATTEXTEDIT_H diff --git a/src/UI/tool/croppinglabel.cpp b/src/UI/tool/croppinglabel.cpp index 5bdf0167..5c398853 100644 --- a/src/UI/tool/croppinglabel.cpp +++ b/src/UI/tool/croppinglabel.cpp @@ -17,23 +17,15 @@ #include CroppingLabel::CroppingLabel(QWidget* parent) - : QLabel(parent) - , blockPaintEvents(false) - , editable(false) - , elideMode(Qt::ElideRight) -{ + : QLabel(parent), blockPaintEvents(false), editable(false), elideMode(Qt::ElideRight) { setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - class LineEdit : public QLineEdit - { + class LineEdit : public QLineEdit { public: - explicit LineEdit(QWidget* parent = nullptr) - : QLineEdit(parent) - {} + explicit LineEdit(QWidget* parent = nullptr) : QLineEdit(parent) {} protected: - void keyPressEvent(QKeyEvent* event) override - { + void keyPressEvent(QKeyEvent* event) override { if (event->key() == Qt::Key_Escape) { undo(); clearFocus(); @@ -45,19 +37,18 @@ CroppingLabel::CroppingLabel(QWidget* parent) textEdit = new LineEdit(this); textEdit->hide(); - textEdit->setInputMethodHints(Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText | Qt::ImhPreferLatin); + textEdit->setInputMethodHints(Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText | + Qt::ImhPreferLatin); connect(textEdit, &QLineEdit::editingFinished, this, &CroppingLabel::editingFinished); } -void CroppingLabel::editBegin() -{ +void CroppingLabel::editBegin() { showTextEdit(); textEdit->selectAll(); } -void CroppingLabel::setEditable(bool editable) -{ +void CroppingLabel::setEditable(bool editable) { this->editable = editable; if (editable) @@ -66,38 +57,28 @@ void CroppingLabel::setEditable(bool editable) unsetCursor(); } -void CroppingLabel::setElideMode(Qt::TextElideMode elide) -{ - elideMode = elide; -} +void CroppingLabel::setElideMode(Qt::TextElideMode elide) { elideMode = elide; } -void CroppingLabel::setText(const QString& text) -{ +void CroppingLabel::setText(const QString& text) { origText = text.trimmed(); setElidedText(); } -void CroppingLabel::setPlaceholderText(const QString& text) -{ +void CroppingLabel::setPlaceholderText(const QString& text) { textEdit->setPlaceholderText(text); setElidedText(); } -void CroppingLabel::resizeEvent(QResizeEvent* ev) -{ +void CroppingLabel::resizeEvent(QResizeEvent* ev) { setElidedText(); textEdit->resize(ev->size()); QLabel::resizeEvent(ev); } -QSize CroppingLabel::sizeHint() const -{ - return QSize(0, QLabel::sizeHint().height()); -} +QSize CroppingLabel::sizeHint() const { return QSize(0, QLabel::sizeHint().height()); } -QSize CroppingLabel::minimumSizeHint() const -{ +QSize CroppingLabel::minimumSizeHint() const { #if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)) return QSize(fontMetrics().horizontalAdvance("..."), QLabel::minimumSizeHint().height()); #else @@ -105,18 +86,15 @@ QSize CroppingLabel::minimumSizeHint() const #endif } -void CroppingLabel::mouseReleaseEvent(QMouseEvent* e) -{ - if (editable) - showTextEdit(); +void CroppingLabel::mouseReleaseEvent(QMouseEvent* e) { + if (editable) showTextEdit(); emit clicked(); QLabel::mouseReleaseEvent(e); } -void CroppingLabel::paintEvent(QPaintEvent* paintEvent) -{ +void CroppingLabel::paintEvent(QPaintEvent* paintEvent) { if (blockPaintEvents) { paintEvent->ignore(); return; @@ -124,8 +102,7 @@ void CroppingLabel::paintEvent(QPaintEvent* paintEvent) QLabel::paintEvent(paintEvent); } -void CroppingLabel::setElidedText() -{ +void CroppingLabel::setElidedText() { QString elidedText = fontMetrics().elidedText(origText, elideMode, width()); if (elidedText != origText) setToolTip(Qt::convertFromPlainText(origText, Qt::WhiteSpaceNormal)); @@ -139,14 +116,12 @@ void CroppingLabel::setElidedText() } } -void CroppingLabel::hideTextEdit() -{ +void CroppingLabel::hideTextEdit() { textEdit->hide(); blockPaintEvents = false; } -void CroppingLabel::showTextEdit() -{ +void CroppingLabel::showTextEdit() { blockPaintEvents = true; textEdit->show(); textEdit->setFocus(); @@ -158,29 +133,24 @@ void CroppingLabel::showTextEdit() * @brief Get original full text. * @return The un-cropped text. */ -QString CroppingLabel::fullText() -{ - return origText; -} +QString CroppingLabel::fullText() { return origText; } -void CroppingLabel::minimizeMaximumWidth() -{ +void CroppingLabel::minimizeMaximumWidth() { // This function chooses the smallest possible maximum width. // Text width + padding. Without padding, we'll have elipses. #if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)) - setMaximumWidth(fontMetrics().horizontalAdvance(origText) + fontMetrics().horizontalAdvance("...")); + setMaximumWidth(fontMetrics().horizontalAdvance(origText) + + fontMetrics().horizontalAdvance("...")); #else setMaximumWidth(fontMetrics().width(origText) + fontMetrics().width("...")); #endif } -void CroppingLabel::editingFinished() -{ +void CroppingLabel::editingFinished() { hideTextEdit(); QString newText = textEdit->text().trimmed().remove(QRegExp("[\\t\\n\\v\\f\\r\\x0000]")); - if (origText != newText) - emit editFinished(textEdit->text()); + if (origText != newText) emit editFinished(textEdit->text()); emit editRemoved(); } diff --git a/src/UI/tool/croppinglabel.h b/src/UI/tool/croppinglabel.h index bffdb475..2bb369ba 100644 --- a/src/UI/tool/croppinglabel.h +++ b/src/UI/tool/croppinglabel.h @@ -17,8 +17,7 @@ class QLineEdit; -class CroppingLabel : public QLabel -{ +class CroppingLabel : public QLabel { Q_OBJECT public: explicit CroppingLabel(QWidget* parent = nullptr); @@ -61,4 +60,4 @@ private slots: Qt::TextElideMode elideMode; }; -#endif // CROPPINGLABEL_H +#endif // CROPPINGLABEL_H diff --git a/src/UI/tool/flyoutoverlaywidget.cpp b/src/UI/tool/flyoutoverlaywidget.cpp index bf80fe67..7111c3d6 100644 --- a/src/UI/tool/flyoutoverlaywidget.cpp +++ b/src/UI/tool/flyoutoverlaywidget.cpp @@ -18,9 +18,7 @@ #include #include -FlyoutOverlayWidget::FlyoutOverlayWidget(QWidget* parent) - : QWidget(parent) -{ +FlyoutOverlayWidget::FlyoutOverlayWidget(QWidget* parent) : QWidget(parent) { setContentsMargins(0, 0, 0, 0); animation = new QPropertyAnimation(this, QByteArrayLiteral("flyoutPercent"), this); @@ -28,32 +26,21 @@ FlyoutOverlayWidget::FlyoutOverlayWidget(QWidget* parent) animation->setKeyValueAt(1, 1.0f); animation->setDuration(200); - connect(animation, &QAbstractAnimation::finished, this, &FlyoutOverlayWidget::finishedAnimation); + connect(animation, &QAbstractAnimation::finished, this, + &FlyoutOverlayWidget::finishedAnimation); setFlyoutPercent(0); hide(); } -FlyoutOverlayWidget::~FlyoutOverlayWidget() -{ -} +FlyoutOverlayWidget::~FlyoutOverlayWidget() {} -int FlyoutOverlayWidget::animationDuration() const -{ - return animation->duration(); -} +int FlyoutOverlayWidget::animationDuration() const { return animation->duration(); } -void FlyoutOverlayWidget::setAnimationDuration(int timeMs) -{ - animation->setDuration(timeMs); -} +void FlyoutOverlayWidget::setAnimationDuration(int timeMs) { animation->setDuration(timeMs); } -qreal FlyoutOverlayWidget::flyoutPercent() const -{ - return percent; -} +qreal FlyoutOverlayWidget::flyoutPercent() const { return percent; } -void FlyoutOverlayWidget::setFlyoutPercent(qreal progress) -{ +void FlyoutOverlayWidget::setFlyoutPercent(qreal progress) { percent = progress; QSize self = size(); @@ -62,51 +49,38 @@ void FlyoutOverlayWidget::setFlyoutPercent(qreal progress) setVisible(progress != 0); } -bool FlyoutOverlayWidget::isShown() const -{ - return (percent == 1); -} +bool FlyoutOverlayWidget::isShown() const { return (percent == 1); } -bool FlyoutOverlayWidget::isBeingAnimated() const -{ +bool FlyoutOverlayWidget::isBeingAnimated() const { return (animation->state() == QAbstractAnimation::Running); } -bool FlyoutOverlayWidget::isBeingShown() const -{ +bool FlyoutOverlayWidget::isBeingShown() const { return (isBeingAnimated() && animation->direction() == QAbstractAnimation::Forward); } -void FlyoutOverlayWidget::animateShow() -{ - if (percent == 1.0f) - return; +void FlyoutOverlayWidget::animateShow() { + if (percent == 1.0f) return; - if (animation->state() != QAbstractAnimation::Running) - this->startPos = pos(); + if (animation->state() != QAbstractAnimation::Running) this->startPos = pos(); startAnimation(true); } -void FlyoutOverlayWidget::animateHide() -{ - if (animation->state() != QAbstractAnimation::Running) - this->startPos = pos(); +void FlyoutOverlayWidget::animateHide() { + if (animation->state() != QAbstractAnimation::Running) this->startPos = pos(); startAnimation(false); } -void FlyoutOverlayWidget::finishedAnimation() -{ +void FlyoutOverlayWidget::finishedAnimation() { bool hide = (animation->direction() == QAbstractAnimation::Backward); // Delay it by a few frames to let the system catch up on rendering - if (hide) - QTimer::singleShot(50, this, SIGNAL(hidden())); + if (hide) QTimer::singleShot(50, this, SIGNAL(hidden())); } -void FlyoutOverlayWidget::startAnimation(bool forward) -{ +void FlyoutOverlayWidget::startAnimation(bool forward) { setAttribute(Qt::WA_TransparentForMouseEvents, !forward); animation->setDirection(forward ? QAbstractAnimation::Forward : QAbstractAnimation::Backward); animation->start(); diff --git a/src/UI/tool/flyoutoverlaywidget.h b/src/UI/tool/flyoutoverlaywidget.h index ae41d3c4..b6846559 100644 --- a/src/UI/tool/flyoutoverlaywidget.h +++ b/src/UI/tool/flyoutoverlaywidget.h @@ -17,8 +17,7 @@ class QPropertyAnimation; -class FlyoutOverlayWidget : public QWidget -{ +class FlyoutOverlayWidget : public QWidget { Q_OBJECT Q_PROPERTY(qreal flyoutPercent READ flyoutPercent WRITE setFlyoutPercent) public: @@ -52,4 +51,4 @@ class FlyoutOverlayWidget : public QWidget QPoint startPos; }; -#endif // FLYOUTOVERLAYWIDGET_HPP +#endif // FLYOUTOVERLAYWIDGET_HPP diff --git a/src/UI/tool/friendrequestdialog.cpp b/src/UI/tool/friendrequestdialog.cpp index 5196129f..fbb99d89 100644 --- a/src/UI/tool/friendrequestdialog.cpp +++ b/src/UI/tool/friendrequestdialog.cpp @@ -19,9 +19,9 @@ #include #include -FriendRequestDialog::FriendRequestDialog(QWidget* parent, const QString& userId, const QString& message) - : QDialog(parent) -{ +FriendRequestDialog::FriendRequestDialog(QWidget* parent, const QString& userId, + const QString& message) + : QDialog(parent) { setAttribute(Qt::WA_QuitOnClose, false); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); setWindowTitle(tr("Friend request", "Title of the window to aceept/deny a friend request")); @@ -35,7 +35,6 @@ FriendRequestDialog::FriendRequestDialog(QWidget* parent, const QString& userId, QPlainTextEdit* messageEdit = new QPlainTextEdit(message, this); messageEdit->setReadOnly(true); - QDialogButtonBox* buttonBox = new QDialogButtonBox(Qt::Horizontal, this); buttonBox->addButton(tr("Accept", "Accept a friend request"), QDialogButtonBox::AcceptRole); diff --git a/src/UI/tool/friendrequestdialog.h b/src/UI/tool/friendrequestdialog.h index 228aaee0..22024369 100644 --- a/src/UI/tool/friendrequestdialog.h +++ b/src/UI/tool/friendrequestdialog.h @@ -15,11 +15,10 @@ #include -class FriendRequestDialog : public QDialog -{ +class FriendRequestDialog : public QDialog { Q_OBJECT public: explicit FriendRequestDialog(QWidget* parent, const QString& userId, const QString& message); }; -#endif // FRIENDREQUESTDIALOG_HPP +#endif // FRIENDREQUESTDIALOG_HPP diff --git a/src/UI/tool/identicon.cpp b/src/UI/tool/identicon.cpp index 25a25f98..dec58285 100644 --- a/src/UI/tool/identicon.cpp +++ b/src/UI/tool/identicon.cpp @@ -53,31 +53,30 @@ * @brief Creates an Identicon, that visualizes a hash in graphical form. * @param data Data to visualize */ -Identicon::Identicon(const QByteArray &data) { - static_assert(Identicon::COLORS == 2, "Only two colors are implemented"); - // hash with sha256 - QByteArray hash = QCryptographicHash::hash(data, QCryptographicHash::Sha256); - for (int colorIndex = 0; colorIndex < COLORS; ++colorIndex) { - const QByteArray hashPart = hash.right(IDENTICON_COLOR_BYTES); - hash.truncate(hash.length() - IDENTICON_COLOR_BYTES); - - const qreal hue = bytesToColor(hashPart); - // change offset when COLORS != 2 - const qreal lig = static_cast(colorIndex) / COLORS + 0.3; - const qreal sat = 0.5; - colors[colorIndex].setHslF(hue, sat, lig); - } - - const uint8_t *const hashBytes = - reinterpret_cast(hash.constData()); - // compute the block colors from the hash - for (int row = 0; row < IDENTICON_ROWS; ++row) { - for (int col = 0; col < ACTIVE_COLS; ++col) { - const int hashIdx = row * ACTIVE_COLS + col; - const uint8_t colorIndex = hashBytes[hashIdx] % COLORS; - identiconColors[row][col] = colorIndex; +Identicon::Identicon(const QByteArray& data) { + static_assert(Identicon::COLORS == 2, "Only two colors are implemented"); + // hash with sha256 + QByteArray hash = QCryptographicHash::hash(data, QCryptographicHash::Sha256); + for (int colorIndex = 0; colorIndex < COLORS; ++colorIndex) { + const QByteArray hashPart = hash.right(IDENTICON_COLOR_BYTES); + hash.truncate(hash.length() - IDENTICON_COLOR_BYTES); + + const qreal hue = bytesToColor(hashPart); + // change offset when COLORS != 2 + const qreal lig = static_cast(colorIndex) / COLORS + 0.3; + const qreal sat = 0.5; + colors[colorIndex].setHslF(hue, sat, lig); + } + + const uint8_t* const hashBytes = reinterpret_cast(hash.constData()); + // compute the block colors from the hash + for (int row = 0; row < IDENTICON_ROWS; ++row) { + for (int col = 0; col < ACTIVE_COLS; ++col) { + const int hashIdx = row * ACTIVE_COLS + col; + const uint8_t colorIndex = hashBytes[hashIdx] % COLORS; + identiconColors[row][col] = colorIndex; + } } - } } /** @@ -87,24 +86,22 @@ Identicon::Identicon(const QByteArray &data) { * @return Value in the range of 0.0..1.0 */ float Identicon::bytesToColor(QByteArray bytes) { - static_assert(IDENTICON_COLOR_BYTES <= 8, "IDENTICON_COLOR max value is 8"); - const uint8_t *const bytesChr = - reinterpret_cast(bytes.constData()); - assert(bytes.length() == IDENTICON_COLOR_BYTES); - - // get foreground color - uint64_t hue = bytesChr[0]; - - // convert the last bytes to an uint - for (int i = 1; i < IDENTICON_COLOR_BYTES; ++i) { - hue = hue << 8; - hue += bytesChr[i]; - } - - // normalize to 0.0 ... 1.0 - return (static_cast(hue)) / - (static_cast( - ((static_cast(1)) << (8 * IDENTICON_COLOR_BYTES)) - 1)); + static_assert(IDENTICON_COLOR_BYTES <= 8, "IDENTICON_COLOR max value is 8"); + const uint8_t* const bytesChr = reinterpret_cast(bytes.constData()); + assert(bytes.length() == IDENTICON_COLOR_BYTES); + + // get foreground color + uint64_t hue = bytesChr[0]; + + // convert the last bytes to an uint + for (int i = 1; i < IDENTICON_COLOR_BYTES; ++i) { + hue = hue << 8; + hue += bytesChr[i]; + } + + // normalize to 0.0 ... 1.0 + return (static_cast(hue)) / + (static_cast(((static_cast(1)) << (8 * IDENTICON_COLOR_BYTES)) - 1)); } /** @@ -114,25 +111,24 @@ float Identicon::bytesToColor(QByteArray bytes) { * @return a QImage with the identicon */ QImage Identicon::toImage(int scaleFactor) { - if (scaleFactor < 1) { - qDebug() << "Can't scale with values <1, clamping to 1"; - scaleFactor = 1; - } + if (scaleFactor < 1) { + qDebug() << "Can't scale with values <1, clamping to 1"; + scaleFactor = 1; + } - scaleFactor *= IDENTICON_ROWS; + scaleFactor *= IDENTICON_ROWS; - QImage pixels(IDENTICON_ROWS, IDENTICON_ROWS, QImage::Format_RGB888); + QImage pixels(IDENTICON_ROWS, IDENTICON_ROWS, QImage::Format_RGB888); - for (int row = 0; row < IDENTICON_ROWS; ++row) { - for (int col = 0; col < IDENTICON_ROWS; ++col) { - // mirror on vertical axis - const int columnIdx = abs((col * 2 - (IDENTICON_ROWS - 1)) / 2); - const int colorIdx = identiconColors[row][columnIdx]; - pixels.setPixel(col, row, colors[colorIdx].rgb()); + for (int row = 0; row < IDENTICON_ROWS; ++row) { + for (int col = 0; col < IDENTICON_ROWS; ++col) { + // mirror on vertical axis + const int columnIdx = abs((col * 2 - (IDENTICON_ROWS - 1)) / 2); + const int colorIdx = identiconColors[row][columnIdx]; + pixels.setPixel(col, row, colors[colorIdx].rgb()); + } } - } - // scale up without smoothing to make it look sharp - return pixels.scaled(scaleFactor, scaleFactor, Qt::IgnoreAspectRatio, - Qt::FastTransformation); + // scale up without smoothing to make it look sharp + return pixels.scaled(scaleFactor, scaleFactor, Qt::IgnoreAspectRatio, Qt::FastTransformation); } diff --git a/src/UI/tool/identicon.h b/src/UI/tool/identicon.h index 06cbb7ec..f86cd553 100644 --- a/src/UI/tool/identicon.h +++ b/src/UI/tool/identicon.h @@ -16,8 +16,7 @@ #include #include -class Identicon -{ +class Identicon { public: Identicon(const QByteArray& data); QImage toImage(int scaleFactor = 1); @@ -32,11 +31,11 @@ class Identicon static constexpr int COLORS = 2; static constexpr int ACTIVE_COLS = (IDENTICON_ROWS + 1) / 2; static constexpr int IDENTICON_COLOR_BYTES = 6; - static constexpr int HASH_MIN_LEN = ACTIVE_COLS * IDENTICON_ROWS - + COLORS * IDENTICON_COLOR_BYTES; + static constexpr int HASH_MIN_LEN = + ACTIVE_COLS * IDENTICON_ROWS + COLORS * IDENTICON_COLOR_BYTES; uint8_t identiconColors[IDENTICON_ROWS][ACTIVE_COLS]; QColor colors[COLORS]; }; -#endif // IDENTICON_H +#endif // IDENTICON_H diff --git a/src/UI/tool/movablewidget.cpp b/src/UI/tool/movablewidget.cpp index 179ab707..399151f8 100644 --- a/src/UI/tool/movablewidget.cpp +++ b/src/UI/tool/movablewidget.cpp @@ -15,239 +15,223 @@ #include #include -MovableWidget::MovableWidget(QWidget *parent) : QWidget(parent) { - setMinimumHeight(64); - setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored)); - actualSize = minimumSize(); - boundaryRect = QRect(0, 0, 0, 0); - setRatio(1.0f); - resize(minimumSize()); - actualPos = QPoint(0, 0); +MovableWidget::MovableWidget(QWidget* parent) : QWidget(parent) { + setMinimumHeight(64); + setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored)); + actualSize = minimumSize(); + boundaryRect = QRect(0, 0, 0, 0); + setRatio(1.0f); + resize(minimumSize()); + actualPos = QPoint(0, 0); } void MovableWidget::resetBoundary(QRect newBoundary) { - boundaryRect = newBoundary; - resize(QSize(round(actualSize.width()), round(actualSize.height()))); + boundaryRect = newBoundary; + resize(QSize(round(actualSize.width()), round(actualSize.height()))); - QPoint moveTo = QPoint(round(actualPos.x()), round(actualPos.y())); - checkBoundary(moveTo); - move(moveTo); - actualPos = moveTo; + QPoint moveTo = QPoint(round(actualPos.x()), round(actualPos.y())); + checkBoundary(moveTo); + move(moveTo); + actualPos = moveTo; } void MovableWidget::setBoundary(QRect newBoundary) { - if (boundaryRect.isNull()) { - boundaryRect = newBoundary; - return; - } + if (boundaryRect.isNull()) { + boundaryRect = newBoundary; + return; + } - float changeX = - newBoundary.width() / static_cast(boundaryRect.width()); - float changeY = - newBoundary.height() / static_cast(boundaryRect.height()); + float changeX = newBoundary.width() / static_cast(boundaryRect.width()); + float changeY = newBoundary.height() / static_cast(boundaryRect.height()); - float percentageX = (x() - boundaryRect.x()) / - static_cast(boundaryRect.width() - width()); - float percentageY = (y() - boundaryRect.y()) / - static_cast(boundaryRect.height() - height()); + float percentageX = + (x() - boundaryRect.x()) / static_cast(boundaryRect.width() - width()); + float percentageY = + (y() - boundaryRect.y()) / static_cast(boundaryRect.height() - height()); - actualSize.setWidth(actualSize.width() * changeX); - actualSize.setHeight(actualSize.height() * changeY); + actualSize.setWidth(actualSize.width() * changeX); + actualSize.setHeight(actualSize.height() * changeY); - if (actualSize.width() == 0) - actualSize.setWidth(1); + if (actualSize.width() == 0) actualSize.setWidth(1); - if (actualSize.height() == 0) - actualSize.setHeight(1); + if (actualSize.height() == 0) actualSize.setHeight(1); - resize(QSize(round(actualSize.width()), round(actualSize.height()))); + resize(QSize(round(actualSize.width()), round(actualSize.height()))); - actualPos = QPointF(percentageX * (newBoundary.width() - width()), - percentageY * (newBoundary.height() - height())); - actualPos += QPointF(newBoundary.topLeft()); + actualPos = QPointF(percentageX * (newBoundary.width() - width()), + percentageY * (newBoundary.height() - height())); + actualPos += QPointF(newBoundary.topLeft()); - QPoint moveTo = QPoint(round(actualPos.x()), round(actualPos.y())); - move(moveTo); + QPoint moveTo = QPoint(round(actualPos.x()), round(actualPos.y())); + move(moveTo); - boundaryRect = newBoundary; + boundaryRect = newBoundary; } float MovableWidget::getRatio() const { return ratio; } void MovableWidget::setRatio(float r) { - ratio = r; - resize(width(), width() / ratio); - QPoint position = QPoint(actualPos.x(), actualPos.y()); - checkBoundary(position); - move(position); - - actualPos = pos(); - actualSize = size(); + ratio = r; + resize(width(), width() / ratio); + QPoint position = QPoint(actualPos.x(), actualPos.y()); + checkBoundary(position); + move(position); + + actualPos = pos(); + actualSize = size(); } -void MovableWidget::mousePressEvent(QMouseEvent *event) { - if (event->buttons() & Qt::LeftButton) { - if (!(mode & Resize)) - mode |= Moving; +void MovableWidget::mousePressEvent(QMouseEvent* event) { + if (event->buttons() & Qt::LeftButton) { + if (!(mode & Resize)) mode |= Moving; - lastPoint = event->globalPos(); - } + lastPoint = event->globalPos(); + } } -void MovableWidget::mouseMoveEvent(QMouseEvent *event) { - if (mode & Moving) { - QPoint moveTo = pos() - (lastPoint - event->globalPos()); - checkBoundary(moveTo); - - move(moveTo); - lastPoint = event->globalPos(); +void MovableWidget::mouseMoveEvent(QMouseEvent* event) { + if (mode & Moving) { + QPoint moveTo = pos() - (lastPoint - event->globalPos()); + checkBoundary(moveTo); - actualPos = pos(); - } else { - if (!(event->buttons() & Qt::LeftButton)) { - if (event->x() < 6) - mode |= ResizeLeft; - else - mode &= ~ResizeLeft; - - if (event->y() < 6) - mode |= ResizeUp; - else - mode &= ~ResizeUp; - - if (event->x() > width() - 6) - mode |= ResizeRight; - else - mode &= ~ResizeRight; - - if (event->y() > height() - 6) - mode |= ResizeDown; - else - mode &= ~ResizeDown; - } + move(moveTo); + lastPoint = event->globalPos(); - if (mode & Resize) { - const Modes ResizeUpRight = ResizeUp | ResizeRight; - const Modes ResizeUpLeft = ResizeUp | ResizeLeft; - const Modes ResizeDownRight = ResizeDown | ResizeRight; - const Modes ResizeDownLeft = ResizeDown | ResizeLeft; - - if ((mode & ResizeUpRight) == ResizeUpRight || - (mode & ResizeDownLeft) == ResizeDownLeft) - setCursor(Qt::SizeBDiagCursor); - else if ((mode & ResizeUpLeft) == ResizeUpLeft || - (mode & ResizeDownRight) == ResizeDownRight) - setCursor(Qt::SizeFDiagCursor); - else if (mode & (ResizeLeft | ResizeRight)) - setCursor(Qt::SizeHorCursor); - else - setCursor(Qt::SizeVerCursor); - - if (event->buttons() & Qt::LeftButton) { - QPoint lastPosition = pos(); - QPoint displacement = lastPoint - event->globalPos(); - QSize lastSize = size(); - - if (mode & ResizeUp) { - lastSize.setHeight(height() + displacement.y()); - - if (lastSize.height() > maximumHeight()) - lastPosition.setY(y() - displacement.y() + - (lastSize.height() - maximumHeight())); - else - lastPosition.setY(y() - displacement.y()); + actualPos = pos(); + } else { + if (!(event->buttons() & Qt::LeftButton)) { + if (event->x() < 6) + mode |= ResizeLeft; + else + mode &= ~ResizeLeft; + + if (event->y() < 6) + mode |= ResizeUp; + else + mode &= ~ResizeUp; + + if (event->x() > width() - 6) + mode |= ResizeRight; + else + mode &= ~ResizeRight; + + if (event->y() > height() - 6) + mode |= ResizeDown; + else + mode &= ~ResizeDown; } - if (mode & ResizeLeft) { - lastSize.setWidth(width() + displacement.x()); - if (lastSize.width() > maximumWidth()) - lastPosition.setX(x() - displacement.x() + - (lastSize.width() - maximumWidth())); - else - lastPosition.setX(x() - displacement.x()); - } + if (mode & Resize) { + const Modes ResizeUpRight = ResizeUp | ResizeRight; + const Modes ResizeUpLeft = ResizeUp | ResizeLeft; + const Modes ResizeDownRight = ResizeDown | ResizeRight; + const Modes ResizeDownLeft = ResizeDown | ResizeLeft; - if (mode & ResizeRight) - lastSize.setWidth(width() - displacement.x()); + if ((mode & ResizeUpRight) == ResizeUpRight || + (mode & ResizeDownLeft) == ResizeDownLeft) + setCursor(Qt::SizeBDiagCursor); + else if ((mode & ResizeUpLeft) == ResizeUpLeft || + (mode & ResizeDownRight) == ResizeDownRight) + setCursor(Qt::SizeFDiagCursor); + else if (mode & (ResizeLeft | ResizeRight)) + setCursor(Qt::SizeHorCursor); + else + setCursor(Qt::SizeVerCursor); - if (mode & ResizeDown) - lastSize.setHeight(height() - displacement.y()); + if (event->buttons() & Qt::LeftButton) { + QPoint lastPosition = pos(); + QPoint displacement = lastPoint - event->globalPos(); + QSize lastSize = size(); - if (lastSize.height() > maximumHeight()) - lastSize.setHeight(maximumHeight()); + if (mode & ResizeUp) { + lastSize.setHeight(height() + displacement.y()); - if (lastSize.width() > maximumWidth()) - lastSize.setWidth(maximumWidth()); + if (lastSize.height() > maximumHeight()) + lastPosition.setY(y() - displacement.y() + + (lastSize.height() - maximumHeight())); + else + lastPosition.setY(y() - displacement.y()); + } - if (mode & (ResizeLeft | ResizeRight)) { - if (mode & (ResizeUp | ResizeDown)) { - int height = lastSize.width() / getRatio(); + if (mode & ResizeLeft) { + lastSize.setWidth(width() + displacement.x()); + if (lastSize.width() > maximumWidth()) + lastPosition.setX(x() - displacement.x() + + (lastSize.width() - maximumWidth())); + else + lastPosition.setX(x() - displacement.x()); + } - if (!(mode & ResizeDown)) - lastPosition.setY(lastPosition.y() - - (height - lastSize.height())); + if (mode & ResizeRight) lastSize.setWidth(width() - displacement.x()); - resize(lastSize.width(), height); + if (mode & ResizeDown) lastSize.setHeight(height() - displacement.y()); - if (lastSize.width() < minimumWidth()) - lastPosition.setX(pos().x()); + if (lastSize.height() > maximumHeight()) lastSize.setHeight(maximumHeight()); - if (height < minimumHeight()) - lastPosition.setY(pos().y()); - } else { - resize(lastSize.width(), lastSize.width() / getRatio()); - } - } else { - resize(lastSize.height() * getRatio(), lastSize.height()); - } + if (lastSize.width() > maximumWidth()) lastSize.setWidth(maximumWidth()); - updateGeometry(); + if (mode & (ResizeLeft | ResizeRight)) { + if (mode & (ResizeUp | ResizeDown)) { + int height = lastSize.width() / getRatio(); - checkBoundary(lastPosition); + if (!(mode & ResizeDown)) + lastPosition.setY(lastPosition.y() - (height - lastSize.height())); - move(lastPosition); + resize(lastSize.width(), height); - lastPoint = event->globalPos(); - actualSize = size(); - actualPos = pos(); - } - } else { - unsetCursor(); + if (lastSize.width() < minimumWidth()) lastPosition.setX(pos().x()); + + if (height < minimumHeight()) lastPosition.setY(pos().y()); + } else { + resize(lastSize.width(), lastSize.width() / getRatio()); + } + } else { + resize(lastSize.height() * getRatio(), lastSize.height()); + } + + updateGeometry(); + + checkBoundary(lastPosition); + + move(lastPosition); + + lastPoint = event->globalPos(); + actualSize = size(); + actualPos = pos(); + } + } else { + unsetCursor(); + } } - } } -void MovableWidget::mouseReleaseEvent(QMouseEvent *event) { - if (!(event->buttons() & Qt::LeftButton)) - mode = 0; +void MovableWidget::mouseReleaseEvent(QMouseEvent* event) { + if (!(event->buttons() & Qt::LeftButton)) mode = 0; } -void MovableWidget::mouseDoubleClickEvent(QMouseEvent *event) { - if (!(event->buttons() & Qt::LeftButton)) - return; - - if (!graphicsEffect()) { - QGraphicsOpacityEffect *opacityEffect = new QGraphicsOpacityEffect(this); - opacityEffect->setOpacity(0.5); - setGraphicsEffect(opacityEffect); - } else { - setGraphicsEffect(nullptr); - } +void MovableWidget::mouseDoubleClickEvent(QMouseEvent* event) { + if (!(event->buttons() & Qt::LeftButton)) return; + + if (!graphicsEffect()) { + QGraphicsOpacityEffect* opacityEffect = new QGraphicsOpacityEffect(this); + opacityEffect->setOpacity(0.5); + setGraphicsEffect(opacityEffect); + } else { + setGraphicsEffect(nullptr); + } } -void MovableWidget::checkBoundary(QPoint &point) const { - int x1, y1, x2, y2; - boundaryRect.getCoords(&x1, &y1, &x2, &y2); +void MovableWidget::checkBoundary(QPoint& point) const { + int x1, y1, x2, y2; + boundaryRect.getCoords(&x1, &y1, &x2, &y2); - if (point.x() < boundaryRect.left()) - point.setX(boundaryRect.left()); + if (point.x() < boundaryRect.left()) point.setX(boundaryRect.left()); - if (point.y() < boundaryRect.top()) - point.setY(boundaryRect.top()); + if (point.y() < boundaryRect.top()) point.setY(boundaryRect.top()); - if (point.x() + width() > boundaryRect.right() + 1) - point.setX(boundaryRect.right() - width() + 1); + if (point.x() + width() > boundaryRect.right() + 1) + point.setX(boundaryRect.right() - width() + 1); - if (point.y() + height() > boundaryRect.bottom() + 1) - point.setY(boundaryRect.bottom() - height() + 1); + if (point.y() + height() > boundaryRect.bottom() + 1) + point.setY(boundaryRect.bottom() - height() + 1); } diff --git a/src/UI/tool/movablewidget.h b/src/UI/tool/movablewidget.h index b1222fbb..501383b5 100644 --- a/src/UI/tool/movablewidget.h +++ b/src/UI/tool/movablewidget.h @@ -15,8 +15,7 @@ #include -class MovableWidget : public QWidget -{ +class MovableWidget : public QWidget { public: explicit MovableWidget(QWidget* parent); void resetBoundary(QRect newBoundary); @@ -36,8 +35,7 @@ class MovableWidget : public QWidget typedef uint8_t Modes; - enum Mode : Modes - { + enum Mode : Modes { Moving = 0x01, ResizeLeft = 0x02, ResizeRight = 0x04, @@ -54,4 +52,4 @@ class MovableWidget : public QWidget float ratio; }; -#endif // MOVABLEWIDGET_H +#endif // MOVABLEWIDGET_H diff --git a/src/UI/tool/profileimporter.cpp b/src/UI/tool/profileimporter.cpp index 7cb1b940..a1951655 100644 --- a/src/UI/tool/profileimporter.cpp +++ b/src/UI/tool/profileimporter.cpp @@ -28,23 +28,23 @@ * to create dialog forms. */ -ProfileImporter::ProfileImporter(QWidget *parent) : QWidget(parent) {} +ProfileImporter::ProfileImporter(QWidget* parent) : QWidget(parent) {} /** * @brief Show a file dialog. Selected file will be imported as Tox profile. * @return True, if the import was succesful. False otherwise. */ bool ProfileImporter::importProfile() { - QString title = tr("Import profile", "import dialog title"); - QString filter = tr("Tox save file (*.tox)", "import dialog filter"); - QString dir = QDir::homePath(); + QString title = tr("Import profile", "import dialog title"); + QString filter = tr("Tox save file (*.tox)", "import dialog filter"); + QString dir = QDir::homePath(); - // TODO: Change all QFileDialog instances across project to use - // this instead of Q_NULLPTR. Possibly requires >Qt 5.9 due to: - // https://bugreports.qt.io/browse/QTBUG-59184 - QString path = QFileDialog::getOpenFileName(Q_NULLPTR, title, dir, filter); + // TODO: Change all QFileDialog instances across project to use + // this instead of Q_NULLPTR. Possibly requires >Qt 5.9 due to: + // https://bugreports.qt.io/browse/QTBUG-59184 + QString path = QFileDialog::getOpenFileName(Q_NULLPTR, title, dir, filter); - return importProfile(path); + return importProfile(path); } /** @@ -54,17 +54,15 @@ bool ProfileImporter::importProfile() { * @return True if the answer is positive, false otherwise. */ bool ProfileImporter::askQuestion(QString title, QString message) { - QMessageBox::Icon icon = QMessageBox::Warning; - QMessageBox box(icon, title, message, QMessageBox::NoButton, this); - QPushButton *pushButton1 = - box.addButton(QApplication::tr("Yes"), QMessageBox::AcceptRole); - QPushButton *pushButton2 = - box.addButton(QApplication::tr("No"), QMessageBox::RejectRole); - box.setDefaultButton(pushButton2); - box.setEscapeButton(pushButton2); - - box.exec(); - return box.clickedButton() == pushButton1; + QMessageBox::Icon icon = QMessageBox::Warning; + QMessageBox box(icon, title, message, QMessageBox::NoButton, this); + QPushButton* pushButton1 = box.addButton(QApplication::tr("Yes"), QMessageBox::AcceptRole); + QPushButton* pushButton2 = box.addButton(QApplication::tr("No"), QMessageBox::RejectRole); + box.setDefaultButton(pushButton2); + box.setEscapeButton(pushButton2); + + box.exec(); + return box.clickedButton() == pushButton1; } /** @@ -72,52 +70,49 @@ bool ProfileImporter::askQuestion(QString title, QString message) { * @param path Path to Tox profile. * @return True, if the import was succesful. False otherwise. */ -bool ProfileImporter::importProfile(const QString &path) { - if (path.isEmpty()) - return false; - - QFileInfo info(path); - if (!info.exists()) { - QMessageBox::warning(this, tr("File doesn't exist"), - tr("Profile doesn't exist"), QMessageBox::Ok); - return false; - } - - QString profile = info.completeBaseName(); - - if (info.suffix() != "tox") { - QMessageBox::warning(this, tr("Ignoring non-Tox file", "popup title"), - tr("Warning: You have chosen a file that is not a " - "Tox save file; ignoring.", - "popup text"), - QMessageBox::Ok); - return false; // ingore importing non-tox file - } - - QString settingsPath = Settings::getInstance().getSettingsDirPath(); - QString profilePath = QDir(settingsPath).filePath(profile + lib::IM::Core::TOX_EXT); - - if (QFileInfo(profilePath).exists()) { - QString title = tr("Profile already exists", "import confirm title"); - QString message = tr("A profile named \"%1\" already exists. " - "Do you want to erase it?", - "import confirm text") - .arg(profile); - bool erase = askQuestion(title, message); - - if (!erase) - return false; // import canelled - - QFile(profilePath).remove(); - } - - 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(this, tr("Profile imported"), - tr("%1.tox was successfully imported").arg(profile), - QMessageBox::Ok); - - return true; // import successfull +bool ProfileImporter::importProfile(const QString& path) { + if (path.isEmpty()) return false; + + QFileInfo info(path); + if (!info.exists()) { + QMessageBox::warning(this, tr("File doesn't exist"), tr("Profile doesn't exist"), + QMessageBox::Ok); + return false; + } + + QString profile = info.completeBaseName(); + + if (info.suffix() != "tox") { + QMessageBox::warning(this, tr("Ignoring non-Tox file", "popup title"), + tr("Warning: You have chosen a file that is not a " + "Tox save file; ignoring.", + "popup text"), + QMessageBox::Ok); + return false; // ingore importing non-tox file + } + + QString settingsPath = Settings::getInstance().getSettingsDirPath(); + QString profilePath = QDir(settingsPath).filePath(profile + lib::IM::Core::TOX_EXT); + + if (QFileInfo(profilePath).exists()) { + QString title = tr("Profile already exists", "import confirm title"); + QString message = tr("A profile named \"%1\" already exists. " + "Do you want to erase it?", + "import confirm text") + .arg(profile); + bool erase = askQuestion(title, message); + + if (!erase) return false; // import canelled + + QFile(profilePath).remove(); + } + + 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(this, tr("Profile imported"), + tr("%1.tox was successfully imported").arg(profile), QMessageBox::Ok); + + return true; // import successfull } diff --git a/src/UI/tool/profileimporter.h b/src/UI/tool/profileimporter.h index 72cef7d3..40f96e27 100644 --- a/src/UI/tool/profileimporter.h +++ b/src/UI/tool/profileimporter.h @@ -15,8 +15,7 @@ #include -class ProfileImporter : public QWidget -{ +class ProfileImporter : public QWidget { Q_OBJECT public: @@ -28,4 +27,4 @@ class ProfileImporter : public QWidget bool askQuestion(QString title, QString message); }; -#endif // PROFILEIMPORTER_H +#endif // PROFILEIMPORTER_H diff --git a/src/UI/tool/removefrienddialog.cpp b/src/UI/tool/removefrienddialog.cpp index 7807cf99..a88a490c 100644 --- a/src/UI/tool/removefrienddialog.cpp +++ b/src/UI/tool/removefrienddialog.cpp @@ -13,16 +13,14 @@ #include "removefrienddialog.h" #include - RemoveFriendDialog::RemoveFriendDialog(QWidget* parent, const lib::IM::Friend* f) - : QDialog(parent) -{ + : QDialog(parent) { setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); setAttribute(Qt::WA_QuitOnClose, false); ui.setupUi(this); QString name = f->getDisplayedName().toHtmlEscaped(); QString text = tr("Are you sure you want to remove %1 from your contacts list?") - .arg(QString("%1").arg(name)); + .arg(QString("%1").arg(name)); ui.label->setText(text); auto removeButton = ui.buttonBox->button(QDialogButtonBox::Ok); @@ -35,8 +33,7 @@ RemoveFriendDialog::RemoveFriendDialog(QWidget* parent, const lib::IM::Friend* f setFocus(); } -void RemoveFriendDialog::onAccepted() -{ +void RemoveFriendDialog::onAccepted() { _accepted = true; close(); } diff --git a/src/UI/tool/removefrienddialog.h b/src/UI/tool/removefrienddialog.h index f78d9c65..eb8d8c4f 100644 --- a/src/UI/tool/removefrienddialog.h +++ b/src/UI/tool/removefrienddialog.h @@ -13,27 +13,18 @@ #ifndef DELETEFRIENDDIALOG_H #define DELETEFRIENDDIALOG_H - -#include "ui_removefrienddialog.h" -#include "lib/lib/messenger/model/friend.h" #include +#include "lib/lib/messenger/model/friend.h" +#include "ui_removefrienddialog.h" - -class RemoveFriendDialog : public QDialog -{ +class RemoveFriendDialog : public QDialog { Q_OBJECT public: explicit RemoveFriendDialog(QWidget* parent, const lib::IM::Friend* f); - inline bool removeHistory() - { - return ui.removeHistory->isChecked(); - } + inline bool removeHistory() { return ui.removeHistory->isChecked(); } - inline bool accepted() - { - return _accepted; - } + inline bool accepted() { return _accepted; } public slots: void onAccepted(); @@ -43,4 +34,4 @@ public slots: bool _accepted = false; }; -#endif // DELETEFRIENDDIALOG_H +#endif // DELETEFRIENDDIALOG_H diff --git a/src/UI/tool/screengrabberchooserrectitem.cpp b/src/UI/tool/screengrabberchooserrectitem.cpp index dcaf00df..84f20793 100644 --- a/src/UI/tool/screengrabberchooserrectitem.cpp +++ b/src/UI/tool/screengrabberchooserrectitem.cpp @@ -17,14 +17,12 @@ #include #include -enum -{ +enum { HandleSize = 10, MinRectSize = 2, }; -ScreenGrabberChooserRectItem::ScreenGrabberChooserRectItem(QGraphicsScene* scene) -{ +ScreenGrabberChooserRectItem::ScreenGrabberChooserRectItem(QGraphicsScene* scene) { scene->addItem(this); setCursor(QCursor(Qt::OpenHandCursor)); @@ -51,18 +49,14 @@ ScreenGrabberChooserRectItem::ScreenGrabberChooserRectItem(QGraphicsScene* scene hideHandles(); } -ScreenGrabberChooserRectItem::~ScreenGrabberChooserRectItem() -{ -} +ScreenGrabberChooserRectItem::~ScreenGrabberChooserRectItem() {} -QRectF ScreenGrabberChooserRectItem::boundingRect() const -{ +QRectF ScreenGrabberChooserRectItem::boundingRect() const { return QRectF(-HandleSize - 1, -HandleSize - 1, rectWidth + HandleSize + 1, rectHeight + HandleSize + 1); } -void ScreenGrabberChooserRectItem::beginResize(QPointF mousePos) -{ +void ScreenGrabberChooserRectItem::beginResize(QPointF mousePos) { rectWidth = this->rectHeight = 0; mainRect->setRect(QRect()); state = Resizing; @@ -73,8 +67,7 @@ void ScreenGrabberChooserRectItem::beginResize(QPointF mousePos) mainRect->grabMouse(); } -QRect ScreenGrabberChooserRectItem::chosenRect() const -{ +QRect ScreenGrabberChooserRectItem::chosenRect() const { QRect rect(x(), y(), rectWidth, rectHeight); if (rectWidth < 0) { rect.setX(rect.x() + rectWidth); @@ -89,8 +82,7 @@ QRect ScreenGrabberChooserRectItem::chosenRect() const return rect; } -void ScreenGrabberChooserRectItem::showHandles() -{ +void ScreenGrabberChooserRectItem::showHandles() { this->topLeft->show(); this->topCenter->show(); this->topRight->show(); @@ -101,8 +93,7 @@ void ScreenGrabberChooserRectItem::showHandles() this->leftCenter->show(); } -void ScreenGrabberChooserRectItem::hideHandles() -{ +void ScreenGrabberChooserRectItem::hideHandles() { this->topLeft->hide(); this->topCenter->hide(); this->topRight->hide(); @@ -113,16 +104,14 @@ void ScreenGrabberChooserRectItem::hideHandles() this->leftCenter->hide(); } -void ScreenGrabberChooserRectItem::mousePress(QGraphicsSceneMouseEvent* event) -{ +void ScreenGrabberChooserRectItem::mousePress(QGraphicsSceneMouseEvent* event) { if (event->button() == Qt::LeftButton) { this->state = Moving; setCursor(QCursor(Qt::ClosedHandCursor)); } } -void ScreenGrabberChooserRectItem::mouseMove(QGraphicsSceneMouseEvent* event) -{ +void ScreenGrabberChooserRectItem::mouseMove(QGraphicsSceneMouseEvent* event) { if (this->state == Moving) { QPointF delta = event->scenePos() - event->lastScenePos(); moveBy(delta.x(), delta.y()); @@ -141,8 +130,7 @@ void ScreenGrabberChooserRectItem::mouseMove(QGraphicsSceneMouseEvent* event) emit regionChosen(chosenRect()); } -void ScreenGrabberChooserRectItem::mouseRelease(QGraphicsSceneMouseEvent* event) -{ +void ScreenGrabberChooserRectItem::mouseRelease(QGraphicsSceneMouseEvent* event) { if (event->button() == Qt::LeftButton) { setCursor(QCursor(Qt::OpenHandCursor)); @@ -168,25 +156,20 @@ void ScreenGrabberChooserRectItem::mouseRelease(QGraphicsSceneMouseEvent* event) } } -void ScreenGrabberChooserRectItem::mouseDoubleClick(QGraphicsSceneMouseEvent* event) -{ +void ScreenGrabberChooserRectItem::mouseDoubleClick(QGraphicsSceneMouseEvent* event) { Q_UNUSED(event); emit doubleClicked(); } -void ScreenGrabberChooserRectItem::mousePressHandle(int x, int y, QGraphicsSceneMouseEvent* event) -{ +void ScreenGrabberChooserRectItem::mousePressHandle(int x, int y, QGraphicsSceneMouseEvent* event) { Q_UNUSED(x); Q_UNUSED(y); - if (event->button() == Qt::LeftButton) - this->state = HandleResizing; + if (event->button() == Qt::LeftButton) this->state = HandleResizing; } -void ScreenGrabberChooserRectItem::mouseMoveHandle(int x, int y, QGraphicsSceneMouseEvent* event) -{ - if (this->state != HandleResizing) - return; +void ScreenGrabberChooserRectItem::mouseMoveHandle(int x, int y, QGraphicsSceneMouseEvent* event) { + if (this->state != HandleResizing) return; QPointF delta = event->scenePos() - event->lastScenePos(); delta.rx() *= qAbs(x); @@ -214,46 +197,35 @@ void ScreenGrabberChooserRectItem::mouseMoveHandle(int x, int y, QGraphicsSceneM emit regionChosen(chosenRect()); } -void ScreenGrabberChooserRectItem::mouseReleaseHandle(int x, int y, QGraphicsSceneMouseEvent* event) -{ +void ScreenGrabberChooserRectItem::mouseReleaseHandle(int x, int y, + QGraphicsSceneMouseEvent* event) { Q_UNUSED(x); Q_UNUSED(y); - if (event->button() == Qt::LeftButton) - this->state = None; + if (event->button() == Qt::LeftButton) this->state = None; } -QPoint ScreenGrabberChooserRectItem::getHandleMultiplier(QGraphicsItem* handle) -{ - if (handle == this->topLeft) - return QPoint(-1, -1); +QPoint ScreenGrabberChooserRectItem::getHandleMultiplier(QGraphicsItem* handle) { + if (handle == this->topLeft) return QPoint(-1, -1); - if (handle == this->topCenter) - return QPoint(0, -1); + if (handle == this->topCenter) return QPoint(0, -1); - if (handle == this->topRight) - return QPoint(1, -1); + if (handle == this->topRight) return QPoint(1, -1); - if (handle == this->rightCenter) - return QPoint(1, 0); + if (handle == this->rightCenter) return QPoint(1, 0); - if (handle == this->bottomRight) - return QPoint(1, 1); + if (handle == this->bottomRight) return QPoint(1, 1); - if (handle == this->bottomCenter) - return QPoint(0, 1); + if (handle == this->bottomCenter) return QPoint(0, 1); - if (handle == this->bottomLeft) - return QPoint(-1, 1); + if (handle == this->bottomLeft) return QPoint(-1, 1); - if (handle == this->leftCenter) - return QPoint(-1, 0); + if (handle == this->leftCenter) return QPoint(-1, 0); return QPoint(); } -void ScreenGrabberChooserRectItem::updateHandlePositions() -{ +void ScreenGrabberChooserRectItem::updateHandlePositions() { this->topLeft->setPos(-HandleSize, -HandleSize); this->topCenter->setPos((this->rectWidth - HandleSize) / 2, -HandleSize); this->topRight->setPos(this->rectWidth, -HandleSize); @@ -264,8 +236,7 @@ void ScreenGrabberChooserRectItem::updateHandlePositions() this->leftCenter->setPos(-HandleSize, (this->rectHeight - HandleSize) / 2); } -QGraphicsRectItem* ScreenGrabberChooserRectItem::createHandleItem(QGraphicsScene* scene) -{ +QGraphicsRectItem* ScreenGrabberChooserRectItem::createHandleItem(QGraphicsScene* scene) { QGraphicsRectItem* handle = new QGraphicsRectItem(0, 0, HandleSize, HandleSize); handle->setPen(QPen(Qt::blue)); handle->setBrush(Qt::NoBrush); @@ -277,8 +248,7 @@ QGraphicsRectItem* ScreenGrabberChooserRectItem::createHandleItem(QGraphicsScene return handle; } -bool ScreenGrabberChooserRectItem::sceneEventFilter(QGraphicsItem* watched, QEvent* event) -{ +bool ScreenGrabberChooserRectItem::sceneEventFilter(QGraphicsItem* watched, QEvent* event) { if (watched == this->mainRect) forwardMainRectEvent(event); else @@ -287,40 +257,37 @@ bool ScreenGrabberChooserRectItem::sceneEventFilter(QGraphicsItem* watched, QEve return true; } -void ScreenGrabberChooserRectItem::forwardMainRectEvent(QEvent* event) -{ +void ScreenGrabberChooserRectItem::forwardMainRectEvent(QEvent* event) { QGraphicsSceneMouseEvent* mouseEvent = static_cast(event); switch (event->type()) { - case QEvent::GraphicsSceneMousePress: - return mousePress(mouseEvent); - case QEvent::GraphicsSceneMouseMove: - return mouseMove(mouseEvent); - case QEvent::GraphicsSceneMouseRelease: - return mouseRelease(mouseEvent); - case QEvent::GraphicsSceneMouseDoubleClick: - return mouseDoubleClick(mouseEvent); - default: - return; + case QEvent::GraphicsSceneMousePress: + return mousePress(mouseEvent); + case QEvent::GraphicsSceneMouseMove: + return mouseMove(mouseEvent); + case QEvent::GraphicsSceneMouseRelease: + return mouseRelease(mouseEvent); + case QEvent::GraphicsSceneMouseDoubleClick: + return mouseDoubleClick(mouseEvent); + default: + return; } } -void ScreenGrabberChooserRectItem::forwardHandleEvent(QGraphicsItem* watched, QEvent* event) -{ +void ScreenGrabberChooserRectItem::forwardHandleEvent(QGraphicsItem* watched, QEvent* event) { QGraphicsSceneMouseEvent* mouseEvent = static_cast(event); QPoint multiplier = getHandleMultiplier(watched); - if (multiplier.isNull()) - return; + if (multiplier.isNull()) return; switch (event->type()) { - case QEvent::GraphicsSceneMousePress: - return mousePressHandle(multiplier.x(), multiplier.y(), mouseEvent); - case QEvent::GraphicsSceneMouseMove: - return mouseMoveHandle(multiplier.x(), multiplier.y(), mouseEvent); - case QEvent::GraphicsSceneMouseRelease: - return mouseReleaseHandle(multiplier.x(), multiplier.y(), mouseEvent); - default: - return; + case QEvent::GraphicsSceneMousePress: + return mousePressHandle(multiplier.x(), multiplier.y(), mouseEvent); + case QEvent::GraphicsSceneMouseMove: + return mouseMoveHandle(multiplier.x(), multiplier.y(), mouseEvent); + case QEvent::GraphicsSceneMouseRelease: + return mouseReleaseHandle(multiplier.x(), multiplier.y(), mouseEvent); + default: + return; } } diff --git a/src/UI/tool/screengrabberchooserrectitem.h b/src/UI/tool/screengrabberchooserrectitem.h index 5ef97b11..c20ab47e 100644 --- a/src/UI/tool/screengrabberchooserrectitem.h +++ b/src/UI/tool/screengrabberchooserrectitem.h @@ -15,8 +15,7 @@ #include -class ScreenGrabberChooserRectItem final : public QObject, public QGraphicsItemGroup -{ +class ScreenGrabberChooserRectItem final : public QObject, public QGraphicsItemGroup { Q_OBJECT public: explicit ScreenGrabberChooserRectItem(QGraphicsScene* scene); @@ -39,8 +38,7 @@ class ScreenGrabberChooserRectItem final : public QObject, public QGraphicsItemG virtual bool sceneEventFilter(QGraphicsItem* watched, QEvent* event) final override; private: - enum State - { + enum State { None, Resizing, HandleResizing, @@ -80,5 +78,4 @@ class ScreenGrabberChooserRectItem final : public QObject, public QGraphicsItemG QGraphicsRectItem* leftCenter; }; - -#endif // SCREENGRABBERCHOOSERRECTITEM_HPP +#endif // SCREENGRABBERCHOOSERRECTITEM_HPP diff --git a/src/UI/tool/screengrabberoverlayitem.cpp b/src/UI/tool/screengrabberoverlayitem.cpp index 8c4b6593..3fddfc2e 100644 --- a/src/UI/tool/screengrabberoverlayitem.cpp +++ b/src/UI/tool/screengrabberoverlayitem.cpp @@ -20,35 +20,27 @@ #include "screenshotgrabber.h" ScreenGrabberOverlayItem::ScreenGrabberOverlayItem(ScreenshotGrabber* grabber) - : screnshootGrabber(grabber) -{ - - QBrush overlayBrush(QColor(0x00, 0x00, 0x00, 0x70)); // Translucent black + : screnshootGrabber(grabber) { + QBrush overlayBrush(QColor(0x00, 0x00, 0x00, 0x70)); // Translucent black setCursor(QCursor(Qt::CrossCursor)); setBrush(overlayBrush); setPen(QPen(Qt::NoPen)); } -ScreenGrabberOverlayItem::~ScreenGrabberOverlayItem() -{ -} +ScreenGrabberOverlayItem::~ScreenGrabberOverlayItem() {} -void ScreenGrabberOverlayItem::setChosenRect(QRect rect) -{ +void ScreenGrabberOverlayItem::setChosenRect(QRect rect) { QRect oldRect = chosenRect; chosenRect = rect; update(oldRect.united(rect)); } -void ScreenGrabberOverlayItem::mousePressEvent(QGraphicsSceneMouseEvent* event) -{ - if (event->button() == Qt::LeftButton) - this->screnshootGrabber->beginRectChooser(event); +void ScreenGrabberOverlayItem::mousePressEvent(QGraphicsSceneMouseEvent* event) { + if (event->button() == Qt::LeftButton) this->screnshootGrabber->beginRectChooser(event); } -void ScreenGrabberOverlayItem::paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*) -{ +void ScreenGrabberOverlayItem::paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*) { painter->setBrush(brush()); painter->setPen(pen()); @@ -58,9 +50,9 @@ void ScreenGrabberOverlayItem::paint(QPainter* painter, const QStyleOptionGraphi qreal topY = chosenRect.y(); qreal bottomY = chosenRect.y() + chosenRect.height(); - painter->drawRect(0, 0, leftX, self.height()); // Left of chosen - painter->drawRect(rightX, 0, self.width() - rightX, self.height()); // Right of chosen - painter->drawRect(leftX, 0, chosenRect.width(), topY); // Top of chosen + painter->drawRect(0, 0, leftX, self.height()); // Left of chosen + painter->drawRect(rightX, 0, self.width() - rightX, self.height()); // Right of chosen + painter->drawRect(leftX, 0, chosenRect.width(), topY); // Top of chosen painter->drawRect(leftX, bottomY, chosenRect.width(), - self.height() - bottomY); // Bottom of chosen + self.height() - bottomY); // Bottom of chosen } diff --git a/src/UI/tool/screengrabberoverlayitem.h b/src/UI/tool/screengrabberoverlayitem.h index 959be73e..a54b8e38 100644 --- a/src/UI/tool/screengrabberoverlayitem.h +++ b/src/UI/tool/screengrabberoverlayitem.h @@ -17,8 +17,7 @@ class ScreenshotGrabber; -class ScreenGrabberOverlayItem final : public QObject, public QGraphicsRectItem -{ +class ScreenGrabberOverlayItem final : public QObject, public QGraphicsRectItem { Q_OBJECT public: explicit ScreenGrabberOverlayItem(ScreenshotGrabber* grabber); @@ -37,4 +36,4 @@ class ScreenGrabberOverlayItem final : public QObject, public QGraphicsRectItem QRect chosenRect; }; -#endif // SCREENGRABBEROVERLAYITEM_HPP +#endif // SCREENGRABBEROVERLAYITEM_HPP diff --git a/src/UI/tool/screenshotgrabber.cpp b/src/UI/tool/screenshotgrabber.cpp index adc3a384..ca375a0a 100644 --- a/src/UI/tool/screenshotgrabber.cpp +++ b/src/UI/tool/screenshotgrabber.cpp @@ -29,12 +29,8 @@ // #include "UI/widget/im/widget.h" ScreenshotGrabber::ScreenshotGrabber() - : QObject() - , mKeysBlocked(false) - , scene(nullptr) - , mQToxVisible(true) -{ - window = new QGraphicsView(scene); // Top-level widget + : QObject(), mKeysBlocked(false), scene(nullptr), mQToxVisible(true) { + window = new QGraphicsView(scene); // Top-level widget window->setWindowFlags(Qt::FramelessWindowHint | Qt::BypassWindowManagerHint); window->setContentsMargins(0, 0, 0, 0); window->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); @@ -46,30 +42,25 @@ ScreenshotGrabber::ScreenshotGrabber() setupScene(); } -void ScreenshotGrabber::reInit() -{ +void ScreenshotGrabber::reInit() { window->resetCachedContent(); setupScene(); showGrabber(); mKeysBlocked = false; } -ScreenshotGrabber::~ScreenshotGrabber() -{ +ScreenshotGrabber::~ScreenshotGrabber() { delete scene; delete window; } -bool ScreenshotGrabber::eventFilter(QObject* object, QEvent* event) -{ - if (event->type() == QEvent::KeyPress) - return handleKeyPress(static_cast(event)); +bool ScreenshotGrabber::eventFilter(QObject* object, QEvent* event) { + if (event->type() == QEvent::KeyPress) return handleKeyPress(static_cast(event)); return QObject::eventFilter(object, event); } -void ScreenshotGrabber::showGrabber() -{ +void ScreenshotGrabber::showGrabber() { this->screenGrab = grabScreen(); this->screenGrabDisplay->setPixmap(this->screenGrab); this->window->show(); @@ -86,10 +77,8 @@ void ScreenshotGrabber::showGrabber() adjustTooltipPosition(); } -bool ScreenshotGrabber::handleKeyPress(QKeyEvent* event) -{ - if (mKeysBlocked) - return false; +bool ScreenshotGrabber::handleKeyPress(QKeyEvent* event) { + if (mKeysBlocked) return false; if (event->key() == Qt::Key_Escape) reject(); @@ -111,11 +100,9 @@ bool ScreenshotGrabber::handleKeyPress(QKeyEvent* event) return true; } -void ScreenshotGrabber::acceptRegion() -{ +void ScreenshotGrabber::acceptRegion() { QRect rect = this->chooserRect->chosenRect(); - if (rect.width() < 1 || rect.height() < 1) - return; + if (rect.width() < 1 || rect.height() < 1) return; // Scale the accepted region from DIPs to actual pixels rect.setRect(rect.x() * pixRatio, rect.y() * pixRatio, rect.width() * pixRatio, @@ -130,8 +117,7 @@ void ScreenshotGrabber::acceptRegion() deleteLater(); } -void ScreenshotGrabber::setupScene() -{ +void ScreenshotGrabber::setupScene() { delete scene; scene = new QGraphicsScene; window->setScene(scene); @@ -158,31 +144,28 @@ void ScreenshotGrabber::setupScene() &ScreenGrabberOverlayItem::setChosenRect); } -void ScreenshotGrabber::useNothingSelectedTooltip() -{ +void ScreenshotGrabber::useNothingSelectedTooltip() { helperTooltip->setHtml( - tr("Click and drag to select a region. Press %1 to " - "hide/show qTox window, or %2 to cancel.", - "Help text shown when no region has been selected yet") - .arg(QString("%1").arg(tr("Space", "[Space] key on the keyboard")), - QString("%1").arg(tr("Escape", "[Escape] key on the keyboard")))); + tr("Click and drag to select a region. Press %1 to " + "hide/show qTox window, or %2 to cancel.", + "Help text shown when no region has been selected yet") + .arg(QString("%1").arg(tr("Space", "[Space] key on the keyboard")), + QString("%1").arg(tr("Escape", "[Escape] key on the keyboard")))); adjustTooltipPosition(); } -void ScreenshotGrabber::useRegionSelectedTooltip() -{ +void ScreenshotGrabber::useRegionSelectedTooltip() { helperTooltip->setHtml( - tr("Press %1 to send a screenshot of the selection, " - "%2 to hide/show qTox window, or %3 to cancel.", - "Help text shown when a region has been selected") - .arg(QString("%1").arg(tr("Enter", "[Enter] key on the keyboard")), - QString("%1").arg(tr("Space", "[Space] key on the keyboard")), - QString("%1").arg(tr("Escape", "[Escape] key on the keyboard")))); + tr("Press %1 to send a screenshot of the selection, " + "%2 to hide/show qTox window, or %3 to cancel.", + "Help text shown when a region has been selected") + .arg(QString("%1").arg(tr("Enter", "[Enter] key on the keyboard")), + QString("%1").arg(tr("Space", "[Space] key on the keyboard")), + QString("%1").arg(tr("Escape", "[Escape] key on the keyboard")))); adjustTooltipPosition(); } -void ScreenshotGrabber::chooseHelperTooltipText(QRect rect) -{ +void ScreenshotGrabber::chooseHelperTooltipText(QRect rect) { if (rect.size().isNull()) useNothingSelectedTooltip(); else @@ -193,8 +176,7 @@ void ScreenshotGrabber::chooseHelperTooltipText(QRect rect) * @internal * @brief Align the tooltip centered at top of screen with the mouse cursor. */ -void ScreenshotGrabber::adjustTooltipPosition() -{ +void ScreenshotGrabber::adjustTooltipPosition() { QRect recGL = QGuiApplication::primaryScreen()->virtualGeometry(); #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) const auto rec = QGuiApplication::screenAt(QCursor::pos())->geometry(); @@ -209,14 +191,12 @@ void ScreenshotGrabber::adjustTooltipPosition() helperToolbox->setY(y); } -void ScreenshotGrabber::reject() -{ +void ScreenshotGrabber::reject() { restoreHiddenWindows(); deleteLater(); } -QPixmap ScreenshotGrabber::grabScreen() -{ +QPixmap ScreenshotGrabber::grabScreen() { QScreen* screen = QGuiApplication::primaryScreen(); QRect rec = screen->virtualGeometry(); @@ -225,8 +205,7 @@ QPixmap ScreenshotGrabber::grabScreen() rec.y() * pixRatio, rec.width() * pixRatio, rec.height() * pixRatio); } -void ScreenshotGrabber::hideVisibleWindows() -{ +void ScreenshotGrabber::hideVisibleWindows() { foreach (QWidget* w, qApp->topLevelWidgets()) { if (w != window && w->isVisible()) { mHiddenWindows << w; @@ -237,19 +216,16 @@ void ScreenshotGrabber::hideVisibleWindows() mQToxVisible = false; } -void ScreenshotGrabber::restoreHiddenWindows() -{ +void ScreenshotGrabber::restoreHiddenWindows() { foreach (QWidget* w, mHiddenWindows) { - if (w) - w->setVisible(true); + if (w) w->setVisible(true); } mHiddenWindows.clear(); mQToxVisible = true; } -void ScreenshotGrabber::beginRectChooser(QGraphicsSceneMouseEvent* event) -{ +void ScreenshotGrabber::beginRectChooser(QGraphicsSceneMouseEvent* event) { QPointF pos = event->scenePos(); this->chooserRect->setX(pos.x()); this->chooserRect->setY(pos.y()); diff --git a/src/UI/tool/screenshotgrabber.h b/src/UI/tool/screenshotgrabber.h index ecd38e65..3e5ad9cb 100644 --- a/src/UI/tool/screenshotgrabber.h +++ b/src/UI/tool/screenshotgrabber.h @@ -27,8 +27,7 @@ class ScreenGrabberChooserRectItem; class ScreenGrabberOverlayItem; class ToolBoxGraphicsItem; -class ScreenshotGrabber : public QObject -{ +class ScreenshotGrabber : public QObject { Q_OBJECT public: ScreenshotGrabber(); @@ -84,5 +83,4 @@ public slots: QVector> mHiddenWindows; }; - -#endif // SCREENSHOTGRABBER_H +#endif // SCREENSHOTGRABBER_H diff --git a/src/UI/tool/toolboxgraphicsitem.cpp b/src/UI/tool/toolboxgraphicsitem.cpp index 6619527e..a6105c16 100644 --- a/src/UI/tool/toolboxgraphicsitem.cpp +++ b/src/UI/tool/toolboxgraphicsitem.cpp @@ -14,8 +14,7 @@ #include -ToolBoxGraphicsItem::ToolBoxGraphicsItem() -{ +ToolBoxGraphicsItem::ToolBoxGraphicsItem() { this->opacityAnimation = new QPropertyAnimation(this, QByteArrayLiteral("opacity"), this); this->opacityAnimation->setKeyValueAt(0, this->idleOpacity); @@ -25,31 +24,25 @@ ToolBoxGraphicsItem::ToolBoxGraphicsItem() setOpacity(this->activeOpacity); } -ToolBoxGraphicsItem::~ToolBoxGraphicsItem() -{ -} +ToolBoxGraphicsItem::~ToolBoxGraphicsItem() {} -void ToolBoxGraphicsItem::hoverEnterEvent(QGraphicsSceneHoverEvent* event) -{ +void ToolBoxGraphicsItem::hoverEnterEvent(QGraphicsSceneHoverEvent* event) { startAnimation(QAbstractAnimation::Backward); QGraphicsItemGroup::hoverEnterEvent(event); } -void ToolBoxGraphicsItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* event) -{ +void ToolBoxGraphicsItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* event) { startAnimation(QAbstractAnimation::Forward); QGraphicsItemGroup::hoverLeaveEvent(event); } -void ToolBoxGraphicsItem::startAnimation(QAbstractAnimation::Direction direction) -{ +void ToolBoxGraphicsItem::startAnimation(QAbstractAnimation::Direction direction) { this->opacityAnimation->setDirection(direction); this->opacityAnimation->start(); } void ToolBoxGraphicsItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, - QWidget* widget) -{ + QWidget* widget) { painter->save(); painter->setPen(Qt::NoPen); painter->setBrush(QBrush(QColor(0xFF, 0xE2, 0x82))); diff --git a/src/UI/tool/toolboxgraphicsitem.h b/src/UI/tool/toolboxgraphicsitem.h index 087cf8c2..baaa2e64 100644 --- a/src/UI/tool/toolboxgraphicsitem.h +++ b/src/UI/tool/toolboxgraphicsitem.h @@ -17,8 +17,7 @@ #include #include -class ToolBoxGraphicsItem final : public QObject, public QGraphicsItemGroup -{ +class ToolBoxGraphicsItem final : public QObject, public QGraphicsItemGroup { Q_OBJECT Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity) public: @@ -41,4 +40,4 @@ class ToolBoxGraphicsItem final : public QObject, public QGraphicsItemGroup int fadeTimeMs = 300; }; -#endif // TOOLBOXGRAPHICSITEM_HPP +#endif // TOOLBOXGRAPHICSITEM_HPP diff --git a/src/UI/tool/verticalonlyscroller.cpp b/src/UI/tool/verticalonlyscroller.cpp index cfe8eda7..5f2cd5c8 100644 --- a/src/UI/tool/verticalonlyscroller.cpp +++ b/src/UI/tool/verticalonlyscroller.cpp @@ -15,21 +15,14 @@ #include "verticalonlyscroller.h" -VerticalOnlyScroller::VerticalOnlyScroller(QWidget* parent) - : QScrollArea(parent) -{ -} +VerticalOnlyScroller::VerticalOnlyScroller(QWidget* parent) : QScrollArea(parent) {} -void VerticalOnlyScroller::resizeEvent(QResizeEvent* event) -{ +void VerticalOnlyScroller::resizeEvent(QResizeEvent* event) { QScrollArea::resizeEvent(event); - if (widget()) - widget()->setMaximumWidth(event->size().width()); + if (widget()) widget()->setMaximumWidth(event->size().width()); } -void VerticalOnlyScroller::showEvent(QShowEvent* event) -{ +void VerticalOnlyScroller::showEvent(QShowEvent* event) { QScrollArea::showEvent(event); - if (widget()) - widget()->setMaximumWidth(size().width()); + if (widget()) widget()->setMaximumWidth(size().width()); } diff --git a/src/UI/tool/verticalonlyscroller.h b/src/UI/tool/verticalonlyscroller.h index 8237428e..26c59f5d 100644 --- a/src/UI/tool/verticalonlyscroller.h +++ b/src/UI/tool/verticalonlyscroller.h @@ -18,8 +18,7 @@ class QResizeEvent; class QShowEvent; -class VerticalOnlyScroller : public QScrollArea -{ +class VerticalOnlyScroller : public QScrollArea { Q_OBJECT public: explicit VerticalOnlyScroller(QWidget* parent = nullptr); @@ -29,4 +28,4 @@ class VerticalOnlyScroller : public QScrollArea virtual void showEvent(QShowEvent* event) final override; }; -#endif // VERTICALONLYSCROLLER_H +#endif // VERTICALONLYSCROLLER_H diff --git a/src/UI/widget/GenericForm.cpp b/src/UI/widget/GenericForm.cpp index 92655455..d55d3e1e 100644 --- a/src/UI/widget/GenericForm.cpp +++ b/src/UI/widget/GenericForm.cpp @@ -17,7 +17,7 @@ #include #include -namespace UI{ +namespace UI { /** * @class GenericForm * @@ -25,16 +25,9 @@ namespace UI{ * It provides correct behaviour of controls for settings forms. */ -GenericForm::GenericForm(const QPixmap& icon, QWidget* parent) - : QWidget(parent), formIcon(icon) -{ -} - -QPixmap GenericForm::getFormIcon() -{ - return formIcon; -} +GenericForm::GenericForm(const QPixmap& icon, QWidget* parent) : QWidget(parent), formIcon(icon) {} +QPixmap GenericForm::getFormIcon() { return formIcon; } /** * @brief Prevent stealing mouse wheel scroll. @@ -44,8 +37,7 @@ QPixmap GenericForm::getFormIcon() * theme / skin / icons etc. * @see GenericForm::eventFilter(QObject *o, QEvent *e) at the bottom of this file for more */ -void GenericForm::eventsInit() -{ +void GenericForm::eventsInit() { for (QComboBox* cb : findChildren()) { cb->installEventFilter(this); cb->setFocusPolicy(Qt::StrongFocus); @@ -56,7 +48,8 @@ void GenericForm::eventsInit() sp->setFocusPolicy(Qt::WheelFocus); } - for (QCheckBox* cb : findChildren()) // this one is to allow scrolling on checkboxes + for (QCheckBox* cb : + findChildren()) // this one is to allow scrolling on checkboxes cb->installEventFilter(this); } @@ -66,18 +59,15 @@ void GenericForm::eventsInit() * @param e Event object. * @return True to stop it being handled further, false otherwise. */ -bool GenericForm::eventFilter(QObject* o, QEvent* e) -{ - if ((e->type() == QEvent::Wheel) - && (qobject_cast(o) || qobject_cast(o) - || qobject_cast(o))) { +bool GenericForm::eventFilter(QObject* o, QEvent* e) { + if ((e->type() == QEvent::Wheel) && + (qobject_cast(o) || qobject_cast(o) || + qobject_cast(o))) { e->ignore(); return true; } return QWidget::eventFilter(o, e); } -GenericForm::~GenericForm() { - -} -} +GenericForm::~GenericForm() {} +} // namespace UI diff --git a/src/UI/widget/GenericForm.h b/src/UI/widget/GenericForm.h index f2e4ad18..d43e1cf7 100644 --- a/src/UI/widget/GenericForm.h +++ b/src/UI/widget/GenericForm.h @@ -9,7 +9,7 @@ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * See the Mulan PubL v2 for more details. */ -#pragma once +#pragma once #include @@ -19,20 +19,20 @@ namespace UI { * 代表模块内标签页(一个模块内子标签页) */ class GenericForm : public QWidget { - Q_OBJECT + Q_OBJECT public: - explicit GenericForm(const QPixmap &icon, QWidget *parent = nullptr); - ~GenericForm() ; + explicit GenericForm(const QPixmap& icon, QWidget* parent = nullptr); + ~GenericForm(); - virtual QString getFormName() = 0; - QPixmap getFormIcon(); - virtual void retranslateUi() = 0; + virtual QString getFormName() = 0; + QPixmap getFormIcon(); + virtual void retranslateUi() = 0; protected: - bool eventFilter(QObject *o, QEvent *e) final override; - void eventsInit(); + bool eventFilter(QObject* o, QEvent* e) final override; + void eventsInit(); protected: - QPixmap formIcon; + QPixmap formIcon; }; -} // namespace UI +} // namespace UI diff --git a/src/UI/widget/MoveableBar.cpp b/src/UI/widget/MoveableBar.cpp index c9b056e9..c0f22930 100644 --- a/src/UI/widget/MoveableBar.cpp +++ b/src/UI/widget/MoveableBar.cpp @@ -17,46 +17,43 @@ namespace UI { - -MoveableBar::MoveableBar(QWidget *parent) - : QWidget(parent), _moveable(true), m_target(nullptr) {} +MoveableBar::MoveableBar(QWidget* parent) : QWidget(parent), _moveable(true), m_target(nullptr) {} MoveableBar::~MoveableBar() {} -void MoveableBar::mousePressEvent(QMouseEvent *event) { - if (_moveable) { - m_isPressed = true; - m_startMovePos = event->globalPos(); - } - return QWidget::mousePressEvent(event); +void MoveableBar::mousePressEvent(QMouseEvent* event) { + if (_moveable) { + m_isPressed = true; + m_startMovePos = event->globalPos(); + } + return QWidget::mousePressEvent(event); } -void MoveableBar::mouseMoveEvent(QMouseEvent *event) { - if (m_isPressed) { - QWidget *p = m_target; +void MoveableBar::mouseMoveEvent(QMouseEvent* event) { + if (m_isPressed) { + QWidget* p = m_target; - if (!p) { - p = this->parentWidget(); - } + if (!p) { + p = this->parentWidget(); + } - if (p) { - QPoint movePoint = event->globalPos() - m_startMovePos; - QPoint widgetPos = p->pos() + movePoint; - m_startMovePos = event->globalPos(); - p->move(widgetPos.x(), widgetPos.y()); + if (p) { + QPoint movePoint = event->globalPos() - m_startMovePos; + QPoint widgetPos = p->pos() + movePoint; + m_startMovePos = event->globalPos(); + p->move(widgetPos.x(), widgetPos.y()); + } } - } - return QWidget::mouseMoveEvent(event); + return QWidget::mouseMoveEvent(event); } -void MoveableBar::mouseReleaseEvent(QMouseEvent *event) { - m_isPressed = false; - return QWidget::mouseReleaseEvent(event); +void MoveableBar::mouseReleaseEvent(QMouseEvent* event) { + m_isPressed = false; + return QWidget::mouseReleaseEvent(event); } -void MoveableBar::setTarget(QWidget *target) { m_target = target; } +void MoveableBar::setTarget(QWidget* target) { m_target = target; } void MoveableBar::setMoveable(bool moveable) { _moveable = moveable; } - -} // namespace UI +} // namespace UI diff --git a/src/UI/widget/MoveableBar.h b/src/UI/widget/MoveableBar.h index 08596f42..2a9782c8 100644 --- a/src/UI/widget/MoveableBar.h +++ b/src/UI/widget/MoveableBar.h @@ -16,29 +16,28 @@ namespace UI { - class MoveableBar : public QWidget { - Q_OBJECT + Q_OBJECT public: - MoveableBar(QWidget *parent = nullptr); - ~MoveableBar(); + MoveableBar(QWidget* parent = nullptr); + ~MoveableBar(); - void setMoveable(bool); - virtual void setTarget(QWidget *); + void setMoveable(bool); + virtual void setTarget(QWidget*); protected: - bool _moveable; + bool _moveable; - QWidget *m_target; + QWidget* m_target; - virtual void mousePressEvent(QMouseEvent *); - virtual void mouseMoveEvent(QMouseEvent *); - virtual void mouseReleaseEvent(QMouseEvent *); + virtual void mousePressEvent(QMouseEvent*); + virtual void mouseMoveEvent(QMouseEvent*); + virtual void mouseReleaseEvent(QMouseEvent*); private: - bool m_isPressed = false; - QPoint m_startMovePos; + bool m_isPressed = false; + QPoint m_startMovePos; }; -} // namespace UI +} // namespace UI diff --git a/src/UI/widget/OMenuWidget.cpp b/src/UI/widget/OMenuWidget.cpp index 61db861f..739ac6dd 100644 --- a/src/UI/widget/OMenuWidget.cpp +++ b/src/UI/widget/OMenuWidget.cpp @@ -4,10 +4,10 @@ * You can use this software according to the terms and conditions of the Mulan * PubL v2. You may obtain a copy of Mulan PubL v2 at: * http://license.coscl.org.cn/MulanPubL-2.0 - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, - * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, - * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * See the Mulan PubL v2 for more details. + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY + * KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO + * NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the + * Mulan PubL v2 for more details. */ // @@ -16,11 +16,14 @@ #include "OMenuWidget.h" -namespace UI{ -OMenuWidget::OMenuWidget(QWidget *parent): QFrame(parent){ +#include "modules/module.h" -} -OMenuWidget::~OMenuWidget(){ +namespace UI { + +OMenuWidget::OMenuWidget(QWidget* parent) + : QFrame(parent) { } -} \ No newline at end of file + +OMenuWidget::~OMenuWidget() {} +} // namespace UI \ No newline at end of file diff --git a/src/UI/widget/OMenuWidget.h b/src/UI/widget/OMenuWidget.h index 007558bc..7a7def87 100644 --- a/src/UI/widget/OMenuWidget.h +++ b/src/UI/widget/OMenuWidget.h @@ -4,10 +4,10 @@ * You can use this software according to the terms and conditions of the Mulan * PubL v2. You may obtain a copy of Mulan PubL v2 at: * http://license.coscl.org.cn/MulanPubL-2.0 - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, - * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, - * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * See the Mulan PubL v2 for more details. + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY + * KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO + * NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the + * Mulan PubL v2 for more details. */ // @@ -18,15 +18,28 @@ #include +class Module; + namespace UI { + /** * 代表一个菜单控件(左侧一级业务功能),内部维护菜单内所有关联(模块、页面集) */ class OMenuWidget : public QFrame { - Q_OBJECT + Q_OBJECT public: - explicit OMenuWidget(QWidget *parent = nullptr); - ~OMenuWidget(); -}; -} // namespace UI + explicit OMenuWidget(QWidget* parent = nullptr); + ~OMenuWidget(); + void setModule(Module* module_){ + module = module_; + } + + Module* getModule()const{ + return module; + } + +private: + Module* module; +}; +} // namespace UI diff --git a/src/UI/widget/OWidget.cpp b/src/UI/widget/OWidget.cpp index 146f6cd1..70ecfa95 100644 --- a/src/UI/widget/OWidget.cpp +++ b/src/UI/widget/OWidget.cpp @@ -11,44 +11,35 @@ */ #include "OWidget.h" -#include +#include +#include #include #include -#include -#include +#include namespace UI { -OWidget::OWidget(QWidget *parent): QWidget(parent) -{ -// QPalette palette = this->palette(); - -// QBrush brush; -// brush.setColor(QColor(83,83,83, 20)); -// palette.setBrush(QPalette::Background, brush); +OWidget::OWidget(QWidget* parent) : QWidget(parent) { + // QPalette palette = this->palette(); -// setPalette(palette); -// setAutoFillBackground(true); + // QBrush brush; + // brush.setColor(QColor(83,83,83, 20)); + // palette.setBrush(QPalette::Background, brush); -// setAttribute(Qt::WA_TranslucentBackground); //设置窗口透明 + // setPalette(palette); + // setAutoFillBackground(true); + // setAttribute(Qt::WA_TranslucentBackground); //设置窗口透明 + // QGraphicsDropShadowEffect *effect = new QGraphicsDropShadowEffect; + // effect->setOffset(4,4); + // effect->setColor(QColor(0,0,0,50)); + // effect->setBlurRadius(10); - - -// QGraphicsDropShadowEffect *effect = new QGraphicsDropShadowEffect; -// effect->setOffset(4,4); -// effect->setColor(QColor(0,0,0,50)); -// effect->setBlurRadius(10); - -// setGraphicsEffect(effect); + // setGraphicsEffect(effect); } -void OWidget::paintEvent(QPaintEvent *event) -{ - -} +void OWidget::paintEvent(QPaintEvent* event) {} OWidget::~OWidget() {} -} - +} // namespace UI diff --git a/src/UI/widget/OWidget.h b/src/UI/widget/OWidget.h index 96f8b121..03bf5e41 100644 --- a/src/UI/widget/OWidget.h +++ b/src/UI/widget/OWidget.h @@ -19,14 +19,14 @@ namespace UI { class OWidget : public QWidget { - Q_OBJECT + Q_OBJECT public: - OWidget(QWidget *parent = nullptr); - virtual ~OWidget() override; + OWidget(QWidget* parent = nullptr); + virtual ~OWidget() override; protected: - virtual void paintEvent(QPaintEvent *event) override; + virtual void paintEvent(QPaintEvent* event) override; private: }; -} // namespace UI +} // namespace UI diff --git a/src/UI/widget/OWindow.cpp b/src/UI/widget/OWindow.cpp index 14e80dbb..d4de52d0 100644 --- a/src/UI/widget/OWindow.cpp +++ b/src/UI/widget/OWindow.cpp @@ -15,11 +15,7 @@ namespace UI { namespace window { -OWindow::OWindow(QWidget *parent, Qt::WindowFlags f): - QDialog(parent, f) -{ +OWindow::OWindow(QWidget* parent, Qt::WindowFlags f) : QDialog(parent, f) {} -} - -} -} +} // namespace window +} // namespace UI diff --git a/src/UI/widget/OWindow.h b/src/UI/widget/OWindow.h index f887c1d6..56a687ab 100644 --- a/src/UI/widget/OWindow.h +++ b/src/UI/widget/OWindow.h @@ -15,20 +15,16 @@ #include - namespace UI { namespace window { - -class OWindow : public QDialog -{ +class OWindow : public QDialog { public: - explicit OWindow(QWidget *parent = nullptr, - Qt::WindowFlags f = Qt::FramelessWindowHint|Qt::WindowSystemMenuHint); - virtual ~OWindow() override{} + explicit OWindow(QWidget* parent = nullptr, + Qt::WindowFlags f = Qt::FramelessWindowHint | Qt::WindowSystemMenuHint); + virtual ~OWindow() override {} }; - -} -} -#endif // OWINDOW_H +} // namespace window +} // namespace UI +#endif // OWINDOW_H diff --git a/src/UI/widget/tool/croppinglabel.cpp b/src/UI/widget/tool/croppinglabel.cpp index 5bdf0167..5c398853 100644 --- a/src/UI/widget/tool/croppinglabel.cpp +++ b/src/UI/widget/tool/croppinglabel.cpp @@ -17,23 +17,15 @@ #include CroppingLabel::CroppingLabel(QWidget* parent) - : QLabel(parent) - , blockPaintEvents(false) - , editable(false) - , elideMode(Qt::ElideRight) -{ + : QLabel(parent), blockPaintEvents(false), editable(false), elideMode(Qt::ElideRight) { setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - class LineEdit : public QLineEdit - { + class LineEdit : public QLineEdit { public: - explicit LineEdit(QWidget* parent = nullptr) - : QLineEdit(parent) - {} + explicit LineEdit(QWidget* parent = nullptr) : QLineEdit(parent) {} protected: - void keyPressEvent(QKeyEvent* event) override - { + void keyPressEvent(QKeyEvent* event) override { if (event->key() == Qt::Key_Escape) { undo(); clearFocus(); @@ -45,19 +37,18 @@ CroppingLabel::CroppingLabel(QWidget* parent) textEdit = new LineEdit(this); textEdit->hide(); - textEdit->setInputMethodHints(Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText | Qt::ImhPreferLatin); + textEdit->setInputMethodHints(Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText | + Qt::ImhPreferLatin); connect(textEdit, &QLineEdit::editingFinished, this, &CroppingLabel::editingFinished); } -void CroppingLabel::editBegin() -{ +void CroppingLabel::editBegin() { showTextEdit(); textEdit->selectAll(); } -void CroppingLabel::setEditable(bool editable) -{ +void CroppingLabel::setEditable(bool editable) { this->editable = editable; if (editable) @@ -66,38 +57,28 @@ void CroppingLabel::setEditable(bool editable) unsetCursor(); } -void CroppingLabel::setElideMode(Qt::TextElideMode elide) -{ - elideMode = elide; -} +void CroppingLabel::setElideMode(Qt::TextElideMode elide) { elideMode = elide; } -void CroppingLabel::setText(const QString& text) -{ +void CroppingLabel::setText(const QString& text) { origText = text.trimmed(); setElidedText(); } -void CroppingLabel::setPlaceholderText(const QString& text) -{ +void CroppingLabel::setPlaceholderText(const QString& text) { textEdit->setPlaceholderText(text); setElidedText(); } -void CroppingLabel::resizeEvent(QResizeEvent* ev) -{ +void CroppingLabel::resizeEvent(QResizeEvent* ev) { setElidedText(); textEdit->resize(ev->size()); QLabel::resizeEvent(ev); } -QSize CroppingLabel::sizeHint() const -{ - return QSize(0, QLabel::sizeHint().height()); -} +QSize CroppingLabel::sizeHint() const { return QSize(0, QLabel::sizeHint().height()); } -QSize CroppingLabel::minimumSizeHint() const -{ +QSize CroppingLabel::minimumSizeHint() const { #if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)) return QSize(fontMetrics().horizontalAdvance("..."), QLabel::minimumSizeHint().height()); #else @@ -105,18 +86,15 @@ QSize CroppingLabel::minimumSizeHint() const #endif } -void CroppingLabel::mouseReleaseEvent(QMouseEvent* e) -{ - if (editable) - showTextEdit(); +void CroppingLabel::mouseReleaseEvent(QMouseEvent* e) { + if (editable) showTextEdit(); emit clicked(); QLabel::mouseReleaseEvent(e); } -void CroppingLabel::paintEvent(QPaintEvent* paintEvent) -{ +void CroppingLabel::paintEvent(QPaintEvent* paintEvent) { if (blockPaintEvents) { paintEvent->ignore(); return; @@ -124,8 +102,7 @@ void CroppingLabel::paintEvent(QPaintEvent* paintEvent) QLabel::paintEvent(paintEvent); } -void CroppingLabel::setElidedText() -{ +void CroppingLabel::setElidedText() { QString elidedText = fontMetrics().elidedText(origText, elideMode, width()); if (elidedText != origText) setToolTip(Qt::convertFromPlainText(origText, Qt::WhiteSpaceNormal)); @@ -139,14 +116,12 @@ void CroppingLabel::setElidedText() } } -void CroppingLabel::hideTextEdit() -{ +void CroppingLabel::hideTextEdit() { textEdit->hide(); blockPaintEvents = false; } -void CroppingLabel::showTextEdit() -{ +void CroppingLabel::showTextEdit() { blockPaintEvents = true; textEdit->show(); textEdit->setFocus(); @@ -158,29 +133,24 @@ void CroppingLabel::showTextEdit() * @brief Get original full text. * @return The un-cropped text. */ -QString CroppingLabel::fullText() -{ - return origText; -} +QString CroppingLabel::fullText() { return origText; } -void CroppingLabel::minimizeMaximumWidth() -{ +void CroppingLabel::minimizeMaximumWidth() { // This function chooses the smallest possible maximum width. // Text width + padding. Without padding, we'll have elipses. #if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)) - setMaximumWidth(fontMetrics().horizontalAdvance(origText) + fontMetrics().horizontalAdvance("...")); + setMaximumWidth(fontMetrics().horizontalAdvance(origText) + + fontMetrics().horizontalAdvance("...")); #else setMaximumWidth(fontMetrics().width(origText) + fontMetrics().width("...")); #endif } -void CroppingLabel::editingFinished() -{ +void CroppingLabel::editingFinished() { hideTextEdit(); QString newText = textEdit->text().trimmed().remove(QRegExp("[\\t\\n\\v\\f\\r\\x0000]")); - if (origText != newText) - emit editFinished(textEdit->text()); + if (origText != newText) emit editFinished(textEdit->text()); emit editRemoved(); } diff --git a/src/UI/widget/tool/croppinglabel.h b/src/UI/widget/tool/croppinglabel.h index bffdb475..2bb369ba 100644 --- a/src/UI/widget/tool/croppinglabel.h +++ b/src/UI/widget/tool/croppinglabel.h @@ -17,8 +17,7 @@ class QLineEdit; -class CroppingLabel : public QLabel -{ +class CroppingLabel : public QLabel { Q_OBJECT public: explicit CroppingLabel(QWidget* parent = nullptr); @@ -61,4 +60,4 @@ private slots: Qt::TextElideMode elideMode; }; -#endif // CROPPINGLABEL_H +#endif // CROPPINGLABEL_H diff --git a/src/UI/widget/tool/movablewidget.cpp b/src/UI/widget/tool/movablewidget.cpp index 179ab707..399151f8 100644 --- a/src/UI/widget/tool/movablewidget.cpp +++ b/src/UI/widget/tool/movablewidget.cpp @@ -15,239 +15,223 @@ #include #include -MovableWidget::MovableWidget(QWidget *parent) : QWidget(parent) { - setMinimumHeight(64); - setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored)); - actualSize = minimumSize(); - boundaryRect = QRect(0, 0, 0, 0); - setRatio(1.0f); - resize(minimumSize()); - actualPos = QPoint(0, 0); +MovableWidget::MovableWidget(QWidget* parent) : QWidget(parent) { + setMinimumHeight(64); + setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored)); + actualSize = minimumSize(); + boundaryRect = QRect(0, 0, 0, 0); + setRatio(1.0f); + resize(minimumSize()); + actualPos = QPoint(0, 0); } void MovableWidget::resetBoundary(QRect newBoundary) { - boundaryRect = newBoundary; - resize(QSize(round(actualSize.width()), round(actualSize.height()))); + boundaryRect = newBoundary; + resize(QSize(round(actualSize.width()), round(actualSize.height()))); - QPoint moveTo = QPoint(round(actualPos.x()), round(actualPos.y())); - checkBoundary(moveTo); - move(moveTo); - actualPos = moveTo; + QPoint moveTo = QPoint(round(actualPos.x()), round(actualPos.y())); + checkBoundary(moveTo); + move(moveTo); + actualPos = moveTo; } void MovableWidget::setBoundary(QRect newBoundary) { - if (boundaryRect.isNull()) { - boundaryRect = newBoundary; - return; - } + if (boundaryRect.isNull()) { + boundaryRect = newBoundary; + return; + } - float changeX = - newBoundary.width() / static_cast(boundaryRect.width()); - float changeY = - newBoundary.height() / static_cast(boundaryRect.height()); + float changeX = newBoundary.width() / static_cast(boundaryRect.width()); + float changeY = newBoundary.height() / static_cast(boundaryRect.height()); - float percentageX = (x() - boundaryRect.x()) / - static_cast(boundaryRect.width() - width()); - float percentageY = (y() - boundaryRect.y()) / - static_cast(boundaryRect.height() - height()); + float percentageX = + (x() - boundaryRect.x()) / static_cast(boundaryRect.width() - width()); + float percentageY = + (y() - boundaryRect.y()) / static_cast(boundaryRect.height() - height()); - actualSize.setWidth(actualSize.width() * changeX); - actualSize.setHeight(actualSize.height() * changeY); + actualSize.setWidth(actualSize.width() * changeX); + actualSize.setHeight(actualSize.height() * changeY); - if (actualSize.width() == 0) - actualSize.setWidth(1); + if (actualSize.width() == 0) actualSize.setWidth(1); - if (actualSize.height() == 0) - actualSize.setHeight(1); + if (actualSize.height() == 0) actualSize.setHeight(1); - resize(QSize(round(actualSize.width()), round(actualSize.height()))); + resize(QSize(round(actualSize.width()), round(actualSize.height()))); - actualPos = QPointF(percentageX * (newBoundary.width() - width()), - percentageY * (newBoundary.height() - height())); - actualPos += QPointF(newBoundary.topLeft()); + actualPos = QPointF(percentageX * (newBoundary.width() - width()), + percentageY * (newBoundary.height() - height())); + actualPos += QPointF(newBoundary.topLeft()); - QPoint moveTo = QPoint(round(actualPos.x()), round(actualPos.y())); - move(moveTo); + QPoint moveTo = QPoint(round(actualPos.x()), round(actualPos.y())); + move(moveTo); - boundaryRect = newBoundary; + boundaryRect = newBoundary; } float MovableWidget::getRatio() const { return ratio; } void MovableWidget::setRatio(float r) { - ratio = r; - resize(width(), width() / ratio); - QPoint position = QPoint(actualPos.x(), actualPos.y()); - checkBoundary(position); - move(position); - - actualPos = pos(); - actualSize = size(); + ratio = r; + resize(width(), width() / ratio); + QPoint position = QPoint(actualPos.x(), actualPos.y()); + checkBoundary(position); + move(position); + + actualPos = pos(); + actualSize = size(); } -void MovableWidget::mousePressEvent(QMouseEvent *event) { - if (event->buttons() & Qt::LeftButton) { - if (!(mode & Resize)) - mode |= Moving; +void MovableWidget::mousePressEvent(QMouseEvent* event) { + if (event->buttons() & Qt::LeftButton) { + if (!(mode & Resize)) mode |= Moving; - lastPoint = event->globalPos(); - } + lastPoint = event->globalPos(); + } } -void MovableWidget::mouseMoveEvent(QMouseEvent *event) { - if (mode & Moving) { - QPoint moveTo = pos() - (lastPoint - event->globalPos()); - checkBoundary(moveTo); - - move(moveTo); - lastPoint = event->globalPos(); +void MovableWidget::mouseMoveEvent(QMouseEvent* event) { + if (mode & Moving) { + QPoint moveTo = pos() - (lastPoint - event->globalPos()); + checkBoundary(moveTo); - actualPos = pos(); - } else { - if (!(event->buttons() & Qt::LeftButton)) { - if (event->x() < 6) - mode |= ResizeLeft; - else - mode &= ~ResizeLeft; - - if (event->y() < 6) - mode |= ResizeUp; - else - mode &= ~ResizeUp; - - if (event->x() > width() - 6) - mode |= ResizeRight; - else - mode &= ~ResizeRight; - - if (event->y() > height() - 6) - mode |= ResizeDown; - else - mode &= ~ResizeDown; - } + move(moveTo); + lastPoint = event->globalPos(); - if (mode & Resize) { - const Modes ResizeUpRight = ResizeUp | ResizeRight; - const Modes ResizeUpLeft = ResizeUp | ResizeLeft; - const Modes ResizeDownRight = ResizeDown | ResizeRight; - const Modes ResizeDownLeft = ResizeDown | ResizeLeft; - - if ((mode & ResizeUpRight) == ResizeUpRight || - (mode & ResizeDownLeft) == ResizeDownLeft) - setCursor(Qt::SizeBDiagCursor); - else if ((mode & ResizeUpLeft) == ResizeUpLeft || - (mode & ResizeDownRight) == ResizeDownRight) - setCursor(Qt::SizeFDiagCursor); - else if (mode & (ResizeLeft | ResizeRight)) - setCursor(Qt::SizeHorCursor); - else - setCursor(Qt::SizeVerCursor); - - if (event->buttons() & Qt::LeftButton) { - QPoint lastPosition = pos(); - QPoint displacement = lastPoint - event->globalPos(); - QSize lastSize = size(); - - if (mode & ResizeUp) { - lastSize.setHeight(height() + displacement.y()); - - if (lastSize.height() > maximumHeight()) - lastPosition.setY(y() - displacement.y() + - (lastSize.height() - maximumHeight())); - else - lastPosition.setY(y() - displacement.y()); + actualPos = pos(); + } else { + if (!(event->buttons() & Qt::LeftButton)) { + if (event->x() < 6) + mode |= ResizeLeft; + else + mode &= ~ResizeLeft; + + if (event->y() < 6) + mode |= ResizeUp; + else + mode &= ~ResizeUp; + + if (event->x() > width() - 6) + mode |= ResizeRight; + else + mode &= ~ResizeRight; + + if (event->y() > height() - 6) + mode |= ResizeDown; + else + mode &= ~ResizeDown; } - if (mode & ResizeLeft) { - lastSize.setWidth(width() + displacement.x()); - if (lastSize.width() > maximumWidth()) - lastPosition.setX(x() - displacement.x() + - (lastSize.width() - maximumWidth())); - else - lastPosition.setX(x() - displacement.x()); - } + if (mode & Resize) { + const Modes ResizeUpRight = ResizeUp | ResizeRight; + const Modes ResizeUpLeft = ResizeUp | ResizeLeft; + const Modes ResizeDownRight = ResizeDown | ResizeRight; + const Modes ResizeDownLeft = ResizeDown | ResizeLeft; - if (mode & ResizeRight) - lastSize.setWidth(width() - displacement.x()); + if ((mode & ResizeUpRight) == ResizeUpRight || + (mode & ResizeDownLeft) == ResizeDownLeft) + setCursor(Qt::SizeBDiagCursor); + else if ((mode & ResizeUpLeft) == ResizeUpLeft || + (mode & ResizeDownRight) == ResizeDownRight) + setCursor(Qt::SizeFDiagCursor); + else if (mode & (ResizeLeft | ResizeRight)) + setCursor(Qt::SizeHorCursor); + else + setCursor(Qt::SizeVerCursor); - if (mode & ResizeDown) - lastSize.setHeight(height() - displacement.y()); + if (event->buttons() & Qt::LeftButton) { + QPoint lastPosition = pos(); + QPoint displacement = lastPoint - event->globalPos(); + QSize lastSize = size(); - if (lastSize.height() > maximumHeight()) - lastSize.setHeight(maximumHeight()); + if (mode & ResizeUp) { + lastSize.setHeight(height() + displacement.y()); - if (lastSize.width() > maximumWidth()) - lastSize.setWidth(maximumWidth()); + if (lastSize.height() > maximumHeight()) + lastPosition.setY(y() - displacement.y() + + (lastSize.height() - maximumHeight())); + else + lastPosition.setY(y() - displacement.y()); + } - if (mode & (ResizeLeft | ResizeRight)) { - if (mode & (ResizeUp | ResizeDown)) { - int height = lastSize.width() / getRatio(); + if (mode & ResizeLeft) { + lastSize.setWidth(width() + displacement.x()); + if (lastSize.width() > maximumWidth()) + lastPosition.setX(x() - displacement.x() + + (lastSize.width() - maximumWidth())); + else + lastPosition.setX(x() - displacement.x()); + } - if (!(mode & ResizeDown)) - lastPosition.setY(lastPosition.y() - - (height - lastSize.height())); + if (mode & ResizeRight) lastSize.setWidth(width() - displacement.x()); - resize(lastSize.width(), height); + if (mode & ResizeDown) lastSize.setHeight(height() - displacement.y()); - if (lastSize.width() < minimumWidth()) - lastPosition.setX(pos().x()); + if (lastSize.height() > maximumHeight()) lastSize.setHeight(maximumHeight()); - if (height < minimumHeight()) - lastPosition.setY(pos().y()); - } else { - resize(lastSize.width(), lastSize.width() / getRatio()); - } - } else { - resize(lastSize.height() * getRatio(), lastSize.height()); - } + if (lastSize.width() > maximumWidth()) lastSize.setWidth(maximumWidth()); - updateGeometry(); + if (mode & (ResizeLeft | ResizeRight)) { + if (mode & (ResizeUp | ResizeDown)) { + int height = lastSize.width() / getRatio(); - checkBoundary(lastPosition); + if (!(mode & ResizeDown)) + lastPosition.setY(lastPosition.y() - (height - lastSize.height())); - move(lastPosition); + resize(lastSize.width(), height); - lastPoint = event->globalPos(); - actualSize = size(); - actualPos = pos(); - } - } else { - unsetCursor(); + if (lastSize.width() < minimumWidth()) lastPosition.setX(pos().x()); + + if (height < minimumHeight()) lastPosition.setY(pos().y()); + } else { + resize(lastSize.width(), lastSize.width() / getRatio()); + } + } else { + resize(lastSize.height() * getRatio(), lastSize.height()); + } + + updateGeometry(); + + checkBoundary(lastPosition); + + move(lastPosition); + + lastPoint = event->globalPos(); + actualSize = size(); + actualPos = pos(); + } + } else { + unsetCursor(); + } } - } } -void MovableWidget::mouseReleaseEvent(QMouseEvent *event) { - if (!(event->buttons() & Qt::LeftButton)) - mode = 0; +void MovableWidget::mouseReleaseEvent(QMouseEvent* event) { + if (!(event->buttons() & Qt::LeftButton)) mode = 0; } -void MovableWidget::mouseDoubleClickEvent(QMouseEvent *event) { - if (!(event->buttons() & Qt::LeftButton)) - return; - - if (!graphicsEffect()) { - QGraphicsOpacityEffect *opacityEffect = new QGraphicsOpacityEffect(this); - opacityEffect->setOpacity(0.5); - setGraphicsEffect(opacityEffect); - } else { - setGraphicsEffect(nullptr); - } +void MovableWidget::mouseDoubleClickEvent(QMouseEvent* event) { + if (!(event->buttons() & Qt::LeftButton)) return; + + if (!graphicsEffect()) { + QGraphicsOpacityEffect* opacityEffect = new QGraphicsOpacityEffect(this); + opacityEffect->setOpacity(0.5); + setGraphicsEffect(opacityEffect); + } else { + setGraphicsEffect(nullptr); + } } -void MovableWidget::checkBoundary(QPoint &point) const { - int x1, y1, x2, y2; - boundaryRect.getCoords(&x1, &y1, &x2, &y2); +void MovableWidget::checkBoundary(QPoint& point) const { + int x1, y1, x2, y2; + boundaryRect.getCoords(&x1, &y1, &x2, &y2); - if (point.x() < boundaryRect.left()) - point.setX(boundaryRect.left()); + if (point.x() < boundaryRect.left()) point.setX(boundaryRect.left()); - if (point.y() < boundaryRect.top()) - point.setY(boundaryRect.top()); + if (point.y() < boundaryRect.top()) point.setY(boundaryRect.top()); - if (point.x() + width() > boundaryRect.right() + 1) - point.setX(boundaryRect.right() - width() + 1); + if (point.x() + width() > boundaryRect.right() + 1) + point.setX(boundaryRect.right() - width() + 1); - if (point.y() + height() > boundaryRect.bottom() + 1) - point.setY(boundaryRect.bottom() - height() + 1); + if (point.y() + height() > boundaryRect.bottom() + 1) + point.setY(boundaryRect.bottom() - height() + 1); } diff --git a/src/UI/widget/tool/movablewidget.h b/src/UI/widget/tool/movablewidget.h index b1222fbb..501383b5 100644 --- a/src/UI/widget/tool/movablewidget.h +++ b/src/UI/widget/tool/movablewidget.h @@ -15,8 +15,7 @@ #include -class MovableWidget : public QWidget -{ +class MovableWidget : public QWidget { public: explicit MovableWidget(QWidget* parent); void resetBoundary(QRect newBoundary); @@ -36,8 +35,7 @@ class MovableWidget : public QWidget typedef uint8_t Modes; - enum Mode : Modes - { + enum Mode : Modes { Moving = 0x01, ResizeLeft = 0x02, ResizeRight = 0x04, @@ -54,4 +52,4 @@ class MovableWidget : public QWidget float ratio; }; -#endif // MOVABLEWIDGET_H +#endif // MOVABLEWIDGET_H diff --git a/src/UI/window/BaseWindow.cpp b/src/UI/window/BaseWindow.cpp index 9d0fdaaa..2788ee73 100644 --- a/src/UI/window/BaseWindow.cpp +++ b/src/UI/window/BaseWindow.cpp @@ -12,26 +12,20 @@ #include "BaseWindow.h" -#include #include -#include +#include #include -#include #include +#include +#include #include -BaseWindow::BaseWindow(QWidget *parent) : QWidget(parent) -{ - this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinimizeButtonHint); - // setAttribute(Qt::WA_TranslucentBackground); +BaseWindow::BaseWindow(QWidget* parent) : QWidget(parent) { + this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinimizeButtonHint); + // setAttribute(Qt::WA_TranslucentBackground); } -BaseWindow::~BaseWindow() -{ -} +BaseWindow::~BaseWindow() {} -void BaseWindow::paintEvent(QPaintEvent *event) -{ - return QWidget::paintEvent(event); -} +void BaseWindow::paintEvent(QPaintEvent* event) { return QWidget::paintEvent(event); } diff --git a/src/UI/window/BaseWindow.h b/src/UI/window/BaseWindow.h index 176acea4..6e80e76c 100644 --- a/src/UI/window/BaseWindow.h +++ b/src/UI/window/BaseWindow.h @@ -17,18 +17,18 @@ #include class BaseWindow : public QWidget { - Q_OBJECT + Q_OBJECT public: - BaseWindow(QWidget *parent = 0); - ~BaseWindow(); + BaseWindow(QWidget* parent = 0); + ~BaseWindow(); protected: - void paintEvent(QPaintEvent *event); + void paintEvent(QPaintEvent* event); private slots: protected: }; -#endif // BASEWINDOW_H +#endif // BASEWINDOW_H diff --git a/src/UI/window/WindowManager.cpp b/src/UI/window/WindowManager.cpp index bb6d17c4..b1470070 100644 --- a/src/UI/window/WindowManager.cpp +++ b/src/UI/window/WindowManager.cpp @@ -16,62 +16,52 @@ #include #include -#include "base/Page.h" #include "UI/window/main/src/MainWindow.h" +#include "base/Page.h" namespace UI { -WindowManager::WindowManager(QObject *parent) : QObject(parent) { +WindowManager::WindowManager(QObject* parent) : QObject(parent) {} -} +WindowManager::~WindowManager() {} -WindowManager::~WindowManager() { +WindowManager* WindowManager::Instance() { + static WindowManager* instance = nullptr; + if (!instance) { + instance = new WindowManager; + } + return instance; } -WindowManager *WindowManager::Instance() { - static WindowManager *instance = nullptr; - if (!instance) { - instance = new WindowManager; - } - return instance; -} - -QFrame *WindowManager::getPage(PageMenu menu) { - return m_mainWindow->getPage(menu); -} +QFrame* WindowManager::getPage(PageMenu menu) { return m_mainWindow->getPage(menu); } void WindowManager::startMainUI() { - m_mainWindow = std::make_unique(); - - /** - * connect menu's button events. - */ - connect(m_mainWindow.get(), &UI::MainWindow::toClose, // - [&](){ - emit mainClose({ - m_mainWindow->saveGeometry() - }); - } ); + m_mainWindow = std::make_unique(); + /** + * connect menu's button events. + */ + connect(m_mainWindow.get(), &UI::MainWindow::toClose, // + [&]() { emit mainClose({m_mainWindow->saveGeometry()}); }); // 统一注册类型 - qRegisterMetaType("PageMenu"); - connect(m_mainWindow->menu(), &OMainMenu::menuPushed, - [&](PageMenu menu, bool checked) { emit menuPushed(menu, checked); }); - m_mainWindow->show(); + qRegisterMetaType("PageMenu"); + connect(m_mainWindow->menu(), &OMainMenu::menuPushed, + [&](PageMenu menu, bool checked) { emit menuPushed(menu, checked); }); + m_mainWindow->show(); } void WindowManager::stopMainUI() { - m_mainWindow->close(); - m_mainWindow.reset(); + m_mainWindow->close(); + m_mainWindow.reset(); } -QWidget *WindowManager::getContainer(PageMenu menu) { // - return m_mainWindow->getContainer(menu); +QWidget* WindowManager::getContainer(PageMenu menu) { // + return m_mainWindow->getContainer(menu); } -OMainMenu *WindowManager::getMainMenu() { // - return m_mainWindow->menu(); +OMainMenu* WindowManager::getMainMenu() { // + return m_mainWindow->menu(); } -} // namespace UI +} // namespace UI diff --git a/src/UI/window/WindowManager.h b/src/UI/window/WindowManager.h index b51af2a1..6439b41e 100644 --- a/src/UI/window/WindowManager.h +++ b/src/UI/window/WindowManager.h @@ -15,39 +15,38 @@ #include #include -#include "base/Page.h" #include "UI/window/main/src/MainWindow.h" +#include "base/Page.h" #include "modules/module.h" namespace UI { class WindowManager : public QObject { - Q_OBJECT + Q_OBJECT public: - WindowManager(QObject *parent = nullptr); - ~WindowManager(); + WindowManager(QObject* parent = nullptr); + ~WindowManager(); - static WindowManager *Instance(); + static WindowManager* Instance(); - void startMainUI(); - void stopMainUI(); + void startMainUI(); + void stopMainUI(); - void putPage(PageMenu menu, QFrame *p); + void putPage(PageMenu menu, QFrame* p); - QFrame *getPage(PageMenu menu); + QFrame* getPage(PageMenu menu); - inline UI::MainWindow *window() { return m_mainWindow.get(); } + inline UI::MainWindow* window() { return m_mainWindow.get(); } - QWidget *getContainer(PageMenu menu); + QWidget* getContainer(PageMenu menu); - OMainMenu* getMainMenu(); + OMainMenu* getMainMenu(); private: - - std::unique_ptr m_mainWindow; + std::unique_ptr m_mainWindow; signals: - void menuPushed(PageMenu menu, bool checked); - void mainClose(SavedInfo savedInfo); + void menuPushed(PageMenu menu, bool checked); + void mainClose(SavedInfo savedInfo); }; -} // namespace UI +} // namespace UI diff --git a/src/UI/window/config/about/src/aboutform.cpp b/src/UI/window/config/about/src/aboutform.cpp index 3169b6c9..c0180d34 100644 --- a/src/UI/window/config/about/src/aboutform.cpp +++ b/src/UI/window/config/about/src/aboutform.cpp @@ -12,14 +12,14 @@ #include "aboutform.h" -#include "lib/settings/translator.h" -#include "src/UI/widget/GenericForm.h" -#include "src/base/RecursiveSignalBlocker.h" -#include "src/lib/settings/style.h" #include #include #include #include +#include "lib/settings/translator.h" +#include "src/UI/widget/GenericForm.h" +#include "src/base/RecursiveSignalBlocker.h" +#include "src/lib/settings/style.h" #include namespace UI { @@ -37,38 +37,37 @@ enum class updateIndex { available = 0, upToDate = 1, failed = 2 }; /** * @brief Constructor of AboutForm. */ -AboutForm::AboutForm(QWidget *parent) - :GenericForm(QPixmap(":/img/settings/general.png"), parent), - bodyUI(new Ui::AboutSettings), - progressTimer(new QTimer(this)) { - - bodyUI->setupUi(this); - - if (QString(GIT_VERSION).indexOf(" ") > -1) - bodyUI->gitVersion->setOpenExternalLinks(false); - - QString lic = QString("Copyright (c) 2022 **%1 %2**\n\r" - "**%3** is licensed under Mulan PubL v2.\n\r" - "You can use this software according to the terms and conditions of the Mulan PubL v2.\n\r" - "You may obtain a copy of Mulan PubL v2 at:\n\r" - "**http://license.coscl.org.cn/MulanPubL-2.0**\n\r" - " THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS,\n\r" - " WITHOUT WARRANTIES OF ANY KIND,EITHER EXPRESS OR IMPLIED,\n\r" - " INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n\r" - " MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n\r" - " See the Mulan PubL v2 for more details.\n\r") - .arg(ORGANIZATION_NAME) - .arg(ORGANIZATION_DOMAIN) - .arg(APPLICATION_NAME); - - bodyUI->license->setMarkdown(lic); - - // block all child signals during initialization - const RecursiveSignalBlocker signalBlocker(this); - - replaceVersions(); - - settings::Translator::registerHandler(std::bind(&AboutForm::retranslateUi, this), this); +AboutForm::AboutForm(QWidget* parent) + : GenericForm(QPixmap(":/img/settings/general.png"), parent) + , bodyUI(new Ui::AboutSettings) + , progressTimer(new QTimer(this)) { + bodyUI->setupUi(this); + + if (QString(GIT_VERSION).indexOf(" ") > -1) bodyUI->gitVersion->setOpenExternalLinks(false); + + QString lic = QString("Copyright (c) 2022 **%1 %2**\n\r" + "**%3** is licensed under Mulan PubL v2.\n\r" + "You can use this software according to the terms and conditions of the " + "Mulan PubL v2.\n\r" + "You may obtain a copy of Mulan PubL v2 at:\n\r" + "**http://license.coscl.org.cn/MulanPubL-2.0**\n\r" + " THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS,\n\r" + " WITHOUT WARRANTIES OF ANY KIND,EITHER EXPRESS OR IMPLIED,\n\r" + " INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n\r" + " MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n\r" + " See the Mulan PubL v2 for more details.\n\r") + .arg(ORGANIZATION_NAME) + .arg(ORGANIZATION_DOMAIN) + .arg(APPLICATION_NAME); + + bodyUI->license->setMarkdown(lic); + + // block all child signals during initialization + const RecursiveSignalBlocker signalBlocker(this); + + replaceVersions(); + + settings::Translator::registerHandler(std::bind(&AboutForm::retranslateUi, this), this); } /** @@ -78,50 +77,61 @@ AboutForm::AboutForm(QWidget *parent) * It also updates qTox, toxcore and Qt versions. */ void AboutForm::replaceVersions() { - // TODO: When we finally have stable releases: build-in a way to tell - bodyUI->youAreUsing->setText(tr("You are using qTox version %1.").arg(QString(GIT_DESCRIBE))); + // TODO: When we finally have stable releases: build-in a way to tell + bodyUI->youAreUsing->setText(tr("You are using qTox version %1.").arg(QString(GIT_DESCRIBE))); #if UPDATE_CHECK_ENABLED - if (updateCheck != nullptr) { - connect(updateCheck, &UpdateCheck::updateAvailable, this, &AboutForm::onUpdateAvailable); - connect(updateCheck, &UpdateCheck::upToDate, this, &AboutForm::onUpToDate); - connect(updateCheck, &UpdateCheck::updateCheckFailed, this, &AboutForm::onUpdateCheckFailed); - } else { - qWarning() << "AboutForm passed null UpdateCheck!"; - } + if (updateCheck != nullptr) { + connect(updateCheck, &UpdateCheck::updateAvailable, this, &AboutForm::onUpdateAvailable); + connect(updateCheck, &UpdateCheck::upToDate, this, &AboutForm::onUpToDate); + connect(updateCheck, + &UpdateCheck::updateCheckFailed, + this, + &AboutForm::onUpdateCheckFailed); + } else { + qWarning() << "AboutForm passed null UpdateCheck!"; + } #else - qDebug() << "AboutForm not showing updates, qTox built without UPDATE_CHECK"; + qDebug() << "AboutForm not showing updates, qTox built without UPDATE_CHECK"; #endif - QString projectLink = ORGANIZATION_HOME "/" APPLICATION_ALIAS; - QString commitLink = projectLink + "/commit/" + QString(GIT_VERSION); - bodyUI->gitVersion->setText(tr("Commit hash: %1").arg(createLink(commitLink, QString(GIT_VERSION)))); - bodyUI->qtVersion->setText(tr("Qt version: %1").arg(QT_VERSION_STR)); - - QString issueBody = QString("##### Brief Description\n\n" - "OS: %1\n" - "version: %2\n" - "Commit hash: %3\n" - "Qt: %4\n") - .arg(QSysInfo::prettyProductName(), GIT_DESCRIBE, GIT_VERSION, QT_VERSION_STR); - - issueBody.replace("#", "%23").replace(":", "%3A"); - - QString issue = QString("%1").arg(createLink(projectLink + "/issues", "Issues")); - bodyUI->knownIssues->setText(issue); - - QString authorInfo = QString("

%1

").arg(ORGANIZATION_HOME); - bodyUI->authorInfo->setText(authorInfo); + QString projectLink = ORGANIZATION_HOME "/" APPLICATION_ALIAS; + QString commitLink = projectLink + "/commit/" + QString(GIT_VERSION); + bodyUI->gitVersion->setText( + tr("Commit hash: %1").arg(createLink(commitLink, QString(GIT_VERSION)))); + bodyUI->qtVersion->setText(tr("Qt version: %1").arg(QT_VERSION_STR)); + + QString issueBody = + QString("##### Brief Description\n\n" + "OS: %1\n" + "version: %2\n" + "Commit hash: %3\n" + "Qt: %4\n") + .arg(QSysInfo::prettyProductName(), GIT_DESCRIBE, GIT_VERSION, QT_VERSION_STR); + + issueBody.replace("#", "%23").replace(":", "%3A"); + + QString issue = QString("%1").arg(createLink(projectLink + "/issues", "Issues")); + bodyUI->knownIssues->setText(issue); + + QString authorInfo = QString("

%1

").arg(ORGANIZATION_HOME); + bodyUI->authorInfo->setText(authorInfo); } void AboutForm::onUpdateAvailable(QString latestVersion, QUrl link) { - QObject::disconnect(linkConnection); - linkConnection = connect(bodyUI->updateAvailableButton, &QPushButton::clicked, [link]() { QDesktopServices::openUrl(link); }); - bodyUI->updateStack->setCurrentIndex(static_cast(updateIndex::available)); + QObject::disconnect(linkConnection); + linkConnection = connect(bodyUI->updateAvailableButton, &QPushButton::clicked, [link]() { + QDesktopServices::openUrl(link); + }); + bodyUI->updateStack->setCurrentIndex(static_cast(updateIndex::available)); } -void AboutForm::onUpToDate() { bodyUI->updateStack->setCurrentIndex(static_cast(updateIndex::upToDate)); } +void AboutForm::onUpToDate() { + bodyUI->updateStack->setCurrentIndex(static_cast(updateIndex::upToDate)); +} -void AboutForm::onUpdateCheckFailed() { bodyUI->updateStack->setCurrentIndex(static_cast(updateIndex::failed)); } +void AboutForm::onUpdateCheckFailed() { + bodyUI->updateStack->setCurrentIndex(static_cast(updateIndex::failed)); +} /** * @brief Creates hyperlink with specific style. @@ -130,20 +140,22 @@ void AboutForm::onUpdateCheckFailed() { bodyUI->updateStack->setCurrentIndex(sta * @return Hyperlink to paste. */ QString AboutForm::createLink(QString path, QString text) const { - return QString::fromUtf8("%3").arg(path, Style::getColor(Style::Link).name(), text); + return QString::fromUtf8( + "%3") + .arg(path, Style::getColor(Style::Link).name(), text); } AboutForm::~AboutForm() { - settings::Translator::unregister(this); - delete bodyUI; + settings::Translator::unregister(this); + delete bodyUI; } /** * @brief Retranslate all elements in the form. */ void AboutForm::retranslateUi() { - bodyUI->retranslateUi(this); - replaceVersions(); + bodyUI->retranslateUi(this); + replaceVersions(); } -} // namespace UI \ No newline at end of file +} // namespace UI \ No newline at end of file diff --git a/src/UI/window/config/about/src/aboutform.h b/src/UI/window/config/about/src/aboutform.h index 43425f86..77b64af2 100644 --- a/src/UI/window/config/about/src/aboutform.h +++ b/src/UI/window/config/about/src/aboutform.h @@ -18,23 +18,18 @@ #include - class QTimer; class QString; class QLayoutItem; -namespace UI{ +namespace UI { -class AboutForm : public GenericForm -{ +class AboutForm : public GenericForm { Q_OBJECT public: - AboutForm(QWidget *parent= nullptr); + AboutForm(QWidget* parent = nullptr); ~AboutForm(); - virtual QString getFormName() final override - { - return tr("About form"); - } + virtual QString getFormName() final override { return tr("About form"); } public slots: void onUpdateAvailable(QString latestVersion, QUrl link); @@ -52,6 +47,6 @@ public slots: QMetaObject::Connection linkConnection; }; -} +} // namespace UI -#endif // ABOUTFORM_H +#endif // ABOUTFORM_H diff --git a/src/UI/window/config/plugin/src/PluginInfoForm.cpp b/src/UI/window/config/plugin/src/PluginInfoForm.cpp index a2c54a49..da23997f 100644 --- a/src/UI/window/config/plugin/src/PluginInfoForm.cpp +++ b/src/UI/window/config/plugin/src/PluginInfoForm.cpp @@ -12,149 +12,150 @@ #include "PluginInfoForm.h" +#include +#include "base/OkSettings.h" #include "base/files.h" -#include "lib/plugin/pluginhost.h" #include "lib/network/NetworkHttp.h" -#include "base/OkSettings.h" +#include "lib/plugin/pluginhost.h" #include "ui_PluginInfoForm.h" -#include namespace ok { namespace plugin { -inline QString makePath(const QString &id, const QString &name) { - return QString("%1/%2_%3").arg(ok::base::OkSettings::downloadDir().path(), id, name); +inline QString makePath(const QString& id, const QString& name) { + return QString("%1/%2_%3").arg(ok::base::OkSettings::downloadDir().path(), id, name); } -inline QString makePluginPath(const QString &name) { - return QString("%1/%2").arg(ok::base::OkSettings().getAppPluginPath().path(), name); +inline QString makePluginPath(const QString& name) { + return QString("%1/%2").arg(ok::base::OkSettings().getAppPluginPath().path(), name); } -PluginInfoForm::PluginInfoForm(ok::backend::PluginInfo &info, QWidget *parent) - : QWidget(parent), ui(new Ui::PluginInfoForm), - pluginManager(PluginManager::instance()), id(info.id), mPluginInfo(info), - downUrl(info.downUrl), mDownloaded(false), isDownloading(false) { - - ui->setupUi(this); - ui->progressBar->setValue(0); - ui->name->setText(info.name); - ui->version->setText(info.version); - ui->home->setText(info.homeUrl); - ui->intro->setText(info.content); - ui->installBtn->setText(tr("Install")); - ui->installBtn->setCursor(Qt::PointingHandCursor); - ui->progressBar->hide(); - - qDebug() << "Display plugin" << info.shortName; - - if (pluginManager->isAvailable(info.shortName)) { - qDebug()<<"Plugin is available"<pluginDirs()) { - qDebug() << "PluginDir:" << dir; - }; - - connect(this, &PluginInfoForm::downloadFinished, [&](const QString &path) { - QMutexLocker ml{&mMutex}; - http.reset(); - - auto installed = pluginManager->installPlugin(path, mPluginInfo.fileName); - if (installed) - setInstalled(); - }); +PluginInfoForm::PluginInfoForm(ok::backend::PluginInfo& info, QWidget* parent) + : QWidget(parent) + , ui(new Ui::PluginInfoForm) + , pluginManager(PluginManager::instance()) + , id(info.id) + , mPluginInfo(info) + , downUrl(info.downUrl) + , mDownloaded(false) + , isDownloading(false) { + ui->setupUi(this); + ui->progressBar->setValue(0); + ui->name->setText(info.name); + ui->version->setText(info.version); + ui->home->setText(info.homeUrl); + ui->intro->setText(info.content); + ui->installBtn->setText(tr("Install")); + ui->installBtn->setCursor(Qt::PointingHandCursor); + ui->progressBar->hide(); + + qDebug() << "Display plugin" << info.shortName; + + if (pluginManager->isAvailable(info.shortName)) { + qDebug() << "Plugin is available" << info.shortName; + setInstalled(); + } + + for (const auto& dir : pluginManager->pluginDirs()) { + qDebug() << "PluginDir:" << dir; + }; + + connect(this, &PluginInfoForm::downloadFinished, [&](const QString& path) { + QMutexLocker ml{&mMutex}; + http.reset(); + + auto installed = pluginManager->installPlugin(path, mPluginInfo.fileName); + if (installed) setInstalled(); + }); } PluginInfoForm::~PluginInfoForm() { delete ui; } void PluginInfoForm::on_installBtn_released() { - QMutexLocker ml{&mMutex}; - if (mDownloaded) { - qDebug() << "Is downloaded, will to uninstall the plugin."; - toUninstall(); - } else { - qDebug() << "Is not downloaded, will to install the plugin."; - toInstall(); - } + QMutexLocker ml{&mMutex}; + if (mDownloaded) { + qDebug() << "Is downloaded, will to uninstall the plugin."; + toUninstall(); + } else { + qDebug() << "Is not downloaded, will to install the plugin."; + toInstall(); + } } void PluginInfoForm::toUninstall() { - qDebug() << "To uninstall:" << mPluginInfo.shortName; - setUninstalling(); + qDebug() << "To uninstall:" << mPluginInfo.shortName; + setUninstalling(); - auto uninstallPlugin = pluginManager->uninstallPlugin(mPluginInfo.shortName); - qDebug() << "To uninstall:" << mPluginInfo.shortName << "=>" - << uninstallPlugin; + auto uninstallPlugin = pluginManager->uninstallPlugin(mPluginInfo.shortName); + qDebug() << "To uninstall:" << mPluginInfo.shortName << "=>" << uninstallPlugin; - if (uninstallPlugin) - setUninstalled(); + if (uninstallPlugin) setUninstalled(); } void PluginInfoForm::toInstall() { - qDebug() << "To install:" << mPluginInfo.shortName; - - if (isDownloading) { - qWarning() << "Is downloading..."; - return; - } - - qDebug() << "download=>" << downUrl; - isDownloading = true; - http = std::make_unique(); - http->get( - downUrl, - [&](QByteArray buf, const QString &fileName) { - auto path = makePath(QString::number(id), fileName); - qDebug() << "download bytes" << buf.size() << "be saved to=>" << path; - if (!ok::base::Files::writeTo(buf, path)) { - qWarning() << "Cannot to write plugin files." << path; - return; - } - isDownloading = false; - emit downloadFinished(path); - }, - [&](qint64 bytesReceived, qint64 bytesTotal) { - ui->progressBar->setMaximum(bytesTotal); - ui->progressBar->setValue(bytesReceived); - }, - - [&](int code, const QString& err){ - qWarning()<<"Install code:" << code <" << downUrl; + isDownloading = true; + http = std::make_unique(); + http->get( + downUrl, + [&](QByteArray buf, const QString& fileName) { + auto path = makePath(QString::number(id), fileName); + qDebug() << "download bytes" << buf.size() << "be saved to=>" << path; + if (!ok::base::Files::writeTo(buf, path)) { + qWarning() << "Cannot to write plugin files." << path; + return; + } + isDownloading = false; + emit downloadFinished(path); + }, + [&](qint64 bytesReceived, qint64 bytesTotal) { + ui->progressBar->setMaximum(bytesTotal); + ui->progressBar->setValue(bytesReceived); + }, + + [&](int code, const QString& err) { + qWarning() << "Install code:" << code << err; + isDownloading = false; + setUninstalled(); + }); + + setInstalling(); } void PluginInfoForm::setInstalled() { - mDownloaded = true; - ui->progressBar->hide(); - ui->installBtn->setText(tr("Uninstall")); + mDownloaded = true; + ui->progressBar->hide(); + ui->installBtn->setText(tr("Uninstall")); } void PluginInfoForm::setUninstalled() { - mDownloaded = false; - ui->progressBar->hide(); - ui->installBtn->setText(tr("Install")); + mDownloaded = false; + ui->progressBar->hide(); + ui->installBtn->setText(tr("Install")); } void PluginInfoForm::setInstalling() { - mDownloaded = false; - ui->progressBar->show(); - ui->installBtn->setText(tr("Installing")); + mDownloaded = false; + ui->progressBar->show(); + ui->installBtn->setText(tr("Installing")); } void PluginInfoForm::setUninstalling() { - mDownloaded = false; - ui->progressBar->show(); - ui->installBtn->setText(tr("Uninstalling")); + mDownloaded = false; + ui->progressBar->show(); + ui->installBtn->setText(tr("Uninstalling")); } void PluginInfoForm::retranslateUi() { - ui->retranslateUi(this); - ui->installBtn->setText(tr("Install")); + ui->retranslateUi(this); + ui->installBtn->setText(tr("Install")); } -} // namespace plugin -} // namespace ok +} // namespace plugin +} // namespace ok diff --git a/src/UI/window/config/plugin/src/PluginInfoForm.h b/src/UI/window/config/plugin/src/PluginInfoForm.h index 858d8d6a..5f4a7b69 100644 --- a/src/UI/window/config/plugin/src/PluginInfoForm.h +++ b/src/UI/window/config/plugin/src/PluginInfoForm.h @@ -13,11 +13,11 @@ #ifndef PLUGININFOFORM_H #define PLUGININFOFORM_H -#include "lib/plugin/PluginInfo.h" -#include "lib/plugin/pluginmanager.h" -#include "lib/backend/OkCloudService.h" #include #include +#include "lib/backend/OkCloudService.h" +#include "lib/plugin/PluginInfo.h" +#include "lib/plugin/pluginmanager.h" namespace Ui { class PluginInfoForm; @@ -31,41 +31,40 @@ namespace ok { namespace plugin { class PluginInfoForm : public QWidget { - Q_OBJECT + Q_OBJECT public: - explicit PluginInfoForm(ok::backend::PluginInfo &info, QWidget *parent = nullptr); - ~PluginInfoForm(); + explicit PluginInfoForm(ok::backend::PluginInfo& info, QWidget* parent = nullptr); + ~PluginInfoForm(); + + const qint64 pluginId() const { return id; } + void setInstalling(); + void setInstalled(); + void setUninstalling(); + void setUninstalled(); - const qint64 pluginId() const { return id; } - void setInstalling(); - void setInstalled(); - void setUninstalling(); - void setUninstalled(); + void toInstall(); + void toUninstall(); + void retranslateUi(); - void toInstall(); - void toUninstall(); - void retranslateUi(); private: - Ui::PluginInfoForm *ui; - PluginManager *pluginManager; - quint64 id; - QString downUrl; - ok::backend::PluginInfo mPluginInfo; - std::unique_ptr http; - QRecursiveMutex mMutex; + Ui::PluginInfoForm* ui; + PluginManager* pluginManager; + quint64 id; + QString downUrl; + ok::backend::PluginInfo mPluginInfo; + std::unique_ptr http; + QRecursiveMutex mMutex; - bool mDownloaded; - bool isDownloading; + bool mDownloaded; + bool isDownloading; signals: - void downloadFinished(const QString& path); - + void downloadFinished(const QString& path); private slots: - void on_installBtn_released(); - + void on_installBtn_released(); }; -} // namespace plugin -} // namespace ok -#endif // PLUGININFOFORM_H +} // namespace plugin +} // namespace ok +#endif // PLUGININFOFORM_H diff --git a/src/UI/window/config/plugin/src/PluginItemForm.cpp b/src/UI/window/config/plugin/src/PluginItemForm.cpp index 9373b439..c691930c 100644 --- a/src/UI/window/config/plugin/src/PluginItemForm.cpp +++ b/src/UI/window/config/plugin/src/PluginItemForm.cpp @@ -11,64 +11,53 @@ */ #include "PluginItemForm.h" +#include #include "base/files.h" +#include "base/images.h" #include "lib/network/NetworkHttp.h" #include "ui_PluginItemForm.h" -#include -#include "base/images.h" - -PluginItemForm::PluginItemForm(int row_, ok::backend::PluginInfo &pluginInfo, - QWidget *parent) - : QWidget(parent), ui(new Ui::PluginItemForm), info(pluginInfo), row(row_) { - ui->setupUi(this); - ui->name->setText(pluginInfo.name); - ui->version->setText(pluginInfo.version); - - - http = std::make_unique(); - connect(this, &PluginItemForm::logoDownloaded, this, - &PluginItemForm::onLogoDownloaded); +PluginItemForm::PluginItemForm(int row_, ok::backend::PluginInfo& pluginInfo, QWidget* parent) + : QWidget(parent), ui(new Ui::PluginItemForm), info(pluginInfo), row(row_) { + ui->setupUi(this); + ui->name->setText(pluginInfo.name); + ui->version->setText(pluginInfo.version); + http = std::make_unique(); + connect(this, &PluginItemForm::logoDownloaded, this, &PluginItemForm::onLogoDownloaded); } PluginItemForm::~PluginItemForm() { - disconnect(this, &PluginItemForm::loadLogo, this, &PluginItemForm::downLogo); - disconnect(this, &PluginItemForm::logoDownloaded, this, - &PluginItemForm::onLogoDownloaded); - delete ui; + disconnect(this, &PluginItemForm::loadLogo, this, &PluginItemForm::downLogo); + disconnect(this, &PluginItemForm::logoDownloaded, this, &PluginItemForm::onLogoDownloaded); + delete ui; } void PluginItemForm::downLogo() { - if(isSetLogo()) - return; - http->get(info.logoUrl, [&](QByteArray img, const QString &fileName) { - Q_UNUSED(fileName); - qDebug() << "download image:" << fileName << img.size(); - emit logoDownloaded(fileName, img); - }); + if (isSetLogo()) return; + http->get(info.logoUrl, [&](QByteArray img, const QString& fileName) { + Q_UNUSED(fileName); + qDebug() << "download image:" << fileName << img.size(); + emit logoDownloaded(fileName, img); + }); } -void PluginItemForm::setLogo(const QPixmap &pixmap) { - ui->logoLabel->setPixmap(pixmap); - ui->logoLabel->setScaledContents(true); +void PluginItemForm::setLogo(const QPixmap& pixmap) { + ui->logoLabel->setPixmap(pixmap); + ui->logoLabel->setScaledContents(true); } -bool PluginItemForm::isSetLogo() -{ +bool PluginItemForm::isSetLogo() { auto p = ui->logoLabel->pixmap(Qt::ReturnByValueConstant::ReturnByValue); return !p.isNull(); } -void PluginItemForm::showEvent(QShowEvent *) -{ - downLogo(); -} +void PluginItemForm::showEvent(QShowEvent*) { downLogo(); } -void PluginItemForm::onLogoDownloaded(const QString &fileName, QByteArray &img) { - qDebug() <<"logo downloaded"< #include "base/timer.h" -#include "lib/plugin/PluginInfo.h" #include "lib/backend/OkCloudService.h" #include "lib/network/NetworkHttp.h" -#include +#include "lib/plugin/PluginInfo.h" namespace Ui { class PluginItemForm; } class PluginItemForm : public QWidget { - Q_OBJECT + Q_OBJECT public: - explicit PluginItemForm(int row, ok::backend::PluginInfo &pluginInfo, - QWidget *parent = nullptr); - ~PluginItemForm(); - void downLogo(); - void setLogo(const QPixmap &pixmap); - bool isSetLogo(); + explicit PluginItemForm(int row, ok::backend::PluginInfo& pluginInfo, + QWidget* parent = nullptr); + ~PluginItemForm(); + void downLogo(); + void setLogo(const QPixmap& pixmap); + bool isSetLogo(); + protected: - void showEvent(QShowEvent*); + void showEvent(QShowEvent*); private: - Ui::PluginItemForm *ui; - ok::backend::PluginInfo info; - int row; - std::unique_ptr http; + Ui::PluginItemForm* ui; + ok::backend::PluginInfo info; + int row; + std::unique_ptr http; signals: - void loadLogo(); - void logoDownloaded(const QString &fileName, QByteArray &img); + void loadLogo(); + void logoDownloaded(const QString& fileName, QByteArray& img); public slots: - void onLogoDownloaded(const QString &fileName, QByteArray &img); + void onLogoDownloaded(const QString& fileName, QByteArray& img); }; -#endif // PLUGINITEMFORM_H +#endif // PLUGINITEMFORM_H diff --git a/src/UI/window/config/plugin/src/PluginManagerForm.cpp b/src/UI/window/config/plugin/src/PluginManagerForm.cpp index 511907be..e3842211 100644 --- a/src/UI/window/config/plugin/src/PluginManagerForm.cpp +++ b/src/UI/window/config/plugin/src/PluginManagerForm.cpp @@ -26,85 +26,86 @@ namespace ok { namespace plugin { -PluginManagerForm::PluginManagerForm(QWidget *parent) : UI::GenericForm(QPixmap(":/img/settings/general.png"), parent), ui(new Ui::PluginManagerForm) { - - ui->setupUi(this); - - if (parent) { - setGeometry(parent->contentsRect()); - } - - // QString locale = ok::base::OkSettings::getInstance().getTranslation(); - // settings::Translator::translate(OK_UIWindowConfig_MODULE, "plugin_"+locale); - // settings::Translator::registerHandler([this] { retranslateUi(); }, this); - // retranslateUi(); - - connect(ui->listWidget, &QListWidget::itemClicked, this, &PluginManagerForm::pluginClicked, Qt::UniqueConnection); - - delayCaller_ = std::make_unique<::base::DelayedCallTimer>(); - http = std::make_unique(this); - - delayCaller_->call(400, [&]() { - http->GetPluginPage( - [&](backend::ResPage &resList) { - int i = 0; - for (auto &item : resList.data.list) { - qDebug() << "add plugin:" << item.name; - add(item, i++); - } - }, - [](int code, const QString &err) { qWarning() << "GetPluginPage" << err; }); - }); +PluginManagerForm::PluginManagerForm(QWidget* parent) + : UI::GenericForm(QPixmap(":/img/settings/general.png"), parent) + , ui(new Ui::PluginManagerForm) { + ui->setupUi(this); + + if (parent) { + setGeometry(parent->contentsRect()); + } + + // QString locale = ok::base::OkSettings::getInstance().getTranslation(); + // settings::Translator::translate(OK_UIWindowConfig_MODULE, "plugin_"+locale); + // settings::Translator::registerHandler([this] { retranslateUi(); }, this); + // retranslateUi(); + + connect(ui->listWidget, &QListWidget::itemClicked, this, &PluginManagerForm::pluginClicked, + Qt::UniqueConnection); + + delayCaller_ = std::make_unique<::base::DelayedCallTimer>(); + http = std::make_unique(this); + + delayCaller_->call(400, [&]() { + http->GetPluginPage( + [&](backend::ResPage& resList) { + int i = 0; + for (auto& item : resList.data.list) { + qDebug() << "add plugin:" << item.name; + add(item, i++); + } + }, + [](int code, const QString& err) { qWarning() << "GetPluginPage" << err; }); + }); } PluginManagerForm::~PluginManagerForm() { delete ui; } -void PluginManagerForm::pluginClicked(QListWidgetItem *item) { - Q_UNUSED(item); - auto wdg = static_cast(sender()); - auto mCurrentRow = wdg->currentRow(); - auto info = mPluginInfos.at(mCurrentRow); - setPluginInfo(info); +void PluginManagerForm::pluginClicked(QListWidgetItem* item) { + Q_UNUSED(item); + auto wdg = static_cast(sender()); + auto mCurrentRow = wdg->currentRow(); + auto info = mPluginInfos.at(mCurrentRow); + setPluginInfo(info); } -void PluginManagerForm::add(ok::backend::PluginInfo &info, int i) { - mPluginInfos.append(info); - createPlugin(info, i); +void PluginManagerForm::add(ok::backend::PluginInfo& info, int i) { + mPluginInfos.append(info); + createPlugin(info, i); } -void PluginManagerForm::createPlugin(ok::backend::PluginInfo &info, int i) { - auto pitem = new PluginItemForm(0, info, this); - auto aitem = new QListWidgetItem(ui->listWidget); - aitem->setSizeHint(QSize(ui->listWidget->width(), 70)); +void PluginManagerForm::createPlugin(ok::backend::PluginInfo& info, int i) { + auto pitem = new PluginItemForm(0, info, this); + auto aitem = new QListWidgetItem(ui->listWidget); + aitem->setSizeHint(QSize(ui->listWidget->width(), 70)); - ui->listWidget->addItem(aitem); - ui->listWidget->setItemWidget(aitem, pitem); + ui->listWidget->addItem(aitem); + ui->listWidget->setItemWidget(aitem, pitem); - retranslateUi(); + retranslateUi(); } -void PluginManagerForm::setPluginInfo(ok::backend::PluginInfo &info) { - - for (auto i = 0; i < ui->stackedWidget->count(); i++) { - auto entry = static_cast(ui->stackedWidget->widget(i)); - if (entry->pluginId() == info.id) { - ui->stackedWidget->setCurrentWidget(entry); - return; +void PluginManagerForm::setPluginInfo(ok::backend::PluginInfo& info) { + for (auto i = 0; i < ui->stackedWidget->count(); i++) { + auto entry = static_cast(ui->stackedWidget->widget(i)); + if (entry->pluginId() == info.id) { + ui->stackedWidget->setCurrentWidget(entry); + return; + } } - } - auto selectedInfoForm = new PluginInfoForm(info); - ui->stackedWidget->addWidget(selectedInfoForm); - ui->stackedWidget->setCurrentWidget(selectedInfoForm); + auto selectedInfoForm = new PluginInfoForm(info); + ui->stackedWidget->addWidget(selectedInfoForm); + ui->stackedWidget->setCurrentWidget(selectedInfoForm); } void PluginManagerForm::retranslateUi() { - ui->retranslateUi(this); - for (int i = 0; i < ui->stackedWidget->count(); i++) { - auto form = static_cast (ui->stackedWidget->widget(i)); - form->retranslateUi(); - } + ui->retranslateUi(this); + for (int i = 0; i < ui->stackedWidget->count(); i++) { + auto form = static_cast(ui->stackedWidget->widget(i)); + form->retranslateUi(); + } } -} // namespace plugin -} // namespace ok +} // namespace plugin +} // namespace ok diff --git a/src/UI/window/config/plugin/src/PluginManagerForm.h b/src/UI/window/config/plugin/src/PluginManagerForm.h index 079e958e..ca20ee3d 100644 --- a/src/UI/window/config/plugin/src/PluginManagerForm.h +++ b/src/UI/window/config/plugin/src/PluginManagerForm.h @@ -13,17 +13,17 @@ #ifndef PLUGINFORM_H #define PLUGINFORM_H +#include +#include #include "UI/widget/GenericForm.h" #include "base/timer.h" #include "lib/backend/OkCloudService.h" #include "lib/plugin/PluginInfo.h" -#include -#include namespace Ui { class PluginManagerForm; class PluginInfoForm; -} // namespace Ui +} // namespace Ui class QListWidgetItem; @@ -33,30 +33,30 @@ namespace plugin { class PluginInfoForm; class PluginManagerForm : public UI::GenericForm { - Q_OBJECT + Q_OBJECT public: - explicit PluginManagerForm(QWidget *parent = nullptr); - ~PluginManagerForm() override; + explicit PluginManagerForm(QWidget* parent = nullptr); + ~PluginManagerForm() override; - virtual QString getFormName() final override { return tr("Plugin manager"); } + virtual QString getFormName() final override { return tr("Plugin manager"); } - void add(ok::backend::PluginInfo &info, int i); + void add(ok::backend::PluginInfo& info, int i); - void retranslateUi() override; + void retranslateUi() override; private: - Ui::PluginManagerForm *ui; - QList mPluginInfos; - std::unique_ptr<::base::DelayedCallTimer> delayCaller_; - std::unique_ptr http; + Ui::PluginManagerForm* ui; + QList mPluginInfos; + std::unique_ptr<::base::DelayedCallTimer> delayCaller_; + std::unique_ptr http; - void createPlugin(ok::backend::PluginInfo &, int i); - void setPluginInfo(ok::backend::PluginInfo &); + void createPlugin(ok::backend::PluginInfo&, int i); + void setPluginInfo(ok::backend::PluginInfo&); protected slots: - void pluginClicked(QListWidgetItem *); + void pluginClicked(QListWidgetItem*); }; -} // namespace plugin -} // namespace ok -#endif // PLUGINFORM_H +} // namespace plugin +} // namespace ok +#endif // PLUGINFORM_H diff --git a/src/UI/window/config/settings/src/GeneralForm.cpp b/src/UI/window/config/settings/src/GeneralForm.cpp index 817f54b3..7a34d262 100644 --- a/src/UI/window/config/settings/src/GeneralForm.cpp +++ b/src/UI/window/config/settings/src/GeneralForm.cpp @@ -14,14 +14,13 @@ #include #include +#include "Bus.h" #include "application.h" #include "base/OkSettings.h" #include "lib/settings/settings.h" #include "lib/settings/translator.h" #include "src/base/RecursiveSignalBlocker.h" #include "src/lib/settings/style.h" -#include "Bus.h" - namespace UI { /** @@ -29,115 +28,117 @@ namespace UI { * * This form contains all settings that are not suited to other forms */ -GeneralForm::GeneralForm(SettingsWidget *myParent) - : GenericForm(QPixmap(":/img/settings/general.png")), - bodyUI(new Ui::GeneralForm) { - parent = myParent; +GeneralForm::GeneralForm(SettingsWidget* myParent) + : GenericForm(QPixmap(":/img/settings/general.png")), bodyUI(new Ui::GeneralForm) { + parent = myParent; - bodyUI->setupUi(this); + bodyUI->setupUi(this); - // block all child signals during initialization - const RecursiveSignalBlocker signalBlocker(this); + // block all child signals during initialization + const RecursiveSignalBlocker signalBlocker(this); -// Settings &s = Settings::getInstance(); + // Settings &s = Settings::getInstance(); - // 先获取当前语言 -// QString locale0 = ok::base::OkSettings::getInstance().getTranslation(); -// settings::Translator::translate(OK_UIWindowConfig_MODULE, locale0); -// settings::Translator::registerHandler([this] { retranslateUi(); }, this); -// retranslateUi(); + // 先获取当前语言 + // QString locale0 = ok::base::OkSettings::getInstance().getTranslation(); + // settings::Translator::translate(OK_UIWindowConfig_MODULE, locale0); + // settings::Translator::registerHandler([this] { retranslateUi(); }, this); + // retranslateUi(); #ifndef UPDATE_CHECK_ENABLED - bodyUI->checkUpdates->setVisible(false); + bodyUI->checkUpdates->setVisible(false); #endif #ifndef SPELL_CHECKING - bodyUI->cbSpellChecking->setVisible(false); + bodyUI->cbSpellChecking->setVisible(false); #endif - // 获取复选框状态 -// bodyUI->checkUpdates->setChecked(s.getCheckUpdates()); - - auto &okSettings = ok::base::OkSettings::getInstance(); - - for (int i = 0; i < okSettings.getLocales().size(); ++i) { - QString langName; - auto &locale = okSettings.getLocales().at(i); - if (locale.startsWith(QLatin1String("eo"))) // QTBUG-57802 - langName = QLocale::languageToString(QLocale::Esperanto); - else if (locale.startsWith(QLatin1String("jbo"))) - langName = QLatin1String("Lojban"); - else if (locale.startsWith(QLatin1String("pr"))) - langName = QLatin1String("Pirate"); - else if (locale == (QLatin1String("pt"))) // QTBUG-47891 - langName = QStringLiteral("português"); - else - langName = QLocale(locale).nativeLanguageName(); - - bodyUI->transComboBox->insertItem(i, langName); - } - // 当前语言下拉框状态 - bodyUI->transComboBox->setCurrentIndex(okSettings.getLocales().indexOf(okSettings.getTranslation())); - - // autorun - bodyUI->cbAutorun->setChecked(okSettings.getAutorun()); - -// bodyUI->cbSpellChecking->setChecked(s.getSpellCheckingEnabled()); - - bool showSystemTray = okSettings.getShowSystemTray(); - bodyUI->showSystemTray->setChecked(showSystemTray); - bodyUI->startInTray->setChecked(okSettings.getAutostartInTray()); - bodyUI->startInTray->setEnabled(showSystemTray); - bodyUI->minimizeToTray->setChecked(okSettings.getMinimizeToTray()); - bodyUI->minimizeToTray->setEnabled(showSystemTray); - bodyUI->closeToTray->setChecked(okSettings.getCloseToTray()); - bodyUI->closeToTray->setEnabled(showSystemTray); - - + // 获取复选框状态 + // bodyUI->checkUpdates->setChecked(s.getCheckUpdates()); + + auto& okSettings = ok::base::OkSettings::getInstance(); + + for (int i = 0; i < okSettings.getLocales().size(); ++i) { + QString langName; + auto& locale = okSettings.getLocales().at(i); + if (locale.startsWith(QLatin1String("eo"))) // QTBUG-57802 + langName = QLocale::languageToString(QLocale::Esperanto); + else if (locale.startsWith(QLatin1String("jbo"))) + langName = QLatin1String("Lojban"); + else if (locale.startsWith(QLatin1String("pr"))) + langName = QLatin1String("Pirate"); + else if (locale == (QLatin1String("pt"))) // QTBUG-47891 + langName = QStringLiteral("português"); + else + langName = QLocale(locale).nativeLanguageName(); + + bodyUI->transComboBox->insertItem(i, langName); + } + // 当前语言下拉框状态 + bodyUI->transComboBox->setCurrentIndex( + okSettings.getLocales().indexOf(okSettings.getTranslation())); + + // autorun + bodyUI->cbAutorun->setChecked(okSettings.getAutorun()); + + // bodyUI->cbSpellChecking->setChecked(s.getSpellCheckingEnabled()); + + bool showSystemTray = okSettings.getShowSystemTray(); + bodyUI->showSystemTray->setChecked(showSystemTray); + bodyUI->startInTray->setChecked(okSettings.getAutostartInTray()); + bodyUI->startInTray->setEnabled(showSystemTray); + bodyUI->minimizeToTray->setChecked(okSettings.getMinimizeToTray()); + bodyUI->minimizeToTray->setEnabled(showSystemTray); + bodyUI->closeToTray->setChecked(okSettings.getCloseToTray()); + bodyUI->closeToTray->setEnabled(showSystemTray); } GeneralForm::~GeneralForm() { -// settings::Translator::unregister(this); - delete bodyUI; + // settings::Translator::unregister(this); + delete bodyUI; } void GeneralForm::on_transComboBox_currentIndexChanged(int index) { - auto &s = ok::base::OkSettings::getInstance(); - const QString &locale = s.getLocales().at(index); - s.setTranslation(locale); - s.saveGlobal(); - emit onLanguageChanged(locale); - emit ok::Application::Instance()->bus()->languageChanged(locale); - settings::Translator::translate(OK_UIWindowConfig_MODULE, locale); + auto& s = ok::base::OkSettings::getInstance(); + const QString& locale = s.getLocales().at(index); + s.setTranslation(locale); + s.saveGlobal(); + emit onLanguageChanged(locale); + emit ok::Application::Instance() -> bus()->languageChanged(locale); + settings::Translator::translate(OK_UIWindowConfig_MODULE, locale); } void GeneralForm::on_cbAutorun_stateChanged() { - ok::base::OkSettings::getInstance().setAutorun(bodyUI->cbAutorun->isChecked()); } + ok::base::OkSettings::getInstance().setAutorun(bodyUI->cbAutorun->isChecked()); +} void GeneralForm::on_cbSpellChecking_stateChanged() { -// Settings::getInstance().setSpellCheckingEnabled(bodyUI->cbSpellChecking->isChecked()); + // Settings::getInstance().setSpellCheckingEnabled(bodyUI->cbSpellChecking->isChecked()); } void GeneralForm::on_showSystemTray_stateChanged() { - ok::base::OkSettings::getInstance().setShowSystemTray(bodyUI->showSystemTray->isChecked()); -// Settings::getInstance().saveGlobal(); + ok::base::OkSettings::getInstance().setShowSystemTray(bodyUI->showSystemTray->isChecked()); + // Settings::getInstance().saveGlobal(); } -void GeneralForm::on_startInTray_stateChanged() { ok::base::OkSettings::getInstance().setAutostartInTray(bodyUI->startInTray->isChecked()); } - -void GeneralForm::on_closeToTray_stateChanged() { ok::base::OkSettings::getInstance().setCloseToTray(bodyUI->closeToTray->isChecked()); } +void GeneralForm::on_startInTray_stateChanged() { + ok::base::OkSettings::getInstance().setAutostartInTray(bodyUI->startInTray->isChecked()); +} -void GeneralForm::on_minimizeToTray_stateChanged() { ok::base::OkSettings::getInstance().setMinimizeToTray(bodyUI->minimizeToTray->isChecked()); } +void GeneralForm::on_closeToTray_stateChanged() { + ok::base::OkSettings::getInstance().setCloseToTray(bodyUI->closeToTray->isChecked()); +} +void GeneralForm::on_minimizeToTray_stateChanged() { + ok::base::OkSettings::getInstance().setMinimizeToTray(bodyUI->minimizeToTray->isChecked()); +} void GeneralForm::on_checkUpdates_stateChanged() { -// Settings::getInstance().setCheckUpdates(bodyUI->checkUpdates->isChecked()); + // Settings::getInstance().setCheckUpdates(bodyUI->checkUpdates->isChecked()); } /** * @brief Retranslate all elements in the form. */ -void GeneralForm::retranslateUi() { - bodyUI->retranslateUi(this); -} +void GeneralForm::retranslateUi() { bodyUI->retranslateUi(this); } -} // namespace UI +} // namespace UI diff --git a/src/UI/window/config/settings/src/GeneralForm.h b/src/UI/window/config/settings/src/GeneralForm.h index 85657599..29f349d8 100644 --- a/src/UI/window/config/settings/src/GeneralForm.h +++ b/src/UI/window/config/settings/src/GeneralForm.h @@ -16,19 +16,14 @@ #include "src/UI/widget/GenericForm.h" #include "ui_GeneralForm.h" - -namespace UI{ +namespace UI { class SettingsWidget; -class GeneralForm : public GenericForm -{ +class GeneralForm : public GenericForm { Q_OBJECT public: explicit GeneralForm(SettingsWidget* parent); ~GeneralForm(); - virtual QString getFormName() final override - { - return tr("General"); - } + virtual QString getFormName() final override { return tr("General"); } void retranslateUi() override; signals: @@ -45,10 +40,9 @@ private slots: void on_minimizeToTray_stateChanged(); void on_checkUpdates_stateChanged(); - private: Ui::GeneralForm* bodyUI; SettingsWidget* parent; }; -} +} // namespace UI #endif diff --git a/src/UI/window/config/settings/src/SettingsForm.cpp b/src/UI/window/config/settings/src/SettingsForm.cpp index 5459e793..b9be125a 100644 --- a/src/UI/window/config/settings/src/SettingsForm.cpp +++ b/src/UI/window/config/settings/src/SettingsForm.cpp @@ -24,83 +24,84 @@ #include namespace UI { -SettingsWidget::SettingsWidget(QWidget *parent) : - GenericForm(QPixmap(":/img/settings/general.png"), parent) { - settingsWidgets = std::unique_ptr(new QTabWidget(this)); - settingsWidgets->setTabPosition(QTabWidget::North); +SettingsWidget::SettingsWidget(QWidget* parent) + : GenericForm(QPixmap(":/img/settings/general.png"), parent) { + settingsWidgets = std::unique_ptr(new QTabWidget(this)); + settingsWidgets->setTabPosition(QTabWidget::North); - bodyLayout = std::unique_ptr(new QVBoxLayout(this)); - bodyLayout->setContentsMargins(0, 0, 0, 0); - bodyLayout->addWidget(settingsWidgets.get()); - setLayout(bodyLayout.get()); + bodyLayout = std::unique_ptr(new QVBoxLayout(this)); + bodyLayout->setContentsMargins(0, 0, 0, 0); + bodyLayout->addWidget(settingsWidgets.get()); + setLayout(bodyLayout.get()); -// std::unique_ptr gfrm(new GeneralForm(this)); - // connect(gfrm.get(), &GeneralForm::updateIcons, parent, &Widget::updateIcons); + // std::unique_ptr gfrm(new GeneralForm(this)); + // connect(gfrm.get(), &GeneralForm::updateIcons, parent, &Widget::updateIcons); + std::unique_ptr uifrm(new UserInterfaceForm(this)); + // std::unique_ptr pfrm(new PrivacyForm()); + // connect(pfrm.get(), &PrivacyForm::clearAllReceipts, parent, &Widget::clearAllReceipts); - std::unique_ptr uifrm(new UserInterfaceForm(this)); -// std::unique_ptr pfrm(new PrivacyForm()); - // connect(pfrm.get(), &PrivacyForm::clearAllReceipts, parent, &Widget::clearAllReceipts); - -// std::unique_ptr expfrm(new AdvancedForm()); -// std::unique_ptr abtfrm(new AboutForm()); + // std::unique_ptr expfrm(new AdvancedForm()); + // std::unique_ptr abtfrm(new AboutForm()); #if UPDATE_CHECK_ENABLED - if (updateCheck != nullptr) { - connect(updateCheck, &UpdateCheck::updateAvailable, this, &SettingsWidget::onUpdateAvailable); - } else { - qWarning() << "SettingsWidget passed null UpdateCheck!"; - } + if (updateCheck != nullptr) { + connect(updateCheck, &UpdateCheck::updateAvailable, this, + &SettingsWidget::onUpdateAvailable); + } else { + qWarning() << "SettingsWidget passed null UpdateCheck!"; + } #endif - cfgForms = {{ - new GeneralForm(this), // -// std::move(uifrm), // -// std::move(pfrm), // -// std::move(expfrm), // -// std::move(abtfrm) // - }}; + cfgForms = {{ + new GeneralForm(this), // + // std::move(uifrm), // + // std::move(pfrm), // + // std::move(expfrm), // + // std::move(abtfrm) // + }}; - for (auto &cfgForm : cfgForms) - settingsWidgets->addTab(cfgForm, cfgForm->getFormIcon(), cfgForm->getFormName()); -// settingsWidgets->addTab(gfrm, gfrm->getFormIcon(), gfrm->getFormName()); + for (auto& cfgForm : cfgForms) + settingsWidgets->addTab(cfgForm, cfgForm->getFormIcon(), cfgForm->getFormName()); + // settingsWidgets->addTab(gfrm, gfrm->getFormIcon(), gfrm->getFormName()); - connect(settingsWidgets.get(), &QTabWidget::currentChanged, this, &SettingsWidget::onTabChanged); + connect(settingsWidgets.get(), &QTabWidget::currentChanged, this, + &SettingsWidget::onTabChanged); - settings::Translator::registerHandler([this] { retranslateUi(); }, this); - retranslateUi(); + settings::Translator::registerHandler([this] { retranslateUi(); }, this); + retranslateUi(); } -SettingsWidget::~SettingsWidget() { - settings::Translator::unregister(this); -} +SettingsWidget::~SettingsWidget() { settings::Translator::unregister(this); } -void SettingsWidget::setBodyHeadStyle(QString style) { settingsWidgets->setStyle(QStyleFactory::create(style)); } +void SettingsWidget::setBodyHeadStyle(QString style) { + settingsWidgets->setStyle(QStyleFactory::create(style)); +} void SettingsWidget::showAbout() { onTabChanged(settingsWidgets->count() - 1); } bool SettingsWidget::isShown() const { - if (settingsWidgets->isVisible()) { - settingsWidgets->window()->windowHandle()->alert(0); - return true; - } + if (settingsWidgets->isVisible()) { + settingsWidgets->window()->windowHandle()->alert(0); + return true; + } - return false; + return false; } void SettingsWidget::onTabChanged(int index) { settingsWidgets->setCurrentIndex(index); } void SettingsWidget::onUpdateAvailable(void) { - // settingsWidgets->tabBar()->setProperty("update-available", true); - // settingsWidgets->tabBar()->style()->unpolish(settingsWidgets->tabBar()); - // settingsWidgets->tabBar()->style()->polish(settingsWidgets->tabBar()); + // settingsWidgets->tabBar()->setProperty("update-available", true); + // settingsWidgets->tabBar()->style()->unpolish(settingsWidgets->tabBar()); + // settingsWidgets->tabBar()->style()->polish(settingsWidgets->tabBar()); } void SettingsWidget::retranslateUi() { - for (int i = 0; i < cfgForms.size(); ++i){ - settingsWidgets->setTabText(i, cfgForms.at(i)->getFormName()); - cfgForms.at(i)->retranslateUi(); - } + for (int i = 0; i < cfgForms.size(); ++i) { + settingsWidgets->setTabText(i, cfgForms.at(i)->getFormName()); + cfgForms.at(i)->retranslateUi(); + } } -} // namespace UI +} // namespace UI diff --git a/src/UI/window/config/settings/src/SettingsForm.h b/src/UI/window/config/settings/src/SettingsForm.h index 581541f1..29db340d 100644 --- a/src/UI/window/config/settings/src/SettingsForm.h +++ b/src/UI/window/config/settings/src/SettingsForm.h @@ -16,43 +16,38 @@ #include #include -#include "GeneralForm.h" -#include "src/UI/widget/GenericForm.h" #include #include #include +#include "GeneralForm.h" +#include "src/UI/widget/GenericForm.h" namespace UI { class SettingsWidget : public GenericForm { - Q_OBJECT + Q_OBJECT public: - SettingsWidget(QWidget *parent = nullptr); - ~SettingsWidget(); + SettingsWidget(QWidget* parent = nullptr); + ~SettingsWidget(); - virtual QString getFormName() final override - { - return tr("Settings"); - } + virtual QString getFormName() final override { return tr("Settings"); } - bool isShown() const; - void setBodyHeadStyle(QString style); + bool isShown() const; + void setBodyHeadStyle(QString style); - void showAbout(); - GeneralForm * general(){ - return static_cast( cfgForms.at(0)); - } - void retranslateUi() override ; + void showAbout(); + GeneralForm* general() { return static_cast(cfgForms.at(0)); } + void retranslateUi() override; public slots: - void onUpdateAvailable(void); + void onUpdateAvailable(void); private slots: - void onTabChanged(int); + void onTabChanged(int); private: - std::unique_ptr bodyLayout; - std::unique_ptr settingsWidgets; - std::vector cfgForms; - int currentIndex; + std::unique_ptr bodyLayout; + std::unique_ptr settingsWidgets; + std::vector cfgForms; + int currentIndex; }; -} // namespace UI +} // namespace UI diff --git a/src/UI/window/config/settings/src/UserInterfaceForm.cpp b/src/UI/window/config/settings/src/UserInterfaceForm.cpp index bef0150c..23ccb211 100644 --- a/src/UI/window/config/settings/src/UserInterfaceForm.cpp +++ b/src/UI/window/config/settings/src/UserInterfaceForm.cpp @@ -28,7 +28,7 @@ #include "src/lib/settings/settings.h" #include "src/lib/settings/style.h" -namespace UI{ +namespace UI { /** * @class UserInterfaceForm @@ -44,9 +44,8 @@ namespace UI{ * Restores all controls from the settings. */ UserInterfaceForm::UserInterfaceForm(SettingsWidget* myParent) - : GenericForm(QPixmap(":/img/settings/general.png"), myParent), - bodyUI{new Ui::UserInterfaceForm} -{ + : GenericForm(QPixmap(":/img/settings/general.png"), myParent) + , bodyUI{new Ui::UserInterfaceForm} { bodyUI->setupUi(this); parent = myParent; @@ -62,7 +61,7 @@ UserInterfaceForm::UserInterfaceForm(SettingsWidget* myParent) // bodyUI->useNameColors->setChecked(s.getEnableGroupChatsColor()); // // bodyUI->notify->setChecked(s.getNotify()); - // Note: UI is boolean inversed from settings to maintain setting file backwards compatibility +// Note: UI is boolean inversed from settings to maintain setting file backwards compatibility // bodyUI->groupOnlyNotfiyWhenMentioned->setChecked(!s.getGroupAlwaysNotify()); // bodyUI->groupOnlyNotfiyWhenMentioned->setEnabled(s.getNotify()); // bodyUI->notifySound->setChecked(s.getNotifySound()); @@ -77,202 +76,197 @@ UserInterfaceForm::UserInterfaceForm(SettingsWidget* myParent) bodyUI->desktopNotify->hide(); #endif -// bodyUI->showWindow->setChecked(s.getShowWindow()); + // bodyUI->showWindow->setChecked(s.getShowWindow()); -// bodyUI->cbGroupchatPosition->setChecked(s.getGroupchatPosition()); -// bodyUI->cbCompactLayout->setChecked(s.getCompactLayout()); -// bodyUI->cbSeparateWindow->setChecked(s.getSeparateWindow()); -// bodyUI->cbDontGroupWindows->setChecked(s.getDontGroupWindows()); -// bodyUI->cbDontGroupWindows->setEnabled(s.getSeparateWindow()); -// bodyUI->cbShowIdenticons->setChecked(s.getShowIdenticons()); + // bodyUI->cbGroupchatPosition->setChecked(s.getGroupchatPosition()); + // bodyUI->cbCompactLayout->setChecked(s.getCompactLayout()); + // bodyUI->cbSeparateWindow->setChecked(s.getSeparateWindow()); + // bodyUI->cbDontGroupWindows->setChecked(s.getDontGroupWindows()); + // bodyUI->cbDontGroupWindows->setEnabled(s.getSeparateWindow()); + // bodyUI->cbShowIdenticons->setChecked(s.getShowIdenticons()); -// bodyUI->useEmoticons->setChecked(s.getUseEmoticons()); -// for (auto entry : SmileyPack::listSmileyPacks()) -// bodyUI->smileyPackBrowser->addItem(entry.first, entry.second); + // bodyUI->useEmoticons->setChecked(s.getUseEmoticons()); + // for (auto entry : SmileyPack::listSmileyPacks()) + // bodyUI->smileyPackBrowser->addItem(entry.first, entry.second); bodyUI->styleBrowser->addItem(tr("None")); bodyUI->styleBrowser->addItems(QStyleFactory::keys()); -// QString style; -// if (QStyleFactory::keys().contains(s.getStyle())) -// style = s.getStyle(); -// else -// style = tr("None"); + // QString style; + // if (QStyleFactory::keys().contains(s.getStyle())) + // style = s.getStyle(); + // else + // style = tr("None"); -// bodyUI->styleBrowser->setCurrentText(style); + // bodyUI->styleBrowser->setCurrentText(style); -// for (QString color : Style::getThemeColorNames()) -// bodyUI->themeColorCBox->addItem(color); + // for (QString color : Style::getThemeColorNames()) + // bodyUI->themeColorCBox->addItem(color); -// bodyUI->themeColorCBox->setCurrentIndex(s.getThemeColor()); -// bodyUI->emoticonSize->setValue(s.getEmojiFontPointSize()); + // bodyUI->themeColorCBox->setCurrentIndex(s.getThemeColor()); + // bodyUI->emoticonSize->setValue(s.getEmojiFontPointSize()); QLocale ql; QStringList timeFormats; timeFormats << ql.timeFormat(QLocale::ShortFormat) << ql.timeFormat(QLocale::LongFormat) - << "hh:mm AP" - << "hh:mm:ss AP" - << "hh:mm:ss"; + << "hh:mm AP" << "hh:mm:ss AP" << "hh:mm:ss"; timeFormats.removeDuplicates(); bodyUI->timestamp->addItems(timeFormats); QRegularExpression re(QString("^[^\\n]{0,%0}$").arg(MAX_FORMAT_LENGTH)); QRegularExpressionValidator* validator = new QRegularExpressionValidator(re, this); -// QString timeFormat = s.getTimestampFormat(); - -// if (!re.match(timeFormat).hasMatch()) -// timeFormat = timeFormats[0]; -// -// bodyUI->timestamp->setCurrentText(timeFormat); -// bodyUI->timestamp->setValidator(validator); -// on_timestamp_editTextChanged(timeFormat); -// -// QStringList dateFormats; -// dateFormats << QStringLiteral("yyyy-MM-dd") // ISO 8601 -// format strings from system locale -// << ql.dateFormat(QLocale::LongFormat) << ql.dateFormat(QLocale::ShortFormat) -// << ql.dateFormat(QLocale::NarrowFormat) << "dd-MM-yyyy" -// << "d-MM-yyyy" -// << "dddd dd-MM-yyyy" -// << "dddd d-MM"; - -// dateFormats.removeDuplicates(); -// bodyUI->dateFormats->addItems(dateFormats); -// -// QString dateFormat = s.getDateFormat(); -// if (!re.match(dateFormat).hasMatch()) -// dateFormat = dateFormats[0]; -// -// bodyUI->dateFormats->setCurrentText(dateFormat); -// bodyUI->dateFormats->setValidator(validator); -// on_dateFormats_editTextChanged(dateFormat); - -// eventsInit(); -// settings::Translator::registerHandler(std::bind(&UserInterfaceForm::retranslateUi, this), this); + // QString timeFormat = s.getTimestampFormat(); + + // if (!re.match(timeFormat).hasMatch()) + // timeFormat = timeFormats[0]; + // + // bodyUI->timestamp->setCurrentText(timeFormat); + // bodyUI->timestamp->setValidator(validator); + // on_timestamp_editTextChanged(timeFormat); + // + // QStringList dateFormats; + // dateFormats << QStringLiteral("yyyy-MM-dd") // ISO 8601 + // format strings from system locale + // << ql.dateFormat(QLocale::LongFormat) << ql.dateFormat(QLocale::ShortFormat) + // << ql.dateFormat(QLocale::NarrowFormat) << "dd-MM-yyyy" + // << "d-MM-yyyy" + // << "dddd dd-MM-yyyy" + // << "dddd d-MM"; + + // dateFormats.removeDuplicates(); + // bodyUI->dateFormats->addItems(dateFormats); + // + // QString dateFormat = s.getDateFormat(); + // if (!re.match(dateFormat).hasMatch()) + // dateFormat = dateFormats[0]; + // + // bodyUI->dateFormats->setCurrentText(dateFormat); + // bodyUI->dateFormats->setValidator(validator); + // on_dateFormats_editTextChanged(dateFormat); + + // eventsInit(); + // settings::Translator::registerHandler(std::bind(&UserInterfaceForm::retranslateUi, this), + // this); } -UserInterfaceForm::~UserInterfaceForm() -{ +UserInterfaceForm::~UserInterfaceForm() { settings::Translator::unregister(this); delete bodyUI; } -//void UserInterfaceForm::on_styleBrowser_currentIndexChanged(QString style) +// void UserInterfaceForm::on_styleBrowser_currentIndexChanged(QString style) //{ -// if (bodyUI->styleBrowser->currentIndex() == 0) -// Settings::getInstance().setStyle("None"); -// else -// Settings::getInstance().setStyle(style); +// if (bodyUI->styleBrowser->currentIndex() == 0) +// Settings::getInstance().setStyle("None"); +// else +// Settings::getInstance().setStyle(style); // -// this->setStyle(QStyleFactory::create(style)); -// parent->setBodyHeadStyle(style); -//} - +// this->setStyle(QStyleFactory::create(style)); +// parent->setBodyHeadStyle(style); +// } -void UserInterfaceForm::on_timestamp_editTextChanged(const QString& format) -{ +void UserInterfaceForm::on_timestamp_editTextChanged(const QString& format) { QString timeExample = QTime::currentTime().toString(format); bodyUI->timeExample->setText(timeExample); -// Settings::getInstance().setTimestampFormat(format); -// QString locale = Settings::getInstance().getTranslation(); -// settings::Translator::translate(OK_UIWindowConfig_MODULE, locale); + // Settings::getInstance().setTimestampFormat(format); + // QString locale = Settings::getInstance().getTranslation(); + // settings::Translator::translate(OK_UIWindowConfig_MODULE, locale); } -void UserInterfaceForm::on_dateFormats_editTextChanged(const QString& format) -{ +void UserInterfaceForm::on_dateFormats_editTextChanged(const QString& format) { QString dateExample = QDate::currentDate().toString(format); bodyUI->dateExample->setText(dateExample); -// Settings::getInstance().setDateFormat(format); -// QString locale = Settings::getInstance().getTranslation(); -// settings::Translator::translate(OK_UIWindowConfig_MODULE, locale); + // Settings::getInstance().setDateFormat(format); + // QString locale = Settings::getInstance().getTranslation(); + // settings::Translator::translate(OK_UIWindowConfig_MODULE, locale); } -//void UserInterfaceForm::on_useEmoticons_stateChanged() +// void UserInterfaceForm::on_useEmoticons_stateChanged() //{ -// Settings::getInstance().setUseEmoticons(bodyUI->useEmoticons->isChecked()); -// bodyUI->smileyPackBrowser->setEnabled(bodyUI->useEmoticons->isChecked()); -//} +// Settings::getInstance().setUseEmoticons(bodyUI->useEmoticons->isChecked()); +// bodyUI->smileyPackBrowser->setEnabled(bodyUI->useEmoticons->isChecked()); +// } // -//void UserInterfaceForm::on_textStyleComboBox_currentTextChanged() +// void UserInterfaceForm::on_textStyleComboBox_currentTextChanged() //{ -// Settings::StyleType styleType = -// static_cast(bodyUI->textStyleComboBox->currentIndex()); -// Settings::getInstance().setStylePreference(styleType); -//} +// Settings::StyleType styleType = +// static_cast(bodyUI->textStyleComboBox->currentIndex()); +// Settings::getInstance().setStylePreference(styleType); +// } -//void UserInterfaceForm::on_notify_stateChanged() +// void UserInterfaceForm::on_notify_stateChanged() //{ -// const bool notify = bodyUI->notify->isChecked(); -// Settings::getInstance().setNotify(notify); -// bodyUI->groupOnlyNotfiyWhenMentioned->setEnabled(notify); -// bodyUI->notifySound->setEnabled(notify); -// bodyUI->busySound->setEnabled(notify && bodyUI->notifySound->isChecked()); -// bodyUI->desktopNotify->setEnabled(notify); -//} - -//void UserInterfaceForm::on_notifySound_stateChanged() +// const bool notify = bodyUI->notify->isChecked(); +// Settings::getInstance().setNotify(notify); +// bodyUI->groupOnlyNotfiyWhenMentioned->setEnabled(notify); +// bodyUI->notifySound->setEnabled(notify); +// bodyUI->busySound->setEnabled(notify && bodyUI->notifySound->isChecked()); +// bodyUI->desktopNotify->setEnabled(notify); +// } + +// void UserInterfaceForm::on_notifySound_stateChanged() //{ -// const bool notify = bodyUI->notifySound->isChecked(); -// Settings::getInstance().setNotifySound(notify); -// bodyUI->busySound->setEnabled(notify); -//} +// const bool notify = bodyUI->notifySound->isChecked(); +// Settings::getInstance().setNotifySound(notify); +// bodyUI->busySound->setEnabled(notify); +// } -//void UserInterfaceForm::on_desktopNotify_stateChanged() +// void UserInterfaceForm::on_desktopNotify_stateChanged() //{ -// const bool notify = bodyUI->desktopNotify->isChecked(); -// Settings::getInstance().setDesktopNotify(notify); -//} +// const bool notify = bodyUI->desktopNotify->isChecked(); +// Settings::getInstance().setDesktopNotify(notify); +// } // -//void UserInterfaceForm::on_busySound_stateChanged() +// void UserInterfaceForm::on_busySound_stateChanged() //{ -// Settings::getInstance().setBusySound(bodyUI->busySound->isChecked()); -//} +// Settings::getInstance().setBusySound(bodyUI->busySound->isChecked()); +// } // -//void UserInterfaceForm::on_showWindow_stateChanged() +// void UserInterfaceForm::on_showWindow_stateChanged() //{ -// Settings::getInstance().setShowWindow(bodyUI->showWindow->isChecked()); -//} +// Settings::getInstance().setShowWindow(bodyUI->showWindow->isChecked()); +// } // -//void UserInterfaceForm::on_groupOnlyNotfiyWhenMentioned_stateChanged() +// void UserInterfaceForm::on_groupOnlyNotfiyWhenMentioned_stateChanged() //{ -// // Note: UI is boolean inversed from settings to maintain setting file backwards compatibility -//// Settings::getInstance().setGroupAlwaysNotify(!bodyUI->groupOnlyNotfiyWhenMentioned->isChecked()); +// // Note: UI is boolean inversed from settings to maintain setting file backwards +// compatibility +//// +/// Settings::getInstance().setGroupAlwaysNotify(!bodyUI->groupOnlyNotfiyWhenMentioned->isChecked()); //} - -//void UserInterfaceForm::on_themeColorCBox_currentIndexChanged(int) +// void UserInterfaceForm::on_themeColorCBox_currentIndexChanged(int) //{ -// int index = bodyUI->themeColorCBox->currentIndex(); -// Settings::getInstance().setThemeColor(index); -// Style::setThemeColor(index); -// Style::applyTheme(); -//} +// int index = bodyUI->themeColorCBox->currentIndex(); +// Settings::getInstance().setThemeColor(index); +// Style::setThemeColor(index); +// Style::applyTheme(); +// } /** * @brief Retranslate all elements in the form. */ -void UserInterfaceForm::retranslateUi() -{ +void UserInterfaceForm::retranslateUi() { // Block signals during translation to prevent settings change RecursiveSignalBlocker signalBlocker{this}; bodyUI->retranslateUi(this); // Restore text style index once translation is complete -// bodyUI->textStyleComboBox->setCurrentIndex( -// static_cast(Settings::getInstance().getStylePreference())); -// -// QStringList colorThemes(Style::getThemeColorNames()); -// for (int i = 0; i < colorThemes.size(); ++i) { -// bodyUI->themeColorCBox->setItemText(i, colorThemes[i]); -// } -// -// bodyUI->styleBrowser->setItemText(0, tr("None")); + // bodyUI->textStyleComboBox->setCurrentIndex( + // static_cast(Settings::getInstance().getStylePreference())); + // + // QStringList colorThemes(Style::getThemeColorNames()); + // for (int i = 0; i < colorThemes.size(); ++i) { + // bodyUI->themeColorCBox->setItemText(i, colorThemes[i]); + // } + // + // bodyUI->styleBrowser->setItemText(0, tr("None")); } // -//void UserInterfaceForm::on_txtChatFont_currentFontChanged(const QFont& f) +// void UserInterfaceForm::on_txtChatFont_currentFontChanged(const QFont& f) //{ // QFont tmpFont = f; // const int px = bodyUI->txtChatFontSize->value(); @@ -283,7 +277,7 @@ void UserInterfaceForm::retranslateUi() // Settings::getInstance().setChatMessageFont(tmpFont); //} // -//void UserInterfaceForm::on_txtChatFontSize_valueChanged(int px) +// void UserInterfaceForm::on_txtChatFontSize_valueChanged(int px) //{ // Settings& s = Settings::getInstance(); // QFont tmpFont = s.getChatMessageFont(); @@ -295,14 +289,14 @@ void UserInterfaceForm::retranslateUi() // } //} // -//void UserInterfaceForm::on_useNameColors_stateChanged(int value) +// void UserInterfaceForm::on_useNameColors_stateChanged(int value) //{ // Settings::getInstance().setEnableGroupChatsColor(value); //} // -//void UserInterfaceForm::on_notifyHide_stateChanged(int value) +// void UserInterfaceForm::on_notifyHide_stateChanged(int value) //{ // Settings::getInstance().setNotifyHide(value); //} -} +} // namespace UI diff --git a/src/UI/window/config/settings/src/UserInterfaceForm.h b/src/UI/window/config/settings/src/UserInterfaceForm.h index 8215c781..45c7c470 100644 --- a/src/UI/window/config/settings/src/UserInterfaceForm.h +++ b/src/UI/window/config/settings/src/UserInterfaceForm.h @@ -24,41 +24,41 @@ class UserInterfaceForm; namespace UI { class UserInterfaceForm : public GenericForm { - Q_OBJECT + Q_OBJECT public: - explicit UserInterfaceForm(SettingsWidget *myParent); - ~UserInterfaceForm(); - QString getFormName() final override { return tr("User Interface"); } + explicit UserInterfaceForm(SettingsWidget* myParent); + ~UserInterfaceForm(); + QString getFormName() final override { return tr("User Interface"); } private slots: -// void on_styleBrowser_currentIndexChanged(QString style); - void on_timestamp_editTextChanged(const QString &format); - void on_dateFormats_editTextChanged(const QString &format); -// void on_textStyleComboBox_currentTextChanged(); -// void on_useEmoticons_stateChanged(); -// void on_notify_stateChanged(); -// void on_desktopNotify_stateChanged(); -// void on_notifySound_stateChanged(); -// void on_notifyHide_stateChanged(int); -// void on_busySound_stateChanged(); -// void on_showWindow_stateChanged(); -// void on_groupOnlyNotfiyWhenMentioned_stateChanged(); -// -// void on_themeColorCBox_currentIndexChanged(int); -// -// void on_txtChatFont_currentFontChanged(const QFont &f); -// void on_txtChatFontSize_valueChanged(int arg1); -// void on_useNameColors_stateChanged(int value); + // void on_styleBrowser_currentIndexChanged(QString style); + void on_timestamp_editTextChanged(const QString& format); + void on_dateFormats_editTextChanged(const QString& format); + // void on_textStyleComboBox_currentTextChanged(); + // void on_useEmoticons_stateChanged(); + // void on_notify_stateChanged(); + // void on_desktopNotify_stateChanged(); + // void on_notifySound_stateChanged(); + // void on_notifyHide_stateChanged(int); + // void on_busySound_stateChanged(); + // void on_showWindow_stateChanged(); + // void on_groupOnlyNotfiyWhenMentioned_stateChanged(); + // + // void on_themeColorCBox_currentIndexChanged(int); + // + // void on_txtChatFont_currentFontChanged(const QFont &f); + // void on_txtChatFontSize_valueChanged(int arg1); + // void on_useNameColors_stateChanged(int value); private: - void retranslateUi(); + void retranslateUi(); private: - QList smileLabels; - QList> emoticonsIcons; - SettingsWidget *parent; - Ui::UserInterfaceForm *bodyUI; - const int MAX_FORMAT_LENGTH = 128; + QList smileLabels; + QList> emoticonsIcons; + SettingsWidget* parent; + Ui::UserInterfaceForm* bodyUI; + const int MAX_FORMAT_LENGTH = 128; }; -} // namespace UI \ No newline at end of file +} // namespace UI \ No newline at end of file diff --git a/src/UI/window/config/src/ConfigWindow.cpp b/src/UI/window/config/src/ConfigWindow.cpp index c67dce22..5368f614 100644 --- a/src/UI/window/config/src/ConfigWindow.cpp +++ b/src/UI/window/config/src/ConfigWindow.cpp @@ -30,55 +30,49 @@ #include #endif - namespace UI { -ConfigWindow::ConfigWindow(QWidget *parent) - : OMenuWidget(parent), ui(new Ui::ConfigWindow){ - - OK_RESOURCE_INIT(UIWindowConfig); +ConfigWindow::ConfigWindow(QWidget* parent) : OMenuWidget(parent), ui(new Ui::ConfigWindow) { + OK_RESOURCE_INIT(UIWindowConfig); - ui->setupUi(this); - setObjectName(qsl("Page:%1").arg(static_cast(PageMenu::setting))); + ui->setupUi(this); - auto qss = ok::base::Files::readStringAll(":/qss/plugin.qss"); - setStyleSheet(qss); + auto qss = ok::base::Files::readStringAll(":/qss/plugin.qss"); + setStyleSheet(qss); - QString locale = ok::base::OkSettings::getInstance().getTranslation(); - settings::Translator::translate(OK_UIWindowConfig_MODULE, locale); - settings::Translator::registerHandler([this] { retranslateUi(); }, this); - retranslateUi(); + QString locale = ok::base::OkSettings::getInstance().getTranslation(); + settings::Translator::translate(OK_UIWindowConfig_MODULE, locale); + settings::Translator::registerHandler([this] { retranslateUi(); }, this); + retranslateUi(); #if OK_PLUGIN - ui->tabWidget->addTab(new ok::plugin::PluginManagerForm(this), tr("Plugin form")); + ui->tabWidget->addTab(new ok::plugin::PluginManagerForm(this), tr("Plugin form")); #endif - auto sw = new SettingsWidget(this); - connect( sw->general(), &GeneralForm::onLanguageChanged, [](QString locale){ - settings::Translator::translate(OK_UIWindowConfig_MODULE, locale); - }); + auto sw = new SettingsWidget(this); + connect(sw->general(), &GeneralForm::onLanguageChanged, [](QString locale) { + settings::Translator::translate(OK_UIWindowConfig_MODULE, locale); + }); - - ui->tabWidget->addTab(sw, tr("Settings form")); - ui->tabWidget->addTab(new AboutForm(this), tr("About form")); + ui->tabWidget->addTab(sw, tr("Settings form")); + ui->tabWidget->addTab(new AboutForm(this), tr("About form")); } ConfigWindow::~ConfigWindow() { - settings::Translator::unregister(this); - delete ui; + settings::Translator::unregister(this); + delete ui; } void ConfigWindow::retranslateUi() { - ui->retranslateUi(this); - ui->tabWidget->setTabText(0,tr("Plugin form") ); - ui->tabWidget->setTabText(1,tr("Settings form") ); - ui->tabWidget->setTabText(2,tr("About form") ); - - for(int i = 0; i < ui->tabWidget->count(); i++){ - auto gf = static_cast( ui->tabWidget->widget(i)); - gf->retranslateUi(); - } - + ui->retranslateUi(this); + ui->tabWidget->setTabText(0, tr("Plugin form")); + ui->tabWidget->setTabText(1, tr("Settings form")); + ui->tabWidget->setTabText(2, tr("About form")); + + for (int i = 0; i < ui->tabWidget->count(); i++) { + auto gf = static_cast(ui->tabWidget->widget(i)); + gf->retranslateUi(); + } } -} // namespace UI +} // namespace UI diff --git a/src/UI/window/config/src/ConfigWindow.h b/src/UI/window/config/src/ConfigWindow.h index 12479373..fe7fbdc8 100644 --- a/src/UI/window/config/src/ConfigWindow.h +++ b/src/UI/window/config/src/ConfigWindow.h @@ -25,40 +25,39 @@ OK_RESOURCE_LOADER(UIWindowConfig) -namespace Ui{ +namespace Ui { class ConfigWindow; } namespace UI { class ConfigWindow : public OMenuWidget { - Q_OBJECT + Q_OBJECT public: - ConfigWindow(QWidget *parent = nullptr); - ~ConfigWindow() ; + ConfigWindow(QWidget* parent = nullptr); + ~ConfigWindow(); protected: - void retranslateUi(); + void retranslateUi(); private: + OK_RESOURCE_PTR(UIWindowConfig); - OK_RESOURCE_PTR(UIWindowConfig); + Ui::ConfigWindow* ui; + bool inited = false; - Ui::ConfigWindow *ui; - bool inited = false; + std::unique_ptr bodyLayout; + std::unique_ptr settingsWidgets; - std::unique_ptr bodyLayout; - std::unique_ptr settingsWidgets; - - // std::unique_ptr _hLayout; - // QGridLayout *_gLayout; - // std::unique_ptr _stack_view; + // std::unique_ptr _hLayout; + // QGridLayout *_gLayout; + // std::unique_ptr _stack_view; signals: - // void view(widget::SettingViewMenu menu); + // void view(widget::SettingViewMenu menu); public slots: - // void onMenu(int id); + // void onMenu(int id); }; -} // namespace UI +} // namespace UI diff --git a/src/UI/window/login/CMakeLists.txt b/src/UI/window/login/CMakeLists.txt index 5d2982b3..d24bb614 100644 --- a/src/UI/window/login/CMakeLists.txt +++ b/src/UI/window/login/CMakeLists.txt @@ -55,7 +55,7 @@ execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different qt5_add_resources( ${PROJECT_NAME}_RESOURCES - ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.qrc + ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.qrc ) add_library(${PROJECT_NAME} STATIC diff --git a/src/UI/window/login/src/BannerWidget.cpp b/src/UI/window/login/src/BannerWidget.cpp index d40c2c68..c331aa0f 100644 --- a/src/UI/window/login/src/BannerWidget.cpp +++ b/src/UI/window/login/src/BannerWidget.cpp @@ -22,19 +22,15 @@ namespace UI { +BannerWidget::BannerWidget(QWidget* parent) + : QWidget(parent), ui(std::make_unique()) { + ui->setupUi(this); - -BannerWidget::BannerWidget(QWidget *parent) - : QWidget(parent), ui(std::make_unique()) { - ui->setupUi(this); - - ui->imgBox->setGeometry(rect()); - ui->imgBox->setFixedSize(256,256); - ui->imgBox->setStyleSheet("border-image: url(:/resources/logo/main.svg);"); + ui->imgBox->setGeometry(rect()); + ui->imgBox->setFixedSize(256, 256); + ui->imgBox->setStyleSheet("border-image: url(:/resources/logo/main.svg);"); } BannerWidget::~BannerWidget() {} - - -} // namespace UI +} // namespace UI diff --git a/src/UI/window/login/src/BannerWidget.h b/src/UI/window/login/src/BannerWidget.h index 890dcbc1..f0c01ccb 100644 --- a/src/UI/window/login/src/BannerWidget.h +++ b/src/UI/window/login/src/BannerWidget.h @@ -21,18 +21,16 @@ class BannerWidget; namespace UI { - - class BannerWidget : public QWidget { - Q_OBJECT + Q_OBJECT public: - explicit BannerWidget(QWidget *parent = nullptr); + explicit BannerWidget(QWidget* parent = nullptr); - ~BannerWidget(); + ~BannerWidget(); private: - std::unique_ptr ui; + std::unique_ptr ui; }; -} // namespace UI +} // namespace UI diff --git a/src/UI/window/login/src/LoginWidget.cpp b/src/UI/window/login/src/LoginWidget.cpp index c3bcb785..69c40d6c 100644 --- a/src/UI/window/login/src/LoginWidget.cpp +++ b/src/UI/window/login/src/LoginWidget.cpp @@ -33,193 +33,203 @@ using namespace ok; using namespace ok::session; using namespace ok::base; -LoginWidget::LoginWidget(bool bootstrap, QWidget *parent) - : QWidget(parent), // - ui(new Ui::LoginWidget), // - bootstrap{bootstrap}, m_loginKey(nullptr), // - m_settingManager(new SettingManager(this)), // - m_loaded(0) { - qDebug() << __func__; - ui->setupUi(this); - - // return keyboard - m_loginKey = new QShortcut(QKeySequence(Qt::Key_Return), this); - connect(m_loginKey, SIGNAL(activated()), this, SLOT(on_loginBtn_released())); - - // translator - settings::Translator::registerHandler([&] { retranslateUi(); }, this); - - // timer for login #TODO need to refactor - if (bootstrap) { - qDebug() << __func__ << "Init timer"; - m_timer = std::make_unique(); - m_timer->start(1000); - connect(m_timer.get(), &QTimer::timeout, this, &LoginWidget::onTimeout); - } - // connect login result - connect(ok::session::AuthSession::Instance(), &AuthSession::loginResult, this, &LoginWidget::onConnectResult); - - init(); +LoginWidget::LoginWidget(std::shared_ptr session, bool bootstrap, + QWidget* parent) + : QWidget(parent) + , // + ui(new Ui::LoginWidget) + , session(session) + , // + bootstrap{bootstrap} + , m_loginKey(nullptr) + , // + m_settingManager(new SettingManager(this)) + , // + m_loaded(0) { + qDebug() << __func__; + ui->setupUi(this); + + // return keyboard + m_loginKey = new QShortcut(QKeySequence(Qt::Key_Return), this); + connect(m_loginKey, SIGNAL(activated()), this, SLOT(on_loginBtn_released())); + + // translator + settings::Translator::registerHandler([&] { retranslateUi(); }, this); + + // timer for login #TODO need to refactor + if (bootstrap) { + qDebug() << __func__ << "Init timer"; + m_timer = std::make_unique(); + m_timer->start(3000); + connect(m_timer.get(), &QTimer::timeout, this, &LoginWidget::onTimeout); + } + + // session + connect(session.get(), // + &AuthSession::loginResult, // + this, &LoginWidget::onLoginResult); + init(); } LoginWidget::~LoginWidget() { - qDebug() << __func__; - settings::Translator::unregister(this); - delete ui; + qDebug() << __func__; + settings::Translator::unregister(this); + delete ui; } void LoginWidget::init() { - // 1. get remember account - m_settingManager->getAccount([&](const QString &acc, const QString &password) { - ui->rember->setChecked(!acc.isEmpty()); - ui->accountInput->setText(acc); - ui->passwordInput->setText(password); - }); - - // 2. i18n - auto &setting = ok::base::OkSettings::getInstance(); - qDebug() << "Last settings translation:" << setting.getTranslation(); - - for (int i = 0; i < setting.getLocales().size(); ++i) { - auto &locale = setting.getLocales().at(i); - QString langName = QLocale(locale).nativeLanguageName(); - ui->language->addItem(langName); - } - // set default - auto i = setting.getLocales().indexOf(setting.getTranslation()); - if (i >= 0 && i < ui->language->count()) - ui->language->setCurrentIndex(i + 1); - - retranslateUi(); - - // 3.provider - okCloudService = new ok::backend::OkCloudService(this); - okCloudService->GetFederalInfo( - [&](ok::backend::Res &res) { - for (const auto &item : res.data->states) { - if (!item.xmppHost.isEmpty()) { - ui->providers->addItem(item.name); - m_hosts.push_back(item.xmppHost); - m_stacks.push_back(item.stackUrl); - } - } - - if (ui->providers->count() > 1) { - auto &setting = ok::base::OkSettings::getInstance(); - int index = ui->providers->findText(setting.getProvider()); - // found - if (index != -1) { - ui->providers->setCurrentIndex(index); - } else { - qDebug() << "provide not found in the comboBox: " << setting.getProvider(); - ui->providers->setCurrentIndex(1); - } - - m_loaded++; - } - }, - [&](int code, const QString &error) { onError(code, error); }); - - // 4. UI - ui->signUp->setStyleSheet("QLabel { color: blue; text-decoration: underline; } " - "QLabel:hover { color: red; }"); - ui->signUp->setCursor(Qt::PointingHandCursor); - - ui->findPwd->setStyleSheet("QLabel { color: blue; text-decoration: underline; } " - "QLabel:hover { color: red; }"); - ui->findPwd->setCursor(Qt::PointingHandCursor); - - ui->loginBtn->setCursor(Qt::PointingHandCursor); - - ui->signUp->installEventFilter(this); - ui->findPwd->installEventFilter(this); + // 1. get remember account + m_settingManager->getAccount([&](const QString& acc, const QString& password) { + ui->rember->setChecked(!acc.isEmpty()); + ui->accountInput->setText(acc); + ui->passwordInput->setText(password); + }); + + // 2. i18n + auto& setting = ok::base::OkSettings::getInstance(); + qDebug() << "Last settings translation:" << setting.getTranslation(); + + for (int i = 0; i < setting.getLocales().size(); ++i) { + auto& locale = setting.getLocales().at(i); + QString langName = QLocale(locale).nativeLanguageName(); + ui->language->addItem(langName); + } + // set default + auto i = setting.getLocales().indexOf(setting.getTranslation()); + if (i >= 0 && i < ui->language->count()) ui->language->setCurrentIndex(i + 1); + + retranslateUi(); + + // 3.provider + okCloudService = new ok::backend::OkCloudService(this); + okCloudService->GetFederalInfo( + [&](ok::backend::Res& res) { + for (const auto& item : res.data->states) { + if (!item.xmppHost.isEmpty()) { + ui->providers->addItem(item.name); + m_hosts.push_back(item.xmppHost); + m_stacks.push_back(item.stackUrl); + } + } + + if (ui->providers->count() > 1) { + auto& setting = ok::base::OkSettings::getInstance(); + int index = ui->providers->findText(setting.getProvider()); + // found + if (index != -1) { + ui->providers->setCurrentIndex(index); + } else { + qDebug() << "provide not found in the comboBox: " << setting.getProvider(); + ui->providers->setCurrentIndex(1); + } + + m_loaded++; + } + }, + [&](int code, const QString& error) { onError(code, error); }); + + // 4. UI + ui->signUp->setStyleSheet( + "QLabel { color: blue; text-decoration: underline; } " + "QLabel:hover { color: red; }"); + ui->signUp->setCursor(Qt::PointingHandCursor); + + ui->findPwd->setStyleSheet( + "QLabel { color: blue; text-decoration: underline; } " + "QLabel:hover { color: red; }"); + ui->findPwd->setCursor(Qt::PointingHandCursor); + + ui->loginBtn->setCursor(Qt::PointingHandCursor); + + ui->signUp->installEventFilter(this); + ui->findPwd->installEventFilter(this); } void LoginWidget::deinit() {} void LoginWidget::doLogin() { - if (m_error) - return; - - if (m_loaded < 1) { - m_currentOriginalMsg = "Please waiting the page is loaded"; - setMsg(tr("Please waiting the page is loaded")); - return; - } - - // 获取服务提供商 - auto providerIdx = ui->providers->currentIndex(); - if (!(providerIdx > 0)) { - m_currentOriginalMsg = "Please select service provider"; - setMsg(tr("Please select service provider")); - return; - } - - // 对登录时状态判断 - auto status = ok::session::AuthSession::Instance()->status(); - switch (status) { - case ok::session::Status::SUCCESS: { - qDebug(("SUCCESS ...")); - return; - } - case ok::session::Status::CONNECTING: { - qDebug(("CONNECTING ...")); - // sess->interrupt(); - return; - } - default: { - QString host = m_hosts.at(providerIdx - 1); - qDebug() << "Select provider host:" << host; - - // 登陆 - QString account(ui->accountInput->text()); - QString password(ui->passwordInput->text()); - // 对账号和密码判断 - if (account.isEmpty()) { - return; - } - if (ui->rember->isCheckable()) { - m_settingManager->saveAccount(account, password); - } else { - m_settingManager->clearAccount(); + if (m_error) return; + + if (m_loaded < 1) { + m_currentOriginalMsg = "Please waiting the page is loaded"; + setMsg(tr("Please waiting the page is loaded")); + return; } - SignInInfo info = {.account = account, .password = password, .host = host, .stackUrl = m_stacks.at(providerIdx - 1)}; + // 获取服务提供商 + auto providerIdx = ui->providers->currentIndex(); + if (!(providerIdx > 0)) { + m_currentOriginalMsg = "Please select service provider"; + setMsg(tr("Please select service provider")); + return; + } - ok::session::AuthSession::Instance()->doLogin(info); - break; - } - } + // 对登录时状态判断 + auto status = session->status(); + switch (status) { + case ok::session::Status::SUCCESS: { + qDebug(("SUCCESS ...")); + return; + } + case ok::session::Status::CONNECTING: { + qDebug(("CONNECTING ...")); + // sess->interrupt(); + return; + } + default: { + QString host = m_hosts.at(providerIdx - 1); + qDebug() << "Select provider host:" << host; + + // 登陆 + QString account(ui->accountInput->text()); + QString password(ui->passwordInput->text()); + // 对账号和密码判断 + if (account.isEmpty()) { + qWarning() << "account is empty!"; + return; + } + if (ui->rember->isCheckable()) { + m_settingManager->saveAccount(account, password); + } else { + m_settingManager->clearAccount(); + } + + SignInInfo info = {.account = account, + .password = password, + .host = host, + .stackUrl = m_stacks.at(providerIdx - 1)}; + session->doLogin(info); + break; + } + } } -void LoginWidget::onConnectResult(ok::session::SignInInfo info, ok::session::LoginResult result) { - - qDebug() << __func__ << result.msg; - - switch (result.status) { - case ok::session::Status::NONE: - break; - case ok::session::Status::CONNECTING: { - ui->loginMessage->setText(tr("...")); - ui->loginBtn->setText(tr("Logging in")); - QString account(ui->accountInput->text()); - QString password(ui->passwordInput->text()); - emit loginFailed(account, password); - break; - } - case ok::session::Status::SUCCESS: { - ui->loginMessage->setText(tr("login success")); - QString account(ui->accountInput->text()); - QString password(ui->passwordInput->text()); - emit loginSuccess(account, password); - break; - } - case ok::session::Status::FAILURE: - ui->loginBtn->setText(tr("Login")); - onError(result.statusCode, result.msg); - break; - } - emit loginResult(info, result); +void LoginWidget::onLoginResult(ok::session::SignInInfo info, ok::session::LoginResult result) { + qDebug() << __func__ << info.account << info.password << result.msg; + + switch (result.status) { + case ok::session::Status::NONE: + break; + case ok::session::Status::CONNECTING: { + ui->loginMessage->setText(tr("...")); + ui->loginBtn->setText(tr("Logging in")); + QString account(ui->accountInput->text()); + QString password(ui->passwordInput->text()); + emit loginFailed(account, password); + break; + } + case ok::session::Status::SUCCESS: { + ui->loginMessage->setText(tr("login success")); + QString account(ui->accountInput->text()); + QString password(ui->passwordInput->text()); + emit loginSuccess(account, password); + break; + } + case ok::session::Status::FAILURE: + ui->loginBtn->setText(tr("Login")); + onError(result.statusCode, result.msg); + break; + } } void LoginWidget::on_loginBtn_released() { doLogin(); } @@ -228,111 +238,111 @@ void LoginWidget::on_loginBtn_released() { doLogin(); } * 语言选择事件 */ void LoginWidget::on_language_currentIndexChanged(int index) { - qDebug() << "Select language:" << index; - if (index == 0) { - return; - } - - auto &s = ok::base::OkSettings::getInstance(); - const QString &locale = s.getLocales().at(index - 1); - s.setTranslation(locale); - s.saveGlobal(); - qDebug() << "Selected locale:" << locale; - - settings::Translator::translate(OK_UIWindowLogin_MODULE, locale); - qDebug() << "Translated locale:" << locale; + qDebug() << "Select language:" << index; + if (index == 0) { + return; + } + + auto& s = ok::base::OkSettings::getInstance(); + const QString& locale = s.getLocales().at(index - 1); + s.setTranslation(locale); + s.saveGlobal(); + qDebug() << "Selected locale:" << locale; + + settings::Translator::translate(OK_UIWindowLogin_MODULE, locale); + qDebug() << "Translated locale:" << locale; } /** * 服务提供者事件 */ void LoginWidget::on_providers_currentIndexChanged(int index) { - qDebug() << "providers currentIndexChanged : " << index; - if (index <= 0) { - qDebug() << "provider index illegal"; - return; - } - - auto &setting = ok::base::OkSettings::getInstance(); - QString provider = ui->providers->currentText(); - QString settingProvider = setting.getProvider(); - - qDebug() << "setting provider: " << settingProvider << " wanna change to: " << provider; - - if (settingProvider == provider) { - qDebug() << "already in provider: " << provider; - return; - } - setting.setProvider(provider); - setting.saveGlobal(); - qDebug() << "change to provider:" << provider; -} + qDebug() << "providers currentIndexChanged : " << index; + if (index <= 0) { + qDebug() << "provider index illegal"; + return; + } -void LoginWidget::retranslateUi() { - ui->retranslateUi(this); - QString translatedMessage = tr(m_currentOriginalMsg.toUtf8().constData()); - setMsg(translatedMessage); -} + auto& setting = ok::base::OkSettings::getInstance(); + QString provider = ui->providers->currentText(); + QString settingProvider = setting.getProvider(); + + qDebug() << "setting provider: " << settingProvider << " wanna change to: " << provider; -void LoginWidget::onError(int statusCode, const QString &msg) { - QString newMsg = msg; - switch (statusCode / 100) { - case 0: { - newMsg = tr("Network is not available!"); - m_currentOriginalMsg = "Network is not available!"; - break; - } - case 4: { - newMsg = tr("Account does not exist!"); - m_currentOriginalMsg = "Account does not exist!"; - break; - } - case 5: { - newMsg = tr("Server error, please try again later!"); - m_currentOriginalMsg = "Server error, please try again later!"; - break; - } - } - - setMsg(newMsg); - m_timer.reset(); + if (settingProvider == provider) { + qDebug() << "already in provider: " << provider; + return; + } + setting.setProvider(provider); + setting.saveGlobal(); + qDebug() << "change to provider:" << provider; } -void LoginWidget::setMsg(const QString &msg) { ui->loginMessage->setText(msg); } +void LoginWidget::retranslateUi() { + ui->retranslateUi(this); + QString translatedMessage = tr(m_currentOriginalMsg.toUtf8().constData()); + setMsg(translatedMessage); +} -bool LoginWidget::eventFilter(QObject *obj, QEvent *event) { - switch (event->type()) { - case QEvent::MouseButtonPress: { - auto providerIdx = ui->providers->currentIndex(); - // validate - if (providerIdx <= 0 || m_stacks.size() <= 0) { - qWarning() << "providerIdx is illegal or servers is null"; - break; +void LoginWidget::onError(int statusCode, const QString& msg) { + QString newMsg = msg; + switch (statusCode / 100) { + case 0: { + newMsg = tr("Network is not available!"); + m_currentOriginalMsg = "Network is not available!"; + break; + } + case 4: { + newMsg = tr("Account does not exist!"); + m_currentOriginalMsg = "Account does not exist!"; + break; + } + case 5: { + newMsg = tr("Server error, please try again later!"); + m_currentOriginalMsg = "Server error, please try again later!"; + break; + } } - QString host = m_stacks.at(providerIdx - 1); - qDebug() << "Select provider host:" << host; - if (obj == ui->signUp) { - QDesktopServices::openUrl(QUrl(host + "/auth/register")); - } else if (obj == ui->findPwd) { - QDesktopServices::openUrl(QUrl(host + "/auth/forgot")); - } - break; - } - default: - break; - }; - return QObject::eventFilter(obj, event); + setMsg(newMsg); + m_timer.reset(); } -void LoginWidget::showEvent(QShowEvent *e) {} +void LoginWidget::setMsg(const QString& msg) { ui->loginMessage->setText(msg); } + +bool LoginWidget::eventFilter(QObject* obj, QEvent* event) { + switch (event->type()) { + case QEvent::MouseButtonPress: { + auto providerIdx = ui->providers->currentIndex(); + // validate + if (providerIdx <= 0 || m_stacks.size() <= 0) { + qWarning() << "providerIdx is illegal or servers is null"; + break; + } + QString host = m_stacks.at(providerIdx - 1); + qDebug() << "Select provider host:" << host; + + if (obj == ui->signUp) { + QDesktopServices::openUrl(QUrl(host + "/auth/register")); + } else if (obj == ui->findPwd) { + QDesktopServices::openUrl(QUrl(host + "/auth/forgot")); + } + break; + } + default: + break; + }; + return QObject::eventFilter(obj, event); +} + +void LoginWidget::showEvent(QShowEvent* e) {} void LoginWidget::onTimeout() { - if (ui->rember->isChecked() && ui->providers->count() > 0) { - if (!ui->passwordInput->text().isEmpty() && !ui->accountInput->text().isEmpty()) { - on_loginBtn_released(); + if (ui->rember->isChecked() && ui->providers->count() > 0) { + if (!ui->passwordInput->text().isEmpty() && !ui->accountInput->text().isEmpty()) { + on_loginBtn_released(); + } } - } } -} // namespace UI +} // namespace UI diff --git a/src/UI/window/login/src/LoginWidget.h b/src/UI/window/login/src/LoginWidget.h index 20233848..15d4c564 100644 --- a/src/UI/window/login/src/LoginWidget.h +++ b/src/UI/window/login/src/LoginWidget.h @@ -26,7 +26,6 @@ namespace Ui { class LoginWidget; } - namespace ok::backend { class OkCloudService; } @@ -34,57 +33,56 @@ namespace session { class AuthSession; } - namespace UI { class LoginWidget : public QWidget { - Q_OBJECT + Q_OBJECT public: - explicit LoginWidget(bool bootstrap, QWidget *parent = nullptr); - ~LoginWidget() override; - void onError(int code, const QString &msg); - void setMsg(const QString &msg); - void init(); - void deinit(); + explicit LoginWidget(std::shared_ptr session, bool bootstrap, + QWidget* parent = nullptr); + ~LoginWidget() override; + void onError(int code, const QString& msg); + void setMsg(const QString& msg); + void init(); + void deinit(); protected: - void retranslateUi(); - virtual bool eventFilter(QObject *obj, QEvent *event) override; - virtual void showEvent(QShowEvent *e) override; + void retranslateUi(); + virtual bool eventFilter(QObject* obj, QEvent* event) override; + virtual void showEvent(QShowEvent* e) override; + private: - bool bootstrap; - Ui::LoginWidget *ui; + Ui::LoginWidget* ui; + std::shared_ptr session; + bool bootstrap; - QShortcut *m_loginKey; + QShortcut* m_loginKey; - ok::SettingManager *m_settingManager; - ok::backend::OkCloudService *okCloudService; + ok::SettingManager* m_settingManager; + ok::backend::OkCloudService* okCloudService; - bool m_error = false; + bool m_error = false; - //加载项 - int m_loaded; + // 加载项 + int m_loaded; - QStringList m_hosts; - QStringList m_stacks; - std::unique_ptr m_timer; - QString m_currentOriginalMsg{""}; + QStringList m_hosts; + QStringList m_stacks; + std::unique_ptr m_timer; + QString m_currentOriginalMsg{""}; signals: - void loginSuccess(QString name, QString password); - void loginFailed(QString name, QString password); - void loginTimeout(QString name); - void loginResult(ok::session::SignInInfo &info, - ok::session::LoginResult &result); + void loginSuccess(QString name, QString password); + void loginFailed(QString name, QString password); + void loginTimeout(QString name); private slots: - void onTimeout(); - void doLogin(); - void onConnectResult(ok::session::SignInInfo info, - ok::session::LoginResult result); - void on_loginBtn_released(); - void on_language_currentIndexChanged(int index); - void on_providers_currentIndexChanged(int index); + void onTimeout(); + void doLogin(); + void onLoginResult(ok::session::SignInInfo info, ok::session::LoginResult result); + void on_loginBtn_released(); + void on_language_currentIndexChanged(int index); + void on_providers_currentIndexChanged(int index); }; -} // namespace UI +} // namespace UI diff --git a/src/UI/window/login/src/LoginWindow.cpp b/src/UI/window/login/src/LoginWindow.cpp index b59af3ad..269ae819 100644 --- a/src/UI/window/login/src/LoginWindow.cpp +++ b/src/UI/window/login/src/LoginWindow.cpp @@ -10,60 +10,53 @@ * See the Mulan PubL v2 for more details. */ -#include "BannerWidget.h" #include "LoginWindow.h" +#include "BannerWidget.h" #include "LoginWidget.h" #include "base/files.h" #include "base/resources.h" #include "ui_LoginWindow.h" - namespace UI { - using namespace ok::session; /* 登录主窗口 */ -LoginWindow::LoginWindow(bool bootstrap, QWidget *parent) - : QMainWindow(parent), ui(new Ui::LoginWindow) { +LoginWindow::LoginWindow(std::shared_ptr session, bool bootstrap, + QWidget* parent) + : QMainWindow(parent), ui(new Ui::LoginWindow) { + // 初始化资源 + OK_RESOURCE_INIT(UIWindowLogin); - //初始化资源 - OK_RESOURCE_INIT(UIWindowLogin); + setAttribute(Qt::WA_DeleteOnClose, true); + setWindowTitle(APPLICATION_NAME); + // 黄金分割比例 874/520 = 1.618 + setFixedSize(QSize(874, 520)); - setAttribute(Qt::WA_DeleteOnClose, true); - setWindowTitle(APPLICATION_NAME); - //黄金分割比例 874/520 = 1.618 - setFixedSize(QSize(874, 520)); + ui->setupUi(this); - ui->setupUi(this); + bannerWidget = new BannerWidget(this); + bannerWidget->setFixedWidth(width() / 2); - bannerWidget = new BannerWidget(this); - bannerWidget->setFixedWidth(width()/2); + ui->hBoxLayout->addWidget(bannerWidget); - ui->hBoxLayout->addWidget(bannerWidget); + loginWidget = new LoginWidget(session, bootstrap, this); + ui->hBoxLayout->addWidget(loginWidget); - loginWidget = new LoginWidget(bootstrap, this); - ui->hBoxLayout->addWidget(loginWidget); + // 设置样式 + QString qss = ok::base::Files::readStringAll(":/qss/login.qss"); + setStyleSheet(qss); - - // 设置样式 - QString qss = ok::base::Files::readStringAll(":/qss/login.qss"); - setStyleSheet(qss); - - connect(loginWidget, &UI::LoginWidget::loginResult, - [&](ok::session::SignInInfo &info, // - ok::session::LoginResult &result) { - emit loginResult(info, result); - }); + // connect(loginWidget, &UI::LoginWidget::loginResult, + // [&](ok::session::SignInInfo &info, // + // ok::session::LoginResult &result) { + // emit loginResult(info, result); + // }); } -LoginWindow::~LoginWindow() { - qDebug() << __func__; -} +LoginWindow::~LoginWindow() { qDebug() << __func__; } -void LoginWindow::onProfileLoadFailed(QString msg) { - loginWidget->onError(200, msg); -} +void LoginWindow::onProfileLoadFailed(QString msg) { loginWidget->onError(200, msg); } -} // namespace UI +} // namespace UI diff --git a/src/UI/window/login/src/LoginWindow.h b/src/UI/window/login/src/LoginWindow.h index 90a6bc4b..2f6cc11a 100644 --- a/src/UI/window/login/src/LoginWindow.h +++ b/src/UI/window/login/src/LoginWindow.h @@ -15,16 +15,15 @@ #include #include -#include "lib/session/AuthSession.h" #include "base/resources.h" +#include "lib/session/AuthSession.h" - -//初始化资源加载器 +// 初始化资源加载器 OK_RESOURCE_LOADER(UIWindowLogin) namespace Ui { class LoginWindow; -} // namespace Ui +} // namespace Ui namespace UI { @@ -32,24 +31,24 @@ class LoginWidget; class BannerWidget; class LoginWindow : public QMainWindow { - Q_OBJECT + Q_OBJECT public: - explicit LoginWindow(bool bootstrap, QWidget *parent = nullptr); - ~LoginWindow(); + explicit LoginWindow(std::shared_ptr session, bool bootstrap, + QWidget* parent = nullptr); + ~LoginWindow(); -private: - Ui::LoginWindow *ui; - LoginWidget* loginWidget; - BannerWidget* bannerWidget; + [[nodiscard]] LoginWidget* widget() { return loginWidget; } - //资源指针申明 - OK_RESOURCE_PTR(UIWindowLogin); +private: + Ui::LoginWindow* ui; + LoginWidget* loginWidget; + BannerWidget* bannerWidget; -signals: - void loginResult(ok::session::SignInInfo &, ok::session::LoginResult &); + // 资源指针申明 + OK_RESOURCE_PTR(UIWindowLogin); public slots: - void onProfileLoadFailed(QString msg); + void onProfileLoadFailed(QString msg); }; -} // namespace UI +} // namespace UI diff --git a/src/UI/window/main/src/MainWindow.cpp b/src/UI/window/main/src/MainWindow.cpp index eacae9d6..39ce8f1c 100644 --- a/src/UI/window/main/src/MainWindow.cpp +++ b/src/UI/window/main/src/MainWindow.cpp @@ -27,95 +27,100 @@ #include #include #include +#include #include #include namespace UI { -static MainWindow *instance = nullptr; +static MainWindow* instance = nullptr; -MainWindow::MainWindow(ok::session::SignInInfo &m_signInInfo_, QWidget *parent) - : QMainWindow(parent), ui(new Ui::MainWindow), m_signInInfo{m_signInInfo_} { +MainWindow::MainWindow(std::shared_ptr session, QWidget* parent) + : QMainWindow(parent) + , ui(new Ui::MainWindow) + , delayCaller(std::make_unique()) + , session{session} { + qDebug() << __func__; - qDebug() << __func__; + ui->setupUi(this); + // setStyleSheet("QMainWindow{background-color: white;}"); + // setAutoFillBackground(false); - ui->setupUi(this); - // setStyleSheet("QMainWindow{background-color: white;}"); - // setAutoFillBackground(false); + setAutoFillBackground(true); + // 创建一个QPalette对象 + QPalette palette = this->palette(); + // 设置背景颜色为浅蓝色 + palette.setColor(QPalette::Window, Qt::white); + // 应用新的调色板 + this->setPalette(palette); - setAutoFillBackground(true); - // 创建一个QPalette对象 - QPalette palette = this->palette(); - // 设置背景颜色为浅蓝色 - palette.setColor(QPalette::Window, Qt::white); - // 应用新的调色板 - this->setPalette(palette); + setWindowTitle(APPLICATION_NAME); + setAttribute(Qt::WA_QuitOnClose, true); + // 黄金分割比例 874/520 = 1.618 + setMinimumSize(QSize(874, 520)); - setWindowTitle(APPLICATION_NAME); - setAttribute(Qt::WA_QuitOnClose, true); - // 黄金分割比例 874/520 = 1.618 - setMinimumSize(QSize(874, 520)); + m_menu = ui->menu_widget; - m_menu = ui->menu_widget; + timer = std::make_unique(); + timer->start(1000); + connect(timer.get(), &QTimer::timeout, this, &MainWindow::onTryCreateTrayIcon); - timer = new QTimer(this); - timer->start(1000); - connect(timer, &QTimer::timeout, this, &MainWindow::onTryCreateTrayIcon); + int icon_size = 15; - int icon_size = 15; - - actionQuit = new QAction(this); + actionQuit = new QAction(this); #ifndef Q_OS_OSX - actionQuit->setMenuRole(QAction::QuitRole); + actionQuit->setMenuRole(QAction::QuitRole); #endif - actionQuit->setIcon(prepareIcon(Style::getImagePath("rejectCall/rejectCall.svg"), icon_size, icon_size)); - actionQuit->setText(tr("Exit", "Tray action menu to exit tox")); - connect(actionQuit, &QAction::triggered, qApp, &QApplication::quit); + actionQuit->setIcon( + prepareIcon(Style::getImagePath("rejectCall/rejectCall.svg"), icon_size, icon_size)); + actionQuit->setText(tr("Exit", "Tray action menu to exit tox")); + connect(actionQuit, &QAction::triggered, qApp, &QApplication::quit); - actionShow = new QAction(this); - actionShow->setText(tr("Show", "Tray action menu to show window")); - connect(actionShow, &QAction::triggered, this, &MainWindow::forceShow); + actionShow = new QAction(this); + actionShow->setText(tr("Show", "Tray action menu to show window")); + connect(actionShow, &QAction::triggered, this, &MainWindow::forceShow); - // connect to menu - connect(m_menu, &OMainMenu::menuPushed, this, &MainWindow::onSwitchPage); + // connect to menu + connect(m_menu, &OMainMenu::menuPushed, this, &MainWindow::onSwitchPage); - instance = this; + instance = this; } MainWindow::~MainWindow() { - qDebug() << __func__; - disconnect(m_menu); - delete ui; + qDebug() << __func__; + disconnect(m_menu); + delete ui; } -MainWindow *MainWindow::getInstance() { return instance; } +MainWindow* MainWindow::getInstance() { return instance; } // Preparing needed to set correct size of icons for GTK tray backend inline QIcon MainWindow::prepareIcon(QString path, int w, int h) { #ifdef Q_OS_LINUX - QString desktop = getenv("XDG_CURRENT_DESKTOP"); - if (desktop.isEmpty()) { - desktop = getenv("DESKTOP_SESSION"); - } + QString desktop = getenv("XDG_CURRENT_DESKTOP"); + if (desktop.isEmpty()) { + desktop = getenv("DESKTOP_SESSION"); + } - desktop = desktop.toLower(); - if (desktop == "xfce" || desktop.contains("gnome") || desktop == "mate" || desktop == "x-cinnamon") { - if (w > 0 && h > 0) { - QSvgRenderer renderer(path); + desktop = desktop.toLower(); + if (desktop == "xfce" || desktop.contains("gnome") || desktop == "mate" || + desktop == "x-cinnamon") { + if (w > 0 && h > 0) { + QSvgRenderer renderer(path); - QPixmap pm(w, h); - pm.fill(Qt::transparent); - QPainter painter(&pm); - renderer.render(&painter, pm.rect()); + QPixmap pm(w, h); + pm.fill(Qt::transparent); + QPainter painter(&pm); + renderer.render(&painter, pm.rect()); - return QIcon(pm); + return QIcon(pm); + } } - } #endif - return QIcon(path); + return QIcon(path); } // void MainWindow::saveWindowGeometry() { @@ -129,187 +134,196 @@ inline QIcon MainWindow::prepareIcon(QString path, int w, int h) { // } // } -void MainWindow::showEvent(QShowEvent *event) {} +void MainWindow::showEvent(QShowEvent* event) {} -void MainWindow::closeEvent(QCloseEvent *event) { - qDebug() << __func__ << "closeEvent..."; - // auto &settings = ok::base::OkSettings::getInstance(); +void MainWindow::closeEvent(QCloseEvent* event) { + qDebug() << __func__ << "closeEvent..."; + // auto &settings = ok::base::OkSettings::getInstance(); - // if (settings.getShowSystemTray() && settings.getCloseToTray()) { - // QWidget::closeEvent(event); - // close(); - // return; - // } + // if (settings.getShowSystemTray() && settings.getCloseToTray()) { + // QWidget::closeEvent(event); + // close(); + // return; + // } - // if (autoAwayActive) { - // emit statusSet(Status::Status::Online); - // autoAwayActive = false; - // } - // saveWindowGeometry(); + // if (autoAwayActive) { + // emit statusSet(Status::Status::Online); + // autoAwayActive = false; + // } + // saveWindowGeometry(); - // emit toClose(); + // emit toClose(); - // saveSplitterGeometry(); - // QWidget::closeEvent(event); - // qApp->quit(); + // saveSplitterGeometry(); + // QWidget::closeEvent(event); + // qApp->quit(); -// emit Nexus::getInstance().exit(""); + // emit Nexus::getInstance().exit(""); } void MainWindow::init() {} void MainWindow::onTryCreateTrayIcon() { - auto &settings = ok::base::OkSettings::getInstance(); - - static int32_t tries = 15; - if (!icon && tries--) { - if (QSystemTrayIcon::isSystemTrayAvailable()) { - icon = std::unique_ptr(new QSystemTrayIcon); - updateIcons(); - trayMenu = new QMenu(this); - - // adding activate to the top, avoids accidentally clicking quit - trayMenu->addAction(actionShow); - // trayMenu->addSeparator(); - // trayMenu->addAction(statusOnline); - // trayMenu->addAction(statusAway); - // trayMenu->addAction(statusBusy); - // trayMenu->addSeparator(); - // trayMenu->addAction(actionLogout); - trayMenu->addAction(actionQuit); - icon->setContextMenu(trayMenu); - - connect(icon.get(), &QSystemTrayIcon::activated, this, &MainWindow::onIconClick); - - if (settings.getShowSystemTray()) { - icon->show(); - setHidden(settings.getAutostartInTray()); - } else { - show(); - } + auto& settings = ok::base::OkSettings::getInstance(); + + static int32_t tries = 15; + if (!icon && tries--) { + if (QSystemTrayIcon::isSystemTrayAvailable()) { + icon = std::make_unique(); + updateIcons(); + trayMenu = new QMenu(this); + + // adding activate to the top, avoids accidentally clicking quit + trayMenu->addAction(actionShow); + // trayMenu->addSeparator(); + // trayMenu->addAction(statusOnline); + // trayMenu->addAction(statusAway); + // trayMenu->addAction(statusBusy); + // trayMenu->addSeparator(); + // trayMenu->addAction(actionLogout); + trayMenu->addAction(actionQuit); + icon->setContextMenu(trayMenu); + + connect(icon.get(), &QSystemTrayIcon::activated, this, &MainWindow::onIconClick); + + if (settings.getShowSystemTray()) { + icon->show(); + setHidden(settings.getAutostartInTray()); + } else { + show(); + } #ifdef Q_OS_MAC - Nexus::getInstance().dockMenu->setAsDockMenu(); + Nexus::getInstance().dockMenu->setAsDockMenu(); #endif - } else if (!isVisible()) { - show(); - } - } else { - disconnect(timer, &QTimer::timeout, this, &MainWindow::onTryCreateTrayIcon); - if (!icon) { - qWarning() << "No system tray detected!"; - show(); + } else if (!isVisible()) { + show(); + } + } else { + disconnect(timer.get(), &QTimer::timeout, this, &MainWindow::onTryCreateTrayIcon); + if (!icon) { + qWarning() << "No system tray detected!"; + show(); + } } - } } void MainWindow::onIconClick(QSystemTrayIcon::ActivationReason reason) { - if (reason == QSystemTrayIcon::Trigger) { - if (isHidden() || isMinimized()) { - if (wasMaximized) { - showMaximized(); - } else { - showNormal(); - } - - activateWindow(); - } else if (!isActiveWindow()) { - activateWindow(); - } else { - wasMaximized = isMaximized(); - hide(); - } - } else if (reason == QSystemTrayIcon::Unknown) { - if (isHidden()) { - forceShow(); + if (reason == QSystemTrayIcon::Trigger) { + if (isHidden() || isMinimized()) { + if (wasMaximized) { + showMaximized(); + } else { + showNormal(); + } + + activateWindow(); + } else if (!isActiveWindow()) { + activateWindow(); + } else { + wasMaximized = isMaximized(); + hide(); + } + } else if (reason == QSystemTrayIcon::Unknown) { + if (isHidden()) { + forceShow(); + } } - } } void MainWindow::forceShow() { - hide(); - // Workaround to force minimized window to be restored - show(); - activateWindow(); + hide(); + // Workaround to force minimized window to be restored + show(); + activateWindow(); } void MainWindow::updateIcons() { - if (!icon) { - return; - } + if (!icon) { + return; + } + + const QString assetSuffix = "online"; + static bool checkedHasThemeIcon = false; + static bool hasThemeIconBug = false; - const QString assetSuffix = "online"; - static bool checkedHasThemeIcon = false; - static bool hasThemeIconBug = false; + if (!checkedHasThemeIcon) { + hasThemeIconBug = QIcon::hasThemeIcon("qtox-asjkdfhawjkeghdfjgh"); + checkedHasThemeIcon = true; - if (!checkedHasThemeIcon) { - hasThemeIconBug = QIcon::hasThemeIcon("qtox-asjkdfhawjkeghdfjgh"); - checkedHasThemeIcon = true; + if (hasThemeIconBug) { + qDebug() << "Detected buggy QIcon::hasThemeIcon. Icon overrides from " + "theme will be ignored."; + } + } - if (hasThemeIconBug) { - qDebug() << "Detected buggy QIcon::hasThemeIcon. Icon overrides from " - "theme will be ignored."; + QIcon ico; + if (!hasThemeIconBug && QIcon::hasThemeIcon("qtox-" + assetSuffix)) { + ico = QIcon::fromTheme("qtox-" + assetSuffix); + } else { + // QString color = Settings.getLightTrayIcon() ? "light" : "dark"; + QString color = "light"; + QString path = ":/img/taskbar/" + color + "/taskbar_" + assetSuffix + ".svg"; + + QSvgRenderer renderer(path); + + // Prepare a QImage with desired characteritisc + QImage image = QImage(250, 250, QImage::Format_ARGB32); + image.fill(Qt::transparent); + QPainter painter(&image); + renderer.render(&painter); + ico = QIcon(QPixmap::fromImage(image)); + } + + setWindowIcon(ico); + if (icon) { + icon->setIcon(ico); } - } - - QIcon ico; - if (!hasThemeIconBug && QIcon::hasThemeIcon("qtox-" + assetSuffix)) { - ico = QIcon::fromTheme("qtox-" + assetSuffix); - } else { - // QString color = Settings.getLightTrayIcon() ? "light" : "dark"; - QString color = "light"; - QString path = ":/img/taskbar/" + color + "/taskbar_" + assetSuffix + ".svg"; - - QSvgRenderer renderer(path); - - // Prepare a QImage with desired characteritisc - QImage image = QImage(250, 250, QImage::Format_ARGB32); - image.fill(Qt::transparent); - QPainter painter(&image); - renderer.render(&painter); - ico = QIcon(QPixmap::fromImage(image)); - } - - setWindowIcon(ico); - if (icon) { - icon->setIcon(ico); - } } -OMenuWidget *MainWindow::initMenuWindow(PageMenu menu) { - - OMenuWidget *w = nullptr; - switch (menu) { - case PageMenu::chat: - w = createChatModule(this); - break; - case PageMenu::platform: - w = createPlatformModule(this); - break; - case PageMenu::setting: - w = new ConfigWindow(this); - break; - } - - if (w) { - ui->stacked_widget->addWidget(w); - } - return w; +OMenuWidget* MainWindow::initMenuWindow(PageMenu menu) { + OMenuWidget* w = nullptr; + switch (menu) { + case PageMenu::chat: + w = createChatModule(this); + break; + case PageMenu::platform: + w = createPlatformModule(this); + break; + case PageMenu::setting: + w = new ConfigWindow(this); + break; + } + if (w) { + auto m = w->getModule(); + if (m) { + delayCaller->call(1000, [=, this]() { + assert(w); + assert(session); + qDebug() << "Start module:" << m->name(); + m->start(session); + }); + } + + menuWindow.insert(menu, w); + ui->stacked_widget->addWidget(w); + } + return w; } -OMenuWidget *MainWindow::getMenuWindow(PageMenu menu) { return menuWindow.value(menu); } +OMenuWidget* MainWindow::getMenuWindow(PageMenu menu) { return menuWindow.value(menu); } void MainWindow::onSwitchPage(PageMenu menu, bool checked) { - OMenuWidget *p = getMenuWindow(menu); - if (!p) { - p = initMenuWindow(menu); - } + OMenuWidget* p = getMenuWindow(menu); + if (!p) { + p = initMenuWindow(menu); + } - if (!p) { - return; - } + if (!p) { + return; + } - ui->stacked_widget->setCurrentWidget(p); + ui->stacked_widget->setCurrentWidget(p); } // // void MainWindow::on_btnMin_clicked() { showMinimized(); } @@ -352,35 +366,36 @@ void MainWindow::onSwitchPage(PageMenu menu, bool checked) { // messenger->initRoom(); //} -QWidget *MainWindow::getContainer(PageMenu menu) { return ui->stacked_widget; } - - -OMenuWidget *MainWindow::createChatModule(MainWindow *pWindow) { - - qDebug() <<"Creating module:" << Nexus::Name(); - auto module = Nexus::Create(); - auto nexus = static_cast(module); - connect(nexus, &Nexus::updateAvatar, // - ok::Application::Instance(), &ok::Application::onAvatar); - -// connect(nexus, &Nexus::destroyProfile, this, &core::Application::on_logout); -// connect(nexus, &Nexus::exit, this, &core::Application::on_exit); - - module->start(m_signInInfo); +QWidget* MainWindow::getContainer(PageMenu menu) { return ui->stacked_widget; } + +OMenuWidget* MainWindow::createChatModule(MainWindow* pWindow) { + qDebug() << "Creating m:" << Nexus::Name(); + auto m = Nexus::Create(); + auto nexus = static_cast(m); + + connect(nexus, &Nexus::updateAvatar, // + ok::Application::Instance(), &ok::Application::onAvatar); + connect(nexus, &Nexus::destroyProfile, // + ok::Application::Instance(), &ok::Application::on_logout); + connect(nexus, &Nexus::exit, // + ok::Application::Instance(), &ok::Application::on_exit); + + auto w = new OMenuWidget(this); + w->setModule(m); + w->setLayout(new QGridLayout()); + w->layout()->addWidget(m->widget()); + return w; +} +OMenuWidget* MainWindow::createPlatformModule(MainWindow* pWindow) { + auto m = new ok::platform::Platform(); - auto m = new OMenuWidget(this); - m->setLayout(new QGridLayout()); - m->layout()->addWidget(module->widget()); - return m; -} + auto w = new OMenuWidget(this); + w->setModule(m); + w->setLayout(new QGridLayout()); + w->layout()->addWidget(m->widget()); -OMenuWidget *MainWindow::createPlatformModule(MainWindow *pWindow) { - auto module = new platform::Platform(); - auto m= new OMenuWidget(this); - m->setLayout(new QGridLayout()); - m->layout()->addWidget(module->widget()); - return m; + return w; } -} // namespace UI +} // namespace UI diff --git a/src/UI/window/main/src/MainWindow.h b/src/UI/window/main/src/MainWindow.h index f42d8ab8..edec9026 100644 --- a/src/UI/window/main/src/MainWindow.h +++ b/src/UI/window/main/src/MainWindow.h @@ -12,12 +12,11 @@ #ifndef MAINWINDOW_H #define MAINWINDOW_H - #include #include +#include #include #include -#include #include "base/Page.h" #include "lib/session/AuthSession.h" @@ -33,62 +32,62 @@ class OMainMenu; class OMenuWidget; class MainWindow : public QMainWindow { - Q_OBJECT + Q_OBJECT public: - explicit MainWindow(ok::session::SignInInfo &m_signInInfo, QWidget *parent = nullptr); - ~MainWindow(); + explicit MainWindow(std::shared_ptr session, + QWidget* parent = nullptr); + ~MainWindow(); - static MainWindow* getInstance(); + static MainWindow* getInstance(); - void init(); - OMenuWidget *getMenuWindow(PageMenu menu); - OMenuWidget *initMenuWindow(PageMenu menu); - inline OMainMenu *menu() { return m_menu; } - QWidget *getContainer(PageMenu menu); + void init(); + OMenuWidget* getMenuWindow(PageMenu menu); + OMenuWidget* initMenuWindow(PageMenu menu); + inline OMainMenu* menu() { return m_menu; } + QWidget* getContainer(PageMenu menu); protected: - void showEvent(QShowEvent *event) override; - void closeEvent(QCloseEvent *event) override; - void updateIcons(); + void showEvent(QShowEvent* event) override; + void closeEvent(QCloseEvent* event) override; + void updateIcons(); private: - Ui::MainWindow *ui; + std::shared_ptr session; + std::unique_ptr timer; + std::shared_ptr<::base::DelayedCallTimer> delayCaller; - OMainMenu *m_menu; - QMap menuWindow; + Ui::MainWindow* ui; + OMainMenu* m_menu; + QMap menuWindow; - std::unique_ptr icon; - QMenu *trayMenu; - QTimer *timer; - QAction *actionQuit; - QAction *actionShow; - bool wasMaximized = false; - // bool autoAwayActive = false; + std::unique_ptr icon; + QMenu* trayMenu; + QAction* actionQuit; + QAction* actionShow; + bool wasMaximized = false; - // void saveWindowGeometry(); - // void saveSplitterGeometry(); + // bool autoAwayActive = false; + // void saveWindowGeometry(); + // void saveSplitterGeometry(); - ok::session::SignInInfo &m_signInInfo; - - static inline QIcon prepareIcon(QString path, int w = 0, int h = 0); + static inline QIcon prepareIcon(QString path, int w = 0, int h = 0); signals: - void toClose(); + void toClose(); private slots: - void onSwitchPage(PageMenu menu, bool checked); + void onSwitchPage(PageMenu menu, bool checked); - void onIconClick(QSystemTrayIcon::ActivationReason); + void onIconClick(QSystemTrayIcon::ActivationReason); - void onTryCreateTrayIcon(); + void onTryCreateTrayIcon(); - void forceShow(); - OMenuWidget *createChatModule(MainWindow *pWindow); - OMenuWidget *createPlatformModule(MainWindow *pWindow); + void forceShow(); + OMenuWidget* createChatModule(MainWindow* pWindow); + OMenuWidget* createPlatformModule(MainWindow* pWindow); }; +} // namespace UI -} // namespace UI - -#endif // MAINWINDOW_H +#endif // MAINWINDOW_H diff --git a/src/UI/window/main/src/OMainMenu.cpp b/src/UI/window/main/src/OMainMenu.cpp index c6ca50b1..df98c13b 100644 --- a/src/UI/window/main/src/OMainMenu.cpp +++ b/src/UI/window/main/src/OMainMenu.cpp @@ -17,67 +17,65 @@ #include "ui_OMainMenu.h" #include "base/files.h" -#include "base/resources.h" #include "base/images.h" +#include "base/resources.h" namespace UI { -OMainMenu::OMainMenu(QWidget *parent) - : QFrame(parent), ui(new Ui::OMainMenu), _showTimes(0) { - qDebug() << __func__ ; +OMainMenu::OMainMenu(QWidget* parent) : QFrame(parent), ui(new Ui::OMainMenu), _showTimes(0) { + qDebug() << __func__; - OK_RESOURCE_INIT(UIWindowMain); + OK_RESOURCE_INIT(UIWindowMain); - ui->setupUi(this); + ui->setupUi(this); - // 设置样式 - QString qss = ok::base::Files::readStringAll(":/qss/menu.css"); - setStyleSheet(qss); + // 设置样式 + QString qss = ok::base::Files::readStringAll(":/qss/menu.css"); + setStyleSheet(qss); - ui->chatBtn->setCursor(Qt::PointingHandCursor); - ui->chatBtn->setIconSize(QSize(40, 40)); - ui->settingBtn->setCursor(Qt::PointingHandCursor); - ui->settingBtn->setIconSize(QSize(40, 40)); - ui->platformBtn->setCursor(Qt::PointingHandCursor); - ui->platformBtn->setIconSize(QSize(40, 40)); + ui->chatBtn->setCursor(Qt::PointingHandCursor); + ui->chatBtn->setIconSize(QSize(40, 40)); + ui->settingBtn->setCursor(Qt::PointingHandCursor); + ui->settingBtn->setIconSize(QSize(40, 40)); + ui->platformBtn->setCursor(Qt::PointingHandCursor); + ui->platformBtn->setIconSize(QSize(40, 40)); - delayCaller_ = std::make_unique(); + delayCaller_ = std::make_unique(); } OMainMenu::~OMainMenu() { - qDebug() << __func__ ; - delete ui; + qDebug() << __func__; + delete ui; } -void OMainMenu::setAvatar(const QPixmap &pixmap) { - QSize size = ui->label_avatar->size() * ui->label_avatar->devicePixelRatioF(); - auto newImage = base::Images::roundRectPixmap(pixmap, size, 100 * ui->label_avatar->devicePixelRatioF()); - newImage.setDevicePixelRatio(ui->label_avatar->devicePixelRatioF()); - ui->label_avatar->setPixmap(newImage); +void OMainMenu::setAvatar(const QPixmap& pixmap) { + QSize size = ui->label_avatar->size() * ui->label_avatar->devicePixelRatioF(); + auto newImage = base::Images::roundRectPixmap(pixmap, size, + 100 * ui->label_avatar->devicePixelRatioF()); + newImage.setDevicePixelRatio(ui->label_avatar->devicePixelRatioF()); + ui->label_avatar->setPixmap(newImage); } -void OMainMenu::showEvent(QShowEvent *e) { - Q_UNUSED(e); - _showTimes++; - if (_showTimes == 1) { - updateUI(); - } +void OMainMenu::showEvent(QShowEvent* e) { + Q_UNUSED(e); + _showTimes++; + if (_showTimes == 1) { + updateUI(); + } } void OMainMenu::updateUI() { on_chatBtn_clicked(true); } -void OMainMenu::on_personalBtn_clicked(bool checked) {} - /** * 聊天 * @brief OMainMenu::on_chatBtn_clicked * @param checked */ void OMainMenu::on_chatBtn_clicked(bool checked) { - ui->chatBtn->setChecked(true); - ui->settingBtn->setChecked(false); - ui->platformBtn->setChecked(false); - emit menuPushed(UI::PageMenu::chat, ui->chatBtn->isChecked()); + ui->chatBtn->setChecked(true); + ui->settingBtn->setChecked(false); + ui->platformBtn->setChecked(false); + emit menuPushed(UI::PageMenu::chat, ui->chatBtn->isChecked()); } /** @@ -85,10 +83,10 @@ void OMainMenu::on_chatBtn_clicked(bool checked) { * @param checked */ void OMainMenu::on_settingBtn_clicked(bool checked) { - ui->platformBtn->setChecked(false); - ui->chatBtn->setChecked(false); - ui->settingBtn->setChecked(true); - emit menuPushed(UI::PageMenu::setting, ui->settingBtn->isChecked()); + ui->platformBtn->setChecked(false); + ui->chatBtn->setChecked(false); + ui->settingBtn->setChecked(true); + emit menuPushed(UI::PageMenu::setting, ui->settingBtn->isChecked()); } /** @@ -96,10 +94,10 @@ void OMainMenu::on_settingBtn_clicked(bool checked) { * @param checked */ void OMainMenu::on_platformBtn_clicked(bool checked) { - ui->chatBtn->setChecked(false); - ui->settingBtn->setChecked(false); - ui->platformBtn->setChecked(true); - emit menuPushed(UI::PageMenu::platform, ui->platformBtn->isChecked()); + ui->chatBtn->setChecked(false); + ui->settingBtn->setChecked(false); + ui->platformBtn->setChecked(true); + emit menuPushed(UI::PageMenu::platform, ui->platformBtn->isChecked()); } -} // namespace UI +} // namespace UI diff --git a/src/UI/window/main/src/OMainMenu.h b/src/UI/window/main/src/OMainMenu.h index 25575dbd..5d2c60b3 100644 --- a/src/UI/window/main/src/OMainMenu.h +++ b/src/UI/window/main/src/OMainMenu.h @@ -16,8 +16,8 @@ #include #include "base/Page.h" -#include "base/timer.h" #include "base/resources.h" +#include "base/timer.h" OK_RESOURCE_LOADER(UIWindowMain) @@ -28,42 +28,39 @@ class OMainMenu; namespace UI { class OMainMenu : public QFrame { - Q_OBJECT + Q_OBJECT public: - explicit OMainMenu(QWidget *parent = nullptr); - ~OMainMenu() override; + explicit OMainMenu(QWidget* parent = nullptr); + ~OMainMenu() override; - - void onSetting(); + void onSetting(); protected: - virtual void showEvent(QShowEvent *e) override; + virtual void showEvent(QShowEvent* e) override; private: - OK_RESOURCE_PTR(UIWindowMain); + OK_RESOURCE_PTR(UIWindowMain); - Ui::OMainMenu *ui; + Ui::OMainMenu* ui; - int _showTimes; - // delayCaller - std::shared_ptr delayCaller_; + int _showTimes; + // delayCaller + std::shared_ptr delayCaller_; - void updateUI(); + void updateUI(); signals: - void menuPushed(PageMenu menu, bool checked); + void menuPushed(PageMenu menu, bool checked); private slots: - void on_personalBtn_clicked(bool checked); - void on_chatBtn_clicked(bool checked); - void on_settingBtn_clicked(bool checked); - void on_platformBtn_clicked(bool checked); + void on_chatBtn_clicked(bool checked); + void on_settingBtn_clicked(bool checked); + void on_platformBtn_clicked(bool checked); public slots: - void setAvatar(const QPixmap &); - + void setAvatar(const QPixmap&); }; -} // namespace UI +} // namespace UI -#endif // OMAINMENU_H +#endif // OMAINMENU_H diff --git a/src/UI/window/widgetfactory.cpp b/src/UI/window/widgetfactory.cpp index dd3eb546..4947e7d7 100644 --- a/src/UI/window/widgetfactory.cpp +++ b/src/UI/window/widgetfactory.cpp @@ -12,18 +12,8 @@ #include "widgetfactory.h" +namespace UI { +WidgetFactory::WidgetFactory(QObject* parent) : QObject(parent) {} - -namespace UI{ - - -WidgetFactory::WidgetFactory(QObject *parent) : QObject(parent) -{ - -} - - - - -} +} // namespace UI diff --git a/src/UI/window/widgetfactory.h b/src/UI/window/widgetfactory.h index b35f4f41..a77e1f28 100644 --- a/src/UI/window/widgetfactory.h +++ b/src/UI/window/widgetfactory.h @@ -12,57 +12,45 @@ #ifndef WIDGETFACTORY_H #define WIDGETFACTORY_H -#include #include #include +#include -namespace UI{ - - - +namespace UI { -class WidgetFactory : public QObject -{ +class WidgetFactory : public QObject { Q_OBJECT - - private: - explicit WidgetFactory(QObject *parent = nullptr); + explicit WidgetFactory(QObject* parent = nullptr); public: - typedef std::list WidgetList; - template - static T* CreateWidget(QWidget *parent = nullptr) - { - -// static_assert(sizeof(QWidget) == sizeof(T), -// "T type is not the QWidget"); + template static T* CreateWidget(QWidget* parent = nullptr) { + // static_assert(sizeof(QWidget) == sizeof(T), + // "T type is not the QWidget"); T* t = new T(parent); -// QPalette palette = t->palette() ; -// t->setAutoFillBackground(true); -// palette.setColor(QPalette::Window, QColor("#838383")); -// palette.setColor(QPalette::Text, QColor("#ffffff")); -// t->setPalette(palette); + // QPalette palette = t->palette() ; + // t->setAutoFillBackground(true); + // palette.setColor(QPalette::Window, QColor("#838383")); + // palette.setColor(QPalette::Text, QColor("#ffffff")); + // t->setPalette(palette); -// widgets_.push_back(t); + // widgets_.push_back(t); return t; } private: - -// WidgetList widgets_; + // WidgetList widgets_; signals: public slots: }; - -} -#endif // WIDGETFACTORY_H +} // namespace UI +#endif // WIDGETFACTORY_H diff --git a/src/application.cpp b/src/application.cpp index 44b94211..477220c7 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -17,12 +17,12 @@ #include #include #include -#include #include "Bus.h" #include "UI/core/FontManager.h" -#include "UI/window/main/src/OMainMenu.h" +#include "UI/window/login/src/LoginWidget.h" #include "UI/window/login/src/LoginWindow.h" +#include "UI/window/main/src/OMainMenu.h" #include "base/OkSettings.h" #include "base/files.h" #include "base/logs.h" @@ -35,240 +35,193 @@ namespace ok { -Application::Application(int &argc, char *argv[]) - : QApplication(argc, argv), _argc(argc), _argv(argv) { - - //Qt application settings. - setApplicationName(APPLICATION_NAME); - setApplicationVersion(APPLICATION_VERSION_ID); +Application::Application(int& argc, char* argv[]) + : QApplication(argc, argv), _argc(argc), _argv(argv) { + // Qt application settings. + setApplicationName(APPLICATION_NAME); + setApplicationVersion(APPLICATION_VERSION_ID); #if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0) - setDesktopFileName(APPLICATION_NAME); + setDesktopFileName(APPLICATION_NAME); #endif + // Initialize log manager. + ok::lib::LogManager::Instance(); + qDebug() << "QT_VERSION:" << QT_VERSION_STR; + qDebug() << QString("argc:%1").arg(argc); + for (int i = 0; i < argc; i++) { + qDebug() << QString("argv:%1->%2").arg(i).arg(argv[i]); + } - //Initialize log manager. - ok::lib::LogManager::Instance(); - qDebug() << "QT_VERSION:" << QT_VERSION_STR; - qDebug() << QString("argc:%1").arg(argc); - for (int i = 0; i < argc; i++) { - qDebug() << QString("argv:%1->%2").arg(i).arg(argv[i]); - } - - ok::base::CpuInfo cpuInfo; - ok::base::SysInfo::GetCpuInfo(cpuInfo); - - qDebug() << "CpuInfo :" // - << cpuInfo.arch // - << cpuInfo.manufacturer // - << cpuInfo.name // - << cpuInfo.cores // - << cpuInfo.processors; // - - ok::base::OsInfo osInfo; - ok::base::SysInfo::GetOsInfo(osInfo); - qDebug() << "OsInfo :" // - << osInfo.kernelName //"linux" - << osInfo.kernelVersion //"5.19.0-50-generic" - << osInfo.name //"ubuntu" - << osInfo.version //"22.04" - << osInfo.prettyName //"Ubuntu 22.04.2 LTS" - << osInfo.hostName //"root-host" - << osInfo.uniqueId; //"OWVjYjNmZTY0OTFmNGZiZGFhYjI0ODA2OTgwY2QxODQ=" - - qDebug() <<"APPLICATION_RELEASE :" << APPLICATION_RELEASE; - qDebug() <<"APPLICATION_VERSION_ID:" << APPLICATION_VERSION_ID; - qDebug() <<"APPLICATION_ID :" << APPLICATION_ID; - qDebug() <<"APPLICATION_NAME :" << APPLICATION_NAME; - - auto configDir = ok::base::OkSettings::configDir(); - qDebug()<< "ConfigDir :"<< configDir.path(); - auto cacheDir = ok::base::OkSettings::cacheDir(); - qDebug()<<"CacheDir :"<< cacheDir.path(); - auto dataDir = ok::base::OkSettings::dataDir(); - qDebug()<<"DataDir :"<< dataDir.path(); - auto downloadDir = ok::base::OkSettings::downloadDir(); - qDebug()<<"DownloadDir:"<< downloadDir.path(); - - auto pluginDir = ok::base::OkSettings::getAppPluginPath(); - qDebug()<<"PluginDir :"<< pluginDir.path(); - auto logDir = ok::base::OkSettings::getAppLogPath(); - qDebug()<<"LogDir :"<< logDir.path(); - - // Windows platform plugins DLL hell fix - QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath()); - addLibraryPath("platforms"); - - _bus = std::make_unique(); - - QString qss = ok::base::Files::readStringAll("application.qss"); - qApp->setStyleSheet(qss); - - // 字体 - FontManager fm; - fm.loadFonts(); - - // 设置 - _settingManager = std::make_unique(this); - - connect(this, &QApplication::aboutToQuit, this, &Application::cleanup); - - auto _session = ok::session::AuthSession::Instance(); - - connect(_session, &ok::session::AuthSession::loginResult, - [&](ok::session::SignInInfo signInInfo, ok::session::LoginResult result) { - qDebug()<<"result:" << result.msg; - }); - - - connect(_session, &ok::session::AuthSession::imStarted, - [&](ok::session::SignInInfo signInInfo){ - onLoginSuccess(signInInfo); - }); - - qDebug() << "Application has be created"; + ok::base::CpuInfo cpuInfo; + ok::base::SysInfo::GetCpuInfo(cpuInfo); + + qDebug() << "CpuInfo :" // + << cpuInfo.arch // + << cpuInfo.manufacturer // + << cpuInfo.name // + << cpuInfo.cores // + << cpuInfo.processors; // + + ok::base::OsInfo osInfo; + ok::base::SysInfo::GetOsInfo(osInfo); + qDebug() << "OsInfo :" // + << osInfo.kernelName //"linux" + << osInfo.kernelVersion //"5.19.0-50-generic" + << osInfo.name //"ubuntu" + << osInfo.version //"22.04" + << osInfo.prettyName //"Ubuntu 22.04.2 LTS" + << osInfo.hostName //"root-host" + << osInfo.uniqueId; //"OWVjYjNmZTY0OTFmNGZiZGFhYjI0ODA2OTgwY2QxODQ=" + + qDebug() << "APPLICATION_RELEASE :" << APPLICATION_RELEASE; + qDebug() << "APPLICATION_VERSION_ID:" << APPLICATION_VERSION_ID; + qDebug() << "APPLICATION_ID :" << APPLICATION_ID; + qDebug() << "APPLICATION_NAME :" << APPLICATION_NAME; + + auto configDir = ok::base::OkSettings::configDir(); + qDebug() << "ConfigDir :" << configDir.path(); + auto cacheDir = ok::base::OkSettings::cacheDir(); + qDebug() << "CacheDir :" << cacheDir.path(); + auto dataDir = ok::base::OkSettings::dataDir(); + qDebug() << "DataDir :" << dataDir.path(); + auto downloadDir = ok::base::OkSettings::downloadDir(); + qDebug() << "DownloadDir:" << downloadDir.path(); + + auto pluginDir = ok::base::OkSettings::getAppPluginPath(); + qDebug() << "PluginDir :" << pluginDir.path(); + auto logDir = ok::base::OkSettings::getAppLogPath(); + qDebug() << "LogDir :" << logDir.path(); + + // Windows platform plugins DLL hell fix + QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath()); + addLibraryPath("platforms"); + + _bus = std::make_unique(); + + QString qss = ok::base::Files::readStringAll("application.qss"); + qApp->setStyleSheet(qss); + + // 字体 + FontManager fm; + fm.loadFonts(); + + // 设置 + _settingManager = std::make_unique(this); + + qDebug() << "Application has be created"; } -Application *Application::Instance() { - return qobject_cast(qApp); -} +Application* Application::Instance() { return qobject_cast(qApp); } -void Application::start() { - this->createLoginUI(true); -} +void Application::start() { this->createLoginUI(true); } void Application::createLoginUI(bool bootstrap) { - qDebug() << __func__ ; - m_loginWindow = new UI::LoginWindow(bootstrap); - m_loginWindow->show(); + qDebug() << __func__; + session = std::make_shared(); + connect(session.get(), &ok::session::AuthSession::tokenSet, // + [&]() { // + startMainUI(session); + }); + m_loginWindow = new UI::LoginWindow(session, bootstrap); + m_loginWindow->show(); } /** * 关闭login窗口 */ void Application::closeLoginUI() { - qDebug() << __func__ ; - if(!m_loginWindow){ - return; - } + qDebug() << __func__; + if (!m_loginWindow) { + return; + } disconnect(m_loginWindow); m_loginWindow->close(); - //no need to delete + // no need to delete m_loginWindow = nullptr; } -void Application::onLoginSuccess(ok::session::SignInInfo &signInInfo) { - qDebug() << qsl("onLoginSuccess account:%1").arg(signInInfo.account); - m_signInInfo = signInInfo; - - // 启动主界面 - startMainUI(m_signInInfo); -#ifdef OK_PLUGIN - // 初始化插件平台 - initPluginManager(); -#endif - - // 初始化 Painter 模块 -#ifdef OK_MODULE_PAINTER - initModulePainter(); -#endif - - // 关闭登录界面 - closeLoginUI(); -} - -void Application::startMainUI(ok::session::SignInInfo &m_signInInfo) { +void Application::startMainUI(std::shared_ptr session) { qDebug() << __func__; - m_mainWindow = std::make_unique(m_signInInfo); - /** - * connect menu's button events. - */ -// connect(m_mainWindow.get(), &UI::MainWindow::toClose, // -// [&](){ -// emit mainClose({ -// m_mainWindow->saveGeometry() -// }); -// } ); - -// connect(m_mainWindow.get(), &UI::MainWindow::menuPushed, -// this, &Application::onMenuPushed); + // Check the access token. + assert(session); + assert(!session->getToken().accessToken.isEmpty()); + if (m_mainWindow) { + qWarning() << "Main window was show."; + return; + } + // Create main window + m_mainWindow = std::make_unique(session); m_mainWindow->show(); + closeLoginUI(); -// m_windowManager = UI::WindowManager::Instance(); - -// connect(m_windowManager, &UI::WindowManager::menuPushed, this, -// &Application::onMenuPushed); -// connect(m_windowManager, &UI::WindowManager::mainClose, this, -// [&](SavedInfo savedInfo) { -// for (auto m : m_moduleMap) { -// m->onSave(savedInfo); -// } -// }); +#ifdef OK_PLUGIN + // 初始化插件平台 + initPluginManager(); +#endif -// m_windowManager->startMainUI(); + // 初始化 Painter 模块 +#ifdef OK_MODULE_PAINTER + initModulePainter(); +#endif } -void Application::stopMainUI() { - m_mainWindow.reset(); -} +void Application::stopMainUI() { m_mainWindow.reset(); } void Application::cleanup() { - qDebug(("Cleanup...")); - for (auto e : m_moduleMap) { - e->cleanup(); - } + qDebug(("Cleanup...")); + for (auto e : m_moduleMap) { + e->cleanup(); + } } void Application::finish() {} #ifdef OK_PLUGIN void Application::initPluginManager() { - ok::plugin::PluginManager *pm = ok::plugin::PluginManager::instance(); - QStringList plugins = pm->availablePlugins(); - for (const QString &plugin : plugins) { - qDebug() << "load plugin:" << plugin; - } + ok::plugin::PluginManager* pm = ok::plugin::PluginManager::instance(); + QStringList plugins = pm->availablePlugins(); + for (const QString& plugin : plugins) { + qDebug() << "load plugin:" << plugin; + } } #endif -void Application::onAvatar(const QPixmap &pixmap) { - auto menu = m_mainWindow->menu(); - if (!menu) - return; +void Application::onAvatar(const QPixmap& pixmap) { + auto menu = m_mainWindow->menu(); + if (!menu) return; - menu->setAvatar(pixmap); + menu->setAvatar(pixmap); } -void Application::on_logout(const QString &profile) -{ - qDebug() << __func__<sleep(1); createLoginUI(false); } -void Application::on_exit(const QString &profile) -{ - qDebug() << __func__<exit(); } -void Application::doLogout(){ - qDebug() << __func__< remove; - for(auto mod : m_moduleMap){ - qDebug() <<"delete module:" <name(); - remove.push_back(mod->name()); - mod->cleanup(); + for (auto mod : m_moduleMap) { + qDebug() << "delete module:" << mod->name(); + remove.push_back(mod->name()); + mod->cleanup(); } - for(auto &name:remove){ + for (auto& name : remove) { m_moduleMap.remove(name); } - stopMainUI(); + stopMainUI(); } -} // namespace core +} // namespace ok diff --git a/src/application.h b/src/application.h index 396423ac..39690f9e 100644 --- a/src/application.h +++ b/src/application.h @@ -20,13 +20,13 @@ #include "UI/core/ControllerManager.h" #include "UI/core/SettingManager.h" -#include "UI/window/login/src/LoginWindow.h" #include "UI/window/WindowManager.h" +#include "UI/window/login/src/LoginWindow.h" #include "modules/module.h" -namespace UI{ - class MainWindow; +namespace UI { +class MainWindow; } namespace ok { @@ -35,71 +35,65 @@ class Bus; using namespace network; class Application : public QApplication { - Q_OBJECT + Q_OBJECT public: - Application(int &argc, char **argv); + Application(int& argc, char** argv); - static Application *Instance(); + static Application* Instance(); - void start(); - void finish(); + void start(); + void finish(); - inline SettingManager *settingManager() { return _settingManager.get(); } + inline SettingManager* settingManager() { return _settingManager.get(); } - inline ControllerManager *controllerManager() { - return _controllerManager.get(); - } + inline ControllerManager* controllerManager() { return _controllerManager.get(); } - inline Bus* bus() const { - return _bus.get(); - } + inline Bus* bus() const { return _bus.get(); } -private: - QMap m_moduleMap; + inline ok::session::AuthSession* getSession() { return session.get(); } - void *profile = nullptr; +private: + QMap m_moduleMap; - int _argc; - char **_argv; - std::unique_ptr _bus; - std::unique_ptr _settingManager; + void* profile = nullptr; - std::unique_ptr _controllerManager; + int _argc; + char** _argv; - ok::session::SignInInfo m_signInInfo; + std::shared_ptr session; - UI::LoginWindow* m_loginWindow; - std::unique_ptr m_mainWindow; + std::unique_ptr _bus; + std::unique_ptr _settingManager; + std::unique_ptr _controllerManager; - void loadService(); - void doLogout(); - /** - * bootstrap: 打开程序首次启动为true,登出启动为false - */ - void createLoginUI(bool bootstrap); - void closeLoginUI(); + UI::LoginWindow* m_loginWindow; + std::unique_ptr m_mainWindow; - void startMainUI(ok::session::SignInInfo &m_signInInfo); - void stopMainUI(); + void loadService(); + void doLogout(); + /** + * bootstrap: 打开程序首次启动为true,登出启动为false + */ + void createLoginUI(bool bootstrap); + void closeLoginUI(); + void startMainUI(std::shared_ptr session); + void stopMainUI(); #ifdef OK_MODULE_PAINTER - void initModulePainter(); + void initModulePainter(); #endif #ifdef OK_PLUGIN - void initPluginManager(); + void initPluginManager(); #endif public slots: - void cleanup(); - - void onLoginSuccess(ok::session::SignInInfo &); - - void onAvatar(const QPixmap &); + void cleanup(); - void on_logout(const QString &profile); - void on_exit(const QString &profile); + void onAvatar(const QPixmap&); + void on_logout(const QString& profile); + void on_exit(const QString& profile); }; -} // namespace core +} // namespace ok diff --git a/src/base/OkAccount.cpp b/src/base/OkAccount.cpp index 6c21c26e..dae67a9a 100644 --- a/src/base/OkAccount.cpp +++ b/src/base/OkAccount.cpp @@ -20,14 +20,11 @@ namespace ok { namespace base { -OkAccount::OkAccount(const QString &username_) - : username(username_) {} +OkAccount::OkAccount(const QString& username_) : username(username_) {} -void OkAccount::setJid(const ::base::Jid &jid) { m_jid = jid; } +void OkAccount::setJid(const ::base::Jid& jid) { m_jid = jid; } ::base::Jid OkAccount::realJid(::base::Jid jid) { return jid; } - - -} // namespace base -} // namespace ok +} // namespace base +} // namespace ok diff --git a/src/base/OkAccount.h b/src/base/OkAccount.h index 7209748e..2d144f02 100644 --- a/src/base/OkAccount.h +++ b/src/base/OkAccount.h @@ -16,39 +16,32 @@ #pragma once -#include "jid.h" #include +#include "jid.h" namespace ok { namespace base { class OkAccount : public QObject { - Q_OBJECT + Q_OBJECT public: - explicit OkAccount(const QString &username); + explicit OkAccount(const QString& username); + + [[nodiscard]] inline const QString& name() const { return username; } - [[nodiscard]] inline const QString& name() const { - return username; - } + [[nodiscard]] inline const QString& getUsername() const { return username; } - [[nodiscard]] inline const QString& getUsername() const { - return username; - } + [[maybe_unused]] inline const ::base::Jid& jid() const { return m_jid; } - [[maybe_unused]] inline const ::base::Jid& jid() const { - return m_jid; - } + void setJid(const ::base::Jid& jid); - void setJid(const ::base::Jid& jid); + [[maybe_unused]] ::base::Jid realJid(::base::Jid jid); + [[maybe_unused]] QString id() const { return username; } - [[maybe_unused]] ::base::Jid realJid(::base::Jid jid); - [[maybe_unused]] QString id() const { - return username; - } private: - QString username; - ::base::Jid m_jid; + QString username; + ::base::Jid m_jid; }; -} // namespace base -} // namespace ok +} // namespace base +} // namespace ok diff --git a/src/base/OkProcess.h b/src/base/OkProcess.h index f67217eb..cfb02585 100644 --- a/src/base/OkProcess.h +++ b/src/base/OkProcess.h @@ -21,15 +21,9 @@ namespace ok::base { -class OkProcess{ +class OkProcess { public: - - static qint64 selfPid(){ - return QCoreApplication::applicationPid(); - } - - + static qint64 selfPid() { return QCoreApplication::applicationPid(); } }; - -} \ No newline at end of file +} // namespace ok::base \ No newline at end of file diff --git a/src/base/OkSettings.cpp b/src/base/OkSettings.cpp index 8389d10c..1aafda84 100644 --- a/src/base/OkSettings.cpp +++ b/src/base/OkSettings.cpp @@ -15,123 +15,122 @@ // #include "OkSettings.h" -#include "base/autorun.h" -#include "system/sys_info.h" #include #include #include #include #include #include +#include "base/autorun.h" +#include "system/sys_info.h" namespace ok::base { static QStringList locales = { - "zh_CN", // 中文简体 zh_CN - "zh_TW", // 中文繁体(zh_TW, zh_HK) - "en", // 英文 en_US, en_UK -// "es", // 西班牙语 -// "fr", // 法语 -// "ar", // 阿拉伯语 -// "ru", // 俄语 -// "de", // 德语 -// "pt", // 葡萄牙语 -// "it", // 意大利语 -// "ja", // 日文 -// "ko", // 韩文 + "zh_CN", // 中文简体 zh_CN + "zh_TW", // 中文繁体(zh_TW, zh_HK) + "en", // 英文 en_US, en_UK + // "es", // 西班牙语 + // "fr", // 法语 + // "ar", // 阿拉伯语 + // "ru", // 俄语 + // "de", // 德语 + // "pt", // 葡萄牙语 + // "it", // 意大利语 + // "ja", // 日文 + // "ko", // 韩文 }; -OkSettings::OkSettings(QObject *parent) // - : QObject(parent), // - settingsThread(nullptr), // - currentProfileId(0) { - - settingsThread = new QThread(); - settingsThread->setObjectName(objectName()); - settingsThread->start(QThread::LowPriority); - moveToThread(settingsThread); - - loadGlobal(); +OkSettings::OkSettings(QObject* parent) // + : QObject(parent) + , // + settingsThread(nullptr) + , // + currentProfileId(0) { + settingsThread = new QThread(); + settingsThread->setObjectName(objectName()); + settingsThread->start(QThread::LowPriority); + moveToThread(settingsThread); + + loadGlobal(); } void OkSettings::loadGlobal() { - - QString filePath = getGlobalSettingsFile(); - qDebug() << "Loading settings from " + filePath; - - QSettings s(filePath, QSettings::IniFormat); - s.setIniCodec("UTF-8"); - - s.beginGroup("General"); - { - if (currentProfile.isEmpty()) { - currentProfile = s.value("currentProfile", "").toString(); - currentProfileId = makeProfileId(currentProfile); + QString filePath = getGlobalSettingsFile(); + qDebug() << "Loading settings from " + filePath; + + QSettings s(filePath, QSettings::IniFormat); + s.setIniCodec("UTF-8"); + + s.beginGroup("General"); + { + if (currentProfile.isEmpty()) { + currentProfile = s.value("currentProfile", "").toString(); + currentProfileId = makeProfileId(currentProfile); + } + + translation = s.value("translation", true).toString(); + provider = s.value("provider", "").toString(); + showSystemTray = s.value("showSystemTray", true).toBool(); + closeToTray = s.value("closeToTray", false).toBool(); + autostartInTray = s.value("autostartInTray", false).toBool(); + autoSaveEnabled = s.value("autoSaveEnabled", false).toBool(); + minimizeOnClose = s.value("minimizeOnClose", false).toBool(); + minimizeToTray = s.value("minimizeToTray", false).toBool(); } - - translation = s.value("translation", true).toString(); - provider = s.value("provider", "").toString(); - showSystemTray = s.value("showSystemTray", true).toBool(); - closeToTray = s.value("closeToTray", false).toBool(); - autostartInTray = s.value("autostartInTray", false).toBool(); - autoSaveEnabled = s.value("autoSaveEnabled", false).toBool(); - minimizeOnClose = s.value("minimizeOnClose", false).toBool(); - minimizeToTray = s.value("minimizeToTray", false).toBool(); - } - s.endGroup(); + s.endGroup(); } void OkSettings::saveGlobal() { - if (QThread::currentThread() != settingsThread) - return (void)QMetaObject::invokeMethod(&getInstance(), "saveGlobal"); - - QMutexLocker locker{&bigLock}; - - QString path = ok::base::PlatformInfo::getGlobalSettingsFile(); - qDebug() << "Saving global settings at " + path; - - QSettings s(path, QSettings::IniFormat); - s.setIniCodec("UTF-8"); - - s.clear(); - s.beginGroup("General"); - { - // - s.setValue("currentProfile", currentProfile); - s.setValue("translation", translation); - s.setValue("provider", provider); - s.setValue("showSystemTray", showSystemTray); - s.setValue("closeToTray", closeToTray); - s.setValue("autostartInTray", autostartInTray); - s.setValue("autoSaveEnabled", autoSaveEnabled); - s.setValue("minimizeOnClose", minimizeOnClose); - s.setValue("minimizeToTray", minimizeToTray); - } - s.endGroup(); + if (QThread::currentThread() != settingsThread) + return (void)QMetaObject::invokeMethod(&getInstance(), "saveGlobal"); + + QMutexLocker locker{&bigLock}; + + QString path = ok::base::PlatformInfo::getGlobalSettingsFile(); + qDebug() << "Saving global settings at " + path; + + QSettings s(path, QSettings::IniFormat); + s.setIniCodec("UTF-8"); + + s.clear(); + s.beginGroup("General"); + { + // + s.setValue("currentProfile", currentProfile); + s.setValue("translation", translation); + s.setValue("provider", provider); + s.setValue("showSystemTray", showSystemTray); + s.setValue("closeToTray", closeToTray); + s.setValue("autostartInTray", autostartInTray); + s.setValue("autoSaveEnabled", autoSaveEnabled); + s.setValue("minimizeOnClose", minimizeOnClose); + s.setValue("minimizeToTray", minimizeToTray); + } + s.endGroup(); } -OkSettings &OkSettings::getInstance() { - static OkSettings *settings = nullptr; - if (!settings) - settings = new OkSettings(); - return *settings; +OkSettings& OkSettings::getInstance() { + static OkSettings* settings = nullptr; + if (!settings) settings = new OkSettings(); + return *settings; } // 国际化下拉框 QStringList OkSettings::getLocales() { return locales; } QString OkSettings::getTranslation() { - QMutexLocker locker{&bigLock}; - return translation; + QMutexLocker locker{&bigLock}; + return translation; } -void OkSettings::setTranslation(const QString &newValue) { - QMutexLocker locker{&bigLock}; +void OkSettings::setTranslation(const QString& newValue) { + QMutexLocker locker{&bigLock}; - if (newValue != translation) { - translation = newValue; - emit translationChanged(translation); - } + if (newValue != translation) { + translation = newValue; + emit translationChanged(translation); + } } QDir OkSettings::downloadDir() { return ok::base::PlatformInfo::getAppDownloadDirPath(); } @@ -153,140 +152,142 @@ QDir OkSettings::getAppPluginPath() { return PlatformInfo::getAppPluginDirPath() QDir OkSettings::getAppLogPath() { return PlatformInfo::getAppLogDirPath(); } bool OkSettings::getShowSystemTray() { - QMutexLocker locker{&bigLock}; - return showSystemTray; + QMutexLocker locker{&bigLock}; + return showSystemTray; } void OkSettings::setShowSystemTray(bool newValue) { - QMutexLocker locker{&bigLock}; - if (newValue != showSystemTray) { - showSystemTray = newValue; - emit showSystemTrayChanged(newValue); - } + QMutexLocker locker{&bigLock}; + if (newValue != showSystemTray) { + showSystemTray = newValue; + emit showSystemTrayChanged(newValue); + } } bool OkSettings::getCloseToTray() { - QMutexLocker locker{&bigLock}; - return closeToTray; + QMutexLocker locker{&bigLock}; + return closeToTray; } void OkSettings::setCloseToTray(bool newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != closeToTray) { - closeToTray = newValue; - emit closeToTrayChanged(newValue); - } + if (newValue != closeToTray) { + closeToTray = newValue; + emit closeToTrayChanged(newValue); + } } bool OkSettings::getAutoSaveEnabled() { - QMutexLocker locker{&bigLock}; - return autoSaveEnabled; + QMutexLocker locker{&bigLock}; + return autoSaveEnabled; } void OkSettings::setAutoSaveEnabled(bool newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != autoSaveEnabled) { - autoSaveEnabled = newValue; - emit autoSaveEnabledChanged(autoSaveEnabled); - } + if (newValue != autoSaveEnabled) { + autoSaveEnabled = newValue; + emit autoSaveEnabledChanged(autoSaveEnabled); + } } void OkSettings::setAutostartInTray(bool newValue) { - QMutexLocker locker{&bigLock}; - if (newValue != autostartInTray) { - autostartInTray = newValue; - emit autostartInTrayChanged(autostartInTray); - } + QMutexLocker locker{&bigLock}; + if (newValue != autostartInTray) { + autostartInTray = newValue; + emit autostartInTrayChanged(autostartInTray); + } } bool OkSettings::getMinimizeToTray() { - QMutexLocker locker{&bigLock}; - return minimizeToTray; + QMutexLocker locker{&bigLock}; + return minimizeToTray; } void OkSettings::setMinimizeToTray(bool newValue) { - QMutexLocker locker{&bigLock}; - if (newValue != minimizeToTray) { - minimizeToTray = newValue; - emit minimizeToTrayChanged(minimizeToTray); - } + QMutexLocker locker{&bigLock}; + if (newValue != minimizeToTray) { + minimizeToTray = newValue; + emit minimizeToTrayChanged(minimizeToTray); + } } bool OkSettings::getMinimizeOnClose() { - QMutexLocker locker{&bigLock}; - return minimizeOnClose; + QMutexLocker locker{&bigLock}; + return minimizeOnClose; } void OkSettings::setMinimizeOnClose(bool newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != minimizeOnClose) { - minimizeOnClose = newValue; - emit minimizeOnCloseChanged(minimizeOnClose); - } + if (newValue != minimizeOnClose) { + minimizeOnClose = newValue; + emit minimizeOnCloseChanged(minimizeOnClose); + } } bool OkSettings::getAutorun() { - QMutexLocker locker{&bigLock}; - return Platform::getAutorun(); + QMutexLocker locker{&bigLock}; + return Platform::getAutorun(); } void OkSettings::setAutorun(bool newValue) { - QMutexLocker locker{&bigLock}; - bool autorun = Platform::getAutorun(); - if (newValue != autorun) { - Platform::setAutorun(newValue); - emit autorunChanged(autorun); - } + QMutexLocker locker{&bigLock}; + bool autorun = Platform::getAutorun(); + if (newValue != autorun) { + Platform::setAutorun(newValue); + emit autorunChanged(autorun); + } } bool OkSettings::getAutostartInTray() { - QMutexLocker locker{&bigLock}; - return autostartInTray; + QMutexLocker locker{&bigLock}; + return autostartInTray; } QString OkSettings::getCurrentProfile() { - QMutexLocker locker{&bigLock}; - return currentProfile; + QMutexLocker locker{&bigLock}; + return currentProfile; } uint32_t OkSettings::getCurrentProfileId() { - QMutexLocker locker{&bigLock}; - return currentProfileId; + QMutexLocker locker{&bigLock}; + return currentProfileId; } -void OkSettings::setCurrentProfile(const QString &profile) { - QMutexLocker locker{&bigLock}; +void OkSettings::setCurrentProfile(const QString& profile) { + QMutexLocker locker{&bigLock}; - if (profile != currentProfile) { - currentProfile = profile; - currentProfileId = makeProfileId(currentProfile); + if (profile != currentProfile) { + currentProfile = profile; + currentProfileId = makeProfileId(currentProfile); - emit currentProfileIdChanged(currentProfileId); - } + emit currentProfileIdChanged(currentProfileId); + } } -uint32_t OkSettings::makeProfileId(const QString &profile) { - QByteArray data = QCryptographicHash::hash(profile.toUtf8(), QCryptographicHash::Md5); - const uint32_t *dwords = reinterpret_cast(data.constData()); - return dwords[0] ^ dwords[1] ^ dwords[2] ^ dwords[3]; +uint32_t OkSettings::makeProfileId(const QString& profile) { + QByteArray data = QCryptographicHash::hash(profile.toUtf8(), QCryptographicHash::Md5); + const uint32_t* dwords = reinterpret_cast(data.constData()); + return dwords[0] ^ dwords[1] ^ dwords[2] ^ dwords[3]; } -QString OkSettings::getGlobalSettingsFile() { return ok::base::PlatformInfo::getGlobalSettingsFile(); } +QString OkSettings::getGlobalSettingsFile() { + return ok::base::PlatformInfo::getGlobalSettingsFile(); +} -QString OkSettings::getProvider() { - QMutexLocker locker{&bigLock}; - return provider; +QString OkSettings::getProvider() { + QMutexLocker locker{&bigLock}; + return provider; } void OkSettings::setProvider(QString val) { - QMutexLocker locker{&bigLock}; - if (val != provider) { - provider = val; - emit providerChanged(provider); - } + QMutexLocker locker{&bigLock}; + if (val != provider) { + provider = val; + emit providerChanged(provider); + } } -} // namespace ok::base +} // namespace ok::base diff --git a/src/base/OkSettings.h b/src/base/OkSettings.h index af4f91e2..af7454c5 100644 --- a/src/base/OkSettings.h +++ b/src/base/OkSettings.h @@ -16,115 +16,111 @@ #pragma once -#include "base/compatiblerecursivemutex.h" #include #include +#include "base/compatiblerecursivemutex.h" namespace ok::base { class OkSettings : public QObject { - Q_OBJECT + Q_OBJECT public: - explicit OkSettings(QObject *parent = nullptr); - ~OkSettings() override {} - static OkSettings &getInstance(); - - QString getGlobalSettingsFile(); + explicit OkSettings(QObject* parent = nullptr); + ~OkSettings() override {} + static OkSettings& getInstance(); - void loadGlobal(); + QString getGlobalSettingsFile(); - QStringList getLocales(); - QString getTranslation() ; - void setTranslation(const QString &newValue); + void loadGlobal(); - static QDir downloadDir(); - static QDir cacheDir(); - static QDir configDir(); - static QDir dataDir(); + QStringList getLocales(); + QString getTranslation(); + void setTranslation(const QString& newValue); - static QDir getAppCacheDirPath() ; - static QDir getAppLogPath() ; - static QDir getAppPluginPath() ; + static QDir downloadDir(); + static QDir cacheDir(); + static QDir configDir(); + static QDir dataDir(); - bool getShowSystemTray() ; - void setShowSystemTray(bool newValue); + static QDir getAppCacheDirPath(); + static QDir getAppLogPath(); + static QDir getAppPluginPath(); - Q_PROPERTY(bool showSystemTray - READ getShowSystemTray - WRITE setShowSystemTray NOTIFY - showSystemTrayChanged FINAL) + bool getShowSystemTray(); + void setShowSystemTray(bool newValue); + Q_PROPERTY(bool showSystemTray READ getShowSystemTray WRITE setShowSystemTray NOTIFY + showSystemTrayChanged FINAL) - bool getCloseToTray() ; - void setCloseToTray(bool newValue); + bool getCloseToTray(); + void setCloseToTray(bool newValue); - Q_PROPERTY(bool autorun READ getAutorun WRITE setAutorun NOTIFY autorunChanged FINAL) - bool getAutorun() ; - void setAutorun(bool newValue); + Q_PROPERTY(bool autorun READ getAutorun WRITE setAutorun NOTIFY autorunChanged FINAL) + bool getAutorun(); + void setAutorun(bool newValue); - bool getAutostartInTray() ; - void setAutostartInTray(bool newValue); + bool getAutostartInTray(); + void setAutostartInTray(bool newValue); - bool getMinimizeToTray(); - void setMinimizeToTray(bool newValue); + bool getMinimizeToTray(); + void setMinimizeToTray(bool newValue); - void setAutoSaveEnabled(bool newValue); - bool getAutoSaveEnabled() ; + void setAutoSaveEnabled(bool newValue); + bool getAutoSaveEnabled(); - Q_PROPERTY(bool minimizeOnClose READ getMinimizeOnClose WRITE setMinimizeOnClose NOTIFY - minimizeOnCloseChanged FINAL) + Q_PROPERTY(bool minimizeOnClose READ getMinimizeOnClose WRITE setMinimizeOnClose NOTIFY + minimizeOnCloseChanged FINAL) - bool getMinimizeOnClose() ; - void setMinimizeOnClose(bool newValue); + bool getMinimizeOnClose(); + void setMinimizeOnClose(bool newValue); + QString getCurrentProfile(); + uint32_t getCurrentProfileId(); + void setCurrentProfile(const QString& profile); - QString getCurrentProfile() ; - uint32_t getCurrentProfileId() ; - void setCurrentProfile(const QString& profile); - - QString getProvider() ; - void setProvider(QString val); + QString getProvider(); + void setProvider(QString val); private: - static uint32_t makeProfileId(const QString& profile); + static uint32_t makeProfileId(const QString& profile); - QThread* settingsThread; + QThread* settingsThread; - CompatibleRecursiveMutex bigLock; - QString translation; - QString provider; + CompatibleRecursiveMutex bigLock; + QString translation; + QString provider; - bool showSystemTray; - bool closeToTray; - bool autostartInTray; - bool minimizeToTray; - bool minimizeOnClose; + bool showSystemTray; + bool closeToTray; + bool autostartInTray; + bool minimizeToTray; + bool minimizeOnClose; - bool autoSaveEnabled; + bool autoSaveEnabled; - QString currentProfile; - uint32_t currentProfileId; + QString currentProfile; + uint32_t currentProfileId; signals: - void translationChanged(const QString &translation); - void providerChanged(const QString &p); - - void showSystemTrayChanged(bool enabled); + void translationChanged(const QString& translation); + void providerChanged(const QString& p); + + void showSystemTrayChanged(bool enabled); - void closeToTrayChanged(bool enabled); + void closeToTrayChanged(bool enabled); - void autostartInTrayChanged(bool enabled); + void autostartInTrayChanged(bool enabled); - bool minimizeOnCloseChanged(bool enabled); - void minimizeToTrayChanged(bool enabled); + bool minimizeOnCloseChanged(bool enabled); + void minimizeToTrayChanged(bool enabled); - void autorunChanged(bool enabled); - void autoSaveEnabledChanged(bool enabled); + void autorunChanged(bool enabled); + void autoSaveEnabledChanged(bool enabled); - void currentProfileIdChanged(quint32 id); + void currentProfileIdChanged(quint32 id); public slots: - void saveGlobal(); + void saveGlobal(); }; -} // namespace base +} // namespace ok::base diff --git a/src/base/Page.cpp b/src/base/Page.cpp index 90f39f2f..6cf6e266 100644 --- a/src/base/Page.cpp +++ b/src/base/Page.cpp @@ -15,7 +15,7 @@ namespace UI { -Page::Page(QWidget *parent) : QFrame(parent) {} +Page::Page(QWidget* parent) : QFrame(parent) {} Page::~Page() {} -} // namespace UI \ No newline at end of file +} // namespace UI \ No newline at end of file diff --git a/src/base/Page.h b/src/base/Page.h index 2cb72075..c9ac8956 100644 --- a/src/base/Page.h +++ b/src/base/Page.h @@ -12,22 +12,18 @@ #pragma once -#include "UI/core/ui.h" #include +#include "UI/core/ui.h" namespace UI { -enum class PageMenu { - chat, - setting, - platform -}; +enum class PageMenu { chat, setting, platform }; class Page : public QFrame { - Q_OBJECT + Q_OBJECT public: - explicit Page(QWidget *parent = nullptr) ; -~Page() ; + explicit Page(QWidget* parent = nullptr); + ~Page(); }; -} // namespace UI +} // namespace UI diff --git a/src/base/PageFactory.h b/src/base/PageFactory.h index c63c1a90..b282e653 100644 --- a/src/base/PageFactory.h +++ b/src/base/PageFactory.h @@ -16,20 +16,20 @@ #include - namespace UI { -class PageFactory{ +class PageFactory { public: - template + template static - //Restrict type T to Page - typename std::enable_if::type //T -> Page - *Create(QWidget *parent = Q_NULLPTR){ + // Restrict type T to Page + typename std::enable_if::type // T -> Page + * + Create(QWidget* parent = Q_NULLPTR) { return new T(parent); } }; -} +} // namespace UI -#endif // PAGEFACTORY_H +#endif // PAGEFACTORY_H diff --git a/src/base/RecursiveSignalBlocker.cpp b/src/base/RecursiveSignalBlocker.cpp index c6acb097..c523537b 100644 --- a/src/base/RecursiveSignalBlocker.cpp +++ b/src/base/RecursiveSignalBlocker.cpp @@ -28,22 +28,15 @@ blocker gets destroyed. According to QSignalBlocker, we are also exception safe. @brief Creates a QSignalBlocker recursively on the object and child objects. @param[in] object the object, which signals should be blocked */ -RecursiveSignalBlocker::RecursiveSignalBlocker(QObject* object) -{ - recursiveBlock(object); -} +RecursiveSignalBlocker::RecursiveSignalBlocker(QObject* object) { recursiveBlock(object); } -RecursiveSignalBlocker::~RecursiveSignalBlocker() -{ - qDeleteAll(mBlockers); -} +RecursiveSignalBlocker::~RecursiveSignalBlocker() { qDeleteAll(mBlockers); } /** @brief Recursively blocks all signals of the object. @param[in] object the object to block */ -void RecursiveSignalBlocker::recursiveBlock(QObject* object) -{ +void RecursiveSignalBlocker::recursiveBlock(QObject* object) { mBlockers << new QSignalBlocker(object); for (QObject* child : object->children()) { diff --git a/src/base/RecursiveSignalBlocker.h b/src/base/RecursiveSignalBlocker.h index e0890661..36a1b441 100644 --- a/src/base/RecursiveSignalBlocker.h +++ b/src/base/RecursiveSignalBlocker.h @@ -18,8 +18,7 @@ class QObject; class QSignalBlocker; -class RecursiveSignalBlocker -{ +class RecursiveSignalBlocker { public: explicit RecursiveSignalBlocker(QObject* object); ~RecursiveSignalBlocker(); diff --git a/src/base/StringUtils.cpp b/src/base/StringUtils.cpp index e24474a0..4f7756fe 100644 --- a/src/base/StringUtils.cpp +++ b/src/base/StringUtils.cpp @@ -19,29 +19,27 @@ namespace olc { namespace base { -void str_tolower(std::string &s) { - std::transform(s.begin(), s.end(), s.begin(), - [](unsigned char c) { return std::toupper(c); }); +void str_tolower(std::string& s) { + std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c) { return std::toupper(c); }); } bool str_equals(std::string s1, std::string s2, bool case_sensitivity) { - if (!case_sensitivity) { - str_tolower(s1); - str_tolower(s2); - } - return s1 == s2; + if (!case_sensitivity) { + str_tolower(s1); + str_tolower(s2); + } + return s1 == s2; } -void str_join(std::vector &v, std::string &out, - const std::string &dot) { - for (std::size_t i = 0; i < v.size(); i++) { - out += v.at(i); - if (i < v.size() - 1) { - out += dot; +void str_join(std::vector& v, std::string& out, const std::string& dot) { + for (std::size_t i = 0; i < v.size(); i++) { + out += v.at(i); + if (i < v.size() - 1) { + out += dot; + } } - } } -} // namespace base +} // namespace base -} // namespace olc +} // namespace olc diff --git a/src/base/StringUtils.h b/src/base/StringUtils.h index 9b30938d..5203773d 100644 --- a/src/base/StringUtils.h +++ b/src/base/StringUtils.h @@ -20,12 +20,11 @@ namespace olc { namespace base { -void str_tolower(std::string &s); +void str_tolower(std::string& s); -void str_join(std::vector &v, std::string &s, - const std::string &dot); +void str_join(std::vector& v, std::string& s, const std::string& dot); bool str_equals(std::string s1, std::string s2, bool case_sensitivity); -} // namespace base -} // namespace olc +} // namespace base +} // namespace olc diff --git a/src/base/SvgUtils.h b/src/base/SvgUtils.h index bba701bd..852eaf20 100644 --- a/src/base/SvgUtils.h +++ b/src/base/SvgUtils.h @@ -24,44 +24,41 @@ class SvgUtils { public: - /** - * 将SVG渲染到QPixmap以支持不失真的伸缩 - * @brief renderTo - * @param path - * @param pm - */ - inline static void renderTo(const QString &path, QPixmap &pm) { - QSvgRenderer renderer(path); - pm.fill(Qt::transparent); - QPainter painter(&pm); - renderer.render(&painter, pm.rect()); - } - - inline static QIcon prepareIcon(const QString &path, int w, int h) { - if (!(w > 0 && h > 0)) { - return QIcon{path}; + /** + * 将SVG渲染到QPixmap以支持不失真的伸缩 + * @brief renderTo + * @param path + * @param pm + */ + inline static void renderTo(const QString& path, QPixmap& pm) { + QSvgRenderer renderer(path); + pm.fill(Qt::transparent); + QPainter painter(&pm); + renderer.render(&painter, pm.rect()); } + inline static QIcon prepareIcon(const QString& path, int w, int h) { + if (!(w > 0 && h > 0)) { + return QIcon{path}; + } + #ifdef Q_OS_LINUX - QPixmap pm(w, h); - renderTo(path, pm); - return QIcon{pm}; + QPixmap pm(w, h); + renderTo(path, pm); + return QIcon{pm}; #else - return QIcon{path}; + return QIcon{path}; #endif - } + } - static QPixmap scaleSvgImage(const QString& path, - quint32 width, - quint32 height) - { - QSvgRenderer render(path); - QPixmap pixmap(width, height); - pixmap.fill(QColor(0, 0, 0, 0)); - QPainter painter(&pixmap); - render.render(&painter, pixmap.rect()); - return pixmap; - } + static QPixmap scaleSvgImage(const QString& path, quint32 width, quint32 height) { + QSvgRenderer render(path); + QPixmap pixmap(width, height); + pixmap.fill(QColor(0, 0, 0, 0)); + QPainter painter(&pixmap); + render.render(&painter, pixmap.rect()); + return pixmap; + } }; -#endif // OKMSG_PROJECT_SVGUTILS_H +#endif // OKMSG_PROJECT_SVGUTILS_H diff --git a/src/base/autorun.h b/src/base/autorun.h index 017bc825..9c0ad36c 100644 --- a/src/base/autorun.h +++ b/src/base/autorun.h @@ -16,8 +16,6 @@ namespace Platform { bool setAutorun(bool on); bool getAutorun(); -} - -#endif // PLATFORM_AUTORUN_H - +} // namespace Platform +#endif // PLATFORM_AUTORUN_H diff --git a/src/base/basic_types.h b/src/base/basic_types.h index 9aad6805..10276ed6 100644 --- a/src/base/basic_types.h +++ b/src/base/basic_types.h @@ -11,47 +11,34 @@ */ #pragma once +#include +#include #include #include -#include -#include -template -using Fn = std::function; +template using Fn = std::function; namespace base { - template - inline Type take(Type &value) { - return std::exchange(value, Type {}); - } +template inline Type take(Type& value) { return std::exchange(value, Type{}); } - template - inline Type duplicate(const Type &value) { - return value; - } +template inline Type duplicate(const Type& value) { return value; } - template - inline constexpr size_t array_size(const Type(&)[Size]) { - return Size; - } +template inline constexpr size_t array_size(const Type (&)[Size]) { + return Size; } - - +} // namespace base #define qsl(s) QStringLiteral(s) #define qstr(s) QLatin1String(s, sizeof(s) - 1) #define qstring(s) QString::fromStdString(s) #define stdstring(s) s.toStdString() -inline QStringList qstringlist(std::list sl){ - QStringList qsl; - for(auto s:sl){ - qsl.append(qstring(s)); - } - return qsl; +inline QStringList qstringlist(std::list sl) { + QStringList qsl; + for (auto s : sl) { + qsl.append(qstring(s)); + } + return qsl; } - #define ARRAY_LENGTH_OF(array) (sizeof(array) / sizeof(array[0])) - - diff --git a/src/base/colorhelper.h b/src/base/colorhelper.h index aae76da0..00718bbc 100644 --- a/src/base/colorhelper.h +++ b/src/base/colorhelper.h @@ -18,42 +18,41 @@ namespace base { class ColorHelper { - public: - enum FORMAT { RGBA, RGB, HEX }; - - static QString makeColorString(const QColor &color, const FORMAT type = HEX) { - switch (type) { - case HEX: - return color.name().toUpper(); - // return QString().sprintf("#%02X%02X%02X", - // color.red(), - // color.green(), - // color.blue()); - // .arg(color.alpha() != 255 ? - // QString().sprintf("%02X", color.alpha()) : - // QString()); - // break; - case RGB: - return QString("rgb(%1, %2, %3)") - .arg(color.red()) - .arg(color.green()) - .arg(color.blue()); - // break; - case RGBA: - - return QString("rgba(%1, %2, %3, %4)") - .arg(color.red()) - .arg(color.green()) - .arg(color.blue()) - .arg(color.alpha()); - // break; + enum FORMAT { RGBA, RGB, HEX }; + + static QString makeColorString(const QColor& color, const FORMAT type = HEX) { + switch (type) { + case HEX: + return color.name().toUpper(); + // return QString().sprintf("#%02X%02X%02X", + // color.red(), + // color.green(), + // color.blue()); + // .arg(color.alpha() != 255 ? + // QString().sprintf("%02X", color.alpha()) : + // QString()); + // break; + case RGB: + return QString("rgb(%1, %2, %3)") + .arg(color.red()) + .arg(color.green()) + .arg(color.blue()); + // break; + case RGBA: + + return QString("rgba(%1, %2, %3, %4)") + .arg(color.red()) + .arg(color.green()) + .arg(color.blue()) + .arg(color.alpha()); + // break; + } + + return color.name(); } - - return color.name(); - } }; -} // namespace base +} // namespace base -#endif // COLORHELPER_H +#endif // COLORHELPER_H diff --git a/src/base/compatiblerecursivemutex.h b/src/base/compatiblerecursivemutex.h index 242ae897..f03d1ca1 100644 --- a/src/base/compatiblerecursivemutex.h +++ b/src/base/compatiblerecursivemutex.h @@ -16,14 +16,10 @@ #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) #include -class CompatibleRecursiveMutex : public QRecursiveMutex -{}; +class CompatibleRecursiveMutex : public QRecursiveMutex {}; #else -class CompatibleRecursiveMutex : public QMutex -{ +class CompatibleRecursiveMutex : public QMutex { public: - CompatibleRecursiveMutex() - : QMutex(QMutex::Recursive) - {} + CompatibleRecursiveMutex() : QMutex(QMutex::Recursive) {} }; #endif diff --git a/src/base/files.h b/src/base/files.h index 0fdf926d..12e22422 100644 --- a/src/base/files.h +++ b/src/base/files.h @@ -23,143 +23,138 @@ namespace ok::base { enum class FileContentType { - UNKOWN, - PDF, - PNG, - JPG, - BMP, - VIDEO, - TXT, - DOC, - DOCX, - PPT, - PPTX, - XLS, - XLSX + UNKOWN, + PDF, + PNG, + JPG, + BMP, + VIDEO, + TXT, + DOC, + DOCX, + PPT, + PPTX, + XLS, + XLSX }; class Files { public: - Files(); - - static QString GetContentTypeStr(const QString &fileName) { - QFileInfo info(fileName); - QMimeDatabase mimeDB; - return mimeDB.mimeTypeForFile(info).name(); - } - - static FileContentType toContentTypeE(const QString &_contentType) { - if (_contentType.compare("application/pdf") == 0) // PDF - { - return FileContentType::PDF; - } else if (_contentType.compare("video/mp4") == 0 || // mp4 - _contentType.compare("video/x-msvideo") == 0 || // avi - _contentType.compare("video/x-ms-wmv") == 0 || // wmv - _contentType.compare("video/x-flv") == 0 // flv - ) { - return FileContentType::VIDEO; - } else if (_contentType.compare("application/msword") == 0) // doc - { - return FileContentType::DOC; - } else if (_contentType.compare("application/" - "vnd.openxmlformats-officedocument." - "wordprocessingml.document") == 0) // docx - { - return FileContentType::DOCX; - } else if (_contentType.compare("application/vnd.ms-powerpoint") == - 0) // ppt - { - return FileContentType::PPT; - } else if (_contentType.compare("application/" - "vnd.openxmlformats-officedocument." - "presentationml.presentation") == 0) // pptx - { - return FileContentType::PPTX; - } else if (_contentType.compare("image/png") == 0) { - return FileContentType::PNG; - } else if (_contentType.compare("image/jpeg") == 0 || - _contentType.compare("image/pjpeg") == 0) { - return FileContentType::JPG; - } else if (_contentType.compare("image/bmp") == 0) { - return FileContentType::BMP; + Files(); + + static QString GetContentTypeStr(const QString& fileName) { + QFileInfo info(fileName); + QMimeDatabase mimeDB; + return mimeDB.mimeTypeForFile(info).name(); + } + + static FileContentType toContentTypeE(const QString& _contentType) { + if (_contentType.compare("application/pdf") == 0) // PDF + { + return FileContentType::PDF; + } else if (_contentType.compare("video/mp4") == 0 || // mp4 + _contentType.compare("video/x-msvideo") == 0 || // avi + _contentType.compare("video/x-ms-wmv") == 0 || // wmv + _contentType.compare("video/x-flv") == 0 // flv + ) { + return FileContentType::VIDEO; + } else if (_contentType.compare("application/msword") == 0) // doc + { + return FileContentType::DOC; + } else if (_contentType.compare("application/" + "vnd.openxmlformats-officedocument." + "wordprocessingml.document") == 0) // docx + { + return FileContentType::DOCX; + } else if (_contentType.compare("application/vnd.ms-powerpoint") == 0) // ppt + { + return FileContentType::PPT; + } else if (_contentType.compare("application/" + "vnd.openxmlformats-officedocument." + "presentationml.presentation") == 0) // pptx + { + return FileContentType::PPTX; + } else if (_contentType.compare("image/png") == 0) { + return FileContentType::PNG; + } else if (_contentType.compare("image/jpeg") == 0 || + _contentType.compare("image/pjpeg") == 0) { + return FileContentType::JPG; + } else if (_contentType.compare("image/bmp") == 0) { + return FileContentType::BMP; + } + + return FileContentType::UNKOWN; } - return FileContentType::UNKOWN; - } - - static FileContentType GetContentType(const QString &filename) { - QString _contentType = GetContentTypeStr(filename); - return toContentTypeE(_contentType); - } - - static bool isImage(const QString &contentType) { - FileContentType _contentType = toContentTypeE(contentType); - switch (_contentType) { - case FileContentType::PNG: - case FileContentType::BMP: - case FileContentType::JPG: - return true; - default: - break; + static FileContentType GetContentType(const QString& filename) { + QString _contentType = GetContentTypeStr(filename); + return toContentTypeE(_contentType); } - return false; - } - - static bool writeTo(const QByteArray &byteArray_, const QString &path) { - QFile file(path); - if (!file.open(QIODevice::OpenModeFlag::WriteOnly)) - return false; - file.write(byteArray_); - file.close(); - return true; - } - - inline static bool moveFile(const QString& oldPath, QString newPath) { - QFile file(oldPath); - if (!file.exists()) - return false; - return file.rename(newPath); - } - - inline static bool removeFile(const QString &filePath) { - QFile file(filePath); - if (file.exists()) { - return file.remove(); - } else { - return false; + static bool isImage(const QString& contentType) { + FileContentType _contentType = toContentTypeE(contentType); + switch (_contentType) { + case FileContentType::PNG: + case FileContentType::BMP: + case FileContentType::JPG: + return true; + default: + break; + } + + return false; } - } - inline static QString readStringAll(const QString& path){ - QFile file(path); - if (!file.open(QFile::ReadOnly)) { - return QString{}; + static bool writeTo(const QByteArray& byteArray_, const QString& path) { + QFile file(path); + if (!file.open(QIODevice::OpenModeFlag::WriteOnly)) return false; + file.write(byteArray_); + file.close(); + return true; } - return file.readAll(); - } - static bool ReadKeyValueLine(const QString &filePath, const QString &delimiter, - Fn fn) { + inline static bool moveFile(const QString& oldPath, QString newPath) { + QFile file(oldPath); + if (!file.exists()) return false; + return file.rename(newPath); + } - QFile file(filePath); + inline static bool removeFile(const QString& filePath) { + QFile file(filePath); + if (file.exists()) { + return file.remove(); + } else { + return false; + } + } - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) - return false; + inline static QString readStringAll(const QString& path) { + QFile file(path); + if (!file.open(QFile::ReadOnly)) { + return QString{}; + } + return file.readAll(); + } - QTextStream stream(&file); - QString line; - while (stream.readLineInto(&line)) { - auto arr = line.split(delimiter); - if (arr.size() == 2 && !arr[1].isEmpty()) { - fn(arr[0].trimmed(), arr[1].trimmed()); - } + static bool ReadKeyValueLine(const QString& filePath, const QString& delimiter, + Fn fn) { + QFile file(filePath); + + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) return false; + + QTextStream stream(&file); + QString line; + while (stream.readLineInto(&line)) { + auto arr = line.split(delimiter); + if (arr.size() == 2 && !arr[1].isEmpty()) { + fn(arr[0].trimmed(), arr[1].trimmed()); + } + } + file.close(); + return true; } - file.close(); - return true; - } }; -} // namespace base +} // namespace ok::base -#endif // FILES_H +#endif // FILES_H diff --git a/src/base/hashs.cpp b/src/base/hashs.cpp index 3676dcc6..7cdb6cd8 100644 --- a/src/base/hashs.cpp +++ b/src/base/hashs.cpp @@ -21,10 +21,10 @@ namespace lib { namespace base { -QString Hashs::sha1(const QByteArray &buf) { - QCryptographicHash hash(QCryptographicHash::Algorithm::Sha1); - hash.addData(buf); - return QString{hash.result().toHex()}; +QString Hashs::sha1(const QByteArray& buf) { + QCryptographicHash hash(QCryptographicHash::Algorithm::Sha1); + hash.addData(buf); + return QString{hash.result().toHex()}; } -} // namespace base -} // namespace lib +} // namespace base +} // namespace lib diff --git a/src/base/hashs.h b/src/base/hashs.h index e65e7556..ec9656f0 100644 --- a/src/base/hashs.h +++ b/src/base/hashs.h @@ -18,7 +18,7 @@ namespace base { class Hashs { public: - static QString sha1(const QByteArray &buf); + static QString sha1(const QByteArray& buf); }; -} // namespace base -} // namespace lib \ No newline at end of file +} // namespace base +} // namespace lib \ No newline at end of file diff --git a/src/base/images.h b/src/base/images.h index ade1366f..248aae49 100644 --- a/src/base/images.h +++ b/src/base/images.h @@ -16,51 +16,50 @@ #pragma once #include -#include #include #include - +#include namespace base { class Images { public: - inline static bool putToImage(const QByteArray &data, QImage &image) { - return image.loadFromData(data); - } - inline static bool putToPixmap(const QByteArray &data, QPixmap &pixmap) { - return pixmap.loadFromData(data); - } - - static QPixmap roundRectPixmap(const QPixmap & srcPixMap, const QSize & size, int radius) - { - //不处理空数据或者错误数据 - if (srcPixMap.isNull()) { - return srcPixMap; + inline static bool putToImage(const QByteArray& data, QImage& image) { + return image.loadFromData(data); + } + inline static bool putToPixmap(const QByteArray& data, QPixmap& pixmap) { + return pixmap.loadFromData(data); } - //获取图片尺寸 - int imageWidth = size.width(); - int imageHeight = size.height(); + static QPixmap roundRectPixmap(const QPixmap& srcPixMap, const QSize& size, int radius) { + // 不处理空数据或者错误数据 + if (srcPixMap.isNull()) { + return srcPixMap; + } - //处理大尺寸的图片,保证图片显示区域完整 - QPixmap newPixMap = srcPixMap.scaled(imageWidth, (imageHeight == 0 ? imageWidth : imageHeight),Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + // 获取图片尺寸 + int imageWidth = size.width(); + int imageHeight = size.height(); - QPixmap destImage(imageWidth, imageHeight); - destImage.fill(Qt::transparent); - QPainter painter(&destImage); - // 抗锯齿 - painter.setRenderHints(QPainter::Antialiasing, true); - // 图片平滑处理 - painter.setRenderHints(QPainter::SmoothPixmapTransform, true); - // 将图片裁剪为圆角 - QPainterPath path; - QRect rect(0, 0, imageWidth, imageHeight); - path.addRoundedRect(rect, radius, radius); - painter.setClipPath(path); - painter.drawPixmap(0, 0, imageWidth, imageHeight, newPixMap); - return destImage; - } + // 处理大尺寸的图片,保证图片显示区域完整 + QPixmap newPixMap = + srcPixMap.scaled(imageWidth, (imageHeight == 0 ? imageWidth : imageHeight), + Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + QPixmap destImage(imageWidth, imageHeight); + destImage.fill(Qt::transparent); + QPainter painter(&destImage); + // 抗锯齿 + painter.setRenderHints(QPainter::Antialiasing, true); + // 图片平滑处理 + painter.setRenderHints(QPainter::SmoothPixmapTransform, true); + // 将图片裁剪为圆角 + QPainterPath path; + QRect rect(0, 0, imageWidth, imageHeight); + path.addRoundedRect(rect, radius, radius); + painter.setClipPath(path); + painter.drawPixmap(0, 0, imageWidth, imageHeight, newPixMap); + return destImage; + } }; -} // namespace base +} // namespace base diff --git a/src/base/interface.h b/src/base/interface.h index cfbcbf05..e9ebc1b1 100644 --- a/src/base/interface.h +++ b/src/base/interface.h @@ -41,27 +41,27 @@ * SIGNAL_IMPL(Example, valueChanged, int value); * }; */ -#define DECLARE_SIGNAL(name, ...) \ - using Slot_##name = std::function; \ - virtual QMetaObject::Connection connectTo_##name(QObject *receiver, Slot_##name slot) const = 0 +#define DECLARE_SIGNAL(name, ...) \ + using Slot_##name = std::function; \ + virtual QMetaObject::Connection connectTo_##name(QObject* receiver, Slot_##name slot) const = 0 /** * @def DECLARE_SIGNAL * @brief Declare signal-like method. Should be used in interface */ -#define DECLARE_SIGNAL(name, ...) \ - using Slot_##name = std::function; \ - virtual QMetaObject::Connection connectTo_##name(QObject *receiver, Slot_##name slot) const = 0 +#define DECLARE_SIGNAL(name, ...) \ + using Slot_##name = std::function; \ + virtual QMetaObject::Connection connectTo_##name(QObject* receiver, Slot_##name slot) const = 0 /** * @def SIGNAL_IMPL * @brief Declare signal and implement signal-like method. */ -#define SIGNAL_IMPL(classname, name, ...) \ - using Slot_##name = std::function; \ - Q_SIGNAL void name(__VA_ARGS__); \ - QMetaObject::Connection connectTo_##name(QObject *receiver, Slot_##name slot) const override { \ - return connect(this, &classname::name, receiver, slot); \ +#define SIGNAL_IMPL(classname, name, ...) \ + using Slot_##name = std::function; \ + Q_SIGNAL void name(__VA_ARGS__); \ + QMetaObject::Connection connectTo_##name(QObject* receiver, Slot_##name slot) const override { \ + return connect(this, &classname::name, receiver, slot); \ } -#endif // INTERFACE_H +#endif // INTERFACE_H diff --git a/src/base/jid.cpp b/src/base/jid.cpp index 8fec8c07..370bec53 100644 --- a/src/base/jid.cpp +++ b/src/base/jid.cpp @@ -20,46 +20,46 @@ namespace base { //---------------------------------------------------------------------------- QScopedPointer StringPrepCache::_instance; -bool StringPrepCache::nameprep(const QString &in, int maxbytes, QString &out) { - if (in.trimmed().isEmpty()) { - out = QString(); - return false; // empty names or just spaces are disallowed (rfc5892+rfc6122) - } +bool StringPrepCache::nameprep(const QString& in, int maxbytes, QString& out) { + if (in.trimmed().isEmpty()) { + out = QString(); + return false; // empty names or just spaces are disallowed (rfc5892+rfc6122) + } - StringPrepCache *that = instance(); + StringPrepCache* that = instance(); - auto it = that->nameprep_table.constFind(in); - if (it != that->nameprep_table.constEnd()) { - if (it.value().isNull()) { - return false; + auto it = that->nameprep_table.constFind(in); + if (it != that->nameprep_table.constEnd()) { + if (it.value().isNull()) { + return false; + } + out = it.value(); + return true; } - out = it.value(); - return true; - } - out = in; - that->nameprep_table.insert(in, out); - return true; + out = in; + that->nameprep_table.insert(in, out); + return true; } -bool StringPrepCache::nodeprep(const QString &in, int maxbytes, QString &out) { - if (in.isEmpty()) { - out = QString(); - return true; - } +bool StringPrepCache::nodeprep(const QString& in, int maxbytes, QString& out) { + if (in.isEmpty()) { + out = QString(); + return true; + } - StringPrepCache *that = instance(); + StringPrepCache* that = instance(); - auto it = that->nodeprep_table.constFind(in); - if (it != that->nodeprep_table.constEnd()) { - if (it.value().isNull()) { - return false; + auto it = that->nodeprep_table.constFind(in); + if (it != that->nodeprep_table.constEnd()) { + if (it.value().isNull()) { + return false; + } + out = it.value(); + return true; } - out = it.value(); - return true; - } - out = in; + out = in; #if 0 if (stringprep(out, (Stringprep_profile_flags)0, stringprep_xmpp_nodeprep) != 0 || @@ -68,50 +68,49 @@ bool StringPrepCache::nodeprep(const QString &in, int maxbytes, QString &out) { return false; } #endif - that->nodeprep_table.insert(in, out); - return true; + that->nodeprep_table.insert(in, out); + return true; } -bool StringPrepCache::resourceprep(const QString &in, int maxbytes, - QString &out) { - if (in.isEmpty()) { - out = QString(); - return true; - } +bool StringPrepCache::resourceprep(const QString& in, int maxbytes, QString& out) { + if (in.isEmpty()) { + out = QString(); + return true; + } - StringPrepCache *that = instance(); + StringPrepCache* that = instance(); - auto it = that->resourceprep_table.constFind(in); - if (it != that->resourceprep_table.constEnd()) { - if (it.value().isNull()) { - return false; + auto it = that->resourceprep_table.constFind(in); + if (it != that->resourceprep_table.constEnd()) { + if (it.value().isNull()) { + return false; + } + out = it.value(); + return true; } - out = it.value(); - return true; - } - that->resourceprep_table.insert(in, out); - return true; + that->resourceprep_table.insert(in, out); + return true; } -bool StringPrepCache::saslprep(const QString &in, int maxbytes, QString &out) { - if (in.isEmpty()) { - out = QString(); - return true; - } +bool StringPrepCache::saslprep(const QString& in, int maxbytes, QString& out) { + if (in.isEmpty()) { + out = QString(); + return true; + } - StringPrepCache *that = instance(); + StringPrepCache* that = instance(); - auto it = that->saslprep_table.constFind(in); - if (it != that->saslprep_table.constEnd()) { - if (it.value().isNull()) { - return false; + auto it = that->saslprep_table.constFind(in); + if (it != that->saslprep_table.constEnd()) { + if (it.value().isNull()) { + return false; + } + out = it.value(); + return true; } - out = it.value(); - return true; - } - out = in; + out = in; #if 0 if (stringprep(out, (Stringprep_profile_flags)0, stringprep_saslprep) != 0 || out.size() > maxbytes) { @@ -119,17 +118,17 @@ bool StringPrepCache::saslprep(const QString &in, int maxbytes, QString &out) { return false; } #endif - that->saslprep_table.insert(in, out); - return true; + that->saslprep_table.insert(in, out); + return true; } void StringPrepCache::cleanup() { _instance.reset(nullptr); } -StringPrepCache *StringPrepCache::instance() { - if (!_instance) { - _instance.reset(new StringPrepCache); - } - return _instance.data(); +StringPrepCache* StringPrepCache::instance() { + if (!_instance) { + _instance.reset(new StringPrepCache); + } + return _instance.data(); } StringPrepCache::StringPrepCache() {} @@ -138,197 +137,190 @@ StringPrepCache::StringPrepCache() {} // Jid //---------------------------------------------------------------------------- // -static inline bool validDomain(const QString &s, QString &norm) { - return StringPrepCache::nameprep(s, 1024, norm); +static inline bool validDomain(const QString& s, QString& norm) { + return StringPrepCache::nameprep(s, 1024, norm); } -static inline bool validNode(const QString &s, QString &norm) { - return StringPrepCache::nodeprep(s, 1024, norm); +static inline bool validNode(const QString& s, QString& norm) { + return StringPrepCache::nodeprep(s, 1024, norm); } -static inline bool validResource(const QString &s, QString &norm) { - return StringPrepCache::resourceprep(s, 1024, norm); +static inline bool validResource(const QString& s, QString& norm) { + return StringPrepCache::resourceprep(s, 1024, norm); } Jid::Jid() { - valid = false; - null = true; + valid = false; + null = true; } Jid::~Jid() {} -Jid::Jid(const QString &s) { set(s); } +Jid::Jid(const QString& s) { set(s); } -Jid::Jid(const QString &node, const QString &domain, const QString &resource) { - set(domain, node, resource); +Jid::Jid(const QString& node, const QString& domain, const QString& resource) { + set(domain, node, resource); } -Jid::Jid(const char *s) { set(QString(s)); } +Jid::Jid(const char* s) { set(QString(s)); } -Jid &Jid::operator=(const QString &s) { - set(s); - return *this; +Jid& Jid::operator=(const QString& s) { + set(s); + return *this; } -Jid &Jid::operator=(const char *s) { - set(QString(s)); - return *this; +Jid& Jid::operator=(const char* s) { + set(QString(s)); + return *this; } -Jid &Jid::operator=(const Jid &s) { - f=s.f; - b = s.b; - d = s.d; - n = s.n; - r = s.r; - return *this; +Jid& Jid::operator=(const Jid& s) { + f = s.f; + b = s.b; + d = s.d; + n = s.n; + r = s.r; + return *this; } void Jid::reset() { - f = QString(); - b = QString(); - d = QString(); - n = QString(); - r = QString(); - valid = false; - null = true; + f = QString(); + b = QString(); + d = QString(); + n = QString(); + r = QString(); + valid = false; + null = true; } void Jid::update() { - // build 'bare' and 'full' jids - if (n.isEmpty()) - b = d; - else - b = n + '@' + d; - if (r.isEmpty()) - f = b; - else - f = b + '/' + r; - if (f.isEmpty()) - valid = false; - null = f.isEmpty() && r.isEmpty(); + // build 'bare' and 'full' jids + if (n.isEmpty()) + b = d; + else + b = n + '@' + d; + if (r.isEmpty()) + f = b; + else + f = b + '/' + r; + if (f.isEmpty()) valid = false; + null = f.isEmpty() && r.isEmpty(); } -void Jid::set(const QString &s) { - QString rest, domain, node, resource; - QString norm_domain, norm_node, norm_resource; - int x = s.indexOf('/'); - if (x != -1) { - rest = s.mid(0, x); - resource = s.mid(x + 1); - } else { - rest = s; - resource = QString(); - } -// if (!validResource(resource, norm_resource)) { -// qDebug()<<"resource"< nameprep_table; - QHash nodeprep_table; - QHash resourceprep_table; - QHash saslprep_table; + QHash nameprep_table; + QHash nodeprep_table; + QHash resourceprep_table; + QHash saslprep_table; - static QScopedPointer _instance; - static StringPrepCache *instance(); + static QScopedPointer _instance; + static StringPrepCache* instance(); - StringPrepCache(); + StringPrepCache(); }; class Jid : public QChar { public: - Jid(); - ~Jid(); - - Jid(const QString &s); - Jid(const QString &node, const QString &domain, const QString &resource = ""); - Jid(const char *s); - Jid &operator=(const QString &s); - Jid &operator=(const char *s); - Jid &operator=(const Jid &s); - - bool isNull() const { return null; } - const QString &domain() const { return d; } - const QString &node() const { return n; } - const QString &resource() const { return r; } - const QString &bare() const { return b; } - const QString &full() const { return f; } - - Jid withNode(const QString &s) const; - Jid withDomain(const QString &s) const; - Jid withResource(const QString &s) const; - - bool isValid() const; - bool isEmpty() const; - bool compare(const Jid &a, bool compareRes = true) const; - inline bool operator==(const Jid &other) const { - return compare(other, true); - } - inline bool operator!=(const Jid &other) const { return !(*this == other); } + Jid(); + ~Jid(); + + Jid(const QString& s); + Jid(const QString& node, const QString& domain, const QString& resource = ""); + Jid(const char* s); + Jid& operator=(const QString& s); + Jid& operator=(const char* s); + Jid& operator=(const Jid& s); + + bool isNull() const { return null; } + const QString& domain() const { return d; } + const QString& node() const { return n; } + const QString& resource() const { return r; } + const QString& bare() const { return b; } + const QString& full() const { return f; } + + Jid withNode(const QString& s) const; + Jid withDomain(const QString& s) const; + Jid withResource(const QString& s) const; + + bool isValid() const; + bool isEmpty() const; + bool compare(const Jid& a, bool compareRes = true) const; + inline bool operator==(const Jid& other) const { return compare(other, true); } + inline bool operator!=(const Jid& other) const { return !(*this == other); } private: - void set(const QString &s); - void set(const QString &domain, const QString &node, - const QString &resource = ""); + void set(const QString& s); + void set(const QString& domain, const QString& node, const QString& resource = ""); - void setDomain(const QString &s); - void setNode(const QString &s); - void setResource(const QString &s); + void setDomain(const QString& s); + void setNode(const QString& s); + void setResource(const QString& s); private: - void reset(); - void update(); + void reset(); + void update(); - QString f, b, d, n, r; - bool valid, null; + QString f, b, d, n, r; + bool valid, null; }; -Q_DECL_PURE_FUNCTION inline uint qHash(const Jid &key, - uint seed = 0) Q_DECL_NOTHROW { - return qHash(key.full(), seed); +Q_DECL_PURE_FUNCTION inline uint qHash(const Jid& key, uint seed = 0) Q_DECL_NOTHROW { + return qHash(key.full(), seed); } -} // namespace base +} // namespace base -#endif // XMPP_JID_H +#endif // XMPP_JID_H diff --git a/src/base/jsons.h b/src/base/jsons.h index 9aa8bdcd..c8bf0ce7 100644 --- a/src/base/jsons.h +++ b/src/base/jsons.h @@ -19,17 +19,16 @@ class Jsons { public: - inline static QString toString(const QJsonDocument &document) { - return QString{document.toJson()}; - } + inline static QString toString(const QJsonDocument& document) { + return QString{document.toJson(QJsonDocument::Compact)}; + } - inline static QJsonDocument toJSON(const QByteArray &buf) { - return QJsonDocument::fromJson(buf); - } + inline static QJsonDocument toJSON(const QByteArray& buf) { + return QJsonDocument::fromJson(buf); + } }; -template -class JsonAble { +template class JsonAble { public: - virtual T fromJson(const QJsonObject &data) = 0; -}; \ No newline at end of file + virtual T fromJson(const QJsonObject& data) = 0; +}; diff --git a/src/base/logs.cpp b/src/base/logs.cpp index 79e6b7b3..ba69ad27 100644 --- a/src/base/logs.cpp +++ b/src/base/logs.cpp @@ -22,26 +22,22 @@ namespace Logs { -void _logsWrite(const QString &msg) { qDebug().noquote() << msg; } +void _logsWrite(const QString& msg) { qDebug().noquote() << msg; } -void writeDebug(const char *file, int line, const char *func, - const std::string &str) { - - writeDebug(file, line, func, qstring(str)); +void writeDebug(const char* file, int line, const char* func, const std::string& str) { + writeDebug(file, line, func, qstring(str)); } -void writeDebug(const char *file, int line, const char *func, - const QString &v) { - QString msg( - QString("LOG:%1 [%2] (%3:%4) %5 %6") - .arg(QDateTime::currentDateTime().toString(Qt::DateFormat::ISODate)) - .arg(QThread::currentThread()->objectName()) - .arg(file) - .arg(line) - .arg(func) - .arg(v)); - - _logsWrite(msg); +void writeDebug(const char* file, int line, const char* func, const QString& v) { + QString msg(QString("LOG:%1 [%2] (%3:%4) %5 %6") + .arg(QDateTime::currentDateTime().toString(Qt::DateFormat::ISODate)) + .arg(QThread::currentThread()->objectName()) + .arg(file) + .arg(line) + .arg(func) + .arg(v)); + + _logsWrite(msg); } -} // namespace Logs +} // namespace Logs diff --git a/src/base/logs.h b/src/base/logs.h index 2623e5ff..528fbdb0 100644 --- a/src/base/logs.h +++ b/src/base/logs.h @@ -12,7 +12,6 @@ */ #pragma once -#include "basic_types.h" #include #include #include @@ -23,6 +22,7 @@ #include #include #include +#include "basic_types.h" #ifndef __FILE_NAME__ #define __FILE_NAME__ (strrchr("/" __FILE__, '/') + 1) @@ -35,10 +35,8 @@ namespace Logs { #define L_WARN "W" #define L_ERROR "E" -void writeDebug(const char *file, int line, const char *func, - const QString &str); +void writeDebug(const char* file, int line, const char* func, const QString& str); -void writeDebug(const char *file, int line, const char *func, - const std::string &str); +void writeDebug(const char* file, int line, const char* func, const std::string& str); -} // namespace Logs +} // namespace Logs diff --git a/src/base/qbasic_types.h b/src/base/qbasic_types.h index baea1745..95978225 100644 --- a/src/base/qbasic_types.h +++ b/src/base/qbasic_types.h @@ -13,13 +13,13 @@ #ifndef QBASIC_TYPES_H #define QBASIC_TYPES_H +#include #include #include -#include #include "basic_types.h" -//using uchar = unsigned char; // Qt has uchar +// using uchar = unsigned char; // Qt has uchar using int8 = qint8; using uint8 = quint8; @@ -31,4 +31,4 @@ using int64 = qint64; using uint64 = quint64; using TimeMs = uint32; -#endif // QBASIC_TYPES_H +#endif // QBASIC_TYPES_H diff --git a/src/base/r.h b/src/base/r.h index 8f5f6479..571e747d 100644 --- a/src/base/r.h +++ b/src/base/r.h @@ -15,7 +15,6 @@ #define APPLICATION_VERSION_ID GIT_VERSION #define APPLICATION_RELEASE APPLICATION_NAME "-" APPLICATION_VERSION - #define BACKEND_CLOUD_URL "https://cloud.okstar.org.cn/api/open" #define XMPP_FOCUS_NAME "focus" @@ -26,5 +25,3 @@ #define FILE_PROFILE_EXT ".profile" #define FILE_INIT_EXT ".ini" - - diff --git a/src/base/resources.h b/src/base/resources.h index d401672c..5f723f28 100644 --- a/src/base/resources.h +++ b/src/base/resources.h @@ -12,25 +12,22 @@ #pragma once -#include #include +#include -#define OK_RESOURCE_LOADER(name) \ - class name ## Loader { \ - public: \ - name ## Loader() { \ - qDebug()<<"loading resource:" << #name ; \ - Q_INIT_RESOURCE(name); \ - }; \ - ~name ## Loader(){ \ - qDebug()<<"cleanup resource:" << #name; \ - Q_CLEANUP_RESOURCE(name); \ - } \ - }; \ - +#define OK_RESOURCE_LOADER(name) \ + class name##Loader { \ + public: \ + name##Loader() { \ + qDebug() << "loading resource:" << #name; \ + Q_INIT_RESOURCE(name); \ + }; \ + ~name##Loader() { \ + qDebug() << "cleanup resource:" << #name; \ + Q_CLEANUP_RESOURCE(name); \ + } \ + }; -#define OK_RESOURCE_PTR(name) \ - std::unique_ptr _ok ## name ## _ptr\ +#define OK_RESOURCE_PTR(name) std::unique_ptr _ok##name##_ptr -#define OK_RESOURCE_INIT(name) \ - _ok ## name ## _ptr = std::make_unique() +#define OK_RESOURCE_INIT(name) _ok##name##_ptr = std::make_unique() diff --git a/src/base/singleton.h b/src/base/singleton.h index 6f4a1624..0370febd 100644 --- a/src/base/singleton.h +++ b/src/base/singleton.h @@ -16,34 +16,27 @@ template -class singleton -{ +class singleton { protected: singleton(){}; + private: singleton(const singleton&){}; - singleton& operator=(const singleton&){}; + singleton& operator=(const singleton&) {}; static T* m_instance; + public: - template - static T* GetInstance(Args&&... args) - { - if(m_instance == NULL) - m_instance = new T(std::forward(args)...); + template static T* GetInstance(Args&&... args) { + if (m_instance == NULL) m_instance = new T(std::forward(args)...); return m_instance; } - - static void DestroyInstance() - { - if(m_instance ) - delete m_instance; + static void DestroyInstance() { + if (m_instance) delete m_instance; m_instance = NULL; } }; +template T* singleton::m_instance = NULL; -template -T* singleton::m_instance = NULL; - -#endif // SINGLETON_H +#endif // SINGLETON_H diff --git a/src/base/stylediconbutton.cpp b/src/base/stylediconbutton.cpp index d4a8abb3..61dc332c 100644 --- a/src/base/stylediconbutton.cpp +++ b/src/base/stylediconbutton.cpp @@ -3,16 +3,16 @@ #include #include -void StyledIconButton::paintEvent(QPaintEvent *event) { - if (icon_use_indicator) { - QStylePainter p(this); - QStyleOptionButton option; - initStyleOption(&option); - p.drawControl(QStyle::CE_PushButtonBevel, option); +void StyledIconButton::paintEvent(QPaintEvent* event) { + if (icon_use_indicator) { + QStylePainter p(this); + QStyleOptionButton option; + initStyleOption(&option); + p.drawControl(QStyle::CE_PushButtonBevel, option); - QRect r = p.style()->subElementRect(QStyle::SE_PushButtonContents, &option, this); - option.rect = QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, iconSize(), r); - p.drawPrimitive(QStyle::PE_IndicatorCheckBox, option); - } - QPushButton::paintEvent(event); + QRect r = p.style()->subElementRect(QStyle::SE_PushButtonContents, &option, this); + option.rect = QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, iconSize(), r); + p.drawPrimitive(QStyle::PE_IndicatorCheckBox, option); + } + QPushButton::paintEvent(event); } diff --git a/src/base/stylediconbutton.h b/src/base/stylediconbutton.h index 3b793874..f8c0fd66 100644 --- a/src/base/stylediconbutton.h +++ b/src/base/stylediconbutton.h @@ -15,21 +15,21 @@ #include class StyledIconButton : public QPushButton { - Q_OBJECT - Q_PROPERTY(bool use_indicator READ iconUseIndicator WRITE setIconUseIndicator) + Q_OBJECT + Q_PROPERTY(bool use_indicator READ iconUseIndicator WRITE setIconUseIndicator) public: - using QPushButton::QPushButton; - void setIconUseIndicator(bool set) { - icon_use_indicator = set; - update(); - } - bool iconUseIndicator() { - return icon_use_indicator; - } + using QPushButton::QPushButton; + void setIconUseIndicator(bool set) { + icon_use_indicator = set; + update(); + } + bool iconUseIndicator() { return icon_use_indicator; } + protected: - void paintEvent(QPaintEvent *event) override; + void paintEvent(QPaintEvent* event) override; + private: - bool icon_use_indicator = false; + bool icon_use_indicator = false; }; #endif \ No newline at end of file diff --git a/src/base/svgiconengine.cpp b/src/base/svgiconengine.cpp index 7a6cda4f..0f6dad9e 100644 --- a/src/base/svgiconengine.cpp +++ b/src/base/svgiconengine.cpp @@ -17,51 +17,51 @@ #include #include -QSize SvgIconEngine::actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state) -{ +QSize SvgIconEngine::actualSize(const QSize& size, QIcon::Mode mode, QIcon::State state) { Q_UNUSED(mode); Q_UNUSED(state); - return size.isEmpty() ? renderer->defaultSize() : renderer->defaultSize().scaled(size, Qt::KeepAspectRatio); + return size.isEmpty() ? renderer->defaultSize() + : renderer->defaultSize().scaled(size, Qt::KeepAspectRatio); } -QIconEngine *SvgIconEngine::clone() const { return new SvgIconEngine(name, renderer); } +QIconEngine* SvgIconEngine::clone() const { return new SvgIconEngine(name, renderer); } -void SvgIconEngine::paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) -{ +void SvgIconEngine::paint(QPainter* painter, const QRect& rect, QIcon::Mode mode, + QIcon::State state) { Q_UNUSED(mode); Q_UNUSED(state); - auto r = rect.isEmpty() ? QRect(0, 0, painter->device()->width(), painter->device()->height()) : rect; + auto r = rect.isEmpty() ? QRect(0, 0, painter->device()->width(), painter->device()->height()) + : rect; renderer->render(painter, r); } -void SvgIconEngine::virtual_hook(int id, void *data) -{ +void SvgIconEngine::virtual_hook(int id, void* data) { switch (id) { - case QIconEngine::AvailableSizesHook: - reinterpret_cast(data)->sizes.clear(); - break; - case QIconEngine::IconNameHook: - *reinterpret_cast(data) = name; - break; + case QIconEngine::AvailableSizesHook: + reinterpret_cast(data)->sizes.clear(); + break; + case QIconEngine::IconNameHook: + *reinterpret_cast(data) = name; + break; #if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0) - case QIconEngine::IsNullHook: - *reinterpret_cast(data) = !(renderer && renderer->isValid()); - break; + case QIconEngine::IsNullHook: + *reinterpret_cast(data) = !(renderer && renderer->isValid()); + break; #endif #if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0) - case QIconEngine::ScaledPixmapHook: { - auto arg = reinterpret_cast(data); - arg->pixmap = pixmap(arg->size * arg->scale, arg->mode, arg->state); - break; - } + case QIconEngine::ScaledPixmapHook: { + auto arg = reinterpret_cast(data); + arg->pixmap = pixmap(arg->size * arg->scale, arg->mode, arg->state); + break; + } #endif } } -QPixmap SvgIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) -{ - QPixmap pm; - static auto findCache = [](std::list &cache, const QSize &size, QPixmap &pm) mutable { +QPixmap SvgIconEngine::pixmap(const QSize& size, QIcon::Mode mode, QIcon::State state) { + QPixmap pm; + static auto findCache = [](std::list& cache, const QSize& size, + QPixmap& pm) mutable { auto it = cache.begin(); while (it != cache.end()) { if (it->size == size) { @@ -76,25 +76,24 @@ QPixmap SvgIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State return false; }; - static auto insertCache = [](std::list &cache, const QSize &size, const QPixmap &pm) mutable { - cache.push_back(CacheEntry { QPixmapCache::insert(pm), size }); + static auto insertCache = [](std::list& cache, const QSize& size, + const QPixmap& pm) mutable { + cache.push_back(CacheEntry{QPixmapCache::insert(pm), size}); if (cache.size() > 5) { QPixmapCache::remove(cache.front().key); } }; - if (mode == QIcon::Disabled && findCache(disabledCache, size, pm)) - return pm; + if (mode == QIcon::Disabled && findCache(disabledCache, size, pm)) return pm; if (findCache(normalCache, size, pm)) { - if (mode == QIcon::Active || mode == QIcon::Normal) - return pm; + if (mode == QIcon::Active || mode == QIcon::Normal) return pm; } if (!pm) { pm = renderPixmap(size, mode, state); insertCache(normalCache, size, pm); - } // else we need selected or disabled from normal which we took from the cache + } // else we need selected or disabled from normal which we took from the cache if (mode == QIcon::Selected) { auto hlColor = qApp->palette().color(QPalette::Normal, QPalette::Highlight); @@ -129,11 +128,11 @@ QPixmap SvgIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State return pm; } -QPixmap SvgIconEngine::renderPixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) -{ +QPixmap SvgIconEngine::renderPixmap(const QSize& size, QIcon::Mode mode, QIcon::State state) { Q_UNUSED(mode) Q_UNUSED(state) - auto sz = size.isEmpty() ? renderer->defaultSize() : renderer->defaultSize().scaled(size, Qt::KeepAspectRatio); + auto sz = size.isEmpty() ? renderer->defaultSize() + : renderer->defaultSize().scaled(size, Qt::KeepAspectRatio); QPixmap pix(sz); pix.fill(Qt::transparent); QPainter p(&pix); diff --git a/src/base/svgiconengine.h b/src/base/svgiconengine.h index 926a039c..8a39a07a 100644 --- a/src/base/svgiconengine.h +++ b/src/base/svgiconengine.h @@ -19,28 +19,28 @@ #include class SvgIconEngine : public QIconEngine { - - QString name; + QString name; std::shared_ptr renderer; struct CacheEntry { QPixmapCache::Key key; - QSize size; + QSize size; }; std::list normalCache, disabledCache; public: - SvgIconEngine(const QString &name, std::shared_ptr renderer) : name(name), renderer(renderer) { } + SvgIconEngine(const QString& name, std::shared_ptr renderer) + : name(name), renderer(renderer) {} - QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state) override; - QIconEngine *clone() const override; - void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) override; - void virtual_hook(int id, void *data) override; + QSize actualSize(const QSize& size, QIcon::Mode mode, QIcon::State state) override; + QIconEngine* clone() const override; + void paint(QPainter* painter, const QRect& rect, QIcon::Mode mode, QIcon::State state) override; + void virtual_hook(int id, void* data) override; - QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) override; + QPixmap pixmap(const QSize& size, QIcon::Mode mode, QIcon::State state) override; private: - QPixmap renderPixmap(const QSize &size, QIcon::Mode mode, QIcon::State state); + QPixmap renderPixmap(const QSize& size, QIcon::Mode mode, QIcon::State state); }; -#endif // SVGICONENGINE_H +#endif // SVGICONENGINE_H diff --git a/src/base/system/linux/autorun_xdg.cpp b/src/base/system/linux/autorun_xdg.cpp index 65474ed8..f753f53a 100644 --- a/src/base/system/linux/autorun_xdg.cpp +++ b/src/base/system/linux/autorun_xdg.cpp @@ -12,48 +12,40 @@ #include "base/autorun.h" -#include "base/r.h" #include #include #include +#include "base/r.h" namespace Platform { QString getAutostartDirPath() { - QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); - QString config = env.value("XDG_CONFIG_HOME"); - if (config.isEmpty()) - config = QDir::homePath() + "/" + ".config"; - return config + "/autostart"; + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); + QString config = env.value("XDG_CONFIG_HOME"); + if (config.isEmpty()) config = QDir::homePath() + "/" + ".config"; + return config + "/autostart"; } -QString getAutostartFilePath(QString dir) { - return dir + "/" APPLICATION_NAME + ".desktop"; -} +QString getAutostartFilePath(QString dir) { return dir + "/" APPLICATION_NAME + ".desktop"; } -inline QString currentCommandLine() { - return QApplication::applicationFilePath(); -} -} // namespace Platform +inline QString currentCommandLine() { return QApplication::applicationFilePath(); } +} // namespace Platform bool Platform::setAutorun(bool on) { - QString dirPath = getAutostartDirPath(); - QFile desktop(getAutostartFilePath(dirPath)); - if (on) { - if (!QDir().mkpath(dirPath) || - !desktop.open(QFile::WriteOnly | QFile::Truncate)) - return false; - desktop.write("[Desktop Entry]\n"); - desktop.write("Type=Application\n"); - desktop.write("Name=" APPLICATION_EXE_NAME "\n"); - desktop.write("Exec=\""); - desktop.write(currentCommandLine().toUtf8()); - desktop.write("\"\n"); - desktop.close(); - return true; - } else - return desktop.remove(); + QString dirPath = getAutostartDirPath(); + QFile desktop(getAutostartFilePath(dirPath)); + if (on) { + if (!QDir().mkpath(dirPath) || !desktop.open(QFile::WriteOnly | QFile::Truncate)) + return false; + desktop.write("[Desktop Entry]\n"); + desktop.write("Type=Application\n"); + desktop.write("Name=" APPLICATION_EXE_NAME "\n"); + desktop.write("Exec=\""); + desktop.write(currentCommandLine().toUtf8()); + desktop.write("\"\n"); + desktop.close(); + return true; + } else + return desktop.remove(); } -bool Platform::getAutorun() { - return QFile(getAutostartFilePath(getAutostartDirPath())).exists(); -} +bool Platform::getAutorun() { return QFile(getAutostartFilePath(getAutostartDirPath())).exists(); } diff --git a/src/base/system/linux/sys_info.cpp b/src/base/system/linux/sys_info.cpp index b4ad628e..13915979 100644 --- a/src/base/system/linux/sys_info.cpp +++ b/src/base/system/linux/sys_info.cpp @@ -20,60 +20,57 @@ namespace ok::base { -bool SysInfo::GetCpuInfo(CpuInfo &info) { - auto arch = QSysInfo::currentCpuArchitecture(); - info.arch = arch == "x86_64" ? "x64" : arch; - return Files::ReadKeyValueLine( - "/proc/cpuinfo", ":", [&](const QString &k, const QString &v) { +bool SysInfo::GetCpuInfo(CpuInfo& info) { + auto arch = QSysInfo::currentCpuArchitecture(); + info.arch = arch == "x86_64" ? "x64" : arch; + return Files::ReadKeyValueLine("/proc/cpuinfo", ":", [&](const QString& k, const QString& v) { if (k == "vendor_id") { - info.manufacturer = v; + info.manufacturer = v; } else if (k == "model name") { - info.name = v; + info.name = v; } else if (k == "cpu cores") { - info.cores = std::stoi(v.toStdString()); + info.cores = std::stoi(v.toStdString()); } else if (k == "processor") { - info.processors = std::stoi(v.toStdString()) + 1; + info.processors = std::stoi(v.toStdString()) + 1; } - }); + }); } -bool SysInfo::GetOsInfo(OsInfo &info) { - - /** - * /etc/os-release - * PRETTY_NAME="Ubuntu 22.04.2 LTS" - * NAME="Ubuntu" - * VERSION_ID="22.04" - */ - info.uniqueId = QSysInfo::machineUniqueId().toBase64(); - info.hostName = QSysInfo::machineHostName(); - info.kernelName = QSysInfo::kernelType(); - info.kernelVersion = QSysInfo::kernelVersion(); - info.prettyName = QSysInfo::prettyProductName(); - info.name = QSysInfo::productType(); - info.version = QSysInfo::productVersion(); - return true; +bool SysInfo::GetOsInfo(OsInfo& info) { + /** + * /etc/os-release + * PRETTY_NAME="Ubuntu 22.04.2 LTS" + * NAME="Ubuntu" + * VERSION_ID="22.04" + */ + info.uniqueId = QSysInfo::machineUniqueId().toBase64(); + info.hostName = QSysInfo::machineHostName(); + info.kernelName = QSysInfo::kernelType(); + info.kernelVersion = QSysInfo::kernelVersion(); + info.prettyName = QSysInfo::prettyProductName(); + info.name = QSysInfo::productType(); + info.version = QSysInfo::productVersion(); + return true; } -SystemInfo *SystemInfo::instance() { - static SystemInfo *instance_ = nullptr; - if (!instance_) - instance_ = new SystemInfo(); - return instance_; +SystemInfo* SystemInfo::instance() { + static SystemInfo* instance_ = nullptr; + if (!instance_) instance_ = new SystemInfo(); + return instance_; } QString SystemInfo::osVersion() { return osInfo().name; } OsInfo SystemInfo::osInfo() { - OsInfo info; - SysInfo::GetOsInfo(info); - return info; + OsInfo info; + SysInfo::GetOsInfo(info); + return info; } CpuInfo SystemInfo::cpuInfo() { - CpuInfo info; - SysInfo::GetCpuInfo(info); - return info; + CpuInfo info; + SysInfo::GetCpuInfo(info); + return info; } -} // namespace ok::base +} // namespace ok::base diff --git a/src/base/system/macos/autorun_osx.cpp b/src/base/system/macos/autorun_osx.cpp index dba30e41..5e0d433a 100644 --- a/src/base/system/macos/autorun_osx.cpp +++ b/src/base/system/macos/autorun_osx.cpp @@ -10,23 +10,22 @@ * See the Mulan PubL v2 for more details. */ -#include "base/autorun.h" #include #include #include #include #include +#include "base/autorun.h" int state; -bool Platform::setAutorun(bool on) -{ +bool Platform::setAutorun(bool on) { QString qtoxPlist = - QDir::cleanPath(QStandardPaths::writableLocation(QStandardPaths::HomeLocation) - + QDir::separator() + "Library" + QDir::separator() + "LaunchAgents" - + QDir::separator() + "chat.tox.qtox.autorun.plist"); + QDir::cleanPath(QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + + QDir::separator() + "Library" + QDir::separator() + "LaunchAgents" + + QDir::separator() + "chat.tox.qtox.autorun.plist"); QString qtoxDir = - QDir::cleanPath(QCoreApplication::applicationDirPath() + QDir::separator() + "qtox"); + QDir::cleanPath(QCoreApplication::applicationDirPath() + QDir::separator() + "qtox"); QSettings autoRun(qtoxPlist, QSettings::NativeFormat); autoRun.setValue("Label", "chat.tox.qtox.autorun"); autoRun.setValue("Program", qtoxDir); @@ -36,7 +35,4 @@ bool Platform::setAutorun(bool on) return true; } -bool Platform::getAutorun() -{ - return state; -} +bool Platform::getAutorun() { return state; } diff --git a/src/base/system/macos/sys_info.cpp b/src/base/system/macos/sys_info.cpp index dc4da3e4..946b7787 100644 --- a/src/base/system/macos/sys_info.cpp +++ b/src/base/system/macos/sys_info.cpp @@ -14,66 +14,65 @@ #include "files.h" #include -#include #include +#include #include #include namespace ok::base { -bool SysInfo::GetCpuInfo(CpuInfo &info) { - auto arch = QSysInfo::currentCpuArchitecture(); - info.arch = arch == "x86_64" ? "x64" : arch; - return ok::base::Files::ReadKeyValueLine("/proc/cpuinfo", ":", - [&](const QString &k, const QString &v) { - if (k == "vendor_id") { - info.manufacturer = v; - } else if (k == "model name") { - info.name = v; - } else if (k == "cpu cores") { - info.cores = std::stoi(v.toStdString()); - } else if (k == "processor") { - info.processors = std::stoi(v.toStdString()) + 1; - } - }); +bool SysInfo::GetCpuInfo(CpuInfo& info) { + auto arch = QSysInfo::currentCpuArchitecture(); + info.arch = arch == "x86_64" ? "x64" : arch; + return ok::base::Files::ReadKeyValueLine( + "/proc/cpuinfo", ":", [&](const QString& k, const QString& v) { + if (k == "vendor_id") { + info.manufacturer = v; + } else if (k == "model name") { + info.name = v; + } else if (k == "cpu cores") { + info.cores = std::stoi(v.toStdString()); + } else if (k == "processor") { + info.processors = std::stoi(v.toStdString()) + 1; + } + }); } -bool SysInfo::GetOsInfo(OsInfo &info) { - /** - * /etc/os-release - * PRETTY_NAME="Ubuntu 22.04.2 LTS" - * NAME="Ubuntu" - * VERSION_ID="22.04" - */ - info.uniqueId = QSysInfo::machineUniqueId().toBase64(); - info.hostName = QSysInfo::machineHostName(); - info.kernelName = QSysInfo::kernelType(); - info.kernelVersion = QSysInfo::kernelVersion(); - info.prettyName = QSysInfo::prettyProductName(); - info.name = QSysInfo::productType(); - info.version = QSysInfo::productVersion(); - return true; +bool SysInfo::GetOsInfo(OsInfo& info) { + /** + * /etc/os-release + * PRETTY_NAME="Ubuntu 22.04.2 LTS" + * NAME="Ubuntu" + * VERSION_ID="22.04" + */ + info.uniqueId = QSysInfo::machineUniqueId().toBase64(); + info.hostName = QSysInfo::machineHostName(); + info.kernelName = QSysInfo::kernelType(); + info.kernelVersion = QSysInfo::kernelVersion(); + info.prettyName = QSysInfo::prettyProductName(); + info.name = QSysInfo::productType(); + info.version = QSysInfo::productVersion(); + return true; } -SystemInfo *SystemInfo::instance() { - static SystemInfo *instance_ = nullptr; - if (!instance_) - instance_ = new SystemInfo(); - return instance_; +SystemInfo* SystemInfo::instance() { + static SystemInfo* instance_ = nullptr; + if (!instance_) instance_ = new SystemInfo(); + return instance_; } QString SystemInfo::osVersion() { return osInfo().name; } OsInfo SystemInfo::osInfo() { - OsInfo info; - SysInfo::GetOsInfo(info); - return info; + OsInfo info; + SysInfo::GetOsInfo(info); + return info; } CpuInfo SystemInfo::cpuInfo() { - CpuInfo info; - SysInfo::GetCpuInfo(info); - return info; + CpuInfo info; + SysInfo::GetCpuInfo(info); + return info; } -} // namespace base +} // namespace ok::base diff --git a/src/base/system/sys_info.h b/src/base/system/sys_info.h index 61ca284a..f31d642b 100644 --- a/src/base/system/sys_info.h +++ b/src/base/system/sys_info.h @@ -13,8 +13,6 @@ #ifndef BASE_SYSTEM_SYS_INFO_H_ #define BASE_SYSTEM_SYS_INFO_H_ -#include "../basic_types.h" -#include "../utils.h" #include #include #include @@ -23,6 +21,8 @@ #include #include #include +#include "../basic_types.h" +#include "../utils.h" namespace ok::base { @@ -31,120 +31,119 @@ static QString GlobalSettingsFileName = APPLICATION_EXE_NAME ".ini"; typedef enum { X86, X64 } Arch; typedef struct { - QString manufacturer; - QString name; - qint32 cores; - qint32 processors; - QString arch; + QString manufacturer; + QString name; + qint32 cores; + qint32 processors; + QString arch; } CpuInfo; typedef struct { - QString name; - QString version; - QString prettyName; - QString kernelName; - QString kernelVersion; - QString hostName; - QString uniqueId; + QString name; + QString version; + QString prettyName; + QString kernelName; + QString kernelVersion; + QString hostName; + QString uniqueId; } OsInfo; class SysInfo { public: - // Returns the host operating system information. - static bool GetOsInfo(OsInfo &info); + // Returns the host operating system information. + static bool GetOsInfo(OsInfo& info); - // Returns the host cpu information. - static bool GetCpuInfo(CpuInfo &info); + // Returns the host cpu information. + static bool GetCpuInfo(CpuInfo& info); }; class SystemInfo { public: - static SystemInfo *instance(); - QString osVersion(); - OsInfo osInfo(); - CpuInfo cpuInfo(); + static SystemInfo* instance(); + QString osVersion(); + OsInfo osInfo(); + CpuInfo cpuInfo(); }; class PlatformInfo { public: - static bool isPortable() { - QString localSettingsPath = - qApp->applicationDirPath() + QDir::separator() + GlobalSettingsFileName; - return QFile(localSettingsPath).exists(); - } - - static QString getGlobalSettingsFile() { - QDir dir(ok::base::PlatformInfo::getAppConfigDirPath()); - return dir.filePath(GlobalSettingsFileName); - } - - static QDir getAppConfigDirPath() { - if (isPortable()) - return qApp->applicationDirPath() + QDir::separator() + "work_dir" + - QDir::separator() + ".config"; - - auto p = QDir::cleanPath(QStandardPaths::writableLocation( - QStandardPaths::AppConfigLocation)) + - QDir::separator(); - return ok::base::PathUtils::ensure(p); - } - - static QDir getAppCacheDirPath() { - if (isPortable()) - return qApp->applicationDirPath() + QDir::separator() + "work_dir" + - QDir::separator() + ".cache"; - - auto p = QDir::cleanPath(QStandardPaths::writableLocation( - QStandardPaths::CacheLocation)) + - QDir::separator(); - return ok::base::PathUtils::ensure(p); - } - - static QDir getAppDataDirPath() { - if (isPortable()) - return qApp->applicationDirPath() + QDir::separator() + "work_dir" + - QDir::separator() + ".data"; - - auto p = QDir::cleanPath(QStandardPaths::writableLocation( - QStandardPaths::AppLocalDataLocation)) + - QDir::separator(); - return ok::base::PathUtils::ensure(p); - } - - static QDir getAppDownloadDirPath() { - if (isPortable()) - return qApp->applicationDirPath() + QDir::separator() + "work_dir" + - QDir::separator() + "downloads"; - - auto p = QDir::cleanPath(QStandardPaths::writableLocation( - QStandardPaths::AppLocalDataLocation)) + - QDir::separator() + "downloads"; - return ok::base::PathUtils::ensure(p); - } - - static QDir getAppLogDirPath() { - if (isPortable()) - return qApp->applicationDirPath() + QDir::separator() + "work_dir" + - QDir::separator() + "logs"; - - auto p = QDir::cleanPath(QStandardPaths::writableLocation( - QStandardPaths::AppLocalDataLocation)) + - QDir::separator() + "logs"; - return ok::base::PathUtils::ensure(p); - } - - static QDir getAppPluginDirPath() { - if (isPortable()) - return qApp->applicationDirPath() + QDir::separator() + "work_dir" + - QDir::separator() + ".plugins"; - - auto p = QDir::cleanPath(QStandardPaths::writableLocation( - QStandardPaths::AppConfigLocation)) + - QDir::separator() + "plugins"; - return ok::base::PathUtils::ensure(p); - } + static bool isPortable() { + QString localSettingsPath = + qApp->applicationDirPath() + QDir::separator() + GlobalSettingsFileName; + return QFile(localSettingsPath).exists(); + } + + static QString getGlobalSettingsFile() { + QDir dir(ok::base::PlatformInfo::getAppConfigDirPath()); + return dir.filePath(GlobalSettingsFileName); + } + + static QDir getAppConfigDirPath() { + if (isPortable()) + return qApp->applicationDirPath() + QDir::separator() + "work_dir" + QDir::separator() + + ".config"; + + auto p = QDir::cleanPath( + QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation)) + + QDir::separator(); + return ok::base::PathUtils::ensure(p); + } + + static QDir getAppCacheDirPath() { + if (isPortable()) + return qApp->applicationDirPath() + QDir::separator() + "work_dir" + QDir::separator() + + ".cache"; + + auto p = QDir::cleanPath(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)) + + QDir::separator(); + return ok::base::PathUtils::ensure(p); + } + + static QDir getAppDataDirPath() { + if (isPortable()) + return qApp->applicationDirPath() + QDir::separator() + "work_dir" + QDir::separator() + + ".data"; + + auto p = QDir::cleanPath( + QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)) + + QDir::separator(); + return ok::base::PathUtils::ensure(p); + } + + static QDir getAppDownloadDirPath() { + if (isPortable()) + return qApp->applicationDirPath() + QDir::separator() + "work_dir" + QDir::separator() + + "downloads"; + + auto p = QDir::cleanPath( + QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)) + + QDir::separator() + "downloads"; + return ok::base::PathUtils::ensure(p); + } + + static QDir getAppLogDirPath() { + if (isPortable()) + return qApp->applicationDirPath() + QDir::separator() + "work_dir" + QDir::separator() + + "logs"; + + auto p = QDir::cleanPath( + QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)) + + QDir::separator() + "logs"; + return ok::base::PathUtils::ensure(p); + } + + static QDir getAppPluginDirPath() { + if (isPortable()) + return qApp->applicationDirPath() + QDir::separator() + "work_dir" + QDir::separator() + + ".plugins"; + + auto p = QDir::cleanPath( + QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation)) + + QDir::separator() + "plugins"; + return ok::base::PathUtils::ensure(p); + } }; -} // namespace ok::base +} // namespace ok::base -#endif // BASE_SYSTEM_SYS_INFO_H_ +#endif // BASE_SYSTEM_SYS_INFO_H_ diff --git a/src/base/system/windows/autorun_win.cpp b/src/base/system/windows/autorun_win.cpp index 6928dfc2..e8a9b170 100644 --- a/src/base/system/windows/autorun_win.cpp +++ b/src/base/system/windows/autorun_win.cpp @@ -10,44 +10,31 @@ * See the Mulan PubL v2 for more details. */ +#include #include -#include "base/autorun.h" #include -#include +#include "base/autorun.h" #ifdef UNICODE using tstring = std::wstring; -static inline tstring toTString(QString s) -{ - return s.toStdWString(); -} +static inline tstring toTString(QString s) { return s.toStdWString(); } #else using tstring = std::string; -static inline tstring toTString(QString s) -{ - return s.toStdString(); -} +static inline tstring toTString(QString s) { return s.toStdString(); } #endif namespace Platform { -inline tstring currentCommandLine() -{ +inline tstring currentCommandLine() { return toTString("\"" + QApplication::applicationFilePath().replace('/', '\\')); } -inline tstring currentRegistryKeyName() -{ - return toTString( APPLICATION_EXE_NAME " - "); -} - +inline tstring currentRegistryKeyName() { return toTString(APPLICATION_EXE_NAME " - "); } -bool setAutorun(bool on) -{ +bool setAutorun(bool on) { HKEY key = 0; if (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Run"), - 0, KEY_ALL_ACCESS, &key) - != ERROR_SUCCESS) + 0, KEY_ALL_ACCESS, &key) != ERROR_SUCCESS) return false; bool result = false; @@ -56,8 +43,7 @@ bool setAutorun(bool on) if (on) { tstring path = currentCommandLine(); result = RegSetValueEx(key, keyName.c_str(), 0, REG_SZ, (PBYTE)path.c_str(), - path.length() * sizeof(TCHAR)) - == ERROR_SUCCESS; + path.length() * sizeof(TCHAR)) == ERROR_SUCCESS; } else result = RegDeleteValue(key, keyName.c_str()) == ERROR_SUCCESS; @@ -65,12 +51,10 @@ bool setAutorun(bool on) return result; } -bool getAutorun() -{ +bool getAutorun() { HKEY key = 0; if (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Run"), - 0, KEY_ALL_ACCESS, &key) - != ERROR_SUCCESS) + 0, KEY_ALL_ACCESS, &key) != ERROR_SUCCESS) return false; tstring keyName = currentRegistryKeyName(); @@ -80,12 +64,12 @@ bool getAutorun() DWORD type = REG_SZ; bool result = false; - if (RegQueryValueEx(key, keyName.c_str(), 0, &type, (PBYTE)path, &length) == ERROR_SUCCESS - && type == REG_SZ) + if (RegQueryValueEx(key, keyName.c_str(), 0, &type, (PBYTE)path, &length) == ERROR_SUCCESS && + type == REG_SZ) result = true; RegCloseKey(key); return result; } -} \ No newline at end of file +} // namespace Platform \ No newline at end of file diff --git a/src/base/system/windows/sys_info.cpp b/src/base/system/windows/sys_info.cpp index 1c96ebac..2f4d3521 100644 --- a/src/base/system/windows/sys_info.cpp +++ b/src/base/system/windows/sys_info.cpp @@ -11,50 +11,49 @@ */ #include "base/system/sys_info.h" -#include -#include #include #include +#include #include +#include namespace ok::base { -bool SysInfo::GetCpuInfo(CpuInfo &info) { - auto arch = QSysInfo::currentCpuArchitecture(); - info.arch = arch == "x86_64" ? "x64" : arch; - // 获取CPU型号和核心数 - return true; +bool SysInfo::GetCpuInfo(CpuInfo& info) { + auto arch = QSysInfo::currentCpuArchitecture(); + info.arch = arch == "x86_64" ? "x64" : arch; + // 获取CPU型号和核心数 + return true; } -bool SysInfo::GetOsInfo(OsInfo &info) { - info.uniqueId = QSysInfo::machineUniqueId().toBase64(); - info.hostName = QSysInfo::machineHostName(); - info.kernelName = QSysInfo::kernelType(); - info.prettyName = QSysInfo::prettyProductName(); - info.name = QSysInfo::productType(); - info.version = QSysInfo::productVersion(); - return true; +bool SysInfo::GetOsInfo(OsInfo& info) { + info.uniqueId = QSysInfo::machineUniqueId().toBase64(); + info.hostName = QSysInfo::machineHostName(); + info.kernelName = QSysInfo::kernelType(); + info.prettyName = QSysInfo::prettyProductName(); + info.name = QSysInfo::productType(); + info.version = QSysInfo::productVersion(); + return true; } -SystemInfo *SystemInfo::instance() { - static SystemInfo *instance_ = nullptr; - if (!instance_) - instance_ = new SystemInfo(); - return instance_; +SystemInfo* SystemInfo::instance() { + static SystemInfo* instance_ = nullptr; + if (!instance_) instance_ = new SystemInfo(); + return instance_; } QString SystemInfo::osVersion() { return osInfo().name; } OsInfo SystemInfo::osInfo() { - OsInfo info; - SysInfo::GetOsInfo(info); - return info; + OsInfo info; + SysInfo::GetOsInfo(info); + return info; } CpuInfo SystemInfo::cpuInfo() { - CpuInfo info; - SysInfo::GetCpuInfo(info); - return info; + CpuInfo info; + SysInfo::GetCpuInfo(info); + return info; } -} // namespace base +} // namespace ok::base diff --git a/src/base/task.h b/src/base/task.h index ceeaa679..2e18833a 100644 --- a/src/base/task.h +++ b/src/base/task.h @@ -22,8 +22,8 @@ namespace lib { class Task : public QThread { public: - virtual void run() override = 0; + virtual void run() override = 0; }; -} // namespace lib -} // namespace ok +} // namespace lib +} // namespace ok diff --git a/src/base/timer.cpp b/src/base/timer.cpp index f0c41b24..e14e4e1a 100644 --- a/src/base/timer.cpp +++ b/src/base/timer.cpp @@ -21,133 +21,135 @@ namespace base { namespace { -QObject *TimersAdjuster() { - static QObject adjuster; - return &adjuster; +QObject* TimersAdjuster() { + static QObject adjuster; + return &adjuster; } -} // namespace +} // namespace -Timer::Timer(QThread *thread, Fn callback) - : Timer(std::move(callback)) // +Timer::Timer(QThread* thread, Fn callback) + : Timer(std::move(callback)) // { - moveToThread(thread); + moveToThread(thread); } Timer::Timer(Fn callback) - : QObject(nullptr), // - _callback(std::move(callback)), // - _type(Qt::PreciseTimer), // - _adjusted(false) { // - - setRepeat(Repeat::Interval); - connect( - TimersAdjuster(), &QObject::destroyed, // - this, [this] { adjust(); }, // - Qt::QueuedConnection); + : QObject(nullptr) + , // + _callback(std::move(callback)) + , // + _type(Qt::PreciseTimer) + , // + _adjusted(false) { // + + setRepeat(Repeat::Interval); + connect( + TimersAdjuster(), &QObject::destroyed, // + this, [this] { adjust(); }, // + Qt::QueuedConnection); } void Timer::start(TimeMs timeout, Qt::TimerType type, Repeat repeat) { - cancel(); - - _type = type; - setRepeat(repeat); - _adjusted = false; - setTimeout(timeout); - _timerId = startTimer(_timeout, _type); - if (_timerId) { - _next = QTime::currentTime().msec() + _timeout; - } else { - _next = 0; - } + cancel(); + + _type = type; + setRepeat(repeat); + _adjusted = false; + setTimeout(timeout); + _timerId = startTimer(_timeout, _type); + if (_timerId) { + _next = QTime::currentTime().msec() + _timeout; + } else { + _next = 0; + } } void Timer::cancel() { - if (isActive()) { - killTimer(::base::take(_timerId)); - } + if (isActive()) { + killTimer(::base::take(_timerId)); + } } TimeMs Timer::remainingTime() const { - if (!isActive()) { - return -1; - } - auto now = QTime::currentTime().msec(); - return (_next > now) ? (_next - now) : TimeMs(0); + if (!isActive()) { + return -1; + } + auto now = QTime::currentTime().msec(); + return (_next > now) ? (_next - now) : TimeMs(0); } void Timer::Adjust() { - QObject emitter; - connect(&emitter, &QObject::destroyed, TimersAdjuster(), &QObject::destroyed); + QObject emitter; + connect(&emitter, &QObject::destroyed, TimersAdjuster(), &QObject::destroyed); } void Timer::adjust() { - auto remaining = remainingTime(); - if (remaining >= 0) { - cancel(); - _timerId = startTimer(remaining, _type); - _adjusted = true; - } + auto remaining = remainingTime(); + if (remaining >= 0) { + cancel(); + _timerId = startTimer(remaining, _type); + _adjusted = true; + } } void Timer::setTimeout(TimeMs timeout) { - if (timeout < 0) { - return; - } - _timeout = static_cast(timeout); + if (timeout < 0) { + return; + } + _timeout = static_cast(timeout); } int Timer::timeout() const { return _timeout; } -void Timer::timerEvent(QTimerEvent *e) { - if (repeat() == Repeat::Interval) { - if (_adjusted) { - start(_timeout, _type, repeat()); +void Timer::timerEvent(QTimerEvent* e) { + if (repeat() == Repeat::Interval) { + if (_adjusted) { + start(_timeout, _type, repeat()); + } else { + _next = QTime::currentTime().msec() + _timeout; + } } else { - _next = QTime::currentTime().msec() + _timeout; + cancel(); } - } else { - cancel(); - } - if (_callback) { - _callback(); - } + if (_callback) { + _callback(); + } } -int DelayedCallTimer::call(TimeMs timeout, Fn callback, - Qt::TimerType type) { - if (!(timeout >= 0)) { - return 0; - } - - if (!callback) { - return 0; - } - auto timerId = QObject::startTimer(static_cast(timeout), type); - if (timerId) { - _callbacks.emplace(timerId, std::move(callback)); - } - return timerId; +int DelayedCallTimer::call(TimeMs timeout, Fn callback, Qt::TimerType type) { + if (!(timeout >= 0)) { + return 0; + } + + if (!callback) { + return 0; + } + auto timerId = QObject::startTimer(static_cast(timeout), type); + if (timerId) { + _callbacks.emplace(timerId, std::move(callback)); + } + return timerId; } void DelayedCallTimer::cancel(int callId) { - if (callId) { - killTimer(callId); - _callbacks.erase(callId); - } + if (callId) { + killTimer(callId); + _callbacks.erase(callId); + } } -void DelayedCallTimer::timerEvent(QTimerEvent *e) { - auto timerId = e->timerId(); - killTimer(timerId); +void DelayedCallTimer::timerEvent(QTimerEvent* e) { + auto timerId = e->timerId(); + killTimer(timerId); - auto it = _callbacks.find(timerId); - if (it != _callbacks.end()) { - auto callback = std::move(it->second); - _callbacks.erase(it); + auto it = _callbacks.find(timerId); + if (it != _callbacks.end()) { + auto callback = std::move(it->second); + _callbacks.erase(it); - callback(); - } + callback(); + } } -} // namespace base +} // namespace base diff --git a/src/base/timer.h b/src/base/timer.h index c653d975..1becf1b9 100644 --- a/src/base/timer.h +++ b/src/base/timer.h @@ -27,78 +27,74 @@ namespace base { class Timer final : private QObject { public: - explicit Timer(QThread *thread, Fn callback = nullptr); + explicit Timer(QThread* thread, Fn callback = nullptr); - explicit Timer(Fn callback = nullptr); + explicit Timer(Fn callback = nullptr); - static Qt::TimerType DefaultType(TimeMs timeout) { - constexpr auto kThreshold = TimeMs(1000); - return (timeout > kThreshold) ? Qt::CoarseTimer : Qt::PreciseTimer; - } + static Qt::TimerType DefaultType(TimeMs timeout) { + constexpr auto kThreshold = TimeMs(1000); + return (timeout > kThreshold) ? Qt::CoarseTimer : Qt::PreciseTimer; + } - void setCallback(Fn callback) { _callback = std::move(callback); } + void setCallback(Fn callback) { _callback = std::move(callback); } - void callOnce(TimeMs timeout) { callOnce(timeout, DefaultType(timeout)); } + void callOnce(TimeMs timeout) { callOnce(timeout, DefaultType(timeout)); } - void callEach(TimeMs timeout) { callEach(timeout, DefaultType(timeout)); } + void callEach(TimeMs timeout) { callEach(timeout, DefaultType(timeout)); } - void callOnce(TimeMs timeout, Qt::TimerType type) { - start(timeout, type, Repeat::SingleShot); - } + void callOnce(TimeMs timeout, Qt::TimerType type) { start(timeout, type, Repeat::SingleShot); } - void callEach(TimeMs timeout, Qt::TimerType type) { - start(timeout, type, Repeat::Interval); - } + void callEach(TimeMs timeout, Qt::TimerType type) { start(timeout, type, Repeat::Interval); } - bool isActive() const { return (_timerId != 0); } + bool isActive() const { return (_timerId != 0); } - void cancel(); - TimeMs remainingTime() const; + void cancel(); + TimeMs remainingTime() const; - static void Adjust(); + static void Adjust(); protected: - void timerEvent(QTimerEvent *e) override; + void timerEvent(QTimerEvent* e) override; private: - enum class Repeat : unsigned { - Interval = 0, - SingleShot = 1, - }; - void start(TimeMs timeout, Qt::TimerType type, Repeat repeat); - void adjust(); - - void setTimeout(TimeMs timeout); - int timeout() const; - - void setRepeat(Repeat repeat) { _repeat = static_cast(repeat); } - Repeat repeat() const { return static_cast(_repeat); } - - Fn _callback; - TimeMs _next = 0; - int _timeout = 0; - int _timerId = 0; - - Qt::TimerType _type : 2; - bool _adjusted : 1; - unsigned _repeat : 1; + enum class Repeat : unsigned { + Interval = 0, + SingleShot = 1, + }; + void start(TimeMs timeout, Qt::TimerType type, Repeat repeat); + void adjust(); + + void setTimeout(TimeMs timeout); + int timeout() const; + + void setRepeat(Repeat repeat) { _repeat = static_cast(repeat); } + Repeat repeat() const { return static_cast(_repeat); } + + Fn _callback; + TimeMs _next = 0; + int _timeout = 0; + int _timerId = 0; + + Qt::TimerType _type : 2; + bool _adjusted : 1; + unsigned _repeat : 1; }; class DelayedCallTimer final : private QObject { public: - int call(TimeMs timeout, Fn callback, Qt::TimerType type); + int call(TimeMs timeout, Fn callback, Qt::TimerType type); - int call(TimeMs timeout, Fn callback) { - return call(timeout, std::move(callback), Timer::DefaultType(timeout)); - } + int call(TimeMs timeout, Fn callback) { + return call(timeout, std::move(callback), Timer::DefaultType(timeout)); + } - void cancel(int callId); + void cancel(int callId); protected: - void timerEvent(QTimerEvent *e) override; + void timerEvent(QTimerEvent* e) override; private: - std::map> _callbacks; + std::map> _callbacks; }; -} // namespace base +} // namespace base diff --git a/src/base/times.h b/src/base/times.h index 6789137c..f8885b46 100644 --- a/src/base/times.h +++ b/src/base/times.h @@ -19,56 +19,54 @@ namespace base { inline QString secondsToDHMS(quint32 duration) { - QString res; - QString cD = "";// - quint32 seconds = duration % 60; - duration /= 60; - quint32 minutes = duration % 60; - duration /= 60; - quint32 hours = duration % 24; - quint32 days = duration / 24; - - // I assume no one will ever have call longer than a month - if (days) { - return cD + - res.asprintf("%dd%02dh %02dm %02ds", days, hours, minutes, seconds); - } - - if (hours) { - return cD + res.asprintf("%02dh %02dm %02ds", hours, minutes, seconds); - } - - if (minutes) { - return cD + res.asprintf("%02dm %02ds", minutes, seconds); - } - - return cD + res.asprintf("%02ds", seconds); -} + QString res; + QString cD = ""; // + quint32 seconds = duration % 60; + duration /= 60; + quint32 minutes = duration % 60; + duration /= 60; + quint32 hours = duration % 24; + quint32 days = duration / 24; + + // I assume no one will ever have call longer than a month + if (days) { + return cD + res.asprintf("%dd%02dh %02dm %02ds", days, hours, minutes, seconds); + } + + if (hours) { + return cD + res.asprintf("%02dh %02dm %02ds", hours, minutes, seconds); + } + + if (minutes) { + return cD + res.asprintf("%02dm %02ds", minutes, seconds); + } + return cD + res.asprintf("%02ds", seconds); +} enum class ReadableTime { - Today, - Yesterday, - ThisWeek, - ThisMonth, - Month1Ago, - Month2Ago, - Month3Ago, - Month4Ago, - Month5Ago, - LongAgo, - Never + Today, + Yesterday, + ThisWeek, + ThisMonth, + Month1Ago, + Month2Ago, + Month3Ago, + Month4Ago, + Month5Ago, + LongAgo, + Never }; static const int LAST_TIME = static_cast(ReadableTime::Never); -inline ReadableTime getTimeBucket(const QDateTime &date) { - if (date == QDateTime()) { - return ReadableTime::Never; - } +inline ReadableTime getTimeBucket(const QDateTime& date) { + if (date == QDateTime()) { + return ReadableTime::Never; + } - QDate today = QDate::currentDate(); - // clang-format off + QDate today = QDate::currentDate(); + // clang-format off const QMap dates { { ReadableTime::Today, today.addDays(0) }, { ReadableTime::Yesterday, today.addDays(-1) }, @@ -80,41 +78,41 @@ inline ReadableTime getTimeBucket(const QDateTime &date) { { ReadableTime::Month4Ago, today.addMonths(-5) }, { ReadableTime::Month5Ago, today.addMonths(-6) }, }; - // clang-format on + // clang-format on - for (ReadableTime time : dates.keys()) { - if (dates[time] <= date.date()) { - return time; + for (ReadableTime time : dates.keys()) { + if (dates[time] <= date.date()) { + return time; + } } - } - return ReadableTime::LongAgo; + return ReadableTime::LongAgo; } class Times { public: - inline static QDateTime now() { return QDateTime::currentDateTime(); } + inline static QDateTime now() { return QDateTime::currentDateTime(); } - inline static QString formatTime(const QDateTime& dateTime, const QString &fmt) { - if(dateTime.isNull()){ - return {}; - } + inline static QString formatTime(const QDateTime& dateTime, const QString& fmt) { + if (dateTime.isNull()) { + return {}; + } - if(fmt.isNull() || fmt.isEmpty()){ - return dateTime.toString(); - } + if (fmt.isNull() || fmt.isEmpty()) { + return dateTime.toString(); + } - return dateTime.toString(fmt); - } + return dateTime.toString(fmt); + } - inline static qint64 timeUntilTomorrow() { - QDateTime now = QDateTime::currentDateTime(); - QDateTime tomorrow = now.addDays(1); // Tomorrow. - tomorrow.setTime(QTime()); // Midnight. - return now.msecsTo(tomorrow); - } + inline static qint64 timeUntilTomorrow() { + QDateTime now = QDateTime::currentDateTime(); + QDateTime tomorrow = now.addDays(1); // Tomorrow. + tomorrow.setTime(QTime()); // Midnight. + return now.msecsTo(tomorrow); + } }; -} // namespace base +} // namespace base -#endif // TIMES_H +#endif // TIMES_H diff --git a/src/base/utils.h b/src/base/utils.h index be0a2361..300f0fc7 100644 --- a/src/base/utils.h +++ b/src/base/utils.h @@ -16,34 +16,31 @@ #include #include - #include "basic_types.h" namespace ok::base { class KeyUtils { public: + static QString GetISOTime() { + return QDateTime::currentDateTime().toString(Qt::DateFormat::ISODate); + } - static QString GetISOTime() { - return QDateTime::currentDateTime().toString(Qt::DateFormat::ISODate); - } - - static QString GetTimestamp() { - QString ts = - QString("%1").arg(QDateTime::currentDateTime().toMSecsSinceEpoch()); - return ts; - } + static QString GetTimestamp() { + QString ts = QString("%1").arg(QDateTime::currentDateTime().toMSecsSinceEpoch()); + return ts; + } }; -class PathUtils{ +class PathUtils { public: - [[nodiscard]] inline static QDir ensure(const QString & path) { - QDir dir(path); - if(!dir.exists()){ - dir.mkpath("."); + [[nodiscard]] inline static QDir ensure(const QString& path) { + QDir dir(path); + if (!dir.exists()) { + dir.mkpath("."); + } + return dir; } - return dir; - } }; -} // namespace base +} // namespace ok::base diff --git a/src/base/uuid.h b/src/base/uuid.h index c63c1263..f3ef3ae5 100644 --- a/src/base/uuid.h +++ b/src/base/uuid.h @@ -17,17 +17,16 @@ #ifndef BASE_UUID_H #define BASE_UUID_H -#include #include +#include namespace base { class UUID { public: - inline static QString make(){ + inline static QString make() { return QUuid::createUuid().toString().remove(0, 1).remove(36, 1); } - }; -} -#endif // MD5_H +} // namespace base +#endif // MD5_H diff --git a/src/base/widgets.h b/src/base/widgets.h index 071baced..f661b72d 100644 --- a/src/base/widgets.h +++ b/src/base/widgets.h @@ -28,58 +28,58 @@ namespace base { class Widgets { public: - Widgets(); + Widgets(); - static void SetPalette(QWidget *w, QPalette::ColorRole role, QColor color) { - if (w) { - QPalette palette(w->palette()); - palette.setColor(role, color); - w->setPalette(palette); - w->setAutoFillBackground(true); + static void SetPalette(QWidget* w, QPalette::ColorRole role, QColor color) { + if (w) { + QPalette palette(w->palette()); + palette.setColor(role, color); + w->setPalette(palette); + w->setAutoFillBackground(true); + } } - } - static void SetPalette(QWidget *w, QPalette::ColorRole role, QBrush brush) { - if (w) { - w->setAutoFillBackground(true); - QPalette palette(w->palette()); - palette.setBrush(role, brush); - w->setPalette(palette); + static void SetPalette(QWidget* w, QPalette::ColorRole role, QBrush brush) { + if (w) { + w->setAutoFillBackground(true); + QPalette palette(w->palette()); + palette.setBrush(role, brush); + w->setPalette(palette); + } } - } - static void SetNoMargins(QWidget *w) { - if (w) { - w->setContentsMargins(QMargins(0, 0, 0, 0)); + static void SetNoMargins(QWidget* w) { + if (w) { + w->setContentsMargins(QMargins(0, 0, 0, 0)); + } } - } - static void SetNoMargins(QLayout *w) { - if (w) { - w->setContentsMargins(QMargins(0, 0, 0, 0)); + static void SetNoMargins(QLayout* w) { + if (w) { + w->setContentsMargins(QMargins(0, 0, 0, 0)); + } } - } - /** - * 实例阴影shadow - * @param w - * @param offset - * @param color - * @param blurRadius - */ - static void SetShadowEffect(QWidget *w, - const QPointF &offset, - const QColor &color, - qreal blurRadius) { - auto *shadow_effect = new QGraphicsDropShadowEffect(w); - shadow_effect->setOffset(offset); - shadow_effect->setColor(color); - shadow_effect->setBlurRadius(blurRadius); - w->setGraphicsEffect(shadow_effect); - } + /** + * 实例阴影shadow + * @param w + * @param offset + * @param color + * @param blurRadius + */ + static void SetShadowEffect(QWidget* w, + const QPointF& offset, + const QColor& color, + qreal blurRadius) { + auto* shadow_effect = new QGraphicsDropShadowEffect(w); + shadow_effect->setOffset(offset); + shadow_effect->setColor(color); + shadow_effect->setBlurRadius(blurRadius); + w->setGraphicsEffect(shadow_effect); + } - static void OpenExternUrl(const QUrl &url) { QDesktopServices::openUrl(url); } + static void OpenExternUrl(const QUrl& url) { QDesktopServices::openUrl(url); } }; -} // namespace base +} // namespace base -#endif // WIDGETS_H +#endif // WIDGETS_H diff --git a/src/base/xmls.h b/src/base/xmls.h index 70749f58..8837ae41 100644 --- a/src/base/xmls.h +++ b/src/base/xmls.h @@ -19,32 +19,30 @@ namespace base { class Xmls { public: - inline static QDomDocument parse(const QString &xmlData) { - QDomDocument document; - if (!document.setContent(xmlData, true)) { - return QDomDocument{}; + inline static QDomDocument parse(const QString& xmlData) { + QDomDocument document; + if (!document.setContent(xmlData, true)) { + return QDomDocument{}; + } + return document; } - return document; - } - inline static QString format(QDomElement& element){ - if(element.isNull()) - return QString{}; + inline static QString format(QDomElement& element) { + if (element.isNull()) return QString{}; - QTextStream stream; - stream.setString(new QString()); - element.save(stream, 0); - return *stream.string(); - } + QTextStream stream; + stream.setString(new QString()); + element.save(stream, 0); + return *stream.string(); + } - inline static QString format(QDomDocument&document){ - if(document.isNull()) - return QString{}; - QTextStream stream; - stream.setString(new QString()); - document.save(stream, 0); - return *stream.string(); - } + inline static QString format(QDomDocument& document) { + if (document.isNull()) return QString{}; + QTextStream stream; + stream.setString(new QString()); + document.save(stream, 0); + return *stream.string(); + } }; -} // namespace base +} // namespace base diff --git a/src/core/utils/desktopinfo.cpp b/src/core/utils/desktopinfo.cpp index 173efe18..4d107694 100644 --- a/src/core/utils/desktopinfo.cpp +++ b/src/core/utils/desktopinfo.cpp @@ -13,27 +13,22 @@ #include "desktopinfo.h" #include -DesktopInfo::DesktopInfo() -{ +DesktopInfo::DesktopInfo() { auto e = QProcessEnvironment::systemEnvironment(); XDG_CURRENT_DESKTOP = e.value(QStringLiteral("XDG_CURRENT_DESKTOP")); XDG_SESSION_TYPE = e.value(QStringLiteral("XDG_SESSION_TYPE")); WAYLAND_DISPLAY = e.value(QStringLiteral("WAYLAND_DISPLAY")); KDE_FULL_SESSION = e.value(QStringLiteral("KDE_FULL_SESSION")); - GNOME_DESKTOP_SESSION_ID = - e.value(QStringLiteral("GNOME_DESKTOP_SESSION_ID")); + GNOME_DESKTOP_SESSION_ID = e.value(QStringLiteral("GNOME_DESKTOP_SESSION_ID")); DESKTOP_SESSION = e.value(QStringLiteral("DESKTOP_SESSION")); } -bool DesktopInfo::waylandDetected() -{ +bool DesktopInfo::waylandDetected() { return XDG_SESSION_TYPE == QLatin1String("wayland") || - WAYLAND_DISPLAY.contains(QLatin1String("wayland"), - Qt::CaseInsensitive); + WAYLAND_DISPLAY.contains(QLatin1String("wayland"), Qt::CaseInsensitive); } -DesktopInfo::WM DesktopInfo::windowManager() -{ +DesktopInfo::WM DesktopInfo::windowManager() { DesktopInfo::WM res = DesktopInfo::OTHER; QStringList desktops = XDG_CURRENT_DESKTOP.split(QChar(':')); for (auto& desktop : desktops) { diff --git a/src/core/utils/desktopinfo.h b/src/core/utils/desktopinfo.h index 94d3a79b..1282d1f2 100644 --- a/src/core/utils/desktopinfo.h +++ b/src/core/utils/desktopinfo.h @@ -14,18 +14,11 @@ #include -class DesktopInfo -{ +class DesktopInfo { public: DesktopInfo(); - enum WM - { - GNOME, - KDE, - OTHER, - SWAY - }; + enum WM { GNOME, KDE, OTHER, SWAY }; bool waylandDetected(); WM windowManager(); diff --git a/src/core/utils/filenamehandler.cpp b/src/core/utils/filenamehandler.cpp index ea9944af..a88beeb7 100644 --- a/src/core/utils/filenamehandler.cpp +++ b/src/core/utils/filenamehandler.cpp @@ -19,11 +19,7 @@ #include #include -FileNameHandler::FileNameHandler(QObject* parent) - : QObject(parent) -{ - -} +FileNameHandler::FileNameHandler(QObject* parent) : QObject(parent) {} /** * @brief Generate a valid destination path from the possibly incomplete `path`. @@ -45,9 +41,7 @@ FileNameHandler::FileNameHandler(QObject* parent) * @param path Possibly incomplete file name to transform * @param format Desired output file suffix (excluding an initial '.' character) */ -QString FileNameHandler::properScreenshotPath(QString path, - const QString& format) -{ +QString FileNameHandler::properScreenshotPath(QString path, const QString& format) { QFileInfo info(path); QString suffix = info.suffix(); @@ -56,8 +50,7 @@ QString FileNameHandler::properScreenshotPath(QString path, path = QDir(QDir(path).absolutePath() + "/" + "xxx").path(); } else { // path points to a file => strip it of its suffix for now - path = QDir(info.dir().absolutePath() + "/" + info.completeBaseName()) - .path(); + path = QDir(info.dir().absolutePath() + "/" + info.completeBaseName()).path(); } if (!format.isEmpty()) { @@ -77,13 +70,11 @@ QString FileNameHandler::properScreenshotPath(QString path, } } -QString FileNameHandler::autoNumerateDuplicate(QString path) -{ +QString FileNameHandler::autoNumerateDuplicate(QString path) { // add numeration in case of repeated filename in the directory // find unused name adding _n where n is a number QFileInfo checkFile(path); - QString directory = checkFile.dir().absolutePath(), - filename = checkFile.completeBaseName(), + QString directory = checkFile.dir().absolutePath(), filename = checkFile.completeBaseName(), suffix = checkFile.suffix(); if (!suffix.isEmpty()) { suffix = QStringLiteral(".") + suffix; @@ -92,8 +83,7 @@ QString FileNameHandler::autoNumerateDuplicate(QString path) filename += QLatin1String("_"); int i = 1; while (true) { - checkFile.setFile(directory + "/" + filename + QString::number(i) + - suffix); + checkFile.setFile(directory + "/" + filename + QString::number(i) + suffix); if (!checkFile.exists()) { filename += QString::number(i); break; diff --git a/src/core/utils/filenamehandler.h b/src/core/utils/filenamehandler.h index 1dcada8a..b4c47d23 100644 --- a/src/core/utils/filenamehandler.h +++ b/src/core/utils/filenamehandler.h @@ -14,14 +14,12 @@ #include -class FileNameHandler : public QObject -{ +class FileNameHandler : public QObject { Q_OBJECT public: explicit FileNameHandler(QObject* parent = nullptr); - QString properScreenshotPath(QString filename, - const QString& format = QString()); + QString properScreenshotPath(QString filename, const QString& format = QString()); static const int MAX_CHARACTERS = 70; diff --git a/src/core/utils/screengrabber.cpp b/src/core/utils/screengrabber.cpp index 77d668e3..0714276e 100644 --- a/src/core/utils/screengrabber.cpp +++ b/src/core/utils/screengrabber.cpp @@ -12,101 +12,95 @@ #include "screengrabber.h" -#include "filenamehandler.h" #include #include #include #include #include - +#include "filenamehandler.h" #if defined(Q_OS_LINUX) || defined(Q_OS_UNIX) #include #include #endif -ScreenGrabber::ScreenGrabber(QObject *parent) : QObject(parent) {} +ScreenGrabber::ScreenGrabber(QObject* parent) : QObject(parent) {} -QPixmap ScreenGrabber::grabEntireDesktop(bool &ok) { - ok = true; +QPixmap ScreenGrabber::grabEntireDesktop(bool& ok) { + ok = true; #if defined(Q_OS_LINUX) || defined(Q_OS_UNIX) - if (m_info.waylandDetected()) { - QPixmap res; - // handle screenshot based on DE - switch (m_info.windowManager()) { - case DesktopInfo::GNOME: { - // https://github.com/GNOME/gnome-shell/blob/695bfb96160033be55cfb5ac41c121998f98c328/data/org.gnome.Shell.Screenshot.xml - QString path = - FileNameHandler().properScreenshotPath(QDir::tempPath()) + ".png"; - QDBusInterface gnomeInterface( - QStringLiteral("org.gnome.Shell"), - QStringLiteral("/org/gnome/Shell/Screenshot"), - QStringLiteral("org.gnome.Shell.Screenshot")); - QDBusReply reply = - gnomeInterface.call("Screenshot", false, false, path); - if (reply.value()) { - res = QPixmap(path); - } else { - ok = false; - } - break; - } - case DesktopInfo::KDE: { - // https://github.com/KDE/spectacle/blob/517a7baf46a4ca0a45f32fd3f2b1b7210b180134/src/PlatformBackends/KWinWaylandImageGrabber.cpp#L145 - QDBusInterface kwinInterface(QStringLiteral("org.kde.KWin"), - QStringLiteral("/Screenshot"), - QStringLiteral("org.kde.kwin.Screenshot")); - QDBusReply reply = kwinInterface.call("screenshotFullscreen"); - res = QPixmap(reply.value()); - break; - } - default: - ok = false; - break; - } - if (!ok) { - - // SystemNotification().sendMessage(tr("Unable to capture screen")); + if (m_info.waylandDetected()) { + QPixmap res; + // handle screenshot based on DE + switch (m_info.windowManager()) { + case DesktopInfo::GNOME: { + // https://github.com/GNOME/gnome-shell/blob/695bfb96160033be55cfb5ac41c121998f98c328/data/org.gnome.Shell.Screenshot.xml + QString path = FileNameHandler().properScreenshotPath(QDir::tempPath()) + ".png"; + QDBusInterface gnomeInterface(QStringLiteral("org.gnome.Shell"), + QStringLiteral("/org/gnome/Shell/Screenshot"), + QStringLiteral("org.gnome.Shell.Screenshot")); + QDBusReply reply = gnomeInterface.call("Screenshot", false, false, path); + if (reply.value()) { + res = QPixmap(path); + } else { + ok = false; + } + break; + } + case DesktopInfo::KDE: { + // https://github.com/KDE/spectacle/blob/517a7baf46a4ca0a45f32fd3f2b1b7210b180134/src/PlatformBackends/KWinWaylandImageGrabber.cpp#L145 + QDBusInterface kwinInterface(QStringLiteral("org.kde.KWin"), + QStringLiteral("/Screenshot"), + QStringLiteral("org.kde.kwin.Screenshot")); + QDBusReply reply = kwinInterface.call("screenshotFullscreen"); + res = QPixmap(reply.value()); + break; + } + default: + ok = false; + break; + } + if (!ok) { + // SystemNotification().sendMessage(tr("Unable to capture screen")); + } + return res; } - return res; - } #endif - QRect geometry; - for (QScreen *const screen : QGuiApplication::screens()) { - geometry = geometry.united(screen->geometry()); - } + QRect geometry; + for (QScreen* const screen : QGuiApplication::screens()) { + geometry = geometry.united(screen->geometry()); + } - QPixmap p(QApplication::primaryScreen()->grabWindow( - QApplication::desktop()->winId(), geometry.x(), geometry.y(), - geometry.width(), geometry.height())); - p.setDevicePixelRatio(QApplication::desktop()->devicePixelRatio()); - return p; + QPixmap p(QApplication::primaryScreen()->grabWindow(QApplication::desktop()->winId(), + geometry.x(), geometry.y(), + geometry.width(), geometry.height())); + p.setDevicePixelRatio(QApplication::desktop()->devicePixelRatio()); + return p; } -QPixmap ScreenGrabber::grabScreen(int screenNumber, bool &ok) { - QPixmap p; - bool isVirtual = QApplication::desktop()->isVirtualDesktop(); - if (isVirtual) { - p = grabEntireDesktop(ok); - if (ok) { - QPoint topLeft(0, 0); +QPixmap ScreenGrabber::grabScreen(int screenNumber, bool& ok) { + QPixmap p; + bool isVirtual = QApplication::desktop()->isVirtualDesktop(); + if (isVirtual) { + p = grabEntireDesktop(ok); + if (ok) { + QPoint topLeft(0, 0); #ifdef Q_OS_WIN - for (QScreen *const screen : QGuiApplication::screens()) { - QPoint topLeftScreen = screen->geometry().topLeft(); - if (topLeft.x() > topLeftScreen.x() || - topLeft.y() > topLeftScreen.y()) { - topLeft = topLeftScreen; - } - } + for (QScreen* const screen : QGuiApplication::screens()) { + QPoint topLeftScreen = screen->geometry().topLeft(); + if (topLeft.x() > topLeftScreen.x() || topLeft.y() > topLeftScreen.y()) { + topLeft = topLeftScreen; + } + } #endif - QRect geometry = QApplication::desktop()->screenGeometry(screenNumber); - geometry.moveTo(geometry.topLeft() - topLeft); - p = p.copy(geometry); + QRect geometry = QApplication::desktop()->screenGeometry(screenNumber); + geometry.moveTo(geometry.topLeft() - topLeft); + p = p.copy(geometry); + } + } else { + p = QApplication::desktop()->screen(screenNumber)->grab(); + ok = true; } - } else { - p = QApplication::desktop()->screen(screenNumber)->grab(); - ok = true; - } - return p; + return p; } diff --git a/src/core/utils/screengrabber.h b/src/core/utils/screengrabber.h index 3f17d9ec..5860a3a4 100644 --- a/src/core/utils/screengrabber.h +++ b/src/core/utils/screengrabber.h @@ -13,21 +13,20 @@ #ifndef SCREENGRABBER_H #define SCREENGRABBER_H -#include "desktopinfo.h" #include +#include "desktopinfo.h" #include #include - class ScreenGrabber : public QObject { - Q_OBJECT + Q_OBJECT public: - explicit ScreenGrabber(QObject *parent = nullptr); - QPixmap grabEntireDesktop(bool &ok); - QPixmap grabScreen(int screenNumber, bool &ok); + explicit ScreenGrabber(QObject* parent = nullptr); + QPixmap grabEntireDesktop(bool& ok); + QPixmap grabScreen(int screenNumber, bool& ok); private: - DesktopInfo m_info; + DesktopInfo m_info; }; #endif diff --git a/src/ipc.cpp b/src/ipc.cpp index 0cd85334..7869ff03 100644 --- a/src/ipc.cpp +++ b/src/ipc.cpp @@ -11,12 +11,12 @@ */ #include "ipc.h" +#include #include #include #include #include #include -#include /** * @var time_t IPC::lastEvent @@ -31,10 +31,7 @@ * @brief Inter-process communication */ -IPC::IPC(uint32_t profileId) - : profileId{profileId} - , globalMemory{"qtox-" IPC_PROTOCOL_VERSION} -{ +IPC::IPC(uint32_t profileId) : profileId{profileId}, globalMemory{"qtox-" IPC_PROTOCOL_VERSION} { qRegisterMetaType("IPCEventHandler"); timer.setInterval(EVENT_TIMER_MS); @@ -67,14 +64,13 @@ IPC::IPC(uint32_t profileId) } else { qDebug() << "Failed to attach to the global shared memory, giving up. Error:" << globalMemory.error(); - return; // We won't be able to do any IPC without being attached, let's get outta here + return; // We won't be able to do any IPC without being attached, let's get outta here } processEvents(); } -IPC::~IPC() -{ +IPC::~IPC() { if (!globalMemory.lock()) { qWarning() << "Failed to lock in ~IPC"; return; @@ -93,8 +89,7 @@ IPC::~IPC() * @param dest Settings::getCurrentProfileId() or 0 (main instance, default). * @return Time the event finished or 0 on error. */ -time_t IPC::postEvent(const QString& name, const QByteArray& data, uint32_t dest) -{ +time_t IPC::postEvent(const QString& name, const QByteArray& data, uint32_t dest) { QByteArray binName = name.toUtf8(); if (binName.length() > (int32_t)sizeof(IPCEvent::name)) { return 0; @@ -133,8 +128,7 @@ time_t IPC::postEvent(const QString& name, const QByteArray& data, uint32_t dest return result; } -bool IPC::isCurrentOwner() -{ +bool IPC::isCurrentOwner() { if (globalMemory.lock()) { const bool isOwner = isCurrentOwnerNoLock(); globalMemory.unlock(); @@ -149,13 +143,11 @@ bool IPC::isCurrentOwner() * @brief Register a handler for an IPC event * @param handler The handler callback. Should not block for more than a second, at worst */ -void IPC::registerEventHandler(const QString& name, IPCEventHandler handler) -{ +void IPC::registerEventHandler(const QString& name, IPCEventHandler handler) { eventHandlers[name] = handler; } -bool IPC::isEventAccepted(time_t time) -{ +bool IPC::isEventAccepted(time_t time) { bool result = false; if (!globalMemory.lock()) { return result; @@ -175,12 +167,10 @@ bool IPC::isEventAccepted(time_t time) return result; } -bool IPC::waitUntilAccepted(time_t postTime, int32_t timeout /*=-1*/) -{ +bool IPC::waitUntilAccepted(time_t postTime, int32_t timeout /*=-1*/) { bool result = false; time_t start = time(nullptr); - forever - { + forever { result = isEventAccepted(postTime); if (result || (timeout > 0 && difftime(time(nullptr), start) >= timeout)) { break; @@ -192,22 +182,15 @@ bool IPC::waitUntilAccepted(time_t postTime, int32_t timeout /*=-1*/) return result; } -bool IPC::isAttached() const -{ - return globalMemory.isAttached(); -} +bool IPC::isAttached() const { return globalMemory.isAttached(); } -void IPC::setProfileId(uint32_t profileId) -{ - this->profileId = profileId; -} +void IPC::setProfileId(uint32_t profileId) { this->profileId = profileId; } /** * @brief Only called when global memory IS LOCKED. * @return nullptr if no evnts present, IPC event otherwise */ -IPC::IPCEvent* IPC::fetchEvent() -{ +IPC::IPCEvent* IPC::fetchEvent() { IPCMemory* mem = global(); for (uint32_t i = 0; i < EVENT_QUEUE_SIZE; ++i) { IPCEvent* evt = &mem->events[i]; @@ -215,13 +198,13 @@ IPC::IPCEvent* IPC::fetchEvent() // Garbage-collect events that were not processed in EVENT_GC_TIMEOUT // and events that were processed and EVENT_GC_TIMEOUT passed after // so sending instance has time to react to those events. - if ((evt->processed && difftime(time(nullptr), evt->processed) > EVENT_GC_TIMEOUT) - || (!evt->processed && difftime(time(nullptr), evt->posted) > EVENT_GC_TIMEOUT)) { + if ((evt->processed && difftime(time(nullptr), evt->processed) > EVENT_GC_TIMEOUT) || + (!evt->processed && difftime(time(nullptr), evt->posted) > EVENT_GC_TIMEOUT)) { memset(evt, 0, sizeof(IPCEvent)); } - if (evt->posted && !evt->processed && evt->sender != getpid() - && (evt->dest == profileId || (evt->dest == 0 && isCurrentOwnerNoLock()))) { + if (evt->posted && !evt->processed && evt->sender != getpid() && + (evt->dest == profileId || (evt->dest == 0 && isCurrentOwnerNoLock()))) { return evt; } } @@ -229,8 +212,7 @@ IPC::IPCEvent* IPC::fetchEvent() return nullptr; } -bool IPC::runEventHandler(IPCEventHandler handler, const QByteArray& arg) -{ +bool IPC::runEventHandler(IPCEventHandler handler, const QByteArray& arg) { bool result = false; if (QThread::currentThread() == qApp->thread()) { result = handler(arg); @@ -243,8 +225,7 @@ bool IPC::runEventHandler(IPCEventHandler handler, const QByteArray& arg) return result; } -void IPC::processEvents() -{ +void IPC::processEvents() { if (!globalMemory.lock()) { timer.start(); return; @@ -300,8 +281,7 @@ void IPC::processEvents() * @brief Only called when global memory IS LOCKED. * @return true if owner, false if not owner or if error */ -bool IPC::isCurrentOwnerNoLock() -{ +bool IPC::isCurrentOwnerNoLock() { const void* const data = globalMemory.data(); if (!data) { qWarning() << "isCurrentOwnerNoLock failed to access the memory, returning false"; @@ -310,7 +290,4 @@ bool IPC::isCurrentOwnerNoLock() return (*static_cast(data) == globalId); } -IPC::IPCMemory* IPC::global() -{ - return static_cast(globalMemory.data()); -} +IPC::IPCMemory* IPC::global() { return static_cast(globalMemory.data()); } diff --git a/src/ipc.h b/src/ipc.h index 02158465..310c350a 100644 --- a/src/ipc.h +++ b/src/ipc.h @@ -10,7 +10,6 @@ * See the Mulan PubL v2 for more details. */ - #ifndef IPC_H #define IPC_H @@ -25,8 +24,7 @@ using IPCEventHandler = std::function; #define IPC_PROTOCOL_VERSION "2" -class IPC : public QObject -{ +class IPC : public QObject { Q_OBJECT protected: @@ -39,8 +37,7 @@ class IPC : public QObject IPC(uint32_t profileId); ~IPC(); - struct IPCEvent - { + struct IPCEvent { uint32_t dest; int32_t sender; char name[16]; @@ -52,8 +49,7 @@ class IPC : public QObject bool global; }; - struct IPCMemory - { + struct IPCMemory { uint64_t globalId; time_t lastEvent; time_t lastProcessed; @@ -85,4 +81,4 @@ public slots: QMap eventHandlers; }; -#endif // IPC_H +#endif // IPC_H diff --git a/src/launcher.cpp b/src/launcher.cpp index 023375fe..fd33e552 100644 --- a/src/launcher.cpp +++ b/src/launcher.cpp @@ -11,49 +11,52 @@ */ #include "launcher.h" -#include "application.h" -#include #include +#include #include +#include "application.h" namespace ok { -std::unique_ptr Launcher::Create(int argc, char *argv[]) { return std::make_unique(argc, argv); } +std::unique_ptr Launcher::Create(int argc, char* argv[]) { + return std::make_unique(argc, argv); +} -Launcher::Launcher(int argc, char *argv[]) - : _argc(argc), // - _argv(argv) // +Launcher::Launcher(int argc, char* argv[]) + : _argc(argc) + , // + _argv(argv) // { - QThread::currentThread()->setObjectName("Launcher"); + QThread::currentThread()->setObjectName("Launcher"); #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) - QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); + QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); #endif #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) - qputenv("QT_ENABLE_HIGHDPI_SCALING", "1"); - QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); + qputenv("QT_ENABLE_HIGHDPI_SCALING", "1"); + QGuiApplication::setHighDpiScaleFactorRoundingPolicy( + Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); #endif } int Launcher::executeApplication() { + app = new Application(_argc, _argv); - app = new Application(_argc, _argv); - - // Windows platform plugins DLL - app->addLibraryPath(QCoreApplication::applicationDirPath()); - app->addLibraryPath("platforms"); - app->start(); - app->finish(); + // Windows platform plugins DLL + app->addLibraryPath(QCoreApplication::applicationDirPath()); + app->addLibraryPath("platforms"); + app->start(); + app->finish(); - return app->exec(); + return app->exec(); } int Launcher::startup() { return executeApplication(); } void Launcher::shutdown() { - app->closeAllWindows(); - qApp->exit(0); + app->closeAllWindows(); + qApp->exit(0); } -} // namespace ok +} // namespace ok diff --git a/src/launcher.h b/src/launcher.h index 51628673..9729b27e 100644 --- a/src/launcher.h +++ b/src/launcher.h @@ -21,23 +21,21 @@ namespace ok { class Application; class Launcher { - public: - static std::unique_ptr Create(int argc, char *argv[]); - - Launcher(int argc, char *argv[]); + static std::unique_ptr Create(int argc, char* argv[]); + Launcher(int argc, char* argv[]); - int startup(); + int startup(); - void shutdown(); + void shutdown(); private: - int executeApplication(); + int executeApplication(); - int _argc; - char **_argv; - Application *app; - QStringList _arguments; + int _argc; + char** _argv; + Application* app; + QStringList _arguments; }; -} // namespace core +} // namespace ok diff --git a/src/lib/backend/BaseService.cpp b/src/lib/backend/BaseService.cpp index fb98eaff..6c4c5ef5 100644 --- a/src/lib/backend/BaseService.cpp +++ b/src/lib/backend/BaseService.cpp @@ -18,17 +18,19 @@ #include "base/r.h" #include "lib/network/NetworkHttp.h" -#include #include #include +#include namespace ok::backend { -BaseService::BaseService(const QString &baseUrl, QObject *parent) // - : QObject(parent), // - http(std::make_unique(this)), // - _baseUrl(baseUrl) {} +BaseService::BaseService(const QString& baseUrl, QObject* parent) // + : QObject(parent), http(std::make_unique(this)), _baseUrl(baseUrl) { + if (!headers.isEmpty()) http->setHeaders(headers); +} BaseService::~BaseService() {} -} // namespace ok::backend +void BaseService::setHeader(QString k, QString v) { headers.insert(k, v); } + +} // namespace ok::backend diff --git a/src/lib/backend/BaseService.h b/src/lib/backend/BaseService.h index f1342bb6..b820a022 100644 --- a/src/lib/backend/BaseService.h +++ b/src/lib/backend/BaseService.h @@ -17,9 +17,9 @@ #include #include +#include "BaseService.h" #include "base/r.h" #include "lib/network/NetworkHttp.h" -#include "BaseService.h" #include #include @@ -27,160 +27,159 @@ namespace ok::backend { typedef struct { - bool success; - QString url; - QString key; - QString contentType; - QString extension; - QString name; + bool success; + QString url; + QString key; + QString contentType; + QString extension; + QString name; } FileResult; -template // +template // class Res { public: - int code; - QString msg; - T *data; - - Res(const QJsonDocument &doc) : code{-1}, data{nullptr} { - if (doc.isEmpty()) { - code = -1; - return; + int code; + QString msg; + T* data; + QMap extra; + + Res(const QJsonDocument& doc) : code{-1}, data{nullptr} { + if (doc.isEmpty()) { + code = -1; + return; + } + + auto obj = doc.object(); + if (obj.contains("code")) { + code = obj.value(("code")).toInt(); + msg = obj.value("msg").toString(); + if (code == 0) { + data = new T(obj.value("data").toObject()); + auto extra = obj.value("extra").toObject(); + for (auto key : extra.keys()) { + extra.insert(key, extra.value(key)); + } + } + } else { + data = new T(obj); + } } - auto obj = doc.object(); - if (obj.contains("code")) { - code = obj.value(("code")).toInt(); - msg = obj.value("msg").toString(); - if (code == 0) - data = new T(obj.value("data").toObject()); - } else { - data = new T(obj); + Res(const QString& err) { + code = -1; + msg = err; } - } - Res(const QString &err) { - code = -1; - msg = err; - } - - ~Res() { - if (code == 0) - delete data; - } + ~Res() { + if (code == 0) delete data; + } - bool success() const { return code == 0; } + bool success() const { return code == 0; } }; -template // +template // class ResList { public: - int code; - QString msg; - QList data; - - ResList(const QJsonDocument &doc) : code{-1} { - if (doc.isEmpty()) { - code = -1; - return; + int code; + QString msg; + QList data; + + ResList(const QJsonDocument& doc) : code{-1} { + if (doc.isEmpty()) { + code = -1; + return; + } + + auto obj = doc.object(); + code = obj.value(("code")).toInt(); + msg = obj.value("msg").toString(); + if (code == 0) { + QJsonArray arr = obj.value("data").toArray(); + for (auto i : arr) { + data.append(new T(i.toObject())); + } + } } - auto obj = doc.object(); - code = obj.value(("code")).toInt(); - msg = obj.value("msg").toString(); - if (code == 0) { - QJsonArray arr = obj.value("data").toArray(); - for (auto i : arr) { - data.append(new T(i.toObject())); - } + ResList(const QString& err) { + code = -1; + msg = err; } - } - ResList(const QString &err) { - code = -1; - msg = err; - } - - ~ResList() { - if (code == 0) { - // qDeleteAll(data.begin(), data.end()); - data.clear(); + ~ResList() { + if (code == 0) { + // qDeleteAll(data.begin(), data.end()); + data.clear(); + } } - } - bool success() const { return code == 0; } + bool success() const { return code == 0; } }; -template // +template // class Page { public: - int totalCount; - int pageCount; - QList list; - - Page() : totalCount(0), pageCount(0){ - - } - - Page(const QJsonObject &obj){ - totalCount = obj.value(("totalCount")).toInt(); - pageCount = obj.value(("pageCount")).toInt(); - QJsonArray arr = obj.value("list").toArray(); - for (auto i : arr) { - list.append( T(i.toObject())); + int totalCount; + int pageCount; + QList list; + + Page() : totalCount(0), pageCount(0) {} + + Page(const QJsonObject& obj) { + totalCount = obj.value(("totalCount")).toInt(); + pageCount = obj.value(("pageCount")).toInt(); + QJsonArray arr = obj.value("list").toArray(); + for (auto i : arr) { + list.append(T(i.toObject())); + } } - } - }; -template // +template // class ResPage { public: - int code; - QString msg; - Page data; - - ResPage(): code{-1} { - - } - - ResPage(const QJsonDocument &doc) : code{-1} { - if (doc.isEmpty()) { - code = -1; - return; + int code; + QString msg; + Page data; + + ResPage() : code{-1} {} + + ResPage(const QJsonDocument& doc) : code{-1} { + if (doc.isEmpty()) { + code = -1; + return; + } + + auto obj = doc.object(); + code = obj.value(("code")).toInt(); + msg = obj.value("msg").toString(); + if (code == 0 && obj.contains("data")) { + data = Page(obj.value("data").toObject()); + } } - auto obj = doc.object(); - code = obj.value(("code")).toInt(); - msg = obj.value("msg").toString(); - if (code == 0 && obj.contains("data")) { - data=Page(obj.value("data").toObject()); + ResPage(const QString& err) { + code = -1; + msg = err; } - } - ResPage(const QString &err) { - code = -1; - msg = err; - } + ~ResPage() {} - ~ResPage() { - - } - - bool success() const { return code == 0; } + bool success() const { return code == 0; } }; class BaseService : public QObject { - Q_OBJECT + Q_OBJECT public: - BaseService(const QString &baseUrl, QObject *parent = nullptr); - ~BaseService(); - - [[maybe_unused]] inline const QString &baseUrl() const { return _baseUrl; } + BaseService(const QString& baseUrl, QObject* parent = nullptr); + ~BaseService(); + [[maybe_unused]] inline const QString& baseUrl() const { return _baseUrl; } + void setHeader(QString k, QString v); protected: - std::unique_ptr http; - QString _baseUrl; + std::unique_ptr http; + QString _baseUrl; + QMap headers; }; -} // namespace ok::backend +} // namespace ok::backend diff --git a/src/lib/backend/OkCloudService.cpp b/src/lib/backend/OkCloudService.cpp index d58f024f..8fd077df 100644 --- a/src/lib/backend/OkCloudService.cpp +++ b/src/lib/backend/OkCloudService.cpp @@ -17,54 +17,48 @@ namespace ok::backend { -PluginInfo PluginInfo::fromJson(const QJsonObject &data) { - return PluginInfo(data); -} - +PluginInfo PluginInfo::fromJson(const QJsonObject& data) { return PluginInfo(data); } -OkCloudService::OkCloudService(QObject *parent) - : BaseService(BACKEND_CLOUD_URL, parent) {} +OkCloudService::OkCloudService(QObject* parent) : BaseService(BACKEND_CLOUD_URL, parent) {} -OkCloudService::~OkCloudService() { - qDebug() <<__func__; -} +OkCloudService::~OkCloudService() { qDebug() << __func__; } -bool OkCloudService::GetFederalInfo(Fn &)> fn, network::HttpErrorFn err) { - QString url = _baseUrl + "/federal/.well-known/info.json"; - return http->getJSON( - QUrl(url), - // success - [=](QJsonDocument doc) { - Res res(doc); - fn(res); - }, - err); +bool OkCloudService::GetFederalInfo(Fn&)> fn, network::HttpErrorFn err) { + QString url = _baseUrl + "/federal/.well-known/info.json"; + return http->getJson( + QUrl(url), + // success + [=](QJsonDocument doc) { + Res res(doc); + fn(res); + }, + err); } -bool OkCloudService::GetPluginPage(Fn &)> fn, network::HttpErrorFn err) { - - auto cpuInfo = ok::base::SystemInfo::instance()->cpuInfo(); - if(cpuInfo.arch.isEmpty()){ - qWarning() << "Unable to read cpu info!"; - return false; - } - auto platform = ok::base::SystemInfo::instance()->osInfo().kernelName; - if(platform.isEmpty()){ +bool OkCloudService::GetPluginPage(Fn&)> fn, + network::HttpErrorFn err) { + auto cpuInfo = ok::base::SystemInfo::instance()->cpuInfo(); + if (cpuInfo.arch.isEmpty()) { + qWarning() << "Unable to read cpu info!"; + return false; + } + auto platform = ok::base::SystemInfo::instance()->osInfo().kernelName; + if (platform.isEmpty()) { qWarning() << "Unable to read os info!"; return false; } - QString url = _baseUrl + "/plugin/page?platform="+platform+"&arch="+cpuInfo.arch; - qDebug() << __func__ << url; + QString url = _baseUrl + "/plugin/page?platform=" + platform + "&arch=" + cpuInfo.arch; + qDebug() << __func__ << url; - return http->getJSON( - QUrl(url), - // success - [=](QJsonDocument doc) { - ResPage res(doc); - fn(res); - }, - err); + return http->getJson( + QUrl(url), + // success + [=](QJsonDocument doc) { + ResPage res(doc); + fn(res); + }, + err); } -} // namespace ok::backend +} // namespace ok::backend diff --git a/src/lib/backend/OkCloudService.h b/src/lib/backend/OkCloudService.h index e6b78eae..2c087748 100644 --- a/src/lib/backend/OkCloudService.h +++ b/src/lib/backend/OkCloudService.h @@ -14,7 +14,6 @@ #include -#include "base/jsons.h" #include #include "base/jsons.h" @@ -22,87 +21,84 @@ namespace ok::backend { class State { public: - QString no; - QString name; - QString xmppHost; - QString stackUrl; + QString no; + QString name; + QString xmppHost; + QString stackUrl; }; class FederalInfo { public: - FederalInfo(const QJsonObject &data) { - /** - * { -"states": [ - { - "no": "1001", - "name": "OkStar开源社区", - "xmppHost": "meet.okstar.org.cn" - }, - { - "no": "1002", - "name": "船山信息", - "xmppHost": "meet.chuanshaninfo.com" - } -] -} - */ + FederalInfo(const QJsonObject& data) { + /** + * { + "states": [ + { + "no": "1001", + "name": "OkStar开源社区", + "xmppHost": "meet.okstar.org.cn" + }, + { + "no": "1002", + "name": "船山信息", + "xmppHost": "meet.chuanshaninfo.com" + } + ] + } + */ - QJsonArray arr = data.value("states").toArray(); - for (auto && item : arr) { - const QJsonObject &object = item.toObject(); - State state; - state.no = object.value("no").toString(); - state.name = object.value("name").toString(); - state.xmppHost = object.value("xmppHost").toString(); - state.stackUrl = object.value("stackUrl").toString(); - states.push_back(state); + QJsonArray arr = data.value("states").toArray(); + for (auto&& item : arr) { + const QJsonObject& object = item.toObject(); + State state; + state.no = object.value("no").toString(); + state.name = object.value("name").toString(); + state.xmppHost = object.value("xmppHost").toString(); + state.stackUrl = object.value("stackUrl").toString(); + states.push_back(state); + } } - } - QList states; + QList states; }; class PluginInfo : public JsonAble { public: - quint64 id; //插件id - quint64 ver; //数字版本 - QString shortName;//标识符 - QString name; //版本名称 - QString fileName; //文件名称 - QString content; //版本说明 - QString version; //可读版本 - QString author; // - QString homeUrl; //主页地址 - QString logoUrl; //logo - QString downUrl; //下载地址 - - PluginInfo(const QJsonObject &obj){ - id = obj.value(("id")).toInt(); - ver = obj.value(("ver")).toInt(); - shortName = obj.value(("shortName")).toString(); - name = obj.value(("name")).toString(); - version = obj.value(("version")).toString(); - fileName = obj.value(("fileName")).toString(); - content = obj.value(("content")).toString(); - author = obj.value(("author")).toString(); - homeUrl = obj.value(("homeUrl")).toString(); - logoUrl = obj.value(("logoUrl")).toString(); - downUrl = obj.value(("downUrl")).toString(); - } + quint64 id; // 插件id + quint64 ver; // 数字版本 + QString shortName; // 标识符 + QString name; // 版本名称 + QString fileName; // 文件名称 + QString content; // 版本说明 + QString version; // 可读版本 + QString author; // + QString homeUrl; // 主页地址 + QString logoUrl; // logo + QString downUrl; // 下载地址 + PluginInfo(const QJsonObject& obj) { + id = obj.value(("id")).toInt(); + ver = obj.value(("ver")).toInt(); + shortName = obj.value(("shortName")).toString(); + name = obj.value(("name")).toString(); + version = obj.value(("version")).toString(); + fileName = obj.value(("fileName")).toString(); + content = obj.value(("content")).toString(); + author = obj.value(("author")).toString(); + homeUrl = obj.value(("homeUrl")).toString(); + logoUrl = obj.value(("logoUrl")).toString(); + downUrl = obj.value(("downUrl")).toString(); + } - PluginInfo fromJson(const QJsonObject &data) override; -} ; + PluginInfo fromJson(const QJsonObject& data) override; +}; class OkCloudService : public BaseService { - Q_OBJECT - + Q_OBJECT public: - OkCloudService(QObject *parent = nullptr); - ~OkCloudService(); - - bool GetFederalInfo(Fn &)> fn, network::HttpErrorFn err = nullptr); - bool GetPluginPage(Fn &)> fn, network::HttpErrorFn err = nullptr); + OkCloudService(QObject* parent = nullptr); + ~OkCloudService(); + bool GetFederalInfo(Fn&)> fn, network::HttpErrorFn err = nullptr); + bool GetPluginPage(Fn&)> fn, network::HttpErrorFn err = nullptr); }; -} // namespace ok::backend +} // namespace ok::backend diff --git a/src/lib/backend/PassportService.cpp b/src/lib/backend/PassportService.cpp index 5545f5cf..6092eedf 100644 --- a/src/lib/backend/PassportService.cpp +++ b/src/lib/backend/PassportService.cpp @@ -11,34 +11,62 @@ */ #include "PassportService.h" - +#include #include #include #include +#include "base/times.h" namespace ok::backend { -using namespace session; - -PassportService::PassportService(const QString& base, QObject *parent) - : BaseService(base, parent) {} +PassportService::PassportService(const QString& base, QObject* parent) + : BaseService(base, parent) {} PassportService::~PassportService() {} -bool PassportService::getAccount(const QString &account, - Fn &)> fn, - network::HttpErrorFn err) { - QString url = _baseUrl + "/api/open/passport/account/" + account; - http->getJSON( - QUrl(url), - // success - [=](QJsonDocument doc) { - Res res(doc); - fn(res); - }, - // error - err); - return true; +bool PassportService::signIn(const QString& account, const QString& password, + Fn&)> fn, const network::HttpErrorFn& err, + bool rememberMe, const QString& grantType) { + QString url = _baseUrl + "/api/auth/passport/signIn"; + QJsonObject data; + /** + * "ts": 0, + "iso": "string", + "grantType": "string", + "account": "string", + "password": "string", + "rememberMe": true + */ + data.insert("ts", ::base::Times::now().toMSecsSinceEpoch()); + data.insert("grantType", grantType); + data.insert("account", account); + data.insert("password", password); + data.insert("rememberMe", rememberMe ? "true" : "false"); + + return http->postJson( + QUrl(url), QJsonDocument(data), + [=](QByteArray doc, QString name) { + Res res(Jsons::toJSON(doc)); + fn(res); + }, + nullptr, nullptr, err); +} + +bool PassportService::refresh(const SysToken& token, Fn&)> fn, + network::HttpErrorFn err) { + QJsonObject data; + data.insert("ts", ::base::Times::now().toMSecsSinceEpoch()); + data.insert("accessToken", token.accessToken); + data.insert("refreshToken", token.refreshToken); + + QString url = _baseUrl + "/api/auth/passport/refresh"; + return http->postJson( + QUrl(url), QJsonDocument(data), + [=](QByteArray doc, QString name) { + Res res(Jsons::toJSON(doc)); + fn(res); + }, + nullptr, nullptr, err); } -} // namespace ok::backend +} // namespace ok::backend diff --git a/src/lib/backend/PassportService.h b/src/lib/backend/PassportService.h index 256a8eca..8ead979d 100644 --- a/src/lib/backend/PassportService.h +++ b/src/lib/backend/PassportService.h @@ -21,21 +21,50 @@ #include #include -#include namespace ok::backend { -using namespace ok::session; +struct SysRefreshToken { + QString accessToken; + quint64 expiresIn; // 有效期(s) + QString refreshToken; + quint64 refreshExpiresIn; -class SysAccount { -public: - quint64 id; - QString iso; - QString name; - QString username; - QString nickname; + SysRefreshToken() : expiresIn{0}, refreshExpiresIn{0} {} + + SysRefreshToken(const QJsonObject& data) { + expiresIn = data.value("expiresIn").toVariant().toULongLong(); // + refreshExpiresIn = data.value("refreshExpiresIn").toVariant().toULongLong(); // + refreshToken = data.value("refreshToken").toString(); // + accessToken = data.value("accessToken").toString(); // + } +}; - SysAccount(const QJsonObject &data) { +struct SysToken : public SysRefreshToken { + /** + * "tokenType": "string", + "accessToken": "string", + "expiresIn": 0, + "refreshToken": "string", + "refreshExpiresIn": 0, + "session_state": "string" + */ + QString username; + QString tokenType; + QString session_state; + SysToken() : SysRefreshToken() {} + SysToken(const QJsonObject& data) { + expiresIn = data.value("expiresIn").toVariant().toULongLong(); // + refreshExpiresIn = data.value("refreshExpiresIn").toVariant().toULongLong(); // + username = data.value("username").toString(); + tokenType = data.value("tokenType").toString(); // + refreshToken = data.value("refreshToken").toString(); // + session_state = data.value("session_state").toString(); // + accessToken = data.value("accessToken").toString(); // + } +}; + +struct SysAccount { /** * { * "id":2001, @@ -49,27 +78,45 @@ class SysAccount { * "name":"OkStar" * } */ - id = data.value("id").toVariant().toULongLong(); // - iso = data.value("iso").toString(); // - name = data.value("name").toString(); // - username = data.value("username").toString(); // - nickname = data.value("nickname").toString(); // - } + quint64 id; + QString iso; + QString name; + QString username; + QString nickname; + + SysAccount(const QJsonObject& data) { + id = data.value("id").toVariant().toULongLong(); // + iso = data.value("iso").toString(); // + name = data.value("name").toString(); // + username = data.value("username").toString(); // + nickname = data.value("nickname").toString(); // + } - QString toString() { - return QString("{id:%1, username:%2, name:%3, nickname:%4 iso:%5}") // - .arg(QString::number(id), username, name, nickname, iso); - } + QString toString() { + return QString("{id:%1, username:%2, name:%3, nickname:%4 iso:%5}") // + .arg(QString::number(id), username, name, nickname, iso); + } }; class PassportService : BaseService { - Q_OBJECT + Q_OBJECT public: - PassportService(const QString& base, QObject *parent = nullptr); - ~PassportService(); + PassportService(const QString& base, QObject* parent = nullptr); + ~PassportService(); + + /** + * 登录 + * @param account 帐号(邮箱、手机号) + * @param password 密码 + * @param rememberMe + * @param grantType + * @return + */ + bool signIn(const QString& account, const QString& password, Fn&)> fn, + const network::HttpErrorFn& err, bool rememberMe = false, + const QString& grantType = "password"); - bool getAccount(const QString &account, - Fn &)> fn, - network::HttpErrorFn err = nullptr); + bool refresh(const SysToken& token, Fn&)> fn, + network::HttpErrorFn err = nullptr); }; -} // namespace ok::backend +} // namespace ok::backend diff --git a/src/lib/backend/UserService.cpp b/src/lib/backend/UserService.cpp index 4d3bc5ba..44738de6 100644 --- a/src/lib/backend/UserService.cpp +++ b/src/lib/backend/UserService.cpp @@ -12,28 +12,28 @@ #include "UserService.h" -#include #include +#include namespace ok::backend { using namespace network; -UserService::UserService(const QString& base, QObject *parent) : BaseService(base, parent) {} +UserService::UserService(const QString& base, QObject* parent) : BaseService(base, parent) {} UserService::~UserService() {} -void UserService::search(const QString &query, Fn &)> fn, network::HttpErrorFn errFn) { - QUrl url(QString(_baseUrl + "/api/open/staff/search?q=%1").arg(query)); - http->getJSON( - QUrl(url), - // success - [=](QJsonDocument doc) { - ResList res(doc); - fn(res.data); - }, errFn); +void UserService::search(const QString& query, Fn&)> fn, + network::HttpErrorFn errFn) { + QUrl url(QString(_baseUrl + "/api/open/staff/search?q=%1").arg(query)); + http->getJson( + QUrl(url), + // success + [=](QJsonDocument doc) { + ResList res(doc); + fn(res.data); + }, + errFn); } - - -} // namespace ok::backend +} // namespace ok::backend diff --git a/src/lib/backend/UserService.h b/src/lib/backend/UserService.h index f47e044b..3d13032f 100644 --- a/src/lib/backend/UserService.h +++ b/src/lib/backend/UserService.h @@ -25,46 +25,47 @@ namespace ok::backend { struct OrgStaff { + QString no; + QString name; + QString phone; + QString email; + QString username; + QString host; + QString posts; - QString no; - QString name; - QString phone; - QString email; - QString username; - QString host; - QString posts; + OrgStaff(const QJsonObject& data) { + no = data.value("no").toString(); // + email = data.value("email").toString(); // + name = data.value("name").toString(); // + username = data.value("username").toString(); // + phone = data.value("phone").toString(); // + host = data.value("host").toString(); // + posts = data.value("posts").toString(); // + } - OrgStaff(const QJsonObject &data) { - no = data.value("no").toString(); // - email = data.value("email").toString(); // - name = data.value("name").toString(); // - username = data.value("username").toString(); // - phone = data.value("phone").toString(); // - host = data.value("host").toString(); // - posts = data.value("posts").toString(); // - } - - QString toString() { - return QString("{no:%1, username:%2, name:%3, phone:%4, email:%5, host:%6, posts: %7}") // - .arg(no).arg(username).arg(name).arg(phone).arg(host).arg(posts); - } - - QString toContactId(){ - return QString("%1@%2").arg(username).arg(host); - } + QString toString() { + return QString("{no:%1, username:%2, name:%3, phone:%4, email:%5, host:%6, posts: %7}") // + .arg(no) + .arg(username) + .arg(name) + .arg(phone) + .arg(host) + .arg(posts); + } + QString toContactId() { return QString("%1@%2").arg(username).arg(host); } }; class UserService : public BaseService { - Q_OBJECT + Q_OBJECT public: - UserService(const QString &base, QObject *parent = nullptr); - ~UserService(); - - void search(const QString &query, - Fn &)> callback, - network::HttpErrorFn errFn = nullptr); + UserService(const QString& base, QObject* parent = nullptr); + ~UserService(); + void search(const QString& query, + Fn&)> + callback, + network::HttpErrorFn errFn = nullptr); }; -} // namespace ok::backend +} // namespace ok::backend diff --git a/src/lib/backend/domain/AuthInfo.h b/src/lib/backend/domain/AuthInfo.h index 03f96e4c..9584b8f1 100644 --- a/src/lib/backend/domain/AuthInfo.h +++ b/src/lib/backend/domain/AuthInfo.h @@ -12,12 +12,8 @@ #pragma once +#include #include #include -#include - -namespace ok::backend { - - -} // namespace ok::backend +namespace ok::backend {} // namespace ok::backend diff --git a/src/lib/backend/domain/RoomInfo.h b/src/lib/backend/domain/RoomInfo.h index f4586414..3e8ba061 100644 --- a/src/lib/backend/domain/RoomInfo.h +++ b/src/lib/backend/domain/RoomInfo.h @@ -12,30 +12,30 @@ #pragma once +#include #include #include -#include namespace ok::backend { -class RoomInfo { +class RoomInfo { public: - QString getJid() { return jid; } - QString getName() { return name; } - QString getPassword() { return password; } - QString getSn() { return sn; } + QString getJid() { return jid; } + QString getName() { return name; } + QString getPassword() { return password; } + QString getSn() { return sn; } - inline void setJid(QString &_jid) { jid = _jid; } + inline void setJid(QString& _jid) { jid = _jid; } - inline void setName(QString &_name) { name = _name; } + inline void setName(QString& _name) { name = _name; } - inline void setPassword(QString &_password) { password = _password; } + inline void setPassword(QString& _password) { password = _password; } private: - QString jid; - QString name; - QString password; - QString sn; + QString jid; + QString name; + QString password; + QString sn; }; -} // namespace ok::backend +} // namespace ok::backend diff --git a/src/lib/log/LogManager.cpp b/src/lib/log/LogManager.cpp index 2052cc83..c0ec4d59 100644 --- a/src/lib/log/LogManager.cpp +++ b/src/lib/log/LogManager.cpp @@ -31,89 +31,84 @@ namespace lib { static QAtomicPointer logFilePointer; static QMutex logMutex; -void logMessageHandler(QtMsgType type, - const QMessageLogContext &ctxt, - const QString &msg) { - - QMutexLocker locker(&logMutex); - - QString file = ctxt.file; - if (file.lastIndexOf("/") > 0) { - file = file.mid(file.lastIndexOf('/') + 1); - } - - // Time should be in UTC to save user privacy on log sharing - QString time = ::base::Times::formatTime(::base::Times::now(), "yy-MM-dd HH:mm:ss.zzz"); - QString line = QString("[%1] [%2] [%3:%4] - ") - .arg(time) - .arg(QThread::currentThread()->objectName()) - .arg(file) - .arg(ctxt.line); - switch (type) { - case QtDebugMsg: - line += "Debug"; - break; - case QtInfoMsg: - line += "Info"; - break; - case QtWarningMsg: - line += "Warning"; - break; - case QtCriticalMsg: - line += "Critical"; - break; - case QtFatalMsg: - line += "Fatal"; - break; - default: - break; - } - - line += ": " + msg + "\n"; - QByteArray lineBytes = line.toUtf8(); - fwrite(lineBytes.constData(), 1, lineBytes.size(), stdout); - fflush(stdout); - QFile *logFilePtr = logFilePointer.loadRelaxed(); - if (logFilePtr) { - logFilePtr->write(lineBytes); - logFilePtr->flush(); - } +void logMessageHandler(QtMsgType type, const QMessageLogContext& ctxt, const QString& msg) { + QMutexLocker locker(&logMutex); + + QString file = ctxt.file; + if (file.lastIndexOf("/") > 0) { + file = file.mid(file.lastIndexOf('/') + 1); + } + + // Time should be in UTC to save user privacy on log sharing + QString time = ::base::Times::formatTime(::base::Times::now(), "yy-MM-dd HH:mm:ss.zzz"); + QString line = QString("[%1] [%2] [%3:%4] - ") + .arg(time) + .arg(QThread::currentThread()->objectName()) + .arg(file) + .arg(ctxt.line); + switch (type) { + case QtDebugMsg: + line += "Debug"; + break; + case QtInfoMsg: + line += "Info"; + break; + case QtWarningMsg: + line += "Warning"; + break; + case QtCriticalMsg: + line += "Critical"; + break; + case QtFatalMsg: + line += "Fatal"; + break; + default: + break; + } + + line += ": " + msg + "\n"; + QByteArray lineBytes = line.toUtf8(); + fwrite(lineBytes.constData(), 1, lineBytes.size(), stdout); + fflush(stdout); + QFile* logFilePtr = logFilePointer.loadRelaxed(); + if (logFilePtr) { + logFilePtr->write(lineBytes); + logFilePtr->flush(); + } } -static LogManager *log = nullptr; +static LogManager* log = nullptr; LogManager::LogManager() { - qDebug() << "Initialize LogManager"; - logFileDir = base::OkSettings::getAppLogPath(); - qDebug() << "Log file dir is:" << logFileDir; - - logName = APPLICATION_NAME "-" + - ::base::Times::formatTime(::base::Times::now(), "yyyyMMddHHmmss") + "-" + - QString::number(base::OkProcess::selfPid()) + ".log"; - - QString logFilePath = logFileDir.path() + QDir::separator() + logName; - qDebug() << "Log file is:" << logFilePath; - file = std::make_unique(logFilePath); - file->open(QIODevice::ReadWrite); - logFilePointer.storeRelaxed(file.get()); - qInstallMessageHandler(logMessageHandler); + qDebug() << "Initialize LogManager"; + logFileDir = base::OkSettings::getAppLogPath(); + qDebug() << "Log file dir is:" << logFileDir; + + logName = APPLICATION_NAME "-" + + ::base::Times::formatTime(::base::Times::now(), "yyyyMMddHHmmss") + "-" + + QString::number(base::OkProcess::selfPid()) + ".log"; + + QString logFilePath = logFileDir.path() + QDir::separator() + logName; + qDebug() << "Log file is:" << logFilePath; + file = std::make_unique(logFilePath); + file->open(QIODevice::ReadWrite); + logFilePointer.storeRelaxed(file.get()); + qInstallMessageHandler(logMessageHandler); } -LogManager::~LogManager() { - Destroy(); -} +LogManager::~LogManager() { Destroy(); } -const LogManager &LogManager::Instance() { - if(!log){ - log = new LogManager(); - } - return *log; +const LogManager& LogManager::Instance() { + if (!log) { + log = new LogManager(); + } + return *log; } void LogManager::Destroy() { - delete log; - log= nullptr; + delete log; + log = nullptr; } -} // namespace lib -} // namespace ok +} // namespace lib +} // namespace ok diff --git a/src/lib/log/LogManager.h b/src/lib/log/LogManager.h index 7fadd56c..60f5d6aa 100644 --- a/src/lib/log/LogManager.h +++ b/src/lib/log/LogManager.h @@ -17,39 +17,34 @@ #ifndef OKMSG_PROJECT_LOGMANAGER_H #define OKMSG_PROJECT_LOGMANAGER_H -#include #include +#include #include #include namespace ok { namespace lib { - class LogManager { public: - static const LogManager& Instance(); - static void Destroy(); + static const LogManager& Instance(); + static void Destroy(); - [[nodiscard]] const QString& getLogFile() const { - return logName; - }; + [[nodiscard]] const QString& getLogFile() const { return logName; }; - [[nodiscard]] QFile& getFile() const { - return *file.get(); - } + [[nodiscard]] QFile& getFile() const { return *file.get(); } - ~LogManager(); -private: - LogManager(); + ~LogManager(); - QString logName; - QDir logFileDir; - std::unique_ptr< QFile> file; +private: + LogManager(); + QString logName; + QDir logFileDir; + std::unique_ptr file; }; -} // namespace lib -} // namespace ok +} // namespace lib +} // namespace ok -#endif // OKMSG_PROJECT_LOGMANAGER_H +#endif // OKMSG_PROJECT_LOGMANAGER_H diff --git a/src/lib/messenger/IM.cpp b/src/lib/messenger/IM.cpp index 2284f883..32d34a29 100644 --- a/src/lib/messenger/IM.cpp +++ b/src/lib/messenger/IM.cpp @@ -26,7 +26,6 @@ #include #include -#include #include #include #include @@ -44,6 +43,7 @@ #include #include #include +#include namespace lib::messenger { @@ -54,10 +54,9 @@ using namespace gloox; #define DISCO_CTX_BOOKMARKS 2 #define DISCO_CTX_CONF_MEMBERS 3 - - ConferenceList mConferenceList; - BookmarkList mBookmarkList; - bool __started = false; +ConferenceList mConferenceList; +BookmarkList mBookmarkList; +bool __started = false; /** * 聊天通讯核心类 @@ -68,45 +67,43 @@ using namespace gloox; IM::IM(QString host, QString user, QString pwd, - QStringList features_) // - : - features(std::move(features_)), // - _host(std::move(host)), // - _username(std::move(user)), // - _password(std::move(pwd)) -{ - - qDebug() << __func__ << "Create instance..."; + QStringList features_) // + : features(std::move(features_)) + , // + _host(std::move(host)) + , // + _username(std::move(user)) + , // + _password(std::move(pwd)) { + qDebug() << __func__ << "Create instance..."; - setObjectName("IM-Connect"); + setObjectName("IM-Connect"); - auto osInfo = ok::base::SystemInfo::instance()->osInfo(); + auto osInfo = ok::base::SystemInfo::instance()->osInfo(); - discoVal = osInfo.prettyName; + discoVal = osInfo.prettyName; - // 生成本机resource. 格式:OkEDU..[VER].[UNIQUE] - _resource = QString("%1.%2.[%3].%4") // - .arg(APPLICATION_ALIAS) - .arg(osInfo.hostName) - .arg(GIT_DESCRIBE) - .arg(osInfo.uniqueId.mid(0, 6)); + // 生成本机resource. 格式:OkEDU..[VER].[UNIQUE] + _resource = QString("%1.%2.[%3].%4") // + .arg(APPLICATION_ALIAS) + .arg(osInfo.hostName) + .arg(GIT_DESCRIBE) + .arg(osInfo.uniqueId.mid(0, 6)); - qDebug() << "Generate self resource:" << _resource; + qDebug() << "Generate self resource:" << _resource; - // qRegisterMetaType - qRegisterMetaType("JID"); - qRegisterMetaType("IMContactId"); - qRegisterMetaType("IMFriend"); - qRegisterMetaType("IMPeerId"); - qRegisterMetaType("IMMessage"); - qRegisterMetaType("IMGroupOccupant"); + // qRegisterMetaType + qRegisterMetaType("JID"); + qRegisterMetaType("IMContactId"); + qRegisterMetaType("IMFriend"); + qRegisterMetaType("IMPeerId"); + qRegisterMetaType("IMMessage"); + qRegisterMetaType("IMGroupOccupant"); - qDebug() << "Create messenger instance is successfully"; + qDebug() << "Create messenger instance is successfully"; } -IM::~IM() { - qDebug() << __func__; -} +IM::~IM() { qDebug() << __func__; } void IM::run() { qDebug() << __func__; @@ -114,538 +111,535 @@ void IM::run() { } std::unique_ptr IM::makeClient() { - JID loginJid(QString("%1@%2/%3").arg(_username).arg(_host).arg( _resource).toStdString()); - - qDebug() << __func__ << "Using Jid:" << qstring(loginJid.full()); - - /** - * Client - */ - auto client = std::make_unique(loginJid, _password.toStdString()); - auto disco = client->disco(); - - disco->setVersion("disco", APPLICATION_VERSION, discoVal.toStdString()); - disco->setIdentity("client", "pc", APPLICATION_RELEASE); - disco->addIdentity("pubsub", "pep"); - disco->addFeature(XMLNS_PUBSUB); - disco->addFeature(XMLNS_PUBSUB_EVENT); - disco->addFeature(XMLNS_PUBSUB_OWNER); - disco->addFeature(XMLNS_PUBSUB_PUBLISH_OPTIONS); - disco->addFeature(XMLNS_PUBSUB_AUTO_SUBSCRIBE); - disco->addFeature(XMLNS_PUBSUB_AUTO_CREATE); - client->registerStanzaExtension(new Disco::Items); - client->registerStanzaExtension(new PubSub::Event()); - - client->registerStanzaExtension(new VCardUpdate); - client->registerStanzaExtension(new Capabilities); - client->registerStanzaExtension(new InBandBytestream::IBB); - client->registerStanzaExtension(new ChatState(nullptr)); - client->registerStanzaExtension(new Receipt(nullptr)); - client->registerStanzaExtension(new Forward()); - client->registerStanzaExtension(new Carbons()); - client->registerStanzaExtension(new Attention()); - client->registerStanzaExtension(new DelayedDelivery()); - client->registerStanzaExtension(new ExtDisco()); - client->registerStanzaExtension(new Addresses()); - client->registerStanzaExtension(new Nickname(nullptr)); - - /** - * - */ - disco->addFeature(XMLNS_X_CONFERENCE); - client->registerStanzaExtension(new Conference); - - /** - * XEP-0402: PEP Native Bookmarks - * urn:xmpp:bookmarks:1 - */ - disco->addFeature(XMLNS_BOOKMARKS2); - disco->addFeature(XMLNS_BOOKMARKS2_NOTIFY); - disco->addFeature(XMLNS_BOOKMARKS2_COMPAT); - disco->addFeature("urn:xmpp:bookmarks-conversion:0"); - m_nativeBookmark = std::make_unique(client.get()); - m_nativeBookmark->registerBookmarkHandler(this); - - for (const auto &feat : features) { - qDebug() << "addFeature:" << feat; - disco->addFeature(stdstring(feat)); - } - - /** - * 聊天相关 - */ - disco->addFeature(XMLNS_CHAT_STATES); - - disco->addFeature(XMLNS_MUC); - disco->addFeature(XMLNS_MUC_ADMIN); - disco->addFeature(XMLNS_MUC_OWNER); - disco->addFeature(XMLNS_MUC_ROOMS); - disco->addFeature(XMLNS_MUC_ROOMINFO); - disco->addFeature(XMLNS_MUC_USER); - disco->addFeature(XMLNS_MUC_UNIQUE); - disco->addFeature(XMLNS_MUC_REQUEST); - - disco->addFeature(XMLNS_DISCO_INFO); - disco->addFeature(XMLNS_DISCO_ITEMS); - disco->addFeature(XMLNS_DISCO_PUBLISH); - disco->addFeature(XMLNS_CAPS); - - disco->addFeature(XMLNS_STANZA_FORWARDING); - - disco->addFeature(XMLNS_BOOKMARKS); - disco->addFeature(XMLNS_PRIVATE_XML); - // XMLNS_RECEIPTS - disco->addFeature(XMLNS_RECEIPTS); - disco->addFeature(XMLNS_MESSAGE_CARBONS); - disco->addFeature("urn:xmpp:carbons:rules:0"); - disco->addFeature(XMLNS_ADDRESSES); - - disco->addFeature(XMLNS_IBB); - - // NICK - disco->addFeature(XMLNS_NICKNAME); - disco->addFeature(XMLNS_NICKNAME + "+notify"); - - client->setTls(TLSPolicy::TLSDisabled); - client->setCompression(false); - - client->registerIqHandler(this, ExtPubSub); - // client->registerIncomingHandler(this); - - /** - * listeners - */ - client->registerConnectionListener(this); - - client->registerPresenceHandler(this); - client->registerMessageSessionHandler(this); - client->registerMessageHandler(this); - // client->setStreamManagement(true, true); + JID loginJid(QString("%1@%2/%3").arg(_username).arg(_host).arg(_resource).toStdString()); + + qDebug() << __func__ << "Using Jid:" << qstring(loginJid.full()); + + /** + * Client + */ + auto client = std::make_unique(loginJid, _password.toStdString()); + auto disco = client->disco(); + + disco->setVersion("disco", APPLICATION_VERSION, discoVal.toStdString()); + disco->setIdentity("client", "pc", APPLICATION_RELEASE); + disco->addIdentity("pubsub", "pep"); + disco->addFeature(XMLNS_PUBSUB); + disco->addFeature(XMLNS_PUBSUB_EVENT); + disco->addFeature(XMLNS_PUBSUB_OWNER); + disco->addFeature(XMLNS_PUBSUB_PUBLISH_OPTIONS); + disco->addFeature(XMLNS_PUBSUB_AUTO_SUBSCRIBE); + disco->addFeature(XMLNS_PUBSUB_AUTO_CREATE); + client->registerStanzaExtension(new Disco::Items); + client->registerStanzaExtension(new PubSub::Event()); + + client->registerStanzaExtension(new VCardUpdate); + client->registerStanzaExtension(new Capabilities); + client->registerStanzaExtension(new InBandBytestream::IBB); + client->registerStanzaExtension(new ChatState(nullptr)); + client->registerStanzaExtension(new Receipt(nullptr)); + client->registerStanzaExtension(new Forward()); + client->registerStanzaExtension(new Carbons()); + client->registerStanzaExtension(new Attention()); + client->registerStanzaExtension(new DelayedDelivery()); + client->registerStanzaExtension(new ExtDisco()); + client->registerStanzaExtension(new Addresses()); + client->registerStanzaExtension(new Nickname(nullptr)); + + /** + * + */ + disco->addFeature(XMLNS_X_CONFERENCE); + client->registerStanzaExtension(new Conference); + + /** + * XEP-0402: PEP Native Bookmarks + * urn:xmpp:bookmarks:1 + */ + disco->addFeature(XMLNS_BOOKMARKS2); + disco->addFeature(XMLNS_BOOKMARKS2_NOTIFY); + disco->addFeature(XMLNS_BOOKMARKS2_COMPAT); + disco->addFeature("urn:xmpp:bookmarks-conversion:0"); + m_nativeBookmark = std::make_unique(client.get()); + m_nativeBookmark->registerBookmarkHandler(this); + + for (const auto& feat : features) { + qDebug() << "addFeature:" << feat; + disco->addFeature(stdstring(feat)); + } + + /** + * 聊天相关 + */ + disco->addFeature(XMLNS_CHAT_STATES); + + disco->addFeature(XMLNS_MUC); + disco->addFeature(XMLNS_MUC_ADMIN); + disco->addFeature(XMLNS_MUC_OWNER); + disco->addFeature(XMLNS_MUC_ROOMS); + disco->addFeature(XMLNS_MUC_ROOMINFO); + disco->addFeature(XMLNS_MUC_USER); + disco->addFeature(XMLNS_MUC_UNIQUE); + disco->addFeature(XMLNS_MUC_REQUEST); + + disco->addFeature(XMLNS_DISCO_INFO); + disco->addFeature(XMLNS_DISCO_ITEMS); + disco->addFeature(XMLNS_DISCO_PUBLISH); + disco->addFeature(XMLNS_CAPS); + + disco->addFeature(XMLNS_STANZA_FORWARDING); + + disco->addFeature(XMLNS_BOOKMARKS); + disco->addFeature(XMLNS_PRIVATE_XML); + // XMLNS_RECEIPTS + disco->addFeature(XMLNS_RECEIPTS); + disco->addFeature(XMLNS_MESSAGE_CARBONS); + disco->addFeature("urn:xmpp:carbons:rules:0"); + disco->addFeature(XMLNS_ADDRESSES); + + disco->addFeature(XMLNS_IBB); + + // NICK + disco->addFeature(XMLNS_NICKNAME); + disco->addFeature(XMLNS_NICKNAME + "+notify"); + + client->setTls(TLSPolicy::TLSDisabled); + client->setCompression(false); + + client->registerIqHandler(this, ExtPubSub); + // client->registerIncomingHandler(this); + + /** + * listeners + */ + client->registerConnectionListener(this); + + client->registerPresenceHandler(this); + client->registerMessageSessionHandler(this); + client->registerMessageHandler(this); + // client->setStreamManagement(true, true); #ifdef LOG_XMPP - client->logInstance().registerLogHandler(LogLevelDebug, LogAreaAll, this); + client->logInstance().registerLogHandler(LogLevelDebug, LogAreaAll, this); #endif - vCardManager = std::make_unique(client.get()); - pubSubManager = std::make_unique(client.get()); - bookmarkStorage = std::make_unique(client.get()); - return std::move(client); + vCardManager = std::make_unique(client.get()); + pubSubManager = std::make_unique(client.get()); + bookmarkStorage = std::make_unique(client.get()); + return std::move(client); } void IM::stop() { - qDebug() << __func__; - doDisconnect(); - emit stopped(); + qDebug() << __func__; + doDisconnect(); + emit stopped(); } - void IM::onDisconnect(ConnectionError e) { - qDebug() << __func__ << "error:" << e; - - if(!__started){ - return; - } - - __started = false; - - IMConnectStatus _status; - switch (e) { - case ConnAuthenticationFailed: - _status = IMConnectStatus::AUTH_FAILED; - break; - case ConnNoError: - _status = IMConnectStatus::DISCONNECTED; - break; - case ConnStreamError: - case ConnStreamVersionError: - _status = IMConnectStatus::CONN_ERROR; - break; - case ConnStreamClosed: - _status = IMConnectStatus::DISCONNECTED; - break; - case ConnProxyGatewayTimeout: - _status = IMConnectStatus::TIMEOUT; - break; - case ConnProxyAuthRequired: - case ConnProxyAuthFailed: - case ConnProxyNoSupportedAuth: - case ConnIoError: - case ConnParseError: - case ConnConnectionRefused: - case ConnDnsError: - _status = IMConnectStatus::CONN_ERROR; - break; - case ConnOutOfMemory: - _status = IMConnectStatus::OUT_OF_RESOURCE; - break; - case ConnNoSupportedAuth: - _status = IMConnectStatus::NO_SUPPORT; - break; - case ConnTlsFailed: - case ConnTlsNotAvailable: - _status = IMConnectStatus::TLS_ERROR; - break; - case ConnCompressionFailed: - case ConnUserDisconnected: - case ConnNotConnected: - _status = IMConnectStatus::DISCONNECTED; - break; - case ConnAttemptTimeout: - _status = IMConnectStatus::TIMEOUT; - break; - default: - _status = IMConnectStatus::DISCONNECTED; - break; - } - - emit connectResult(_status); - emit stopped(); + qDebug() << __func__ << "error:" << e; + + if (!__started) { + return; + } + + __started = false; + + IMConnectStatus _status; + switch (e) { + case ConnAuthenticationFailed: + _status = IMConnectStatus::AUTH_FAILED; + break; + case ConnNoError: + _status = IMConnectStatus::DISCONNECTED; + break; + case ConnStreamError: + case ConnStreamVersionError: + _status = IMConnectStatus::CONN_ERROR; + break; + case ConnStreamClosed: + _status = IMConnectStatus::DISCONNECTED; + break; + case ConnProxyGatewayTimeout: + _status = IMConnectStatus::TIMEOUT; + break; + case ConnProxyAuthRequired: + case ConnProxyAuthFailed: + case ConnProxyNoSupportedAuth: + case ConnIoError: + case ConnParseError: + case ConnConnectionRefused: + case ConnDnsError: + _status = IMConnectStatus::CONN_ERROR; + break; + case ConnOutOfMemory: + _status = IMConnectStatus::OUT_OF_RESOURCE; + break; + case ConnNoSupportedAuth: + _status = IMConnectStatus::NO_SUPPORT; + break; + case ConnTlsFailed: + case ConnTlsNotAvailable: + _status = IMConnectStatus::TLS_ERROR; + break; + case ConnCompressionFailed: + case ConnUserDisconnected: + case ConnNotConnected: + _status = IMConnectStatus::DISCONNECTED; + break; + case ConnAttemptTimeout: + _status = IMConnectStatus::TIMEOUT; + break; + default: + _status = IMConnectStatus::DISCONNECTED; + break; + } + + emit connectResult(_status); + emit stopped(); } void IM::onConnect() { - qDebug() << __func__ << "connected"; - if(__started){ - return; - } + qDebug() << __func__ << "connected"; + if (__started) { + return; + } - __started = true; + __started = true; - auto res = _client->resource(); - qDebug() << __func__ << "resource:" << (qstring(res)); + auto res = _client->resource(); + qDebug() << __func__ << "resource:" << (qstring(res)); - // fetchVCard(qstring(self().bare())); - // emit selfIdChanged(qstring(_client->username())); + // fetchVCard(qstring(self().bare())); + // emit selfIdChanged(qstring(_client->username())); - emit connectResult( IMConnectStatus::CONNECTED); - emit started(); + emit connectResult(IMConnectStatus::CONNECTED); + emit started(); - qDebug() << __func__ << "Resume."; + qDebug() << __func__ << "Resume."; } void IM::doConnect() { - qDebug() << __func__ << "Create IM client..."; - _client = makeClient(); - qDebug() << __func__ << "Create IM client is:" << _client.get(); - _client->connect(true); + qDebug() << __func__ << "Create IM client..."; + _client = makeClient(); + qDebug() << __func__ << "Create IM client is:" << _client.get(); + _client->connect(true); - emit connectResult(IMConnectStatus::CONNECTING); + emit connectResult(IMConnectStatus::CONNECTING); } -void IM::send(const QString &xml) { - if (xml.isEmpty()) { - qWarning() << "send xml content is empty"; - return; - } - _client->send(stdstring(xml)); +void IM::send(const QString& xml) { + if (xml.isEmpty()) { + qWarning() << "send xml content is empty"; + return; + } + _client->send(stdstring(xml)); } -void IM::interrupt() { +void IM::interrupt() {} +IMMessage IM::fromXMsg(MsgType type, const gloox::Message& msg) { + IMMessage imMsg = {.from = qstring(msg.from().full()), + .to = qstring(msg.to().full()), + .body = qstring(msg.body()), + .timestamp = ::base::Times::now()}; + + if (!msg.id().empty()) { + imMsg.id = (qstring(msg.id())); + } + return imMsg; } -IMMessage IM::fromXMsg(MsgType type, const gloox::Message &msg) { +void IM::enableDiscoManager() { + qDebug() << "enableDiscoManager"; - IMMessage imMsg = {.from = qstring(msg.from().full()), .to = qstring(msg.to().full()), .body = qstring(msg.body()), .timestamp = ::base::Times::now()}; + auto client = _client.get(); + auto disco = client->disco(); - if (!msg.id().empty()) { - imMsg.id = (qstring(msg.id())); - } - return imMsg; -} + for (const auto& feat : features) { + qDebug() << "addFeature:" << feat; + disco->addFeature(stdstring(feat)); + } -void IM::enableDiscoManager() { - qDebug() << "enableDiscoManager"; - - auto client = _client.get(); - auto disco = client->disco(); - - for (const auto &feat : features) { - qDebug() << "addFeature:" << feat; - disco->addFeature(stdstring(feat)); - } - - /** - * 头像相关 - */ - // client->registerStanzaExtension(new Avatar); - // // urn:xmpp:avatar:data - // disco->addFeature(XMLNS_AVATAR); - // // urn:xmpp:avatar:metadata - // disco->addFeature(XMLNS_META_AVATAR); - // // urn:xmpp:avatar:metadata+notify - // disco->addFeature(XMLNS_META_AVATAR + "+notify"); - - disco->addFeature(XMLNS_CHAT_STATES); - disco->addFeature(XMLNS_MUC); - disco->addFeature(XMLNS_MUC_ADMIN); - disco->addFeature(XMLNS_MUC_OWNER); - disco->addFeature(XMLNS_MUC_ROOMS); - disco->addFeature(XMLNS_MUC_ROOMINFO); - disco->addFeature(XMLNS_MUC_USER); - disco->addFeature(XMLNS_MUC_UNIQUE); - disco->addFeature(XMLNS_MUC_REQUEST); - - disco->addFeature(XMLNS_DISCO_INFO); - disco->addFeature(XMLNS_DISCO_ITEMS); - disco->addFeature(XMLNS_DISCO_PUBLISH); - disco->addFeature(XMLNS_CAPS); - - disco->addFeature(XMLNS_STANZA_FORWARDING); - - disco->addFeature(XMLNS_BOOKMARKS); - disco->addFeature(XMLNS_PRIVATE_XML); - // XMLNS_RECEIPTS - disco->addFeature(XMLNS_RECEIPTS); - disco->addFeature(XMLNS_MESSAGE_CARBONS); - disco->addFeature("urn:xmpp:carbons:rules:0"); - disco->addFeature(XMLNS_ADDRESSES); - - // 基本Jingle功能 - disco->addFeature(XMLNS_IBB); - disco->addFeature(XMLNS_JINGLE); - disco->addFeature(XMLNS_JINGLE_FILE_TRANSFER); - disco->addFeature(XMLNS_JINGLE_FILE_TRANSFER4); - disco->addFeature(XMLNS_JINGLE_FILE_TRANSFER5); - disco->addFeature(XMLNS_JINGLE_FILE_TRANSFER_MULTI); - - disco->addFeature(XMLNS_JINGLE_IBB); - disco->addFeature(XMLNS_JINGLE_ERRORS); - disco->addFeature(XMLNS_JINGLE_ICE_UDP); - disco->addFeature(XMLNS_JINGLE_APPS_DTLS); - disco->addFeature(XMLNS_JINGLE_APPS_RTP); - disco->addFeature(XMLNS_JINGLE_FEATURE_AUDIO); - disco->addFeature(XMLNS_JINGLE_FEATURE_VIDEO); - disco->addFeature(XMLNS_JINGLE_APPS_RTP_SSMA); - disco->addFeature(XMLNS_JINGLE_APPS_RTP_FB); - disco->addFeature(XMLNS_JINGLE_APPS_RTP_SSMA); - disco->addFeature(XMLNS_JINGLE_APPS_RTP_HDREXT); - disco->addFeature(XMLNS_JINGLE_APPS_GROUP); - disco->addFeature(XMLNS_JINGLE_MESSAGE); - - /** - * 昵称 NICK - */ - disco->addFeature(XMLNS_NICKNAME); - disco->addFeature(XMLNS_NICKNAME + "+notify"); - client->registerStanzaExtension(new Nickname(nullptr)); - - client->registerStanzaExtension(new VCardUpdate); - client->registerStanzaExtension(new Capabilities); - client->registerStanzaExtension(new Disco::Items); - - client->registerStanzaExtension(new Jingle::JingleMessage()); - client->registerStanzaExtension(new InBandBytestream::IBB); - client->registerStanzaExtension(new ChatState(nullptr)); - client->registerStanzaExtension(new Receipt(nullptr)); - client->registerStanzaExtension(new Forward()); - client->registerStanzaExtension(new Carbons()); - client->registerStanzaExtension(new Attention()); - client->registerStanzaExtension(new DelayedDelivery()); - client->registerStanzaExtension(new ExtDisco()); - client->registerStanzaExtension(new Addresses()); - - disco->registerDiscoHandler(this); - disco->registerNodeHandler(this, EmptyString); + /** + * 头像相关 + */ + // client->registerStanzaExtension(new Avatar); + // // urn:xmpp:avatar:data + // disco->addFeature(XMLNS_AVATAR); + // // urn:xmpp:avatar:metadata + // disco->addFeature(XMLNS_META_AVATAR); + // // urn:xmpp:avatar:metadata+notify + // disco->addFeature(XMLNS_META_AVATAR + "+notify"); + + disco->addFeature(XMLNS_CHAT_STATES); + disco->addFeature(XMLNS_MUC); + disco->addFeature(XMLNS_MUC_ADMIN); + disco->addFeature(XMLNS_MUC_OWNER); + disco->addFeature(XMLNS_MUC_ROOMS); + disco->addFeature(XMLNS_MUC_ROOMINFO); + disco->addFeature(XMLNS_MUC_USER); + disco->addFeature(XMLNS_MUC_UNIQUE); + disco->addFeature(XMLNS_MUC_REQUEST); + + disco->addFeature(XMLNS_DISCO_INFO); + disco->addFeature(XMLNS_DISCO_ITEMS); + disco->addFeature(XMLNS_DISCO_PUBLISH); + disco->addFeature(XMLNS_CAPS); + + disco->addFeature(XMLNS_STANZA_FORWARDING); + + disco->addFeature(XMLNS_BOOKMARKS); + disco->addFeature(XMLNS_PRIVATE_XML); + // XMLNS_RECEIPTS + disco->addFeature(XMLNS_RECEIPTS); + disco->addFeature(XMLNS_MESSAGE_CARBONS); + disco->addFeature("urn:xmpp:carbons:rules:0"); + disco->addFeature(XMLNS_ADDRESSES); + + // 基本Jingle功能 + disco->addFeature(XMLNS_IBB); + disco->addFeature(XMLNS_JINGLE); + disco->addFeature(XMLNS_JINGLE_FILE_TRANSFER); + disco->addFeature(XMLNS_JINGLE_FILE_TRANSFER4); + disco->addFeature(XMLNS_JINGLE_FILE_TRANSFER5); + disco->addFeature(XMLNS_JINGLE_FILE_TRANSFER_MULTI); + + disco->addFeature(XMLNS_JINGLE_IBB); + disco->addFeature(XMLNS_JINGLE_ERRORS); + disco->addFeature(XMLNS_JINGLE_ICE_UDP); + disco->addFeature(XMLNS_JINGLE_APPS_DTLS); + disco->addFeature(XMLNS_JINGLE_APPS_RTP); + disco->addFeature(XMLNS_JINGLE_FEATURE_AUDIO); + disco->addFeature(XMLNS_JINGLE_FEATURE_VIDEO); + disco->addFeature(XMLNS_JINGLE_APPS_RTP_SSMA); + disco->addFeature(XMLNS_JINGLE_APPS_RTP_FB); + disco->addFeature(XMLNS_JINGLE_APPS_RTP_SSMA); + disco->addFeature(XMLNS_JINGLE_APPS_RTP_HDREXT); + disco->addFeature(XMLNS_JINGLE_APPS_GROUP); + disco->addFeature(XMLNS_JINGLE_MESSAGE); + + /** + * 昵称 NICK + */ + disco->addFeature(XMLNS_NICKNAME); + disco->addFeature(XMLNS_NICKNAME + "+notify"); + client->registerStanzaExtension(new Nickname(nullptr)); + + client->registerStanzaExtension(new VCardUpdate); + client->registerStanzaExtension(new Capabilities); + client->registerStanzaExtension(new Disco::Items); + + client->registerStanzaExtension(new Jingle::JingleMessage()); + client->registerStanzaExtension(new InBandBytestream::IBB); + client->registerStanzaExtension(new ChatState(nullptr)); + client->registerStanzaExtension(new Receipt(nullptr)); + client->registerStanzaExtension(new Forward()); + client->registerStanzaExtension(new Carbons()); + client->registerStanzaExtension(new Attention()); + client->registerStanzaExtension(new DelayedDelivery()); + client->registerStanzaExtension(new ExtDisco()); + client->registerStanzaExtension(new Addresses()); + + disco->registerDiscoHandler(this); + disco->registerNodeHandler(this, EmptyString); } void IM::requestVCards() { - /** - * VCard - */ - qDebug() << "requestVCards"; - vCardManager->fetchVCard(self().bareJID(), this); -} - -gloox::RosterManager *IM::enableRosterManager() { - qDebug() << __func__; - /** - * roster - */ - auto pRosterManager = _client->enableRoster(); - pRosterManager->registerRosterListener(this); - return pRosterManager; - // enable carbons(多终端支持) - IQ iq(IQ::IqType::Set, JID(), "server"); - iq.addExtension(new Carbons(gloox::Carbons::Enable)); - _client->send(iq); - - // request ext server disco - IQ iq2(gloox::IQ::Get, JID(_host.toStdString())); - auto t = iq2.tag(); - t->addChild(gloox::ExtDisco::newRequest()); - _client->send(t); - // - // /** - // * Registration - // */ - // mRegistration = std::make_unique(_client.get()); - // mRegistration->registerRegistrationHandler(this); + /** + * VCard + */ + qDebug() << "requestVCards"; + vCardManager->fetchVCard(self().bareJID(), this); } -void IM::doDisconnect() { - assert(_client.get()); - _client->disconnect(); +gloox::RosterManager* IM::enableRosterManager() { + qDebug() << __func__; + /** + * roster + */ + auto pRosterManager = _client->enableRoster(); + pRosterManager->registerRosterListener(this); + return pRosterManager; + // enable carbons(多终端支持) + IQ iq(IQ::IqType::Set, JID(), "server"); + iq.addExtension(new Carbons(gloox::Carbons::Enable)); + _client->send(iq); + + // request ext server disco + IQ iq2(gloox::IQ::Get, JID(_host.toStdString())); + auto t = iq2.tag(); + t->addChild(gloox::ExtDisco::newRequest()); + _client->send(t); + // + // /** + // * Registration + // */ + // mRegistration = std::make_unique(_client.get()); + // mRegistration->registerRegistrationHandler(this); } -QDomDocument IM::buildMessage(const QString &to, // - const QString &msg, // - const QString &id) { +void IM::doDisconnect() { + assert(_client.get()); + _client->disconnect(); +} - gloox::Message m(gloox::Message::MessageType::Chat, JID(stdstring(to)), msg.toStdString()); - m.setFrom(_client->jid()); - m.setID(stdstring(id)); - m.addExtension(new Receipt(Receipt::Request)); +QDomDocument IM::buildMessage(const QString& to, // + const QString& msg, // + const QString& id) { + gloox::Message m(gloox::Message::MessageType::Chat, JID(stdstring(to)), msg.toStdString()); + m.setFrom(_client->jid()); + m.setID(stdstring(id)); + m.addExtension(new Receipt(Receipt::Request)); - return ::base::Xmls::parse(qstring(m.tag()->xml())); + return ::base::Xmls::parse(qstring(m.tag()->xml())); } -bool IM::sendTo(const QString &friendId, const QString &msg, const QString &id) { - qDebug() << "sendTo:" << friendId; - qDebug() << "msgId:" << id << "msg:" << msg ; +bool IM::sendTo(const QString& friendId, const QString& msg, const QString& id) { + qDebug() << "sendTo:" << friendId; + qDebug() << "msgId:" << id << "msg:" << msg; - gloox::Message m(gloox::Message::MessageType::Chat, JID(stdstring(friendId)), msg.toStdString()); - m.setFrom(_client->jid()); - m.setID(stdstring(id)); - m.addExtension(new Receipt(Receipt::Request)); + gloox::Message m(gloox::Message::MessageType::Chat, JID(stdstring(friendId)), + msg.toStdString()); + m.setFrom(_client->jid()); + m.setID(stdstring(id)); + m.addExtension(new Receipt(Receipt::Request)); - _client->send(m); - return true; + _client->send(m); + return true; } // Handle Message session -void IM::handleMessageSession(MessageSession *session) { - auto from = qstring(session->target().full()); - auto sid = qstring(session->threadID()); - qDebug() << __func__ << "from" << from << "sid:" << sid; - - // 联系人ID(朋友和群聊) - auto contactId = qstring(session->target().bare()); - emit receiveMessageSession(contactId, sid); - - // 聊天状态过滤器,获取:正在中等输入状态 - auto csf = m_chatStateFilters.value(contactId); - if (!csf) { - csf = new ChatStateFilter(session); - csf->registerChatStateHandler(this); - m_chatStateFilters.insert(contactId, csf); - } -} - -void IM::handleMessage(const gloox::Message &msg, MessageSession *session) { - - auto from = msg.from(); - auto peerId = qstring(from.full()); - auto friendId = qstring(from.bare()); - auto body = qstring(msg.body()); - - qDebug() << __func__ << "from:" << peerId << "subtype:" << (int)msg.subtype(); - - gloox::Message::MessageType msgType = msg.subtype(); - switch (msgType) { - case gloox::Message::Chat: { - doMessageChat(msg, friendId, body); - break; - } - case gloox::Message::Headline: { - doMessageHeadline(msg, friendId, body); - break; - } - case gloox::Message::Normal: - // Normal - doMessageNormal(msg, friendId); - break; - case gloox::Message::Groupchat: - // ignore - break; - case gloox::Message::Error: - case gloox::Message::Invalid: { - // error - break; - } - } - - auto conf = msg.findExtension(ExtConference); - if (conf) { - auto jid = conf->jid(); - qDebug() << "Received Room" << qstring(jid.full()); - requestBookmarks(); - } +void IM::handleMessageSession(MessageSession* session) { + auto from = qstring(session->target().full()); + auto sid = qstring(session->threadID()); + qDebug() << __func__ << "from" << from << "sid:" << sid; + + // 联系人ID(朋友和群聊) + auto contactId = qstring(session->target().bare()); + emit receiveMessageSession(contactId, sid); + + // 聊天状态过滤器,获取:正在中等输入状态 + auto csf = m_chatStateFilters.value(contactId); + if (!csf) { + csf = new ChatStateFilter(session); + csf->registerChatStateHandler(this); + m_chatStateFilters.insert(contactId, csf); + } +} - auto chatState = msg.findExtension(ExtChatState); - if (chatState) { - handleChatState(msg.from(), chatState->state()); - } +void IM::handleMessage(const gloox::Message& msg, MessageSession* session) { + auto from = msg.from(); + auto peerId = qstring(from.full()); + auto friendId = qstring(from.bare()); + auto body = qstring(msg.body()); - auto pEvent = msg.findExtension(ExtPubSubEvent); - if (pEvent) { - doPubSubEvent(pEvent, msg, friendId); - // msleep(100); - emit doPubSubEventDone(); - } + qDebug() << __func__ << "from:" << peerId << "subtype:" << (int)msg.subtype(); - auto delay = msg.when(); - if (delay) { - qDebug() << "delay:" << qstring(delay->stamp()); - } + gloox::Message::MessageType msgType = msg.subtype(); + switch (msgType) { + case gloox::Message::Chat: { + doMessageChat(msg, friendId, body); + break; + } + case gloox::Message::Headline: { + doMessageHeadline(msg, friendId, body); + break; + } + case gloox::Message::Normal: + // Normal + doMessageNormal(msg, friendId); + break; + case gloox::Message::Groupchat: + // ignore + break; + case gloox::Message::Error: + case gloox::Message::Invalid: { + // error + break; + } + } - auto address = msg.address(); - if (address) { - for (const auto &item : address->addresses()) { - qDebug() << "address type:" << qstring(item.type) << "jid:" << qstring(item.jid.full()); + auto conf = msg.findExtension(ExtConference); + if (conf) { + auto jid = conf->jid(); + qDebug() << "Received Room" << qstring(jid.full()); + requestBookmarks(); } - } - auto xml = qstring(msg.tag()->xml()); - emit incoming(xml); -} + auto chatState = msg.findExtension(ExtChatState); + if (chatState) { + handleChatState(msg.from(), chatState->state()); + } + + auto pEvent = msg.findExtension(ExtPubSubEvent); + if (pEvent) { + doPubSubEvent(pEvent, msg, friendId); + // msleep(100); + emit doPubSubEventDone(); + } + + auto delay = msg.when(); + if (delay) { + qDebug() << "delay:" << qstring(delay->stamp()); + } -void IM::doMessageHeadline(const Message &msg, QString &friendId, const QString &body) { + auto address = msg.address(); + if (address) { + for (const auto& item : address->addresses()) { + qDebug() << "address type:" << qstring(item.type) << "jid:" << qstring(item.jid.full()); + } + } + + auto xml = qstring(msg.tag()->xml()); + emit incoming(xml); +} - auto mu = msg.findExtension(ExtMUCUser); - if (mu) { - // 群聊邀请 - if (MUCRoom::OpInviteFrom == mu->operation()) { - emit groupInvite(qstring(JID(*mu->jid()).username()), friendId, body); +void IM::doMessageHeadline(const Message& msg, QString& friendId, const QString& body) { + auto mu = msg.findExtension(ExtMUCUser); + if (mu) { + // 群聊邀请 + if (MUCRoom::OpInviteFrom == mu->operation()) { + emit groupInvite(qstring(JID(*mu->jid()).username()), friendId, body); + } } - } } /** * 处理聊天消息 * */ -void IM::doMessageChat(const Message &msg, QString &friendId, const QString &body) { - qDebug() << "doMessageChat from:" << friendId; - if (!body.isEmpty()) { - if (!msg.encrypted()) { - qDebug() << "Is plain message:" << body; - IMMessage imMsg = fromXMsg(MsgType::Chat, msg); - emit receiveFriendMessage(friendId, imMsg); - } else { - QString xml = qstring(msg.tag()->xml()); - qDebug() << "Is encrypted message:" << xml; - emit exportEncryptedMessage(xml); - } - } - // 从 message.receipt 提取接收确认ID - auto pReceipt = msg.findExtension(ExtReceipt); - if (pReceipt && !pReceipt->id().empty()) { - emit receiveMessageReceipt(friendId, qstring(pReceipt->id())); - } - // forwarded/message - auto pCarbons = msg.findExtension(ExtCarbons); - if (pCarbons && pCarbons->embeddedStanza()) { - qDebug() << "Parse carbon message"; - Message *eMsg = static_cast(pCarbons->embeddedStanza()); - if (eMsg) { - auto ebody = eMsg->body(); - if (!ebody.empty()) { - auto msg = fromXMsg(MsgType::Chat, *eMsg); - msg.to = qstring(eMsg->to().full()); - emit receiveFriendMessage(msg.to, msg); - } - } - } +void IM::doMessageChat(const Message& msg, QString& friendId, const QString& body) { + qDebug() << "doMessageChat from:" << friendId; + if (!body.isEmpty()) { + if (!msg.encrypted()) { + qDebug() << "Is plain message:" << body; + IMMessage imMsg = fromXMsg(MsgType::Chat, msg); + emit receiveFriendMessage(friendId, imMsg); + } else { + QString xml = qstring(msg.tag()->xml()); + qDebug() << "Is encrypted message:" << xml; + emit exportEncryptedMessage(xml); + } + } + // 从 message.receipt 提取接收确认ID + auto pReceipt = msg.findExtension(ExtReceipt); + if (pReceipt && !pReceipt->id().empty()) { + emit receiveMessageReceipt(friendId, qstring(pReceipt->id())); + } + // forwarded/message + auto pCarbons = msg.findExtension(ExtCarbons); + if (pCarbons && pCarbons->embeddedStanza()) { + qDebug() << "Parse carbon message"; + Message* eMsg = static_cast(pCarbons->embeddedStanza()); + if (eMsg) { + auto ebody = eMsg->body(); + if (!ebody.empty()) { + auto msg = fromXMsg(MsgType::Chat, *eMsg); + msg.to = qstring(eMsg->to().full()); + emit receiveFriendMessage(msg.to, msg); + } + } + } } /** @@ -653,111 +647,112 @@ void IM::doMessageChat(const Message &msg, QString &friendId, const QString &bod * @param msg * @param friendId */ -void IM::doMessageNormal(const Message &msg, QString &friendId) { - auto conf = msg.findExtension(ExtConference); - if (conf) { - auto jid = conf->jid().bare(); - qDebug() << "New conference is arrival" << qstring(jid); - cacheJoinRoom(jid); - } -} - -void IM::handleMessageEvent(const JID &from, const MessageEvent *et) { qDebug() << ("JID:") << qstring(from.full()) << " MessageEvent:%2" << et; } - -void IM::doPubSubEvent(const gloox::PubSub::Event *pse, // - const Message &msg, // - QString &friendId) { // - - const QString &selfId = getSelfId().toString(); - auto isSelf = friendId == selfId; - - for (auto &item : pse->items()) { - auto nickTag = item->payload->findChild("nick"); - if (nickTag) { - Nickname nickname(nickTag); - auto newNick = qstring(nickname.nick()); - qDebug() << "nick:" << newNick; - emit receiveNicknameChange(friendId, newNick); - if (isSelf && _nick != newNick) { - _nick = newNick; - emit selfNicknameChanged(newNick); - } - } - auto avatarData = item->payload->findChild("data", XMLNS, XMLNS_AVATAR); - if (avatarData) { - auto base64 = avatarData->cdata(); - if (!base64.empty()) { - std::string::size_type pos = 0; - while ((pos = base64.find('\n')) != std::string::npos) - base64.erase(pos, 1); - while ((pos = base64.find('\r')) != std::string::npos) - base64.erase(pos, 1); - - auto avt = Base64::decode64(base64); - if (isSelf) { - qDebug() << "Receive self avatar size" << avt.size(); - emit selfAvatarChanged(avt); - } else { - qDebug() << "Receive friend avatar" << friendId << "size" << avt.size(); - emit receiveFriendAvatarChanged(friendId, avt); - } - } +void IM::doMessageNormal(const Message& msg, QString& friendId) { + auto conf = msg.findExtension(ExtConference); + if (conf) { + auto jid = conf->jid().bare(); + qDebug() << "New conference is arrival" << qstring(jid); + cacheJoinRoom(jid); } +} - auto avatarMetaData = item->payload->findChild("metadata", // - XMLNS, // - XMLNS_META_AVATAR); - if (avatarMetaData) { +void IM::handleMessageEvent(const JID& from, const MessageEvent* et) { + qDebug() << ("JID:") << qstring(from.full()) << " MessageEvent:%2" << et; +} - auto itemId = avatarMetaData->findChild("info")->findAttribute("id"); +void IM::doPubSubEvent(const gloox::PubSub::Event* pse, // + const Message& msg, // + QString& friendId) { // - ItemList items; - Item *item0 = new Item(); - item0->setID(itemId); - items.emplace_back(item0); + const QString& selfId = getSelfId().toString(); + auto isSelf = friendId == selfId; - if (pubSubManager) { - pubSubManager->requestItems(msg.from(), XMLNS_AVATAR, "", items, this); - } - } + for (auto& item : pse->items()) { + auto nickTag = item->payload->findChild("nick"); + if (nickTag) { + Nickname nickname(nickTag); + auto newNick = qstring(nickname.nick()); + qDebug() << "nick:" << newNick; + emit receiveNicknameChange(friendId, newNick); + if (isSelf) { + if (_nick != newNick) { + _nick = newNick; + emit selfNicknameChanged(newNick); + } + } + } + auto avatarData = item->payload->findChild("data", XMLNS, XMLNS_AVATAR); + if (avatarData) { + auto base64 = avatarData->cdata(); + if (!base64.empty()) { + std::string::size_type pos = 0; + while ((pos = base64.find('\n')) != std::string::npos) base64.erase(pos, 1); + while ((pos = base64.find('\r')) != std::string::npos) base64.erase(pos, 1); + + auto avt = Base64::decode64(base64); + if (isSelf) { + qDebug() << "Receive self avatar size" << avt.size(); + emit selfAvatarChanged(avt); + } else { + qDebug() << "Receive friend avatar" << friendId << "size" << avt.size(); + emit receiveFriendAvatarChanged(friendId, avt); + } + } + } - // list xmlns='eu.siacs.conversations.axolotl' - // auto devices = item->payload->findChild("list", // - // XMLNS, // - // "eu.siacs.conversations.axolotl"); - // if (devices) { - // for (auto dev : devices->findChildren("device")) { - // qDebug() << "device id:" << qstring(dev->findAttribute("id")); - // } - // } - // - // //bundle xmlns="eu.siacs.conversations.axolotl" - // auto bundle = item->payload->findChild("bundle", XMLNS,"eu.siacs.conversations.axolotl" ); - // if(bundle){ - // - // auto deviceId=qstring(pse->node()).split(":")[1]; - // - // qDebug() <<"deviceId: " << deviceId; - // - // auto spkp = bundle->findChild("signedPreKeyPublic")->cdata(); - // qDebug() <<"signedPreKeyPublic: "<< qstring(spkp); - // - // auto spks = bundle->findChild("signedPreKeySignature")->cdata(); - // qDebug() <<"signedPreKeySignature: "<< qstring(spks); - // - // auto ik = bundle->findChild("identityKey")->cdata(); - // qDebug() <<"identityKey: "<< qstring(ik); - // - // // - // auto prekeys = bundle->findChild("prekeys")->children(); - // for (auto pk : prekeys) { - // //preKeyId - // qDebug() <<"preKeyId:" << qstring( pk->findAttribute("preKeyId")) - // <<"identityKey: "<< qstring(pk->cdata()); - // - // } - // } - } + auto avatarMetaData = item->payload->findChild("metadata", // + XMLNS, // + XMLNS_META_AVATAR); + if (avatarMetaData) { + auto itemId = avatarMetaData->findChild("info")->findAttribute("id"); + + ItemList items; + Item* item0 = new Item(); + item0->setID(itemId); + items.emplace_back(item0); + + if (pubSubManager) { + pubSubManager->requestItems(msg.from(), XMLNS_AVATAR, "", items, this); + } + } + + // list xmlns='eu.siacs.conversations.axolotl' + // auto devices = item->payload->findChild("list", // + // XMLNS, // + // "eu.siacs.conversations.axolotl"); + // if (devices) { + // for (auto dev : devices->findChildren("device")) { + // qDebug() << "device id:" << qstring(dev->findAttribute("id")); + // } + // } + // + // //bundle xmlns="eu.siacs.conversations.axolotl" + // auto bundle = item->payload->findChild("bundle", + // XMLNS,"eu.siacs.conversations.axolotl" ); if(bundle){ + // + // auto deviceId=qstring(pse->node()).split(":")[1]; + // + // qDebug() <<"deviceId: " << deviceId; + // + // auto spkp = bundle->findChild("signedPreKeyPublic")->cdata(); + // qDebug() <<"signedPreKeyPublic: "<< qstring(spkp); + // + // auto spks = bundle->findChild("signedPreKeySignature")->cdata(); + // qDebug() <<"signedPreKeySignature: "<< qstring(spks); + // + // auto ik = bundle->findChild("identityKey")->cdata(); + // qDebug() <<"identityKey: "<< qstring(ik); + // + // // + // auto prekeys = bundle->findChild("prekeys")->children(); + // for (auto pk : prekeys) { + // //preKeyId + // qDebug() <<"preKeyId:" << qstring( pk->findAttribute("preKeyId")) + // <<"identityKey: "<< qstring(pk->cdata()); + // + // } + // } + } } /** @@ -766,11 +761,11 @@ void IM::doPubSubEvent(const gloox::PubSub::Event *pse, // * @param from * @param state */ -void IM::handleChatState(const JID &from, ChatStateType state) { - qDebug() << "from:" << qstring(from.full()) << "state:" << static_cast(state); +void IM::handleChatState(const JID& from, ChatStateType state) { + qDebug() << "from:" << qstring(from.full()) << "state:" << static_cast(state); - auto friendId = qstring(from.bare()); - emit receiveFriendChatState(friendId, state); + auto friendId = qstring(from.bare()); + emit receiveFriendChatState(friendId, state); } /** @@ -778,311 +773,305 @@ void IM::handleChatState(const JID &from, ChatStateType state) { * @param to * @param state 聊天状态 */ -void IM::sendChatState(const QString &to, ChatStateType state) { - qDebug() << "sendChatState" << "to:" << to << "state:" << (static_cast(state)); - auto csf = m_chatStateFilters[to]; - if (!csf) { - qWarning() << "Chat state filter is no existing!"; - return; - } - csf->setChatState(state); +void IM::sendChatState(const QString& to, ChatStateType state) { + qDebug() << "sendChatState" << "to:" << to << "state:" << (static_cast(state)); + auto csf = m_chatStateFilters[to]; + if (!csf) { + qWarning() << "Chat state filter is no existing!"; + return; + } + csf->setChatState(state); } // MUC handler -- handleMUCParticipantPresence -void IM::handleMUCParticipantPresence(gloox::MUCRoom *room, // - const MUCRoomParticipant participant, // - const Presence &presence) { - auto groupId = qstring(room->jid().full()); - auto nick = qstring(participant.nick->resource()); - - qDebug() << __func__ << groupId; - auto tag = presence.tag(); - - auto nickTag = tag->findChild("nick"); - if (nickTag) - nick = qstring(nickTag->cdata()); - - auto x = tag->findChild("x", XMLNS, XMLNS_MUC_USER); - if (x) { - IMGroupOccupant occ = {.nick = nick}; +void IM::handleMUCParticipantPresence(gloox::MUCRoom* room, // + const MUCRoomParticipant participant, // + const Presence& presence) { + auto groupId = qstring(room->jid().full()); + auto nick = qstring(participant.nick->resource()); + + qDebug() << __func__ << groupId; + auto tag = presence.tag(); + + auto nickTag = tag->findChild("nick"); + if (nickTag) nick = qstring(nickTag->cdata()); + + auto x = tag->findChild("x", XMLNS, XMLNS_MUC_USER); + if (x) { + IMGroupOccupant occ = {.nick = nick}; + + auto item = x->findChild("item"); + if (item) { + auto affiliation = qstring(item->findAttribute("affiliation")); + auto role = qstring(item->findAttribute("role")); + auto jid = item->findAttribute("jid"); + occ.jid = qstring(jid); + occ.affiliation = affiliation; + occ.role = role; + occ.status = presence.presence(); + } - auto item = x->findChild("item"); - if (item) { - auto affiliation = qstring(item->findAttribute("affiliation")); - auto role = qstring(item->findAttribute("role")); - auto jid = item->findAttribute("jid"); - occ.jid = qstring(jid); - occ.affiliation = affiliation; - occ.role = role; - occ.status = presence.presence(); - } + for (auto t : x->findChildren("status")) { + occ.codes.push_back(qstring(t->findAttribute("code")).toInt()); + } - for (auto t : x->findChildren("status")) { - occ.codes.push_back(qstring(t->findAttribute("code")).toInt()); + emit groupOccupantStatus(groupId, occ); } - - emit groupOccupantStatus(groupId, occ); - } } -void IM::handleMUCMessage(MUCRoom *room, const gloox::Message &msg, bool priv) { - auto msgId = qstring(msg.id()); - qDebug() << "msgId:" << (msgId); +void IM::handleMUCMessage(MUCRoom* room, const gloox::Message& msg, bool priv) { + auto msgId = qstring(msg.id()); + qDebug() << "msgId:" << (msgId); - auto roomId = qstring(room->jid().full()); - qDebug() << "roomId:" << roomId; + auto roomId = qstring(room->jid().full()); + qDebug() << "roomId:" << roomId; - auto from = qstring(msg.from().full()); - qDebug() << "from:" << from; + auto from = qstring(msg.from().full()); + qDebug() << "from:" << from; - auto body = qstring(msg.body()); - qDebug() << "body:" << body; + auto body = qstring(msg.body()); + qDebug() << "body:" << body; - IMPeerId peerId(msg.from()); - for (const auto &id : sendIds) { - if (id == msg.id()) { - qDebug() << "自己发出消息,忽略!"; - sendIds.erase(id); - return; + IMPeerId peerId(msg.from()); + for (const auto& id : sendIds) { + if (id == msg.id()) { + qDebug() << "自己发出消息,忽略!"; + sendIds.erase(id); + return; + } } - } - auto mu = msg.findExtension(ExtMUCUser); - if (mu) { - if (mu->flags() & UserRoomConfigurationChanged) { - room->getRoomInfo(); - } + auto mu = msg.findExtension(ExtMUCUser); + if (mu) { + if (mu->flags() & UserRoomConfigurationChanged) { + room->getRoomInfo(); + } - /** - * - * - * - * - * - * - * - * test8@conference.meet.chuanshaninfo.com/高杰2395 - * invited you to the room test8@conference.meet.chuanshaninfo.com - * - * - */ - if (MUCRoom::OpInviteFrom == mu->operation()) { - emit groupInvite(qstring(JID(*mu->jid()).bare()), roomId, qstring(msg.body())); - } + /** + * + * + * + * + * + * + * + * test8@conference.meet.chuanshaninfo.com/高杰2395 + * invited you to the room test8@conference.meet.chuanshaninfo.com + * + * + */ + if (MUCRoom::OpInviteFrom == mu->operation()) { + emit groupInvite(qstring(JID(*mu->jid()).bare()), roomId, qstring(msg.body())); + } - return; - } + return; + } - if (body.isEmpty()) { - return; - } + if (body.isEmpty()) { + return; + } - IMMessage imMsg = fromXMsg(MsgType::Groupchat, msg); - const DelayedDelivery *dd = msg.when(); - if (dd) { - // yyyy-MM-dd HH:mm:ss 20230614T12:11:43Z - imMsg.timestamp = QDateTime::fromString(qstring(dd->stamp()), "yyyy-MM-ddTHH:mm:ssZ"); - } + IMMessage imMsg = fromXMsg(MsgType::Groupchat, msg); + const DelayedDelivery* dd = msg.when(); + if (dd) { + // yyyy-MM-dd HH:mm:ss 20230614T12:11:43Z + imMsg.timestamp = QDateTime::fromString(qstring(dd->stamp()), "yyyy-MM-ddTHH:mm:ssZ"); + } - auto addresses = msg.address(); - if (addresses) { - for (auto &item : addresses->addresses()) { - // 群消息来源辨别多终端 - if (item.type == "ofrom") { - imMsg.from = qstring(item.jid.full()); - } + auto addresses = msg.address(); + if (addresses) { + for (auto& item : addresses->addresses()) { + // 群消息来源辨别多终端 + if (item.type == "ofrom") { + imMsg.from = qstring(item.jid.full()); + } + } } - } - emit receiveRoomMessage(roomId, peerId, imMsg); + emit receiveRoomMessage(roomId, peerId, imMsg); } -bool IM::handleMUCRoomCreation(MUCRoom *room) { - qDebug() << "handleMUCRoomCreation" << room->jid().full().c_str(); +bool IM::handleMUCRoomCreation(MUCRoom* room) { + qDebug() << "handleMUCRoomCreation" << room->jid().full().c_str(); - room->requestRoomConfig(); + room->requestRoomConfig(); - // 添加到缓存 - auto roomId = qstring(room->jid().bare()); - m_roomMap.insert(roomId, IMRoomInfo{room, {}}); + // 添加到缓存 + auto roomId = qstring(room->jid().bare()); + m_roomMap.insert(roomId, IMRoomInfo{room, {}}); - // 群聊增加 - emit groupReceived(roomId, qstring(room->name())); + // 群聊增加 + emit groupReceived(roomId, qstring(room->name())); - joinRoom(roomId); + joinRoom(roomId); - // bookmarkStorage->requestBookmarks(); - return true; + // bookmarkStorage->requestBookmarks(); + return true; } -void IM::handleMUCSubject(MUCRoom *room, // - const std::string &nick, // - const std::string &subject) { - - qDebug() << __func__ << room->name().c_str() << "subject" << qstring(subject); - emit groupSubjectChanged(room->jid(), subject); +void IM::handleMUCSubject(MUCRoom* room, // + const std::string& nick, // + const std::string& subject) { + qDebug() << __func__ << room->name().c_str() << "subject" << qstring(subject); + emit groupSubjectChanged(room->jid(), subject); - // 可能存在其它更新,执行信息拉取 - room->getRoomInfo(); + // 可能存在其它更新,执行信息拉取 + room->getRoomInfo(); } -void IM::handleMUCInviteDecline(MUCRoom *room, const JID &invitee, const std::string &reason) { - qDebug() << QString("MUCRoom:%1").arg(qstring(room->name())); - qDebug() << QString("invitee:%1 reason:%2").arg(qstring(invitee.full())).arg(qstring(reason)); +void IM::handleMUCInviteDecline(MUCRoom* room, const JID& invitee, const std::string& reason) { + qDebug() << QString("MUCRoom:%1").arg(qstring(room->name())); + qDebug() << QString("invitee:%1 reason:%2").arg(qstring(invitee.full())).arg(qstring(reason)); } -void IM::handleMUCError(MUCRoom *room, StanzaError error) { - qDebug() << __func__ - << "MUCRoom:"<< qstring(room->name()) - << error; +void IM::handleMUCError(MUCRoom* room, StanzaError error) { + qDebug() << __func__ << "MUCRoom:" << qstring(room->name()) << error; } -void IM::handleMUCInfo(MUCRoom *room, // - int features, // - const std::string &name, // - const DataForm *infoForm) { // +void IM::handleMUCInfo(MUCRoom* room, // + int features, // + const std::string& name, // + const DataForm* infoForm) { // - auto roomId = qstring(room->jid().full()); - auto roomName = qstring(name); + auto roomId = qstring(room->jid().full()); + auto roomName = qstring(name); - qDebug() << __func__ << roomId << roomName; + qDebug() << __func__ << roomId << roomName; - IMGroup groupInfo; - groupInfo.name = roomName; + IMGroup groupInfo; + groupInfo.name = roomName; - if (infoForm) { - auto info = const_cast(findRoom(roomId)); + if (infoForm) { + auto info = const_cast(findRoom(roomId)); - for (auto field : infoForm->fields()) { - qDebug() << "field name:" << qstring(field->name()) << qstring(field->value()); + for (auto field : infoForm->fields()) { + qDebug() << "field name:" << qstring(field->name()) << qstring(field->value()); - if (field->name() == "muc#roominfo_occupants") { - groupInfo.occupants = std::stoi(field->value()); - } else if (field->name() == "muc#roominfo_roomname" && !field->value().empty()) { - groupInfo.name = qstring(field->value()); - } else if (field->name() == "muc#roominfo_subject") { - groupInfo.subject = qstring(field->value()); - } else if (field->name() == "muc#roominfo_description") { - groupInfo.description = qstring(field->value()); - } else if (field->name() == "muc#roominfo_creationdate") { - groupInfo.creationdate = qstring(field->value()); - } + if (field->name() == "muc#roominfo_occupants") { + groupInfo.occupants = std::stoi(field->value()); + } else if (field->name() == "muc#roominfo_roomname" && !field->value().empty()) { + groupInfo.name = qstring(field->value()); + } else if (field->name() == "muc#roominfo_subject") { + groupInfo.subject = qstring(field->value()); + } else if (field->name() == "muc#roominfo_description") { + groupInfo.description = qstring(field->value()); + } else if (field->name() == "muc#roominfo_creationdate") { + groupInfo.creationdate = qstring(field->value()); + } + } + info->info = groupInfo; + emit groupRoomInfo(roomId, groupInfo); } - info->info = groupInfo; - emit groupRoomInfo(roomId, groupInfo); - } } -void IM::handleMUCItems(MUCRoom *room, const Disco::ItemList &items) { - qDebug() << QString("MUCRoom:%1").arg(qstring(room->name())); - qDebug() << QString("items:%1").arg(items.size()); +void IM::handleMUCItems(MUCRoom* room, const Disco::ItemList& items) { + qDebug() << QString("MUCRoom:%1").arg(qstring(room->name())); + qDebug() << QString("items:%1").arg(items.size()); } // config -void IM::handleMUCConfigList(MUCRoom *room, // - const MUCListItemList &items, // +void IM::handleMUCConfigList(MUCRoom* room, // + const MUCListItemList& items, // MUCOperation operation) { - qDebug() << QString("IM::handleMUCConfigList"); + qDebug() << QString("IM::handleMUCConfigList"); } -void IM::handleMUCConfigForm(MUCRoom *room, const DataForm &form) { - qDebug() << __func__ << "room:" << room->jid().full().c_str(); - - auto roomId = qstring(room->jid().bare()); +void IM::handleMUCConfigForm(MUCRoom* room, const DataForm& form) { + qDebug() << __func__ << "room:" << room->jid().full().c_str(); - auto find = m_roomMap.find(roomId); - if (find == m_roomMap.end()) { - qWarning() << "Unable to find room from cache:" << roomId; - return; - } + auto roomId = qstring(room->jid().bare()); - /** - * 将缓存的房间配置放入`DataForm` - */ - int changed = 0; - auto &roomInfo = find.value(); - for (auto item : form.fields()) { - for (const auto &change : roomInfo.changes) { - if (item->name() == change.first) { - item->setValue(change.second); - changed += 1; - break; - } + auto find = m_roomMap.find(roomId); + if (find == m_roomMap.end()) { + qWarning() << "Unable to find room from cache:" << roomId; + return; } - } - if (changed) { + /** + * 将缓存的房间配置放入`DataForm` + */ + int changed = 0; + auto& roomInfo = find.value(); + for (auto item : form.fields()) { + for (const auto& change : roomInfo.changes) { + if (item->name() == change.first) { + item->setValue(change.second); + changed += 1; + break; + } + } + } - // 清空修改信息 - roomInfo.changes.clear(); + if (changed) { + // 清空修改信息 + roomInfo.changes.clear(); - auto *mform = new DataForm(form); - mform->setType(FormType::TypeSubmit); - room->setRoomConfig(mform); - qDebug() << "Update room config items" << changed; - } + auto* mform = new DataForm(form); + mform->setType(FormType::TypeSubmit); + room->setRoomConfig(mform); + qDebug() << "Update room config items" << changed; + } }; -void IM::handleMUCConfigResult(MUCRoom *room, bool success, MUCOperation operation) { - qDebug() << __func__ << "room" << qstring(room->jid().full()) << "operation:" << operation << "success:" << success; - if (success) { - // 成功则忽略 - return; - } - - switch (operation) { - case RequestRoomConfig: { - qWarning() << "无操作群配置权限"; - break; - } - default: - // other - break; - } +void IM::handleMUCConfigResult(MUCRoom* room, bool success, MUCOperation operation) { + qDebug() << __func__ << "room" << qstring(room->jid().full()) << "operation:" << operation + << "success:" << success; + if (success) { + // 成功则忽略 + return; + } + + switch (operation) { + case RequestRoomConfig: { + qWarning() << "无操作群配置权限"; + break; + } + default: + // other + break; + } }; -void IM::handleMUCRequest(MUCRoom *room, const DataForm &form) { - qDebug() << "handleMUCRequest room" << qstring(room->jid().full()); - for (const auto &item : form.items()) { - qDebug() << "item" << item; - for (const auto &item_j : item->fields()) { - qDebug() << "field:" << item_j->name().c_str() << "=>" << item_j->value().c_str(); +void IM::handleMUCRequest(MUCRoom* room, const DataForm& form) { + qDebug() << "handleMUCRequest room" << qstring(room->jid().full()); + for (const auto& item : form.items()) { + qDebug() << "item" << item; + for (const auto& item_j : item->fields()) { + qDebug() << "field:" << item_j->name().c_str() << "=>" << item_j->value().c_str(); + } } - } }; /** * 初始化房间并加入 */ -void IM::createRoom(const JID &jid, const std::string &password) { - - qDebug() << __func__ << "jid:" << qstring(jid.full()); +void IM::createRoom(const JID& jid, const std::string& password) { + qDebug() << __func__ << "jid:" << qstring(jid.full()); - auto room = new MUCRoom(_client.get(), jid, this, this); - if (!password.empty()) { - room->setPassword(password); - } - - room->instantRoom(MUCOperation::CreateInstantRoom); - cacheJoinRoom(jid.bare(), jid.resource()); + auto room = new MUCRoom(_client.get(), jid, this, this); + if (!password.empty()) { + room->setPassword(password); + } + room->instantRoom(MUCOperation::CreateInstantRoom); + cacheJoinRoom(jid.bare(), jid.resource()); - setRoomName(qstring(jid.bare()),jid.resource()); + setRoomName(qstring(jid.bare()), jid.resource()); - ConferenceListItem item; - item.name = jid.resource(); - item.jid = room->jid().full(); - item.autojoin = true; - item.nick = stdstring(getNickname()); + ConferenceListItem item; + item.name = jid.resource(); + item.jid = room->jid().full(); + item.autojoin = true; + item.nick = stdstring(getNickname()); - // 添加到书签列表 - mConferenceList.emplace_back(item); + // 添加到书签列表 + mConferenceList.emplace_back(item); - // 存储书签列表 - bookmarkStorage->storeBookmarks(mBookmarkList, mConferenceList); - qDebug() << "Store bookmarks is successful for room"; + // 存储书签列表 + bookmarkStorage->storeBookmarks(mBookmarkList, mConferenceList); + qDebug() << "Store bookmarks is successful for room"; } /** @@ -1090,155 +1079,155 @@ void IM::createRoom(const JID &jid, const std::string &password) { * @param roomJid * @param peerId */ -bool IM::inviteToRoom(const JID &roomJid, const JID &peerId) { - auto roomInfo = findRoom(qstring(roomJid.bare())); - if (!roomInfo) { - return false; - } +bool IM::inviteToRoom(const JID& roomJid, const JID& peerId) { + auto roomInfo = findRoom(qstring(roomJid.bare())); + if (!roomInfo) { + return false; + } - roomInfo->room->invite(peerId, ""); - return true; + roomInfo->room->invite(peerId, ""); + return true; } -const IMRoomInfo *IM::findRoom(const QString &groupId) const { - auto it = m_roomMap.find(groupId); - if (it == m_roomMap.end()) { - qWarning() << "Unable find room" << groupId; - return nullptr; - } - return &(it.value()); +const IMRoomInfo* IM::findRoom(const QString& groupId) const { + auto it = m_roomMap.find(groupId); + if (it == m_roomMap.end()) { + qWarning() << "Unable find room" << groupId; + return nullptr; + } + return &(it.value()); } -void IM::joinRoom(MUCRoom *room) { - room->setNick(stdstring(getNickname())); - room->join(); - room->getRoomInfo(); - _client->disco()->getDiscoItems(room->jid(), XMLNS_BOOKMARKS, this, DISCO_CTX_BOOKMARKS); +void IM::joinRoom(MUCRoom* room) { + room->setNick(stdstring(getNickname())); + room->join(); + room->getRoomInfo(); + _client->disco()->getDiscoItems(room->jid(), XMLNS_BOOKMARKS, this, DISCO_CTX_BOOKMARKS); } -void IM::cacheJoinRoom(const std::string &jid, const std::string &name) { - qDebug() << __func__ << qstring(jid) << qstring(name); +void IM::cacheJoinRoom(const std::string& jid, const std::string& name) { + qDebug() << __func__ << qstring(jid) << qstring(name); - JID roomJid(jid); - auto roomId = qstring(roomJid.bare()); - auto room = new MUCRoom(_client.get(), roomJid, this, this); - m_roomMap.insert(roomId, IMRoomInfo{room, {}}); + JID roomJid(jid); + auto roomId = qstring(roomJid.bare()); + auto room = new MUCRoom(_client.get(), roomJid, this, this); + m_roomMap.insert(roomId, IMRoomInfo{room, {}}); - qDebug() << "emit room:" << roomId; - emit groupReceived(roomId, name.empty() ? qstring(roomJid.username()) : qstring(name)); + qDebug() << "emit room:" << roomId; + emit groupReceived(roomId, name.empty() ? qstring(roomJid.username()) : qstring(name)); - // 查询成员列表 - // XMLNS_DISCO_ITEMS - getClient()->disco()->getDiscoItems(jid, XMLNS_DISCO_ITEMS, this, DISCO_CTX_CONF_MEMBERS); + // 查询成员列表 + // XMLNS_DISCO_ITEMS + getClient()->disco()->getDiscoItems(jid, XMLNS_DISCO_ITEMS, this, DISCO_CTX_CONF_MEMBERS); - joinRoom(room); + joinRoom(room); } -void IM::joinRoom(const QString &roomJid) { - qDebug() << "joinRoom" << roomJid; - qDebug() << "nick" << getNickname(); +void IM::joinRoom(const QString& roomJid) { + qDebug() << "joinRoom" << roomJid; + qDebug() << "nick" << getNickname(); - auto it = m_roomMap.find(roomJid); - if (it == m_roomMap.end()) { - qWarning() << "Unable find room from cache" << roomJid; - return; - } + auto it = m_roomMap.find(roomJid); + if (it == m_roomMap.end()) { + qWarning() << "Unable find room from cache" << roomJid; + return; + } - joinRoom(it.value().room); + joinRoom(it.value().room); } void IM::joinRooms() { - qDebug() << "joinRooms"; - for (const auto &item : m_roomMap) { - joinRoom(item.room); - } -} - -bool IM::sendToRoom(const QString &to, const QString &msg, const QString &id) { - qDebug() << __func__ << "=>" << to; - qDebug() << "msgId:" << id <<"content:" << msg; - - if(msg.isEmpty()){ - qWarning() <<"empty message!"; - return false; - } - - if(id.isEmpty()){ - qWarning() <<"id is empty!"; - return false; - } - - auto pRoomInfo = findRoom((to)); - if (!pRoomInfo) { - qWarning() << "The room is not exist!"; - return false; - } - - auto msgId = stdstring(id); - sendIds.insert(msgId); - return pRoomInfo->room->send(msg.toStdString(),msgId); -} - -void IM::setRoomSubject(const QString &groupId, const std::string &subject) { - auto room = findRoom(groupId); - if (room) { - room->room->setSubject(subject); - } -} - -void IM::setRoomName(const QString &groupId, const std::string &roomName) { - qDebug() << __func__ << groupId << roomName.c_str(); - const IMRoomInfo *pRoomInfo = findRoom(groupId); - if (!pRoomInfo) { - qDebug() << "room is not exist." << groupId; - return; - } - - auto info = const_cast(pRoomInfo); - info->changes.insert(std::make_pair("muc#roomconfig_roomname", roomName)); - // 获取新配置(handleMUCConfigForm处理) - info->room->requestRoomConfig(); -} - -void IM::setRoomAlias(const QString &groupId, const std::string &alias) { - qDebug() << __func__ << groupId << alias.c_str(); - // 修改书签列表 - bool update = false; - for (auto &item : mConferenceList) { - if (item.jid == groupId.toStdString()) { - item.name = alias; - update = true; - break; - } - } - // 存储书签列表 - if (update) { - bookmarkStorage->storeBookmarks(mBookmarkList, mConferenceList); - qDebug() << "Store the bookmarks:" << groupId; - } + qDebug() << "joinRooms"; + for (const auto& item : m_roomMap) { + joinRoom(item.room); + } } -void IM::setRoomDesc(const QString &groupId, const std::string &desc) { - qDebug() << __func__ << groupId << desc.c_str(); - const IMRoomInfo *pRoomInfo = findRoom(groupId); - if (!pRoomInfo) { - qDebug() << "room is not exist." << groupId; - return; - } +bool IM::sendToRoom(const QString& to, const QString& msg, const QString& id) { + qDebug() << __func__ << "=>" << to; + qDebug() << "msgId:" << id << "content:" << msg; + + if (msg.isEmpty()) { + qWarning() << "empty message!"; + return false; + } + + if (id.isEmpty()) { + qWarning() << "id is empty!"; + return false; + } + + auto pRoomInfo = findRoom((to)); + if (!pRoomInfo) { + qWarning() << "The room is not exist!"; + return false; + } + + auto msgId = stdstring(id); + sendIds.insert(msgId); + return pRoomInfo->room->send(msg.toStdString(), msgId); +} + +void IM::setRoomSubject(const QString& groupId, const std::string& subject) { + auto room = findRoom(groupId); + if (room) { + room->room->setSubject(subject); + } +} + +void IM::setRoomName(const QString& groupId, const std::string& roomName) { + qDebug() << __func__ << groupId << roomName.c_str(); + const IMRoomInfo* pRoomInfo = findRoom(groupId); + if (!pRoomInfo) { + qDebug() << "room is not exist." << groupId; + return; + } + + auto info = const_cast(pRoomInfo); + info->changes.insert(std::make_pair("muc#roomconfig_roomname", roomName)); + // 获取新配置(handleMUCConfigForm处理) + info->room->requestRoomConfig(); +} + +void IM::setRoomAlias(const QString& groupId, const std::string& alias) { + qDebug() << __func__ << groupId << alias.c_str(); + // 修改书签列表 + bool update = false; + for (auto& item : mConferenceList) { + if (item.jid == groupId.toStdString()) { + item.name = alias; + update = true; + break; + } + } + // 存储书签列表 + if (update) { + bookmarkStorage->storeBookmarks(mBookmarkList, mConferenceList); + qDebug() << "Store the bookmarks:" << groupId; + } +} + +void IM::setRoomDesc(const QString& groupId, const std::string& desc) { + qDebug() << __func__ << groupId << desc.c_str(); + const IMRoomInfo* pRoomInfo = findRoom(groupId); + if (!pRoomInfo) { + qDebug() << "room is not exist." << groupId; + return; + } - auto info = const_cast(pRoomInfo); - info->changes.insert(std::make_pair("muc#roomconfig_roomdesc", desc)); - // 获取新配置(handleMUCConfigForm处理) - info->room->requestRoomConfig(); + auto info = const_cast(pRoomInfo); + info->changes.insert(std::make_pair("muc#roomconfig_roomdesc", desc)); + // 获取新配置(handleMUCConfigForm处理) + info->room->requestRoomConfig(); } #ifdef WANT_PING -void IM::handlePing(const gloox::PingHandler::PingType type, const std::string &body) { - qDebug() << "ping" << type << qstring(body); - if (type != websocketPong) { - IQ iq(IQ::IqType::Result, JID(_host.toStdString())); - _client->send(iq); - } +void IM::handlePing(const gloox::PingHandler::PingType type, const std::string& body) { + qDebug() << "ping" << type << qstring(body); + if (type != websocketPong) { + IQ iq(IQ::IqType::Result, JID(_host.toStdString())); + _client->send(iq); + } } #endif @@ -1247,53 +1236,53 @@ void IM::handlePing(const gloox::PingHandler::PingType type, const std::string & * @param jid * @param vcard */ -void IM::handleVCard(const JID &jid, const VCard *vcard) { - qDebug() << __func__ << QString("jid:%1").arg(qstring(jid.full())); +void IM::handleVCard(const JID& jid, const VCard* vcard) { + qDebug() << __func__ << QString("jid:%1").arg(qstring(jid.full())); - auto &photo = vcard->photo(); - if (!photo.binval.empty()) { - qDebug() << QString("photo binval size:%1").arg(photo.binval.size()); - emit receiveFriendAvatarChanged(qstring(jid.bare()), photo.binval); - } + auto& photo = vcard->photo(); + if (!photo.binval.empty()) { + qDebug() << QString("photo binval size:%1").arg(photo.binval.size()); + emit receiveFriendAvatarChanged(qstring(jid.bare()), photo.binval); + } - // auto &nickname = vcard->nickname(); - // if (!nickname.empty()) { - // qDebug()<nickname(); + // if (!nickname.empty()) { + // qDebug()<fetchVCard(jid, this); - // pubSubManager->subscribe(jid, "", this); - // _client->rosterManager()->subscribe(jid.bareJID()); +void IM::fetchFriendVCard(const QString& friendId) { + // 获取联系人个人信息 + qDebug() << "fetchVCard" << friendId; + JID jid(stdstring(friendId)); + vCardManager->fetchVCard(jid, this); + // pubSubManager->subscribe(jid, "", this); + // _client->rosterManager()->subscribe(jid.bareJID()); } -void IM::handleTag(Tag *tag) { qDebug() << QString("tag:%1").arg(qstring(tag->xml())); } +void IM::handleTag(Tag* tag) { qDebug() << QString("tag:%1").arg(qstring(tag->xml())); } -bool IM::handleIq(const IQ &iq) { - emit incoming(qstring(iq.tag()->xml())); - return true; +bool IM::handleIq(const IQ& iq) { + emit incoming(qstring(iq.tag()->xml())); + return true; } -void IM::handleIqID(const IQ &iq, int context) {} +void IM::handleIqID(const IQ& iq, int context) {} void IM::requestBookmarks() { - /** - * bookmark - */ - bookmarkStorage->registerBookmarkHandler(this); - bookmarkStorage->requestBookmarks(); + /** + * bookmark + */ + bookmarkStorage->registerBookmarkHandler(this); + bookmarkStorage->requestBookmarks(); } /** @@ -1301,53 +1290,53 @@ void IM::requestBookmarks() { * @param bList * @param cList */ -void IM::handleBookmarks(const BookmarkList &bList, // - const ConferenceList &cList) // +void IM::handleBookmarks(const BookmarkList& bList, // + const ConferenceList& cList) // { - qDebug() << __func__; - qDebug() << "ConferenceList:" << cList.size(); - qDebug() << "BookmarkList:" << bList.size(); - - // 缓存群聊书签列表(新增加群聊加入该书签一起保存) - mConferenceList = cList; - - for (auto &c : cList) { - auto name = (!c.name.empty() ? c.name : JID(c.jid).username()); - qDebug() << "room:" << qstring(name) << "jid:" << qstring(c.jid) << "nick:" << qstring(c.nick) << "autojoin:" << c.autojoin; - // 缓存到本地 - cacheJoinRoom(c.jid, name); - } + qDebug() << __func__; + qDebug() << "ConferenceList:" << cList.size(); + qDebug() << "BookmarkList:" << bList.size(); + + // 缓存群聊书签列表(新增加群聊加入该书签一起保存) + mConferenceList = cList; + + for (auto& c : cList) { + auto name = (!c.name.empty() ? c.name : JID(c.jid).username()); + qDebug() << "room:" << qstring(name) << "jid:" << qstring(c.jid) + << "nick:" << qstring(c.nick) << "autojoin:" << c.autojoin; + // 缓存到本地 + cacheJoinRoom(c.jid, name); + } - mBookmarkList = bList; - for (auto &c : mBookmarkList) { - qDebug() << "Bookmark name:" << qstring(c.name) << "url:" << qstring(c.url); - } + mBookmarkList = bList; + for (auto& c : mBookmarkList) { + qDebug() << "Bookmark name:" << qstring(c.name) << "url:" << qstring(c.url); + } } -void IM::handleBookmarks(const BMConferenceList &cList) { - qDebug() << __func__; - for (const auto &conf : cList) { - qDebug() << "conference:" << qstring(conf.jid); - } +void IM::handleBookmarks(const BMConferenceList& cList) { + qDebug() << __func__; + for (const auto& conf : cList) { + qDebug() << "conference:" << qstring(conf.jid); + } } // Disco handler -void IM::handleDiscoInfo(const JID &from, // - const Disco::Info &info, // +void IM::handleDiscoInfo(const JID& from, // + const Disco::Info& info, // int context) { + QString _from = QString::fromStdString(from.full()); + qDebug() << __func__ << _from << "context:" << (context); - QString _from = QString::fromStdString(from.full()); - qDebug() << __func__ << _from << "context:" << (context); - - const StringList features = info.features(); - for (auto feature : features) { - qDebug() << QString("feature=%1").arg(QString::fromStdString(feature)); - } + const StringList features = info.features(); + for (auto feature : features) { + qDebug() << QString("feature=%1").arg(QString::fromStdString(feature)); + } - const Disco::IdentityList &identities = info.identities(); - for (auto identity : identities) { - qDebug() << QString("identity=%1").arg(qstring(identity->name())); - } + const Disco::IdentityList& identities = info.identities(); + for (auto identity : identities) { + qDebug() << QString("identity=%1").arg(qstring(identity->name())); + } } /** @@ -1356,53 +1345,54 @@ void IM::handleDiscoInfo(const JID &from, // * @param items * @param context */ -void IM::handleDiscoItems(const JID &from, // - const Disco::Items &items, // +void IM::handleDiscoItems(const JID& from, // + const Disco::Items& items, // int context) { + QString _from = QString::fromStdString(from.full()); + qDebug() << __func__ << "from" << _from << "context" << context; - QString _from = QString::fromStdString(from.full()); - qDebug() << __func__ << "from" << _from << "context" << context; - - const Disco::ItemList &localItems = items.items(); - for (auto item : localItems) { - - if (context == DISCO_CTX_ROSTER) { - pubSubManager->subscribe(item->jid(), XMLNS_NICKNAME, this); + const Disco::ItemList& localItems = items.items(); + for (auto item : localItems) { + if (context == DISCO_CTX_ROSTER) { + pubSubManager->subscribe(item->jid(), XMLNS_NICKNAME, this); #ifndef Q_OS_WIN - pubSubManager->subscribe(item->jid(), XMLNS_AVATAR, this); -#endif // !Q_OS_WIN - } + pubSubManager->subscribe(item->jid(), XMLNS_AVATAR, this); +#endif // !Q_OS_WIN + } - else if (context == DISCO_CTX_CONF) { - /** - * 处理服务发现的群聊列表 - */ - auto roomId = qstring(item->jid().bare()); - auto name = qstring(item->name()); - qDebug() << "room:" << name << roomId; - } + else if (context == DISCO_CTX_CONF) { + /** + * 处理服务发现的群聊列表 + */ + auto roomId = qstring(item->jid().bare()); + auto name = qstring(item->name()); + qDebug() << "room:" << name << roomId; + } - else if (context == DISCO_CTX_CONF_MEMBERS) { - // 群聊成员 - auto memberId = qstring(item->jid().bare()); - qDebug() << "member:" << memberId; + else if (context == DISCO_CTX_CONF_MEMBERS) { + // 群聊成员 + auto memberId = qstring(item->jid().bare()); + qDebug() << "member:" << memberId; + } } - } } -void IM::handleDiscoError(const JID &from, // - const gloox::Error *error, // +void IM::handleDiscoError(const JID& from, // + const gloox::Error* error, // int context) { - - QString _from = qstring(from.full()); - qDebug() << QString("from=%1 context=%2 error=%3").arg(_from).arg(context).arg(qstring(error->text())); + QString _from = qstring(from.full()); + qDebug() << QString("from=%1 context=%2 error=%3") + .arg(_from) + .arg(context) + .arg(qstring(error->text())); } // Presence Handler -void IM::handlePresence(const Presence &presence) { - qDebug() << __func__ << "from" << qstring(presence.from().full()) << "presence" << presence.presence(); +void IM::handlePresence(const Presence& presence) { + qDebug() << __func__ << "from" << qstring(presence.from().full()) << "presence" + << presence.presence(); - updateOnlineStatus(presence.from().bare(), presence.from().resource(), presence.presence()); + updateOnlineStatus(presence.from().bare(), presence.from().resource(), presence.presence()); } /** @@ -1414,155 +1404,156 @@ void IM::handlePresence(const Presence &presence) { * @param jid * @return */ -void IM::handleItemAdded(const gloox::JID &jid) { - qDebug() << __func__ << qstring(jid.full()); +void IM::handleItemAdded(const gloox::JID& jid) { + qDebug() << __func__ << qstring(jid.full()); - auto m = _client->rosterManager(); - // 订阅对方 - m->subscribe(jid); + auto m = _client->rosterManager(); + // 订阅对方 + m->subscribe(jid); - auto item = m->getRosterItem(jid); - if (!item) { - qWarning() << "Unable to find roster."; - return; - } - emit receiveFriend(IMFriend{item}); + auto item = m->getRosterItem(jid); + if (!item) { + qWarning() << "Unable to find roster."; + return; + } + emit receiveFriend(IMFriend{item}); } /** * 好友被删除事件 * @param jid */ -void IM::handleItemRemoved(const JID &jid) { - qDebug() << __func__ << qstring(jid.full()); - emit receiveFriendRemoved(qstring(jid.bare())); +void IM::handleItemRemoved(const JID& jid) { + qDebug() << __func__ << qstring(jid.full()); + emit receiveFriendRemoved(qstring(jid.bare())); } // 好友更新 -void IM::handleItemUpdated(const JID &jid) { - qDebug() << __func__ << qstring(jid.full()); +void IM::handleItemUpdated(const JID& jid) { + qDebug() << __func__ << qstring(jid.full()); - auto contactId = qstring(jid.bare()); + auto contactId = qstring(jid.bare()); - auto item = _client->rosterManager()->getRosterItem(jid); - auto subType = item->subscription(); - qDebug() << __func__ << "subscription:" << (subType); - auto data = item->data(); - qDebug() << "ask" << qstring(data->ask()) << "sub" << qstring(data->sub()); + auto item = _client->rosterManager()->getRosterItem(jid); + auto subType = item->subscription(); + qDebug() << __func__ << "subscription:" << (subType); + auto data = item->data(); + qDebug() << "ask" << qstring(data->ask()) << "sub" << qstring(data->sub()); - if (data->sub() == "both") { - qDebug() << "建立订阅双向关联"; - emit receiveFriendAliasChanged(jid, data->name()); - } + if (data->sub() == "both") { + qDebug() << "建立订阅双向关联"; + emit receiveFriendAliasChanged(jid, data->name()); + } } /** * 订阅好友 * @param jid */ -void IM::handleItemSubscribed(const JID &jid) { qDebug() << __func__ << qstring(jid.full()); } +void IM::handleItemSubscribed(const JID& jid) { qDebug() << __func__ << qstring(jid.full()); } /** * 取消订阅好友 * @param jid */ -void IM::handleItemUnsubscribed(const JID &jid) { qDebug() << __func__ << qstring(jid.full()); } +void IM::handleItemUnsubscribed(const JID& jid) { qDebug() << __func__ << qstring(jid.full()); } -bool IM::removeFriend(const JID &jid) { - qDebug() << __func__ << jid.full().c_str(); +bool IM::removeFriend(const JID& jid) { + qDebug() << __func__ << jid.full().c_str(); - /** - * 参考:https://datatracker.ietf.org/doc/html/rfc3921#section-8.4.2 - */ - auto m = _client->rosterManager(); - // 取消订阅 - m->unsubscribe(jid); - // 从联系人列表移除 - m->remove(jid); - return true; -} - -void IM::addFriend(const JID &jid, const QString &nick, const QString &msg) { - qDebug() << __func__ << jid.full().c_str() << nick << msg; - - auto m = _client->rosterManager(); - auto f = m->getRosterItem(jid); - if (f) { - qWarning() << "IMFriend is existing!"; - return; - } - // 订阅对方(同时加入到联系人列表) - m->subscribe(jid, stdstring(nick), {}); - m->add(jid, stdstring(nick), {}); - m->synchronize(); + /** + * 参考:https://datatracker.ietf.org/doc/html/rfc3921#section-8.4.2 + */ + auto m = _client->rosterManager(); + // 取消订阅 + m->unsubscribe(jid); + // 从联系人列表移除 + m->remove(jid); + return true; +} + +void IM::addFriend(const JID& jid, const QString& nick, const QString& msg) { + qDebug() << __func__ << jid.full().c_str() << nick << msg; + + auto m = _client->rosterManager(); + auto f = m->getRosterItem(jid); + if (f) { + qWarning() << "IMFriend is existing!"; + return; + } + // 订阅对方(同时加入到联系人列表) + m->subscribe(jid, stdstring(nick), {}); + m->add(jid, stdstring(nick), {}); + m->synchronize(); } -void IM::acceptFriendRequest(const QString &friendId) { - qDebug() << __func__ << friendId; - auto jid = JID(stdstring(friendId)).bareJID(); +void IM::acceptFriendRequest(const QString& friendId) { + qDebug() << __func__ << friendId; + auto jid = JID(stdstring(friendId)).bareJID(); - auto m = _client->rosterManager(); - // 答复同意订阅 - m->ackSubscriptionRequest(jid, true); - // 同时订阅对方 - m->subscribe(jid); - // 添加到联系人列表 - m->add(jid, {}, {}); - m->synchronize(); + auto m = _client->rosterManager(); + // 答复同意订阅 + m->ackSubscriptionRequest(jid, true); + // 同时订阅对方 + m->subscribe(jid); + // 添加到联系人列表 + m->add(jid, {}, {}); + m->synchronize(); } -void IM::rejectFriendRequest(const QString &friendId) { - qDebug() << __func__ << friendId; - _client->rosterManager()->ackSubscriptionRequest(JID(stdstring(friendId)).bareJID(), false); +void IM::rejectFriendRequest(const QString& friendId) { + qDebug() << __func__ << friendId; + _client->rosterManager()->ackSubscriptionRequest(JID(stdstring(friendId)).bareJID(), false); } size_t IM::getRosterCount() { return _client->rosterManager()->roster()->size(); } -void IM::getRosterList(std::list &list) { - auto rosterManager = _client->rosterManager(); - if (!rosterManager) { - QMutexLocker locker(&m_mutex); - rosterManager = enableRosterManager(); - } +void IM::getRosterList(std::list& list) { + auto rosterManager = _client->rosterManager(); + if (!rosterManager) { + QMutexLocker locker(&m_mutex); + rosterManager = enableRosterManager(); + } - gloox::Roster *rosterMap = rosterManager->roster(); - for (const auto &itr : *rosterMap) { - auto pItem = itr.second; - list.push_back(IMFriend{pItem}); - } + gloox::Roster* rosterMap = rosterManager->roster(); + for (const auto& itr : *rosterMap) { + auto pItem = itr.second; + list.push_back(IMFriend{pItem}); + } } -void IM::setFriendAlias(const JID &jid, const std::string &alias) { - qDebug() << __func__ << jid.bare().c_str() << alias.c_str(); +void IM::setFriendAlias(const JID& jid, const std::string& alias) { + qDebug() << __func__ << jid.bare().c_str() << alias.c_str(); - auto m = _client->rosterManager(); + auto m = _client->rosterManager(); - // 保存联系人 - m->add(jid.bareJID(), alias, {}); - m->synchronize(); + // 保存联系人 + m->add(jid.bareJID(), alias, {}); + m->synchronize(); } -void IM::handleRoster(const Roster &roster) { - qDebug() << __func__ << "size:" << roster.size(); +void IM::handleRoster(const Roster& roster) { + qDebug() << __func__ << "size:" << roster.size(); - for (auto &it : roster) { - auto &key = it.first; - auto &item = it.second; + for (auto& it : roster) { + auto& key = it.first; + auto& item = it.second; - qDebug() << "roster" << item->jid().full().c_str() << "subscription" << item->subscription(); - if (item->jid().server().empty()) { - qWarning() << "Ignore roster whithout server."; - continue; - } + qDebug() << "roster" << item->jid().full().c_str() << "subscription" + << item->subscription(); + if (item->jid().server().empty()) { + qWarning() << "Ignore roster whithout server."; + continue; + } - auto frnd = IMFriend{item}; - emit receiveFriend(frnd); + auto frnd = IMFriend{item}; + emit receiveFriend(frnd); - // Subscription sub(gloox::Subscription::Subscribe, jid); - // _client->send(sub); - } - // enableDiscoManager(); - // loadGroupList(); + // Subscription sub(gloox::Subscription::Subscribe, jid); + // _client->send(sub); + } + // enableDiscoManager(); + // loadGroupList(); }; /** @@ -1573,99 +1564,102 @@ void IM::handleRoster(const Roster &roster) { * @param msg * @return */ -void IM::handleRosterPresence(const RosterItem &item, // - const std::string &resource, // - Presence::PresenceType presenceType, // - const std::string &msg) { - - qDebug() << QString("item:%1 resource:%2 presenceType:%3 msg:%4").arg(qstring(item.jid().full())).arg(qstring(resource)).arg(presenceType).arg(qstring(msg)); - - updateOnlineStatus(item.jid().bare(), resource, presenceType); - - // if (presenceType == gloox::Presence::Available) { - for (auto &it : item.resources()) { - auto sk = it.first; - auto sr = it.second; - for (auto &ext : sr->extensions()) { - switch (ext->extensionType()) { - // case ExtCaps: { - // auto caps = const_cast( - // static_cast(ext)); - // qDebug()<node()))) - // break; - // } - case ExtVCardUpdate: { - // VCard个人信息更新 - /** - * - - - - - */ - auto vCardUpdate = const_cast(static_cast(ext)); - if (vCardUpdate && vCardUpdate->hasPhoto()) { - - ItemList items; - Item *item0 = new Item(); - item0->setID(vCardUpdate->hash()); - items.emplace_back(item0); - - pubSubManager->requestItems(item.jid(), XMLNS_AVATAR, "", items, this); +void IM::handleRosterPresence(const RosterItem& item, // + const std::string& resource, // + Presence::PresenceType presenceType, // + const std::string& msg) { + qDebug() << QString("item:%1 resource:%2 presenceType:%3 msg:%4") + .arg(qstring(item.jid().full())) + .arg(qstring(resource)) + .arg(presenceType) + .arg(qstring(msg)); + + updateOnlineStatus(item.jid().bare(), resource, presenceType); + + // if (presenceType == gloox::Presence::Available) { + for (auto& it : item.resources()) { + auto sk = it.first; + auto sr = it.second; + for (auto& ext : sr->extensions()) { + switch (ext->extensionType()) { + // case ExtCaps: { + // auto caps = const_cast( + // static_cast(ext)); + // qDebug()<node()))) + // break; + // } + case ExtVCardUpdate: { + // VCard个人信息更新 + /** + * + + + + + */ + auto vCardUpdate = + const_cast(static_cast(ext)); + if (vCardUpdate && vCardUpdate->hasPhoto()) { + ItemList items; + Item* item0 = new Item(); + item0->setID(vCardUpdate->hash()); + items.emplace_back(item0); + + pubSubManager->requestItems(item.jid(), XMLNS_AVATAR, "", items, this); + } + break; + } + } } - break; - } - } } - } - // } -} - -void IM::handleSelfPresence(const RosterItem &item, // - const std::string &resource, // - Presence::PresenceType presenceType, // - const std::string &msg) { - - qDebug() << QString("item:%1 resource:%2 presenceType:%3 msg:%4") // - .arg(qstring(item.jid().full())) // - .arg(qstring(resource)) // - .arg(presenceType) // - .arg(qstring(msg)); - - auto st = _client->resource() == resource ? presenceType : (int)gloox::Presence::Available; - - emit selfStatusChanged(st, msg); - - // if (presenceType == gloox::Presence::Available) { - for (auto &it : item.resources()) { - auto sk = it.first; - auto sr = it.second; - for (auto &ext : sr->extensions()) { - switch (ext->extensionType()) { - case ExtVCardUpdate: { - // VCard个人信息更新 - /** - * - - - - - */ - auto vCardUpdate = const_cast(static_cast(ext)); - if (vCardUpdate && vCardUpdate->hasPhoto()) { - - ItemList items; - Item *item0 = new Item(); - item0->setID(vCardUpdate->hash()); - items.emplace_back(item0); - - pubSubManager->requestItems(item.jid().bareJID(), XMLNS_AVATAR, "", items, this); + // } +} + +void IM::handleSelfPresence(const RosterItem& item, // + const std::string& resource, // + Presence::PresenceType presenceType, // + const std::string& msg) { + qDebug() << QString("item:%1 resource:%2 presenceType:%3 msg:%4") // + .arg(qstring(item.jid().full())) // + .arg(qstring(resource)) // + .arg(presenceType) // + .arg(qstring(msg)); + + auto st = _client->resource() == resource ? presenceType : (int)gloox::Presence::Available; + + emit selfStatusChanged(st, msg); + + // if (presenceType == gloox::Presence::Available) { + for (auto& it : item.resources()) { + auto sk = it.first; + auto sr = it.second; + for (auto& ext : sr->extensions()) { + switch (ext->extensionType()) { + case ExtVCardUpdate: { + // VCard个人信息更新 + /** + * + + + + + */ + auto vCardUpdate = + const_cast(static_cast(ext)); + if (vCardUpdate && vCardUpdate->hasPhoto()) { + ItemList items; + Item* item0 = new Item(); + item0->setID(vCardUpdate->hash()); + items.emplace_back(item0); + + pubSubManager->requestItems(item.jid().bareJID(), XMLNS_AVATAR, "", items, + this); + } + break; + } + } } - break; - } - } } - } }; /** @@ -1674,14 +1668,14 @@ void IM::handleSelfPresence(const RosterItem &item, // * @param msg * @return */ -bool IM::handleSubscriptionRequest(const JID &jid, const std::string &msg) { - qDebug() << __func__ << qstring(jid.full()) << qstring(msg); - // emit receiveFriendRequest(qstring(jid.bare()), qstring(msg)); - auto m = _client->rosterManager(); - // 订阅对方 - // m->add(jid.bareJID(), jid.username(), {}); - m->subscribe(jid.bareJID(), jid.username(), {}, {}); - return true; +bool IM::handleSubscriptionRequest(const JID& jid, const std::string& msg) { + qDebug() << __func__ << qstring(jid.full()) << qstring(msg); + // emit receiveFriendRequest(qstring(jid.bare()), qstring(msg)); + auto m = _client->rosterManager(); + // 订阅对方 + // m->add(jid.bareJID(), jid.username(), {}); + m->subscribe(jid.bareJID(), jid.username(), {}, {}); + return true; }; /** @@ -1690,31 +1684,36 @@ bool IM::handleSubscriptionRequest(const JID &jid, const std::string &msg) { * @param msg * @return */ -bool IM::handleUnsubscriptionRequest(const JID &jid, const std::string &msg) { - qDebug() << QString("jid:%1 msg:%2").arg(qstring(jid.full())).arg(qstring(msg)); - return true; +bool IM::handleUnsubscriptionRequest(const JID& jid, const std::string& msg) { + qDebug() << QString("jid:%1 msg:%2").arg(qstring(jid.full())).arg(qstring(msg)); + return true; }; -void IM::handleNonrosterPresence(const Presence &presence) { qDebug() << QString("presence:%1").arg(qstring(presence.from().full())); }; +void IM::handleNonrosterPresence(const Presence& presence) { + qDebug() << QString("presence:%1").arg(qstring(presence.from().full())); +}; -void IM::handleRosterError(const IQ &iq) { qDebug() << QString("text:%1").arg(qstring(iq.error()->text())); }; +void IM::handleRosterError(const IQ& iq) { + qDebug() << QString("text:%1").arg(qstring(iq.error()->text())); +}; -void IM::handleRosterItemExchange(const gloox::JID &from, const gloox::RosterX *items) {} +void IM::handleRosterItemExchange(const gloox::JID& from, const gloox::RosterX* items) {} -void IM::handleRegistrationFields(const JID &from, int fields, std::string instructions) {}; +void IM::handleRegistrationFields(const JID& from, int fields, std::string instructions) {}; /** * This function is called if @ref Registration::createAccount() was called on * an authenticated stream and the server lets us know about this. */ -void IM::handleAlreadyRegistered(const JID &from) {}; +void IM::handleAlreadyRegistered(const JID& from) {}; /** * This funtion is called to notify about the result of an operation. * @param from The server or service the result came from. * @param regResult The result of the last operation. */ -void IM::handleRegistrationResult(const JID &from, RegistrationResult regResult, const Error *error) {}; +void IM::handleRegistrationResult(const JID& from, RegistrationResult regResult, + const Error* error) {}; /** * This function is called additionally to @ref handleRegistrationFields() if @@ -1722,7 +1721,7 @@ void IM::handleRegistrationResult(const JID &from, RegistrationResult regResult, * @param from The server or service the data form came from. * @param form The DataForm containing registration information. */ -void IM::handleDataForm(const JID &from, const DataForm &form) {}; +void IM::handleDataForm(const JID& from, const DataForm& form) {}; /** * This function is called if the server does not offer in-band registration @@ -1730,446 +1729,468 @@ void IM::handleDataForm(const JID &from, const DataForm &form) {}; * @param from The server or service the referal came from. * @param oob The OOB object describing the external URL. */ -void IM::handleOOB(const JID &from, const OOB &oob) {}; +void IM::handleOOB(const JID& from, const OOB& oob) {}; IMContactId IM::getSelfId() { - IMContactId fId(qstring(_client->jid().bare())); - return fId; + IMContactId fId(qstring(_client->jid().bare())); + return fId; } IMPeerId IM::getSelfPeerId() { - return IMPeerId(qstring(_client->jid().full())); - ; + return IMPeerId(qstring(_client->jid().full())); + ; } QString IM::getSelfUsername() { return qstring(self().username()); } -void IM::setNickname(const QString &nickname) { - qDebug() << QString("nickname:%1").arg(nickname); - if (_nick == nickname) { - return; - } - _nick = nickname; +void IM::setNickname(const QString& nickname) { + qDebug() << QString("nickname:%1").arg(nickname); + if (_nick == nickname) { + return; + } + _nick = nickname; - gloox::Nickname nick(nickname.toStdString()); + gloox::Nickname nick(nickname.toStdString()); - ItemList items; - Item *item = new Item(); - item->setID("current"); - item->setPayload(nick.tag()); - items.emplace_back(item); + ItemList items; + Item* item = new Item(); + item->setID("current"); + item->setPayload(nick.tag()); + items.emplace_back(item); - pubSubManager->publishItem(JID(), XMLNS_NICKNAME, items, nullptr, this); + pubSubManager->publishItem(JID(), XMLNS_NICKNAME, items, nullptr, this); } QString IM::getNickname() { - if (!_nick.isEmpty()) { - return _nick; - } - return getSelfUsername(); + if (!_nick.isEmpty()) { + return _nick; + } + return getSelfUsername(); } -void IM::setAvatar(const QByteArray &avatar) { - if (avatar.isEmpty()) - return; +void IM::setAvatar(const QByteArray& avatar) { + if (avatar.isEmpty()) return; - QString sha1 = lib::base::Hashs::sha1(avatar); - qDebug() << QString("avatar size:%1 sha1:%2").arg(avatar.size()).arg(sha1); + QString sha1 = lib::base::Hashs::sha1(avatar); + qDebug() << QString("avatar size:%1 sha1:%2").arg(avatar.size()).arg(sha1); - auto base64 = avatar.toBase64().toStdString(); + auto base64 = avatar.toBase64().toStdString(); - /** - * -qANQR1DBwU4DX7jmYZnncm... - - */ - std::string payload; - int pos = 0; - do { - if (base64.size() <= pos) { - // std::remove(payload.begin(), payload.end(), payload.size()-1); - break; - } - std::string line = base64.substr(pos, 76); - payload += line + "\n"; - pos += 76; - } while (true); + /** + * + qANQR1DBwU4DX7jmYZnncm... + + */ + std::string payload; + int pos = 0; + do { + if (base64.size() <= pos) { + // std::remove(payload.begin(), payload.end(), payload.size()-1); + break; + } + std::string line = base64.substr(pos, 76); + payload += line + "\n"; + pos += 76; + } while (true); - AvatarData avt(payload); + AvatarData avt(payload); - ItemList items; - Item *item = new Item(); - item->setID(sha1.toStdString()); - item->setPayload(avt.tag()); - items.emplace_back(item); + ItemList items; + Item* item = new Item(); + item->setID(sha1.toStdString()); + item->setPayload(avt.tag()); + items.emplace_back(item); - pubSubManager->publishItem(JID(), XMLNS_AVATAR, items, nullptr, this); + pubSubManager->publishItem(JID(), XMLNS_AVATAR, items, nullptr, this); } -void IM::changePassword(const QString &password) { - qDebug() << QString("password:%1").arg(password); - if (password.isEmpty()) - return; +void IM::changePassword(const QString& password) { + qDebug() << QString("password:%1").arg(password); + if (password.isEmpty()) return; - // changing password - mRegistration->changePassword(_client->username(), stdstring(password)); + // changing password + mRegistration->changePassword(_client->username(), stdstring(password)); } void IM::loadGroupList() { - auto disco = _client->disco(); - disco->getDiscoItems(JID(XMPP_CONF_SERVER_HOST), "", this, DISCO_CTX_CONF); - requestBookmarks(); + auto disco = _client->disco(); + disco->getDiscoItems(JID(XMPP_CONF_SERVER_HOST), "", this, DISCO_CTX_CONF); + requestBookmarks(); - /** - * openfire 服务器暂时不支持 - * m_nativeBookmark->retrievesAll(); - */ + /** + * openfire 服务器暂时不支持 + * m_nativeBookmark->retrievesAll(); + */ - loadRosterInfo(); + loadRosterInfo(); } void IM::loadRosterInfo() { - _client->disco()->getDiscoItems(self().bareJID(), "", this, DISCO_CTX_ROSTER); - auto m = _client->rosterManager()->roster(); - for (auto it = m->begin(); it != m->end(); it++) { - msleep(100); - _client->disco()->getDiscoItems(it->first, "", this, DISCO_CTX_ROSTER); - } + _client->disco()->getDiscoItems(self().bareJID(), "", this, DISCO_CTX_ROSTER); + auto m = _client->rosterManager()->roster(); + for (auto it = m->begin(); it != m->end(); it++) { + msleep(100); + _client->disco()->getDiscoItems(it->first, "", this, DISCO_CTX_ROSTER); + } } void IM::sendPresence() { - // - Presence pres(Presence::PresenceType::Available, JID()); - pres.addExtension(new Capabilities); - _client->setPresence(); + // + Presence pres(Presence::PresenceType::Available, JID()); + pres.addExtension(new Capabilities); + _client->setPresence(); } -void IM::sendPresence(const JID &to, Presence::PresenceType type) { _client->setPresence(to, type, 0); } - -void IM::sendReceiptReceived(const QString &id, QString receiptNum) { +void IM::sendPresence(const JID& to, Presence::PresenceType type) { + _client->setPresence(to, type, 0); +} - // +void IM::sendReceiptReceived(const QString& id, QString receiptNum) { + // - Message m(gloox::Message::MessageType::Chat, JID(stdstring(id))); - m.setFrom(_client->jid()); + Message m(gloox::Message::MessageType::Chat, JID(stdstring(id))); + m.setFrom(_client->jid()); - m.addExtension(new Receipt(Receipt::ReceiptType::Received, receiptNum.toStdString())); + m.addExtension(new Receipt(Receipt::ReceiptType::Received, receiptNum.toStdString())); - _client->send(m); + _client->send(m); } void IM::sendServiceDiscoveryItems() { + auto tag = new Tag("query"); + tag->setXmlns(XMLNS_DISCO_ITEMS); - auto tag = new Tag("query"); - tag->setXmlns(XMLNS_DISCO_ITEMS); - - IQ *iq = new IQ(gloox::IQ::Get, self().server(), _client->getID()); - iq->setFrom(self()); + IQ* iq = new IQ(gloox::IQ::Get, self().server(), _client->getID()); + iq->setFrom(self()); - auto iqt = iq->tag(); - iqt->addChild(tag); - _client->send(iqt); + auto iqt = iq->tag(); + iqt->addChild(tag); + _client->send(iqt); } -void IM::sendServiceDiscoveryInfo(const JID &item) { +void IM::sendServiceDiscoveryInfo(const JID& item) { + auto tag = new Tag("query"); + tag->setXmlns(XMLNS_DISCO_INFO); - auto tag = new Tag("query"); - tag->setXmlns(XMLNS_DISCO_INFO); + IQ* iq = new IQ(gloox::IQ::Get, item, _client->getID()); + iq->setFrom(self()); - IQ *iq = new IQ(gloox::IQ::Get, item, _client->getID()); - iq->setFrom(self()); - - auto iqt = iq->tag(); - iqt->addChild(tag); - _client->send(iqt); + auto iqt = iq->tag(); + iqt->addChild(tag); + _client->send(iqt); } -void IM::handleItem(const JID &service, const std::string &node, const Tag *entry) { qDebug() << QString("service:%1 node:%2").arg(qstring(service.full())).arg(qstring(node)); } - -void IM::handleItems(const std::string &id, // - const JID &service, // - const std::string &node, // - const gloox::PubSub::ItemList &itemList, // - const gloox::Error *error) { +void IM::handleItem(const JID& service, const std::string& node, const Tag* entry) { + qDebug() << QString("service:%1 node:%2").arg(qstring(service.full())).arg(qstring(node)); +} - qDebug() << __func__ << qstring(service.full()) << (qstring(node)); +void IM::handleItems(const std::string& id, // + const JID& service, // + const std::string& node, // + const gloox::PubSub::ItemList& itemList, // + const gloox::Error* error) { + qDebug() << __func__ << qstring(service.full()) << (qstring(node)); - if (error) { - qWarning() << "error:" << error->tag()->xml().c_str(); - return; - } + if (error) { + qWarning() << "error:" << error->tag()->xml().c_str(); + return; + } - auto friendId = qstring(service.bare()); - auto isSelf = friendId == getSelfId().toString(); + auto friendId = qstring(service.bare()); + auto isSelf = friendId == getSelfId().toString(); - for (auto &item : itemList) { + for (auto& item : itemList) { + auto data = item->payload(); + auto tagName = data->name(); - auto data = item->payload(); - auto tagName = data->name(); + qDebug() << "handleItem:" << qstring(tagName) << qstring(node); - qDebug() << "handleItem:" << qstring(tagName) << qstring(node); + if (node == XMLNS_NICKNAME) { + gloox::Nickname nickname(data); + auto nick = qstring(nickname.nick()); + qDebug() << "nick:" << nick; + if (isSelf) + emit selfNicknameChanged(nick); + else { + emit receiveNicknameChange(friendId, nick); + } + } - if (node == XMLNS_NICKNAME) { - gloox::Nickname nickname(data); - auto nick = qstring(nickname.nick()); - qDebug() << "nick:" << nick; - if (isSelf) - emit selfNicknameChanged(nick); - else { - emit receiveNicknameChange(friendId, nick); - } + if (node == XMLNS_AVATAR) { + auto base64 = data->cdata(); + if (!base64.empty()) { + std::string::size_type pos = 0; + while ((pos = base64.find('\n')) != std::string::npos) base64.erase(pos, 1); + while ((pos = base64.find('\r')) != std::string::npos) base64.erase(pos, 1); + auto avt = Base64::decode64(base64); + if (isSelf) { + qDebug() << "Receive self avatar"; + emit selfAvatarChanged(avt); + } else { + qDebug() << "Receive friend avatar" << friendId; + emit receiveFriendAvatarChanged(friendId, avt); + } + } + } } +} +void IM::handleItemPublication(const std::string& id, // + const JID& service, // + const std::string& node, // + const ItemList& itemList, // + const gloox::Error* error) { + qDebug() << QString("node:%1").arg(qstring(node)); if (node == XMLNS_AVATAR) { - auto base64 = data->cdata(); - if (!base64.empty()) { - std::string::size_type pos = 0; - while ((pos = base64.find('\n')) != std::string::npos) - base64.erase(pos, 1); - while ((pos = base64.find('\r')) != std::string::npos) - base64.erase(pos, 1); - auto avt = Base64::decode64(base64); - if (isSelf) { - qDebug() << "Receive self avatar"; - emit selfAvatarChanged(avt); - } else { - qDebug() << "Receive friend avatar" << friendId; - emit receiveFriendAvatarChanged(friendId, avt); + // 更新头像元信息 + // https://xmpp.org/extensions/xep-0084.html#process-pubmeta + for (auto& item : itemList) { + qDebug() << QString("itemId:%1").arg(qstring(item->id())); } - } } - } } -void IM::handleItemPublication(const std::string &id, // - const JID &service, // - const std::string &node, // - const ItemList &itemList, // - const gloox::Error *error) { - qDebug() << QString("node:%1").arg(qstring(node)); - if (node == XMLNS_AVATAR) { - // 更新头像元信息 - // https://xmpp.org/extensions/xep-0084.html#process-pubmeta - for (auto &item : itemList) { - qDebug() << QString("itemId:%1").arg(qstring(item->id())); +void IM::handleItemDeletion(const std::string& id, const JID& service, const std::string& node, + const ItemList& itemList, const gloox::Error* error) { + qDebug() << QString("id:%1 service:%2").arg(qstring(id)).arg(qstring(service.full())); +} + +void IM::handleSubscriptionResult(const std::string& id, const JID& service, + const std::string& node, const std::string& sid, const JID& jid, + const gloox::PubSub::SubscriptionType subType, + const gloox::Error* error) { + qDebug() << QString("id:%1 jid:%2").arg(qstring(id)).arg(qstring(jid.full())); + pubSubManager->requestItems(service, node, sid, 100, this); +} + +void IM::handleUnsubscriptionResult(const std::string& id, const JID& service, + const gloox::Error* error) {} +void IM::handleSubscriptionOptions(const std::string& id, const JID& service, const JID& jid, + const std::string& node, const DataForm* options, + const std::string& sid, const gloox::Error* error) {} +void IM::handleSubscriptionOptionsResult(const std::string& id, const JID& service, const JID& jid, + const std::string& node, const std::string& sid, + const gloox::Error* error) {} +void IM::handleSubscribers(const std::string& id, const JID& service, const std::string& node, + const SubscriptionList& list, const gloox::Error* error) {} +void IM::handleSubscribersResult(const std::string& id, const JID& service, const std::string& node, + const SubscriberList* list, const gloox::Error* error) {} + +void IM::handleAffiliates(const std::string& id, const JID& service, const std::string& node, + const AffiliateList* list, const gloox::Error* error) {} + +void IM::handleAffiliatesResult(const std::string& id, const JID& service, const std::string& node, + const AffiliateList* list, const gloox::Error* error) {} +void IM::handleNodeConfig(const std::string& id, const JID& service, const std::string& node, + const DataForm* config, const gloox::Error* error) {} +void IM::handleNodeConfigResult(const std::string& id, const JID& service, const std::string& node, + const gloox::Error* error) {} +void IM::handleNodeCreation(const std::string& id, const JID& service, const std::string& node, + const gloox::Error* error) {} +void IM::handleNodeDeletion(const std::string& id, const JID& service, const std::string& node, + const gloox::Error* error) {} +void IM::handleNodePurge(const std::string& id, const JID& service, const std::string& node, + const gloox::Error* error) {} +void IM::handleSubscriptions(const std::string& id, const JID& service, + const SubscriptionMap& subMap, const gloox::Error* error) {} +void IM::handleAffiliations(const std::string& id, const JID& service, const AffiliationMap& affMap, + const gloox::Error* error) {} + +void IM::handleDefaultNodeConfig(const std::string& id, const JID& service, const DataForm* config, + const gloox::Error* error) { + Q_UNUSED(config); + qDebug() << QString("id:%1 service:%2 error:%3") + .arg(qstring(id)) + .arg(qstring(service.full())) + .arg(qstring(error->text())); +} + +std::string IM::getOnlineResource(const std::string& bare) { + auto it = onlineMap.find(bare); + if (it == onlineMap.end()) { + return std::string{}; + } + for (auto r : it->second) { + return r; } - } + return std::string{}; } -void IM::handleItemDeletion(const std::string &id, const JID &service, const std::string &node, const ItemList &itemList, const gloox::Error *error) { - qDebug() << QString("id:%1 service:%2").arg(qstring(id)).arg(qstring(service.full())); +std::set IM::getOnlineResources(const std::string& bare) { + auto it = onlineMap.find(bare); + if (it != onlineMap.end()) { + return it->second; + } + return {}; } -void IM::handleSubscriptionResult(const std::string &id, const JID &service, const std::string &node, const std::string &sid, const JID &jid, - const gloox::PubSub::SubscriptionType subType, const gloox::Error *error) { +void IM::updateOnlineStatus(const std::string& bare, const std::string& resource, + Presence::PresenceType presenceType) { + if (presenceType == Presence::Error) { + qWarning() << "Ignore error presence."; + return; + } + if (resource.empty()) { + qWarning() << "Ignore resource is empty."; + return; + } - qDebug() << QString("id:%1 jid:%2").arg(qstring(id)).arg(qstring(jid.full())); - pubSubManager->requestItems(service, node, sid, 100, this); + auto friendId = qstring(bare); + int status = -1; + + auto it = onlineMap.find(bare); + if (it == onlineMap.end()) { // 第一次 + if (presenceType != gloox::Presence::Unavailable) { + std::set resources; + resources.insert(resource); + onlineMap.emplace(bare, resources); + status = gloox::Presence::Available; + } + } else { // 第二次+ + std::set& resources = it->second; + if (presenceType != gloox::Presence::Unavailable) { + // multi online endpoint + resources.insert(resource); + onlineMap.emplace(bare, resources); + status = gloox::Presence::Available; + } else { + // one offline + resources.erase(resource); + if (resources.empty()) { + // all offline + onlineMap.erase(bare); + status = gloox::Presence::Unavailable; + } + } + } + emit receiveFriendStatus(friendId, status); } -void IM::handleUnsubscriptionResult(const std::string &id, const JID &service, const gloox::Error *error) {} -void IM::handleSubscriptionOptions(const std::string &id, const JID &service, const JID &jid, const std::string &node, const DataForm *options, const std::string &sid, - const gloox::Error *error) {} -void IM::handleSubscriptionOptionsResult(const std::string &id, const JID &service, const JID &jid, const std::string &node, const std::string &sid, const gloox::Error *error) {} -void IM::handleSubscribers(const std::string &id, const JID &service, const std::string &node, const SubscriptionList &list, const gloox::Error *error) {} -void IM::handleSubscribersResult(const std::string &id, const JID &service, const std::string &node, const SubscriberList *list, const gloox::Error *error) {} +void IM::retry() { doConnect(); } -void IM::handleAffiliates(const std::string &id, const JID &service, const std::string &node, const AffiliateList *list, const gloox::Error *error) {} +bool IM::leaveGroup(const QString& groupId) { + qDebug() << "leaveGroup" << groupId; + auto r = findRoom(groupId); + if (!r) { + qWarning() << "Unable to find room" << groupId; + return false; + } + r->room->leave(); -void IM::handleAffiliatesResult(const std::string &id, const JID &service, const std::string &node, const AffiliateList *list, const gloox::Error *error) {} -void IM::handleNodeConfig(const std::string &id, const JID &service, const std::string &node, const DataForm *config, const gloox::Error *error) {} -void IM::handleNodeConfigResult(const std::string &id, const JID &service, const std::string &node, const gloox::Error *error) {} -void IM::handleNodeCreation(const std::string &id, const JID &service, const std::string &node, const gloox::Error *error) {} -void IM::handleNodeDeletion(const std::string &id, const JID &service, const std::string &node, const gloox::Error *error) {} -void IM::handleNodePurge(const std::string &id, const JID &service, const std::string &node, const gloox::Error *error) {} -void IM::handleSubscriptions(const std::string &id, const JID &service, const SubscriptionMap &subMap, const gloox::Error *error) {} -void IM::handleAffiliations(const std::string &id, const JID &service, const AffiliationMap &affMap, const gloox::Error *error) {} + // 删除缓存 + m_roomMap.remove(groupId); -void IM::handleDefaultNodeConfig(const std::string &id, const JID &service, const DataForm *config, const gloox::Error *error) { - Q_UNUSED(config); - qDebug() << QString("id:%1 service:%2 error:%3").arg(qstring(id)).arg(qstring(service.full())).arg(qstring(error->text())); -} + // 从书签删除,再保存书签 + mConferenceList.remove_if([&](ConferenceListItem& a) { return a.jid == stdstring(groupId); }); + bookmarkStorage->storeBookmarks(mBookmarkList, mConferenceList); -std::string IM::getOnlineResource(const std::string &bare) { - auto it = onlineMap.find(bare); - if (it == onlineMap.end()) { - return std::string{}; - } - for (auto r : it->second) { - return r; - } - return std::string{}; -} - -std::set IM::getOnlineResources(const std::string &bare) { - auto it = onlineMap.find(bare); - if (it != onlineMap.end()) { - return it->second; - } - return {}; -} - -void IM::updateOnlineStatus(const std::string &bare, const std::string &resource, Presence::PresenceType presenceType) { - if (presenceType == Presence::Error) { - qWarning() << "Ignore error presence."; - return; - } - if (resource.empty()) { - qWarning() << "Ignore resource is empty."; - return; - } - - auto friendId = qstring(bare); - int status = -1; - - auto it = onlineMap.find(bare); - if (it == onlineMap.end()) { // 第一次 - if (presenceType != gloox::Presence::Unavailable) { - std::set resources; - resources.insert(resource); - onlineMap.emplace(bare, resources); - status = gloox::Presence::Available; - } - } else { // 第二次+ - std::set &resources = it->second; - if (presenceType != gloox::Presence::Unavailable) { - // multi online endpoint - resources.insert(resource); - onlineMap.emplace(bare, resources); - status = gloox::Presence::Available; - } else { - // one offline - resources.erase(resource); - if (resources.empty()) { - // all offline - onlineMap.erase(bare); - status = gloox::Presence::Unavailable; - } - } - } - emit receiveFriendStatus(friendId, status); + return true; } -void IM::retry() { doConnect(); } +bool IM::destroyGroup(const QString& groupId) { + qDebug() << "destroyGroup" << groupId; -bool IM::leaveGroup(const QString &groupId) { - qDebug() << "leaveGroup" << groupId; - auto r = findRoom(groupId); - if (!r) { - qWarning() << "Unable to find room" << groupId; - return false; - } - r->room->leave(); + auto r = findRoom(groupId); + if (!r) { + qWarning() << "Unable to find room" << groupId; + return false; + } + // 删除 + r->room->destroy(); - // 删除缓存 - m_roomMap.remove(groupId); + // 删除缓存 + m_roomMap.remove(groupId); - // 从书签删除,再保存书签 - mConferenceList.remove_if([&](ConferenceListItem &a) { return a.jid == stdstring(groupId); }); - bookmarkStorage->storeBookmarks(mBookmarkList, mConferenceList); + // 从书签删除,再保存书签 + mConferenceList.remove_if([&](ConferenceListItem& a) { return a.jid == stdstring(groupId); }); + bookmarkStorage->storeBookmarks(mBookmarkList, mConferenceList); - return true; + return true; } -bool IM::destroyGroup(const QString &groupId) { - qDebug() << "destroyGroup" << groupId; - - auto r = findRoom(groupId); - if (!r) { - qWarning() << "Unable to find room" << groupId; - return false; - } - // 删除 - r->room->destroy(); - - // 删除缓存 - m_roomMap.remove(groupId); +Disco::ItemList IM::handleDiscoNodeItems(const JID& from, const JID& to, const std::string& node) { + qDebug() << QString("from:%1").arg(from.full().c_str()); - // 从书签删除,再保存书签 - mConferenceList.remove_if([&](ConferenceListItem &a) { return a.jid == stdstring(groupId); }); - bookmarkStorage->storeBookmarks(mBookmarkList, mConferenceList); + return gloox::Disco::ItemList(); +} - return true; +Disco::IdentityList IM::handleDiscoNodeIdentities(const JID& from, const std::string& node) { + return gloox::Disco::IdentityList(); } -Disco::ItemList IM::handleDiscoNodeItems(const JID &from, const JID &to, const std::string &node) { +StringList IM::handleDiscoNodeFeatures(const JID& from, const std::string& node) { + return gloox::StringList(); +} - qDebug() << QString("from:%1").arg(from.full().c_str()); +void IM::endJingle() { mPeerRequestMedias.clear(); } - return gloox::Disco::ItemList(); +void IM::handleIncoming(gloox::Tag* tag) { + // auto services = tag->findChild("services", XMLNS, XMLNS_EXTERNAL_SERVICE_DISCOVERY); + // if (services) { + // mExtDisco = ExtDisco(services); + // } + // emit incoming(::base::Xmls::parse(qstring(tag->xml()))); +} + +bool IM::onTLSConnect(const CertInfo& info) { + qDebug() << QString("CertInfo:"); + + time_t from(info.date_from); + time_t to(info.date_to); + + qDebug() << QString("status: %1\n" // + "issuer: %2\n" // + "peer: %3\n" // + "protocol: %4\n" // + "mac: %5\n" // + "cipher: %6\n" // + "compression: %7\n") + .arg((info.status)) // + .arg(qstring(info.issuer.c_str())) // + .arg(qstring(info.server.c_str())) // + .arg((info.protocol.c_str())) // + .arg(qstring(info.mac.c_str())) // + .arg(qstring(info.cipher.c_str())) // + .arg(qstring(info.compression.c_str())); // + + qDebug() << QString("from:%1").arg(ctime(&from)); + qDebug() << QString("to:%1").arg(ctime(&to)); + + return true; +} + +void IM::handleLog(LogLevel level, LogArea area, const std::string& message) { + // qDebug()<subscribe(friendId, XMLNS_NICKNAME, this); +} -void IM::handleIncoming(gloox::Tag *tag) { -// auto services = tag->findChild("services", XMLNS, XMLNS_EXTERNAL_SERVICE_DISCOVERY); -// if (services) { -// mExtDisco = ExtDisco(services); -// } - // emit incoming(::base::Xmls::parse(qstring(tag->xml()))); -} - - -bool IM::onTLSConnect(const CertInfo &info) { - qDebug() << QString("CertInfo:"); - - time_t from(info.date_from); - time_t to(info.date_to); - - qDebug() << QString("status: %1\n" // - "issuer: %2\n" // - "peer: %3\n" // - "protocol: %4\n" // - "mac: %5\n" // - "cipher: %6\n" // - "compression: %7\n") - .arg((info.status)) // - .arg(qstring(info.issuer.c_str())) // - .arg(qstring(info.server.c_str())) // - .arg((info.protocol.c_str())) // - .arg(qstring(info.mac.c_str())) // - .arg(qstring(info.cipher.c_str())) // - .arg(qstring(info.compression.c_str())); // - - qDebug() << QString("from:%1").arg(ctime(&from)); - qDebug() << QString("to:%1").arg(ctime(&to)); - - return true; -} - -void IM::handleLog(LogLevel level, LogArea area, const std::string &message) { - // qDebug()<subscribe(friendId, XMLNS_NICKNAME, this); -} - -} // namespace lib::messenger +} // namespace lib::messenger diff --git a/src/lib/messenger/IM.h b/src/lib/messenger/IM.h index 74d823d8..798f62de 100644 --- a/src/lib/messenger/IM.h +++ b/src/lib/messenger/IM.h @@ -11,8 +11,6 @@ */ #pragma once - - #include "base/r.h" #include "base/system/sys_info.h" #include "base/task.h" @@ -25,13 +23,9 @@ #include "lib/session/AuthSession.h" #include "messenger.h" - #include #include -#include -#include -#include #include #include #include @@ -70,9 +64,13 @@ #include #include #include +#include +#include +#include -namespace gloox{ - class MUCRoom; +namespace gloox { +class MUCRoom; +class Message; }; namespace lib::ortc { @@ -82,34 +80,34 @@ enum class JingleCallType; namespace lib { namespace messenger { + using namespace gloox; using namespace gloox::PubSub; enum class CallDirection { CallIn, CallOut }; - struct IMRoomInfo { - MUCRoom *room; - - /** - * 显示项 - * muc#roominfo_ - * 参考: - * https://xmpp.org/extensions/xep-0045.html#registrar-formtype-roominfo - */ - - IMGroup info; - - /** - * 房间待修改项 - * 1、修改项放入该字段; - * 2、请求`room->requestRoomConfig()`获取服务器房间所有配置; - * 3、服务器返回到`handleMUCConfigForm`处理,保存即可; - * - * muc#roomconfig_ - * 参考 - * https://xmpp.org/extensions/xep-0045.html#registrar-formtype-owner - */ - std::map changes; + MUCRoom* room; + + /** + * 显示项 + * muc#roominfo_ + * 参考: + * https://xmpp.org/extensions/xep-0045.html#registrar-formtype-roominfo + */ + + IMGroup info; + + /** + * 房间待修改项 + * 1、修改项放入该字段; + * 2、请求`room->requestRoomConfig()`获取服务器房间所有配置; + * 3、服务器返回到`handleMUCConfigForm`处理,保存即可; + * + * muc#roomconfig_ + * 参考 + * https://xmpp.org/extensions/xep-0045.html#registrar-formtype-owner + */ + std::map changes; }; class IMJingle; @@ -138,686 +136,706 @@ class IM : public ok::lib::Task, public IqHandler, public BookmarkHandler, public NativeBookmarkHandler { - Q_OBJECT + Q_OBJECT public: - explicit IM(QString host, - QString user, - QString pwd, - QStringList features); - ~IM(); - - inline static IMMessage fromXMsg(MsgType type, const gloox::Message &msg); - - std::unique_ptr makeClient(); + explicit IM(QString host, QString user, QString pwd, QStringList features); + ~IM(); - void setNickname(const QString &nickname); - QString getNickname(); + inline static IMMessage fromXMsg(MsgType type, const gloox::Message& msg); - void setAvatar(const QByteArray &avatar); - void changePassword(const QString &password); - IMContactId getSelfId(); - IMPeerId getSelfPeerId(); - QString getSelfUsername(); + std::unique_ptr makeClient(); - /** - * fetchVCard - */ - void fetchFriendVCard(const QString &friendId); - IMStatus getFriendStatus(const QString &friendId); - void requestFriendNickname(const JID &friendId); + void setNickname(const QString& nickname); + QString getNickname(); - /** - * send - */ - void sendPresence(); - void sendPresence(const JID &to, Presence::PresenceType type); - void sendReceiptReceived(const QString &id, QString receiptNum); + void setAvatar(const QByteArray& avatar); + void changePassword(const QString& password); + IMContactId getSelfId(); + IMPeerId getSelfPeerId(); + QString getSelfUsername(); - /** - * 服务发现 - */ - void enableDiscoManager(); + /** + * fetchVCard + */ + void fetchFriendVCard(const QString& friendId); + IMStatus getFriendStatus(const QString& friendId); + void requestFriendNickname(const JID& friendId); - void endJingle(); + /** + * send + */ + void sendPresence(); + void sendPresence(const JID& to, Presence::PresenceType type); + void sendReceiptReceived(const QString& id, QString receiptNum); - void requestBookmarks(); + /** + * 服务发现 + */ + void enableDiscoManager(); - void requestVCards(); + void endJingle(); - void setUIStarted(); + void requestBookmarks(); - /** - * 朋友相关 - */ - RosterManager *enableRosterManager(); + void requestVCards(); - void addFriend(const JID &jid, const QString &nick, const QString &msg); - bool removeFriend(const JID &jid); + /** + * 朋友相关 + */ + RosterManager* enableRosterManager(); - void acceptFriendRequest(const QString &); - void rejectFriendRequest(const QString &); + void addFriend(const JID& jid, const QString& nick, const QString& msg); + bool removeFriend(const JID& jid); + void acceptFriendRequest(const QString&); + void rejectFriendRequest(const QString&); - size_t getRosterCount(); - void getRosterList(std::list &); + size_t getRosterCount(); + void getRosterList(std::list&); - void setFriendAlias(const JID &jid, const std::string &alias); + void setFriendAlias(const JID& jid, const std::string& alias); - void retry(); + void retry(); - // gloox log - void handleLog(LogLevel level, LogArea area, const std::string &message) override; + // gloox log + void handleLog(LogLevel level, LogArea area, const std::string& message) override; - virtual const JID &self() const { return _client->jid(); } + virtual const JID& self() const { return _client->jid(); } - Client *getClient() const { return _client.get(); } + Client* getClient() const { return _client.get(); } - QDomDocument buildMessage(const QString &to, const QString &msg, const QString &id); + QDomDocument buildMessage(const QString& to, const QString& msg, const QString& id); - bool sendTo(const QString &to, const QString &msg, const QString &id); + bool sendTo(const QString& to, const QString& msg, const QString& id); - /** - * 群组相关 - * @param groupId - * @param nick - */ - void setRoomSubject(const QString &groupId, const std::string &nick); - void setRoomName(const QString &groupId, const std::string &name); - void setRoomAlias(const QString &groupId, const std::string &alias); - void setRoomDesc(const QString &groupId, const std::string &desc); - bool inviteToRoom(const JID &roomJid, const JID &peerId); - bool leaveGroup(const QString &groupId); - bool destroyGroup(const QString &groupId); + /** + * 群组相关 + * @param groupId + * @param nick + */ + void setRoomSubject(const QString& groupId, const std::string& nick); + void setRoomName(const QString& groupId, const std::string& name); + void setRoomAlias(const QString& groupId, const std::string& alias); + void setRoomDesc(const QString& groupId, const std::string& desc); + bool inviteToRoom(const JID& roomJid, const JID& peerId); + bool leaveGroup(const QString& groupId); + bool destroyGroup(const QString& groupId); - /** - * @brief sendToRoom - * @param to - * @param msg - * @param id 设置消息ID - */ - bool sendToRoom(const QString &to, const QString &msg, const QString &id = ""); + /** + * @brief sendToRoom + * @param to + * @param msg + * @param id 设置消息ID + */ + bool sendToRoom(const QString& to, const QString& msg, const QString& id = ""); - void joinRoom(const QString &jid); + void joinRoom(const QString& jid); - void createRoom(const JID &jid, const std::string &password = ""); + void createRoom(const JID& jid, const std::string& password = ""); - const IMRoomInfo *findRoom(const QString &groupId) const; + const IMRoomInfo* findRoom(const QString& groupId) const; - void doConnect(); + void doConnect(); - void doDisconnect(); + void doDisconnect(); - // 2-群组列表 - void loadGroupList(); - // 3-用户信息 - void loadRosterInfo(); - // 4-加入群聊 - void joinRooms(); + // 2-群组列表 + void loadGroupList(); + // 3-用户信息 + void loadRosterInfo(); + // 4-加入群聊 + void joinRooms(); - void send(const QString &xml); + void send(const QString& xml); - void stop(); + void stop(); - void interrupt(); + void interrupt(); + /** + * 获取第一个在线终端resource + * @param bare + * @return + */ + std::string getOnlineResource(const std::string& bare); - /** - * 获取第一个在线终端resource - * @param bare - * @return - */ - std::string getOnlineResource(const std::string &bare); + /** + * 获取全部在线终端 + * @param bare + * @return + */ + std::set getOnlineResources(const std::string& bare); + void updateOnlineStatus(const std::string& bare, const std::string& resource, + Presence::PresenceType presenceType); - /** - * 获取全部在线终端 - * @param bare - * @return - */ - std::set getOnlineResources(const std::string &bare); - void updateOnlineStatus(const std::string &bare, const std::string &resource, Presence::PresenceType presenceType); + [[nodiscard]] gloox::JID wrapJid(const QString& f) const; - [[nodiscard]] gloox::JID wrapJid(const QString &f) const; + [[nodiscard]] gloox::JID wrapRoomJid(const QString& group) const; + void sendChatState(const QString& to, ChatStateType state); - [[nodiscard]] gloox::JID wrapRoomJid(const QString &group) const; - void sendChatState(const QString &to, ChatStateType state); + void makeId(QString& id); - void makeId(QString &id); - -// ExtDisco &extDisco() { return mExtDisco; } + // ExtDisco &extDisco() { return mExtDisco; } protected: - void run() override; + void run() override; - virtual void handleBookmarks(const BMConferenceList &cList) override; + virtual void handleBookmarks(const BMConferenceList& cList) override; #ifdef WANT_PING - /** - * ping handler - */ - virtual void handlePing(const gloox::PingHandler::PingType type, const std::string &body) override; + /** + * ping handler + */ + virtual void handlePing(const gloox::PingHandler::PingType type, + const std::string& body) override; #endif - /** - * incoming handler - */ - virtual void handleIncoming(Tag *tag) override; - - /** - * iq handlers - * @param iq - * @return - */ - bool handleIq(const IQ &iq) override; - void handleIqID(const IQ &iq, int context) override; - - /** - * tag handlers - */ - void handleTag(Tag *tag) override; - - /** - * connect handlers - */ - void onConnect() override; - void onDisconnect(ConnectionError e) override; - bool onTLSConnect(const CertInfo &info) override; + /** + * incoming handler + */ + virtual void handleIncoming(Tag* tag) override; - /** - * Registration - */ - virtual void handleRegistrationFields(const JID &from, int fields, std::string instructions) override; + /** + * iq handlers + * @param iq + * @return + */ + bool handleIq(const IQ& iq) override; + void handleIqID(const IQ& iq, int context) override; - virtual void handleAlreadyRegistered(const JID &from) override; + /** + * tag handlers + */ + void handleTag(Tag* tag) override; - virtual void handleRegistrationResult(const JID &from, // - RegistrationResult regResult, // - const Error *error) override; + /** + * connect handlers + */ + void onConnect() override; + void onDisconnect(ConnectionError e) override; + bool onTLSConnect(const CertInfo& info) override; - virtual void handleDataForm(const JID &from, const DataForm &form) override; + /** + * Registration + */ + virtual void handleRegistrationFields(const JID& from, int fields, + std::string instructions) override; - virtual void handleOOB(const JID &from, const OOB &oob) override; + virtual void handleAlreadyRegistered(const JID& from) override; - /** - * vCard - * @param jid - * @param vch - */ - void handleVCard(const JID &jid, const VCard *vcard) override; + virtual void handleRegistrationResult(const JID& from, // + RegistrationResult regResult, // + const Error* error) override; - void handleVCardResult(VCardContext context, const JID &jid, StanzaError error = StanzaErrorUndefined) override; + virtual void handleDataForm(const JID& from, const DataForm& form) override; - /** - * RosterListener - * @param msg - * @param session - */ - void handleItemAdded(const gloox::JID &) override; - void handleItemSubscribed(const JID &jid) override; - void handleItemRemoved(const JID &jid) override; - void handleItemUpdated(const JID &jid) override; - void handleItemUnsubscribed(const JID &jid) override; - void handleRoster(const Roster &roster) override; - void handleRosterPresence(const RosterItem &item, const std::string &resource, Presence::PresenceType presence, const std::string &msg) override; - void handleSelfPresence(const RosterItem &item, const std::string &resource, Presence::PresenceType presence, const std::string &msg) override; + virtual void handleOOB(const JID& from, const OOB& oob) override; - bool handleSubscriptionRequest(const JID &jid, const std::string &msg) override; + /** + * vCard + * @param jid + * @param vch + */ + void handleVCard(const JID& jid, const VCard* vcard) override; - bool handleUnsubscriptionRequest(const JID &jid, const std::string &msg) override; + void handleVCardResult(VCardContext context, const JID& jid, + StanzaError error = StanzaErrorUndefined) override; - void handleNonrosterPresence(const Presence &presence) override; - - void handleRosterError(const IQ &iq) override; - - void handleRosterItemExchange(const JID &from, const RosterX *items) override; - - // MUC config - void handleMUCConfigList(MUCRoom *room, const MUCListItemList &items, MUCOperation operation) override; - - void handleMUCConfigForm(MUCRoom *room, const DataForm &form) override; - - void handleMUCConfigResult(MUCRoom *room, bool success, MUCOperation operation) override; - - void handleMUCRequest(MUCRoom *room, const DataForm &form) override; - - // MessageSessionHandler - void handleMessage(const gloox::Message &msg, MessageSession *session = nullptr) override; - void handleMessageSession(MessageSession *session) override; - - // MessageEventHandler - void handleMessageEvent(const JID &from, const MessageEvent *event) override; - - void handleChatState(const JID &from, ChatStateType state) override; - - // MUC handler - void handleMUCParticipantPresence(MUCRoom *room, const MUCRoomParticipant participant, const Presence &presence) override; - - void handleMUCMessage(MUCRoom *room, const gloox::Message &msg, bool priv) override; - - bool handleMUCRoomCreation(MUCRoom *room) override; - - void handleMUCSubject(MUCRoom *room, const std::string &nick, const std::string &subject) override; - - void handleMUCInviteDecline(MUCRoom *room, const JID &invitee, const std::string &reason) override; - - void handleMUCError(MUCRoom *room, StanzaError error) override; - - void handleMUCInfo(MUCRoom *room, int features, const std::string &name, const DataForm *infoForm) override; - - void handleMUCItems(MUCRoom *room, const Disco::ItemList &items) override; - - // Disco handler - void handleDiscoInfo(const JID &from, const Disco::Info &, int ontext) override; - - void handleDiscoItems(const JID &from, const Disco::Items &, int context) override; - - void handleDiscoError(const JID &from, const gloox::Error *, int context) override; - // DiscoNodeHandler - virtual StringList handleDiscoNodeFeatures(const JID &from, const std::string &node) override; - - virtual Disco::IdentityList handleDiscoNodeIdentities(const JID &from, const std::string &node) override; - - virtual Disco::ItemList handleDiscoNodeItems(const JID &from, const JID &to, const std::string &node = EmptyString) override; - - // Presence handler - void handlePresence(const Presence &presence) override; - - /** - * Receives the payload for an item. - * - * @param service Service hosting the queried node. - * @param node ID of the parent node. - * @param entry The complete item Tag (do not delete). - */ - void handleItem(const JID &service, const std::string &node, const Tag *entry) override; - - /** - * Receives the list of Items for a node. - * - * @param id The reply IQ's id. - * @param service Service hosting the queried node. - * @param node ID of the queried node (empty for the root node). - * @param itemList List of contained items. - * @param error Describes the error case if the request failed. - * - * @see Manager::requestItems() - */ - void handleItems(const std::string &id, const JID &service, const std::string &node, const ItemList &itemList, const gloox::Error *error = 0) override; - - /** - * Receives the result for an item publication. - * - * @param id The reply IQ's id. - * @param service Service hosting the queried node. - * @param node ID of the queried node. If empty, the root node has been - * queried. - * @param itemList List of contained items. - * @param error Describes the error case if the request failed. - * - * @see Manager::publishItem - */ - void handleItemPublication(const std::string &id, const JID &service, const std::string &node, const ItemList &itemList, const gloox::Error *error = 0) override; - - /** - * Receives the result of an item removal. - * - * @param id The reply IQ's id. - * @param service Service hosting the queried node. - * @param node ID of the queried node. If empty, the root node has been - * queried. - * @param itemList List of contained items. - * @param error Describes the error case if the request failed. - * - * @see Manager::deleteItem - */ - void handleItemDeletion(const std::string &id, const JID &service, const std::string &node, const ItemList &itemList, const gloox::Error *error = 0) override; - - /** - * Receives the subscription results. In case a problem occured, the - * Subscription ID and SubscriptionType becomes irrelevant. - * - * @param id The reply IQ's id. - * @param service PubSub service asked for subscription. - * @param node Node asked for subscription. - * @param sid Subscription ID. - * @param jid Subscribed entity. - * @param subType Type of the subscription. - * @param error Subscription Error. - * - * @see Manager::subscribe - */ - void handleSubscriptionResult(const std::string &id, const JID &service, const std::string &node, const std::string &sid, const JID &jid, - const gloox::PubSub::SubscriptionType subType, const gloox::Error *error = 0) override; - - /** - * Receives the unsubscription results. In case a problem occured, the - * subscription ID becomes irrelevant. - * - * @param id The reply IQ's id. - * @param service PubSub service. - * @param error Unsubscription Error. - * - * @see Manager::unsubscribe - */ - void handleUnsubscriptionResult(const std::string &id, const JID &service, const gloox::Error *error = 0) override; - - /** - * Receives the subscription options for a node. - * - * @param id The reply IQ's id. - * @param service Service hosting the queried node. - * @param jid Subscribed entity. - * @param node ID of the node. - * @param options Options DataForm. - * @param sid An optional subscription ID. - * @param error Subscription options retrieval Error. - * - * @see Manager::getSubscriptionOptions - */ - void handleSubscriptionOptions(const std::string &id, const JID &service, const JID &jid, const std::string &node, const DataForm *options, const std::string &sid = EmptyString, - const gloox::Error *error = 0) override; - - /** - * Receives the result for a subscription options modification. - * - * @param id The reply IQ's id. - * @param service Service hosting the queried node. - * @param jid Subscribed entity. - * @param node ID of the queried node. - * @param sid An optional subscription ID. - * @param error Subscription options modification Error. - * - * @see Manager::setSubscriptionOptions - */ - void handleSubscriptionOptionsResult(const std::string &id, const JID &service, const JID &jid, const std::string &node, const std::string &sid = EmptyString, - const gloox::Error *error = 0) override; - - /** - * Receives the list of subscribers to a node. - * - * @param id The reply IQ's id. - * @param service Service hosting the node. - * @param node ID of the queried node. - * @param list Subscriber list. - * @param error Subscription options modification Error. - * - * @see Manager::getSubscribers - */ - void handleSubscribers(const std::string &id, const JID &service, const std::string &node, const SubscriptionList &list, const gloox::Error *error = 0) override; - - /** - * Receives the result of a subscriber list modification. - * - * @param id The reply IQ's id. - * @param service Service hosting the node. - * @param node ID of the queried node. - * @param list Subscriber list. - * @param error Subscriber list modification Error. - * - * @see Manager::setSubscribers - */ - void handleSubscribersResult(const std::string &id, const JID &service, const std::string &node, const SubscriberList *list, const gloox::Error *error = 0) override; - - /** - * Receives the affiliate list for a node. - * - * @param id The reply IQ's id. - * @param service Service hosting the node. - * @param node ID of the queried node. - * @param list Affiliation list. - * @param error Affiliation list retrieval Error. - * - * @see Manager::getAffiliates - */ - void handleAffiliates(const std::string &id, const JID &service, const std::string &node, const AffiliateList *list, const gloox::Error *error = 0) override; - - /** - * Handle the affiliate list for a specific node. - * - * @param id The reply IQ's id. - * @param service Service hosting the node. - * @param node ID of the node. - * @param list The Affiliate list. - * @param error Affiliation list modification Error. - * - * @see Manager::setAffiliations - */ - void handleAffiliatesResult(const std::string &id, const JID &service, const std::string &node, const AffiliateList *list, const gloox::Error *error = 0) override; - - /** - * Receives the configuration for a specific node. - * - * @param id The reply IQ's id. - * @param service Service hosting the node. - * @param node ID of the node. - * @param config Configuration DataForm. - * @param error Configuration retrieval Error. - * - * @see Manager::getNodeConfig - */ - void handleNodeConfig(const std::string &id, const JID &service, const std::string &node, const DataForm *config, const gloox::Error *error = 0) override; - - /** - * Receives the result of a node's configuration modification. - * - * @param id The reply IQ's id. - * @param service Service hosting the node. - * @param node ID of the node. - * @param error Configuration modification Error. - * - * @see Manager::setNodeConfig - */ - void handleNodeConfigResult(const std::string &id, const JID &service, const std::string &node, const gloox::Error *error = 0) override; - - /** - * Receives the result of a node creation. - * - * @param id The reply IQ's id. - * @param service Service hosting the node. - * @param node ID of the node. - * @param error Node creation Error. - * - * @see Manager::setNodeConfig - */ - void handleNodeCreation(const std::string &id, const JID &service, const std::string &node, const gloox::Error *error = 0) override; - - /** - * Receives the result for a node removal. - * - * @param id The reply IQ's id. - * @param service Service hosting the node. - * @param node ID of the node. - * @param error Node removal Error. - * - * @see Manager::deleteNode - */ - void handleNodeDeletion(const std::string &id, const JID &service, const std::string &node, const gloox::Error *error = 0) override; - - /** - * Receives the result of a node purge request. - * - * @param id The reply IQ's id. - * @param service Service hosting the node. - * @param node ID of the node. - * @param error Node purge Error. - * - * @see Manager::purgeNode - */ - void handleNodePurge(const std::string &id, const JID &service, const std::string &node, const gloox::Error *error = 0) override; - - /** - * Receives the Subscription list for a specific service. - * - * @param id The reply IQ's id. - * @param service The queried service. - * @param subMap The map of node's subscription. - * @param error Subscription list retrieval Error. - * - * @see Manager::getSubscriptions - */ - void handleSubscriptions(const std::string &id, const JID &service, const SubscriptionMap &subMap, const gloox::Error *error = 0) override; - - /** - * Receives the Affiliation map for a specific service. - * - * @param id The reply IQ's id. - * @param service The queried service. - * @param affMap The map of node's affiliation. - * @param error Affiliation list retrieval Error. - * - * @see Manager::getAffiliations - */ - void handleAffiliations(const std::string &id, const JID &service, const AffiliationMap &affMap, const gloox::Error *error = 0) override; - - /** - * Receives the default configuration for a specific node type. - * - * @param id The reply IQ's id. - * @param service The queried service. - * @param config Configuration form for the node type. - * @param error Default node config retrieval Error. - * - * @see Manager::getDefaultNodeConfig - */ - void handleDefaultNodeConfig(const std::string &id, // - const JID &service, // - const DataForm *config, // - const gloox::Error *error = 0) override; - - void handleBookmarks(const BookmarkList &bList, // - const ConferenceList &cList) override; - - void doPubSubEvent(const gloox::PubSub::Event *pse, const Message &msg, QString &friendId); - void doMessageHeadline(const Message &msg, QString &friendId, const QString &body); - void doMessageChat(const Message &msg, QString &friendId, const QString &body); - - void doMessageNormal(const Message &msg, QString &friendId); - - void joinRoom(MUCRoom *room); - - void cacheJoinRoom(const std::string &jid, const std::string &name = ""); + /** + * RosterListener + * @param msg + * @param session + */ + void handleItemAdded(const gloox::JID&) override; + void handleItemSubscribed(const JID& jid) override; + void handleItemRemoved(const JID& jid) override; + void handleItemUpdated(const JID& jid) override; + void handleItemUnsubscribed(const JID& jid) override; + void handleRoster(const Roster& roster) override; + void handleRosterPresence(const RosterItem& item, const std::string& resource, + Presence::PresenceType presence, const std::string& msg) override; + void handleSelfPresence(const RosterItem& item, const std::string& resource, + Presence::PresenceType presence, const std::string& msg) override; + + bool handleSubscriptionRequest(const JID& jid, const std::string& msg) override; + + bool handleUnsubscriptionRequest(const JID& jid, const std::string& msg) override; + + void handleNonrosterPresence(const Presence& presence) override; + + void handleRosterError(const IQ& iq) override; + + void handleRosterItemExchange(const JID& from, const RosterX* items) override; + + // MUC config + void handleMUCConfigList(MUCRoom* room, const MUCListItemList& items, + MUCOperation operation) override; + + void handleMUCConfigForm(MUCRoom* room, const DataForm& form) override; + + void handleMUCConfigResult(MUCRoom* room, bool success, MUCOperation operation) override; + + void handleMUCRequest(MUCRoom* room, const DataForm& form) override; + + // MessageSessionHandler + void handleMessage(const gloox::Message& msg, MessageSession* session = nullptr) override; + void handleMessageSession(MessageSession* session) override; + + // MessageEventHandler + void handleMessageEvent(const JID& from, const MessageEvent* event) override; + + void handleChatState(const JID& from, ChatStateType state) override; + + // MUC handler + void handleMUCParticipantPresence(MUCRoom* room, const MUCRoomParticipant participant, + const Presence& presence) override; + + void handleMUCMessage(MUCRoom* room, const gloox::Message& msg, bool priv) override; + + bool handleMUCRoomCreation(MUCRoom* room) override; + + void handleMUCSubject(MUCRoom* room, const std::string& nick, + const std::string& subject) override; + + void handleMUCInviteDecline(MUCRoom* room, const JID& invitee, + const std::string& reason) override; + + void handleMUCError(MUCRoom* room, StanzaError error) override; + + void handleMUCInfo(MUCRoom* room, int features, const std::string& name, + const DataForm* infoForm) override; + + void handleMUCItems(MUCRoom* room, const Disco::ItemList& items) override; + + // Disco handler + void handleDiscoInfo(const JID& from, const Disco::Info&, int ontext) override; + + void handleDiscoItems(const JID& from, const Disco::Items&, int context) override; + + void handleDiscoError(const JID& from, const gloox::Error*, int context) override; + // DiscoNodeHandler + virtual StringList handleDiscoNodeFeatures(const JID& from, const std::string& node) override; + + virtual Disco::IdentityList handleDiscoNodeIdentities(const JID& from, + const std::string& node) override; + + virtual Disco::ItemList handleDiscoNodeItems(const JID& from, const JID& to, + const std::string& node = EmptyString) override; + + // Presence handler + void handlePresence(const Presence& presence) override; + + /** + * Receives the payload for an item. + * + * @param service Service hosting the queried node. + * @param node ID of the parent node. + * @param entry The complete item Tag (do not delete). + */ + void handleItem(const JID& service, const std::string& node, const Tag* entry) override; + + /** + * Receives the list of Items for a node. + * + * @param id The reply IQ's id. + * @param service Service hosting the queried node. + * @param node ID of the queried node (empty for the root node). + * @param itemList List of contained items. + * @param error Describes the error case if the request failed. + * + * @see Manager::requestItems() + */ + void handleItems(const std::string& id, const JID& service, const std::string& node, + const ItemList& itemList, const gloox::Error* error = 0) override; + + /** + * Receives the result for an item publication. + * + * @param id The reply IQ's id. + * @param service Service hosting the queried node. + * @param node ID of the queried node. If empty, the root node has been + * queried. + * @param itemList List of contained items. + * @param error Describes the error case if the request failed. + * + * @see Manager::publishItem + */ + void handleItemPublication(const std::string& id, const JID& service, const std::string& node, + const ItemList& itemList, const gloox::Error* error = 0) override; + + /** + * Receives the result of an item removal. + * + * @param id The reply IQ's id. + * @param service Service hosting the queried node. + * @param node ID of the queried node. If empty, the root node has been + * queried. + * @param itemList List of contained items. + * @param error Describes the error case if the request failed. + * + * @see Manager::deleteItem + */ + void handleItemDeletion(const std::string& id, const JID& service, const std::string& node, + const ItemList& itemList, const gloox::Error* error = 0) override; + + /** + * Receives the subscription results. In case a problem occured, the + * Subscription ID and SubscriptionType becomes irrelevant. + * + * @param id The reply IQ's id. + * @param service PubSub service asked for subscription. + * @param node Node asked for subscription. + * @param sid Subscription ID. + * @param jid Subscribed entity. + * @param subType Type of the subscription. + * @param error Subscription Error. + * + * @see Manager::subscribe + */ + void handleSubscriptionResult(const std::string& id, const JID& service, + const std::string& node, const std::string& sid, const JID& jid, + const gloox::PubSub::SubscriptionType subType, + const gloox::Error* error = 0) override; + + /** + * Receives the unsubscription results. In case a problem occured, the + * subscription ID becomes irrelevant. + * + * @param id The reply IQ's id. + * @param service PubSub service. + * @param error Unsubscription Error. + * + * @see Manager::unsubscribe + */ + void handleUnsubscriptionResult(const std::string& id, const JID& service, + const gloox::Error* error = 0) override; + + /** + * Receives the subscription options for a node. + * + * @param id The reply IQ's id. + * @param service Service hosting the queried node. + * @param jid Subscribed entity. + * @param node ID of the node. + * @param options Options DataForm. + * @param sid An optional subscription ID. + * @param error Subscription options retrieval Error. + * + * @see Manager::getSubscriptionOptions + */ + void handleSubscriptionOptions(const std::string& id, const JID& service, const JID& jid, + const std::string& node, const DataForm* options, + const std::string& sid = EmptyString, + const gloox::Error* error = 0) override; + + /** + * Receives the result for a subscription options modification. + * + * @param id The reply IQ's id. + * @param service Service hosting the queried node. + * @param jid Subscribed entity. + * @param node ID of the queried node. + * @param sid An optional subscription ID. + * @param error Subscription options modification Error. + * + * @see Manager::setSubscriptionOptions + */ + void handleSubscriptionOptionsResult(const std::string& id, const JID& service, const JID& jid, + const std::string& node, + const std::string& sid = EmptyString, + const gloox::Error* error = 0) override; + + /** + * Receives the list of subscribers to a node. + * + * @param id The reply IQ's id. + * @param service Service hosting the node. + * @param node ID of the queried node. + * @param list Subscriber list. + * @param error Subscription options modification Error. + * + * @see Manager::getSubscribers + */ + void handleSubscribers(const std::string& id, const JID& service, const std::string& node, + const SubscriptionList& list, const gloox::Error* error = 0) override; + + /** + * Receives the result of a subscriber list modification. + * + * @param id The reply IQ's id. + * @param service Service hosting the node. + * @param node ID of the queried node. + * @param list Subscriber list. + * @param error Subscriber list modification Error. + * + * @see Manager::setSubscribers + */ + void handleSubscribersResult(const std::string& id, const JID& service, const std::string& node, + const SubscriberList* list, + const gloox::Error* error = 0) override; + + /** + * Receives the affiliate list for a node. + * + * @param id The reply IQ's id. + * @param service Service hosting the node. + * @param node ID of the queried node. + * @param list Affiliation list. + * @param error Affiliation list retrieval Error. + * + * @see Manager::getAffiliates + */ + void handleAffiliates(const std::string& id, const JID& service, const std::string& node, + const AffiliateList* list, const gloox::Error* error = 0) override; + + /** + * Handle the affiliate list for a specific node. + * + * @param id The reply IQ's id. + * @param service Service hosting the node. + * @param node ID of the node. + * @param list The Affiliate list. + * @param error Affiliation list modification Error. + * + * @see Manager::setAffiliations + */ + void handleAffiliatesResult(const std::string& id, const JID& service, const std::string& node, + const AffiliateList* list, const gloox::Error* error = 0) override; + + /** + * Receives the configuration for a specific node. + * + * @param id The reply IQ's id. + * @param service Service hosting the node. + * @param node ID of the node. + * @param config Configuration DataForm. + * @param error Configuration retrieval Error. + * + * @see Manager::getNodeConfig + */ + void handleNodeConfig(const std::string& id, const JID& service, const std::string& node, + const DataForm* config, const gloox::Error* error = 0) override; + + /** + * Receives the result of a node's configuration modification. + * + * @param id The reply IQ's id. + * @param service Service hosting the node. + * @param node ID of the node. + * @param error Configuration modification Error. + * + * @see Manager::setNodeConfig + */ + void handleNodeConfigResult(const std::string& id, const JID& service, const std::string& node, + const gloox::Error* error = 0) override; + + /** + * Receives the result of a node creation. + * + * @param id The reply IQ's id. + * @param service Service hosting the node. + * @param node ID of the node. + * @param error Node creation Error. + * + * @see Manager::setNodeConfig + */ + void handleNodeCreation(const std::string& id, const JID& service, const std::string& node, + const gloox::Error* error = 0) override; + + /** + * Receives the result for a node removal. + * + * @param id The reply IQ's id. + * @param service Service hosting the node. + * @param node ID of the node. + * @param error Node removal Error. + * + * @see Manager::deleteNode + */ + void handleNodeDeletion(const std::string& id, const JID& service, const std::string& node, + const gloox::Error* error = 0) override; + + /** + * Receives the result of a node purge request. + * + * @param id The reply IQ's id. + * @param service Service hosting the node. + * @param node ID of the node. + * @param error Node purge Error. + * + * @see Manager::purgeNode + */ + void handleNodePurge(const std::string& id, const JID& service, const std::string& node, + const gloox::Error* error = 0) override; + + /** + * Receives the Subscription list for a specific service. + * + * @param id The reply IQ's id. + * @param service The queried service. + * @param subMap The map of node's subscription. + * @param error Subscription list retrieval Error. + * + * @see Manager::getSubscriptions + */ + void handleSubscriptions(const std::string& id, const JID& service, + const SubscriptionMap& subMap, const gloox::Error* error = 0) override; + + /** + * Receives the Affiliation map for a specific service. + * + * @param id The reply IQ's id. + * @param service The queried service. + * @param affMap The map of node's affiliation. + * @param error Affiliation list retrieval Error. + * + * @see Manager::getAffiliations + */ + void handleAffiliations(const std::string& id, const JID& service, const AffiliationMap& affMap, + const gloox::Error* error = 0) override; + + /** + * Receives the default configuration for a specific node type. + * + * @param id The reply IQ's id. + * @param service The queried service. + * @param config Configuration form for the node type. + * @param error Default node config retrieval Error. + * + * @see Manager::getDefaultNodeConfig + */ + void handleDefaultNodeConfig(const std::string& id, // + const JID& service, // + const DataForm* config, // + const gloox::Error* error = 0) override; + + void handleBookmarks(const BookmarkList& bList, // + const ConferenceList& cList) override; + + void doPubSubEvent(const gloox::PubSub::Event* pse, const gloox::Message& msg, QString& friendId); + void doMessageHeadline(const gloox::Message& msg, QString& friendId, const QString& body); + void doMessageChat(const gloox::Message& msg, QString& friendId, const QString& body); + + void doMessageNormal(const gloox::Message& msg, QString& friendId); + + void joinRoom(MUCRoom* room); + + void cacheJoinRoom(const std::string& jid, const std::string& name = ""); private: - QMutex m_mutex; - - + QMutex m_mutex; - QStringList features; + QStringList features; - QString discoVal; - QString _host; - QString _username; - QString _password; - QString _resource; + QString discoVal; + QString _host; + QString _username; + QString _password; + QString _resource; - QString _nick; + QString _nick; + std::unique_ptr _client; - std::unique_ptr _client; + // 发送消息的id + std::set sendIds; + /** + * k: sessionId + * v: messageSession + */ + std::map sessionMap; - // 发送消息的id - std::set sendIds; + /** + * k: bare + * v: sessionId + */ + std::map sessionIdMap; - /** - * k: sessionId - * v: messageSession - */ - std::map sessionMap; + /** + * 在线 + * key: bare value:[resource,resource,...] + */ + std::map> onlineMap; - /** - * k: bare - * v: sessionId - */ - std::map sessionIdMap; + std::map mPeerRequestMedias; - /** - * 在线 - * key: bare value:[resource,resource,...] - */ - std::map> onlineMap; + std::unique_ptr vCardManager; + std::unique_ptr pubSubManager; + std::unique_ptr bookmarkStorage; + std::unique_ptr mRegistration; + std::unique_ptr m_nativeBookmark; - std::map mPeerRequestMedias; + std::unique_ptr m_messageEventFilter; + QMap m_chatStateFilters; - std::unique_ptr vCardManager; - std::unique_ptr pubSubManager; - std::unique_ptr bookmarkStorage; - std::unique_ptr mRegistration; - std::unique_ptr m_nativeBookmark; + QMap m_roomMap; - std::unique_ptr m_messageEventFilter; + QThread* thread; - QMap m_chatStateFilters; - - QMap m_roomMap; - - QThread *thread; - -// -// ConferenceList mConferenceList; -// BookmarkList &mBookmarkList; -// ExtDisco mExtDisco; + // + // ConferenceList mConferenceList; + // BookmarkList &mBookmarkList; + // ExtDisco mExtDisco; signals: - void connectResult(IMConnectStatus); - - void receiveRoomMessage(QString groupId, IMPeerId friendId, IMMessage); - - // friend events - void receiveFriend(IMFriend frnd); - - void receiveFriendRequest(QString friendId, QString msg); + void connectResult(IMConnectStatus); - void receiveFriendRemoved(QString friendId); + void receiveRoomMessage(QString groupId, IMPeerId friendId, IMMessage); - void receiveFriendStatus(QString friendId, int status); + // friend events + void receiveFriend(IMFriend frnd); - void receiveMessageSession(QString contactId, QString sid); + void receiveFriendRequest(QString friendId, QString msg); - void receiveFriendMessage(QString peerId, IMMessage); + void receiveFriendRemoved(QString friendId); - void receiveNicknameChange(QString friendId, QString nickname); + void receiveFriendStatus(QString friendId, int status); - void receiveFriendAliasChanged(JID friendId, std::string alias); + void receiveMessageSession(QString contactId, QString sid); - void receiveFriendAvatarChanged(QString friendId, std::string avatar); + void receiveFriendMessage(QString peerId, IMMessage); - void receiveFriendChatState(QString friendId, int state); + void receiveNicknameChange(QString friendId, QString nickname); - void exportEncryptedMessage(QString em); + void receiveFriendAliasChanged(JID friendId, std::string alias); - void receiveMessageReceipt(QString friendId, QString receipt); + void receiveFriendAvatarChanged(QString friendId, std::string avatar); - void incoming(QString xml); + void receiveFriendChatState(QString friendId, int state); + void exportEncryptedMessage(QString em); + void receiveMessageReceipt(QString friendId, QString receipt); - // Self events - void selfIdChanged(QString id); - void selfNicknameChanged(QString nickname); - void selfAvatarChanged(std::string avatar); - void selfStatusChanged(int type, const std::string status); + void incoming(QString xml); + // Self events + void selfIdChanged(QString id); + void selfNicknameChanged(QString nickname); + void selfAvatarChanged(std::string avatar); + void selfStatusChanged(int type, const std::string status); - void started(); - void stopped(); + void started(); + void stopped(); - void groupReceived(const QString groupId, const QString name); - void groupListReceivedDone(); - void groupOccupants(const QString groupId, const uint size); - void groupOccupantStatus(const QString &groupId, IMGroupOccupant occ); - void groupInvite(const QString groupId, const QString peerId, const QString message); + void groupReceived(const QString groupId, const QString name); + void groupListReceivedDone(); + void groupOccupants(const QString groupId, const uint size); + void groupOccupantStatus(const QString& groupId, IMGroupOccupant occ); + void groupInvite(const QString groupId, const QString peerId, const QString message); - void groupRoomInfo(QString groupId, IMGroup groupInfo); + void groupRoomInfo(QString groupId, IMGroup groupInfo); - void groupSubjectChanged(const JID group, const std::string subject); + void groupSubjectChanged(const JID group, const std::string subject); - void doPubSubEventDone(); + void doPubSubEventDone(); public slots: - void sendServiceDiscoveryItems(); - void sendServiceDiscoveryInfo(const JID &item); + void sendServiceDiscoveryItems(); + void sendServiceDiscoveryInfo(const JID& item); }; -} // namespace messenger -} // namespace lib +} // namespace messenger +} // namespace lib diff --git a/src/lib/messenger/IMCall.cpp b/src/lib/messenger/IMCall.cpp index ff1e0bfc..ae882486 100644 --- a/src/lib/messenger/IMCall.cpp +++ b/src/lib/messenger/IMCall.cpp @@ -16,166 +16,293 @@ #include #include "IMCall.h" -#include "IMJingle.h" +#include "lib/ortc/ok_rtc.h" +#include "lib/ortc/ok_rtc_defs.h" +#include "lib/ortc/ok_rtc_manager.h" #include "lib/session/AuthSession.h" namespace lib::messenger { -IMCall::IMCall( QObject *parent): QObject(parent) -{ - jingle = IMJingle::getInstance(); +IMCall::IMCall(IM* im, QObject* parent) : IMJingle(im, parent) { + jingle = IMCall::getInstance(); connectJingle(jingle); } -void IMCall::addCallHandler(CallHandler *hdr) -{ - callHandlers.push_back(hdr); -} +void IMCall::addCallHandler(CallHandler* hdr) { callHandlers.push_back(hdr); } -bool IMCall::callToGroup(const QString &g) -{ - return false; -} +bool IMCall::callToGroup(const QString& g) { return false; } void IMCall::connectJingle(IMJingle* _jingle) { - qDebug()<<__func__<<_jingle; - - /** - * callHandlers - */ - connect(_jingle, &IMJingle - ::receiveCallRequest, this, - [&](IMPeerId peerId, QString callId, bool audio, bool video) { - for (auto handler : callHandlers) { - handler->onCall(peerId, callId, audio, video); - } - }); - - connect(_jingle, &IMJingle::receiveCallRetract, this, - [&](QString friendId, int state) { - for (auto handler : callHandlers) { - handler->onCallRetract(friendId, state); - } - }); - - connect(_jingle, &IMJingle::receiveCallAcceptByOther, this, - [&](const QString& callId, const IMPeerId & peerId) { - for (auto handler : callHandlers) { - handler->onCallAcceptByOther(callId, peerId); - } - }); - - connect(_jingle, &IMJingle::receiveCallStateAccepted, this, &IMCall::onCallAccepted); - - connect(_jingle, &IMJingle::receiveCallStateRejected, this, - [&](IMPeerId friendId, QString callId, bool video) { - for (auto handler : callHandlers) { - handler->receiveCallStateRejected(friendId, callId, video); - } - }); - - connect(_jingle, &IMJingle::receiveFriendHangup, this, - [&](QString friendId, int state) { - for (auto handler : callHandlers) { - handler->onHangup( - friendId, (TOXAV_FRIEND_CALL_STATE)state); - } - }); - - connect(_jingle, &IMJingle::receiveFriendHangup, this, - [&](QString friendId, int state) { - for (auto handler : callHandlers) { - handler->onHangup(friendId, (TOXAV_FRIEND_CALL_STATE)state); - } - }); - - connect(_jingle, &IMJingle::receiveFriendVideoFrame, - this, - [&](const QString &friendId, // - uint16_t w, uint16_t h, // - const uint8_t *y, const uint8_t *u, const uint8_t *v, - int32_t ystride, int32_t ustride, int32_t vstride) { - emit receiveFriendVideoFrame(friendId, // - w, h, // - y, u, v, // - ystride, ustride, vstride); - }); - - connect(_jingle, &IMJingle::receiveSelfVideoFrame, this, - [&](uint16_t w, uint16_t h, // - const uint8_t *y, const uint8_t *u, const uint8_t *v, - int32_t ystride, int32_t ustride, int32_t vstride) { - emit receiveSelfVideoFrame(w, h, // - y, u, v, // - ystride, ustride, vstride); - }); -} - -//对方接受呼叫 -void IMCall::onCallAccepted(IMPeerId peerId, QString callId, bool video) -{ - qDebug() << __func__ - << "peerId:" << peerId.toString() - << "sId" << callId - << "video?" << video; + qDebug() << __func__ << _jingle; + + /** + * callHandlers + */ + connect(_jingle, &IMCall ::receiveCallRequest, this, + [&](IMPeerId peerId, QString callId, bool audio, bool video) { + for (auto handler : callHandlers) { + handler->onCall(peerId, callId, audio, video); + } + }); + + connect(_jingle, &IMCall::receiveCallRetract, this, [&](QString friendId, int state) { + for (auto handler : callHandlers) { + handler->onCallRetract(friendId, state); + } + }); + + connect(_jingle, &IMCall::receiveCallAcceptByOther, this, + [&](const QString& callId, const IMPeerId& peerId) { + for (auto handler : callHandlers) { + handler->onCallAcceptByOther(callId, peerId); + } + }); + + connect(_jingle, &IMCall::receiveCallStateAccepted, this, &IMCall::onCallAccepted); + + connect(_jingle, &IMCall::receiveCallStateRejected, this, + [&](IMPeerId friendId, QString callId, bool video) { + for (auto handler : callHandlers) { + handler->receiveCallStateRejected(friendId, callId, video); + } + }); + + connect(_jingle, &IMCall::receiveFriendHangup, this, [&](QString friendId, int state) { + for (auto handler : callHandlers) { + handler->onHangup(friendId, (CallState)state); + } + }); + + connect(_jingle, &IMCall::receiveFriendHangup, this, [&](QString friendId, int state) { + for (auto handler : callHandlers) { + handler->onHangup(friendId, (CallState)state); + } + }); + + // connect(_jingle, &IMCall::receiveFriendVideoFrame, + // this, + // [&](const QString &friendId, // + // uint16_t w, uint16_t h, // + // const uint8_t *y, const uint8_t *u, const uint8_t *v, + // int32_t ystride, int32_t ustride, int32_t vstride) { + // emit receiveFriendVideoFrame(friendId, // + // w, h, // + // y, u, v, // + // ystride, ustride, vstride); + // }); + // + // connect(_jingle, &IMCall::receiveSelfVideoFrame, this, + // [&](uint16_t w, uint16_t h, // + // const uint8_t *y, const uint8_t *u, const uint8_t *v, + // int32_t ystride, int32_t ustride, int32_t vstride) { + // emit receiveSelfVideoFrame(w, h, // + // y, u, v, // + // ystride, ustride, vstride); + // }); +} + +// 对方接受呼叫 +void IMCall::onCallAccepted(IMPeerId peerId, QString callId, bool video) { + qDebug() << __func__ << "peerId:" << peerId.toString() << "sId" << callId << "video?" << video; for (auto handler : callHandlers) { handler->receiveCallStateAccepted(peerId, callId, video); } } +bool IMCall::callToFriend(const QString& friendId, const QString& sId, bool video) { + qDebug() << __func__ << "friend:" << friendId << "sId" << sId << "video?" << video; + jingle->proposeJingleMessage(friendId, sId, video); -bool IMCall::callToFriend(const QString &friendId, const QString &sId, bool video) { - qDebug() << __func__ <<"friend:" << friendId <<"sId" << sId << "video?" << video; + auto resources = im->getOnlineResources(stdstring(friendId)); + if (resources.empty()) { + qWarning() << "Can not find online friends" << friendId; + return false; + } + jingle->proposeJingleMessage(friendId, sId, video); + qDebug() << "Sent propose jingle message."; + return true; +} - auto im = ok::session::AuthSession::Instance()->im(); - jingle->proposeJingleMessage(friendId, sId, video); +bool IMCall::callToPeerId(const IMPeerId& to, const QString& sId, bool video) { + qDebug() << QString("peerId:%1 video:%2").arg((to.toString())).arg(video); + auto r = createCall(to, sId, video); + qDebug() << "createdCall=>" << r; + return r; +} + +bool IMCall::callAnswerToFriend(const IMPeerId& f, const QString& callId, bool video) { + return answer(f, callId, video); +} - auto resources = im->getOnlineResources(stdstring(friendId)); - if (resources.empty()) { - qWarning() << "Can not find online friends" << friendId; - return false; - } +void IMCall::callRetract(const IMContactId& f, const QString& sId) { cancelCall(f, sId); } - jingle->proposeJingleMessage(friendId, sId, video); - qDebug() << "Sent propose jingle message."; - return true; +void IMCall::callReject(const IMPeerId& f, const QString& sId) { rejectCall(f, sId); } + +// startCall +bool IMCall::startCall(const QString& friendId, const QString& sId, bool video) { + qDebug() << __func__ << "friendId:" << friendId << "video:" << video; + + auto resources = im->getOnlineResources(stdstring(friendId)); + if (resources.empty()) { + qWarning() << "目标用户不在线!"; + return false; + } + + sendCallToResource(friendId, sId, video); + return true; } -bool IMCall::callToPeerId(const IMPeerId &to, const QString &sId, bool video) { +bool IMCall::sendCallToResource(const QString& friendId, const QString& sId, bool video) { + proposeJingleMessage(friendId, sId, video); + return true; +} - qDebug() << QString("peerId:%1 video:%2").arg((to.toString())).arg(video); +bool IMCall::createCall(const IMPeerId& to, const QString& sId, bool video) { + qDebug() << __func__ << "to:" << to.toString() << "sId:" << sId; - auto r = jingle->createCall(to, sId, video ); + auto ws = createSession(to, sId, lib::ortc::JingleCallType::av); - qDebug() <<"createdCall=>" << r; + auto rtc = lib::ortc::OkRTCManager::getInstance()->getRtc(); + rtc->addRTCHandler(this); - return r; + bool createdCall = rtc->call(stdstring(to.toString()), stdstring(sId), video); + if (createdCall) { + ws->createOffer(stdstring(to.toString())); + } + + return createdCall; } -bool IMCall::callAnswerToFriend(const IMPeerId &f, const QString &callId, - bool video) { - qDebug() <<__func__ << "peer:" << f.toString(); - return jingle->answer(f, callId, video); +void IMCall::cancel(const QString& friendId) { + qDebug() << __func__ << friendId; + + auto sId = m_friendSessionMap.value(IMPeerId(friendId)); + + auto session = m_sessionMap.value(sId); + if (session) { + cancelCall(IMContactId{friendId}, qstring(session->getSession()->sid())); + clearSessionInfo(session->getSession()); + } } -void IMCall::callRetract(const IMContactId &f, const QString &sId) { - jingle->cancelCall(f, sId); +void IMCall::cancelCall(const IMContactId& friendId, const QString& sId) { + qDebug() << __func__ << friendId.toString() << sId; + + IMJingleSession* s = findSession(sId); + if (s) { + s->doTerminate(); + s->setCallStage(CallStage::StageNone); + clearSessionInfo(s->getSession()); + } + retractJingleMessage(friendId.toString(), sId); + // else { + // jingle-message + // if (s->direction() == CallDirection:: CallOut) { + // } else if (s->direction() == CallDirection:: CallIn) { + // rejectJingleMessage(friendId.toString(), sId); + // } + // } } -void IMCall::callReject(const IMPeerId &f, const QString &sId) -{ - jingle->rejectCall(f, sId); +void IMCall::rejectCall(const IMPeerId& peerId, const QString& sId) { + qDebug() << __func__ << peerId.toString() << sId; + + IMJingleSession* s = findSession(sId); + if (s) { + s->doTerminate(); + clearSessionInfo(s->getSession()); + } else { + rejectJingleMessage(peerId.toString(), sId); + } } -void IMCall::setMute(bool mute) { - jingle->setMute(mute); +bool IMCall::answer(const IMPeerId& peerId, const QString& callId, bool video) { + qDebug() << __func__ << "peer:" << peerId.toString() << "video:" << video; + + auto rtc = lib::ortc::OkRTCManager::getInstance()->getRtc(); + rtc->addRTCHandler(this); + + acceptJingleMessage(peerId, callId, video); + + return true; } +void IMCall::setMute(bool mute) { lib::ortc::OkRTCManager::getInstance()->getRtc()->setMute(mute); } + void IMCall::setRemoteMute(bool mute) { - jingle->setRemoteMute(mute); + lib::ortc::OkRTCManager::getInstance()->getRtc()->setRemoteMute(mute); +} + +void IMCall::onCreatePeerConnection(const std::string& sId, const std::string& peerId, bool ok) { + auto p = qstring(peerId); + auto s = qstring(sId); + + qDebug() << __func__ << "sId:" << s << "peerId:" << p << "isOk=>" << ok; + + // emit call->sig_createPeerConnection(s, p, ok); +} + +void IMCall::onRTP(const std::string& sid, // + const std::string& peerId, // + const lib::ortc::OJingleContentAv& oContext) { + auto sId = qstring(sid); + qDebug() << __func__ << "sId:" << sId << "peerId:" << qstring(peerId); + + PluginList plugins; + oContext.toPlugins(plugins); + + auto pSession = findSession(sId); + if (!pSession) { + qWarning() << "Unable to find session" << &sId; + return; + } + + if (pSession->direction() == CallDirection::CallIn) { + pSession->getSession()->sessionAccept(plugins); + } else if (pSession->direction() == CallDirection::CallOut) { + pSession->getSession()->sessionInitiate(plugins); + } } +void IMCall::onIce(const std::string& sId, // + const std::string& peerId, // + const lib::ortc::OIceUdp& oIceUdp) { + auto sid = qstring(sId); + + qDebug() << __func__ << "sId:" << sid << "peerId:" << qstring(peerId) + << "mid:" << qstring(oIceUdp.mid) << "mline:" << oIceUdp.mline; + + auto* session = findSession(sid); + if (!session) { + qWarning() << "Unable to find session:" << &sId; + return; + } + + auto* iceUdp = new ICEUDP(oIceUdp.pwd, oIceUdp.ufrag, oIceUdp.candidates); + iceUdp->setDtls(oIceUdp.dtls); + + PluginList pluginList; + pluginList.emplace_back(iceUdp); + auto c = new Jingle::Content(oIceUdp.mid, pluginList); + session->getSession()->transportInfo(c); +} +/** + * 视频渲染 + * @param peerId + * @param image + */ +void IMCall::onRender(const std::string& peerId, lib::ortc::RendererImage image) { + if (peerId.empty()) { + emit receiveSelfVideoFrame(image.width_, image.height_, image.y, image.u, image.v, + image.ystride, image.ustride, image.vstride); + } else { + emit receiveFriendVideoFrame(IMPeerId(peerId).toFriendId(), image.width_, image.height_, + image.y, image.u, image.v, image.ystride, image.ustride, + image.vstride); + } } + +} // namespace lib::messenger diff --git a/src/lib/messenger/IMCall.h b/src/lib/messenger/IMCall.h index d703eb59..c26d8c21 100644 --- a/src/lib/messenger/IMCall.h +++ b/src/lib/messenger/IMCall.h @@ -18,59 +18,9 @@ #define OKMSG_PROJECT_IMCALL_H #include "IMFriend.h" - -#include -#include - +#include "IMJingle.h" #include "tox/toxav.h" - - - -enum TOXAV_FRIEND_CALL_STATE { - - /** - * The empty bit mask. None of the bits specified below are set. - */ - TOXAV_FRIEND_CALL_STATE_NONE = 0, - - /** - * Set by the AV core if an error occurred on the remote end or if friend - * timed out. This is the final state after which no more state - * transitions can occur for the call. This call state will never be triggered - * in combination with other call states. - */ - TOXAV_FRIEND_CALL_STATE_ERROR = 1, - - /** - * The call has finished. This is the final state after which no more state - * transitions can occur for the call. This call state will never be - * triggered in combination with other call states. - */ - TOXAV_FRIEND_CALL_STATE_FINISHED = 2, - - /** - * The flag that marks that friend is sending audio. - */ - TOXAV_FRIEND_CALL_STATE_SENDING_A = 4, - - /** - * The flag that marks that friend is sending video. - */ - TOXAV_FRIEND_CALL_STATE_SENDING_V = 8, - - /** - * The flag that marks that friend is receiving audio. - */ - TOXAV_FRIEND_CALL_STATE_ACCEPTING_A = 16, - - /** - * The flag that marks that friend is receiving video. - */ - TOXAV_FRIEND_CALL_STATE_ACCEPTING_V = 32, - -}; - namespace ok::session { class AuthSession; } @@ -81,47 +31,8 @@ class OkRTCManager; namespace lib::messenger { -class CallHandler { -public: - virtual void onCall(const IMPeerId &peerId, // - const QString &callId, // - bool audio, bool video) = 0; - - virtual void onCallRetract(const QString &friendId, // - int state) = 0; - - virtual void onCallAcceptByOther(const QString& callId, const IMPeerId & peerId) = 0; - - virtual void receiveCallStateAccepted(IMPeerId friendId, // - QString callId, // - bool video) = 0; - - virtual void receiveCallStateRejected(IMPeerId friendId, // - QString callId, // - bool video) = 0; - - virtual void onHangup(const QString &friendId, // - TOXAV_FRIEND_CALL_STATE state) = 0; - - virtual void onSelfVideoFrame(uint16_t w, uint16_t h, // - const uint8_t *y, // - const uint8_t *u, // - const uint8_t *v, // - int32_t ystride, // - int32_t ustride, // - int32_t vstride) = 0; - - virtual void onFriendVideoFrame(const QString &friendId, // - uint16_t w, uint16_t h, // - const uint8_t *y, // - const uint8_t *u, // - const uint8_t *v, // - int32_t ystride, // - int32_t ustride, // - int32_t vstride) = 0; -}; -class Messenger; +class IM; class IMJingle; enum class CallDirection; @@ -131,61 +42,98 @@ struct IMCall0 { CallDirection direction; }; -class IMCall : public QObject { +class IMCall : public IMJingle, public lib::ortc::OkRTCHandler { Q_OBJECT public: - IMCall ( QObject *parent = nullptr); - void addCallHandler(CallHandler *); - bool callToGroup(const QString &g); + IMCall(IM* im, QObject* parent = nullptr); + + void onCreatePeerConnection(const std::string& sId, const std::string& peerId, + bool ok) override; + + // onRTP + void onRTP(const std::string& sId, // + const std::string& friendId, // + const lib::ortc::OJingleContentAv& oContext) override; + + // onIce + void onIce(const std::string& sId, // + const std::string& friendId, // + const lib::ortc::OIceUdp&) override; + + // Renderer + void onRender(const std::string& peerId, lib::ortc::RendererImage image) override; + + void addCallHandler(CallHandler*); + bool callToGroup(const QString& g); // 发起呼叫邀请 - bool callToFriend(const QString &f, const QString &sId, bool video); + bool callToFriend(const QString& f, const QString& sId, bool video); // 创建呼叫 - bool callToPeerId(const IMPeerId &to, const QString &sId, bool video); + bool callToPeerId(const IMPeerId& to, const QString& sId, bool video); // 应答呼叫 - bool callAnswerToFriend(const IMPeerId &peer, const QString &callId, bool video); + bool callAnswerToFriend(const IMPeerId& peer, const QString& callId, bool video); // 取消呼叫 - void callRetract(const IMContactId &f, const QString &sId); + void callRetract(const IMContactId& f, const QString& sId); // 拒绝呼叫 - void callReject(const IMPeerId &f, const QString &sId); + void callReject(const IMPeerId& f, const QString& sId); // 静音功能 void setMute(bool mute); void setRemoteMute(bool mute); - signals: - void sig_createPeerConnection(const QString sId, - const QString peerId, - bool ok); - - void receiveSelfVideoFrame(uint16_t w, uint16_t h, // - const uint8_t *y, // - const uint8_t *u, // - const uint8_t *v, // - int32_t ystride, // - int32_t ustride, // + void sig_createPeerConnection(const QString sId, const QString peerId, bool ok); + + void receiveSelfVideoFrame(uint16_t w, uint16_t h, // + const uint8_t* y, // + const uint8_t* u, // + const uint8_t* v, // + int32_t ystride, // + int32_t ustride, // + int32_t vstride); + + void receiveFriendVideoFrame(const QString& friendId, // + uint16_t w, uint16_t h, // + const uint8_t* y, // + const uint8_t* u, // + const uint8_t* v, // + int32_t ystride, // + int32_t ustride, // int32_t vstride); - void receiveFriendVideoFrame(const QString &friendId, // - uint16_t w, uint16_t h, // - const uint8_t *y, // - const uint8_t *u, // - const uint8_t *v, // - int32_t ystride, // - int32_t ustride, // - int32_t vstride); - private: - void connectJingle(IMJingle *jingle); - IMJingle *jingle; - ok::session::AuthSession *session; - std::vector callHandlers; + void connectJingle(IMJingle* jingle); + + /** + * 发起呼叫 + * @param friendId + * @param video + * @return + */ + bool startCall(const QString& friendId, const QString& sId, bool video); + + bool sendCallToResource(const QString& friendId, const QString& sId, bool video); + + bool createCall(const IMPeerId& to, const QString& sId, bool video); + + bool answer(const IMPeerId& to, const QString& callId, bool video); + + void cancel(const QString& friendId); + // 取消呼叫 + void cancelCall(const IMContactId& friendId, const QString& sId); + void rejectCall(const IMPeerId& friendId, const QString& sId); + + void join(const JID& room); + + IM* im; + IMJingle* jingle; + ok::session::AuthSession* session; + std::vector callHandlers; public slots: - void onCallAccepted(IMPeerId peerId, QString callId, bool video); + void onCallAccepted(IMPeerId peerId, QString callId, bool video); }; -} // namespace lib::messenger -using ToxAV = lib::messenger::IMCall; -#endif // OKMSG_PROJECT_IMCALL_H +} // namespace lib::messenger + +#endif diff --git a/src/lib/messenger/IMConference.cpp b/src/lib/messenger/IMConference.cpp index 109b6745..e2aead53 100644 --- a/src/lib/messenger/IMConference.cpp +++ b/src/lib/messenger/IMConference.cpp @@ -15,110 +15,102 @@ #include #include -#include "base/logs.h" #include #include +#include "base/logs.h" namespace lib { namespace messenger { using namespace gloox; -IMConference::IMConference(Client *client, - Jingle::SessionHandler *sessionHandler) - : _client(client), _sessionHandler(sessionHandler), - delayCaller_((std::make_unique())) { - -// _conferenceManager = -// std::make_unique(_client, this); +IMConference::IMConference(Client* client, Jingle::SessionHandler* sessionHandler) + : _client(client) + , _sessionHandler(sessionHandler) + , delayCaller_((std::make_unique())) { + // _conferenceManager = + // std::make_unique(_client, this); } -//void IMConference::onStart(const gloox::Conference *j) { -// auto c = const_cast(j); -// qDebug(("room:%1").arg(c->room().c_str())) -// qDebug(("ready:%1").arg(c->ready())) -// qDebug(("auth:%1").arg(c->auth())) -// qDebug(("focusJid:%1").arg(qstring(c->focusJid().full()))) -// this->setVideoMute(c->room()); +// void IMConference::onStart(const gloox::Conference *j) { +// auto c = const_cast(j); +// qDebug(("room:%1").arg(c->room().c_str())) +// qDebug(("ready:%1").arg(c->ready())) +// qDebug(("auth:%1").arg(c->auth())) +// qDebug(("focusJid:%1").arg(qstring(c->focusJid().full()))) +// this->setVideoMute(c->room()); // // -//} +// } /** * 发起会议 * @param jid */ -void IMConference::start(const JID &jid) { - +void IMConference::start(const JID& jid) {} + +void IMConference::join(const std::string& room) { + // qDebug(("room:%1").arg(qstring(room))); + // std::string room_host = room + "@" + CONFERENCE_HOST; + // std::string machineUid = _client->getID(); + + // JID focus(XMPP_CONFERENCE_FOCUS); + // Conference* _conference2 = new Conference + // (client->client(), focus, this); + // _room = std::make_unique(_client, JID(room), this, nullptr); + // _room->join(); + // _room->getRoomInfo(); + // _room->getRoomItems(); + + // static JID focus("focus.meet.chuanshaninfo.com"); + // IQ iq(IQ::IqType::Set, focus, _client->getID()); + // iq.addExtension(new Conference(focus, room, machineUid)); + // _client->send(iq); + // + // delayCaller_->call(5 * 1000, [&]() { this->setVideoMute(room); }); } -void IMConference::join(const std::string &room) { -// qDebug(("room:%1").arg(qstring(room))); - // std::string room_host = room + "@" + CONFERENCE_HOST; - // std::string machineUid = _client->getID(); - - // JID focus(XMPP_CONFERENCE_FOCUS); - // Conference* _conference2 = new Conference - // (client->client(), focus, this); - // _room = std::make_unique(_client, JID(room), this, nullptr); - // _room->join(); - // _room->getRoomInfo(); - // _room->getRoomItems(); - - // static JID focus("focus.meet.chuanshaninfo.com"); - // IQ iq(IQ::IqType::Set, focus, _client->getID()); - // iq.addExtension(new Conference(focus, room, machineUid)); - // _client->send(iq); - // - // delayCaller_->call(5 * 1000, [&]() { this->setVideoMute(room); }); -} - -void IMConference::setVideoMute(const std::string &room) { - JID to(room); +void IMConference::setVideoMute(const std::string& room) { + JID to(room); - auto cap = new Capabilities(); - cap->setNode("http://jitsi.org/jitsimeet"); + auto cap = new Capabilities(); + cap->setNode("http://jitsi.org/jitsimeet"); -// Presence p(Presence::PresenceType::Available, to); -// p.addExtension(new MUCRoom::MUC); -// p.addExtension(new VideoMuted(false)); -// p.addExtension(cap); -// _client->sendPresence(p); + // Presence p(Presence::PresenceType::Available, to); + // p.addExtension(new MUCRoom::MUC); + // p.addExtension(new VideoMuted(false)); + // p.addExtension(cap); + // _client->sendPresence(p); } // Disco handler -void IMConference::handleDiscoInfo(const JID &from, const Disco::Info &info, - int context) { - QString _from = QString::fromStdString(from.full()); +void IMConference::handleDiscoInfo(const JID& from, const Disco::Info& info, int context) { + QString _from = QString::fromStdString(from.full()); -// qDebug(("from=%1 context=%2").arg(_from).arg(context)); + // qDebug(("from=%1 context=%2").arg(_from).arg(context)); - // const StringList features = info.features(); - // for(auto feature: features){ - // qDebug(("feature=%1").arg(QString::fromStdString(feature))); - // } + // const StringList features = info.features(); + // for(auto feature: features){ + // qDebug(("feature=%1").arg(QString::fromStdString(feature))); + // } - const Disco::IdentityList &identities = info.identities(); - for (auto identity : identities) - qDebug() << "identity=" << qstring(identity->name()); + const Disco::IdentityList& identities = info.identities(); + for (auto identity : identities) qDebug() << "identity=" << qstring(identity->name()); } -void IMConference::handleDiscoItems(const JID &from, const Disco::Items &items, - int context) { - QString _from = QString::fromStdString(from.full()); -// qDebug(("from=%1 context=%2").arg(_from).arg(context)); +void IMConference::handleDiscoItems(const JID& from, const Disco::Items& items, int context) { + QString _from = QString::fromStdString(from.full()); + // qDebug(("from=%1 context=%2").arg(_from).arg(context)); } -void IMConference::handleDiscoError(const JID &from, const gloox::Error *error, - int context) { - - QString _from = qstring(from.full()); -// qDebug(("from=%1 context=%2 error=%3") -// .arg(_from) -// .arg(context) -// .arg(qstring(error->text()))); +void IMConference::handleDiscoError(const JID& from, const gloox::Error* error, int context) { + QString _from = qstring(from.full()); + // qDebug(("from=%1 context=%2 error=%3") + // .arg(_from) + // .arg(context) + // .arg(qstring(error->text()))); } // Presence Han -} // namespace messenger -} // namespace network +} // namespace messenger +} // namespace lib diff --git a/src/lib/messenger/IMConference.h b/src/lib/messenger/IMConference.h index e6c1bcd8..e0d4beaa 100644 --- a/src/lib/messenger/IMConference.h +++ b/src/lib/messenger/IMConference.h @@ -13,56 +13,54 @@ #ifndef IM_CONFERENCE_H #define IM_CONFERENCE_H -#include "base/timer.h" #include #include #include #include +#include "base/timer.h" namespace lib { namespace messenger { using namespace gloox; -class IMConference : public QObject, - public DiscoHandler { - Q_OBJECT +class IMConference : public QObject, public DiscoHandler { + Q_OBJECT public: - IMConference(Client *client, Jingle::SessionHandler *sessionHandler); + IMConference(Client* client, Jingle::SessionHandler* sessionHandler); - void start(const JID &jid); + void start(const JID& jid); - void join(const std::string &room); + void join(const std::string& room); - void setVideoMute(const std::string &room); + void setVideoMute(const std::string& room); - // Disco handler - virtual void handleDiscoInfo(const JID &from, // - const Disco::Info &, // - int ontext) override; + // Disco handler + virtual void handleDiscoInfo(const JID& from, // + const Disco::Info&, // + int ontext) override; - virtual void handleDiscoItems(const JID &from, // - const Disco::Items &, // - int context) override; + virtual void handleDiscoItems(const JID& from, // + const Disco::Items&, // + int context) override; - virtual void handleDiscoError(const JID &from, // - const gloox::Error *, // - int context) override; + virtual void handleDiscoError(const JID& from, // + const gloox::Error*, // + int context) override; -// virtual void onStart(const gloox::Conference *j) override; + // virtual void onStart(const gloox::Conference *j) override; private: - Client *_client; - Jingle::SessionHandler *_sessionHandler; + Client* _client; + Jingle::SessionHandler* _sessionHandler; -// std::unique_ptr _conferenceManager; - std::shared_ptr<::base::DelayedCallTimer> delayCaller_; + // std::unique_ptr _conferenceManager; + std::shared_ptr<::base::DelayedCallTimer> delayCaller_; signals: - void groupListReceived(const QString &peerId); - + void groupListReceived(const QString& peerId); }; -} // namespace IM -} // namespace lib +} // namespace messenger +} // namespace lib #endif diff --git a/src/lib/messenger/IMFile.cpp b/src/lib/messenger/IMFile.cpp index 4a3a0b73..e600fe1f 100644 --- a/src/lib/messenger/IMFile.cpp +++ b/src/lib/messenger/IMFile.cpp @@ -10,126 +10,302 @@ * Mulan PubL v2 for more details. */ -#include "IM.h" #include "IMFile.h" -#include "IMJingle.h" -#include "lib/session/AuthSession.h" -#include "base/logs.h" -#include #include #include +#include #include +#include "IM.h" +#include "IMFile.h" +#include "IMFileTask.h" +#include "base/logs.h" +#include "lib/session/AuthSession.h" namespace lib { namespace messenger { -QString File::toString() const -{ +QString File::toString() const { return QString("{id:%1, sId:%2, name:%3, path:%4, size:%5, status:%6, direction:%7}") - .arg(id).arg(sId).arg(name).arg(path).arg(size) - .arg((int)status).arg((int)direction); + .arg(id) + .arg(sId) + .arg(name) + .arg(path) + .arg(size) + .arg((int)status) + .arg((int)direction); } -QDebug &operator<<(QDebug &debug, const File &f) { - QDebugStateSaver saver(debug); - debug.nospace() << f.toString(); - return debug; +QDebug& operator<<(QDebug& debug, const File& f) { + QDebugStateSaver saver(debug); + debug.nospace() << f.toString(); + return debug; } -IMFile::IMFile(QObject *parent): QObject(parent) -{ +IMFile::IMFile(IM* im, QObject* parent) : IMJingle(im, parent) { qRegisterMetaType("File"); - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); - - jingle = IMJingle::getInstance(); - jingle->setFileHandlers(&fileHandlers); + // jingle = IMJingle::getInstance(); + // jingle->setFileHandlers(&fileHandlers); /*file handler*/ - connect(jingle, &IMJingle::receiveFileChunk, this, - [&](const IMContactId &friendId, const QString &sId, - int seq, const std::string& chunk) -> void { - for (auto handler : fileHandlers) { - handler->onFileRecvChunk(friendId.toString(), sId, seq, chunk); - } - }); + // connect(jingle, &IMFile::receiveFileChunk, this, [&](const IMContactId &friendId, const + // QString &sId, int seq, const std::string &chunk) -> void { + // for (auto handler : fileHandlers) { + // handler->onFileRecvChunk(friendId.toString(), sId, seq, chunk); + // } + // }); + // + // connect(jingle, &IMFile::receiveFileFinished, this, [&](const IMContactId &friendId, const + // QString &sId) -> void { + // for (auto handler : fileHandlers) { + // handler->onFileRecvFinished(friendId.toString(), sId); + // } + // }); - connect(jingle, &IMJingle::receiveFileFinished, this, - [&](const IMContactId &friendId,const QString &sId) -> void { - for (auto handler : fileHandlers) { - handler->onFileRecvFinished(friendId.toString(), sId); - } - }); - - connect(jingle, &IMJingle::receiveFileRequest, this, - [&](const QString &friendId, const File &file) { - for (auto h : fileHandlers) { - h->onFileRequest(friendId, file); - } - }); + // connect(jingle, &IMFile::receiveFileRequest, this, [&](const QString &friendId, const File + // &file) { + // for (auto h : fileHandlers) { + // h->onFileRequest(friendId, file); + // } + // }); +} +IMFile::~IMFile() { + // disconnect(jingle, &IMFile::receiveFileChunk, this); } -IMFile::~IMFile() -{ -// disconnect(jingle, &IMJingle::receiveFileChunk, this); +void IMFile::addFileHandler(FileHandler* handler) { fileHandlers.emplace_back(handler); } +void IMFile::fileRejectRequest(QString friendId, const File& file) { + auto sId = file.sId; + qDebug() << __func__ << sId; + rejectFileRequest(friendId, sId); } -void IMFile::addFileHandler(FileHandler *handler) { - fileHandlers.emplace_back(handler); +void IMFile::fileAcceptRequest(QString friendId, const File& file) { + auto sId = file.sId; + qDebug() << __func__ << sId; + acceptFileRequest(friendId, file); } -void IMFile::fileRejectRequest(QString friendId, const File &file) { - auto sId = file.sId; - qDebug() << __func__<rejectFileRequest(friendId, sId); +void IMFile::fileCancel(QString fileId) { qDebug() << __func__ << "file" << fileId; } + +void IMFile::fileFinishRequest(QString friendId, const QString& sId) { + qDebug() << __func__ << sId; + finishFileRequest(friendId, sId); } -void IMFile::fileAcceptRequest(QString friendId, const File &file) { - auto sId = file.sId; - qDebug() << __func__<acceptFileRequest(friendId, file); +void IMFile::fileFinishTransfer(QString friendId, const QString& sId) { + qDebug() << __func__ << sId; + finishFileTransfer(friendId, sId); +} + +bool IMFile::fileSendToFriend(const QString& f, const File& file) { + qDebug() << __func__ << "friend:" << f << "file:" << file.id; + + auto bare = stdstring(f); + + auto resources = im->getOnlineResources(bare); + if (resources.empty()) { + qWarning() << "Can not find online friends:" << f; + return false; + } + + JID jid(bare); + for (auto& r : resources) { + jid.setResource(r); + sendFileToResource(jid, file); + } + + return jingle; +} + +void IMFile::addFile(const File& f) { m_waitSendFiles.append(f); } + +void IMFile::doStartFileSendTask(const Session* session, const File& file) { + qDebug() << __func__ << file.sId; + + auto* fileTask = new IMFileTask(session->remote(), &file, im); + connect(fileTask, &IMFileTask::fileSending, + [&](const JID& m_friendId, const File& m_file, int m_seq, int m_sentBytes, bool end) { + for (auto h : fileHandlers) { + h->onFileSendInfo(qstring(m_friendId.bare()), m_file, m_seq, m_sentBytes, end); + } + + // emit sendFileInfo(qstring(m_friendId.bare()), m_file, m_seq, + // m_sentBytes, end); + }); + + connect(fileTask, &IMFileTask::fileAbort, + [&](const JID& m_friendId, const File& m_file, int m_sentBytes) { + // emit sendFileAbort(qstring(m_friendId.bare()), m_file, m_sentBytes); + for (auto h : fileHandlers) { + h->onFileSendAbort(qstring(m_friendId.bare()), m_file, m_sentBytes); + } + }); + + connect(fileTask, &IMFileTask::fileError, + [&](const JID& m_friendId, const File& m_file, int m_sentBytes) { + for (auto h : fileHandlers) { + h->onFileSendError(qstring(m_friendId.bare()), m_file, m_sentBytes); + } + // emit sendFileError(qstring(m_friendId.bare()), m_file, + // m_sentBytes); + }); + fileTask->start(); + m_fileSenderMap.insert(file.id, fileTask); + qDebug() << __func__ << ("Send file task has been stared.") << ((file.id)); } -void IMFile::fileCancel(QString fileId) { - qDebug() << __func__ << "file" << fileId; +void IMFile::doStopFileSendTask(const Session* session, const File& file) { + Q_UNUSED(session) + qDebug() << __func__ << file.sId; + auto* fileTask = m_fileSenderMap.value(file.sId); + if (!fileTask) { + return; + } + + qDebug() << __func__ << "Send file task will be clear." << file.id; + if (fileTask->isRunning()) { + fileTask->forceQuit(); + } + disconnect(fileTask); + delete fileTask; + + // 返回截断后续处理 + m_fileSenderMap.remove(file.sId); + qDebug() << "Send file task has been clean." << file.id; } -void IMFile::fileFinishRequest(QString friendId, const QString &sId) { - qDebug() << __func__<finishFileRequest(friendId, sId); +/** + * 文件传输 + * @param friendId + * @param file + */ +void IMFile::rejectFileRequest(const QString& friendId, const QString& sId) { + // cancelCall(IMContactId{friendId}, sId); + + // void IMJingle::cancelCall(const IMContactId &friendId, const QString &sId) { + qDebug() << __func__ << friendId << sId; + + IMJingleSession* s = findSession(sId); + if (s) { + s->doTerminate(); + s->setCallStage(CallStage::StageNone); + clearSessionInfo(s->getSession()); + } + retractJingleMessage(friendId, sId); + // else { + // jingle-message + // if (s->direction() == CallDirection:: CallOut) { + // } else if (s->direction() == CallDirection:: CallIn) { + // rejectJingleMessage(friendId.toString(), sId); + // } + // } + // } } -void IMFile::fileFinishTransfer(QString friendId, const QString &sId) { - qDebug() << __func__<finishFileTransfer(friendId, sId); +void IMFile::acceptFileRequest(const QString& friendId, const File& file) { + qDebug() << __func__ << file.name << file.sId << file.id; + + auto* ws = findSession(file.sId); + if (!ws) { + qWarning() << "Unable to find session sId:" << file.sId; + return; + } + + // 协议:https://xmpp.org/extensions/xep-0234.html#requesting + PluginList pluginList; + + Jingle::FileTransfer::FileList files; + files.push_back( + Jingle::FileTransfer::File{.name = stdstring(file.name), .size = (long)file.size}); + + auto ftf = new Jingle::FileTransfer(FileTransfer::Request, files); + + auto ibb = new Jingle::IBB(stdstring(file.txIbb.sid), file.txIbb.blockSize); + + pluginList.emplace_back(ftf); + pluginList.emplace_back(ibb); + + auto c = new Jingle::Content("file", pluginList); + ws->getSession()->sessionAccept(c); } +void IMFile::finishFileRequest(const QString& friendId, const QString& sId) { + qDebug() << __func__ << "sId:" << (sId); + auto* s = findSession(sId); + if (!s) { + qWarning() << "Can not find file session" << sId; + return; + } + s->getSession()->sessionTerminate(new Session::Reason(Session::Reason::Success)); +} -bool IMFile::fileSendToFriend(const QString &f, const File &file) { - qDebug() << __func__ <<"friend:" << f <<"file:" <im(); + auto bare = stdstring(friendId); auto resources = im->getOnlineResources(bare); if (resources.empty()) { - qWarning() << "Can not find online friends:" << f; - return false; + qWarning() << "目标用户不在线!"; + return false; } JID jid(bare); - for (auto &r : resources) { - jid.setResource(r); - jingle->sendFileToResource(jid, file); + for (auto& r : resources) { + jid.setResource(r); + sendFileToResource(jid, file); } - return jingle; + return true; } +bool IMFile::sendFileToResource(const JID& jid, const File& file) { + qDebug() << __func__ << qstring(jid.full()) << "sId:" << file.sId; + auto session = _sessionManager->createSession(jid, this, stdstring(file.sId)); + if (!session) { + qDebug() << "Can not create session!"; + return false; + } + + auto ws = cacheSessionInfo(session, ortc::JingleCallType::file); + + PluginList pl; + + // offer-file + FileTransfer::FileList files; + FileTransfer::File f; + f.name = stdstring(file.name); + f.size = file.size; + files.emplace_back(f); + auto ft = new FileTransfer(FileTransfer::Offer, files); + pl.emplace_back(ft); + // ibb + auto ibb = new Jingle::IBB(stdstring(file.id), 4096); + pl.emplace_back(ibb); + + // content + auto jc = new Jingle::Content("offer-a-file", pl); + session->sessionInitiate(jc); + + // 缓存文件 + auto& nf = const_cast(file); + nf.sId = qstring(session->sid()); + addFile(nf); + + return true; +} -} // namespace IMFile -} // namespace lib +} // namespace messenger +} // namespace lib diff --git a/src/lib/messenger/IMFile.h b/src/lib/messenger/IMFile.h index ecb308ed..eabae9a4 100644 --- a/src/lib/messenger/IMFile.h +++ b/src/lib/messenger/IMFile.h @@ -12,104 +12,86 @@ #ifndef IMFILE_H #define IMFILE_H -#include "lib/messenger/messenger.h" #include #include +#include "IMJingle.h" -namespace gloox{ +namespace gloox { class JID; class BytestreamDataHandler; -} +} // namespace gloox -namespace lib { -namespace messenger { +namespace lib::messenger { +class IMFileTask; class IM; -//不要修改顺序和值 -enum class FileStatus { - INITIALIZING = 0, - PAUSED = 1, - TRANSMITTING = 2, - BROKEN = 3, - CANCELED = 4, - FINISHED = 5, -}; +class IMFile : public IMJingle { + Q_OBJECT +public: + IMFile(IM* im, QObject* parent = nullptr); + ~IMFile(); -//不要修改顺序和值 -enum class FileDirection { - SENDING = 0, - RECEIVING = 1, -}; + void addFile(const File& f); + void addFileHandler(FileHandler*); -enum class FileControl{ - RESUME, PAUSE, CANCEL -}; + /** + * File + */ + void fileRejectRequest(QString friendId, const File& file); + void fileAcceptRequest(QString friendId, const File& file); + void fileFinishRequest(QString friendId, const QString& sId); + void fileFinishTransfer(QString friendId, const QString& sId); + void fileCancel(QString fileId); + bool fileSendToFriend(const QString& f, const File& file); + /** + * 启动文件发送任务 + * @param session + * @param file + */ + void doStartFileSendTask(const Jingle::Session* session, const File& file); -struct FileTxIBB { - QString sid; - int blockSize; -}; + /** + * 停止文件发送任务 + * @param session + * @param file + */ + void doStopFileSendTask(const Jingle::Session* session, const File& file); -struct File { -public: - //id(file id = ibb id) 和 sId(session id) - QString id; - QString sId; - QString name; - QString path; - quint64 size; - FileStatus status; - FileDirection direction; - FileTxIBB txIbb; - [[__nodiscard__ ]] QString toString() const; - friend QDebug &operator<<(QDebug &debug, const File &f); -}; +private: + void rejectFileRequest(const QString& friendId, const QString& sId); + void acceptFileRequest(const QString& friendId, const File& file); + void finishFileRequest(const QString& friendId, const QString& sId); + void finishFileTransfer(const QString& friendId, const QString& sId); -class FileHandler { -public: + bool sendFile(const QString& friendId, const File& file); + bool sendFileToResource(const JID& friendId, const File& file); - virtual void onFileRequest(const QString &friendId, const File &file) = 0; - virtual void onFileRecvChunk(const QString &friendId, const QString &fileId, - int seq, const std::string &chunk) = 0; - virtual void onFileRecvFinished(const QString &friendId, - const QString &fileId) = 0; - virtual void onFileSendInfo(const QString &friendId, const File &file, - int m_seq, int m_sentBytes, bool end) = 0; - virtual void onFileSendAbort(const QString &friendId, const File &file, - int m_sentBytes) = 0; - virtual void onFileSendError(const QString &friendId, const File &file, - int m_sentBytes) = 0; -}; + IM* im; + IMJingle* jingle; + std::vector fileHandlers; + // file + QList m_waitSendFiles; + // k: file.id + QMap m_fileSenderMap; -class IMFile : public QObject{ -public: - IMFile(QObject* parent=nullptr); - ~IMFile(); - void addFileHandler(FileHandler *); +signals: + void sendFileInfo(const QString& friendId, const File& file, int m_seq, int m_sentBytes, + bool end); - /** - * File - */ - void fileRejectRequest(QString friendId, const File &file); - void fileAcceptRequest(QString friendId, const File &file); - void fileFinishRequest(QString friendId, const QString &sId); - void fileFinishTransfer(QString friendId, const QString &sId); - void fileCancel(QString fileId); - bool fileSendToFriend(const QString &f, const File &file); + void sendFileAbort(const QString& friendId, const File& file, int m_sentBytes); + void sendFileError(const QString& friendId, const File& file, int m_sentBytes); + void receiveFileRequest(const QString& friendId, const File& file); -private: - IMJingle *jingle; - std::vector fileHandlers; + void receiveFileChunk(const IMContactId friendId, QString sId, int seq, + const std::string chunk); + void receiveFileFinished(const IMContactId friendId, QString sId); }; -} // namespace messenger -} // namespace lib - -using ToxFile1 = lib::messenger::IMFile; +} // namespace lib::messenger -#endif // OKEDU_CLASSROOM_DESKTOP_IMFILE_H +#endif diff --git a/src/lib/messenger/IMFileTask.cpp b/src/lib/messenger/IMFileTask.cpp index 218e6250..f388399e 100644 --- a/src/lib/messenger/IMFileTask.cpp +++ b/src/lib/messenger/IMFileTask.cpp @@ -10,132 +10,138 @@ namespace lib::messenger { -constexpr int BUF_SIZE = 100 * 1024; // 100k - -IMFileTask::IMFileTask(const gloox::JID &friendId, const File *file, const IM *im) - : m_friendId(friendId), m_file(file), m_im(im), m_byteStream(nullptr), m_buf{BUF_SIZE}, m_seq{0}, m_sentBytes{0}, m_ack_seq{0} { - qDebug() << __func__ << "Create FileSender:" << m_file->id; +constexpr int BUF_SIZE = 100 * 1024; // 100k + +IMFileTask::IMFileTask(const gloox::JID& friendId, const File* file, const IM* im) + : m_friendId(friendId) + , m_file(file) + , m_im(im) + , m_byteStream(nullptr) + , m_buf{BUF_SIZE} + , m_seq{0} + , m_sentBytes{0} + , m_ack_seq{0} { + qDebug() << __func__ << "Create FileSender:" << m_file->id; } IMFileTask::~IMFileTask() { qDebug() << __func__ << "Destroyed FileSender:" << m_file->id; } void IMFileTask::run() { - - QThread::currentThread()->setObjectName(tr("FileSender-%1-%2").arg(qstring(m_friendId.username())).arg(m_file->id)); - - qDebug() << "Start file" << m_file->id; - - /** - * 1、创建流通道 - * https://xmpp.org/extensions/xep-0047.html#create - * - */ - auto client = m_im->getClient(); - // client->registerStanzaExtension(new InBandBytestream::IBB); - - auto iqId = client->getID(); - - m_ibb = std::make_unique(client, - client->logInstance(), // - m_im->self(), // - m_friendId, // - stdstring(m_file->id)); - - m_ibb->registerBytestreamDataHandler(this); - m_ibb->setBlockSize(m_buf); - - bool c = m_ibb->connect(); - qDebug() << "IBBConnect=>" << c; - qFile = std::make_unique(m_file->path); - - // QEventLoop loop; - // connect(this, &IMFileTask::fileSent, &loop, &QEventLoop::quit); - // loop.exec(); - - int waitingSecs = 0; - - for (;;) { - - if (!m_byteStream) { - sleep(1); - - if (waitingSecs++ >= 60) { - qWarning() << "Timeout to wait stream open." << waitingSecs; - break; - } - continue; + QThread::currentThread()->setObjectName( + tr("FileSender-%1-%2").arg(qstring(m_friendId.username())).arg(m_file->id)); + + qDebug() << "Start file" << m_file->id; + + /** + * 1、创建流通道 + * https://xmpp.org/extensions/xep-0047.html#create + * + */ + auto client = m_im->getClient(); + // client->registerStanzaExtension(new InBandBytestream::IBB); + + auto iqId = client->getID(); + + m_ibb = std::make_unique(client, + client->logInstance(), // + m_im->self(), // + m_friendId, // + stdstring(m_file->id)); + + m_ibb->registerBytestreamDataHandler(this); + m_ibb->setBlockSize(m_buf); + + bool c = m_ibb->connect(); + qDebug() << "IBBConnect=>" << c; + qFile = std::make_unique(m_file->path); + + // QEventLoop loop; + // connect(this, &IMFileTask::fileSent, &loop, &QEventLoop::quit); + // loop.exec(); + + int waitingSecs = 0; + + for (;;) { + if (!m_byteStream) { + sleep(1); + + if (waitingSecs++ >= 60) { + qWarning() << "Timeout to wait stream open." << waitingSecs; + break; + } + continue; + } + + QByteArray buf = qFile->read(m_buf); + if (buf.isEmpty()) { + break; + } + bool b = m_byteStream->send(buf.toStdString()); + if (!b) { + qWarning() << "send error"; + emit fileError(m_friendId, *m_file, m_sentBytes); + break; + } + m_seq += 1; + m_sentBytes += buf.size(); + emit fileSending(m_friendId, *m_file, m_ack_seq, m_ack_seq * m_buf, false); } - QByteArray buf = qFile->read(m_buf); - if (buf.isEmpty()) { - break; - } - bool b = m_byteStream->send(buf.toStdString()); - if (!b) { - qWarning() << "send error"; - emit fileError(m_friendId, *m_file, m_sentBytes); - break; + if (m_byteStream) { + m_byteStream->close(); + emit fileSending(m_friendId, *m_file, m_ack_seq, m_sentBytes, true); + } else { + qWarning() << ""; } - m_seq += 1; - m_sentBytes += buf.size(); - emit fileSending(m_friendId, *m_file, m_ack_seq, m_ack_seq * m_buf, false); - } - - if (m_byteStream) { - m_byteStream->close(); - emit fileSending(m_friendId, *m_file, m_ack_seq, m_sentBytes, true); - } else { - qWarning() << ""; - } - - qFile->close(); - qDebug("finished."); + + qFile->close(); + qDebug("finished."); } void IMFileTask::abort() { emit fileAbort(m_friendId, *m_file, m_sentBytes); } -void IMFileTask::handleBytestreamOpen(gloox::Bytestream *bs) { - qDebug() << __func__ << ("file") << qFile->fileName(); - if (!qFile->open(QIODevice::ReadOnly)) { - return; - } - m_byteStream = bs; +void IMFileTask::handleBytestreamOpen(gloox::Bytestream* bs) { + qDebug() << __func__ << ("file") << qFile->fileName(); + if (!qFile->open(QIODevice::ReadOnly)) { + return; + } + m_byteStream = bs; } -void IMFileTask::handleBytestreamClose(gloox::Bytestream *bs) { - qDebug() << __func__ << "closed:" << (qstring(bs->sid())); - emit fileSent(m_friendId, *m_file); +void IMFileTask::handleBytestreamClose(gloox::Bytestream* bs) { + qDebug() << __func__ << "closed:" << (qstring(bs->sid())); + emit fileSent(m_friendId, *m_file); } -void IMFileTask::handleBytestreamData(gloox::Bytestream *bs, const std::string &data) { +void IMFileTask::handleBytestreamData(gloox::Bytestream* bs, const std::string& data) { qDebug() << __func__ << "data:" << qstring(bs->sid()); } -void IMFileTask::handleBytestreamDataAck(gloox::Bytestream *bs) { - qDebug() << __func__ << "acked:" << qstring(bs->sid()); - m_ack_seq += 1; - // 考虑性能关系暂时不处理实时反馈ack - // if(m_ack_seq < m_seq){ - // emit fileSending(m_friendId, m_file, m_ack_seq, m_ack_seq*m_buf, - // false); - // } else{ - // emit fileSending(m_friendId, m_file, m_ack_seq, m_sentBytes, true); - // } +void IMFileTask::handleBytestreamDataAck(gloox::Bytestream* bs) { + qDebug() << __func__ << "acked:" << qstring(bs->sid()); + m_ack_seq += 1; + // 考虑性能关系暂时不处理实时反馈ack + // if(m_ack_seq < m_seq){ + // emit fileSending(m_friendId, m_file, m_ack_seq, m_ack_seq*m_buf, + // false); + // } else{ + // emit fileSending(m_friendId, m_file, m_ack_seq, m_sentBytes, true); + // } } -void IMFileTask::handleBytestreamError(gloox::Bytestream *bs, const gloox::IQ &iq) { - qDebug() << __func__ << qstring(bs->sid()); - fileError(m_friendId, *m_file, m_sentBytes); +void IMFileTask::handleBytestreamError(gloox::Bytestream* bs, const gloox::IQ& iq) { + qDebug() << __func__ << qstring(bs->sid()); + fileError(m_friendId, *m_file, m_sentBytes); } bool IMFileTask::sendFinished() const { return m_file->size == m_sentBytes; } bool IMFileTask::ackFinished() const { return m_seq > 0 && m_seq == m_ack_seq; } void IMFileTask::forceQuit() { - qDebug() << __func__ << "..."; - quit(); - wait(); - qDebug() << __func__ << "completed."; + qDebug() << __func__ << "..."; + quit(); + wait(); + qDebug() << __func__ << "completed."; } -} // namespace lib::messenger +} // namespace lib::messenger diff --git a/src/lib/messenger/IMFileTask.h b/src/lib/messenger/IMFileTask.h index b761ea4f..d59f139f 100644 --- a/src/lib/messenger/IMFileTask.h +++ b/src/lib/messenger/IMFileTask.h @@ -17,14 +17,13 @@ #ifndef OKMSG_PROJECT_IMFILETASK_H #define OKMSG_PROJECT_IMFILETASK_H -#include - #include +#include +#include "IMFile.h" #include #include #include -#include "IMFile.h" class QFile; @@ -34,54 +33,55 @@ class IM; struct File; class IMFileTask : public QThread, public gloox::BytestreamDataHandler { - Q_OBJECT + Q_OBJECT public: - IMFileTask(const gloox::JID &friendId, // - const File *file, // - const IM *im); // + IMFileTask(const gloox::JID& friendId, // + const File* file, // + const IM* im); // - ~IMFileTask(); + ~IMFileTask(); - void run() override; + void run() override; - void abort(); + void abort(); - void handleBytestreamData(gloox::Bytestream *bs, const std::string &data) override; + void handleBytestreamData(gloox::Bytestream* bs, const std::string& data) override; - void handleBytestreamDataAck(gloox::Bytestream *bs) override; + void handleBytestreamDataAck(gloox::Bytestream* bs) override; - void handleBytestreamError(gloox::Bytestream *bs, const gloox::IQ &iq) override; + void handleBytestreamError(gloox::Bytestream* bs, const gloox::IQ& iq) override; - void handleBytestreamOpen(gloox::Bytestream *bs) override; + void handleBytestreamOpen(gloox::Bytestream* bs) override; - void handleBytestreamClose(gloox::Bytestream *bs) override; + void handleBytestreamClose(gloox::Bytestream* bs) override; - void forceQuit(); + void forceQuit(); - bool sendFinished() const; - bool ackFinished() const; + bool sendFinished() const; + bool ackFinished() const; private: - gloox::JID m_friendId; - const File *m_file; - const IM *m_im; - int m_buf; - int m_seq; - quint64 m_sentBytes; - int m_ack_seq; - - std::unique_ptr m_ibb; - std::unique_ptr qFile; - gloox::Bytestream *m_byteStream; + gloox::JID m_friendId; + const File* m_file; + const IM* m_im; + int m_buf; + int m_seq; + quint64 m_sentBytes; + int m_ack_seq; + + std::unique_ptr m_ibb; + std::unique_ptr qFile; + gloox::Bytestream* m_byteStream; public: signals: - void fileSent(const gloox::JID &m_friendId, const File &m_file); - void fileError(const gloox::JID &m_friendId, const File &m_file, int m_sentBytes); - void fileAbort(const gloox::JID &m_friendId, const File &m_file, int m_sentBytes); - void fileSending(const gloox::JID &m_friendId, const File &m_file, int m_seq, int m_sentBytes, bool end); + void fileSent(const gloox::JID& m_friendId, const File& m_file); + void fileError(const gloox::JID& m_friendId, const File& m_file, int m_sentBytes); + void fileAbort(const gloox::JID& m_friendId, const File& m_file, int m_sentBytes); + void fileSending( + const gloox::JID& m_friendId, const File& m_file, int m_seq, int m_sentBytes, bool end); }; -} // namespace lib::messenger +} // namespace lib::messenger -#endif // OKMSG_PROJECT_IMFILETASK_H +#endif // OKMSG_PROJECT_IMFILETASK_H diff --git a/src/lib/messenger/IMFriend.cpp b/src/lib/messenger/IMFriend.cpp index bb25ed48..ff0ad1b8 100644 --- a/src/lib/messenger/IMFriend.cpp +++ b/src/lib/messenger/IMFriend.cpp @@ -15,86 +15,93 @@ // #include "IMFriend.h" -#include "base/basic_types.h" -#include #include #include #include +#include +#include "base/basic_types.h" namespace lib::messenger { -IMContactId::IMContactId(const QString &jid_) { - gloox::JID jid(stdstring(jid_)); - username = qstring(jid.username()); - server = qstring(jid.server()); +IMContactId::IMContactId(const QString& jid_) { + gloox::JID jid(stdstring(jid_)); + username = qstring(jid.username()); + server = qstring(jid.server()); } -IMContactId::IMContactId(const gloox::JID &jid) { - username = qstring(jid.username()); - server = qstring(jid.server()); +IMContactId::IMContactId(const gloox::JID& jid) { + username = qstring(jid.username()); + server = qstring(jid.server()); } -IMContactId::IMContactId(const IMContactId &f) : username(f.username), server(f.server) {} +IMContactId::IMContactId(const IMContactId& f) : username(f.username), server(f.server) {} -bool IMContactId::operator==(const QString &friendId) const { return toString() == friendId; } +bool IMContactId::operator==(const QString& friendId) const { return toString() == friendId; } -bool IMContactId::operator==(const IMContactId &friendId) const { return friendId.username == username && friendId.server == server; } +bool IMContactId::operator==(const IMContactId& friendId) const { + return friendId.username == username && friendId.server == server; +} -bool IMContactId::operator!=(const IMContactId &friendId) const { return friendId.username != username && friendId.server != server; } +bool IMContactId::operator!=(const IMContactId& friendId) const { + return friendId.username != username && friendId.server != server; +} -bool IMContactId::operator<(const lib::messenger::IMContactId &friendId) const { - if (friendId.server.isEmpty()) { - return username < friendId.username; - } - return username < friendId.username // - && server < friendId.server; +bool IMContactId::operator<(const lib::messenger::IMContactId& friendId) const { + if (friendId.server.isEmpty()) { + return username < friendId.username; + } + return username < friendId.username // + && server < friendId.server; } IMPeerId::IMPeerId() = default; -IMPeerId::IMPeerId(const gloox::JID &jid) { - username = qstring(jid.username()); - server = qstring(jid.server()); - resource = qstring(jid.resource()); +IMPeerId::IMPeerId(const gloox::JID& jid) { + username = qstring(jid.username()); + server = qstring(jid.server()); + resource = qstring(jid.resource()); } -IMPeerId::IMPeerId(const QString &peerId) { - assert (peerId.contains("@")); +IMPeerId::IMPeerId(const QString& peerId) { + assert(peerId.contains("@")); auto jid = gloox::JID(peerId.toStdString()); username = qstring(jid.username()); server = qstring(jid.server()); resource = qstring(jid.resource()); - } -bool IMPeerId::operator==(const IMPeerId &peerId) const { - return peerId.username == username // - && peerId.server == server // - && peerId.resource == resource; // +bool IMPeerId::operator==(const IMPeerId& peerId) const { + return peerId.username == username // + && peerId.server == server // + && peerId.resource == resource; // } -std::ostream &operator<<(std::ostream &os, const IMFriend &f) { - os << f.toString().toStdString(); - return os; +std::ostream& operator<<(std::ostream& os, const IMFriend& f) { + os << f.toString().toStdString(); + return os; } -IMFriend::IMFriend(gloox::RosterItem *item) // - : id{IMContactId{qstring(item->jid().bare())}}, // - alias{qstring(item->name())}, // - subscription{item->subscription()}, // - online{item->online()}, // - groups{qstringlist(item->groups())} // +IMFriend::IMFriend(gloox::RosterItem* item) // + : id{IMContactId{qstring(item->jid().bare())}} + , // + alias{qstring(item->name())} + , // + subscription{item->subscription()} + , // + online{item->online()} + , // + groups{qstringlist(item->groups())} // {} IMFriend::IMFriend() {} bool IMFriend::isFriend() const { return subscription == gloox::SubscriptionType::S10nBoth; } -QDebug &operator<<(QDebug &debug, const IMFriend &f) { - QDebugStateSaver saver(debug); - debug.nospace() << f.toString(); - return debug; +QDebug& operator<<(QDebug& debug, const IMFriend& f) { + QDebugStateSaver saver(debug); + debug.nospace() << f.toString(); + return debug; } -} // namespace lib::messenger +} // namespace lib::messenger diff --git a/src/lib/messenger/IMFriend.h b/src/lib/messenger/IMFriend.h index 944acb61..1b3cf9a1 100644 --- a/src/lib/messenger/IMFriend.h +++ b/src/lib/messenger/IMFriend.h @@ -23,20 +23,20 @@ namespace gloox { class JID; class RosterItem; -} // namespace gloox +} // namespace gloox namespace lib::messenger { enum class IMStatus { - Available, /**< The entity is online. */ - Chat, /**< The entity is 'available for chat'. */ - Away, /**< The entity is away. */ - DND, /**< The entity is DND (Do Not Disturb). */ - XA, /**< The entity is XA (eXtended Away). */ - Unavailable, /**< The entity is offline. */ - Probe, /**< This is a presence probe. */ - Error, /**< This is a presence error. */ - Invalid /**< The stanza is invalid. */ + Available, /**< The entity is online. */ + Chat, /**< The entity is 'available for chat'. */ + Away, /**< The entity is away. */ + DND, /**< The entity is DND (Do Not Disturb). */ + XA, /**< The entity is XA (eXtended Away). */ + Unavailable, /**< The entity is offline. */ + Probe, /**< This is a presence probe. */ + Error, /**< This is a presence error. */ + Invalid /**< The stanza is invalid. */ }; /** @@ -44,83 +44,80 @@ enum class IMStatus { * 格式:[username]@[server] */ struct IMContactId { - QString username; - QString server; + QString username; + QString server; - bool operator==(const QString &friendId) const; - bool operator==(const IMContactId &friendId) const; - bool operator!=(const IMContactId &friendId) const; - bool operator<(const IMContactId &friendId) const; + bool operator==(const QString& friendId) const; + bool operator==(const IMContactId& friendId) const; + bool operator!=(const IMContactId& friendId) const; + bool operator<(const IMContactId& friendId) const; - IMContactId() = default; - IMContactId(const IMContactId &); - explicit IMContactId(const QString &jid); - explicit IMContactId(const gloox::JID &jid); + IMContactId() = default; + IMContactId(const IMContactId&); + explicit IMContactId(const QString& jid); + explicit IMContactId(const gloox::JID& jid); - [[nodiscard]] QString getUsername() const { return username; } - [[nodiscard]] QString getServer() const { return server; } + [[nodiscard]] QString getUsername() const { return username; } + [[nodiscard]] QString getServer() const { return server; } - [[nodiscard]] QString toString() const { - if (username.isEmpty()) { - return {}; - } + [[nodiscard]] QString toString() const { + if (username.isEmpty()) { + return {}; + } - if (server.isEmpty()) { - return username; - } + if (server.isEmpty()) { + return username; + } - return username + "@" + server; - } + return username + "@" + server; + } }; struct IMPeerId : public IMContactId { - /** - * [username]@[server]/[resource] - */ - QString resource; - - IMPeerId(); - explicit IMPeerId(const QString &peerId); - explicit IMPeerId(const gloox::JID &jid); - bool operator==(const IMPeerId &peerId) const; - - [[nodiscard]] inline QString toFriendId() const { - return username + "@" + server; - } - - [[nodiscard]] inline QString toString() const { - if (resource.isEmpty()) - return toFriendId(); - return toFriendId() + "/" + resource; - } + /** + * [username]@[server]/[resource] + */ + QString resource; + + IMPeerId(); + explicit IMPeerId(const QString& peerId); + explicit IMPeerId(const gloox::JID& jid); + bool operator==(const IMPeerId& peerId) const; + + [[nodiscard]] inline QString toFriendId() const { return username + "@" + server; } + + [[nodiscard]] inline QString toString() const { + if (resource.isEmpty()) return toFriendId(); + return toFriendId() + "/" + resource; + } }; class IMFriend { public: - IMFriend(); - explicit IMFriend(gloox::RosterItem *pItem); - - IMContactId id; - QString alias; - int subscription; - bool online; - QStringList groups; - - // 互相关注才是朋友 - [[nodiscard]] bool isFriend() const; - - [[nodiscard]] QString toString() const { - return QString("{id: %1, alias: %2, subscription:%3, online:%4, groups:[%5]}") // - .arg(id.toString()) - .arg(alias) - .arg(subscription) - .arg(online) - .arg(groups.join(",")); - } - - friend std::ostream &operator<<(std::ostream &os, const IMFriend &f); - friend QDebug &operator<<(QDebug &debug, const IMFriend &f); + IMFriend(); + explicit IMFriend(gloox::RosterItem* pItem); + + IMContactId id; + QString alias; + int subscription; + bool online; + QStringList groups; + + // 互相关注才是朋友 + [[nodiscard]] bool isFriend() const; + + [[nodiscard]] QString toString() const { + return QString("{id: %1, alias: %2, subscription:%3, online:%4, groups:[%5]}") // + .arg(id.toString()) + .arg(alias) + .arg(subscription) + .arg(online) + .arg(groups.join(",")); + } + + friend std::ostream& operator<<(std::ostream& os, const IMFriend& f); + friend QDebug& operator<<(QDebug& debug, const IMFriend& f); }; -} // namespace lib::messenger -#endif // OKMSG_PROJECT_IMFRIEND_H +} // namespace lib::messenger +#endif // OKMSG_PROJECT_IMFRIEND_H diff --git a/src/lib/messenger/IMGroup.cpp b/src/lib/messenger/IMGroup.cpp index 73e7e922..37f71d80 100644 --- a/src/lib/messenger/IMGroup.cpp +++ b/src/lib/messenger/IMGroup.cpp @@ -16,6 +16,4 @@ #include "IMGroup.h" -namespace lib::messenger{ - -} +namespace lib::messenger {} diff --git a/src/lib/messenger/IMGroup.h b/src/lib/messenger/IMGroup.h index 73baabf3..7c0c464c 100644 --- a/src/lib/messenger/IMGroup.h +++ b/src/lib/messenger/IMGroup.h @@ -17,36 +17,35 @@ #ifndef OKMSG_PROJECT_IMGROUP_H #define OKMSG_PROJECT_IMGROUP_H -#include #include +#include - -namespace lib::messenger{ +namespace lib::messenger { /** * 群聊 */ struct IMGroup { - QString name; - QString description; - QString subject; - QString creationdate; - uint64_t occupants=0; -} ; + QString name; + QString description; + QString subject; + QString creationdate; + uint64_t occupants = 0; +}; /** * 群聊名称 */ struct IMGroupOccupant { - QString jid; - QString nick; - QString affiliation; - QString role; - int status; - //https://xmpp.org/registrar/mucstatus.html - QList codes; + QString jid; + QString nick; + QString affiliation; + QString role; + int status; + // https://xmpp.org/registrar/mucstatus.html + QList codes; }; -} +} // namespace lib::messenger -#endif // OKMSG_PROJECT_IMGROUP_H +#endif // OKMSG_PROJECT_IMGROUP_H diff --git a/src/lib/messenger/IMJingle.cpp b/src/lib/messenger/IMJingle.cpp index 2d2e0a35..863b5971 100644 --- a/src/lib/messenger/IMJingle.cpp +++ b/src/lib/messenger/IMJingle.cpp @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -25,9 +24,6 @@ #include #include "IM.h" -#include "IMFile.h" -#include "IMFileTask.h" -#include "IMCall.h" #include "base/logs.h" namespace lib { @@ -37,116 +33,99 @@ using namespace gloox; using namespace Jingle; using namespace lib::ortc; -inline IM* getIM(){ - return ok::session::AuthSession::Instance()->im(); -} - +IMJingle::IMJingle(IM* im, QObject* parent) : QObject(parent), _im(im) { + qDebug() << __func__ << "Creating"; + + qRegisterMetaType("std::string"); + + auto client = _im->getClient(); + client->registerMessageHandler(this); + client->registerIqHandler(this, ExtIBB); + client->registerStanzaExtension(new Jingle::JingleMessage()); + + // jingle session + _sessionManager = std::make_unique(client, this); + _sessionManager->registerPlugin(new Content()); + + auto disco = client->disco(); + // jingle + disco->addFeature(XMLNS_JINGLE); + disco->addFeature(XMLNS_JINGLE_MESSAGE); + disco->addFeature(XMLNS_JINGLE_ERRORS); + + // jingle file + disco->addFeature(XMLNS_JINGLE_FILE_TRANSFER); + disco->addFeature(XMLNS_JINGLE_FILE_TRANSFER4); + disco->addFeature(XMLNS_JINGLE_FILE_TRANSFER5); + disco->addFeature(XMLNS_JINGLE_FILE_TRANSFER_MULTI); + disco->addFeature(XMLNS_JINGLE_IBB); + _sessionManager->registerPlugin(new FileTransfer()); + _sessionManager->registerPlugin(new IBB()); + + // jingle av + disco->addFeature(XMLNS_JINGLE_ICE_UDP); + disco->addFeature(XMLNS_JINGLE_APPS_DTLS); + disco->addFeature(XMLNS_JINGLE_APPS_RTP); + disco->addFeature(XMLNS_JINGLE_FEATURE_AUDIO); + disco->addFeature(XMLNS_JINGLE_FEATURE_VIDEO); + disco->addFeature(XMLNS_JINGLE_APPS_RTP_SSMA); + disco->addFeature(XMLNS_JINGLE_APPS_RTP_FB); + disco->addFeature(XMLNS_JINGLE_APPS_RTP_SSMA); + disco->addFeature(XMLNS_JINGLE_APPS_RTP_HDREXT); + disco->addFeature(XMLNS_JINGLE_APPS_GROUP); + _sessionManager->registerPlugin(new ICEUDP()); + _sessionManager->registerPlugin(new Group()); + _sessionManager->registerPlugin(new RTP()); + + auto rtcManager = OkRTCManager::getInstance(); + + std::list discos; + + ExtDisco::Service disco0; + disco0.type = "turn"; + disco0.host = "chuanshaninfo.com"; + disco0.port = 34780; + disco0.username = "gaojie"; + disco0.password = "hncs"; + discos.push_back(disco0); + + ExtDisco::Service disco1; + disco1.type = "stun"; + disco1.host = "stun.l.google.com"; + disco1.port = 19302; + + discos.push_back(disco1); + + for (const auto& item : discos) { + ortc::IceServer ice; + ice.uri = item.type + ":" + item.host + ":" + std::to_string(item.port); + // "?transport=" + item.transport; + ice.username = item.username; + ice.password = item.password; + qDebug() << "Add ice:" << ice.uri.c_str(); + rtcManager->addIceServer(ice); + } -IMJingle::IMJingle() -// : QObject(parent), im(im_), call{call}, fileHandlers{fileHandlers} -{ - qDebug() << __func__ << "Creating"; - - qRegisterMetaType("std::string"); - - auto client = getIM()->getClient(); - client->registerMessageHandler(this); - client->registerIqHandler(this, ExtIBB); - client->registerStanzaExtension(new Jingle::JingleMessage()); - - //jingle session - _sessionManager = std::make_unique(client, this); - _sessionManager->registerPlugin(new Content()); - - auto disco = client->disco(); - //jingle - disco->addFeature(XMLNS_JINGLE); - disco->addFeature(XMLNS_JINGLE_MESSAGE); - disco->addFeature(XMLNS_JINGLE_ERRORS); - - //jingle file - disco->addFeature(XMLNS_JINGLE_FILE_TRANSFER); - disco->addFeature(XMLNS_JINGLE_FILE_TRANSFER4); - disco->addFeature(XMLNS_JINGLE_FILE_TRANSFER5); - disco->addFeature(XMLNS_JINGLE_FILE_TRANSFER_MULTI); - disco->addFeature(XMLNS_JINGLE_IBB); - _sessionManager->registerPlugin(new FileTransfer()); - _sessionManager->registerPlugin(new IBB()); - - //jingle av - disco->addFeature(XMLNS_JINGLE_ICE_UDP); - disco->addFeature(XMLNS_JINGLE_APPS_DTLS); - disco->addFeature(XMLNS_JINGLE_APPS_RTP); - disco->addFeature(XMLNS_JINGLE_FEATURE_AUDIO); - disco->addFeature(XMLNS_JINGLE_FEATURE_VIDEO); - disco->addFeature(XMLNS_JINGLE_APPS_RTP_SSMA); - disco->addFeature(XMLNS_JINGLE_APPS_RTP_FB); - disco->addFeature(XMLNS_JINGLE_APPS_RTP_SSMA); - disco->addFeature(XMLNS_JINGLE_APPS_RTP_HDREXT); - disco->addFeature(XMLNS_JINGLE_APPS_GROUP); - _sessionManager->registerPlugin(new ICEUDP()); - _sessionManager->registerPlugin(new Group()); - _sessionManager->registerPlugin(new RTP()); - - - auto rtcManager = OkRTCManager::getInstance(); - - - std::list discos; - - ExtDisco::Service disco0; - disco0.type="turn"; - disco0.host = "chuanshaninfo.com"; - disco0.port=34780; - disco0.username="gaojie"; - disco0.password="hncs"; - discos.push_back(disco0); - - ExtDisco::Service disco1; - disco1.type="stun"; - disco1.host = "stun.l.google.com"; - disco1.port=19302; - - discos.push_back(disco1); - - - for (const auto &item : discos) { - ortc::IceServer ice; - ice.uri = item.type + ":" + item.host + ":" + std::to_string(item.port); - // "?transport=" + item.transport; - ice.username = item.username; - ice.password = item.password; - qDebug() <<"Add ice:" << ice.uri.c_str(); - rtcManager->addIceServer(ice); - } - - qDebug() << __func__ << ("Created"); + qDebug() << __func__ << ("Created"); } - - -IMJingle *IMJingle::getInstance() -{ - static IMJingle * jingle = nullptr; - if(!jingle){ - jingle = new IMJingle(); - } +IMJingle* IMJingle::getInstance() { + static IMJingle* jingle = nullptr; + assert(jingle); return jingle; } IMJingle::~IMJingle() { - auto client = getIM()->getClient(); + auto client = _im->getClient(); client->removeMessageHandler(this); qDebug() << __func__ << "Destroyed"; } -void IMJingle::handleMessageSession(MessageSession *session) -{ -// session->registerMessageHandler(this); +void IMJingle::handleMessageSession(MessageSession* session) { + // session->registerMessageHandler(this); } -void IMJingle::handleMessage(const Message &msg, MessageSession *session) -{ +void IMJingle::handleMessage(const Message& msg, MessageSession* session) { qDebug() << __func__ << "..."; /** @@ -155,958 +134,562 @@ void IMJingle::handleMessage(const Message &msg, MessageSession *session) */ auto jm = msg.findExtension(ExtJingleMessage); if (jm) { - doJingleMessage(IMPeerId(msg.from().full()), jm); + doJingleMessage(IMPeerId(msg.from().full()), jm); } - -} - - -void IMJingle::join(const JID &room) { - qDebug()<<("..."); - - // join conference - // JID focus(XMPP_CONFERENCE_FOCUS); - // Conference* _conference2 = new Conference - // (client->client(), focus, this); - // _conference = std::make_shared(client->client(), focus, - // this); - // - // //加入会议 - // _conference->join( - // room.bareJID(), - // QUuid::createUuid().toString().remove(0, 1).remove(36, - // 1).toStdString()); } -void IMJingle::setMute(bool mute) { - OkRTCManager::getInstance()->getRtc()->setMute(mute); -} - -void IMJingle::setRemoteMute(bool mute) { - OkRTCManager::getInstance()->getRtc()->setRemoteMute(mute); -} - -void IMJingle::doJingleMessage(const IMPeerId &peerId, const gloox::Jingle::JingleMessage *jm) -{ - qDebug() << __func__ - <<"peerId:"<id()) - << "action:"<< Jingle::ActionValues[jm->action()]; +void IMJingle::doJingleMessage(const IMPeerId& peerId, const gloox::Jingle::JingleMessage* jm) { + qDebug() << __func__ << "peerId:" << peerId.toString() << "sId:" << qstring(jm->id()) + << "action:" << Jingle::ActionValues[jm->action()]; auto friendId = peerId.toFriendId(); - qDebug() <<"friendId:" << friendId; + qDebug() << "friendId:" << friendId; auto sId = qstring(jm->id()); switch (jm->action()) { + case Jingle::JingleMessage::reject: { + /** + * 对方拒绝 + */ + // mPeerRequestMedias.clear(); + auto ms = jm->medias(); + emit receiveCallStateRejected(peerId, sId, ms.size() > 1); + // emit receiveFriendHangup(friendId, 0); + break; + } + case Jingle::JingleMessage::propose: { + // 被对方发起呼叫 + qDebug() << "On call from:" << peerId.toString(); + + // 获取呼叫类型 + bool audio = false; + bool video = false; + for (auto& m : jm->medias()) { + if (m == Jingle::audio) { + audio = true; + } else if (m == Jingle::video) { + video = true; + } + } - - case Jingle::JingleMessage::reject: { - /** - * 对方拒绝 - */ -// mPeerRequestMedias.clear(); - auto ms = jm->medias(); - emit receiveCallStateRejected(peerId, sId, ms.size() > 1); -// emit receiveFriendHangup(friendId, 0); - break; - } - case Jingle::JingleMessage::propose: - { - // 被对方发起呼叫 - qDebug() << "On call from:" << peerId.toString(); - - //获取呼叫类型 - bool audio = false; - bool video = false; - for(auto& m : jm->medias()){ - if(m == Jingle::audio){ - audio = true; - }else if(m == Jingle::video){ - video = true; - } - } - - emit receiveCallRequest(peerId, sId, audio, video); -// emit receiveCallAcceptByOther(sId, peerId); - break; - } - case Jingle::JingleMessage::retract: { - /** - * 撤回(需要判断是对方还是自己其它终端) - */ - emit receiveCallRetract(friendId, 0); - break; - } - case Jingle::JingleMessage::accept:{ - //自己其它终端接受,挂断自己 - if(peerId != getIM()->getSelfPeerId()){ - emit receiveFriendHangup(friendId, 0); - }else{ - //自己终端接受,不处理 -// OkRTCManager::getInstance()->getRtc()->CreateAnswer(peerId.toString()); + emit receiveCallRequest(peerId, sId, audio, video); + // emit receiveCallAcceptByOther(sId, peerId); + break; } - break; - } - case Jingle::JingleMessage::proceed:{ - //对方接受 - auto removed = m_sidVideo.remove(sId); //确定发起的是否是视频? - emit receiveCallStateAccepted(peerId, sId, removed == 1); - break; - } - case Jingle::JingleMessage::finish: - break; + case Jingle::JingleMessage::retract: { + /** + * 撤回(需要判断是对方还是自己其它终端) + */ + emit receiveCallRetract(friendId, 0); + break; + } + case Jingle::JingleMessage::accept: { + // 自己其它终端接受,挂断自己 + if (peerId != _im->getSelfPeerId()) { + emit receiveFriendHangup(friendId, 0); + } else { + // 自己终端接受,不处理 + // OkRTCManager::getInstance()->getRtc()->CreateAnswer(peerId.toString()); + } + break; + } + case Jingle::JingleMessage::proceed: { + // 对方接受 + auto removed = m_sidVideo.remove(sId); // 确定发起的是否是视频? + emit receiveCallStateAccepted(peerId, sId, removed == 1); + break; + } + case Jingle::JingleMessage::finish: + break; } } -IMJingleSession* IMJingle::cacheSessionInfo(Jingle::Session *session, +IMJingleSession* IMJingle::cacheSessionInfo(Jingle::Session* session, lib::ortc::JingleCallType callType) { + auto& responder = session->remote(); + auto sId = qstring(session->sid()); + auto peer = IMPeerId(responder); - auto &responder = session->remote(); - auto sId = qstring(session->sid()); - auto peer = IMPeerId (responder); - - m_friendSessionMap.insert(peer, sId); - - auto ws = new IMJingleSession(getIM(), peer, sId, callType, - session, - fileHandlers, - this); + m_friendSessionMap.insert(peer, sId); - m_sessionMap.insert(sId, ws); + auto ws = new IMJingleSession(_im, peer, sId, callType, session); -// connect(ws, -// &IMJingleSession::sendFileInfo, -// [&](const JID &m_friendId, const File &m_file, int m_seq, -// int m_sentBytes, bool end){ -// -// }); + m_sessionMap.insert(sId, ws); - return ws; + // connect(ws, + // &IMJingleSession::sendFileInfo, + // [&](const JID &m_friendId, const File &m_file, int m_seq, + // int m_sentBytes, bool end){ + // + // }); + return ws; } -void IMJingle::clearSessionInfo(Jingle::Session *session) { +void IMJingle::clearSessionInfo(Jingle::Session* session) { auto sId = qstring(session->sid()); - qDebug() << __func__ << sId; - - auto &responder = session->remote(); - m_friendSessionMap.remove(IMPeerId(responder)); - m_sessionMap.remove(sId); + qDebug() << __func__ << sId; - _sessionManager->discardSession(session); + auto& responder = session->remote(); + m_friendSessionMap.remove(IMPeerId(responder)); + m_sessionMap.remove(sId); + _sessionManager->discardSession(session); } -QString IMJingle::getSessionByFriendId(const QString &friendId) { - qDebug()<<("getSessionId:%1")<<((friendId)); +QString IMJingle::getSessionByFriendId(const QString& friendId) { + qDebug() << ("getSessionId:%1") << ((friendId)); - return m_friendSessionMap.value(IMPeerId{friendId}, {}); + return m_friendSessionMap.value(IMPeerId{friendId}, {}); } /** * Jingle sessions */ -void IMJingle::handleSessionActionError(Action action, Session *session, - const gloox::Error *error) { - qDebug() << __func__ - << "sid:" << qstring(session->sid()) - << "action:" << static_cast(action) - << "remote:" << qstring(session->remote().full()) - << "error:" << qstring(error->text()); +void IMJingle::handleSessionActionError(Action action, Session* session, + const gloox::Error* error) { + qDebug() << __func__ << "sid:" << qstring(session->sid()) + << "action:" << static_cast(action) + << "remote:" << qstring(session->remote().full()) + << "error:" << qstring(error->text()); } -void IMJingle::handleIncomingSession(Session *session) { - auto sid = qstring(session->sid()); - qDebug() << __func__ << "sId" << sid; - +void IMJingle::handleIncomingSession(Session* session) { + auto sid = qstring(session->sid()); + qDebug() << __func__ << "sId" << sid; } // Session -void IMJingle::handleSessionAction(Action action, - Session *session, - const Session::Jingle *jingle) { - - auto from = session->remote(); - auto friendId = IMPeerId(from); - auto sid = qstring(jingle->sid()); - - qDebug()<<__func__<(action) - <setJingle(jingle); - } - - switch (action) { - case Action::SessionInitiate: { - doSessionInitiate(session, jingle, friendId); - break; - } - case Action::SessionInfo: { - doSessionInfo(jingle, friendId); - break; - } - case Action::SessionTerminate: { - doSessionTerminate(session, jingle, friendId); - break; - } - case Action::SessionAccept: { - doSessionAccept(session, jingle, friendId); - break; - } - case Action::ContentAccept: { - doContentAccept(jingle, friendId); - break; - } - case Action::ContentAdd: { - // source-add|content-add - doContentAdd(jingle, friendId); - break; - } - case Action::ContentRemove: { - doContentRemove(jingle, friendId); - break; - } - case Action::ContentModify: { - doContentModify(jingle, friendId); - break; - } - case Action::ContentReject: { - doContentReject(jingle, friendId); - break; - } - case Action::TransportAccept: { - doTransportAccept(jingle, friendId); - break; - } - case Action::TransportInfo: { - doTransportInfo(jingle, friendId); - break; - } - case Action::TransportReject: { - doTransportReject(jingle, friendId); - break; - } - case Action::TransportReplace: { - doTransportReplace(jingle, friendId); - break; - } - case Action::SecurityInfo: { - doSecurityInfo(jingle, friendId); - break; - } - case Action::DescriptionInfo: { - doDescriptionInfo(jingle, friendId); - break; - } - case Action::InvalidAction: - doInvalidAction(jingle, friendId); - break; - } -} - -void IMJingle::doSessionInitiate(Jingle::Session *session, - const Jingle::Session::Jingle *jingle, - const IMPeerId &peerId) { +void IMJingle::handleSessionAction(Action action, Session* session, const Session::Jingle* jingle) { + auto from = session->remote(); + auto friendId = IMPeerId(from); + auto sid = qstring(jingle->sid()); - auto sid = qstring(session->sid()); - qDebug() <<__func__ << "sId:" << sid - << "peerId:" << peerId.toString(); + qDebug() << __func__ << static_cast(action) << qstring(from.full()) << sid; - bool isFile = false; - for(auto p : jingle->plugins()){ - auto pt = p->pluginType(); - switch (pt) { - case JinglePluginType::PluginContent: { - auto file = p->findPlugin(PluginFileTransfer); - auto ibb = p->findPlugin(PluginIBB); - if (file && ibb) { - for (auto f : file->files()) { - auto id = qstring(ibb->sid()); - auto sId = qstring(session->sid()); - File file = {.id= id, - .sId= sId, - .name = qstring(f.name), - .path= {}, - .size = (quint64)f.size, - .status = FileStatus::INITIALIZING, - .direction=FileDirection::RECEIVING}; - qDebug() << "receive file:" << file.toString(); - emit receiveFileRequest(peerId.toFriendId(), file); - } - isFile = true; - }else{ - //av -// auto group = p->findPlugin(PluginGroup); + auto* ws = findSession(sid); + if (ws) { + ws->setJingle(jingle); + } - } + switch (action) { + case Action::SessionInitiate: { + doSessionInitiate(session, jingle, friendId); break; } - default:{ - + case Action::SessionInfo: { + doSessionInfo(jingle, friendId); + break; + } + case Action::SessionTerminate: { + doSessionTerminate(session, jingle, friendId); + break; + } + case Action::SessionAccept: { + doSessionAccept(session, jingle, friendId); + break; + } + case Action::ContentAccept: { + doContentAccept(jingle, friendId); + break; + } + case Action::ContentAdd: { + // source-add|content-add + doContentAdd(jingle, friendId); + break; + } + case Action::ContentRemove: { + doContentRemove(jingle, friendId); + break; + } + case Action::ContentModify: { + doContentModify(jingle, friendId); + break; + } + case Action::ContentReject: { + doContentReject(jingle, friendId); + break; + } + case Action::TransportAccept: { + doTransportAccept(jingle, friendId); + break; + } + case Action::TransportInfo: { + doTransportInfo(jingle, friendId); + break; + } + case Action::TransportReject: { + doTransportReject(jingle, friendId); + break; + } + case Action::TransportReplace: { + doTransportReplace(jingle, friendId); + break; + } + case Action::SecurityInfo: { + doSecurityInfo(jingle, friendId); + break; } + case Action::DescriptionInfo: { + doDescriptionInfo(jingle, friendId); + break; } + case Action::InvalidAction: + doInvalidAction(jingle, friendId); + break; } +} + +void IMJingle::doSessionInitiate(Jingle::Session* session, + const Jingle::Session::Jingle* jingle, + const IMPeerId& peerId) { + auto sid = qstring(session->sid()); + qDebug() << __func__ << "sId:" << sid << "peerId:" << peerId.toString(); + bool isFile = false; + for (auto p : jingle->plugins()) { + auto pt = p->pluginType(); + switch (pt) { + case JinglePluginType::PluginContent: { + auto file = p->findPlugin(PluginFileTransfer); + auto ibb = p->findPlugin(PluginIBB); + if (file && ibb) { + for (auto f : file->files()) { + auto id = qstring(ibb->sid()); + auto sId = qstring(session->sid()); + + qDebug() << "receive file:" << id << sId; + + // File file = {.id= id, + // .sId= sId, + // .name = qstring(f.name), + // .path= {}, + // .size = (quint64)f.size, + // .status = FileStatus::INITIALIZING, + // .direction=FileDirection::RECEIVING}; + // qDebug() << "receive file:" << file.toString(); + // emit receiveFileRequest(peerId.toFriendId(), file); + } + isFile = true; + } else { + // av + // auto group = p->findPlugin(PluginGroup); + } + break; + } + default: { + } + } + } - if(isFile){ + if (isFile) { cacheSessionInfo(session, lib::ortc::JingleCallType::file); return; - }else{ - //av + } else { + // av cacheSessionInfo(session, lib::ortc::JingleCallType::av); OJingleContentAv cav; cav.parse(jingle); cav.sdpType = lib::ortc::JingleSdpType::Offer; OkRTCManager::getInstance()->getRtc()->CreateAnswer(stdstring(peerId.toString()), cav); - } + // bool isVideo = lib::ortc::JingleCallType::video == callType; + // auto _rtcManager = s->getRtcManager(); + // if (s->isAccepted()) { -// bool isVideo = lib::ortc::JingleCallType::video == callType; -// auto _rtcManager = s->getRtcManager(); -// if (s->isAccepted()) { - -// OJingleContent answer(lib::ortc::JingleSdpType::Answer, -// stdstring(peerId.username), session->sid(), -// SESSION_VERSION, context.getContents()); + // OJingleContent answer(lib::ortc::JingleSdpType::Answer, + // stdstring(peerId.username), session->sid(), + // SESSION_VERSION, context.getContents()); -// _rtcManager->CreateAnswer(stdstring(peerId.toString()), answer); -// emit receiveFriendHangup((peerId.username), -// isVideo ? TOXAV_FRIEND_CALL_STATE_SENDING_V -// : TOXAV_FRIEND_CALL_STATE_SENDING_A); -// } else { + // _rtcManager->CreateAnswer(stdstring(peerId.toString()), answer); + // emit receiveFriendHangup((peerId.username), + // isVideo ? SENDING_V + // : SENDING_A); + // } else { -// emit receiveFriendCall((peerId.username), qstring(session->sid()), true, -// isVideo); -// } + // emit receiveFriendCall((peerId.username), qstring(session->sid()), true, + // isVideo); + // } } -void IMJingle::doSessionTerminate(Jingle::Session *session, - const Session::Jingle *jingle, - const IMPeerId &peerId) { - +void IMJingle::doSessionTerminate(Jingle::Session* session, + const Session::Jingle* jingle, + const IMPeerId& peerId) { auto sid = qstring(jingle->sid()); - qDebug()<<__func__<<"sId:"<onTerminate(); -// int ri = 0; -// for (auto &file : m_waitSendFiles) { -// if (qstring(session->sid()) == file.sId) { -// // TODO 需要处理没有terminate的信令的清理 -// // 清理待发文件 -// qDebug()<<"session is terminate."< - - reason busy:正忙 decline:拒绝 - */ - auto state = TOXAV_FRIEND_CALL_STATE_FINISHED; - auto reason = jingle->tag()->findChild("reason"); - if (reason) { - if (reason->findChild("busy")) { - state = TOXAV_FRIEND_CALL_STATE_SENDING_A; - } - } - // rtc -// auto s = findSession(sid); -// if (s) { -// auto rtcManager = OkRTCManager::getInstance(); -// if (rtcManager) { -// rtcManager->quit(stdstring(peerId.toString())); -// } -// } - - clearSessionInfo(session); - getIM()->endJingle(); - emit receiveFriendHangup(peerId.toFriendId(), (int)state); -} - -void IMJingle::doSessionAccept(Jingle::Session *session, - const Jingle::Session::Jingle *jingle, - const IMPeerId &peerId) { - - auto sid = qstring(jingle->sid()); - qDebug() << __func__ << sid << "peerId:" << peerId.toString(); + // int ri = 0; + // for (auto &file : m_waitSendFiles) { + // if (qstring(session->sid()) == file.sId) { + // // TODO 需要处理没有terminate的信令的清理 + // // 清理待发文件 + // qDebug()<<"session is terminate."< + + reason busy:正忙 decline:拒绝 + */ + // auto state = FINISHED; + // auto reason = jingle->tag()->findChild("reason"); + // if (reason) { + // if (reason->findChild("busy")) { + // state = SENDING_A; + // } + // } + // rtc + // auto s = findSession(sid); + // if (s) { + // auto rtcManager = OkRTCManager::getInstance(); + // if (rtcManager) { + // rtcManager->quit(stdstring(peerId.toString())); + // } + // } + + clearSessionInfo(session); + _im->endJingle(); + // emit receiveFriendHangup(peerId.toFriendId(), (int)state); +} + +void IMJingle::doSessionAccept(Jingle::Session* session, + const Jingle::Session::Jingle* jingle, + const IMPeerId& peerId) { + auto sid = qstring(jingle->sid()); + qDebug() << __func__ << sid << "peerId:" << peerId.toString(); - auto ws = findSession(sid); - if(!ws){ - qWarning() <<"Unable to find session"<onAccept(); + ws->onAccept(); } -void IMJingle::doSessionInfo(const Session::Jingle *jingle, - const IMPeerId &friendId) { - qDebug() << "jingle:%1 peerId:%2" // - << qstring(jingle->sid()) // - << friendId.toString(); +void IMJingle::doSessionInfo(const Session::Jingle* jingle, const IMPeerId& friendId) { + qDebug() << "jingle:%1 peerId:%2" // + << qstring(jingle->sid()) // + << friendId.toString(); } -void IMJingle::doContentAdd(const Session::Jingle *jingle, - const IMPeerId &friendId) { - - qDebug() << "jingle:%1 peerId:%2" << qstring(jingle->sid()) - << friendId.toString(); - // _rtcManager->ContentAdd(sdMap, this); +void IMJingle::doContentAdd(const Session::Jingle* jingle, const IMPeerId& friendId) { + qDebug() << "jingle:%1 peerId:%2" << qstring(jingle->sid()) << friendId.toString(); + // _rtcManager->ContentAdd(sdMap, this); } -void IMJingle::doContentRemove(const Session::Jingle *jingle, - const IMPeerId &peerId) { - qDebug()<<("jingle:%1 peerId:%2") - <<(qstring(jingle->sid())) - <<((peerId.toString())); - - // JID peerJID; - // std::map sdMap; - // const PluginList &plugins = jingle->plugins(); - // for (const auto p : plugins) { - // qDebug()<<("Plugin:%1")<<((QString::fromStdString(p->filterString()))); - // JinglePluginType pt = p->pluginType(); - // switch (pt) { - // case JinglePluginType::PluginContent: { - // break; - // } - // default: - // break; - // } - // } - // - // _rtcManager->ContentRemove(sdMap, this); -} +void IMJingle::doContentRemove(const Session::Jingle* jingle, const IMPeerId& peerId) { + qDebug() << ("jingle:%1 peerId:%2") << (qstring(jingle->sid())) << ((peerId.toString())); -void IMJingle::doContentModify(const Session::Jingle *jingle, - const IMPeerId &peerId) { - qDebug()<<("jingle:%1 peerId:%2") // - <<((qstring(jingle->sid()))) - <<((peerId.toString())); + // JID peerJID; + // std::map sdMap; + // const PluginList &plugins = jingle->plugins(); + // for (const auto p : plugins) { + // qDebug()<<("Plugin:%1")<<((QString::fromStdString(p->filterString()))); + // JinglePluginType pt = p->pluginType(); + // switch (pt) { + // case JinglePluginType::PluginContent: { + // break; + // } + // default: + // break; + // } + // } + // + // _rtcManager->ContentRemove(sdMap, this); } -void IMJingle::doContentAccept(const Session::Jingle *jingle, - const IMPeerId &peerId) { - qDebug()<<("jingle:%1 peerId:%2") // - <<((qstring(jingle->sid()))) - <<((peerId.toString())); +void IMJingle::doContentModify(const Session::Jingle* jingle, const IMPeerId& peerId) { + qDebug() << ("jingle:%1 peerId:%2") // + << ((qstring(jingle->sid()))) << ((peerId.toString())); } -void IMJingle::doContentReject(const Session::Jingle *jingle, - const IMPeerId &peerId) { - qDebug()<<("jingle:%1 peerId:%2") // - <<((qstring(jingle->sid()))) - <<((peerId.toString())); +void IMJingle::doContentAccept(const Session::Jingle* jingle, const IMPeerId& peerId) { + qDebug() << ("jingle:%1 peerId:%2") // + << ((qstring(jingle->sid()))) << ((peerId.toString())); } -void IMJingle::doTransportAccept(const Session::Jingle *jingle, - const IMPeerId &peerId) { - qDebug() << ("jingle:%1 peerId:%2") // - << qstring(jingle->sid()) << peerId.toString(); +void IMJingle::doContentReject(const Session::Jingle* jingle, const IMPeerId& peerId) { + qDebug() << ("jingle:%1 peerId:%2") // + << ((qstring(jingle->sid()))) << ((peerId.toString())); } -void IMJingle::doTransportInfo(const Session::Jingle *jingle, - const IMPeerId &peerId) { +void IMJingle::doTransportAccept(const Session::Jingle* jingle, const IMPeerId& peerId) { + qDebug() << ("jingle:%1 peerId:%2") // + << qstring(jingle->sid()) << peerId.toString(); +} +void IMJingle::doTransportInfo(const Session::Jingle* jingle, const IMPeerId& peerId) { auto sid = qstring(jingle->sid()); - qDebug()<<__func__ << "sId:" << sid << "peerId:" << peerId.toString(); + qDebug() << __func__ << "sId:" << sid << "peerId:" << peerId.toString(); auto s = findSession(sid); if (!s) { - qWarning()<<("Session is no existing."); + qWarning() << ("Session is no existing."); return; } OJingleContentAv content; content.parse(jingle); - for (auto &it : content.contents) { - OkRTCManager::getInstance()->getRtc() - ->setTransportInfo(stdstring(peerId.toString()), jingle->sid(), it.iceUdp); + for (auto& it : content.contents) { + OkRTCManager::getInstance()->getRtc()->setTransportInfo(stdstring(peerId.toString()), + jingle->sid(), it.iceUdp); } } -void IMJingle::doTransportReject(const Session::Jingle *, const IMPeerId &) {} - -void IMJingle::doTransportReplace(const Session::Jingle *, const IMPeerId &) {} - -void IMJingle::doSecurityInfo(const Session::Jingle *, const IMPeerId &) {} - -void IMJingle::doDescriptionInfo(const Session::Jingle *jingle, - const IMPeerId &peerId) { - qDebug()<<("sessionId:%1 from:%2") - <<(qstring(jingle->sid())) - <<((peerId.toString())); -} - -void IMJingle::doInvalidAction(const Session::Jingle *jingle, - const IMPeerId &peerId) { - qDebug()<<("sessionId:%1 from:%2") - <<(qstring(jingle->sid())) - <<((peerId.toString())); -} - -void IMJingle::onCreatePeerConnection(const std::string &sId, - const std::string &peerId, - bool ok) { - auto p = qstring(peerId); - auto s = qstring(sId); - - qDebug()<<__func__<< "sId:" << s - << "peerId:" << p - << "isOk=>" << ok; - -// emit call->sig_createPeerConnection(s, p, ok); -} - -void IMJingle::onRTP(const std::string &sid, // - const std::string &peerId, // - const lib::ortc::OJingleContentAv &oContext) { - auto sId = qstring(sid); - qDebug()<<__func__ << "sId:"<direction() == CallDirection::CallIn) { - pSession->getSession()->sessionAccept(plugins); - } else if (pSession->direction() == CallDirection::CallOut) { - pSession->getSession()->sessionInitiate(plugins); - } -} - -void IMJingle::onIce(const std::string &sId, // - const std::string &peerId, // - const OIceUdp &oIceUdp) { - - auto sid = qstring(sId); - - qDebug()<< __func__ - << "sId:"<< sid - << "peerId:" << qstring(peerId) - << "mid:" << qstring(oIceUdp.mid) - << "mline:" << oIceUdp.mline; - - auto *session = findSession(sid); - if (!session) { - qWarning() << "Unable to find session:" << &sId; - return; - } - - - auto *iceUdp = new ICEUDP(oIceUdp.pwd, oIceUdp.ufrag, oIceUdp.candidates); - iceUdp->setDtls(oIceUdp.dtls); - - PluginList pluginList; - pluginList.emplace_back(iceUdp); - auto c = new Jingle::Content(oIceUdp.mid, pluginList); - session->getSession()->transportInfo(c); -} - -/** - * 视频渲染 - * @param peerId - * @param image - */ -void IMJingle::onRender(const std::string &peerId, lib::ortc::RendererImage image) { - if (peerId.empty()) { - emit receiveSelfVideoFrame(image.width_, image.height_, image.y, image.u, - image.v, image.ystride, image.ustride, - image.vstride); - } else { - emit receiveFriendVideoFrame(IMPeerId(peerId).toFriendId(), image.width_, - image.height_, image.y, image.u, image.v, - image.ystride, image.ustride, image.vstride); - } -} - - - -void IMJingle::proposeJingleMessage(const QString &friendId, const QString &callId, bool video) { - qDebug() <<__func__<<"friend:"<addMedia(Jingle::Media::audio); - if (video) { - jm->addMedia(Jingle::Media::video); - m_sidVideo.insert(callId, true); - } - exts.push_back(jm); - - auto jid = JID{stdstring(friendId)}; - Message m( Message::Chat, jid, {}, {}); - for(auto ext: exts ) - m.addExtension( ext); - - getIM()->getClient()->send(m); - -} - -void IMJingle::rejectJingleMessage(const QString &peerId, const QString &callId) { - - qDebug() <<__func__<<"friend:"<getClient()->send(m); -} - -void IMJingle::acceptJingleMessage(const IMPeerId &peerId, const QString &callId, bool video) { - qDebug() <<__func__<<"friend:"<< peerId.toFriendId() << callId; - - auto proceed = new Jingle::JingleMessage(Jingle::JingleMessage::proceed, stdstring(callId)); - Message proceedMsg(gloox::Message::Chat, JID(stdstring(peerId.toString()))); - proceedMsg.addExtension(proceed); - getIM()->getClient()->send(proceedMsg); - qDebug() << "Sent proceed=>"<self().bareJID(); - - Message msg(gloox::Message::Chat, self); - msg.addExtension(accept); - getIM()->getClient()->send(msg); - qDebug() << "Sent accept=>" << qstring(self.full()); - - // 设置状态为接受 - auto ws = findSession( callId ); - if(!ws){ - ws = createSession(peerId, callId, JingleCallType::av); - } - ws->setAccepted(true); -} - -void IMJingle::retractJingleMessage(const QString &friendId, const QString &callId) { - qDebug() <<__func__<<"friend:"<getClient()->send(m); +void IMJingle::doDescriptionInfo(const Session::Jingle* jingle, const IMPeerId& peerId) { + qDebug() << ("sessionId:%1 from:%2") << (qstring(jingle->sid())) << ((peerId.toString())); } -bool IMJingle::sendCallToResource(const QString &friendId, const QString &sId, - bool video) { - - proposeJingleMessage(friendId, sId, video); - return true; +void IMJingle::doInvalidAction(const Session::Jingle* jingle, const IMPeerId& peerId) { + qDebug() << ("sessionId:%1 from:%2") << (qstring(jingle->sid())) << ((peerId.toString())); } +void IMJingle::proposeJingleMessage(const QString& friendId, const QString& callId, bool video) { + qDebug() << __func__ << "friend:" << friendId << callId; -// startCall -bool IMJingle::startCall(const QString &friendId, const QString &sId, bool video) { - qDebug()<<__func__<<"friendId:"<addMedia(Jingle::Media::audio); + if (video) { + jm->addMedia(Jingle::Media::video); + m_sidVideo.insert(callId, true); + } + exts.push_back(jm); - auto resources = getIM()->getOnlineResources(stdstring(friendId)); - if (resources.empty()) { - qWarning() << "目标用户不在线!"; - return false; - } + auto jid = JID{stdstring(friendId)}; + Message m(Message::Chat, jid, {}, {}); + for (auto ext : exts) m.addExtension(ext); - sendCallToResource(friendId, sId, video); - return true; + _im->getClient()->send(m); } -bool IMJingle::createCall(const IMPeerId &to, const QString &sId, bool video) { - qDebug()<<__func__<< "to:" << to.toString() << "sId:" << sId; +void IMJingle::rejectJingleMessage(const QString& peerId, const QString& callId) { + qDebug() << __func__ << "friend:" << peerId << callId; - auto ws = createSession(to, sId, JingleCallType::av); + StanzaExtensionList exts; + auto reject = new Jingle::JingleMessage(Jingle::JingleMessage::reject, stdstring(callId)); + exts.push_back(reject); - auto rtc = OkRTCManager::getInstance()->getRtc(); - rtc->addRTCHandler(this); + auto jid = JID{stdstring(peerId)}; + Message m(Message::Chat, jid, {}, {}); + for (auto ext : exts) m.addExtension(ext); - bool createdCall = rtc->call(stdstring(to.toString()), stdstring(sId), video); - if(createdCall){ - ws->createOffer(stdstring(to.toString())); - } - - return createdCall; + _im->getClient()->send(m); } -void IMJingle::cancel(const QString &friendId) { - qDebug()<<__func__<getClient()->send(proceedMsg); + qDebug() << "Sent proceed=>" << peerId.toString(); - auto session = m_sessionMap.value(sId); - if (session) { - cancelCall(IMContactId{friendId}, qstring(session->getSession()->sid())); - clearSessionInfo(session->getSession()); - } + // 发送给自己其它终端 + auto accept = new Jingle::JingleMessage(Jingle::JingleMessage::accept, stdstring(callId)); -} + auto self = _im->self().bareJID(); -void IMJingle::cancelCall(const IMContactId &friendId, const QString &sId) { - qDebug()<< __func__ << friendId.toString() << sId; - - IMJingleSession *s = findSession(sId); - if (s) { - s->doTerminate(); - s->setCallStage(CallStage::StageNone); - clearSessionInfo(s->getSession()); - } - retractJingleMessage(friendId.toString(), sId); -// else { - // jingle-message -// if (s->direction() == CallDirection:: CallOut) { -// } else if (s->direction() == CallDirection:: CallIn) { -// rejectJingleMessage(friendId.toString(), sId); -// } -// } -} + Message msg(gloox::Message::Chat, self); + msg.addExtension(accept); + _im->getClient()->send(msg); + qDebug() << "Sent accept=>" << qstring(self.full()); -void IMJingle::rejectCall(const IMPeerId &peerId, const QString &sId) -{ - qDebug()<< __func__ << peerId.toString() << sId; - - IMJingleSession *s = findSession(sId); - if (s) { - s->doTerminate(); - clearSessionInfo(s->getSession()); - }else - { - rejectJingleMessage(peerId.toString(), sId); + // 设置状态为接受 + auto ws = findSession(callId); + if (!ws) { + ws = createSession(peerId, callId, JingleCallType::av); } + ws->setAccepted(true); } -bool IMJingle::answer(const IMPeerId &peerId, - const QString &callId, - bool video) { - - qDebug()<<__func__<< "peer:" << peerId.toString() << "video:"<< video ; - - auto rtc = OkRTCManager::getInstance()->getRtc(); - rtc->addRTCHandler(this); - - acceptJingleMessage(peerId, callId, video); - - return true; -} - -/** - * 文件传输 - * @param friendId - * @param file - */ -void IMJingle::rejectFileRequest(const QString &friendId, - const QString &sId) { - cancelCall(IMContactId{friendId}, sId); -} - -void IMJingle::acceptFileRequest(const QString &friendId, - const File &file) { - qDebug()<< __func__ - << file.name - << file.sId - << file.id; - - auto *ws = findSession(file.sId); - if (!ws) { - qWarning() <<"Unable to find session sId:" << file.sId; - return; - } - // 协议:https://xmpp.org/extensions/xep-0234.html#requesting - - PluginList pluginList; - - Jingle::FileTransfer::FileList files; - files.push_back(Jingle::FileTransfer::File { - .name = stdstring( file.name), - .size = (long)file.size - }); - - auto ftf = new Jingle::FileTransfer(FileTransfer::Request, files); - - auto ibb = new Jingle::IBB(stdstring(file.txIbb.sid), - file.txIbb.blockSize); - - pluginList.emplace_back(ftf); - pluginList.emplace_back(ibb); - +void IMJingle::retractJingleMessage(const QString& friendId, const QString& callId) { + qDebug() << __func__ << "friend:" << friendId << callId; - auto c = new Jingle::Content("file", pluginList); - ws->getSession()->sessionAccept(c); -} - -void IMJingle::finishFileRequest(const QString &friendId, - const QString &sId) { - qDebug()<<__func__<<"sId:"<<(sId); - auto *s = findSession(sId); - if (!s) { - qWarning() << "Can not find file session" << sId; - return; - } - s->getSession()->sessionTerminate(new Session::Reason(Session::Reason::Success)); -} + auto* jm = new Jingle::JingleMessage(Jingle::JingleMessage::retract, stdstring(callId)); -void IMJingle::finishFileTransfer(const QString &friendId, - const QString &sId) { - qDebug()<<__func__<<"sId:"<<(sId); - finishFileRequest(friendId, sId); -} + auto jid = JID{stdstring(friendId)}; + Message m(Message::Chat, jid, {}, {}); + m.addExtension(jm); -bool IMJingle::sendFile(const QString &friendId, - const File &file) { - qDebug()<<__func__ << (friendId) << (file.name); - if (file.id.isEmpty()) { - qWarning() << "file id is no existing"; - return false; - } - - auto bare = stdstring(friendId); - auto resources = getIM()->getOnlineResources(bare); - if (resources.empty()) { - qWarning() << "目标用户不在线!"; - return false; - } - - JID jid(bare); - for (auto &r : resources) { - jid.setResource(r); - sendFileToResource(jid, file); - } - - return true; + _im->getClient()->send(m); } -bool IMJingle::sendFileToResource(const JID &jid, - const File &file) { - - qDebug()<<__func__<< qstring(jid.full()) << "sId:"<createSession(jid, this, stdstring(file.sId)); - if (!session) { - qDebug() << "Can not create session!"; - return false; - } - - auto ws = cacheSessionInfo(session, JingleCallType::file); - - PluginList pl; - - // offer-file - FileTransfer::FileList files; - FileTransfer::File f; - f.name = stdstring(file.name); - f.size = file.size; - files.emplace_back(f); - auto ft = new FileTransfer(FileTransfer::Offer, files); - pl.emplace_back(ft); - - // ibb - auto ibb = new Jingle::IBB(stdstring(file.id), 4096); - pl.emplace_back(ibb); - - // content - auto jc = new Jingle::Content("offer-a-file", pl); - session->sessionInitiate(jc); - - // 缓存文件 - auto &nf = const_cast(file); - nf.sId = qstring(session->sid()); - ws->addFile(nf); - - return true; -} +bool IMJingle::handleIq(const IQ& iq) { + const auto* ibb = iq.findExtension(ExtIBB); + if (ibb) { + IMContactId friendId(qstring(iq.from().bare())); + qDebug() << __func__ << QString("IBB stream id:%1").arg(qstring(ibb->sid())); -bool IMJingle::handleIq(const IQ &iq) -{ + switch (ibb->type()) { + case InBandBytestream::IBBOpen: { + qDebug() << __func__ << QString("Open"); + break; + } + // case InBandBytestream::IBBData: { + // qDebug() << __func__ << QString("Data seq:%1").arg(ibb->seq()); + // emit receiveFileChunk(friendId, qstring(ibb->sid()), ibb->seq(), + // ibb->data()); break; + // } + // case InBandBytestream::IBBClose: { + // qDebug() << __func__ << QString("Close"); + // emit receiveFileFinished(friendId, qstring(ibb->sid())); + // break; + // } + default: { + } + } - const auto *ibb = iq.findExtension(ExtIBB); - if (ibb) { - IMContactId friendId(qstring(iq.from().bare())); - qDebug() << __func__<sid())); - - switch (ibb->type()) { - case InBandBytestream::IBBOpen: { - qDebug() << __func__ << QString("Open"); - break; - } - case InBandBytestream::IBBData: { - qDebug() << __func__ << QString("Data seq:%1").arg(ibb->seq()); - emit receiveFileChunk(friendId, qstring(ibb->sid()), ibb->seq(), ibb->data()); - break; - } - case InBandBytestream::IBBClose: { - qDebug() << __func__ << QString("Close"); - emit receiveFileFinished(friendId, qstring(ibb->sid())); - break; - } - default: { - } - } - - IQ riq(IQ::IqType::Result, iq.from(), iq.id()); - getIM()->getClient()->send(riq); + IQ riq(IQ::IqType::Result, iq.from(), iq.id()); + _im->getClient()->send(riq); } return true; -// auto services = iq.tag()->findChild("services", "xmlns", XMLNS_EXTERNAL_SERVICE_DISCOVERY); -// if (services) { -// mExtDisco = ExtDisco(services); -// } + // auto services = iq.tag()->findChild("services", "xmlns", + // XMLNS_EXTERNAL_SERVICE_DISCOVERY); if (services) { + // mExtDisco = ExtDisco(services); + // } } -void IMJingle::handleIqID(const IQ &iq, int context) -{ +void IMJingle::handleIqID(const IQ& iq, int context) {} -} - -IMJingleSession *IMJingle::findSession(const QString &sId) { - return m_sessionMap.value(sId); -} +IMJingleSession* IMJingle::findSession(const QString& sId) { return m_sessionMap.value(sId); } -IMJingleSession *IMJingle::createSession(const IMPeerId &to, const QString &sId, JingleCallType ct) -{ - - auto s = _sessionManager->createSession( - JID(stdstring(to.toString())), - this, - stdstring(sId)); +IMJingleSession* IMJingle::createSession(const IMPeerId& to, const QString& sId, + JingleCallType ct) { + auto s = _sessionManager->createSession(JID(stdstring(to.toString())), this, stdstring(sId)); auto ws = cacheSessionInfo(s, ct); return ws; - } - -} // namespace messenger -} // namespace lib +} // namespace messenger +} // namespace lib diff --git a/src/lib/messenger/IMJingle.h b/src/lib/messenger/IMJingle.h index de80d86b..7c123fea 100644 --- a/src/lib/messenger/IMJingle.h +++ b/src/lib/messenger/IMJingle.h @@ -13,8 +13,8 @@ #ifndef IMJINGLE_H #define IMJINGLE_H -#include #include +#include #include #include @@ -40,233 +40,142 @@ namespace gloox { namespace Jingle { class JingleMessage; } -} -namespace lib { -namespace messenger { +} // namespace gloox + +namespace lib::messenger { -class IMCall; -class IMFileTask; enum class CallDirection; class IMJingle : public QObject, - public MessageHandler, + public gloox::MessageHandler, public gloox::IqHandler, public gloox::MessageSessionHandler, - public gloox::Jingle::SessionHandler, - public lib::ortc::OkRTCHandler { - Q_OBJECT + public gloox::Jingle::SessionHandler { + Q_OBJECT public: - static IMJingle* getInstance( ); - - - ~IMJingle() override; - - virtual void handleMessageSession( MessageSession* session ) override; - virtual void handleMessage( const Message& msg, MessageSession* session = 0 ) override; - - /** - * 发起呼叫 - * @param friendId - * @param video - * @return - */ - bool startCall(const QString &friendId, const QString &sId, bool video); - - bool sendCallToResource(const QString &friendId, const QString &sId, bool video); + static IMJingle* getInstance(); - bool createCall(const IMPeerId &to, const QString &sId, bool video); + IMJingle(IM* im, QObject* parent = nullptr); + ~IMJingle() override; - bool answer(const IMPeerId &to, const QString &callId, bool video); + virtual void handleMessageSession(gloox::MessageSession* session) override; + virtual void handleMessage(const gloox::Message& msg, gloox::MessageSession* session = 0) override; - void cancel(const QString &friendId); - //取消呼叫 - void cancelCall(const IMContactId &friendId, const QString &sId); - void rejectCall(const IMPeerId &friendId, const QString &sId); + /** + * jingle-message + */ + // 处理JingleMessage消息 + void doJingleMessage(const IMPeerId& peerId, const gloox::Jingle::JingleMessage* jm); - void join(const JID &room); - void setMute(bool mute); - void setRemoteMute(bool mute); + // 发起呼叫邀请 + void proposeJingleMessage(const QString& friendId, const QString& callId, bool video); - /** - * jingle-message - */ - //处理JingleMessage消息 - void doJingleMessage(const IMPeerId &peerId, const gloox::Jingle::JingleMessage *jm); + void rejectJingleMessage(const QString& friendId, const QString& callId); - //发起呼叫邀请 - void proposeJingleMessage(const QString &friendId, const QString &callId, bool video); - - void rejectJingleMessage(const QString &friendId, const QString &callId); - - void acceptJingleMessage(const IMPeerId &peerId, const QString &callId, bool video); - - void retractJingleMessage(const QString &friendId, const QString &callId); - - - - /** - * File - */ - void setFileHandlers(std::vector *fileHandlers_){ - fileHandlers = fileHandlers_; - }; - - void rejectFileRequest(const QString &friendId, - const QString &sId); - void acceptFileRequest(const QString &friendId, - const File &file); - void finishFileRequest(const QString &friendId, - const QString &sId); - void finishFileTransfer(const QString &friendId, - const QString &sId); - - bool sendFile(const QString &friendId, const File &file); - bool sendFileToResource(const JID &friendId, const File &file); + void acceptJingleMessage(const IMPeerId& peerId, const QString& callId, bool video); + void retractJingleMessage(const QString& friendId, const QString& callId); protected: + bool handleIq(const IQ& iq) override; - bool handleIq(const IQ &iq) override; - - void handleIqID(const IQ &iq, int context) override; + void handleIqID(const IQ& iq, int context) override; + void handleSessionAction(Jingle::Action action, Jingle::Session* session, + const Jingle::Session::Jingle* jingle) override; - void handleSessionAction(Jingle::Action action, Jingle::Session *session, - const Jingle::Session::Jingle *jingle) override; + void handleSessionActionError(Jingle::Action action, Jingle::Session* session, + const gloox::Error* error) override; - void handleSessionActionError(Jingle::Action action, Jingle::Session *session, - const gloox::Error *error) override; + void handleIncomingSession(Jingle::Session* session) override; - void handleIncomingSession(Jingle::Session *session) override; + IMJingleSession* findSession(const QString& sId); - void onCreatePeerConnection(const std::string &sId, - const std::string &peerId, - bool ok) override; + IMJingleSession* createSession(const IMPeerId& to, const QString& sId, + lib::ortc::JingleCallType ct); - // onRTP - void onRTP(const std::string &sId, // - const std::string &friendId, // - const lib::ortc::OJingleContentAv &oContext) override; + // receiver -> sid + QMap m_friendSessionMap; - // onIce - void onIce(const std::string &sId, // - const std::string &friendId, // - const lib::ortc::OIceUdp &) override; + // sid -> session + QMap m_sessionMap; - // Renderer - void onRender(const std::string &peerId, - lib::ortc::RendererImage image) override; + void clearSessionInfo(Jingle::Session* session); - IMJingleSession *findSession(const QString &sId); - - IMJingleSession* createSession(const IMPeerId &to, const QString &sId, lib::ortc::JingleCallType ct); + std::unique_ptr _sessionManager; + IMJingleSession* cacheSessionInfo(Jingle::Session* session, lib::ortc::JingleCallType callType); private: - IMJingle(); - - QString getSessionByFriendId(const QString &friendId); - - IMJingleSession* cacheSessionInfo(Jingle::Session *session, lib::ortc::JingleCallType callType); - - void clearSessionInfo(Jingle::Session *session); - - void doSessionInitiate(Jingle::Session *session, - const Jingle::Session::Jingle *, const IMPeerId &); - - void doSessionTerminate(Jingle::Session *session, - const Jingle::Session::Jingle *, const IMPeerId &); - - void doSessionAccept(Jingle::Session *session, // - const Jingle::Session::Jingle *, // - const IMPeerId &); - void doSessionInfo(const Jingle::Session::Jingle *, const IMPeerId &); - void doContentAdd(const Jingle::Session::Jingle *, const IMPeerId &); - void doContentRemove(const Jingle::Session::Jingle *, const IMPeerId &); - void doContentModify(const Jingle::Session::Jingle *, const IMPeerId &); - void doContentAccept(const Jingle::Session::Jingle *, const IMPeerId &); - void doContentReject(const Jingle::Session::Jingle *, const IMPeerId &); - void doTransportAccept(const Jingle::Session::Jingle *, const IMPeerId &); - void doTransportInfo(const Jingle::Session::Jingle *, const IMPeerId &); - void doTransportReject(const Jingle::Session::Jingle *, const IMPeerId &); - void doTransportReplace(const Jingle::Session::Jingle *, const IMPeerId &); - void doSecurityInfo(const Jingle::Session::Jingle *, const IMPeerId &); - void doDescriptionInfo(const Jingle::Session::Jingle *, const IMPeerId &); - void doInvalidAction(const Jingle::Session::Jingle *, const IMPeerId &); - - + QString getSessionByFriendId(const QString& friendId); - std::vector *fileHandlers; + void doSessionInitiate(Jingle::Session* session, const Jingle::Session::Jingle*, + const IMPeerId&); - // receiver -> sid - QMap m_friendSessionMap; + void doSessionTerminate(Jingle::Session* session, const Jingle::Session::Jingle*, + const IMPeerId&); - // sid -> session - QMap m_sessionMap; + void doSessionAccept(Jingle::Session* session, // + const Jingle::Session::Jingle*, // + const IMPeerId&); + void doSessionInfo(const Jingle::Session::Jingle*, const IMPeerId&); + void doContentAdd(const Jingle::Session::Jingle*, const IMPeerId&); + void doContentRemove(const Jingle::Session::Jingle*, const IMPeerId&); + void doContentModify(const Jingle::Session::Jingle*, const IMPeerId&); + void doContentAccept(const Jingle::Session::Jingle*, const IMPeerId&); + void doContentReject(const Jingle::Session::Jingle*, const IMPeerId&); + void doTransportAccept(const Jingle::Session::Jingle*, const IMPeerId&); + void doTransportInfo(const Jingle::Session::Jingle*, const IMPeerId&); + void doTransportReject(const Jingle::Session::Jingle*, const IMPeerId&); + void doTransportReplace(const Jingle::Session::Jingle*, const IMPeerId&); + void doSecurityInfo(const Jingle::Session::Jingle*, const IMPeerId&); + void doDescriptionInfo(const Jingle::Session::Jingle*, const IMPeerId&); + void doInvalidAction(const Jingle::Session::Jingle*, const IMPeerId&); - //sid -> isVideo,在jingle-message阶段暂时保留呼叫的类型是视频(音频无需保存)。 - QMap m_sidVideo; + IM* _im; - std::unique_ptr _sessionManager; + // std::vector *fileHandlers; - QList m_ices; + // sid -> isVideo,在jingle-message阶段暂时保留呼叫的类型是视频(音频无需保存)。 + QMap m_sidVideo; + QList m_ices; signals: - void callStarted(); + void callStarted(); - // 呼叫请求 - void receiveCallRequest(IMPeerId peerId, - QString callId, - bool audio, - bool video); + // 呼叫请求 + void receiveCallRequest(IMPeerId peerId, QString callId, bool audio, bool video); - void receiveFriendCall(QString friendId, - QString callId, - bool audio, - bool video); + void receiveFriendCall(QString friendId, QString callId, bool audio, bool video); + // 呼叫撤回 + void receiveCallRetract(QString friendId, int state); + void receiveCallAcceptByOther(QString callId, IMPeerId peerId); + void receiveFriendHangup(QString friendId, int state); - // 呼叫撤回 - void receiveCallRetract(QString friendId, int state); - void receiveCallAcceptByOther(QString callId, IMPeerId peerId); - void receiveFriendHangup(QString friendId, int state); + // 对方状态变化 + void receiveCallStateAccepted(IMPeerId peerId, QString callId, bool video); + void receiveCallStateRejected(IMPeerId peerId, QString callId, bool video); - // 对方状态变化 - void receiveCallStateAccepted(IMPeerId peerId, QString callId, bool video); - void receiveCallStateRejected(IMPeerId peerId, QString callId, bool video); - - - - void receiveSelfVideoFrame(uint16_t w, uint16_t h, // - const uint8_t *y, // - const uint8_t *u, // - const uint8_t *v, // - int32_t ystride, // - int32_t ustride, // - int32_t vstride); - - void receiveFriendVideoFrame(const QString &friendId, // - uint16_t w, uint16_t h, // - const uint8_t *y, // - const uint8_t *u, // - const uint8_t *v, // + void receiveSelfVideoFrame(uint16_t w, uint16_t h, // + const uint8_t* y, // + const uint8_t* u, // + const uint8_t* v, // int32_t ystride, // int32_t ustride, // int32_t vstride); - void receiveFileRequest(const QString &friendId, - const File &file); - - - - void receiveFileChunk(const IMContactId friendId, QString sId, - int seq, const std::string chunk); - void receiveFileFinished(const IMContactId friendId, QString sId); - + void receiveFriendVideoFrame(const QString& friendId, // + uint16_t w, uint16_t h, // + const uint8_t* y, // + const uint8_t* u, // + const uint8_t* v, // + int32_t ystride, // + int32_t ustride, // + int32_t vstride); }; -} // namespace IM -} // namespace lib -#endif // IMJINGLE_H +} // namespace lib::messenger +#endif // IMJINGLE_H diff --git a/src/lib/messenger/IMJingleSession.cpp b/src/lib/messenger/IMJingleSession.cpp index 1640cd91..204094fd 100644 --- a/src/lib/messenger/IMJingleSession.cpp +++ b/src/lib/messenger/IMJingleSession.cpp @@ -11,183 +11,96 @@ */ #include "IMJingleSession.h" +#include +#include +#include #include "IMFile.h" #include "IMFileTask.h" #include "base/basic_types.h" #include "lib/ortc/ok_rtc.h" #include "lib/ortc/ok_rtc_renderer.h" -#include -#include -#include namespace lib { namespace messenger { IMJingleSession::IMJingleSession(IM* im, - const IMPeerId &peerId, - const QString &sId_, + const IMPeerId& peerId, + const QString& sId_, lib::ortc::JingleCallType callType, - Session *mSession, - std::vector *fileHandlers, - ortc::OkRTCHandler *handler) - : im{im}, - sId(sId_), - session(mSession), - accepted(false), - fileHandlers{fileHandlers}, - m_callType{callType} -{ - qDebug() << __func__ - <<"type:" << (int)m_callType - <<"sid:" << sId - <<"to peer:"<remote().full(); lib::ortc::OJingleContentAv cav; - cav.sdpType =lib::ortc::JingleSdpType::Answer; + cav.sdpType = lib::ortc::JingleSdpType::Answer; cav.parse(jingle); // RTC 接受会话 - lib::ortc:: OkRTCManager::getInstance()->getRtc() - ->setRemoteDescription(peerId, cav); + lib::ortc::OkRTCManager::getInstance()->getRtc()->setRemoteDescription(peerId, cav); -// emit receiveFriendHangup( -// peerId.username, answer.hasVideo() ? TOXAV_FRIEND_CALL_STATE_SENDING_V -// : TOXAV_FRIEND_CALL_STATE_SENDING_A); + // emit receiveFriendHangup( + // peerId.username, answer.hasVideo() ? SENDING_V + // : SENDING_A); } } - -void IMJingleSession::onTerminate() -{ - qDebug()<<__func__; +void IMJingleSession::onTerminate() { + qDebug() << __func__; lib::ortc::OkRTCManager::getInstance()->destroyRtc(); } -void IMJingleSession::doTerminate() -{ - qDebug()<< __func__; +void IMJingleSession::doTerminate() { + qDebug() << __func__; - //发送结束协议 - session->sessionTerminate( - new Session::Reason(Session::Reason::Reasons::Success)); + // 发送结束协议 + session->sessionTerminate(new Session::Reason(Session::Reason::Reasons::Success)); lib::ortc::OkRTCManager::getInstance()->destroyRtc(); } -void IMJingleSession::createOffer(const std::string &peerId) -{ +void IMJingleSession::createOffer(const std::string& peerId) { qDebug() << __func__ << "to" << peerId.c_str(); auto rm = lib::ortc::OkRTCManager::getInstance(); auto r = rm->getRtc(); r->CreateOffer(peerId); } -const Session::Jingle *IMJingleSession::getJingle() const { return jingle; } +const Session::Jingle* IMJingleSession::getJingle() const { return jingle; } -void IMJingleSession::setJingle(const Session::Jingle *jingle_) { - jingle = jingle_; -} +void IMJingleSession::setJingle(const Session::Jingle* jingle_) { jingle = jingle_; } -CallDirection IMJingleSession::direction() const -{ +CallDirection IMJingleSession::direction() const { auto sender = session->initiator().bareJID(); auto self = im->self().bareJID(); - return (sender==self) ? CallDirection::CallOut:CallDirection::CallIn; -} - -void IMJingleSession::setCallStage(CallStage state) -{ - m_callStage=state; -} - -void IMJingleSession::setContext(const ortc::OJingleContent &jc) { - context = jc; -} - - -void IMJingleSession::doStartFileSendTask(const Session *session, - const File &file) { - qDebug()<<__func__<remote(), &file, im); - connect(fileTask, &IMFileTask::fileSending, - [&](const JID &m_friendId, const File &m_file, int m_seq, - int m_sentBytes, bool end) { - - for(auto h: *fileHandlers){ - h->onFileSendInfo(qstring(m_friendId.bare()), - m_file, - m_seq, - m_sentBytes, end); - } - -// emit sendFileInfo(qstring(m_friendId.bare()), m_file, m_seq, -// m_sentBytes, end); - }); - - connect(fileTask, &IMFileTask::fileAbort, - [&](const JID &m_friendId, const File &m_file, - int m_sentBytes) { -// emit sendFileAbort(qstring(m_friendId.bare()), m_file, m_sentBytes); - for(auto h: *fileHandlers){ - h->onFileSendAbort(qstring(m_friendId.bare()), m_file, m_sentBytes); - } - }); - - connect(fileTask, &IMFileTask::fileError, - [&](const JID &m_friendId, const File &m_file, int m_sentBytes) { - for(auto h: *fileHandlers){ - h->onFileSendError(qstring(m_friendId.bare()), m_file, m_sentBytes); - } -// emit sendFileError(qstring(m_friendId.bare()), m_file, -// m_sentBytes); - }); - fileTask->start(); - m_fileSenderMap.insert(file.id, fileTask); - qDebug()<<__func__<<("Send file task has been stared.")<<((file.id)); + return (sender == self) ? CallDirection::CallOut : CallDirection::CallIn; } +void IMJingleSession::setCallStage(CallStage state) { m_callStage = state; } -void IMJingleSession::doStopFileSendTask(const Session *session, - const File &file) { - Q_UNUSED(session) - qDebug()<<__func__<isRunning()) { - fileTask->forceQuit(); - } - disconnect(fileTask); - delete fileTask; - - // 返回截断后续处理 - m_fileSenderMap.remove(file.sId); - qDebug() << "Send file task has been clean."< + #include "IM.h" -#include "IMFile.h" -#include "IMFileTask.h" #include "base/basic_types.h" #include "lib/ortc/ok_rtc_defs.h" #include "lib/ortc/ok_rtc_manager.h" -#include - - -namespace ortc{ -struct IceServer; -} namespace lib { namespace messenger { enum CallStage { - StageNone, - StageMessage, // XEP-0353: Jingle Message Initiation - StageSession // XEP-0166: Jingle https://xmpp.org/extensions/xep-0166.html + StageNone, + StageMessage, // XEP-0353: Jingle Message Initiation + StageSession // XEP-0166: Jingle https://xmpp.org/extensions/xep-0166.html }; using namespace gloox; @@ -40,106 +34,61 @@ using namespace gloox::Jingle; class IMJingleSession : public QObject { Q_OBJECT public: - explicit IMJingleSession(IM* im, - const IMPeerId &peerId, - const QString &sId, - lib::ortc::JingleCallType callType, - Session *mSession, - std::vector* fileHandlers, - ortc::OkRTCHandler *handler); - virtual ~IMJingleSession(); - - - [[nodiscard]] Session *getSession() const; - [[nodiscard]] inline const ortc::OJingleContent &getContext() const { - return context; - } + explicit IMJingleSession(IM* im, + const IMPeerId& peerId, + const QString& sId, + lib::ortc::JingleCallType callType, + Session* mSession); + virtual ~IMJingleSession(); - void onAccept(); - //被动结束 - void onTerminate(); - //主动结束 - void doTerminate(); + [[nodiscard]] Session* getSession() const; + [[nodiscard]] inline const ortc::OJingleContent& getContext() const { return context; } - void createOffer(const std::string &peerId); + void onAccept(); + // 被动结束 + void onTerminate(); + // 主动结束 + void doTerminate(); - void setContext(const ortc::OJingleContent &); + void createOffer(const std::string& peerId); - const Session::Jingle *getJingle() const; - void setJingle(const Session::Jingle *jingle); + void setContext(const ortc::OJingleContent&); - [[nodiscard]] CallDirection direction() const; + const Session::Jingle* getJingle() const; + void setJingle(const Session::Jingle* jingle); - void setCallStage(CallStage state); + [[nodiscard]] CallDirection direction() const; - void setAccepted(bool y) { accepted = y; } + void setCallStage(CallStage state); - [[nodiscard]] bool isAccepted() const { return accepted; } + void setAccepted(bool y) { accepted = y; } + [[nodiscard]] bool isAccepted() const { return accepted; } - const QString & getId() const { - return sId; - } + const QString& getId() const { return sId; } - void appendIce(const ortc::OIceUdp& ice){ - pendingIceCandidates.emplace_back(ice); - } + void appendIce(const ortc::OIceUdp& ice) { pendingIceCandidates.emplace_back(ice); } - void pollIce(Fn fn){ - while (!pendingIceCandidates.empty()){ - fn(pendingIceCandidates.back()); - pendingIceCandidates.pop_back(); + void pollIce(Fn fn) { + while (!pendingIceCandidates.empty()) { + fn(pendingIceCandidates.back()); + pendingIceCandidates.pop_back(); + } } - } - - void addFile(const File &f) { - m_waitSendFiles.append(f); - } - /** - * 启动文件发送任务 - * @param session - * @param file - */ - void doStartFileSendTask(const Jingle::Session *session, - const File &file); - - /** - * 停止文件发送任务 - * @param session - * @param file - */ - void doStopFileSendTask(const Jingle::Session *session, - const File &file); -private: - IM* im; - QString sId; - Session *session; - const Session::Jingle *jingle; - ortc::OJingleContent context; - - - lib::ortc::JingleCallType m_callType; - CallStage m_callStage; - bool accepted; - - //file - QList m_waitSendFiles; - //k: file.id - QMap m_fileSenderMap; - std::vector *fileHandlers; - std::list pendingIceCandidates; - -signals: - void sendFileInfo(const QString &friendId, const File &file, - int m_seq, int m_sentBytes, bool end); +private: + IM* im; + QString sId; + Session* session; + const Session::Jingle* jingle; + ortc::OJingleContent context; - void sendFileAbort(const QString &friendId, const File &file, - int m_sentBytes); - void sendFileError(const QString &friendId, const File &file, - int m_sentBytes); + lib::ortc::JingleCallType m_callType; + CallStage m_callStage; + bool accepted; + std::list pendingIceCandidates; }; -} // namespace IM -} // namespace lib +} // namespace messenger +} // namespace lib diff --git a/src/lib/messenger/IMMessage.cpp b/src/lib/messenger/IMMessage.cpp index 307a283d..b30a5bcd 100644 --- a/src/lib/messenger/IMMessage.cpp +++ b/src/lib/messenger/IMMessage.cpp @@ -11,16 +11,11 @@ */ #include "IMMessage.h" -#include "base/basic_types.h" -#include -#include #include #include #include +#include +#include +#include "base/basic_types.h" -namespace lib::messenger { - - - -} // namespace lib::messenger - +namespace lib::messenger {} // namespace lib::messenger diff --git a/src/lib/messenger/IMMessage.h b/src/lib/messenger/IMMessage.h index 61d43d98..fbdbd0c8 100644 --- a/src/lib/messenger/IMMessage.h +++ b/src/lib/messenger/IMMessage.h @@ -20,23 +20,22 @@ namespace gloox { class JID; class RosterItem; -} +} // namespace gloox namespace lib::messenger { enum class MsgType { - Chat = 1, - Groupchat = 4, + Chat = 1, + Groupchat = 4, }; struct IMMessage { - MsgType type; - QString id; - QString from; - QString to; - QString body; - QDateTime timestamp; + MsgType type; + QString id; + QString from; + QString to; + QString body; + QDateTime timestamp; }; -} // namespace lib::messenger - +} // namespace lib::messenger diff --git a/src/lib/messenger/IMRoomHelper.h b/src/lib/messenger/IMRoomHelper.h index 29021e8d..4eb1e693 100644 --- a/src/lib/messenger/IMRoomHelper.h +++ b/src/lib/messenger/IMRoomHelper.h @@ -12,13 +12,11 @@ #pragma once -#include "messenger.h" #include #include #include +#include "messenger.h" namespace lib { -namespace messenger { - -} // namespace messenger -} // namespace lib +namespace messenger {} // namespace messenger +} // namespace lib diff --git a/src/lib/messenger/messenger.cpp b/src/lib/messenger/messenger.cpp index 59bdab5b..0b44651b 100644 --- a/src/lib/messenger/messenger.cpp +++ b/src/lib/messenger/messenger.cpp @@ -12,615 +12,510 @@ #include "messenger.h" +#include +#include +#include + #include "base/logs.h" #include "base/xmls.h" +#include "src/application.h" #include "lib/messenger/IM.h" #include "lib/messenger/IMConference.h" -#include "lib/messenger/IMJingle.h" +#include "lib/messenger/IMFile.h" +#include "lib/messenger/IMCall.h" #include "lib/plugin/pluginmanager.h" -#include -#include -#include - namespace lib { namespace messenger { - -Messenger::Messenger(QObject *parent) - : QObject(parent), // - _delayer(std::make_unique<::base::DelayedCallTimer>()) // +Messenger::Messenger(const QString& host, + const QString& name, + const QString& password, + QObject* parent) + : QObject(parent) + , _im{nullptr} + , _delayer(std::make_unique<::base::DelayedCallTimer>()) // { qDebug() << __func__; + connect(this, &Messenger::disconnect, this, &Messenger::onDisconnect); - connect(this, &Messenger::disconnect, this, &Messenger::onDisconnect); - auto _session = ok::session::AuthSession::Instance(); - /** - * IM - */ - connectIM(); - + auto _session = ok::Application::Instance()->getSession(); - QStringList features; + QStringList features; #ifdef OK_PLUGIN - auto pm = ok::plugin::PluginManager::instance(); - auto features0 = pm->pluginFeatures(); - features << features0; + auto pm = ok::plugin::PluginManager::instance(); + features << pm->pluginFeatures(); + int acc = pm->addAccount(_session->account(), this); + qDebug() << "PluginManager account id=>" << acc; +#endif + _im = new ::lib::messenger::IM(host, name, password, features); + connectIM(); - int acc = pm->addAccount(_session->account(), this); - qDebug() << "PluginManager account id=>"<("ok::session::SignInInfo"); - ok::session::AuthSession::Instance(); - auto _im = _session->im(); + // connect(_im, &::lib::messenger::IM::started, this, &AuthSession::onIMStarted); - connect(_im, &IM::connectResult, this, [pm,_session](lib::messenger::IMConnectStatus status) { - if(status == lib::messenger::IMConnectStatus::CONNECTED){ - pm->startLogin(_session->account()); - } - }); - -#endif + // connect(_im, &IM::connectResult, this, [pm, &_session](lib::messenger::IMConnectStatus + // status) { + // if(status == lib::messenger::IMConnectStatus::CONNECTED){ + // pm->startLogin(_session->account()); + // } + // }); } -Messenger::~Messenger() { - qDebug() << __func__; -} +Messenger::~Messenger() { qDebug() << __func__; } -//Messenger *Messenger::getInstance() { -// static Messenger *self = nullptr; -// if (!self) -// self = new Messenger(); -// return self; -//} +// Messenger *Messenger::getInstance() { +// static Messenger *self = nullptr; +// if (!self) +// self = new Messenger(); +// return self; +// } void Messenger::start() { -qDebug() << __func__; + qDebug() << __func__; + _im->start(); + connect(_im, &IM::started, [&]() { + _imFile = new IMFile(_im, this); + emit started(); + }); } - - -void Messenger::sendChatState(const QString &friendId, int state) { - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); - _im->sendChatState(friendId, static_cast(state)); +void Messenger::sendChatState(const QString& friendId, int state) { + _im->sendChatState(friendId, static_cast(state)); } void Messenger::onConnectResult(lib::messenger::IMConnectStatus status) { - qDebug() << ("status:") << (int)status; - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); - if (status == lib::messenger::IMConnectStatus::DISCONNECTED) { - _delayer->call(1000 * 5, [&]() { - qDebug(("Retry connect...")); - _im->doConnect(); - }); - } + qDebug() << ("status:") << (int)status; + if (status == lib::messenger::IMConnectStatus::DISCONNECTED) { + _delayer->call(1000 * 5, [&]() { + qDebug(("Retry connect...")); + _im->doConnect(); + }); + } } void Messenger::onStarted() { - qDebug() << "connected..."; - - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); + qDebug() << __func__; -// _im->enableRosterManager(); -// _im->sendPresence(); -// _im->sendServiceDiscoveryItems(); + // _im->enableRosterManager(); + // _im->sendPresence(); + // _im->sendServiceDiscoveryItems(); #ifdef OK_PLUGIN - qDebug() << "Initialize plugin manager..."; - qRegisterMetaType("QDomDocument"); - connect(_im, &IM::exportEncryptedMessage, this, &Messenger::onEncryptedMessage); - qDebug() << "Initialized plugin manager successfully"; + qDebug() << "Initialize plugin manager..."; + qRegisterMetaType("QDomDocument"); + connect(_im, &IM::exportEncryptedMessage, this, &Messenger::onEncryptedMessage); + qDebug() << "Initialized plugin manager successfully"; #endif - qDebug() << "connected completed"; + qDebug() << "connected completed"; } void Messenger::onStopped() { qDebug() << "onStopped..."; } -bool Messenger::connectIM( ) { - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); - - connect(_im, &IM::started, this, &Messenger::onStarted); - connect(_im, &IM::incoming, this, - [=, this](QString xml) { emit incoming(xml); }, Qt::QueuedConnection); - - /** - * selfHandlers - */ - connect(_im, &IM::selfNicknameChanged, this, - [&](const QString &nickname) { - for (auto handler : selfHandlers) { - handler->onSelfNameChanged(nickname); - } - }); - connect(_im, &IM::selfAvatarChanged, this, - [&](const std::string avatar) { - for (auto handler : selfHandlers) { - handler->onSelfAvatarChanged(avatar); - } - }); - connect(_im, &IM::selfStatusChanged, this, - [&](int type, const std::string &status) { - for (auto handler : selfHandlers) { - handler->onSelfStatusChanged(static_cast(type), - status); - } - }); - connect( - _im, &IM::selfIdChanged, this, - [&](QString id) { +bool Messenger::connectIM() { + connect(_im, &IM::started, this, &Messenger::onStarted); + connect( + _im, &IM::incoming, this, [=, this](QString xml) { emit incoming(xml); }, + Qt::QueuedConnection); + + /** + * selfHandlers + */ + connect(_im, &IM::selfNicknameChanged, this, [&](const QString& nickname) { for (auto handler : selfHandlers) { - handler->onSelfIdChanged(id); + handler->onSelfNameChanged(nickname); } - }); - - /** - * friendHandlers - */ - connect(_im, &IM::receiveFriend, this, - [&](const IMFriend & frnd){ - for (auto handler : friendHandlers) { - handler->onFriend(frnd); - } - }); - - connect(_im, &IM::receiveFriendRequest, this, - [&](const QString friendId, QString msg) -> void { - for (auto handler : friendHandlers) { - handler->onFriendRequest(friendId, msg); - } - }); - - connect(_im, &IM::receiveMessageReceipt, this, - [&](QString friendId, QString receipt) -> void { - for (auto handler : friendHandlers) { - handler->onMessageReceipt(friendId, receipt); - } - }); - - connect(_im, &IM::receiveFriendStatus, this, - [&](QString friendId, int type) -> void { - for (auto handler : friendHandlers) { - handler->onFriendStatus(friendId, static_cast(type)); - } - }); - - connect(_im, &IM::receiveFriendChatState, this, - [&](QString friendId, int state) -> void { - for (auto handler : friendHandlers) { - handler->onFriendChatState(friendId, state); - } - }); - - connect(_im, &IM::receiveFriendMessage, this, - [&](QString friendId, IMMessage msg) -> void { - for (auto handler : friendHandlers) { - handler->onFriendMessage(friendId, msg); - } - }); - - connect(_im, &IM::receiveMessageSession, this, - [&](QString contactId, QString sid) -> void { - for (auto handler : friendHandlers) { - handler->onMessageSession(contactId, sid); - } - }); - - connect(_im, &IM::receiveNicknameChange, this, - [&](QString friendId, QString nickname) { - for (auto handler : friendHandlers) { - handler->onFriendNameChanged(friendId, nickname); - } - }); - - connect(_im, &IM::receiveFriendAvatarChanged, this, - [&](QString friendId, std::string avatar) { - for (auto handler : friendHandlers) { - handler->onFriendAvatarChanged(friendId, avatar); - } - }); - - connect(_im, &IM::receiveFriendAliasChanged, this, - [&](const JID& friendId, const std::string& alias) { - for (auto handler : friendHandlers) { - handler->onFriendAliasChanged(IMContactId(friendId.bareJID()), qstring(alias)); - } - }); - - - - //group - connect(_im, &IM::groupInvite, this, - [&](const QString &groupId, const QString &peerId, - const QString &message) { - for (auto handler : groupHandlers) { - handler->onGroupInvite(groupId, peerId, message); - } - }); - - - connect(_im, &IM::groupSubjectChanged, this, - [&](const JID &group, const std::string &subject) -> void { - for (auto handler : groupHandlers) { - handler->onGroupSubjectChanged(qstring(group.bare()), qstring(subject)); - } - }); - - connect(_im, &IM::groupReceived, this, - &Messenger::onGroupReceived); - - connect(_im, &IM::receiveRoomMessage, this, - [&](QString groupId, IMPeerId peerId, IMMessage msg) -> void { - for (auto handler : groupHandlers) { - handler->onGroupMessage(groupId, peerId, msg); - } - }); - - connect(_im, &IM::groupOccupants, this, - [&](const QString &groupId, const uint size) -> void { - for (auto handler : groupHandlers) { - handler->onGroupOccupants(groupId, size); - } - }); - - connect( - _im, &IM::groupOccupantStatus, this, - [&](const QString &groupId, const IMGroupOccupant &go) -> void { - for (auto handler : groupHandlers) { - handler->onGroupOccupantStatus(groupId, go); + }); + connect(_im, &IM::selfAvatarChanged, this, [&](const std::string avatar) { + for (auto handler : selfHandlers) { + handler->onSelfAvatarChanged(avatar); } - }); - - qRegisterMetaType("IMGroup"); - connect(_im, &IM::groupRoomInfo, this, - [&](const QString &groupId, const IMGroup info) -> void { - for (auto handler : groupHandlers) { - handler->onGroupInfo(groupId, info); - } - }); - + }); + connect(_im, &IM::selfStatusChanged, this, [&](int type, const std::string& status) { + for (auto handler : selfHandlers) { + handler->onSelfStatusChanged(static_cast(type), status); + } + }); + connect(_im, &IM::selfIdChanged, this, [&](QString id) { + for (auto handler : selfHandlers) { + handler->onSelfIdChanged(id); + } + }); - return true; -} + /** + * friendHandlers + */ + connect(_im, &IM::receiveFriend, this, [&](const IMFriend& frnd) { + for (auto handler : friendHandlers) { + handler->onFriend(frnd); + } + }); + connect(_im, &IM::receiveFriendRequest, this, [&](const QString friendId, QString msg) -> void { + for (auto handler : friendHandlers) { + handler->onFriendRequest(friendId, msg); + } + }); -bool Messenger::initRoom() { - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); - _im->loadGroupList(); - return true; -} + connect(_im, &IM::receiveMessageReceipt, this, [&](QString friendId, QString receipt) -> void { + for (auto handler : friendHandlers) { + handler->onMessageReceipt(friendId, receipt); + } + }); -void Messenger::onReceiveGroupMessage(IMMessage msg) { - emit receivedGroupMessage(msg); -} + connect(_im, &IM::receiveFriendStatus, this, [&](QString friendId, int type) -> void { + for (auto handler : friendHandlers) { + handler->onFriendStatus(friendId, static_cast(type)); + } + }); -QString Messenger::genUniqueId() { - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); - return qstring(_im->getClient()->getID()); -} + connect(_im, &IM::receiveFriendChatState, this, [&](QString friendId, int state) -> void { + for (auto handler : friendHandlers) { + handler->onFriendChatState(friendId, state); + } + }); -bool Messenger::sendToGroup(const QString &g,const QString &msg,const QString &id) { + connect(_im, &IM::receiveFriendMessage, this, [&](QString friendId, IMMessage msg) -> void { + for (auto handler : friendHandlers) { + handler->onFriendMessage(friendId, msg); + } + }); - qDebug() << QString("sendToGroup=>%1 id:%2 msg:%2").arg(g).arg(id).arg(msg); - sentCount++; + connect(_im, &IM::receiveMessageSession, this, [&](QString contactId, QString sid) -> void { + for (auto handler : friendHandlers) { + handler->onMessageSession(contactId, sid); + } + }); - auto _session = ok::session::AuthSession::Instance(); - return _session->im()->sendToRoom(g, msg, id); -} + connect(_im, &IM::receiveNicknameChange, this, [&](QString friendId, QString nickname) { + for (auto handler : friendHandlers) { + handler->onFriendNickChanged(friendId, nickname); + } + }); + connect(_im, &IM::receiveFriendAvatarChanged, this, [&](QString friendId, std::string avatar) { + for (auto handler : friendHandlers) { + handler->onFriendAvatarChanged(friendId, avatar); + } + }); -bool Messenger::sendToFriend(const QString &f, - const QString &msg, - const QString &id, - bool encrypt) { - qDebug() << __func__ << msg << "=>" << f; - sentCount++; + connect(_im, &IM::receiveFriendAliasChanged, this, + [&](const JID& friendId, const std::string& alias) { + for (auto handler : friendHandlers) { + handler->onFriendAliasChanged(IMContactId(friendId.bareJID()), qstring(alias)); + } + }); + + // group + connect(_im, &IM::groupInvite, this, + [&](const QString& groupId, const QString& peerId, const QString& message) { + for (auto handler : groupHandlers) { + handler->onGroupInvite(groupId, peerId, message); + } + }); + + connect(_im, &IM::groupSubjectChanged, this, + [&](const JID& group, const std::string& subject) -> void { + for (auto handler : groupHandlers) { + handler->onGroupSubjectChanged(qstring(group.bare()), qstring(subject)); + } + }); + + connect(_im, &IM::groupReceived, this, &Messenger::onGroupReceived); + + connect(_im, &IM::receiveRoomMessage, this, + [&](QString groupId, IMPeerId peerId, IMMessage msg) -> void { + for (auto handler : groupHandlers) { + handler->onGroupMessage(groupId, peerId, msg); + } + }); + + connect(_im, &IM::groupOccupants, this, [&](const QString& groupId, const uint size) -> void { + for (auto handler : groupHandlers) { + handler->onGroupOccupants(groupId, size); + } + }); - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); + connect(_im, &IM::groupOccupantStatus, this, + [&](const QString& groupId, const IMGroupOccupant& go) -> void { + for (auto handler : groupHandlers) { + handler->onGroupOccupantStatus(groupId, go); + } + }); + qRegisterMetaType("IMGroup"); + connect(_im, &IM::groupRoomInfo, this, [&](const QString& groupId, const IMGroup info) -> void { + for (auto handler : groupHandlers) { + handler->onGroupInfo(groupId, info); + } + }); - bool y = false; - if (encrypt) { -#ifdef OK_PLUGIN - auto _session = ok::session::AuthSession::Instance(); - base::Jid ownJid(qstring(_im->self().full())); - _session->account()->setJid(ownJid); + return true; +} - auto pm = ok::plugin::PluginManager::instance(); - pm->addAccount(_session->account(), this); +bool Messenger::initRoom() { + _im->loadGroupList(); + return true; +} - auto dom = _im->buildMessage(f, msg, id); - auto ele = dom.documentElement(); +void Messenger::onReceiveGroupMessage(IMMessage msg) { emit receivedGroupMessage(msg); } - if (pm->encryptMessageElement(_session->account(), ele)) { - qDebug()<<"encryptMessageElement=>"<send(xml); - y = true; - } -#endif - } - if (!y) { - y = _im->sendTo(f, msg, id); - } - return y; -} +QString Messenger::genUniqueId() { return qstring(_im->getClient()->getID()); } -void Messenger::receiptReceived(const QString &f, QString receipt) { - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); - return _im->sendReceiptReceived(f, receipt); +bool Messenger::sendToGroup(const QString& g, const QString& msg, const QString& id) { + qDebug() << QString("sendToGroup=>%1 id:%2 msg:%2").arg(g).arg(id).arg(msg); + sentCount++; + return _im->sendToRoom(g, msg, id); } -void Messenger::sendFriendRequest(const QString &f,const QString &nick, const QString &message) { - qDebug() <<__func__ << f << nick << message; - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); - _im->addFriend(JID(stdstring(f)), nick, message); -} +bool Messenger::sendToFriend(const QString& f, + const QString& msg, + const QString& id, + bool encrypt) { + qDebug() << __func__ << msg << "=>" << f; + sentCount++; + bool y = false; + if (encrypt) { +#ifdef OK_PLUGIN + auto _session = ok::Application::Instance()->getSession(); + base::Jid ownJid(qstring(_im->self().full())); + _session->account()->setJid(ownJid); + auto pm = ok::plugin::PluginManager::instance(); + pm->addAccount(_session->account(), this); -void Messenger::acceptFriendRequest(const QString &f) { - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); - _im->acceptFriendRequest(f); -} + auto dom = _im->buildMessage(f, msg, id); + auto ele = dom.documentElement(); -void Messenger::rejectFriendRequest(const QString &f) { - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); - _im->rejectFriendRequest(f); + if (pm->encryptMessageElement(_session->account(), ele)) { + qDebug() << "encryptMessageElement=>" << ele.ownerDocument().toString(); + auto xml = ::base::Xmls::format(ele); + _im->send(xml); + y = true; + } +#endif + } + if (!y) { + y = _im->sendTo(f, msg, id); + } + return y; } -void Messenger::getFriendVCard(const QString &f) { - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); - _im->fetchFriendVCard(f); +void Messenger::receiptReceived(const QString& f, QString receipt) { + return _im->sendReceiptReceived(f, receipt); } -bool Messenger::removeFriend(const QString &f) { - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); - return _im->removeFriend(JID(f.toStdString())); +void Messenger::sendFriendRequest(const QString& f, const QString& nick, const QString& message) { + qDebug() << __func__ << f << nick << message; + _im->addFriend(JID(stdstring(f)), nick, message); } -size_t Messenger::getFriendCount() { - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); - return _im->getRosterCount(); -} +void Messenger::acceptFriendRequest(const QString& f) { _im->acceptFriendRequest(f); } -void Messenger::getFriendList(std::list& list) { - auto _session = ok::session::AuthSession::Instance(); - _session->im()->getRosterList(list); -} +void Messenger::rejectFriendRequest(const QString& f) { _im->rejectFriendRequest(f); } -void Messenger::setFriendAlias(const QString &f, const QString &alias) -{ - auto _session = ok::session::AuthSession::Instance(); - _session->im()->setFriendAlias(JID(stdstring(f)), stdstring(alias)); -} +void Messenger::getFriendVCard(const QString& f) { _im->fetchFriendVCard(f); } -IMStatus Messenger::getFriendStatus(const QString &f) { - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); - return _im->getFriendStatus(f); -} +bool Messenger::removeFriend(const QString& f) { return _im->removeFriend(JID(f.toStdString())); } +size_t Messenger::getFriendCount() { return _im->getRosterCount(); } -void Messenger::addSelfHandler(SelfHandler *handler) { - selfHandlers.push_back(handler); -} +void Messenger::getFriendList(std::list& list) { _im->getRosterList(list); } -void Messenger::addFriendHandler(FriendHandler *handler) { - friendHandlers.push_back(handler); +void Messenger::setFriendAlias(const QString& f, const QString& alias) { + _im->setFriendAlias(JID(stdstring(f)), stdstring(alias)); } -void Messenger::addGroupHandler(GroupHandler *handler) { - groupHandlers.push_back(handler); -} +IMStatus Messenger::getFriendStatus(const QString& f) { return _im->getFriendStatus(f); } +void Messenger::addSelfHandler(SelfHandler* handler) { selfHandlers.push_back(handler); } +void Messenger::addFriendHandler(FriendHandler* handler) { friendHandlers.push_back(handler); } +void Messenger::addGroupHandler(GroupHandler* handler) { groupHandlers.push_back(handler); } -void Messenger::stop() { - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); - _im->stop(); -} +void Messenger::stop() { _im->stop(); } -void Messenger::send(const QString &xml) { - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); - _im->send(xml); -} +void Messenger::send(const QString& xml) { _im->send(xml); } -IMPeerId Messenger::getSelfId() const { - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); - return _im->getSelfPeerId(); -} +IMPeerId Messenger::getSelfId() const { return _im->getSelfPeerId(); } IMStatus Messenger::getSelfStatus() const { - auto pt = gloox::Presence::PresenceType::Available; - return static_cast(pt); + auto pt = gloox::Presence::PresenceType::Available; + return static_cast(pt); } -void Messenger::setSelfNickname(const QString &nickname) { - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); - _im->setNickname(nickname); -} +void Messenger::setSelfNickname(const QString& nickname) { _im->setNickname(nickname); } -QString Messenger::getSelfUsername() const { - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); - return _im->getSelfUsername(); -} +QString Messenger::getSelfUsername() const { return _im->getSelfUsername(); } -QString Messenger::getSelfNick() const { - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); - return _im->getNickname(); -} +QString Messenger::getSelfNick() const { return _im->getNickname(); } -void Messenger::changePassword(const QString &password) { - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); - _im->changePassword(password); -} +void Messenger::changePassword(const QString& password) { _im->changePassword(password); } void Messenger::onDisconnect() { - _delayer->call(1000 * 5, [&]() { - qDebug(("retry connect...")); - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); - _im->start(); - }); + _delayer->call(1000 * 5, [&]() { + qDebug(("retry connect...")); + _im->start(); + }); } void Messenger::onEncryptedMessage(QString xml) { #ifdef OK_PLUGIN - if(xml.isNull()) - { - qWarning()<<"Empty encryptedMessage!"; - return; - } - auto dom = ::base::Xmls::parse(xml); - - qDebug() << "onEncryptedMessage:"<getSignInInfo(); - auto _im = _session->im(); - _session->account()->setJid(qstring(_im->self().full())); - auto pm = ok::plugin::PluginManager::instance(); - pm->addAccount(_session->account(), this); - auto ele= dom.documentElement(); - bool decrypted = pm->decryptMessageElement(_session->account(), ele); - qDebug()<<"decrypt message=>" << decrypted; - - auto body = ele.firstChildElement("body").text(); - if (body.isEmpty()){ - qWarning()<<"Empty body!"; - return; - } - - auto from = ele.attribute("from"); - auto to = ele.attribute("to"); - auto id = ele.attribute("id"); - - auto msg = IMMessage{MsgType::Chat, id, from, to, body, QDateTime::currentDateTime()}; - - for (auto handler : friendHandlers) { - handler->onFriendMessage(qstring(JID(stdstring(from)).bareJID().bare()), msg); - } -#endif -} + if (xml.isNull()) { + qWarning() << "Empty encryptedMessage!"; + return; + } + auto dom = ::base::Xmls::parse(xml); -void Messenger::loadGroupList() { - ok::session::AuthSession::Instance()->im()->loadGroupList(); -} + qDebug() << "onEncryptedMessage:" << dom.toString(); + auto _session = ok::Application::Instance()->getSession(); + auto info = _session->getSignInInfo(); + + _session->account()->setJid(qstring(_im->self().full())); + auto pm = ok::plugin::PluginManager::instance(); + pm->addAccount(_session->account(), this); -QString Messenger::createGroup(const QString &groupId, const QString& groupName) { - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); - JID self = _im->self(); - self.setUsername(stdstring(groupId)); - self.setResource(stdstring(groupName)); - self.setServer("conference."+self.server()); + auto ele = dom.documentElement(); + bool decrypted = pm->decryptMessageElement(_session->account(), ele); + qDebug() << "decrypt message=>" << decrypted; - _im->createRoom(self); - return qstring(self.bare()); -} + auto body = ele.firstChildElement("body").text(); + if (body.isEmpty()) { + qWarning() << "Empty body!"; + return; + } -bool Messenger::inviteGroup(const IMContactId &group, const IMContactId &f) { - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); - return _im->inviteToRoom(JID(stdstring(group.toString())), JID(stdstring(f.toString()))); -} + auto from = ele.attribute("from"); + auto to = ele.attribute("to"); + auto id = ele.attribute("id"); -bool Messenger::leaveGroup(const QString &group) { - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); - return _im->leaveGroup(group); + auto msg = IMMessage{MsgType::Chat, id, from, to, body, QDateTime::currentDateTime()}; + + for (auto handler : friendHandlers) { + handler->onFriendMessage(qstring(JID(stdstring(from)).bareJID().bare()), msg); + } +#endif } +void Messenger::loadGroupList() { _im->loadGroupList(); } -bool Messenger::destroyGroup(const QString &group) { - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); - return _im->destroyGroup(group); -} +QString Messenger::createGroup(const QString& groupId, const QString& groupName) { + JID self = _im->self(); + self.setUsername(stdstring(groupId)); + self.setResource(stdstring(groupName)); + self.setServer("conference." + self.server()); -void Messenger::setRoomName(const QString &group, const QString &nick) { - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); - _im->setRoomName(group, stdstring(nick)); + _im->createRoom(self); + return qstring(self.bare()); } -void Messenger::setRoomDesc(const QString &group, const QString &nick) -{ - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); - _im->setRoomDesc(group, stdstring(nick)); +bool Messenger::inviteGroup(const IMContactId& group, const IMContactId& f) { + return _im->inviteToRoom(JID(stdstring(group.toString())), JID(stdstring(f.toString()))); } -void Messenger::setRoomSubject(const QString &group, const QString ¬ice) { - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); - _im->setRoomSubject(group, stdstring(notice)); +bool Messenger::leaveGroup(const QString& group) { return _im->leaveGroup(group); } + +bool Messenger::destroyGroup(const QString& group) { return _im->destroyGroup(group); } + +void Messenger::setRoomName(const QString& group, const QString& nick) { + _im->setRoomName(group, stdstring(nick)); } -void Messenger::setRoomAlias(const QString &group, const QString &alias) -{ - auto _session = ok::session::AuthSession::Instance(); - _session->im()->setRoomAlias(group, stdstring(alias)); +void Messenger::setRoomDesc(const QString& group, const QString& nick) { + _im->setRoomDesc(group, stdstring(nick)); } +void Messenger::setRoomSubject(const QString& group, const QString& notice) { + _im->setRoomSubject(group, stdstring(notice)); +} -void Messenger::joinGroup(const QString &group) { - qDebug() << QString("group:%1").arg(group); - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); - _im->joinRoom(group); +void Messenger::setRoomAlias(const QString& group, const QString& alias) { + _im->setRoomAlias(group, stdstring(alias)); } -void Messenger::setSelfAvatar(const QByteArray &avatar) { - auto _session = ok::session::AuthSession::Instance(); - auto _im = _session->im(); - _im->setAvatar(avatar); +void Messenger::joinGroup(const QString& group) { + qDebug() << QString("group:%1").arg(group); + _im->joinRoom(group); } -void Messenger::requestBookmarks() { - auto session = ok::session::AuthSession::Instance(); - auto im = session->im(); - im->requestVCards(); - // im->requestBookmarks(); - //im->enablePubSubManager(); +void Messenger::setSelfAvatar(const QByteArray& avatar) { + _im->setAvatar(avatar); } -void Messenger::setUIStarted(){ - auto session = ok::session::AuthSession::Instance(); - auto im = session->im(); -// im->setUIStarted(); +void Messenger::requestBookmarks() { + _im->requestVCards(); + // im->requestBookmarks(); + // im->enablePubSubManager(); } void Messenger::onGroupReceived(QString groupId, QString name) { for (auto handler : groupHandlers) { - handler->onGroup(groupId, name); + handler->onGroup(groupId, name); } } +//Call +MessengerCall::MessengerCall(Messenger* messenger, QObject* parent) { + call = messenger->imCall(); +} +void MessengerCall::addCallHandler(CallHandler* h) { + call->addCallHandler(h); +} +bool MessengerCall::callToFriend(const QString& f, const QString& sId, bool video) { + return call->callToFriend(f, sId, video); +} +bool MessengerCall::callToPeerId(const IMPeerId& to, const QString& sId, bool video) { + return call->callToPeerId(to, sId,video); +} +bool MessengerCall::callAnswerToFriend(const IMPeerId& peer, const QString& callId, bool video) { + return call->callAnswerToFriend(peer, callId, video); +} +void MessengerCall::callRetract(const IMContactId& f, const QString& sId) { + call->callRetract(f, sId); +} +void MessengerCall::callReject(const IMPeerId& f, const QString& sId) { + call->callReject(f, sId); +} +void MessengerCall::setMute(bool mute) { + call->setMute(mute); +} +void MessengerCall::setRemoteMute(bool mute) { + call->setRemoteMute(mute); +} + +//File + +MessengerFile::MessengerFile(Messenger* messenger, QObject* parent) : QObject(parent){ + fileSender = messenger->imFile(); +} + +void MessengerFile::fileRejectRequest(QString friendId, const File& file) { + fileSender->fileRejectRequest(friendId, file); +} +void MessengerFile::fileAcceptRequest(QString friendId, const File& file) { + fileSender->fileAcceptRequest(friendId, file); +} +void MessengerFile::fileFinishRequest(QString friendId, const QString& sId) { + fileSender->fileFinishRequest(friendId, sId); +} +void MessengerFile::fileFinishTransfer(QString friendId, const QString& sId) { + fileSender->fileFinishTransfer(friendId, sId); +} +void MessengerFile::fileCancel(QString fileId) { + fileSender->fileCancel(fileId); +} +bool MessengerFile::fileSendToFriend(const QString& f, const File& file) { + return fileSender->fileSendToFriend(f, file); +} -} // namespace messenger -} // namespace lib +} // namespace messenger +} // namespace lib diff --git a/src/lib/messenger/messenger.h b/src/lib/messenger/messenger.h index 3dadcddf..374cb73a 100644 --- a/src/lib/messenger/messenger.h +++ b/src/lib/messenger/messenger.h @@ -12,9 +12,9 @@ #pragma once -#include "IMMessage.h" #include "IMFriend.h" #include "IMGroup.h" +#include "IMMessage.h" #include "base/task.h" #include "base/timer.h" @@ -35,214 +35,438 @@ class IMJingle; class IMConference; enum class IMStatus; -} // namespace messenger -} // namespace lib +} // namespace messenger +} // namespace lib namespace ok { namespace session { class AuthSession; } -} // namespace ok +} // namespace ok namespace lib { namespace messenger { +class IM; +class IMFile; +class IMCall; /** * 连接状态 * */ enum class IMConnectStatus { - CONNECTING, AUTH_FAILED, CONNECTED, - DISCONNECTED, TIMEOUT, CONN_ERROR, - TLS_ERROR, OUT_OF_RESOURCE, NO_SUPPORT + CONNECTING, + AUTH_FAILED, + CONNECTED, + DISCONNECTED, + TIMEOUT, + CONN_ERROR, + TLS_ERROR, + OUT_OF_RESOURCE, + NO_SUPPORT }; class SelfHandler { public: - virtual void onSelfIdChanged(QString id) = 0; - virtual void onSelfNameChanged(QString name) = 0; - virtual void onSelfAvatarChanged(const std::string avatar) = 0; - virtual void onSelfStatusChanged(IMStatus status, const std::string &msg) = 0; + virtual void onSelfIdChanged(QString id) = 0; + virtual void onSelfNameChanged(QString name) = 0; + virtual void onSelfAvatarChanged(const std::string avatar) = 0; + virtual void onSelfStatusChanged(IMStatus status, const std::string& msg) = 0; }; class FriendHandler { public: - virtual void onFriend(const IMFriend & frnd) = 0; - virtual void onFriendRequest(QString friendId, QString msg) = 0; - virtual void onFriendRemoved(QString friendId) = 0; - virtual void onFriendStatus(QString friendId, IMStatus status) = 0; - virtual void onFriendMessage(QString friendId, IMMessage message) = 0; - virtual void onMessageSession(QString contactId, QString sid) = 0; - virtual void onFriendNameChanged(QString friendId, QString name) = 0; - virtual void onFriendAvatarChanged(const QString friendId, - const std::string avatar) = 0; - - virtual void onFriendAliasChanged(const IMContactId & fId, const QString& alias)=0; - - virtual void onFriendChatState(QString friendId, int state) = 0; - virtual void onMessageReceipt(QString friendId, QString receipt) = 0; + virtual void onFriend(const IMFriend& frnd) = 0; + virtual void onFriendRequest(QString friendId, QString msg) = 0; + virtual void onFriendRemoved(QString friendId) = 0; + virtual void onFriendStatus(QString friendId, IMStatus status) = 0; + virtual void onFriendMessage(QString friendId, IMMessage message) = 0; + virtual void onMessageSession(QString contactId, QString sid) = 0; + virtual void onFriendNickChanged(QString friendId, QString name) = 0; + virtual void onFriendAvatarChanged(const QString friendId, const std::string avatar) = 0; + + virtual void onFriendAliasChanged(const IMContactId& fId, const QString& alias) = 0; + + virtual void onFriendChatState(QString friendId, int state) = 0; + virtual void onMessageReceipt(QString friendId, QString receipt) = 0; }; class GroupHandler { public: - virtual void onGroup(const QString groupId, - const QString name) = 0; + virtual void onGroup(const QString groupId, const QString name) = 0; - virtual void onGroupInvite(const QString groupId, // - const QString peerId, // - const QString message) = 0; + virtual void onGroupInvite(const QString groupId, // + const QString peerId, // + const QString message) = 0; - virtual void onGroupSubjectChanged(const QString &groupId, const QString &subject)=0; + virtual void onGroupSubjectChanged(const QString& groupId, const QString& subject) = 0; - virtual void onGroupMessage(const QString groupId, // - const IMPeerId peerId, // - const IMMessage message) = 0; + virtual void onGroupMessage(const QString groupId, // + const IMPeerId peerId, // + const IMMessage message) = 0; - virtual void onGroupOccupants(const QString groupId, uint size) = 0; + virtual void onGroupOccupants(const QString groupId, uint size) = 0; - virtual void onGroupInfo(QString groupId, IMGroup groupInfo) = 0; + virtual void onGroupInfo(QString groupId, IMGroup groupInfo) = 0; - virtual void onGroupOccupantStatus(const QString groupId, // - IMGroupOccupant) = 0; + virtual void onGroupOccupantStatus(const QString groupId, // + IMGroupOccupant) = 0; }; - - +/** + * OkIM模块对外接口 + */ class Messenger : public QObject { - Q_OBJECT + Q_OBJECT public: -// using Ptr = std::shared_ptr; - explicit Messenger(QObject *parent = nullptr); - ~Messenger() override; + explicit Messenger(const QString& host, + const QString& name, + const QString& password, + QObject* parent = nullptr); + ~Messenger() override; -// static Messenger *getInstance(); + void start(); + void stop(); - void start(); - void stop(); + void send(const QString& xml); - void send(const QString &xml); + IM* im() const { + assert(_im); + return _im; + } - IMPeerId getSelfId() const; - QString getSelfUsername() const; - QString getSelfNick() const; - IMStatus getSelfStatus() const; + IMFile* imFile() const { + assert(_imFile); + return _imFile; + } - void addSelfHandler(SelfHandler *); - void addGroupHandler(GroupHandler *); + IMCall* imCall()const{ + assert(_imCall); + return _imCall; + } + IMPeerId getSelfId() const; + QString getSelfUsername() const; + QString getSelfNick() const; + IMStatus getSelfStatus() const; - bool sendToGroup(const QString &g, const QString &msg, const QString &id); + void addSelfHandler(SelfHandler*); + void addGroupHandler(GroupHandler*); + bool sendToGroup(const QString& g, const QString& msg, const QString& id); + void receiptReceived(const QString& f, QString receipt); - void receiptReceived(const QString &f, QString receipt); + QString genUniqueId(); + /** self */ + void setSelfNickname(const QString& nickname); + void changePassword(const QString& password); + void setSelfAvatar(const QByteArray& avatar); + // void setMute(bool mute); - QString genUniqueId(); + /** + * IMFriend (audio/video) + */ + void addFriendHandler(FriendHandler*); - /** self */ - void setSelfNickname(const QString &nickname); - void changePassword(const QString &password); - void setSelfAvatar(const QByteArray &avatar); - // void setMute(bool mute); + size_t getFriendCount(); - /** - * IMFriend (audio/video) - */ - void addFriendHandler(FriendHandler *); + void getFriendList(std::list&); - size_t getFriendCount(); + void setFriendAlias(const QString& f, const QString& alias); - void getFriendList(std::list &); + // 添加好友 + void sendFriendRequest(const QString& username, const QString& nick, const QString& message); + // 接受朋友邀请 + void acceptFriendRequest(const QString& f); + // 拒绝朋友邀请 + void rejectFriendRequest(const QString& f); - void setFriendAlias(const QString &f, const QString &alias); + void getFriendVCard(const QString& f); - // 添加好友 - void sendFriendRequest(const QString &username, const QString &nick, const QString &message); - // 接受朋友邀请 - void acceptFriendRequest(const QString &f); - // 拒绝朋友邀请 - void rejectFriendRequest(const QString &f); - - void getFriendVCard(const QString &f); + IMStatus getFriendStatus(const QString& f); - IMStatus getFriendStatus(const QString &f); + bool sendToFriend(const QString& f, + const QString& msg, + const QString& id, + bool encrypt = false); + bool removeFriend(const QString& f); - bool sendToFriend(const QString &f, const QString &msg, const QString &id, - bool encrypt = false); - bool removeFriend(const QString &f); + /** + * Group + */ + void loadGroupList(); + bool initRoom(); - /** - * Group - */ - void loadGroupList(); - bool initRoom(); + QString createGroup(const QString& group, const QString& name); + void joinGroup(const QString& group); + void setRoomName(const QString& group, const QString& nick); + void setRoomDesc(const QString& group, const QString& desc); + void setRoomSubject(const QString& group, const QString& subject); + void setRoomAlias(const QString& group, const QString& alias); + bool inviteGroup(const IMContactId& group, const IMContactId& f); + bool leaveGroup(const QString& group); + bool destroyGroup(const QString& group); - QString createGroup(const QString &group, const QString &name); - void joinGroup(const QString &group); - void setRoomName(const QString &group, const QString &nick); - void setRoomDesc(const QString &group, const QString &desc); - void setRoomSubject(const QString &group, const QString &subject); - void setRoomAlias(const QString &group, const QString &alias); - bool inviteGroup(const IMContactId &group, const IMContactId &f); - bool leaveGroup(const QString &group); - bool destroyGroup(const QString &group); + void sendChatState(const QString& friendId, int state); + void requestBookmarks(); +private: + bool connectIM(); + IM* _im; + IMJingle* jingle; + IMFile* _imFile; + IMCall* _imCall; - void sendChatState(const QString &friendId, int state); + // key: sId value:Jingle + // QMap jingleMap; + std::unique_ptr _conference; - void requestBookmarks(); - void setUIStarted(); + std::vector friendHandlers; + std::vector selfHandlers; + std::vector groupHandlers; -private: + size_t sentCount = 0; + std::unique_ptr _delayer; +signals: + void started(); + void stopped(); + void connected(); + void disconnect(); + void incoming(const QString dom); + void receivedGroupMessage(lib::messenger::IMMessage imMsg); // + void messageSent(const IMMessage& message); // - bool connectIM(); +private slots: + void onConnectResult(lib::messenger::IMConnectStatus); + void onStarted(); + void onStopped(); + void onReceiveGroupMessage(lib::messenger::IMMessage imMsg); + void onDisconnect(); + void onEncryptedMessage(QString dom); + void onGroupReceived(QString groupId, QString name); +}; - IMJingle *jingle; +class IMCall; + +enum class CallState { + + /** + * The empty bit mask. None of the bits specified below are set. + */ + NONE = 0, + + /** + * Set by the AV core if an error occurred on the remote end or if friend + * timed out. This is the final state after which no more state + * transitions can occur for the call. This call state will never be triggered + * in combination with other call states. + */ + ERROR0 = 1, + + /** + * The call has finished. This is the final state after which no more state + * transitions can occur for the call. This call state will never be + * triggered in combination with other call states. + */ + FINISHED = 2, + + /** + * The flag that marks that friend is sending audio. + */ + SENDING_A = 4, + + /** + * The flag that marks that friend is sending video. + */ + SENDING_V = 8, + + /** + * The flag that marks that friend is receiving audio. + */ + ACCEPTING_A = 16, + + /** + * The flag that marks that friend is receiving video. + */ + ACCEPTING_V = 32, +}; + +class CallHandler { +public: + virtual void onCall(const IMPeerId& peerId, // + const QString& callId, // + bool audio, bool video) = 0; + + virtual void onCallRetract(const QString& friendId, // + int state) = 0; + + virtual void onCallAcceptByOther(const QString& callId, const IMPeerId& peerId) = 0; + + virtual void receiveCallStateAccepted(IMPeerId friendId, // + QString callId, // + bool video) = 0; + + virtual void receiveCallStateRejected(IMPeerId friendId, // + QString callId, // + bool video) = 0; + + virtual void onHangup(const QString& friendId, // + CallState state) = 0; + + virtual void onSelfVideoFrame(uint16_t w, uint16_t h, // + const uint8_t* y, // + const uint8_t* u, // + const uint8_t* v, // + int32_t ystride, // + int32_t ustride, // + int32_t vstride) = 0; + + virtual void onFriendVideoFrame(const QString& friendId, // + uint16_t w, uint16_t h, // + const uint8_t* y, // + const uint8_t* u, // + const uint8_t* v, // + int32_t ystride, // + int32_t ustride, // + int32_t vstride) = 0; +}; - //key: sId value:Jingle -// QMap jingleMap; - std::unique_ptr _conference; +class MessengerCall : public QObject{ + Q_OBJECT +public: + MessengerCall(Messenger *messenger, QObject* parent = nullptr); + void addCallHandler(CallHandler*); + + // 发起呼叫邀请 + bool callToFriend(const QString& f, const QString& sId, bool video); + // 创建呼叫 + bool callToPeerId(const IMPeerId& to, const QString& sId, bool video); + // 应答呼叫 + bool callAnswerToFriend(const IMPeerId& peer, const QString& callId, bool video); + // 取消呼叫 + void callRetract(const IMContactId& f, const QString& sId); + // 拒绝呼叫 + void callReject(const IMPeerId& f, const QString& sId); + + // 静音功能 + void setMute(bool mute); + void setRemoteMute(bool mute); - std::vector friendHandlers; - std::vector selfHandlers; - std::vector groupHandlers; +private: + IMCall* call; + + signals: + void receiveSelfVideoFrame(uint16_t w, uint16_t h, // + const uint8_t* y, // + const uint8_t* u, // + const uint8_t* v, // + int32_t ystride, // + int32_t ustride, // + int32_t vstride); + + void receiveFriendVideoFrame(const QString& friendId, // + uint16_t w, uint16_t h, // + const uint8_t* y, // + const uint8_t* u, // + const uint8_t* v, // + int32_t ystride, // + int32_t ustride, // + int32_t vstride); +}; +// 不要修改顺序和值 +enum class FileStatus { + INITIALIZING = 0, + PAUSED = 1, + TRANSMITTING = 2, + BROKEN = 3, + CANCELED = 4, + FINISHED = 5, +}; +// 不要修改顺序和值 +enum class FileDirection { + SENDING = 0, + RECEIVING = 1, +}; - size_t sentCount = 0; - std::unique_ptr _delayer; +enum class FileControl { RESUME, PAUSE, CANCEL }; -signals: - void started(); - void stopped(); - void connected(); - void disconnect(); - void incoming(const QString dom); +struct FileTxIBB { + QString sid; + int blockSize; +}; - void receivedGroupMessage(lib::messenger::IMMessage imMsg); // - void messageSent(const IMMessage &message); // +struct File { +public: + // id(file id = ibb id) 和 sId(session id) + QString id; + QString sId; + QString name; + QString path; + quint64 size; + FileStatus status; + FileDirection direction; + FileTxIBB txIbb; + [[__nodiscard__]] QString toString() const; + friend QDebug& operator<<(QDebug& debug, const File& f); +}; +class FileHandler { +public: + virtual void onFileRequest(const QString& friendId, const File& file) = 0; + virtual void onFileRecvChunk(const QString& friendId, const QString& fileId, int seq, + const std::string& chunk) = 0; + virtual void onFileRecvFinished(const QString& friendId, const QString& fileId) = 0; + virtual void onFileSendInfo(const QString& friendId, const File& file, int m_seq, + int m_sentBytes, bool end) = 0; + virtual void onFileSendAbort(const QString& friendId, const File& file, int m_sentBytes) = 0; + virtual void onFileSendError(const QString& friendId, const File& file, int m_sentBytes) = 0; +}; -private slots: - void onConnectResult(lib::messenger::IMConnectStatus); - void onStarted(); - void onStopped(); - void onReceiveGroupMessage(lib::messenger::IMMessage imMsg); - void onDisconnect(); - void onEncryptedMessage(QString dom); +class MessengerFile : public QObject{ + Q_OBJECT +public: + MessengerFile(Messenger *messenger, QObject* parent = nullptr); + + void addFileHandler(FileHandler*); + + /** + * File + */ + void fileRejectRequest(QString friendId, const File& file); + void fileAcceptRequest(QString friendId, const File& file); + void fileFinishRequest(QString friendId, const QString& sId); + void fileFinishTransfer(QString friendId, const QString& sId); + void fileCancel(QString fileId); + bool fileSendToFriend(const QString& f, const File& file); + +// /** +// * 启动文件发送任务 +// * @param session +// * @param file +// */ +// void doStartFileSendTask(const Jingle::Session* session, const File& file); +// +// /** +// * 停止文件发送任务 +// * @param session +// * @param file +// */ +// void doStopFileSendTask(const Jingle::Session* session, const File& file); - void onGroupReceived(QString groupId, QString name); +private: + IMFile *fileSender; }; -} // namespace messenger -} // namespace lib - -using Tox = lib::messenger::Messenger; +} // namespace messenger +} // namespace lib diff --git a/src/lib/messenger/tox/toxav.h b/src/lib/messenger/tox/toxav.h index e3f93866..eb2fd976 100644 --- a/src/lib/messenger/tox/toxav.h +++ b/src/lib/messenger/tox/toxav.h @@ -10,18 +10,18 @@ // * See the Mulan PubL v2 for more details. // */ -//#ifndef C_TOXCORE_TOXAV_TOXAV_H -//#define C_TOXCORE_TOXAV_TOXAV_H +// #ifndef C_TOXCORE_TOXAV_TOXAV_H +// #define C_TOXCORE_TOXAV_TOXAV_H -//#include -//#include -//#include +// #include +// #include +// #include ////! TOKSTYLE- -//#ifdef __cplusplus -//extern "C" { -//#endif +// #ifdef __cplusplus +// extern "C" { +// #endif ///** \page av Public audio/video API for Tox clients. // * @@ -72,19 +72,19 @@ // * forcibly terminated without notifying peers. // * // */ -//#ifndef TOXAV_DEFINED -//#define TOXAV_DEFINED +// #ifndef TOXAV_DEFINED +// #define TOXAV_DEFINED -//namespace lib { -//namespace messenger { -//class Messenger; -//class IMCall; -//} // namespace IM -//} // namespace lib +// namespace lib { +// namespace messenger { +// class Messenger; +// class IMCall; +// } // namespace IM +// } // namespace lib -//typedef lib::messenger::Messenger Tox; -//typedef lib::messenger::IMCall ToxAV; -//#endif /* TOXAV_DEFINED */ +// typedef lib::messenger::Messenger Tox; +// typedef lib::messenger::IMCall ToxAV; +// #endif /* TOXAV_DEFINED */ ///******************************************************************************* // * @@ -92,7 +92,7 @@ // * // ******************************************************************************/ -//typedef enum TOXAV_ERR_NEW { +// typedef enum TOXAV_ERR_NEW { // /** // * The function returned successfully. @@ -120,7 +120,7 @@ ///** // * Start new A/V session. There can only be only one session per Tox instance. // */ -//ToxAV *toxav_new(Tox *tox, TOXAV_ERR_NEW *error); +// ToxAV *toxav_new(Tox *tox, TOXAV_ERR_NEW *error); ///** // * Releases all resources associated with the A/V session. @@ -129,12 +129,12 @@ // * notifying peers. After calling this function, no other functions may be // * called and the av pointer becomes invalid. // */ -//void toxav_kill(ToxAV *av); +// void toxav_kill(ToxAV *av); ///** // * Returns the Tox instance the A/V object was created for. // */ -//Tox *toxav_get_tox(const ToxAV *av); +// Tox *toxav_get_tox(const ToxAV *av); ///******************************************************************************* // * @@ -146,14 +146,14 @@ // * Returns the interval in milliseconds when the next toxav_iterate call should // * be. If no call is active at the moment, this function returns 200. // */ -//uint32_t toxav_iteration_interval(const ToxAV *av); +// uint32_t toxav_iteration_interval(const ToxAV *av); ///** // * Main loop for the session. This function needs to be called in intervals of // * toxav_iteration_interval() milliseconds. It is best called in the separate // * thread from tox_iterate. // */ -//void toxav_iterate(ToxAV *av); +// void toxav_iterate(ToxAV *av); ///******************************************************************************* // * @@ -161,7 +161,7 @@ // * // ******************************************************************************/ -//typedef enum TOXAV_ERR_CALL { +// typedef enum TOXAV_ERR_CALL { // /** // * The function returned successfully. @@ -216,7 +216,7 @@ // * @param video_bit_rate Video bit rate in Kb/sec. Set this to 0 to disable // * video sending. // */ -//bool toxav_call(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, +// bool toxav_call(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, // uint32_t video_bit_rate, TOXAV_ERR_CALL *error); ///** @@ -226,7 +226,7 @@ // * @param audio_enabled True if friend is sending audio. // * @param video_enabled True if friend is sending video. // */ -//typedef void toxav_call_cb(ToxAV *av, uint32_t friend_number, +// typedef void toxav_call_cb(ToxAV *av, uint32_t friend_number, // bool audio_enabled, bool video_enabled, // void *user_data); @@ -234,9 +234,9 @@ // * Set the callback for the `call` event. Pass NULL to unset. // * // */ -//void toxav_callback_call(ToxAV *av, toxav_call_cb *callback, void *user_data); +// void toxav_callback_call(ToxAV *av, toxav_call_cb *callback, void *user_data); -//typedef enum TOXAV_ERR_ANSWER { +// typedef enum TOXAV_ERR_ANSWER { // /** // * The function returned successfully. @@ -286,7 +286,7 @@ // * @param video_bit_rate Video bit rate in Kb/sec. Set this to 0 to disable // * video sending. // */ -//bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, +// bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, // uint32_t video_bit_rate, TOXAV_ERR_ANSWER *error); ///******************************************************************************* @@ -295,12 +295,12 @@ // * // ******************************************************************************/ -//enum TOXAV_FRIEND_CALL_STATE { +// enum CallState { // /** // * The empty bit mask. None of the bits specified below are set. // */ -// TOXAV_FRIEND_CALL_STATE_NONE = 0, +// NONE = 0, // /** // * Set by the AV core if an error occurred on the remote end or if friend @@ -308,34 +308,34 @@ // * transitions can occur for the call. This call state will never be triggered // * in combination with other call states. // */ -// TOXAV_FRIEND_CALL_STATE_ERROR = 1, +// ERROR = 1, // /** // * The call has finished. This is the final state after which no more state // * transitions can occur for the call. This call state will never be // * triggered in combination with other call states. // */ -// TOXAV_FRIEND_CALL_STATE_FINISHED = 2, +// FINISHED = 2, // /** // * The flag that marks that friend is sending audio. // */ -// TOXAV_FRIEND_CALL_STATE_SENDING_A = 4, +// SENDING_A = 4, // /** // * The flag that marks that friend is sending video. // */ -// TOXAV_FRIEND_CALL_STATE_SENDING_V = 8, +// SENDING_V = 8, // /** // * The flag that marks that friend is receiving audio. // */ -// TOXAV_FRIEND_CALL_STATE_ACCEPTING_A = 16, +// ACCEPTING_A = 16, // /** // * The flag that marks that friend is receiving video. // */ -// TOXAV_FRIEND_CALL_STATE_ACCEPTING_V = 32, +// ACCEPTING_V = 32, //}; @@ -348,14 +348,14 @@ // * paused. The bitmask represents all the activities currently performed by the // * friend. // */ -//typedef void toxav_call_state_cb(ToxAV *av, uint32_t friend_number, +// typedef void toxav_call_state_cb(ToxAV *av, uint32_t friend_number, // uint32_t state, void *user_data); ///** // * Set the callback for the `call_state` event. Pass NULL to unset. // * // */ -//void toxav_callback_call_state(ToxAV *av, toxav_call_state_cb *callback, +// void toxav_callback_call_state(ToxAV *av, toxav_call_state_cb *callback, // void *user_data); ///******************************************************************************* @@ -364,7 +364,7 @@ // * // ******************************************************************************/ -//typedef enum TOXAV_CALL_CONTROL { +// typedef enum TOXAV_CALL_CONTROL { // /** // * Resume a previously paused call. Only valid if the pause was caused by this @@ -410,7 +410,7 @@ //} TOXAV_CALL_CONTROL; -//typedef enum TOXAV_ERR_CALL_CONTROL { +// typedef enum TOXAV_ERR_CALL_CONTROL { // /** // * The function returned successfully. @@ -450,7 +450,7 @@ // * // * @return true on success. // */ -//bool toxav_call_control(ToxAV *av, uint32_t friend_number, +// bool toxav_call_control(ToxAV *av, uint32_t friend_number, // TOXAV_CALL_CONTROL control, // TOXAV_ERR_CALL_CONTROL *error); @@ -460,7 +460,7 @@ // * // ******************************************************************************/ -//typedef enum TOXAV_ERR_BIT_RATE_SET { +// typedef enum TOXAV_ERR_BIT_RATE_SET { // /** // * The function returned successfully. @@ -495,7 +495,7 @@ // * // ******************************************************************************/ -//typedef enum TOXAV_ERR_SEND_FRAME { +// typedef enum TOXAV_ERR_SEND_FRAME { // /** // * The function returned successfully. @@ -572,14 +572,14 @@ // * bit rate. // * @param audio_bit_rate Suggested maximum audio bit rate in Kb/sec. // */ -//typedef void toxav_audio_bit_rate_cb(ToxAV *av, uint32_t friend_number, +// typedef void toxav_audio_bit_rate_cb(ToxAV *av, uint32_t friend_number, // uint32_t audio_bit_rate, void *user_data); ///** // * Set the callback for the `audio_bit_rate` event. Pass NULL to unset. // * // */ -//void toxav_callback_audio_bit_rate(ToxAV *av, toxav_audio_bit_rate_cb *callback, +// void toxav_callback_audio_bit_rate(ToxAV *av, toxav_audio_bit_rate_cb *callback, // void *user_data); ///** @@ -597,7 +597,7 @@ // * @param u U (Chroma) plane data. // * @param v V (Chroma) plane data. // */ -//bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, +// bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, // uint16_t height, const uint8_t *y, const uint8_t *u, // const uint8_t *v, TOXAV_ERR_SEND_FRAME *error); @@ -610,7 +610,7 @@ // * // * @return true on success. // */ -//bool toxav_video_set_bit_rate(ToxAV *av, uint32_t friend_number, +// bool toxav_video_set_bit_rate(ToxAV *av, uint32_t friend_number, // uint32_t bit_rate, TOXAV_ERR_BIT_RATE_SET *error); ///** @@ -622,14 +622,14 @@ // * bit rate. // * @param video_bit_rate Suggested maximum video bit rate in Kb/sec. // */ -//typedef void toxav_video_bit_rate_cb(ToxAV *av, uint32_t friend_number, +// typedef void toxav_video_bit_rate_cb(ToxAV *av, uint32_t friend_number, // uint32_t video_bit_rate, void *user_data); ///** // * Set the callback for the `video_bit_rate` event. Pass NULL to unset. // * // */ -//void toxav_callback_video_bit_rate(ToxAV *av, toxav_video_bit_rate_cb *callback, +// void toxav_callback_video_bit_rate(ToxAV *av, toxav_video_bit_rate_cb *callback, // void *user_data); ///******************************************************************************* @@ -650,7 +650,7 @@ // * @param sampling_rate Sampling rate used in this frame. // * // */ -//typedef void toxav_audio_receive_frame_cb(ToxAV *av, uint32_t friend_number, +// typedef void toxav_audio_receive_frame_cb(ToxAV *av, uint32_t friend_number, // const int16_t *pcm, // size_t sample_count, uint8_t channels, // uint32_t sampling_rate, @@ -660,7 +660,7 @@ // * Set the callback for the `audio_receive_frame` event. Pass NULL to unset. // * // */ -//void toxav_callback_audio_receive_frame(ToxAV *av, +// void toxav_callback_audio_receive_frame(ToxAV *av, // toxav_audio_receive_frame_cb *callback, // void *user_data); @@ -686,18 +686,17 @@ // * @param ustride U chroma plane stride. // * @param vstride V chroma plane stride. // */ -//typedef void toxav_video_receive_frame_cb(ToxAV *av, uint32_t friend_number, +// typedef void toxav_video_receive_frame_cb(ToxAV *av, uint32_t friend_number, // uint16_t width, uint16_t height, // const uint8_t *y, const uint8_t *u, // const uint8_t *v, int32_t ystride, // int32_t ustride, int32_t vstride, // void *user_data); -//#ifdef __cplusplus -//} -//#endif - +// #ifdef __cplusplus +// } +// #endif ////! TOKSTYLE+ -//#endif // C_TOXCORE_TOXAV_TOXAV_H +// #endif // C_TOXCORE_TOXAV_TOXAV_H diff --git a/src/lib/messenger/tox/toxencryptsave.h b/src/lib/messenger/tox/toxencryptsave.h index 0529e7bf..04c74823 100644 --- a/src/lib/messenger/tox/toxencryptsave.h +++ b/src/lib/messenger/tox/toxencryptsave.h @@ -16,7 +16,7 @@ #ifndef C_TOXCORE_TOXENCRYPTSAVE_TOXENCRYPTSAVE_H #define C_TOXCORE_TOXENCRYPTSAVE_TOXENCRYPTSAVE_H -//!TOKSTYLE- +//! TOKSTYLE- #ifdef __cplusplus extern "C" { @@ -26,7 +26,6 @@ extern "C" { #include #include - /******************************************************************************* * * This module is organized into two parts. @@ -54,19 +53,17 @@ extern "C" { * ******************************************************************************/ - - /** * The size of the salt part of a pass-key. */ -#define TOX_PASS_SALT_LENGTH 32 +#define TOX_PASS_SALT_LENGTH 32 uint32_t tox_pass_salt_length(void); /** * The size of the key part of a pass-key. */ -#define TOX_PASS_KEY_LENGTH 32 +#define TOX_PASS_KEY_LENGTH 32 uint32_t tox_pass_key_length(void); @@ -99,7 +96,6 @@ typedef enum TOX_ERR_KEY_DERIVATION { } TOX_ERR_KEY_DERIVATION; - typedef enum TOX_ERR_ENCRYPTION { /** @@ -126,7 +122,6 @@ typedef enum TOX_ERR_ENCRYPTION { } TOX_ERR_ENCRYPTION; - typedef enum TOX_ERR_DECRYPTION { /** @@ -165,8 +160,6 @@ typedef enum TOX_ERR_DECRYPTION { } TOX_ERR_DECRYPTION; - - /******************************************************************************* * * BEGIN PART 1 @@ -177,8 +170,6 @@ typedef enum TOX_ERR_DECRYPTION { * ******************************************************************************/ - - /** * Encrypts the given data with the given passphrase. * @@ -194,8 +185,8 @@ typedef enum TOX_ERR_DECRYPTION { * * @return true on success. */ -bool tox_pass_encrypt(const uint8_t *plaintext, size_t plaintext_len, const uint8_t *passphrase, size_t passphrase_len, - uint8_t *ciphertext, TOX_ERR_ENCRYPTION *error); +bool tox_pass_encrypt(const uint8_t* plaintext, size_t plaintext_len, const uint8_t* passphrase, + size_t passphrase_len, uint8_t* ciphertext, TOX_ERR_ENCRYPTION* error); /** * Decrypts the given data with the given passphrase. @@ -204,16 +195,16 @@ bool tox_pass_encrypt(const uint8_t *plaintext, size_t plaintext_len, const uint * bytes long. This delegates to tox_pass_key_decrypt. * * @param ciphertext A byte array of length `ciphertext_len`. - * @param ciphertext_len The length of the cipher text array. At least TOX_PASS_ENCRYPTION_EXTRA_LENGTH. + * @param ciphertext_len The length of the cipher text array. At least + * TOX_PASS_ENCRYPTION_EXTRA_LENGTH. * @param passphrase The user-provided password. Can be empty. * @param passphrase_len The length of the password. * @param plaintext The plain text array to write the decrypted data to. * * @return true on success. */ -bool tox_pass_decrypt(const uint8_t *ciphertext, size_t ciphertext_len, const uint8_t *passphrase, - size_t passphrase_len, uint8_t *plaintext, TOX_ERR_DECRYPTION *error); - +bool tox_pass_decrypt(const uint8_t* ciphertext, size_t ciphertext_len, const uint8_t* passphrase, + size_t passphrase_len, uint8_t* plaintext, TOX_ERR_DECRYPTION* error); /******************************************************************************* * @@ -224,8 +215,6 @@ bool tox_pass_decrypt(const uint8_t *ciphertext, size_t ciphertext_len, const ui * ******************************************************************************/ - - /** * This type represents a pass-key. * @@ -235,7 +224,8 @@ bool tox_pass_decrypt(const uint8_t *ciphertext, size_t ciphertext_len, const ui * provided password. * * The Tox_Pass_Key structure is hidden in the implementation. It can be created - * using tox_pass_key_derive or tox_pass_key_derive_with_salt and must be deallocated using tox_pass_key_free. + * using tox_pass_key_derive or tox_pass_key_derive_with_salt and must be deallocated using + * tox_pass_key_free. */ #ifndef TOX_PASS_KEY_DEFINED #define TOX_PASS_KEY_DEFINED @@ -246,7 +236,7 @@ typedef struct Tox_Pass_Key Tox_Pass_Key; * Deallocate a Tox_Pass_Key. This function behaves like free(), so NULL is an * acceptable argument value. */ -void tox_pass_key_free(struct Tox_Pass_Key *_key); +void tox_pass_key_free(struct Tox_Pass_Key* _key); /** * Generates a secret symmetric key from the given passphrase. @@ -263,8 +253,8 @@ void tox_pass_key_free(struct Tox_Pass_Key *_key); * * @return true on success. */ -struct Tox_Pass_Key *tox_pass_key_derive(const uint8_t *passphrase, size_t passphrase_len, - TOX_ERR_KEY_DERIVATION *error); +struct Tox_Pass_Key* tox_pass_key_derive(const uint8_t* passphrase, size_t passphrase_len, + TOX_ERR_KEY_DERIVATION* error); /** * Same as above, except use the given salt for deterministic key derivation. @@ -275,8 +265,9 @@ struct Tox_Pass_Key *tox_pass_key_derive(const uint8_t *passphrase, size_t passp * * @return true on success. */ -struct Tox_Pass_Key *tox_pass_key_derive_with_salt(const uint8_t *passphrase, size_t passphrase_len, - const uint8_t *salt, TOX_ERR_KEY_DERIVATION *error); +struct Tox_Pass_Key* tox_pass_key_derive_with_salt(const uint8_t* passphrase, size_t passphrase_len, + const uint8_t* salt, + TOX_ERR_KEY_DERIVATION* error); /** * Encrypt a plain text with a key produced by tox_pass_key_derive or tox_pass_key_derive_with_salt. @@ -290,21 +281,22 @@ struct Tox_Pass_Key *tox_pass_key_derive_with_salt(const uint8_t *passphrase, si * * @return true on success. */ -bool tox_pass_key_encrypt(const struct Tox_Pass_Key *_key, const uint8_t *plaintext, size_t plaintext_len, - uint8_t *ciphertext, TOX_ERR_ENCRYPTION *error); +bool tox_pass_key_encrypt(const struct Tox_Pass_Key* _key, const uint8_t* plaintext, + size_t plaintext_len, uint8_t* ciphertext, TOX_ERR_ENCRYPTION* error); /** * This is the inverse of tox_pass_key_encrypt, also using only keys produced by * tox_pass_key_derive or tox_pass_key_derive_with_salt. * * @param ciphertext A byte array of length `ciphertext_len`. - * @param ciphertext_len The length of the cipher text array. At least TOX_PASS_ENCRYPTION_EXTRA_LENGTH. + * @param ciphertext_len The length of the cipher text array. At least + * TOX_PASS_ENCRYPTION_EXTRA_LENGTH. * @param plaintext The plain text array to write the decrypted data to. * * @return true on success. */ -bool tox_pass_key_decrypt(const struct Tox_Pass_Key *_key, const uint8_t *ciphertext, size_t ciphertext_len, - uint8_t *plaintext, TOX_ERR_DECRYPTION *error); +bool tox_pass_key_decrypt(const struct Tox_Pass_Key* _key, const uint8_t* ciphertext, + size_t ciphertext_len, uint8_t* plaintext, TOX_ERR_DECRYPTION* error); typedef enum TOX_ERR_GET_SALT { @@ -326,7 +318,6 @@ typedef enum TOX_ERR_GET_SALT { } TOX_ERR_GET_SALT; - /** * Retrieves the salt used to encrypt the given data. * @@ -346,7 +337,7 @@ typedef enum TOX_ERR_GET_SALT { * * @return true on success. */ -bool tox_get_salt(const uint8_t *ciphertext, uint8_t *salt, TOX_ERR_GET_SALT *error); +bool tox_get_salt(const uint8_t* ciphertext, uint8_t* salt, TOX_ERR_GET_SALT* error); /** * Determines whether or not the given data is encrypted by this module. @@ -362,8 +353,7 @@ bool tox_get_salt(const uint8_t *ciphertext, uint8_t *salt, TOX_ERR_GET_SALT *er * * @return true if the data is encrypted by this module. */ -bool tox_is_data_encrypted(const uint8_t *data); - +bool tox_is_data_encrypted(const uint8_t* data); #ifdef __cplusplus } @@ -374,6 +364,6 @@ typedef TOX_ERR_ENCRYPTION Tox_Err_Encryption; typedef TOX_ERR_DECRYPTION Tox_Err_Decryption; typedef TOX_ERR_GET_SALT Tox_Err_Get_Salt; -//!TOKSTYLE+ +//! TOKSTYLE+ -#endif // C_TOXCORE_TOXENCRYPTSAVE_TOXENCRYPTSAVE_H +#endif // C_TOXCORE_TOXENCRYPTSAVE_TOXENCRYPTSAVE_H diff --git a/src/lib/network/ImageLoader.cpp b/src/lib/network/ImageLoader.cpp index 480ef7dc..0588e1fe 100644 --- a/src/lib/network/ImageLoader.cpp +++ b/src/lib/network/ImageLoader.cpp @@ -25,21 +25,19 @@ namespace utils { -ImageLoader::ImageLoader(QObject *parent) : QObject(parent) {} +ImageLoader::ImageLoader(QObject* parent) : QObject(parent) {} ImageLoader::~ImageLoader() {} -void ImageLoader::load(const QString &url, Fn fn) { +void ImageLoader::load(const QString& url, Fn fn) { + QNetworkAccessManager manager; + QEventLoop loop; - QNetworkAccessManager manager; - QEventLoop loop; + QNetworkReply* reply = manager.get(QNetworkRequest(url)); + QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); + loop.exec(); - QNetworkReply *reply = manager.get(QNetworkRequest(url)); - QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); - loop.exec(); - - fn(reply->readAll()); + fn(reply->readAll()); } - -} // namespace utils +} // namespace utils diff --git a/src/lib/network/ImageLoader.h b/src/lib/network/ImageLoader.h index b473c36b..e7c2eec6 100644 --- a/src/lib/network/ImageLoader.h +++ b/src/lib/network/ImageLoader.h @@ -25,15 +25,14 @@ namespace utils { class ImageLoader : public QObject { - - Q_OBJECT + Q_OBJECT public: - ImageLoader(QObject *parent = nullptr); - ~ImageLoader(); + ImageLoader(QObject* parent = nullptr); + ~ImageLoader(); - void load(const QString &url, Fn fn); + void load(const QString& url, Fn fn); private: }; -} // namespace utils +} // namespace utils diff --git a/src/lib/network/NetworkHttp.cpp b/src/lib/network/NetworkHttp.cpp index 779ea859..ca0d9cd7 100644 --- a/src/lib/network/NetworkHttp.cpp +++ b/src/lib/network/NetworkHttp.cpp @@ -28,241 +28,256 @@ #include #include +#include #include "NetworkHttp.h" #include "base/jsons.h" -#include namespace network { -NetworkHttp::NetworkHttp(QObject *parent) : QObject(parent), _manager{nullptr} { - qDebug() << __func__; +static QString CONTENT_TYPE_JSON = "application/json"; + +NetworkHttp::NetworkHttp(QObject* parent) : QObject(parent), _manager{nullptr} { + qDebug() << __func__; #ifndef QT_NO_SSL - QString buildVersion = QSslSocket::sslLibraryBuildVersionString(); - qDebug() << "The build-in ssl library version is:" << buildVersion; - - bool supportsSsl = QSslSocket::supportsSsl(); - qDebug() << "Detected ssl:" << supportsSsl; - if (supportsSsl) { - QString libraryVersion = QSslSocket::sslLibraryVersionString(); - qDebug() << "libraryVersion:" << libraryVersion; - } + QString buildVersion = QSslSocket::sslLibraryBuildVersionString(); + qDebug() << "The build-in ssl library version is:" << buildVersion; + + bool supportsSsl = QSslSocket::supportsSsl(); + qDebug() << "Detected ssl:" << supportsSsl; + if (supportsSsl) { + QString libraryVersion = QSslSocket::sslLibraryVersionString(); + qDebug() << "libraryVersion:" << libraryVersion; + } #endif - // QNetworkAccessManager - _manager = new QNetworkAccessManager(this); - auto schemes = _manager->supportedSchemes(); - qDebug() << "supportedSchemes:" << schemes.join(" "); + // QNetworkAccessManager + _manager = new QNetworkAccessManager(this); + auto schemes = _manager->supportedSchemes(); + qDebug() << "supportedSchemes:" << schemes.join(" "); } NetworkHttp::~NetworkHttp() { qDebug() << __func__; } -inline void forRequest(QNetworkRequest &req){ - req.setAttribute(QNetworkRequest::RedirectPolicyAttribute, true); +inline void NetworkHttp::forRequest(QNetworkRequest& req) { + req.setAttribute(QNetworkRequest::RedirectPolicyAttribute, true); + for(const auto& k: headers.keys()){ + req.setRawHeader(k.toUtf8(), headers[k].toUtf8()); + } } -bool NetworkHttp::get(const QUrl &url, +bool NetworkHttp::get(const QUrl& url, const HttpBodyFn& fn, - const HttpDownloadProgressFn &progress, - const HttpErrorFn &failed) { + const HttpDownloadProgressFn& progress, + const HttpErrorFn& failed) { + qDebug() << "Url:" << url.toString(); + if (url.isEmpty()) { + qWarning() << "url is empty"; + return false; + } + + QNetworkRequest req(url); + forRequest(req); - qDebug() << "Url:" << url.toString(); - if (url.isEmpty()) { - qWarning() << "url is empty"; - return false; - } + auto* reply = _manager->get(req); + doRequest(req, reply, fn, progress, nullptr, failed); + return reply->isOpen(); +} - QNetworkRequest req(url); - forRequest(req); +QByteArray NetworkHttp::get(const QUrl& url, const HttpDownloadProgressFn& downloadProgress) { + qDebug() << "Url:" << url.toString(); + auto _reply = _manager->get(QNetworkRequest(url)); + _reply->ignoreSslErrors(); + if (!_reply->errorString().isEmpty()) { + return {}; + } - auto *reply = _manager->get(req); - doRequest(req, reply, fn, progress, nullptr, failed); - return reply; + if (downloadProgress) { + connect(_reply, &QNetworkReply::downloadProgress, downloadProgress); + } + + QEventLoop loop; + connect(_reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); + loop.exec(); + + QByteArray byteArr = _reply->readAll(); + int size = byteArr.size(); + qDebug() << ("Received bytes:") << (size); + return byteArr; } -QByteArray NetworkHttp::get(const QUrl &url, - const HttpDownloadProgressFn &downloadProgress) { - qDebug() << "Url:" << url.toString(); - auto _reply = _manager->get(QNetworkRequest(url)); - _reply->ignoreSslErrors(); - if (!_reply->errorString().isEmpty()) { - return {}; - } - - if (downloadProgress) { - connect(_reply, &QNetworkReply::downloadProgress, downloadProgress); - } - - QEventLoop loop; - connect(_reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); - loop.exec(); - - QByteArray byteArr = _reply->readAll(); - int size = byteArr.size(); - qDebug() << ("Received bytes:") << (size); - return byteArr; +bool NetworkHttp::getJson(const QUrl& url, Fn fn, const HttpErrorFn& err) { + return get( + url, + [=](QByteArray buf, QString fileName) { + Q_UNUSED(fileName) + fn(Jsons::toJSON(buf)); + }, + nullptr, err); } -bool NetworkHttp::getJSON(const QUrl &url, - Fn fn, - const HttpErrorFn& errFn) { - return get(url,[=](QByteArray buf, QString fileName) { - Q_UNUSED(fileName) - fn(Jsons::toJSON(buf)); - }, - nullptr, errFn); +/** + * 发送Post请求Json数据 + * @brief NetworkHttp::postJson + * @param url + * @param data + * @param fn + * @param progress + * @param upload + * @param failed + * @return + */ +bool NetworkHttp::postJson(const QUrl& url, + const QJsonDocument& data, + const HttpBodyFn& fn, + const HttpDownloadProgressFn& progress, + const HttpUploadProgressFn& upload, + const HttpErrorFn& failed) { + return post(url, data.toJson(), CONTENT_TYPE_JSON, fn, progress, upload, failed); } -void NetworkHttp::postJSON(const QUrl &url, - const QJsonObject &data, - Fn fn, - const HttpDownloadProgressFn &progress, - const HttpUploadProgressFn& upload, - const HttpErrorFn &failed) { - post(url, - QJsonDocument(data).toJson() , - "application/json", - [&](QByteArray buf, QString name) { - fn(Jsons::toJSON(buf)); - }, - progress, upload, failed); +bool NetworkHttp::postJson1(const QUrl &url, const QJsonDocument &data, const HttpJsonBodyFn &fn, const HttpDownloadProgressFn &progress, const HttpUploadProgressFn &upload, const HttpErrorFn &failed) +{ + return post(url, data.toJson(), CONTENT_TYPE_JSON, [&](QByteArray body, QString name){ + auto doc=QJsonDocument::fromJson(body); + fn(doc, name); + }, progress, upload, failed); } -void NetworkHttp::post(const QUrl &url, - const QByteArray &data, +bool NetworkHttp::post(const QUrl& url, + const QByteArray& data, const QString& contentType, - const HttpBodyFn &fn, - const HttpDownloadProgressFn &progress, + const HttpBodyFn& fn, + const HttpDownloadProgressFn& progress, const HttpUploadProgressFn& upload, - const HttpErrorFn &failed) { - qDebug() << __func__ << url.toString(); - - QNetworkRequest req(url); - forRequest(req); - req.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(contentType)); + const HttpErrorFn& failed) { + qDebug() << __func__ << url.toString(); - auto _reply = _manager->post(req, data); - doRequest(req, _reply, fn, progress, upload, failed); -} + QNetworkRequest req(url); + forRequest(req); + req.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(contentType)); -void NetworkHttp::PostFormData(const QUrl &url, - const QByteArray &byteArray, - const QString &contentType, - const QString &filename, - const HttpUploadProgressFn &uploadProgress, - Fn readyRead) { - - if (url.isEmpty()) { - qWarning() << "url is empty!"; - return; - } - - if (byteArray.size() <= 0) { - qWarning() << "byteArray is empty!"; - return; - } - // 添加认证信息 - auto *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); - - /* type */ - QUrlQuery uQuery(url.query()); - // uQuery.addQueryItem("type", (UploadFileFolders[(int)folder])); - const_cast(url).setQuery(uQuery); - - // file - QHttpPart imagePart; - imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(contentType)); - imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"file\"; filename=\"" + filename + "\"")); - - imagePart.setBody(byteArray); - multiPart->append(imagePart); - - QNetworkRequest req(url); - forRequest(req); - - QList cookies = _manager->cookieJar()->cookiesForUrl(url); - // cookies.append(QNetworkCookie(QString("ticket").toUtf8(), - // client->token().toUtf8())); - QVariant var; - var.setValue(cookies); - - req.setHeader(QNetworkRequest::CookieHeader, var); - QNetworkReply *reply = _manager->post(req, multiPart); - multiPart->setParent(reply); - - if (uploadProgress) { - connect(reply, &QNetworkReply::uploadProgress, uploadProgress); - } + auto _reply = _manager->post(req, data); + doRequest(req, _reply, fn, progress, upload, failed); + return _reply->isOpen(); } -void NetworkHttp::doRequest(QNetworkRequest &req, - QNetworkReply *reply, - const HttpBodyFn &fn, - const HttpDownloadProgressFn &progress, - const HttpUploadProgressFn& upload, - const HttpErrorFn &failed) { - - qDebug() << __func__; - - if (!reply) { - return; - } - reply->ignoreSslErrors(); - - connect(reply, &QNetworkReply::finished, [=]() { - // 获取HTTP状态码 - QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute); - if (statusCode.isValid()) { - qDebug() << "statusCode:" << statusCode.toInt(); +void NetworkHttp::PostFormData(const QUrl& url, + const QByteArray& byteArray, + const QString& contentType, + const QString& filename, + const HttpUploadProgressFn& uploadProgress, + Fn + readyRead) { + if (url.isEmpty()) { + qWarning() << "url is empty!"; + return; } - if (statusCode.toInt() / 100 != 2) { - qWarning() << "Error:" << reply->errorString(); - if (failed) { - failed(statusCode.toInt(), reply->errorString()); - } - return; + if (byteArray.size() <= 0) { + qWarning() << "byteArray is empty!"; + return; } - - auto bytes = reply->readAll(); - auto size = bytes.size(); - qDebug() << "Received bytes:" << size; - - if (size <= 0) { - qWarning() << "No content!"; - return; + // 添加认证信息 + auto* multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); + + /* type */ + QUrlQuery uQuery(url.query()); + // uQuery.addQueryItem("type", (UploadFileFolders[(int)folder])); + const_cast(url).setQuery(uQuery); + + // file + QHttpPart imagePart; + imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(contentType)); + imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, + QVariant("form-data; name=\"file\"; filename=\"" + filename + "\"")); + + imagePart.setBody(byteArray); + multiPart->append(imagePart); + + QNetworkRequest req(url); + forRequest(req); + + QList cookies = _manager->cookieJar()->cookiesForUrl(url); + // cookies.append(QNetworkCookie(QString("ticket").toUtf8(), + // client->token().toUtf8())); + QVariant var; + var.setValue(cookies); + + req.setHeader(QNetworkRequest::CookieHeader, var); + QNetworkReply* reply = _manager->post(req, multiPart); + multiPart->setParent(reply); + + if (uploadProgress) { + connect(reply, &QNetworkReply::uploadProgress, uploadProgress); } +} - if (!fn) { - qWarning() << "Not put callback for content!"; - return; +void NetworkHttp::doRequest(QNetworkRequest& req, + QNetworkReply* reply, + const HttpBodyFn& fn, + const HttpDownloadProgressFn& progress, + const HttpUploadProgressFn& upload, + const HttpErrorFn& failed) { + if (!reply) { + return; } - - auto cth = reply->header(QNetworkRequest::KnownHeaders::ContentTypeHeader); - if (cth.isValid()) { - auto type = cth.toString(); - qDebug() << "content-type:" << type; - if (type.startsWith("text/", Qt::CaseInsensitive) || type.startsWith("application/json", Qt::CaseInsensitive)) { - qDebug() << qstring("body:%1").arg(QString::fromUtf8(bytes)); - } + reply->ignoreSslErrors(); + + connect(reply, &QNetworkReply::finished, [=]() { + // 获取HTTP状态码 + QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute); + if (statusCode.isValid()) { + qDebug() << "statusCode:" << statusCode.toInt(); + } + + if (statusCode.toInt() / 100 != 2) { + qWarning() << "Error:" << reply->errorString(); + if (failed) { + failed(statusCode.toInt(), reply->errorString()); + } + return; + } + + auto bytes = reply->readAll(); + auto size = bytes.size(); + qDebug() << "Received bytes:" << size; + + if (size <= 0) { + qWarning() << "No content!"; + return; + } + + if (!fn) { + qWarning() << "Not put callback for content!"; + return; + } + + auto cth = reply->header(QNetworkRequest::KnownHeaders::ContentTypeHeader); + if (cth.isValid()) { + auto type = cth.toString(); + qDebug() << "content-type:" << type; + if (type.startsWith("text/", Qt::CaseInsensitive) || + type.startsWith(CONTENT_TYPE_JSON, Qt::CaseInsensitive)) + qDebug() << "body:" << (QString::fromUtf8(bytes)); + } + + auto cdh = reply->header(QNetworkRequest::KnownHeaders::ContentDispositionHeader); + if (!cdh.isNull()) { + QString filename = cdh.toString().split("=").last().trimmed(); + fn(bytes, filename); + } else { + fn(bytes, req.url().fileName()); + } + // delete reply + // reply->deleteLater(); + }); + + if (progress) { + connect(reply, &QNetworkReply::downloadProgress, progress); } - auto cdh = reply->header(QNetworkRequest::KnownHeaders::ContentDispositionHeader); - if (!cdh.isNull()) { - QString filename = cdh.toString().split("=").last().trimmed(); - fn(bytes, filename); - } else { - fn(bytes, req.url().fileName()); + if (upload) { + connect(reply, &QNetworkReply::uploadProgress, upload); } - // delete reply - reply->deleteLater(); - }); - - if (progress) { - connect(reply, &QNetworkReply::downloadProgress, progress); - } - - if(upload){ - connect(reply, &QNetworkReply::uploadProgress, upload); - } } /**上传表单数据 @@ -271,26 +286,27 @@ void NetworkHttp::doRequest(QNetworkRequest &req, * @param file * @param fn */ -void NetworkHttp::PostFormData(const QUrl &url, QFile *file, - const HttpUploadProgressFn &uploadProgress, - Fn readyRead) { - if (url.isEmpty()) { - qWarning() << "url is empty!"; - return; - } - - if (!file) { - qWarning() << "file is nullptr!"; - return; - } - - QString contentType = ok::base::Files::GetContentTypeStr(file->fileName()); - file->open(QIODevice::ReadOnly); - - QByteArray byteArray = file->readAll(); - PostFormData(url, byteArray, ok::base::Files::GetContentTypeStr(file->fileName()), file->fileName(), uploadProgress, readyRead); +void NetworkHttp::PostFormData(const QUrl& url, QFile* file, + const HttpUploadProgressFn& uploadProgress, + Fn readyRead) { + if (url.isEmpty()) { + qWarning() << "url is empty!"; + return; + } + + if (!file) { + qWarning() << "file is nullptr!"; + return; + } + + QString contentType = ok::base::Files::GetContentTypeStr(file->fileName()); + file->open(QIODevice::ReadOnly); + + QByteArray byteArray = file->readAll(); + PostFormData(url, byteArray, ok::base::Files::GetContentTypeStr(file->fileName()), + file->fileName(), uploadProgress, readyRead); } void NetworkHttp::httpFinished() { qDebug() << "finished."; } -} // namespace network +} // namespace network diff --git a/src/lib/network/NetworkHttp.h b/src/lib/network/NetworkHttp.h index 0089e182..3097da3f 100644 --- a/src/lib/network/NetworkHttp.h +++ b/src/lib/network/NetworkHttp.h @@ -30,65 +30,81 @@ class QNetworkReply; namespace network { -using HttpErrorFn = Fn; +using HttpErrorFn = Fn; using HttpDownloadProgressFn = Fn; using HttpUploadProgressFn = Fn; using HttpBodyFn = Fn; +using HttpJsonBodyFn = Fn; class NetworkHttp : public QObject { - Q_OBJECT + Q_OBJECT public: - explicit NetworkHttp(QObject *parent = nullptr); - ~NetworkHttp() override; - - void httpFinished(); - - bool get(const QUrl &url, - const HttpBodyFn &fn, - const HttpDownloadProgressFn &progress = nullptr, - const HttpErrorFn &failed = nullptr); - - QByteArray get(const QUrl &url, - const HttpDownloadProgressFn &downloadProgress = nullptr); - - bool getJSON(const QUrl &url, - Fn fn = nullptr, - const HttpErrorFn& err = nullptr); - - void post(const QUrl &url, - const QByteArray &data, - const QString& contentType, - const HttpBodyFn &fn = nullptr, - const HttpDownloadProgressFn &progress= nullptr, - const HttpUploadProgressFn& upload= nullptr, - const HttpErrorFn &failed= nullptr); - - void postJSON(const QUrl &url, - const QJsonObject &data, - Fn fn, - const HttpDownloadProgressFn &progress= nullptr, - const HttpUploadProgressFn& upload= nullptr, - const HttpErrorFn &failed= nullptr); - - void PostFormData(const QUrl &url, QFile *file, - const HttpUploadProgressFn &uploadProgress, - Fn readyRead); - - virtual void PostFormData(const QUrl &url, - const QByteArray &byteArray, - const QString &contentType, - const QString &filename, - const HttpUploadProgressFn &uploadProgress, - Fn readyRead); - - void doRequest(QNetworkRequest &req, QNetworkReply *reply, - const HttpBodyFn &fn = nullptr, - const HttpDownloadProgressFn & = nullptr, - const HttpUploadProgressFn& = nullptr, - const HttpErrorFn & = nullptr); + explicit NetworkHttp(QObject* parent = nullptr); + ~NetworkHttp() override; + + void setHeader(QString k, QString v){ + headers.insert(k, v); + }; + + void setHeaders(const QMap map){ + headers.insert(map); + } + + void httpFinished(); + + bool get(const QUrl& url, + const HttpBodyFn& fn, + const HttpDownloadProgressFn& progress = nullptr, + const HttpErrorFn& failed = nullptr); + + QByteArray get(const QUrl& url, const HttpDownloadProgressFn& downloadProgress = nullptr); + + bool getJson(const QUrl& url, + Fn fn = nullptr, + const HttpErrorFn& err = nullptr); + + bool post(const QUrl& url, + const QByteArray& data, + const QString& contentType, + const HttpBodyFn& fn = nullptr, + const HttpDownloadProgressFn& progress = nullptr, + const HttpUploadProgressFn& upload = nullptr, + const HttpErrorFn& failed = nullptr); + + bool postJson(const QUrl& url, + const QJsonDocument& data, + const HttpBodyFn& fn = nullptr, + const HttpDownloadProgressFn& progress = nullptr, + const HttpUploadProgressFn& upload = nullptr, + const HttpErrorFn& failed = nullptr); + + bool postJson1(const QUrl& url, + const QJsonDocument& data, + const HttpJsonBodyFn& fn = nullptr, + const HttpDownloadProgressFn& progress = nullptr, + const HttpUploadProgressFn& upload = nullptr, + const HttpErrorFn& failed = nullptr); + + void PostFormData(const QUrl& url, QFile* file, const HttpUploadProgressFn& uploadProgress, + Fn readyRead); + + virtual void PostFormData(const QUrl& url, + const QByteArray& byteArray, + const QString& contentType, + const QString& filename, + const HttpUploadProgressFn& uploadProgress, + Fn + readyRead); + + void doRequest(QNetworkRequest& req, QNetworkReply* reply, const HttpBodyFn& fn = nullptr, + const HttpDownloadProgressFn& = nullptr, const HttpUploadProgressFn& = nullptr, + const HttpErrorFn& = nullptr); + + void forRequest(QNetworkRequest &req); protected: - QNetworkAccessManager *_manager; + QNetworkAccessManager* _manager; + QMap headers; }; -} // namespace network +} // namespace network diff --git a/src/lib/network/network.h b/src/lib/network/network.h index 6e85fbb1..1ffe1323 100644 --- a/src/lib/network/network.h +++ b/src/lib/network/network.h @@ -15,9 +15,6 @@ #include -namespace network { +namespace network {} -} - - -#endif // NETWORK_H \ No newline at end of file +#endif // NETWORK_H \ No newline at end of file diff --git a/src/lib/ortc/ok_rtc.h b/src/lib/ortc/ok_rtc.h index 3e27631e..bc7ca766 100644 --- a/src/lib/ortc/ok_rtc.h +++ b/src/lib/ortc/ok_rtc.h @@ -12,10 +12,10 @@ #pragma once -#include -#include #include #include +#include +#include #include "ok_rtc_defs.h" #include "ok_rtc_renderer.h" @@ -24,109 +24,109 @@ namespace lib { namespace ortc { struct RendererImage { - size_t width_; - size_t height_; - uint8_t *y; // - uint8_t *u; // - uint8_t *v; // - int32_t ystride; // - int32_t ustride; // - int32_t vstride; // + size_t width_; + size_t height_; + uint8_t* y; // + uint8_t* u; // + uint8_t* v; // + int32_t ystride; // + int32_t ustride; // + int32_t vstride; // }; struct IceServer { - std::string uri; - std::string username; - std::string password; - - std::string toString() const { - std::stringstream ss; - ss <<"{uri:" << uri << "," - " username:"<< username<< ", " - " password:"<< password <<"}"; - return ss.str();; - } + std::string uri; + std::string username; + std::string password; + + std::string toString() const { + std::stringstream ss; + ss << "{uri:" << uri + << "," + " username:" + << username + << ", " + " password:" + << password << "}"; + return ss.str(); + ; + } }; typedef struct join_options { - std::string conference; - std::string conference_id; - std::string peer_name; - long peer_id; + std::string conference; + std::string conference_id; + std::string peer_name; + long peer_id; } JoinOptions; class OkRTCHandler { public: - virtual void onCreatePeerConnection( - const std::string &sId , - const std::string &peerId, - bool ok) = 0; + virtual void onCreatePeerConnection(const std::string& sId, + const std::string& peerId, + bool ok) = 0; - virtual void onRTP(const std::string &sId, - const std::string &peerId, - const OJingleContentAv &osd) = 0; - - virtual void onIce(const std::string &sId, - const std::string &peerId, - const OIceUdp &iceUdp) = 0; - - virtual void onRender(const std::string &friendId, RendererImage image) = 0; + virtual void onRTP(const std::string& sId, + const std::string& peerId, + const OJingleContentAv& osd) = 0; + virtual void onIce(const std::string& sId, + const std::string& peerId, + const OIceUdp& iceUdp) = 0; + virtual void onRender(const std::string& friendId, RendererImage image) = 0; }; /** * RTC 接口 */ class OkRTC { - public: - virtual ~OkRTC() = default; - - //启动rtc实例 - virtual bool start() = 0; - //停止rtc实例 - virtual bool stop() = 0; - - virtual bool isStarted() = 0; - - virtual bool ensureStart() = 0; - - virtual void setIceOptions(std::list& ices) = 0; - - - virtual void addRTCHandler( OkRTCHandler* hand) = 0; + virtual ~OkRTC() = default; + // 启动rtc实例 + virtual bool start() = 0; + // 停止rtc实例 + virtual bool stop() = 0; - virtual void CreateOffer(const std::string &peerId) = 0; + virtual bool isStarted() = 0; - virtual void CreateAnswer(const std::string &peerId, const OJingleContentAv &pContent) = 0; + virtual bool ensureStart() = 0; - virtual void setRemoteDescription(const std::string &peerId, const OJingleContentAv &jingleContext) = 0; + virtual void setIceOptions(std::list& ices) = 0; - virtual void ContentAdd(std::map sdMap, OkRTCHandler *handler) = 0; + virtual void addRTCHandler(OkRTCHandler* hand) = 0; - virtual void ContentRemove(std::map sdMap, OkRTCHandler *handler) = 0; + virtual void CreateOffer(const std::string& peerId) = 0; - virtual void SessionTerminate(const std::string &peerId) = 0; + virtual void CreateAnswer(const std::string& peerId, const OJingleContentAv& pContent) = 0; - virtual void setTransportInfo(const std::string &peerId, const std::string &sId, const OIceUdp &oIceUdp) = 0; + virtual void setRemoteDescription(const std::string& peerId, + const OJingleContentAv& jingleContext) = 0; - virtual void setMute(bool mute) = 0; + virtual void ContentAdd(std::map sdMap, + OkRTCHandler* handler) = 0; - virtual void setRemoteMute(bool mute) = 0; + virtual void ContentRemove(std::map sdMap, + OkRTCHandler* handler) = 0; + virtual void SessionTerminate(const std::string& peerId) = 0; - virtual bool call(const std::string &peerId, const std::string &sId, bool video) = 0; + virtual void setTransportInfo(const std::string& peerId, + const std::string& sId, + const OIceUdp& oIceUdp) = 0; - virtual bool quit(const std::string &peerId) = 0; + virtual void setMute(bool mute) = 0; + virtual void setRemoteMute(bool mute) = 0; - // 获取视频设备数量 - virtual size_t getVideoSize() = 0; + virtual bool call(const std::string& peerId, const std::string& sId, bool video) = 0; + virtual bool quit(const std::string& peerId) = 0; + // 获取视频设备数量 + virtual size_t getVideoSize() = 0; }; -} // namespace ortc -} // namespace lib +} // namespace ortc +} // namespace lib diff --git a/src/lib/ortc/ok_rtc_defs.cpp b/src/lib/ortc/ok_rtc_defs.cpp index 4bac1723..313c4984 100644 --- a/src/lib/ortc/ok_rtc_defs.cpp +++ b/src/lib/ortc/ok_rtc_defs.cpp @@ -15,149 +15,145 @@ namespace lib { namespace ortc { -void OJingleContent::toPlugins(PluginList &plugins) const { +void OJingleContent::toPlugins(PluginList& plugins) const { }; -void OJingleContent::parse(const Session::Jingle *jingle) { - sessionId = jingle->sid(); - sessionVersion = SESSION_VERSION; +void OJingleContent::parse(const Session::Jingle* jingle) { + sessionId = jingle->sid(); + sessionVersion = SESSION_VERSION; } -void OJingleContentFile::toPlugins(PluginList &plugins) const {} - -void OJingleContentFile::parse(const Jingle::Session::Jingle *jingle) { - - OJingleContent::parse(jingle); - callType = JingleCallType::file; - - for (const auto p : jingle->plugins()) { - Jingle::JinglePluginType pt = p->pluginType(); - switch (pt) { - case JinglePluginType::PluginContent: { - - OContent oContent; - const auto *content = static_cast(p); - oContent.name = content->name(); - - const auto *file = content->findPlugin(PluginFileTransfer); - if (file) { - OFile oFile = {file->files()}; - const auto *ibb = content->findPlugin(PluginIBB); - if (ibb) { - oFile.ibb = *ibb; +void OJingleContentFile::toPlugins(PluginList& plugins) const {} + +void OJingleContentFile::parse(const Jingle::Session::Jingle* jingle) { + OJingleContent::parse(jingle); + callType = JingleCallType::file; + + for (const auto p : jingle->plugins()) { + Jingle::JinglePluginType pt = p->pluginType(); + switch (pt) { + case JinglePluginType::PluginContent: { + OContent oContent; + const auto* content = static_cast(p); + oContent.name = content->name(); + + const auto* file = content->findPlugin(PluginFileTransfer); + if (file) { + OFile oFile = {file->files()}; + const auto* ibb = content->findPlugin(PluginIBB); + if (ibb) { + oFile.ibb = *ibb; + } + oContent.file = oFile; + } + contents.emplace_back(oContent); + break; + } + default: + break; } - oContent.file = oFile; - } - contents.emplace_back(oContent); - break; - } - default: - break; } - } } -void OJingleContentAv::toPlugins(PluginList &plugins) const { - // - Jingle::Group::ContentList contentList; - for (auto &content : contents) { - auto name = content.name; - auto desc = content.rtp; +void OJingleContentAv::toPlugins(PluginList& plugins) const { + // + Jingle::Group::ContentList contentList; + for (auto& content : contents) { + auto name = content.name; + auto desc = content.rtp; - contentList.push_back(Jingle::Group::Content{name}); + contentList.push_back(Jingle::Group::Content{name}); - // description - Jingle::PluginList rtpPlugins; + // description + Jingle::PluginList rtpPlugins; - // rtcp - auto rtp = new Jingle::RTP(desc.media, desc.payloadTypes); - rtp->setRtcpMux(desc.rtcpMux); + // rtcp + auto rtp = new Jingle::RTP(desc.media, desc.payloadTypes); + rtp->setRtcpMux(desc.rtcpMux); - // payload-type - rtp->setPayloadTypes(desc.payloadTypes); + // payload-type + rtp->setPayloadTypes(desc.payloadTypes); - // rtp-hdrExt - rtp->setHdrExts(desc.hdrExts); + // rtp-hdrExt + rtp->setHdrExts(desc.hdrExts); - // source - if (!desc.sources.empty()) { - rtp->setSources(desc.sources); - } + // source + if (!desc.sources.empty()) { + rtp->setSources(desc.sources); + } - // ssrc-group - if (!desc.ssrcGroup.ssrcs.empty()) { - rtp->setSsrcGroup(desc.ssrcGroup); - } + // ssrc-group + if (!desc.ssrcGroup.ssrcs.empty()) { + rtp->setSsrcGroup(desc.ssrcGroup); + } - // rtp - rtpPlugins.emplace_back(rtp); + // rtp + rtpPlugins.emplace_back(rtp); - // transport - OIceUdp oIceUdp = content.iceUdp; - auto ice = new Jingle::ICEUDP(oIceUdp.pwd, oIceUdp.ufrag, oIceUdp.candidates); - ice->setDtls(oIceUdp.dtls); - rtpPlugins.emplace_back(ice); + // transport + OIceUdp oIceUdp = content.iceUdp; + auto ice = new Jingle::ICEUDP(oIceUdp.pwd, oIceUdp.ufrag, oIceUdp.candidates); + ice->setDtls(oIceUdp.dtls); + rtpPlugins.emplace_back(ice); - auto *pContent = new Jingle::Content(name, rtpPlugins, Jingle::Content::CInitiator); - plugins.emplace_back(pContent); - } + auto* pContent = new Jingle::Content(name, rtpPlugins, Jingle::Content::CInitiator); + plugins.emplace_back(pContent); + } - auto group = new Jingle::Group("BUNDLE", contentList); - plugins.push_back(group); + auto group = new Jingle::Group("BUNDLE", contentList); + plugins.push_back(group); } -void OJingleContentAv::parse(const Jingle::Session::Jingle *jingle) { - OJingleContent::parse(jingle); - callType = JingleCallType::av; - - int mid = 0; - for (const auto p : jingle->plugins()) { - Jingle::JinglePluginType pt = p->pluginType(); - switch (pt) { - case JinglePluginType::PluginContent: { - - OSdp oContent; - - const auto *content = static_cast(p); - oContent.name = content->name(); - - const auto *rtp = content->findPlugin(PluginRTP); - if (rtp) { - ORTP description = { - rtp->media(), // - rtp->payloadTypes(), // - rtp->hdrExts(), // - rtp->sources(), // - rtp->ssrcGroup(), // - rtp->rtcpMux() // - }; - oContent.rtp = description; - } - - const auto *udp = content->findPlugin(PluginICEUDP); - if (udp) { - OIceUdp iceUdp = { - std::to_string(mid), // - mid, // - udp->ufrag(), // - udp->pwd(), // - udp->dtls(), // - udp->candidates() // - }; - oContent.iceUdp = iceUdp; - } - - contents.emplace_back(oContent); - break; - } - default: - break; +void OJingleContentAv::parse(const Jingle::Session::Jingle* jingle) { + OJingleContent::parse(jingle); + callType = JingleCallType::av; + + int mid = 0; + for (const auto p : jingle->plugins()) { + Jingle::JinglePluginType pt = p->pluginType(); + switch (pt) { + case JinglePluginType::PluginContent: { + OSdp oContent; + + const auto* content = static_cast(p); + oContent.name = content->name(); + + const auto* rtp = content->findPlugin(PluginRTP); + if (rtp) { + ORTP description = { + rtp->media(), // + rtp->payloadTypes(), // + rtp->hdrExts(), // + rtp->sources(), // + rtp->ssrcGroup(), // + rtp->rtcpMux() // + }; + oContent.rtp = description; + } + + const auto* udp = content->findPlugin(PluginICEUDP); + if (udp) { + OIceUdp iceUdp = { + std::to_string(mid), // + mid, // + udp->ufrag(), // + udp->pwd(), // + udp->dtls(), // + udp->candidates() // + }; + oContent.iceUdp = iceUdp; + } + + contents.emplace_back(oContent); + break; + } + default: + break; + } + mid++; } - mid++; - } } - -} // namespace ortc -} // namespace lib +} // namespace ortc +} // namespace lib diff --git a/src/lib/ortc/ok_rtc_defs.h b/src/lib/ortc/ok_rtc_defs.h index 8002835f..69c6253d 100644 --- a/src/lib/ortc/ok_rtc_defs.h +++ b/src/lib/ortc/ok_rtc_defs.h @@ -34,98 +34,90 @@ using namespace gloox; using namespace gloox::Jingle; struct OIceUdp { - std::string mid; - int mline; - std::string ufrag; - std::string pwd; - ICEUDP::Dtls dtls; - ICEUDP::CandidateList candidates; + std::string mid; + int mline; + std::string ufrag; + std::string pwd; + ICEUDP::Dtls dtls; + ICEUDP::CandidateList candidates; }; struct ORTP { - Media media; - RTP::PayloadTypes payloadTypes; - RTP::HdrExts hdrExts; - RTP::Sources sources; - RTP::SsrcGroup ssrcGroup; - bool rtcpMux; + Media media; + RTP::PayloadTypes payloadTypes; + RTP::HdrExts hdrExts; + RTP::Sources sources; + RTP::SsrcGroup ssrcGroup; + bool rtcpMux; }; struct OFile { - Jingle::FileTransfer::FileList files; - Jingle::IBB ibb; + Jingle::FileTransfer::FileList files; + Jingle::IBB ibb; }; struct OContent { - std::string name; - OFile file; + std::string name; + OFile file; }; struct OSdp { - std::string name; - ORTP rtp; - OIceUdp iceUdp; + std::string name; + ORTP rtp; + OIceUdp iceUdp; }; enum class JingleSdpType { - Offer, - Answer, - Rollback, + Offer, + Answer, + Rollback, }; // 呼叫类型 enum class JingleCallType { - none, // none - file, // file - av, // audio & video + none, // none + file, // file + av, // audio & video }; struct OJingleContent { public: + [[nodiscard]] inline JingleCallType getCallType() const { return callType; } - [[nodiscard]] inline JingleCallType getCallType() const { - return callType; - } + [[nodiscard]] inline JingleSdpType getSdpType() { return sdpType; } - [[nodiscard]] inline JingleSdpType getSdpType(){ - return sdpType; - } + JingleSdpType sdpType; - JingleSdpType sdpType; + std::string sessionId; + std::string sessionVersion; - std::string sessionId; - std::string sessionVersion; - - JingleCallType callType; - - virtual void toPlugins(PluginList& plugins) const; - virtual void parse(const Jingle::Session::Jingle *jingle); + JingleCallType callType; + virtual void toPlugins(PluginList& plugins) const; + virtual void parse(const Jingle::Session::Jingle* jingle); }; - struct OJingleContentFile : public OJingleContent { void toPlugins(PluginList& plugins) const override; - void parse(const Jingle::Session::Jingle *jingle) override; + void parse(const Jingle::Session::Jingle* jingle) override; std::vector contents; }; struct OJingleContentAv : public OJingleContent { public: void toPlugins(PluginList& plugins) const override; - void parse(const Jingle::Session::Jingle *jingle) override; + void parse(const Jingle::Session::Jingle* jingle) override; std::vector contents; inline bool isVideo() const { - for(auto s : contents){ - if(s.rtp.media == Jingle::Media::video){ - return true; - } + for (auto s : contents) { + if (s.rtp.media == Jingle::Media::video) { + return true; + } } return false; } - }; -} // namespace ortc -} // namespace lib +} // namespace ortc +} // namespace lib diff --git a/src/lib/ortc/ok_rtc_manager.cpp b/src/lib/ortc/ok_rtc_manager.cpp index ae2ee453..bf00607c 100644 --- a/src/lib/ortc/ok_rtc_manager.cpp +++ b/src/lib/ortc/ok_rtc_manager.cpp @@ -14,7 +14,6 @@ #include - #include "ok_rtc.h" #include "ok_rtc_defs.h" #include "ok_rtc_renderer.h" @@ -23,90 +22,66 @@ namespace lib { namespace ortc { -static OkRTCManager *instance = nullptr; +static OkRTCManager* instance = nullptr; static std::mutex mtx; -OkRTCManager::OkRTCManager() -{ - -} +OkRTCManager::OkRTCManager() {} -OkRTCManager::~OkRTCManager() { - rtc.reset(); -} +OkRTCManager::~OkRTCManager() { rtc.reset(); } -OkRTCManager *OkRTCManager::getInstance() -{ - std::lock_guard lock(mtx); - if(!instance){ - RTC_DLOG_F(LS_INFO) << "Creating instance."; - instance = new OkRTCManager(); - } - return instance; +OkRTCManager* OkRTCManager::getInstance() { + std::lock_guard lock(mtx); + if (!instance) { + RTC_DLOG_F(LS_INFO) << "Creating instance."; + instance = new OkRTCManager(); + } + return instance; } -void OkRTCManager::destroyInstance() -{ +void OkRTCManager::destroyInstance() { std::lock_guard lock(mtx); - if(!instance) - { + if (!instance) { RTC_DLOG_F(LS_WARNING) << "The instance has been destroyed!"; return; } - RTC_DLOG_F(LS_INFO) << "instance:"<(); rtc->setIceOptions(_iceOptions); } return rtc.get(); } -void OkRTCManager::destroyRtc() -{ - rtc.reset(); -} +void OkRTCManager::destroyRtc() { rtc.reset(); } +void OkRTCManager::addIceServer(const IceServer& ice) { _iceOptions.push_back(ice); } -void OkRTCManager::addIceServer(const IceServer &ice) -{ - _iceOptions.push_back(ice); -} - -void OkRTCManager::CreateOffer(const std::string &peerId) { - rtc->CreateOffer(peerId); -} +void OkRTCManager::CreateOffer(const std::string& peerId) { rtc->CreateOffer(peerId); } -void OkRTCManager::ContentAdd( - std::map &sdMap, - ortc::OkRTCHandler *handler) { - rtc->ContentAdd(sdMap, handler); +void OkRTCManager::ContentAdd(std::map& sdMap, + ortc::OkRTCHandler* handler) { + rtc->ContentAdd(sdMap, handler); } -void OkRTCManager::ContentRemove( - std::map &sdMap, - ortc::OkRTCHandler *handler) { - rtc->ContentRemove(sdMap, handler); +void OkRTCManager::ContentRemove(std::map& sdMap, + ortc::OkRTCHandler* handler) { + rtc->ContentRemove(sdMap, handler); } -void OkRTCManager::SessionTerminate(const std::string &sid) { - rtc->SessionTerminate(sid); -} +void OkRTCManager::SessionTerminate(const std::string& sid) { rtc->SessionTerminate(sid); } void OkRTCManager::setMute(bool mute) { rtc->setMute(mute); } -void OkRTCManager::setRemoteMute(bool mute) { } - +void OkRTCManager::setRemoteMute(bool mute) {} size_t OkRTCManager::getVideoSize() { return rtc->getVideoSize(); } - -} // namespace ortc -} // namespace lib +} // namespace ortc +} // namespace lib diff --git a/src/lib/ortc/ok_rtc_manager.h b/src/lib/ortc/ok_rtc_manager.h index 8d49194e..f2b66d5a 100644 --- a/src/lib/ortc/ok_rtc_manager.h +++ b/src/lib/ortc/ok_rtc_manager.h @@ -22,45 +22,40 @@ namespace lib { namespace ortc { class OkRTCManager { - public: + static OkRTCManager* getInstance(); + static void destroyInstance(); - static OkRTCManager* getInstance(); - static void destroyInstance(); - - ~OkRTCManager(); + ~OkRTCManager(); - OkRTC* getRtc(); - void destroyRtc(); + OkRTC* getRtc(); + void destroyRtc(); - void addIceServer(const IceServer &ice); + void addIceServer(const IceServer& ice); - size_t getVideoSize(); + size_t getVideoSize(); - void CreateOffer(const std::string &peerId); + void CreateOffer(const std::string& peerId); - void CreateOffer(const std::string &peerId, - const lib::ortc::OJingleContent &pContent); + void CreateOffer(const std::string& peerId, const lib::ortc::OJingleContent& pContent); - void ContentAdd(std::map &sdMap, - ortc::OkRTCHandler *handler); + void ContentAdd(std::map& sdMap, + ortc::OkRTCHandler* handler); - void ContentRemove(std::map &sdMap, - ortc::OkRTCHandler *handler); + void ContentRemove(std::map& sdMap, + ortc::OkRTCHandler* handler); - void SessionTerminate(const std::string &peerId); - - void setMute(bool mute); - void setRemoteMute(bool mute); + void SessionTerminate(const std::string& peerId); + void setMute(bool mute); + void setRemoteMute(bool mute); private: - OkRTCManager(); - - std::list _iceOptions; - std::unique_ptr rtc; + OkRTCManager(); + std::list _iceOptions; + std::unique_ptr rtc; }; -} // namespace ortc -} // namespace lib +} // namespace ortc +} // namespace lib diff --git a/src/lib/ortc/ok_rtc_renderer.h b/src/lib/ortc/ok_rtc_renderer.h index bb2ce31e..dade7d16 100644 --- a/src/lib/ortc/ok_rtc_renderer.h +++ b/src/lib/ortc/ok_rtc_renderer.h @@ -16,11 +16,5 @@ #include namespace lib { -namespace ortc { - - - - - -} // namespace ortc -} // namespace lib +namespace ortc {} // namespace ortc +} // namespace lib diff --git a/src/lib/ortc/webrtc/Instance.h b/src/lib/ortc/webrtc/Instance.h index 19173b32..4f0d9cfa 100644 --- a/src/lib/ortc/webrtc/Instance.h +++ b/src/lib/ortc/webrtc/Instance.h @@ -12,13 +12,13 @@ namespace rtc { template class VideoSinkInterface; template class scoped_refptr; -} // namespace rtc +} // namespace rtc namespace webrtc { class VideoFrame; class AudioDeviceModule; class TaskQueueFactory; -} // namespace webrtc +} // namespace webrtc namespace lib::ortc { @@ -26,84 +26,98 @@ class VideoCaptureInterface; struct FilePath { #ifndef _WIN32 - std::string data; + std::string data; #else - std::wstring data; + std::wstring data; #endif }; struct Proxy { - std::string host; - uint16_t port = 0; - std::string login; - std::string password; + std::string host; + uint16_t port = 0; + std::string login; + std::string password; }; struct RtcServer { - uint8_t id = 0; - std::string host; - uint16_t port = 0; - std::string login; - std::string password; - bool isTurn = false; - bool isTcp = false; + uint8_t id = 0; + std::string host; + uint16_t port = 0; + std::string login; + std::string password; + bool isTurn = false; + bool isTcp = false; }; enum class EndpointType { Inet, Lan, UdpRelay, TcpRelay }; struct EndpointHost { - std::string ipv4; - std::string ipv6; + std::string ipv4; + std::string ipv6; }; struct Endpoint { - int64_t endpointId = 0; - EndpointHost host; - uint16_t port = 0; - EndpointType type = EndpointType{}; - unsigned char peerTag[16] = {0}; + int64_t endpointId = 0; + EndpointHost host; + uint16_t port = 0; + EndpointType type = EndpointType{}; + unsigned char peerTag[16] = {0}; }; enum class ProtocolVersion { - V0, - V1 // Low-cost network negotiation + V0, + V1 // Low-cost network negotiation }; -enum class NetworkType { Unknown, Gprs, Edge, ThirdGeneration, Hspa, Lte, WiFi, Ethernet, OtherHighSpeed, OtherLowSpeed, OtherMobile, Dialup }; +enum class NetworkType { + Unknown, + Gprs, + Edge, + ThirdGeneration, + Hspa, + Lte, + WiFi, + Ethernet, + OtherHighSpeed, + OtherLowSpeed, + OtherMobile, + Dialup +}; enum class DataSaving { Never, Mobile, Always }; struct PersistentState { - std::vector value; + std::vector value; }; struct Config { - double initializationTimeout = 0.; - double receiveTimeout = 0.; - DataSaving dataSaving = DataSaving::Never; - bool enableP2P = false; - bool allowTCP = false; - bool enableStunMarking = false; - bool enableAEC = false; - bool enableNS = false; - bool enableAGC = false; - bool enableCallUpgrade = false; - bool enableVolumeControl = false; - FilePath logPath; - FilePath statsLogPath; - int maxApiLayer = 0; - bool enableHighBitrateVideo = false; - std::vector preferredVideoCodecs; - ProtocolVersion protocolVersion = ProtocolVersion::V0; + double initializationTimeout = 0.; + double receiveTimeout = 0.; + DataSaving dataSaving = DataSaving::Never; + bool enableP2P = false; + bool allowTCP = false; + bool enableStunMarking = false; + bool enableAEC = false; + bool enableNS = false; + bool enableAGC = false; + bool enableCallUpgrade = false; + bool enableVolumeControl = false; + FilePath logPath; + FilePath statsLogPath; + int maxApiLayer = 0; + bool enableHighBitrateVideo = false; + std::vector preferredVideoCodecs; + ProtocolVersion protocolVersion = ProtocolVersion::V0; }; struct EncryptionKey { - static constexpr int kSize = 256; + static constexpr int kSize = 256; - std::shared_ptr> value; - bool isOutgoing = false; + std::shared_ptr> value; + bool isOutgoing = false; - EncryptionKey(std::shared_ptr> value, bool isOutgoing) : value(std::move(value)), isOutgoing(isOutgoing) {} + EncryptionKey(std::shared_ptr> value, bool isOutgoing) + : value(std::move(value)), isOutgoing(isOutgoing) {} }; enum class State { WaitInit, WaitInitAck, Established, Failed, Reconnecting }; @@ -112,125 +126,129 @@ enum class State { WaitInit, WaitInitAck, Established, Failed, Reconnecting }; enum class VideoState; enum class AudioState { - Muted, - Active, + Muted, + Active, }; struct TrafficStats { - uint64_t bytesSentWifi = 0; - uint64_t bytesReceivedWifi = 0; - uint64_t bytesSentMobile = 0; - uint64_t bytesReceivedMobile = 0; + uint64_t bytesSentWifi = 0; + uint64_t bytesReceivedWifi = 0; + uint64_t bytesSentMobile = 0; + uint64_t bytesReceivedMobile = 0; }; struct FinalState { - PersistentState persistentState; - std::string debugLog; - TrafficStats trafficStats; - CallStats callStats; - bool isRatingSuggested = false; + PersistentState persistentState; + std::string debugLog; + TrafficStats trafficStats; + CallStats callStats; + bool isRatingSuggested = false; }; struct MediaDevicesConfig { - std::string audioInputId; - std::string audioOutputId; - float inputVolume = 1.f; - float outputVolume = 1.f; + std::string audioInputId; + std::string audioOutputId; + float inputVolume = 1.f; + float outputVolume = 1.f; }; class Instance { protected: - Instance() = default; + Instance() = default; public: - virtual ~Instance() = default; + virtual ~Instance() = default; - virtual void setNetworkType(NetworkType networkType) = 0; - virtual void setMuteMicrophone(bool muteMicrophone) = 0; - virtual void setAudioOutputGainControlEnabled(bool enabled) = 0; - virtual void setEchoCancellationStrength(int strength) = 0; + virtual void setNetworkType(NetworkType networkType) = 0; + virtual void setMuteMicrophone(bool muteMicrophone) = 0; + virtual void setAudioOutputGainControlEnabled(bool enabled) = 0; + virtual void setEchoCancellationStrength(int strength) = 0; - virtual bool supportsVideo() = 0; - virtual void setIncomingVideoOutput(std::weak_ptr> sink) = 0; + virtual bool supportsVideo() = 0; + virtual void setIncomingVideoOutput( + std::weak_ptr> sink) = 0; - virtual void setAudioInputDevice(std::string id) = 0; - virtual void setAudioOutputDevice(std::string id) = 0; - virtual void setInputVolume(float level) = 0; - virtual void setOutputVolume(float level) = 0; - virtual void setAudioOutputDuckingEnabled(bool enabled) = 0; - virtual void addExternalAudioSamples(std::vector &&samples) {} + virtual void setAudioInputDevice(std::string id) = 0; + virtual void setAudioOutputDevice(std::string id) = 0; + virtual void setInputVolume(float level) = 0; + virtual void setOutputVolume(float level) = 0; + virtual void setAudioOutputDuckingEnabled(bool enabled) = 0; + virtual void addExternalAudioSamples(std::vector&& samples) {} - virtual void setIsLowBatteryLevel(bool isLowBatteryLevel) = 0; + virtual void setIsLowBatteryLevel(bool isLowBatteryLevel) = 0; - virtual std::string getLastError() = 0; - virtual std::string getDebugInfo() = 0; - virtual int64_t getPreferredRelayId() = 0; - virtual TrafficStats getTrafficStats() = 0; - virtual PersistentState getPersistentState() = 0; + virtual std::string getLastError() = 0; + virtual std::string getDebugInfo() = 0; + virtual int64_t getPreferredRelayId() = 0; + virtual TrafficStats getTrafficStats() = 0; + virtual PersistentState getPersistentState() = 0; - virtual void receiveSignalingData(const std::vector &data) = 0; - virtual void setVideoCapture(std::shared_ptr videoCapture) = 0; - virtual void sendVideoDeviceUpdated() = 0; - virtual void setRequestedVideoAspect(float aspect) = 0; + virtual void receiveSignalingData(const std::vector& data) = 0; + virtual void setVideoCapture(std::shared_ptr videoCapture) = 0; + virtual void sendVideoDeviceUpdated() = 0; + virtual void setRequestedVideoAspect(float aspect) = 0; - virtual void stop(std::function completion) = 0; + virtual void stop(std::function completion) = 0; }; template bool Register(); struct Descriptor { - std::string version; - Config config; - PersistentState persistentState; - std::vector endpoints; - std::unique_ptr proxy; - std::vector rtcServers; - NetworkType initialNetworkType = NetworkType(); - EncryptionKey encryptionKey; - MediaDevicesConfig mediaDevicesConfig; - std::shared_ptr videoCapture; - std::function stateUpdated; - std::function signalBarsUpdated; - std::function audioLevelUpdated; - std::function remoteBatteryLevelIsLowUpdated; - std::function remoteMediaStateUpdated; - std::function remotePrefferedAspectRatioUpdated; - std::function &)> signalingDataEmitted; - std::function(webrtc::TaskQueueFactory *)> createAudioDeviceModule; + std::string version; + Config config; + PersistentState persistentState; + std::vector endpoints; + std::unique_ptr proxy; + std::vector rtcServers; + NetworkType initialNetworkType = NetworkType(); + EncryptionKey encryptionKey; + MediaDevicesConfig mediaDevicesConfig; + std::shared_ptr videoCapture; + std::function stateUpdated; + std::function signalBarsUpdated; + std::function audioLevelUpdated; + std::function remoteBatteryLevelIsLowUpdated; + std::function remoteMediaStateUpdated; + std::function remotePrefferedAspectRatioUpdated; + std::function&)> signalingDataEmitted; + std::function(webrtc::TaskQueueFactory*)> + createAudioDeviceModule; }; class Meta { public: - virtual ~Meta() = default; + virtual ~Meta() = default; - virtual std::unique_ptr construct(Descriptor &&descriptor) = 0; - virtual int connectionMaxLayer() = 0; - virtual std::vector versions() = 0; + virtual std::unique_ptr construct(Descriptor&& descriptor) = 0; + virtual int connectionMaxLayer() = 0; + virtual std::vector versions() = 0; - static std::unique_ptr Create(const std::string &version, Descriptor &&descriptor); - static std::vector Versions(); - static int MaxLayer(); + static std::unique_ptr Create(const std::string& version, Descriptor&& descriptor); + static std::vector Versions(); + static int MaxLayer(); private: - template friend bool Register(); + template friend bool Register(); - template static bool RegisterOne(); - static void RegisterOne(std::shared_ptr meta); + template static bool RegisterOne(); + static void RegisterOne(std::shared_ptr meta); }; template bool Meta::RegisterOne() { - class MetaImpl final : public Meta { - public: - int connectionMaxLayer() override { return Implementation::GetConnectionMaxLayer(); } - std::vector versions() override { return Implementation::GetVersions(); } - std::unique_ptr construct(Descriptor &&descriptor) override { return std::make_unique(std::move(descriptor)); } - }; - RegisterOne(std::make_shared()); - return true; + class MetaImpl final : public Meta { + public: + int connectionMaxLayer() override { return Implementation::GetConnectionMaxLayer(); } + std::vector versions() override { return Implementation::GetVersions(); } + std::unique_ptr construct(Descriptor&& descriptor) override { + return std::make_unique(std::move(descriptor)); + } + }; + RegisterOne(std::make_shared()); + return true; } -void SetLoggingFunction(std::function loggingFunction); +void SetLoggingFunction(std::function loggingFunction); -} // namespace lib::ortc +} // namespace lib::ortc #endif diff --git a/src/lib/ortc/webrtc/LogSinkImpl.cpp b/src/lib/ortc/webrtc/LogSinkImpl.cpp index 3ab7a977..6d099d3a 100644 --- a/src/lib/ortc/webrtc/LogSinkImpl.cpp +++ b/src/lib/ortc/webrtc/LogSinkImpl.cpp @@ -1,67 +1,62 @@ #include "LogSinkImpl.h" #include #ifdef WEBRTC_WIN -#include "windows.h" #include -#else // WEBRTC_WIN -#include +#include "windows.h" +#else // WEBRTC_WIN #include -#endif // WEBRTC_WIN +#include +#endif // WEBRTC_WIN namespace lib::ortc { -LogSinkImpl::LogSinkImpl( ) { - -} +LogSinkImpl::LogSinkImpl() {} -void LogSinkImpl::OnLogMessage(const std::string &msg, rtc::LoggingSeverity severity, const char *tag) { - OnLogMessage(std::string(tag) + ": " + msg); +void LogSinkImpl::OnLogMessage(const std::string& msg, rtc::LoggingSeverity severity, + const char* tag) { + OnLogMessage(std::string(tag) + ": " + msg); } -void LogSinkImpl::OnLogMessage(const std::string &message, rtc::LoggingSeverity severity) { - OnLogMessage(message); +void LogSinkImpl::OnLogMessage(const std::string& message, rtc::LoggingSeverity severity) { + OnLogMessage(message); } -void LogSinkImpl::OnLogMessage(const std::string &message) { - time_t rawTime; - time(&rawTime); - struct tm timeinfo; +void LogSinkImpl::OnLogMessage(const std::string& message) { + time_t rawTime; + time(&rawTime); + struct tm timeinfo; #ifdef WEBRTC_WIN - localtime_s(&timeinfo, &rawTime); + localtime_s(&timeinfo, &rawTime); - FILETIME ft; - unsigned __int64 full = 0; - GetSystemTimeAsFileTime(&ft); + FILETIME ft; + unsigned __int64 full = 0; + GetSystemTimeAsFileTime(&ft); - full |= ft.dwHighDateTime; - full <<= 32; - full |= ft.dwLowDateTime; + full |= ft.dwHighDateTime; + full <<= 32; + full |= ft.dwLowDateTime; - const auto deltaEpochInMicrosecs = 11644473600000000Ui64; - full -= deltaEpochInMicrosecs; - full /= 10; - int32_t milliseconds = (long)(full % 1000000UL) / 1000; + const auto deltaEpochInMicrosecs = 11644473600000000Ui64; + full -= deltaEpochInMicrosecs; + full /= 10; + int32_t milliseconds = (long)(full % 1000000UL) / 1000; #else - timeval curTime = { 0 }; - localtime_r(&rawTime, &timeinfo); - gettimeofday(&curTime, nullptr); - int32_t milliseconds = curTime.tv_usec / 1000; + timeval curTime = {0}; + localtime_r(&rawTime, &timeinfo); + gettimeofday(&curTime, nullptr); + int32_t milliseconds = curTime.tv_usec / 1000; #endif - std::cout - << (timeinfo.tm_year + 1900) - << "-" << (timeinfo.tm_mon + 1) - << "-" << (timeinfo.tm_mday) - << " " << timeinfo.tm_hour - << ":" << timeinfo.tm_min - << ":" << timeinfo.tm_sec - << ":" << milliseconds - << " " << message << std::endl; + std::cout << (timeinfo.tm_year + 1900) << "-" << (timeinfo.tm_mon + 1) << "-" + << (timeinfo.tm_mday) << " " << timeinfo.tm_hour << ":" << timeinfo.tm_min << ":" + << timeinfo.tm_sec << ":" << milliseconds << " " << message << std::endl; #if DEBUG - printf("%d-%d-%d %d:%d:%d:%d %s\n", timeinfo.tm_year + 1900, timeinfo.tm_mon + 1, timeinfo.tm_mday, timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec, milliseconds, message.c_str()); + printf("%d-%d-%d %d:%d:%d:%d %s\n", timeinfo.tm_year + 1900, timeinfo.tm_mon + 1, + timeinfo.tm_mday, timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec, milliseconds, + message.c_str()); #endif } -} // namespace lib::ortc +} // namespace lib::ortc diff --git a/src/lib/ortc/webrtc/LogSinkImpl.h b/src/lib/ortc/webrtc/LogSinkImpl.h index 1ae62640..b24f0daa 100644 --- a/src/lib/ortc/webrtc/LogSinkImpl.h +++ b/src/lib/ortc/webrtc/LogSinkImpl.h @@ -1,31 +1,27 @@ #ifndef TGCALLS_LOG_SINK_IMPL_H #define TGCALLS_LOG_SINK_IMPL_H -#include "rtc_base/logging.h" #include +#include "rtc_base/logging.h" namespace lib::ortc { - - class LogSinkImpl final : public rtc::LogSink { public: - LogSinkImpl( ); + LogSinkImpl(); - void OnLogMessage(const std::string &msg, rtc::LoggingSeverity severity, const char *tag) override; - void OnLogMessage(const std::string &message, rtc::LoggingSeverity severity) override; - void OnLogMessage(const std::string &message) override; + void OnLogMessage(const std::string& msg, rtc::LoggingSeverity severity, + const char* tag) override; + void OnLogMessage(const std::string& message, rtc::LoggingSeverity severity) override; + void OnLogMessage(const std::string& message) override; - std::string result() const { - return _data.str(); - } + std::string result() const { return _data.str(); } private: - std::ofstream _file; - std::ostringstream _data; - + std::ofstream _file; + std::ostringstream _data; }; -} // namespace lib::ortc +} // namespace lib::ortc #endif diff --git a/src/lib/ortc/webrtc/StaticThreads.cpp b/src/lib/ortc/webrtc/StaticThreads.cpp index 3fa949f9..f172e063 100644 --- a/src/lib/ortc/webrtc/StaticThreads.cpp +++ b/src/lib/ortc/webrtc/StaticThreads.cpp @@ -1,151 +1,130 @@ #include "StaticThreads.h" -#include "rtc_base/thread.h" #include "call/call.h" +#include "rtc_base/thread.h" -#include #include +#include namespace lib::ortc { template class Pool : public std::enable_shared_from_this> { - struct Entry { - std::unique_ptr value; - size_t refcnt; + struct Entry { + std::unique_ptr value; + size_t refcnt; - bool operator < (const Entry &other) const { - return refcnt < other.refcnt; - } - }; + bool operator<(const Entry& other) const { return refcnt < other.refcnt; } + }; public: - explicit Pool(CreatorT creator) : creator_(std::move(creator)) { - } - std::shared_ptr get() { - std::unique_lock lock(mutex_); - set_pool_size_locked(1); - auto i = std::min_element(entries_.begin(), entries_.end()) - entries_.begin(); - return std::shared_ptr(entries_[i].value.get(), - [i, self = this->shared_from_this()](auto *ptr) { - self->dec_ref(i); - }); - } - - void set_pool_size(size_t size) { - std::unique_lock lock(mutex_); - set_pool_size_locked(size); - } - - void dec_ref(size_t i) { - std::unique_lock lock(mutex_); - entries_.at(i).refcnt--; - } + explicit Pool(CreatorT creator) : creator_(std::move(creator)) {} + std::shared_ptr get() { + std::unique_lock lock(mutex_); + set_pool_size_locked(1); + auto i = std::min_element(entries_.begin(), entries_.end()) - entries_.begin(); + return std::shared_ptr( + entries_[i].value.get(), + [i, self = this->shared_from_this()](auto* ptr) { self->dec_ref(i); }); + } + + void set_pool_size(size_t size) { + std::unique_lock lock(mutex_); + set_pool_size_locked(size); + } + + void dec_ref(size_t i) { + std::unique_lock lock(mutex_); + entries_.at(i).refcnt--; + } private: - std::mutex mutex_; - std::vector entries_; + std::mutex mutex_; + std::vector entries_; - CreatorT creator_; + CreatorT creator_; - void set_pool_size_locked(size_t size) { - for (size_t i = entries_.size(); i < size; i++) { - entries_.emplace_back(Entry{creator_(i + 1), 0}); + void set_pool_size_locked(size_t size) { + for (size_t i = entries_.size(); i < size; i++) { + entries_.emplace_back(Entry{creator_(i + 1), 0}); + } } - } }; class ThreadsImpl : public Threads { - using Thread = std::unique_ptr; + using Thread = std::unique_ptr; + public: - explicit ThreadsImpl(size_t i) { - auto suffix = i == 0 ? "" : "#" + std::to_string(i); - media_ = create("ortc-media" + suffix); - worker_ = create("ortc-work" + suffix); - network_ = create_network("ortc-net" + suffix); -// worker_ = create_network("ortc-work" + suffix); - //network_->DisallowAllInvokes(); - //worker_->DisallowAllInvokes(); - //worker_->AllowInvokesToThread(network_.get()); - } - - rtc::Thread *getNetworkThread() override { - return network_.get(); - } - rtc::Thread *getMediaThread() override { - return media_.get(); - } - rtc::Thread *getWorkerThread() override { - return worker_.get(); - } -// rtc::scoped_refptr getSharedModuleThread() override { - // This function must be called from a single thread because of SharedModuleThread implementation - // So we don't care about making it thread safe -// if (!shared_module_thread_) { -// shared_module_thread_ = webrtc::SharedModuleThread::Create( -// webrtc::ProcessThread::Create("tgc-module"), -// [=] { shared_module_thread_ = nullptr; }); -// } -// return shared_module_thread_; -// } + explicit ThreadsImpl(size_t i) { + auto suffix = i == 0 ? "" : "#" + std::to_string(i); + media_ = create("ortc-media" + suffix); + worker_ = create("ortc-work" + suffix); + network_ = create_network("ortc-net" + suffix); + // worker_ = create_network("ortc-work" + suffix); + // network_->DisallowAllInvokes(); + // worker_->DisallowAllInvokes(); + // worker_->AllowInvokesToThread(network_.get()); + } + + rtc::Thread* getNetworkThread() override { return network_.get(); } + rtc::Thread* getMediaThread() override { return media_.get(); } + rtc::Thread* getWorkerThread() override { return worker_.get(); } + // rtc::scoped_refptr getSharedModuleThread() override { + // This function must be called from a single thread because of SharedModuleThread + // implementation So we don't care about making it thread safe + // if (!shared_module_thread_) { + // shared_module_thread_ = webrtc::SharedModuleThread::Create( + // webrtc::ProcessThread::Create("tgc-module"), + // [=] { shared_module_thread_ = nullptr; }); + // } + // return shared_module_thread_; + // } private: - Thread network_; - Thread media_; - Thread worker_; -// rtc::scoped_refptr shared_module_thread_; - - static Thread create(const std::string &name) { - return init(std::unique_ptr(rtc::Thread::Create()), name); - } - static Thread create_network(const std::string &name) { - return init(std::unique_ptr(rtc::Thread::CreateWithSocketServer()), name); - } - - static Thread init(Thread value, const std::string &name) { - value->SetName(name, nullptr); - value->Start(); - return value; - } + Thread network_; + Thread media_; + Thread worker_; + // rtc::scoped_refptr shared_module_thread_; + + static Thread create(const std::string& name) { + return init(std::unique_ptr(rtc::Thread::Create()), name); + } + static Thread create_network(const std::string& name) { + return init(std::unique_ptr(rtc::Thread::CreateWithSocketServer()), name); + } + + static Thread init(Thread value, const std::string& name) { + value->SetName(name, nullptr); + value->Start(); + return value; + } }; class ThreadsCreator { public: - std::unique_ptr operator()(size_t i) { - return std::make_unique(i); - } + std::unique_ptr operator()(size_t i) { return std::make_unique(i); } }; -Pool &get_pool() { - static auto pool = std::make_shared>(ThreadsCreator()); - return *pool; +Pool& get_pool() { + static auto pool = std::make_shared>(ThreadsCreator()); + return *pool; } -void Threads::setPoolSize(size_t size){ - get_pool().set_pool_size(size); -} -std::shared_ptr Threads::getThreads(){ - return get_pool().get(); -} +void Threads::setPoolSize(size_t size) { get_pool().set_pool_size(size); } +std::shared_ptr Threads::getThreads() { return get_pool().get(); } namespace StaticThreads { -rtc::Thread *getNetworkThread() { - return getThreads()->getNetworkThread(); -} +rtc::Thread* getNetworkThread() { return getThreads()->getNetworkThread(); } -rtc::Thread *getMediaThread() { - return getThreads()->getMediaThread(); -} +rtc::Thread* getMediaThread() { return getThreads()->getMediaThread(); } -rtc::Thread *getWorkerThread() { - return getThreads()->getWorkerThread(); -} +rtc::Thread* getWorkerThread() { return getThreads()->getWorkerThread(); } -std::shared_ptr &getThreads() { - static std::shared_ptr threads = std::make_shared(0); - return threads; +std::shared_ptr& getThreads() { + static std::shared_ptr threads = std::make_shared(0); + return threads; } -}; +}; // namespace StaticThreads -} +} // namespace lib::ortc diff --git a/src/lib/ortc/webrtc/StaticThreads.h b/src/lib/ortc/webrtc/StaticThreads.h index 78d26e18..f8a81ba2 100644 --- a/src/lib/ortc/webrtc/StaticThreads.h +++ b/src/lib/ortc/webrtc/StaticThreads.h @@ -5,34 +5,33 @@ namespace rtc { class Thread; -template -class scoped_refptr; -} -//namespace webrtc { -//class SharedModuleThread; -//} +template class scoped_refptr; +} // namespace rtc +// namespace webrtc { +// class SharedModuleThread; +// } namespace lib::ortc { class Threads { public: - virtual ~Threads() = default; - virtual rtc::Thread *getNetworkThread() = 0; - virtual rtc::Thread *getMediaThread() = 0; - virtual rtc::Thread *getWorkerThread() = 0; -// virtual rtc::scoped_refptr getSharedModuleThread() = 0; + virtual ~Threads() = default; + virtual rtc::Thread* getNetworkThread() = 0; + virtual rtc::Thread* getMediaThread() = 0; + virtual rtc::Thread* getWorkerThread() = 0; + // virtual rtc::scoped_refptr getSharedModuleThread() = 0; - // it is not possible to decrease pool size - static void setPoolSize(size_t size); - static std::shared_ptr getThreads(); + // it is not possible to decrease pool size + static void setPoolSize(size_t size); + static std::shared_ptr getThreads(); }; namespace StaticThreads { -rtc::Thread *getNetworkThread(); -rtc::Thread *getMediaThread(); -rtc::Thread *getWorkerThread(); -//rtc::scoped_refptr getSharedMoudleThread(); -std::shared_ptr &getThreads(); -} +rtc::Thread* getNetworkThread(); +rtc::Thread* getMediaThread(); +rtc::Thread* getWorkerThread(); +// rtc::scoped_refptr getSharedMoudleThread(); +std::shared_ptr& getThreads(); +} // namespace StaticThreads -}; +}; // namespace lib::ortc diff --git a/src/lib/ortc/webrtc/Stats.h b/src/lib/ortc/webrtc/Stats.h index 4b624fe2..73ecdde4 100644 --- a/src/lib/ortc/webrtc/Stats.h +++ b/src/lib/ortc/webrtc/Stats.h @@ -14,8 +14,8 @@ enum class CallStatsConnectionEndpointType { struct CallStatsNetworkRecord { int32_t timestamp = 0; - CallStatsConnectionEndpointType endpointType - = CallStatsConnectionEndpointType::ConnectionEndpointP2P; + CallStatsConnectionEndpointType endpointType = + CallStatsConnectionEndpointType::ConnectionEndpointP2P; bool isLowCost = false; }; @@ -30,6 +30,6 @@ struct CallStats { std::vector bitrateRecords; }; -} // namespace lib::ortc +} // namespace lib::ortc #endif diff --git a/src/lib/ortc/webrtc/VideoCaptureInterface.cpp b/src/lib/ortc/webrtc/VideoCaptureInterface.cpp index af996881..5fc23472 100644 --- a/src/lib/ortc/webrtc/VideoCaptureInterface.cpp +++ b/src/lib/ortc/webrtc/VideoCaptureInterface.cpp @@ -5,14 +5,12 @@ namespace lib::ortc { std::unique_ptr VideoCaptureInterface::Create( - rtc::Thread *signalingThread, rtc::Thread *workerThread, - std::string deviceId, - bool isScreenCapture, - std::shared_ptr platformContext) -{ - return std::make_unique( signalingThread, workerThread, deviceId, isScreenCapture, platformContext); + rtc::Thread* signalingThread, rtc::Thread* workerThread, std::string deviceId, + bool isScreenCapture, std::shared_ptr platformContext) { + return std::make_unique(signalingThread, workerThread, deviceId, + isScreenCapture, platformContext); } VideoCaptureInterface::~VideoCaptureInterface() = default; -} // namespace lib::ortc +} // namespace lib::ortc diff --git a/src/lib/ortc/webrtc/VideoCaptureInterface.h b/src/lib/ortc/webrtc/VideoCaptureInterface.h index bdefd750..9ff1d752 100644 --- a/src/lib/ortc/webrtc/VideoCaptureInterface.h +++ b/src/lib/ortc/webrtc/VideoCaptureInterface.h @@ -2,19 +2,18 @@ #define ORTC_VIDEO_CAPTURE_INTERFACE_H #include +#include #include #include -#include #include namespace rtc { -template -class VideoSinkInterface; -} // namespace rtc +template class VideoSinkInterface; +} // namespace rtc namespace webrtc { class VideoFrame; -} // namespace webrtc +} // namespace webrtc namespace lib::ortc { @@ -22,46 +21,44 @@ class PlatformContext; class Threads; enum class VideoState { - Inactive, - Paused, - Active, + Inactive, + Paused, + Active, }; - class VideoCaptureInterface { protected: - VideoCaptureInterface() = default; + VideoCaptureInterface() = default; public: - static std::unique_ptr Create( - rtc::Thread *signalingThread, rtc::Thread *workerThread, - std::string deviceId = std::string(), - bool isScreenCapture = false, - std::shared_ptr platformContext = nullptr); + static std::unique_ptr Create( + rtc::Thread* signalingThread, rtc::Thread* workerThread, + std::string deviceId = std::string(), bool isScreenCapture = false, + std::shared_ptr platformContext = nullptr); - virtual ~VideoCaptureInterface(); + virtual ~VideoCaptureInterface(); virtual rtc::scoped_refptr source() = 0; virtual void switchToDevice(std::string deviceId, bool isScreenCapture) = 0; - virtual void setState(VideoState state) = 0; + virtual void setState(VideoState state) = 0; virtual void setPreferredAspectRatio(float aspectRatio) = 0; - virtual void setOutput(std::shared_ptr> sink) = 0; + virtual void setOutput(std::shared_ptr> sink) = 0; virtual void setOnFatalError(std::function error) { - // TODO: make this function pure virtual when everybody implements it. + // TODO: make this function pure virtual when everybody implements it. } virtual void setOnPause(std::function pause) { - // TODO: make this function pure virtual when everybody implements it. + // TODO: make this function pure virtual when everybody implements it. } virtual void setOnIsActiveUpdated(std::function onIsActiveUpdated) { - // TODO: make this function pure virtual when everybody implements it. + // TODO: make this function pure virtual when everybody implements it. } - virtual void withNativeImplementation(std::function completion) { + virtual void withNativeImplementation(std::function completion) { completion(nullptr); } }; -} // namespace lib::ortc +} // namespace lib::ortc #endif diff --git a/src/lib/ortc/webrtc/VideoCaptureInterfaceImpl.cpp b/src/lib/ortc/webrtc/VideoCaptureInterfaceImpl.cpp index e8f15f55..ac538b5e 100644 --- a/src/lib/ortc/webrtc/VideoCaptureInterfaceImpl.cpp +++ b/src/lib/ortc/webrtc/VideoCaptureInterfaceImpl.cpp @@ -1,26 +1,31 @@ #include "VideoCaptureInterfaceImpl.h" +#include "StaticThreads.h" #include "VideoCapturerInterface.h" #include "platform/PlatformInterface.h" -#include "StaticThreads.h" namespace lib::ortc { -VideoCaptureInterfaceObject::VideoCaptureInterfaceObject(rtc::Thread *signalingThread, rtc::Thread *workerThread, std::string deviceId, bool isScreenCapture, std::shared_ptr platformContext) -: _videoSource(PlatformInterface::SharedInstance()->makeVideoSource(signalingThread, workerThread)) -{ - _platformContext = platformContext; - switchToDevice(deviceId, isScreenCapture); +VideoCaptureInterfaceObject::VideoCaptureInterfaceObject(rtc::Thread* signalingThread, + rtc::Thread* workerThread, + std::string deviceId, + bool isScreenCapture, + std::shared_ptr + platformContext) + : _videoSource(PlatformInterface::SharedInstance()->makeVideoSource(signalingThread, + workerThread)) { + _platformContext = platformContext; + switchToDevice(deviceId, isScreenCapture); } VideoCaptureInterfaceObject::~VideoCaptureInterfaceObject() { - if (_videoCapturer) { - _videoCapturer->setUncroppedOutput(nullptr); - } + if (_videoCapturer) { + _videoCapturer->setUncroppedOutput(nullptr); + } } rtc::scoped_refptr VideoCaptureInterfaceObject::source() { - return _videoSource; + return _videoSource; } int VideoCaptureInterfaceObject::getRotation() { @@ -31,62 +36,68 @@ int VideoCaptureInterfaceObject::getRotation() { } } -bool VideoCaptureInterfaceObject::isScreenCapture() { - return _isScreenCapture; -} +bool VideoCaptureInterfaceObject::isScreenCapture() { return _isScreenCapture; } void VideoCaptureInterfaceObject::switchToDevice(std::string deviceId, bool isScreenCapture) { if (_videoCapturer) { - _videoCapturer->setUncroppedOutput(nullptr); + _videoCapturer->setUncroppedOutput(nullptr); } _isScreenCapture = isScreenCapture; - if (_videoSource) { - //this should outlive the capturer + if (_videoSource) { + // this should outlive the capturer _videoCapturer = nullptr; - _videoCapturer = PlatformInterface::SharedInstance()->makeVideoCapturer(_videoSource, deviceId, [this](VideoState state) { - if (this->_stateUpdated) { - this->_stateUpdated(state); - } - if (this->_onIsActiveUpdated) { - switch (state) { - case VideoState::Active: { - this->_onIsActiveUpdated(true); - break; + _videoCapturer = PlatformInterface::SharedInstance()->makeVideoCapturer( + _videoSource, + deviceId, + [this](VideoState state) { + if (this->_stateUpdated) { + this->_stateUpdated(state); } - default: { - this->_onIsActiveUpdated(false); - break; + if (this->_onIsActiveUpdated) { + switch (state) { + case VideoState::Active: { + this->_onIsActiveUpdated(true); + break; + } + default: { + this->_onIsActiveUpdated(false); + break; + } + } } - } - } - }, [this](PlatformCaptureInfo info) { - if (this->_shouldBeAdaptedToReceiverAspectRate != info.shouldBeAdaptedToReceiverAspectRate) { - this->_shouldBeAdaptedToReceiverAspectRate = info.shouldBeAdaptedToReceiverAspectRate; - } - if (this->_rotationUpdated) { - this->_rotationUpdated(info.rotation); - } - this->updateAspectRateAdaptation(); - }, _platformContext, _videoCapturerResolution); - } - if (_videoCapturer) { - if (_preferredAspectRatio > 0) { - _videoCapturer->setPreferredCaptureAspectRatio(_preferredAspectRatio); - } - if (const auto currentUncroppedSink = _currentUncroppedSink.lock()) { - _videoCapturer->setUncroppedOutput(currentUncroppedSink); - } + }, + [this](PlatformCaptureInfo info) { + if (this->_shouldBeAdaptedToReceiverAspectRate != + info.shouldBeAdaptedToReceiverAspectRate) { + this->_shouldBeAdaptedToReceiverAspectRate = + info.shouldBeAdaptedToReceiverAspectRate; + } + if (this->_rotationUpdated) { + this->_rotationUpdated(info.rotation); + } + this->updateAspectRateAdaptation(); + }, + _platformContext, + _videoCapturerResolution); + } + if (_videoCapturer) { + if (_preferredAspectRatio > 0) { + _videoCapturer->setPreferredCaptureAspectRatio(_preferredAspectRatio); + } + if (const auto currentUncroppedSink = _currentUncroppedSink.lock()) { + _videoCapturer->setUncroppedOutput(currentUncroppedSink); + } if (_onFatalError) { _videoCapturer->setOnFatalError(_onFatalError); } if (_onPause) { _videoCapturer->setOnPause(_onPause); } - _videoCapturer->setState(_state); - } + _videoCapturer->setState(_state); + } } -void VideoCaptureInterfaceObject::withNativeImplementation(std::function completion) { +void VideoCaptureInterfaceObject::withNativeImplementation(std::function completion) { if (_videoCapturer) { _videoCapturer->withNativeImplementation(completion); } else { @@ -95,12 +106,12 @@ void VideoCaptureInterfaceObject::withNativeImplementation(std::functionsetState(state); - } - } + if (_state != state) { + _state = state; + if (_videoCapturer) { + _videoCapturer->setState(state); + } + } } void VideoCaptureInterfaceObject::setPreferredAspectRatio(float aspectRatio) { @@ -118,25 +129,31 @@ void VideoCaptureInterfaceObject::updateAspectRateAdaptation() { float aspectRatio = _preferredAspectRatio; float width = (originalWidth > aspectRatio * originalHeight) - ? int(std::round(aspectRatio * originalHeight)) - : originalWidth; + ? int(std::round(aspectRatio * originalHeight)) + : originalWidth; float height = (originalWidth > aspectRatio * originalHeight) - ? originalHeight - : int(std::round(originalHeight / aspectRatio)); + ? originalHeight + : int(std::round(originalHeight / aspectRatio)); - PlatformInterface::SharedInstance()->adaptVideoSource(_videoSource, (int)width, (int)height, 25); + PlatformInterface::SharedInstance()->adaptVideoSource( + _videoSource, (int)width, (int)height, 25); } else { - PlatformInterface::SharedInstance()->adaptVideoSource(_videoSource, _videoCapturerResolution.first, _videoCapturerResolution.second, 25); + PlatformInterface::SharedInstance()->adaptVideoSource( + _videoSource, + _videoCapturerResolution.first, + _videoCapturerResolution.second, + 25); } } } } -void VideoCaptureInterfaceObject::setOutput(std::shared_ptr> sink) { - if (_videoCapturer) { - _videoCapturer->setUncroppedOutput(sink); - } - _currentUncroppedSink = sink; +void VideoCaptureInterfaceObject::setOutput( + std::shared_ptr> sink) { + if (_videoCapturer) { + _videoCapturer->setUncroppedOutput(sink); + } + _currentUncroppedSink = sink; } void VideoCaptureInterfaceObject::setOnFatalError(std::function error) { @@ -152,86 +169,87 @@ void VideoCaptureInterfaceObject::setOnPause(std::function pause) { _onPause = pause; } -void VideoCaptureInterfaceObject::setOnIsActiveUpdated(std::function onIsActiveUpdated) { +void VideoCaptureInterfaceObject::setOnIsActiveUpdated( + std::function onIsActiveUpdated) { _onIsActiveUpdated = onIsActiveUpdated; } void VideoCaptureInterfaceObject::setStateUpdated(std::function stateUpdated) { - _stateUpdated = stateUpdated; + _stateUpdated = stateUpdated; } void VideoCaptureInterfaceObject::setRotationUpdated(std::function rotationUpdated) { _rotationUpdated = rotationUpdated; } -VideoCaptureInterfaceImpl::VideoCaptureInterfaceImpl(rtc::Thread *signalingThread, - rtc::Thread *workerThread, +VideoCaptureInterfaceImpl::VideoCaptureInterfaceImpl(rtc::Thread* signalingThread, + rtc::Thread* workerThread, std::string deviceId, bool isScreenCapture, - std::shared_ptr platformContext ) : -_impl( //threads->getMediaThread(), [deviceId, isScreenCapture, platformContext, threads]() { -// return - new VideoCaptureInterfaceObject(signalingThread, workerThread, deviceId, isScreenCapture, platformContext) -//} -) -{ - -} + std::shared_ptr + platformContext) + : _impl( // threads->getMediaThread(), [deviceId, isScreenCapture, platformContext, + // threads]() { + // return + new VideoCaptureInterfaceObject( + signalingThread, workerThread, deviceId, isScreenCapture, platformContext) + //} + ) {} VideoCaptureInterfaceImpl::~VideoCaptureInterfaceImpl() = default; void VideoCaptureInterfaceImpl::switchToDevice(std::string deviceId, bool isScreenCapture) { -// _impl.perform(RTC_FROM_HERE, [deviceId, isScreenCapture](VideoCaptureInterfaceObject *impl) { - _impl->switchToDevice(deviceId, isScreenCapture); -// }); + // _impl.perform(RTC_FROM_HERE, [deviceId, isScreenCapture](VideoCaptureInterfaceObject *impl) + //{ + _impl->switchToDevice(deviceId, isScreenCapture); + // }); } -void VideoCaptureInterfaceImpl::withNativeImplementation(std::function completion) { -// _impl.perform(RTC_FROM_HERE, [completion](VideoCaptureInterfaceObject *impl) { - _impl->withNativeImplementation(completion); -// }); +void VideoCaptureInterfaceImpl::withNativeImplementation(std::function completion) { + // _impl.perform(RTC_FROM_HERE, [completion](VideoCaptureInterfaceObject *impl) { + _impl->withNativeImplementation(completion); + // }); } void VideoCaptureInterfaceImpl::setState(VideoState state) { -// _impl.perform(RTC_FROM_HERE, [state](VideoCaptureInterfaceObject *impl) { - _impl->setState(state); -// }); + // _impl.perform(RTC_FROM_HERE, [state](VideoCaptureInterfaceObject *impl) { + _impl->setState(state); + // }); } void VideoCaptureInterfaceImpl::setPreferredAspectRatio(float aspectRatio) { -// _impl.perform(RTC_FROM_HERE, [aspectRatio](VideoCaptureInterfaceObject *impl) { - _impl->setPreferredAspectRatio(aspectRatio); -// }); + // _impl.perform(RTC_FROM_HERE, [aspectRatio](VideoCaptureInterfaceObject *impl) { + _impl->setPreferredAspectRatio(aspectRatio); + // }); } void VideoCaptureInterfaceImpl::setOnFatalError(std::function error) { -// _impl.perform(RTC_FROM_HERE, [error](VideoCaptureInterfaceObject *impl) { - _impl->setOnFatalError(error); -// }); + // _impl.perform(RTC_FROM_HERE, [error](VideoCaptureInterfaceObject *impl) { + _impl->setOnFatalError(error); + // }); } void VideoCaptureInterfaceImpl::setOnPause(std::function pause) { -// _impl.perform(RTC_FROM_HERE, [pause](VideoCaptureInterfaceObject *impl) { - _impl->setOnPause(pause); -// }); + // _impl.perform(RTC_FROM_HERE, [pause](VideoCaptureInterfaceObject *impl) { + _impl->setOnPause(pause); + // }); } void VideoCaptureInterfaceImpl::setOnIsActiveUpdated(std::function onIsActiveUpdated) { -// _impl.perform(RTC_FROM_HERE, [onIsActiveUpdated](VideoCaptureInterfaceObject *impl) { - _impl->setOnIsActiveUpdated(onIsActiveUpdated); -// }); + // _impl.perform(RTC_FROM_HERE, [onIsActiveUpdated](VideoCaptureInterfaceObject *impl) { + _impl->setOnIsActiveUpdated(onIsActiveUpdated); + // }); } -void VideoCaptureInterfaceImpl::setOutput(std::shared_ptr> sink) { -// _impl.perform(RTC_FROM_HERE, [sink](VideoCaptureInterfaceObject *impl) { - _impl->setOutput(sink); -// }); +void VideoCaptureInterfaceImpl::setOutput( + std::shared_ptr> sink) { + // _impl.perform(RTC_FROM_HERE, [sink](VideoCaptureInterfaceObject *impl) { + _impl->setOutput(sink); + // }); } - VideoCaptureInterfaceObject *VideoCaptureInterfaceImpl::object() { - return _impl; -} +VideoCaptureInterfaceObject* VideoCaptureInterfaceImpl::object() { return _impl; } rtc::scoped_refptr VideoCaptureInterfaceImpl::source() { - return _impl->source(); + return _impl->source(); } -} // namespace lib::ortc +} // namespace lib::ortc diff --git a/src/lib/ortc/webrtc/VideoCaptureInterfaceImpl.h b/src/lib/ortc/webrtc/VideoCaptureInterfaceImpl.h index 723f96e1..d3624845 100644 --- a/src/lib/ortc/webrtc/VideoCaptureInterfaceImpl.h +++ b/src/lib/ortc/webrtc/VideoCaptureInterfaceImpl.h @@ -1,10 +1,10 @@ #ifndef ORTC_VIDEO_CAPTURE_INTERFACE_IMPL_H #define ORTC_VIDEO_CAPTURE_INTERFACE_IMPL_H -#include "VideoCaptureInterface.h" -#include #include #include +#include +#include "VideoCaptureInterface.h" namespace lib::ortc { @@ -13,65 +13,66 @@ class Threads; class VideoCaptureInterfaceObject { public: - VideoCaptureInterfaceObject(rtc::Thread *signalingThread, rtc::Thread *workerThread, std::string deviceId, bool isScreenCapture, std::shared_ptr platformContext); - ~VideoCaptureInterfaceObject(); + VideoCaptureInterfaceObject(rtc::Thread* signalingThread, rtc::Thread* workerThread, + std::string deviceId, bool isScreenCapture, + std::shared_ptr platformContext); + ~VideoCaptureInterfaceObject(); - void switchToDevice(std::string deviceId, bool isScreenCapture); - void withNativeImplementation(std::function completion); - void setState(VideoState state); - void setPreferredAspectRatio(float aspectRatio); - void setOutput(std::shared_ptr> sink); - void setStateUpdated(std::function stateUpdated); - void setRotationUpdated(std::function rotationUpdated); - void setOnFatalError(std::function error); - void setOnPause(std::function pause); - void setOnIsActiveUpdated(std::function onIsActiveUpdated); - rtc::scoped_refptr source(); - int getRotation(); - bool isScreenCapture(); + void switchToDevice(std::string deviceId, bool isScreenCapture); + void withNativeImplementation(std::function completion); + void setState(VideoState state); + void setPreferredAspectRatio(float aspectRatio); + void setOutput(std::shared_ptr> sink); + void setStateUpdated(std::function stateUpdated); + void setRotationUpdated(std::function rotationUpdated); + void setOnFatalError(std::function error); + void setOnPause(std::function pause); + void setOnIsActiveUpdated(std::function onIsActiveUpdated); + rtc::scoped_refptr source(); + int getRotation(); + bool isScreenCapture(); private: - void updateAspectRateAdaptation(); + void updateAspectRateAdaptation(); - rtc::scoped_refptr _videoSource; - std::weak_ptr> _currentUncroppedSink; - std::shared_ptr _platformContext; - std::pair _videoCapturerResolution; - std::unique_ptr _videoCapturer; - std::function _stateUpdated; - std::function _onFatalError; - std::function _onPause; - std::function _onIsActiveUpdated; - std::function _rotationUpdated; - VideoState _state = VideoState::Active; - float _preferredAspectRatio = 0.0f; - bool _shouldBeAdaptedToReceiverAspectRate = true; - bool _isScreenCapture = false; + rtc::scoped_refptr _videoSource; + std::weak_ptr> _currentUncroppedSink; + std::shared_ptr _platformContext; + std::pair _videoCapturerResolution; + std::unique_ptr _videoCapturer; + std::function _stateUpdated; + std::function _onFatalError; + std::function _onPause; + std::function _onIsActiveUpdated; + std::function _rotationUpdated; + VideoState _state = VideoState::Active; + float _preferredAspectRatio = 0.0f; + bool _shouldBeAdaptedToReceiverAspectRate = true; + bool _isScreenCapture = false; }; class VideoCaptureInterfaceImpl : public VideoCaptureInterface { public: - VideoCaptureInterfaceImpl(rtc::Thread *signalingThread, rtc::Thread *workerThread, - std::string deviceId, - bool isScreenCapture, - std::shared_ptr platformContext); - virtual ~VideoCaptureInterfaceImpl(); + VideoCaptureInterfaceImpl(rtc::Thread* signalingThread, rtc::Thread* workerThread, + std::string deviceId, bool isScreenCapture, + std::shared_ptr platformContext); + virtual ~VideoCaptureInterfaceImpl(); - void switchToDevice(std::string deviceId, bool isScreenCapture) override; - void withNativeImplementation(std::function completion) override; - void setState(VideoState state) override; - void setPreferredAspectRatio(float aspectRatio) override; - void setOutput(std::shared_ptr> sink) override; - void setOnFatalError(std::function error) override; - void setOnPause(std::function pause) override; - void setOnIsActiveUpdated(std::function onIsActiveUpdated) override; - rtc::scoped_refptr source() override; - VideoCaptureInterfaceObject *object(); + void switchToDevice(std::string deviceId, bool isScreenCapture) override; + void withNativeImplementation(std::function completion) override; + void setState(VideoState state) override; + void setPreferredAspectRatio(float aspectRatio) override; + void setOutput(std::shared_ptr> sink) override; + void setOnFatalError(std::function error) override; + void setOnPause(std::function pause) override; + void setOnIsActiveUpdated(std::function onIsActiveUpdated) override; + rtc::scoped_refptr source() override; + VideoCaptureInterfaceObject* object(); private: - VideoCaptureInterfaceObject *_impl; + VideoCaptureInterfaceObject* _impl; }; -} // namespace lib::ortc +} // namespace lib::ortc #endif diff --git a/src/lib/ortc/webrtc/VideoCapturerInterface.h b/src/lib/ortc/webrtc/VideoCapturerInterface.h index 892eb978..fc04ddd7 100644 --- a/src/lib/ortc/webrtc/VideoCapturerInterface.h +++ b/src/lib/ortc/webrtc/VideoCapturerInterface.h @@ -3,40 +3,39 @@ #include "Instance.h" -#include #include +#include namespace rtc { -template -class VideoSinkInterface; -} // namespace rtc +template class VideoSinkInterface; +} // namespace rtc namespace webrtc { class VideoFrame; -} // namespace webrtc +} // namespace webrtc namespace lib::ortc { class VideoCapturerInterface { public: - virtual ~VideoCapturerInterface() = default; + virtual ~VideoCapturerInterface() = default; - virtual void setState(VideoState state) = 0; - virtual void setPreferredCaptureAspectRatio(float aspectRatio) = 0; - virtual void setUncroppedOutput(std::shared_ptr> sink) = 0; + virtual void setState(VideoState state) = 0; + virtual void setPreferredCaptureAspectRatio(float aspectRatio) = 0; + virtual void setUncroppedOutput( + std::shared_ptr> sink) = 0; virtual int getRotation() = 0; virtual void setOnFatalError(std::function error) { - // TODO: make this function pure virtual when everybody implements it. + // TODO: make this function pure virtual when everybody implements it. } virtual void setOnPause(std::function pause) { - // TODO: make this function pure virtual when everybody implements it. + // TODO: make this function pure virtual when everybody implements it. } - virtual void withNativeImplementation(std::function completion) { + virtual void withNativeImplementation(std::function completion) { completion(nullptr); } - }; -} // namespace lib::ortc +} // namespace lib::ortc #endif diff --git a/src/lib/ortc/webrtc/ok_conductor.cpp b/src/lib/ortc/webrtc/ok_conductor.cpp index 225cdb07..99bbb523 100644 --- a/src/lib/ortc/webrtc/ok_conductor.cpp +++ b/src/lib/ortc/webrtc/ok_conductor.cpp @@ -30,145 +30,140 @@ namespace lib { namespace ortc { -Conductor::Conductor( - WebRTC* webrtc, - const std::string &peerId_, // - const std::string &sId_ // - ) - : - peerId(peerId_), // - sId(sId_), // - - webRtc{webrtc}, - _remote_audio_track(nullptr), - _remote_video_track(nullptr) { - - RTC_LOG(LS_INFO) <<"..."; +Conductor::Conductor(WebRTC* webrtc, + const std::string& peerId_, // + const std::string& sId_ // + ) + : peerId(peerId_) + , // + sId(sId_) + , // + + webRtc{webrtc} + , _remote_audio_track(nullptr) + , _remote_video_track(nullptr) { + RTC_LOG(LS_INFO) << "..."; assert(webRtc); assert(webRtc->ensureStart()); assert(!peerId_.empty()); - CreatePeerConnection(); - RTC_LOG(LS_INFO) << __FUNCTION__; + RTC_LOG(LS_INFO) << __FUNCTION__; } Conductor::~Conductor() { - RTC_LOG(LS_INFO) << __FUNCTION__ << "..."; - DestroyPeerConnection(); - RTC_LOG(LS_INFO) << __FUNCTION__ << "Destroyed"; + RTC_LOG(LS_INFO) << __FUNCTION__ << "..."; + DestroyPeerConnection(); + RTC_LOG(LS_INFO) << __FUNCTION__ << "Destroyed"; } void Conductor::CreatePeerConnection() { - RTC_LOG(LS_INFO) << __FUNCTION__<< "..."; + RTC_LOG(LS_INFO) << __FUNCTION__ << "..."; - webrtc::PeerConnectionDependencies pc_dependencies(this); + webrtc::PeerConnectionDependencies pc_dependencies(this); - auto maybe = webRtc->getFactory()->CreatePeerConnectionOrError(webRtc->getConfig(), - std::move(pc_dependencies)); - if(webRtc->getHandler()){ - webRtc->getHandler()->onCreatePeerConnection(sId, peerId, maybe.ok()); - } + auto maybe = webRtc->getFactory()->CreatePeerConnectionOrError(webRtc->getConfig(), + std::move(pc_dependencies)); + if (webRtc->getHandler()) { + webRtc->getHandler()->onCreatePeerConnection(sId, peerId, maybe.ok()); + } - if(!maybe.ok()){ - return; - } + if (!maybe.ok()) { + return; + } - peer_connection_ = maybe.value(); - RTC_LOG(LS_INFO) << __FUNCTION__<<" done."; + peer_connection_ = maybe.value(); + RTC_LOG(LS_INFO) << __FUNCTION__ << " done."; } void Conductor::DestroyPeerConnection() { - RTC_LOG(LS_INFO) << __FUNCTION__ << "..."; - RemoveAudioTrack(); - RemoveVideoTrack(); - peer_connection_->Close(); - peer_connection_.release(); - RTC_LOG(LS_INFO) << __FUNCTION__ <<" done."; + RTC_LOG(LS_INFO) << __FUNCTION__ << "..."; + RemoveAudioTrack(); + RemoveVideoTrack(); + peer_connection_->Close(); + peer_connection_.release(); + RTC_LOG(LS_INFO) << __FUNCTION__ << " done."; } size_t Conductor::getVideoCaptureSize() { - std::unique_ptr info( - webrtc::VideoCaptureFactory::CreateDeviceInfo()); - if (!info) { - return 0; - } - int num_devices = info->NumberOfDevices(); - return num_devices; + std::unique_ptr info( + webrtc::VideoCaptureFactory::CreateDeviceInfo()); + if (!info) { + return 0; + } + int num_devices = info->NumberOfDevices(); + return num_devices; } void Conductor::setMute(bool mute) { - RTC_LOG(LS_INFO) << __FUNCTION__; - if(_audioTrack){ + RTC_LOG(LS_INFO) << __FUNCTION__; + if (_audioTrack) { _audioTrack->set_enabled(!mute); } } void Conductor::setRemoteMute(bool mute) { - RTC_LOG(LS_INFO) << __FUNCTION__ ; - if (_remote_audio_track) { - _remote_audio_track->set_enabled(!mute); - } + RTC_LOG(LS_INFO) << __FUNCTION__; + if (_remote_audio_track) { + _remote_audio_track->set_enabled(!mute); + } } -bool Conductor::AddAudioTrack(webrtc::AudioSourceInterface *_audioSource) { - RTC_LOG(LS_INFO) << __FUNCTION__ << ":" <<_audioSource; +bool Conductor::AddAudioTrack(webrtc::AudioSourceInterface* _audioSource) { + RTC_LOG(LS_INFO) << __FUNCTION__ << ":" << _audioSource; - std::string label = "ok-audio-label"; - _audioTrack = webRtc->getFactory()->CreateAudioTrack(label, _audioSource); - RTC_LOG(LS_INFO) << "Created audio track:" << _videoTrack.get(); + std::string label = "ok-audio-label"; + _audioTrack = webRtc->getFactory()->CreateAudioTrack(label, _audioSource); + RTC_LOG(LS_INFO) << "Created audio track:" << _videoTrack.get(); - std::string streamId = "ok-audio-stream"; - auto added = peer_connection_->AddTrack(_audioTrack, {streamId}); - if (!added.ok()) { - RTC_LOG(LS_INFO)<< "Failed to add track:%1" << added.error().message(); - return false; - } + std::string streamId = "ok-audio-stream"; + auto added = peer_connection_->AddTrack(_audioTrack, {streamId}); + if (!added.ok()) { + RTC_LOG(LS_INFO) << "Failed to add track:%1" << added.error().message(); + return false; + } - _audioRtpSender = added.value(); - RTC_LOG(LS_INFO)<< "Audio rtp sender:"<< _audioRtpSender.get(); - return true; + _audioRtpSender = added.value(); + RTC_LOG(LS_INFO) << "Audio rtp sender:" << _audioRtpSender.get(); + return true; } -bool Conductor::RemoveAudioTrack(){ - RTC_LOG(LS_INFO) << __FUNCTION__; - auto result = peer_connection_->RemoveTrackOrError(_audioRtpSender); - return result.ok(); +bool Conductor::RemoveAudioTrack() { + RTC_LOG(LS_INFO) << __FUNCTION__; + auto result = peer_connection_->RemoveTrackOrError(_audioRtpSender); + return result.ok(); } +bool Conductor::AddVideoTrack(webrtc::VideoTrackSourceInterface* _videoTrackSource) { + RTC_LOG(LS_INFO) << __FUNCTION__ << ":" << _videoTrackSource; -bool Conductor::AddVideoTrack(webrtc::VideoTrackSourceInterface *_videoTrackSource) { - RTC_LOG(LS_INFO) << __FUNCTION__ << ":" << _videoTrackSource; - - std::string label = "ok-video-track-label"; + std::string label = "ok-video-track-label"; - _videoTrack = webRtc->getFactory()->CreateVideoTrack(label, _videoTrackSource); - RTC_LOG(LS_INFO) << "Created video track:" << _videoTrack.get(); + _videoTrack = webRtc->getFactory()->CreateVideoTrack(label, _videoTrackSource); + RTC_LOG(LS_INFO) << "Created video track:" << _videoTrack.get(); -// _videoTrack->AddOrUpdateSink(new VideoSink(_rtcRenderer), -// // rtc::VideoSinkWants()); qDebug(("Added video track, The device num -// // is:%1").arg(i)); + // _videoTrack->AddOrUpdateSink(new VideoSink(_rtcRenderer), + // // rtc::VideoSinkWants()); qDebug(("Added video track, The device num + // // is:%1").arg(i)); - std::string streamId = "ok-video-stream"; - auto added = peer_connection_->AddTrack(_videoTrack, {streamId}); + std::string streamId = "ok-video-stream"; + auto added = peer_connection_->AddTrack(_videoTrack, {streamId}); - if (!added.ok()) { - RTC_LOG(LS_INFO)<< "Failed to add track:" << added.error().message(); - return false; - } - - _videoRtpSender = added.value(); - RTC_LOG(LS_INFO) << "Video rtp sender:" << _videoRtpSender.get(); + if (!added.ok()) { + RTC_LOG(LS_INFO) << "Failed to add track:" << added.error().message(); + return false; + } - return true; + _videoRtpSender = added.value(); + RTC_LOG(LS_INFO) << "Video rtp sender:" << _videoRtpSender.get(); + return true; } -bool Conductor::RemoveVideoTrack() -{ +bool Conductor::RemoveVideoTrack() { RTC_LOG(LS_INFO) << __FUNCTION__; auto result = peer_connection_->RemoveTrackOrError(_videoRtpSender); return result.ok(); @@ -178,142 +173,134 @@ void Conductor::OnDataChannel(rtc::scoped_refptr c RTC_LOG(LS_INFO) << __FUNCTION__ << "OnDataChannel channel id:" << channel->id(); } -void Conductor::OnRenegotiationNeeded() { - RTC_LOG(LS_INFO) << __FUNCTION__; -} +void Conductor::OnRenegotiationNeeded() { RTC_LOG(LS_INFO) << __FUNCTION__; } /** * ICE 连接状态 * @param state */ -void Conductor::OnIceConnectionChange( - webrtc::PeerConnectionInterface::IceConnectionState state) { - - RTC_LOG(LS_INFO) << __FUNCTION__ << "=>" << webrtc::PeerConnectionInterface::AsString(state).data(); +void Conductor::OnIceConnectionChange(webrtc::PeerConnectionInterface::IceConnectionState state) { + RTC_LOG(LS_INFO) << __FUNCTION__ << "=>" + << webrtc::PeerConnectionInterface::AsString(state).data(); } void Conductor::OnIceGatheringChange(webrtc::PeerConnectionInterface::IceGatheringState state) { - RTC_LOG(LS_INFO) << __FUNCTION__ <<"=>"<< webrtc::PeerConnectionInterface::AsString(state).data(); -} - -void Conductor::OnIceCandidate(const webrtc::IceCandidateInterface *ice) { - - std::string str; - ice->ToString(&str); - - RTC_LOG(LS_INFO) << __FUNCTION__ << "=> mid:" << ice->sdp_mid() << " "<< str; - - auto &cand = ice->candidate(); - - /** - * 发送 IceCandidate - */ - OIceUdp iceUdp; - iceUdp.mid = ice->sdp_mid(); // - iceUdp.mline = ice->sdp_mline_index(); // - iceUdp.ufrag = cand.username(); - iceUdp.pwd = cand.password(); - - auto sdp = peer_connection_->local_description(); - auto transportInfos = sdp->description()->transport_infos(); - for (auto info : transportInfos) { - - if (info.content_name == ice->sdp_mid()) { - if(info.description.identity_fingerprint){ - iceUdp.dtls.hash = info.description.identity_fingerprint->algorithm; - iceUdp.dtls.fingerprint = info.description.identity_fingerprint->GetRfc4572Fingerprint(); + RTC_LOG(LS_INFO) << __FUNCTION__ << "=>" + << webrtc::PeerConnectionInterface::AsString(state).data(); +} + +void Conductor::OnIceCandidate(const webrtc::IceCandidateInterface* ice) { + std::string str; + ice->ToString(&str); + + RTC_LOG(LS_INFO) << __FUNCTION__ << "=> mid:" << ice->sdp_mid() << " " << str; + + auto& cand = ice->candidate(); + + /** + * 发送 IceCandidate + */ + OIceUdp iceUdp; + iceUdp.mid = ice->sdp_mid(); // + iceUdp.mline = ice->sdp_mline_index(); // + iceUdp.ufrag = cand.username(); + iceUdp.pwd = cand.password(); + + auto sdp = peer_connection_->local_description(); + auto transportInfos = sdp->description()->transport_infos(); + for (auto info : transportInfos) { + if (info.content_name == ice->sdp_mid()) { + if (info.description.identity_fingerprint) { + iceUdp.dtls.hash = info.description.identity_fingerprint->algorithm; + iceUdp.dtls.fingerprint = + info.description.identity_fingerprint->GetRfc4572Fingerprint(); + } + + switch (info.description.connection_role) { + case ::cricket::CONNECTIONROLE_ACTIVE: + iceUdp.dtls.setup = ::cricket::CONNECTIONROLE_ACTIVE_STR; + break; + case ::cricket::CONNECTIONROLE_ACTPASS: + iceUdp.dtls.setup = ::cricket::CONNECTIONROLE_ACTPASS_STR; + break; + case ::cricket::CONNECTIONROLE_HOLDCONN: + iceUdp.dtls.setup = ::cricket::CONNECTIONROLE_HOLDCONN_STR; + break; + case ::cricket::CONNECTIONROLE_PASSIVE: + iceUdp.dtls.setup = ::cricket::CONNECTIONROLE_PASSIVE_STR; + break; + case ::cricket::CONNECTIONROLE_NONE: + break; + } } + } + // candidate + gloox::Jingle::ICEUDP::Candidate oc; + oc.id = cand.id(); + oc.foundation = cand.foundation(); + oc.priority = cand.priority(); + oc.protocol = cand.protocol(); + oc.tcptype = cand.tcptype(); + oc.generation = std::to_string(cand.generation()); + oc.component = std::to_string(cand.component()); + oc.network = std::to_string(cand.network_id()); + + // addr + oc.ip = cand.address().ipaddr().ToString(); + oc.port = cand.address().port(); + + // “host” / “srflx” / “prflx” / “relay” / token + if (cand.type() == ::cricket::LOCAL_PORT_TYPE) { + oc.type = gloox::Jingle::ICEUDP::Host; + } else if (cand.type() == ::cricket::STUN_PORT_TYPE) { + oc.type = gloox::Jingle::ICEUDP::ServerReflexive; + } else if (cand.type() == ::cricket::PRFLX_PORT_TYPE) { + oc.type = gloox::Jingle::ICEUDP::PeerReflexive; + } else if (cand.type() == ::cricket::RELAY_PORT_TYPE) { + oc.type = gloox::Jingle::ICEUDP::Relayed; + } - switch (info.description.connection_role) { - case ::cricket::CONNECTIONROLE_ACTIVE: - iceUdp.dtls.setup = ::cricket::CONNECTIONROLE_ACTIVE_STR; - break; - case ::cricket::CONNECTIONROLE_ACTPASS: - iceUdp.dtls.setup = ::cricket::CONNECTIONROLE_ACTPASS_STR; - break; - case ::cricket::CONNECTIONROLE_HOLDCONN: - iceUdp.dtls.setup = ::cricket::CONNECTIONROLE_HOLDCONN_STR; - break; - case ::cricket::CONNECTIONROLE_PASSIVE: - iceUdp.dtls.setup = ::cricket::CONNECTIONROLE_PASSIVE_STR; - break; - case ::cricket::CONNECTIONROLE_NONE: - break; - } + if (oc.type != gloox::Jingle::ICEUDP::Host && 0 < cand.related_address().port()) { + oc.rel_addr = cand.related_address().ipaddr().ToString(); + oc.rel_port = cand.related_address().port(); } - } - // candidate - gloox::Jingle::ICEUDP::Candidate oc; - oc.id = cand.id(); - oc.foundation = cand.foundation(); - oc.priority = cand.priority(); - oc.protocol = cand.protocol(); - oc.tcptype = cand.tcptype(); - oc.generation = std::to_string(cand.generation()); - oc.component = std::to_string(cand.component()); - oc.network = std::to_string(cand.network_id()); - - // addr - oc.ip = cand.address().ipaddr().ToString(); - oc.port = cand.address().port(); - - // “host” / “srflx” / “prflx” / “relay” / token - if (cand.type() == ::cricket::LOCAL_PORT_TYPE) { - oc.type = gloox::Jingle::ICEUDP::Host; - } else if (cand.type() == ::cricket::STUN_PORT_TYPE) { - oc.type = gloox::Jingle::ICEUDP::ServerReflexive; - } else if (cand.type() == ::cricket::PRFLX_PORT_TYPE) { - oc.type = gloox::Jingle::ICEUDP::PeerReflexive; - } else if (cand.type() == ::cricket::RELAY_PORT_TYPE) { - oc.type = gloox::Jingle::ICEUDP::Relayed; - } - - if (oc.type != gloox::Jingle::ICEUDP::Host && - 0 < cand.related_address().port()) { - oc.rel_addr = cand.related_address().ipaddr().ToString(); - oc.rel_port = cand.related_address().port(); - } - - iceUdp.candidates.push_back(oc); - - webRtc->getHandler()->onIce(sId, peerId, iceUdp); + + iceUdp.candidates.push_back(oc); + + webRtc->getHandler()->onIce(sId, peerId, iceUdp); } void Conductor::OnIceConnectionReceivingChange(bool receiving) { - RTC_LOG(LS_INFO) << __FUNCTION__ << receiving; + RTC_LOG(LS_INFO) << __FUNCTION__ << receiving; } void Conductor::OnSignalingChange(webrtc::PeerConnectionInterface::SignalingState state) { - RTC_LOG(LS_INFO) << __FUNCTION__ <<"=>"<< webrtc::PeerConnectionInterface::AsString(state).data(); + RTC_LOG(LS_INFO) << __FUNCTION__ << "=>" + << webrtc::PeerConnectionInterface::AsString(state).data(); } - void Conductor::OnAddTrack( - rtc::scoped_refptr receiver, - const std::vector> - &streams) { - - std::string receiverId = receiver->id(); - RTC_LOG(LS_INFO) << __FUNCTION__ << "receiver id:" << receiverId; - - // track - auto track = receiver->track(); - RTC_LOG(LS_INFO) << __FUNCTION__ << "track id:" << track->id() << " kind:"<kind(); - - if ( track->kind() == webrtc::MediaStreamTrackInterface::kAudioKind) { - _remote_audio_track = static_cast(track.get()); - } else if ( track->kind() == webrtc::MediaStreamTrackInterface::kVideoKind) { - _videoSink = std::make_unique( webRtc->getHandler(), peerId); - _remote_video_track = static_cast(track.get()); - _remote_video_track->AddOrUpdateSink(_videoSink.get(), rtc::VideoSinkWants()); - } + rtc::scoped_refptr receiver, + const std::vector>& streams) { + std::string receiverId = receiver->id(); + RTC_LOG(LS_INFO) << __FUNCTION__ << "receiver id:" << receiverId; + + // track + auto track = receiver->track(); + RTC_LOG(LS_INFO) << __FUNCTION__ << "track id:" << track->id() << " kind:" << track->kind(); + + if (track->kind() == webrtc::MediaStreamTrackInterface::kAudioKind) { + _remote_audio_track = static_cast(track.get()); + } else if (track->kind() == webrtc::MediaStreamTrackInterface::kVideoKind) { + _videoSink = std::make_unique(webRtc->getHandler(), peerId); + _remote_video_track = static_cast(track.get()); + _remote_video_track->AddOrUpdateSink(_videoSink.get(), rtc::VideoSinkWants()); + } } -void Conductor::OnTrack( - rtc::scoped_refptr transceiver) { - RTC_LOG(LS_INFO) <<__FUNCTION__ - << " mid:" << transceiver->mid()->data() - << " type:"<media_type(); +void Conductor::OnTrack(rtc::scoped_refptr transceiver) { + RTC_LOG(LS_INFO) << __FUNCTION__ << " mid:" << transceiver->mid()->data() + << " type:" << transceiver->media_type(); } /** @@ -321,27 +308,24 @@ void Conductor::OnTrack( * @brief Conductor::OnRemoveTrack * @param receiver */ -void Conductor::OnRemoveTrack( - rtc::scoped_refptr receiver) { - RTC_LOG(LS_INFO) << "TrackId:" << receiver->id(); +void Conductor::OnRemoveTrack(rtc::scoped_refptr receiver) { + RTC_LOG(LS_INFO) << "TrackId:" << receiver->id(); - rtc::scoped_refptr track = - receiver->track(); + rtc::scoped_refptr track = receiver->track(); - if (track->kind() == webrtc::MediaStreamTrackInterface::kVideoKind) { - auto remote_video_track = static_cast(track.get()); - } + if (track->kind() == webrtc::MediaStreamTrackInterface::kVideoKind) { + auto remote_video_track = static_cast(track.get()); + } } /** * CreateOffer */ void Conductor::CreateOffer() { - RTC_LOG(LS_INFO) << "CreateOffer..."; - peer_connection_->SetLocalDescription(this); - peer_connection_->CreateOffer( - this, webrtc::PeerConnectionInterface::RTCOfferAnswerOptions()); - RTC_LOG(LS_INFO) << "CreateOffer has done."; + RTC_LOG(LS_INFO) << "CreateOffer..."; + peer_connection_->SetLocalDescription(this); + peer_connection_->CreateOffer(this, webrtc::PeerConnectionInterface::RTCOfferAnswerOptions()); + RTC_LOG(LS_INFO) << "CreateOffer has done."; } /** @@ -350,74 +334,68 @@ void Conductor::CreateOffer() { * @param desc */ void Conductor::CreateAnswer() { - RTC_LOG(LS_INFO) << __FUNCTION__ << "..."; - peer_connection_->CreateAnswer(this, webrtc::PeerConnectionInterface::RTCOfferAnswerOptions()); - RTC_LOG(LS_INFO) << __FUNCTION__ << "done."; + RTC_LOG(LS_INFO) << __FUNCTION__ << "..."; + peer_connection_->CreateAnswer(this, webrtc::PeerConnectionInterface::RTCOfferAnswerOptions()); + RTC_LOG(LS_INFO) << __FUNCTION__ << "done."; } void Conductor::SetRemoteDescription(std::unique_ptr desc) { - RTC_LOG(LS_INFO) <<__FUNCTION__ << "desc type:" << desc->type(); + RTC_LOG(LS_INFO) << __FUNCTION__ << "desc type:" << desc->type(); - std::string sdp; - desc->ToString(&sdp); - RTC_LOG(LS_INFO) << "sdp:\n" << sdp; + std::string sdp; + desc->ToString(&sdp); + RTC_LOG(LS_INFO) << "sdp:\n" << sdp; - peer_connection_->SetRemoteDescription(this, desc.release()); + peer_connection_->SetRemoteDescription(this, desc.release()); } -void Conductor::setTransportInfo( - std::unique_ptr candidate) { - - // candidate:2956132637 2 udp 41623294 122.9.45.183 58616 typ relay raddr 116.162.2.202 rport 33010 generation 0 - std::string str; - candidate->ToString(&str); - RTC_LOG(LS_INFO) << __FUNCTION__ << " mid:" << candidate->sdp_mid() << " "<< str; +void Conductor::setTransportInfo(std::unique_ptr candidate) { + // candidate:2956132637 2 udp 41623294 122.9.45.183 58616 typ relay raddr 116.162.2.202 rport + // 33010 generation 0 + std::string str; + candidate->ToString(&str); + RTC_LOG(LS_INFO) << __FUNCTION__ << " mid:" << candidate->sdp_mid() << " " << str; - auto c = candidate.release(); - auto added = peer_connection_->AddIceCandidate(c); - - RTC_LOG(LS_INFO) << __FUNCTION__ << " => " <AddIceCandidate(c); + RTC_LOG(LS_INFO) << __FUNCTION__ << " => " << added; } void Conductor::sessionTerminate() { peer_connection_->Close(); } -void Conductor::OnContentAdd( - std::map sdMap, - OkRTCHandler *handler) { - - std::lock_guard lock(_session_mutex); - const webrtc::SessionDescriptionInterface *remoteSDI = - peer_connection_->remote_description(); - - std::string sdp; - remoteSDI->ToString(&sdp); - RTC_LOG(LS_INFO) << "OnContentAdd remote sdp:" << sdp; +void Conductor::OnContentAdd(std::map sdMap, + OkRTCHandler* handler) { + std::lock_guard lock(_session_mutex); + const webrtc::SessionDescriptionInterface* remoteSDI = peer_connection_->remote_description(); - std::unique_ptr jsd = - webrtc::CreateSessionDescription(webrtc::SdpType::kOffer, sdp); + std::string sdp; + remoteSDI->ToString(&sdp); + RTC_LOG(LS_INFO) << "OnContentAdd remote sdp:" << sdp; - ::cricket::ContentGroup group(::cricket::GROUP_TYPE_BUNDLE); - for (auto it = sdMap.begin(); it != sdMap.end(); ++it) { - std::string name = it->first; - gloox::Jingle::Session sdp = it->second; - ::cricket::ContentInfo *info = jsd->description()->GetContentByName(name); - if (!info) { - continue; + std::unique_ptr jsd = + webrtc::CreateSessionDescription(webrtc::SdpType::kOffer, sdp); + + ::cricket::ContentGroup group(::cricket::GROUP_TYPE_BUNDLE); + for (auto it = sdMap.begin(); it != sdMap.end(); ++it) { + std::string name = it->first; + gloox::Jingle::Session sdp = it->second; + ::cricket::ContentInfo* info = jsd->description()->GetContentByName(name); + if (!info) { + continue; + } } - } - std::string new_sdp; - jsd->ToString(&new_sdp); - // qDebug(("remote new sdp:\n%1\n").arg(qstring(new_sdp))); - peer_connection_->SetRemoteDescription(this, jsd.release()); + std::string new_sdp; + jsd->ToString(&new_sdp); + // qDebug(("remote new sdp:\n%1\n").arg(qstring(new_sdp))); + peer_connection_->SetRemoteDescription(this, jsd.release()); - // qDebug(("end")); + // qDebug(("end")); } -void Conductor::OnContentRemove( - std::map sdMap, - OkRTCHandler *handler) { +void Conductor::OnContentRemove(std::map sdMap, + OkRTCHandler* handler) { #if 0 // qDebug(LS_INFO); std::lock_guard lock(_session_mutex); @@ -492,225 +470,216 @@ void Conductor::OnContentRemove( #endif } -void Conductor::OnSessionTerminate(const std::string &sid, - OkRTCHandler *handler) { - // qDebug(("begin sid:").arg(qstring(sid))); - std::lock_guard lock(_session_mutex); - // Shutdown(); - // qDebug(("end")); +void Conductor::OnSessionTerminate(const std::string& sid, OkRTCHandler* handler) { + // qDebug(("begin sid:").arg(qstring(sid))); + std::lock_guard lock(_session_mutex); + // Shutdown(); + // qDebug(("end")); } -OJingleContentAv Conductor::toJingleSdp(const webrtc::SessionDescriptionInterface *desc) { - - OJingleContentAv osdp; - osdp.sessionId = desc->session_id(); - osdp.sessionVersion = desc->session_version(); +OJingleContentAv Conductor::toJingleSdp(const webrtc::SessionDescriptionInterface* desc) { + OJingleContentAv osdp; + osdp.sessionId = desc->session_id(); + osdp.sessionVersion = desc->session_version(); - // ContentGroup - ::cricket::ContentGroup group(::cricket::GROUP_TYPE_BUNDLE); + // ContentGroup + ::cricket::ContentGroup group(::cricket::GROUP_TYPE_BUNDLE); - auto sd = desc->description(); - for (auto rtcContent : sd->contents()) { - OSdp oContent; + auto sd = desc->description(); + for (auto rtcContent : sd->contents()) { + OSdp oContent; - const std::string &name = rtcContent.mid(); - // qDebug(("Content name: %1").arg(qstring(name))); + const std::string& name = rtcContent.mid(); + // qDebug(("Content name: %1").arg(qstring(name))); - oContent.name = name; + oContent.name = name; - auto mediaDescription = rtcContent.media_description(); - // media type - auto mt = mediaDescription->type(); + auto mediaDescription = rtcContent.media_description(); + // media type + auto mt = mediaDescription->type(); - // rtcp_mux - oContent.rtp.rtcpMux = mediaDescription->rtcp_mux(); + // rtcp_mux + oContent.rtp.rtcpMux = mediaDescription->rtcp_mux(); - // Transport - auto ti = sd->GetTransportInfoByName(name); + // Transport + auto ti = sd->GetTransportInfoByName(name); - // pwd ufrag - oContent.iceUdp.pwd = ti->description.ice_pwd; - oContent.iceUdp.ufrag = ti->description.ice_ufrag; + // pwd ufrag + oContent.iceUdp.pwd = ti->description.ice_pwd; + oContent.iceUdp.ufrag = ti->description.ice_ufrag; - // fingerprint - if (ti->description.identity_fingerprint) { - oContent.iceUdp.dtls.fingerprint = - ti->description.identity_fingerprint->GetRfc4572Fingerprint(); - oContent.iceUdp.dtls.hash = - ti->description.identity_fingerprint->algorithm; + // fingerprint + if (ti->description.identity_fingerprint) { + oContent.iceUdp.dtls.fingerprint = + ti->description.identity_fingerprint->GetRfc4572Fingerprint(); + oContent.iceUdp.dtls.hash = ti->description.identity_fingerprint->algorithm; - // connection_role - std::string setup; - ::cricket::ConnectionRoleToString(ti->description.connection_role, &setup); - oContent.iceUdp.dtls.setup = setup; - } - - // hdrext - const ::cricket::RtpHeaderExtensions hdrs = - mediaDescription->rtp_header_extensions(); - for (auto &hdr : hdrs) { - gloox::Jingle::RTP::HdrExt hdrExt = {hdr.id, hdr.uri}; - oContent.rtp.hdrExts.push_back(hdrExt); - } - - // ssrc - for (auto &stream : mediaDescription->streams()) { - // "{id:5e9a64d8-b9d3-4fc7-a8eb-0ee6dec72138; //track id - // ssrcs:[1679428189,751024037]; - // ssrc_groups:{semantics:FID; ssrcs:[1679428189,751024037]}; - // cname:dBhnE4FRSAUq1FZp; - // stream_ids:okedu-video-id; - // }" - RTC_LOG(LS_INFO) << "stream: " << (stream.ToString()); - - // label - const std::string &first_stream_id = stream.first_stream_id(); - - for (auto &ssrc1 : stream.ssrcs) { - RTC_LOG(LS_INFO) << " label:" << first_stream_id - << " id:" << stream.id - << " ssrc" << ssrc1; - - gloox::Jingle::RTP::Parameter cname = {"cname", stream.cname}; - gloox::Jingle::RTP::Parameter label = {"label", stream.id}; - gloox::Jingle::RTP::Parameter mslabel = {"mslabel", first_stream_id}; - gloox::Jingle::RTP::Parameter msid = {"msid", first_stream_id + " " + - stream.id}; - - // msid = mslabel+ label(stream.id) - RTP::Parameters parameters; - parameters.emplace_back(cname); - parameters.emplace_back(msid); - parameters.emplace_back(mslabel); - parameters.emplace_back(label); - - gloox::Jingle::RTP::Source source = {std::to_string(ssrc1), parameters}; - oContent.rtp.sources.emplace_back(source); - } - } - - // ssrc-group - if (oContent.rtp.sources.size() >= 2) { - oContent.rtp.ssrcGroup.semantics = "FID"; - for (auto &ssrc : oContent.rtp.sources) { - oContent.rtp.ssrcGroup.ssrcs.emplace_back(ssrc.ssrc); - } - } - - // codecs - switch (mt) { - case ::cricket::MediaType::MEDIA_TYPE_AUDIO: { - oContent.rtp.media = gloox::Jingle::audio; - auto audio_desc = mediaDescription->as_audio(); - auto codecs = audio_desc->codecs(); - - for (auto &codec : codecs) { - gloox::Jingle::RTP::PayloadType type; - type.id = codec.id; - type.name = codec.name; - type.channels = codec.channels; - type.clockrate = codec.clockrate; - type.bitrate = codec.bitrate; - - auto cps = codec.ToCodecParameters(); - for (auto &it : cps.parameters) { - gloox::Jingle::RTP::Parameter parameter; - if (parameter.name.empty()) - continue; - parameter.name = it.first; - parameter.value = it.second; - type.parameters.emplace_back(parameter); + // connection_role + std::string setup; + ::cricket::ConnectionRoleToString(ti->description.connection_role, &setup); + oContent.iceUdp.dtls.setup = setup; } - // rtcp-fb - for (auto &it : codec.feedback_params.params()) { - gloox::Jingle::RTP::Feedback fb = {it.id(), it.param()}; - type.feedbacks.push_back(fb); + // hdrext + const ::cricket::RtpHeaderExtensions hdrs = mediaDescription->rtp_header_extensions(); + for (auto& hdr : hdrs) { + gloox::Jingle::RTP::HdrExt hdrExt = {hdr.id, hdr.uri}; + oContent.rtp.hdrExts.push_back(hdrExt); } - oContent.rtp.payloadTypes.emplace_back(type); - } + // ssrc + for (auto& stream : mediaDescription->streams()) { + // "{id:5e9a64d8-b9d3-4fc7-a8eb-0ee6dec72138; //track id + // ssrcs:[1679428189,751024037]; + // ssrc_groups:{semantics:FID; ssrcs:[1679428189,751024037]}; + // cname:dBhnE4FRSAUq1FZp; + // stream_ids:okedu-video-id; + // }" + RTC_LOG(LS_INFO) << "stream: " << (stream.ToString()); + + // label + const std::string& first_stream_id = stream.first_stream_id(); + + for (auto& ssrc1 : stream.ssrcs) { + RTC_LOG(LS_INFO) << " label:" << first_stream_id << " id:" << stream.id << " ssrc" + << ssrc1; + + gloox::Jingle::RTP::Parameter cname = {"cname", stream.cname}; + gloox::Jingle::RTP::Parameter label = {"label", stream.id}; + gloox::Jingle::RTP::Parameter mslabel = {"mslabel", first_stream_id}; + gloox::Jingle::RTP::Parameter msid = {"msid", first_stream_id + " " + stream.id}; + + // msid = mslabel+ label(stream.id) + RTP::Parameters parameters; + parameters.emplace_back(cname); + parameters.emplace_back(msid); + parameters.emplace_back(mslabel); + parameters.emplace_back(label); + + gloox::Jingle::RTP::Source source = {std::to_string(ssrc1), parameters}; + oContent.rtp.sources.emplace_back(source); + } + } - break; - } - case ::cricket::MediaType::MEDIA_TYPE_VIDEO: { - oContent.rtp.media = (gloox::Jingle::video); - auto video_desc = mediaDescription->as_video(); - for (auto &codec : video_desc->codecs()) { - // PayloadType - gloox::Jingle::RTP::PayloadType type; - type.id = codec.id; - type.name = codec.name; - type.clockrate = codec.clockrate; - - // PayloadType parameter - auto cps = codec.ToCodecParameters(); - for (auto &it : cps.parameters) { - gloox::Jingle::RTP::Parameter parameter; - parameter.name = it.first; - parameter.value = it.second; - type.parameters.emplace_back(parameter); + // ssrc-group + if (oContent.rtp.sources.size() >= 2) { + oContent.rtp.ssrcGroup.semantics = "FID"; + for (auto& ssrc : oContent.rtp.sources) { + oContent.rtp.ssrcGroup.ssrcs.emplace_back(ssrc.ssrc); + } } - // rtcp-fb - for (auto &it : codec.feedback_params.params()) { - gloox::Jingle::RTP::Feedback fb = {it.id(), it.param()}; - type.feedbacks.push_back(fb); + // codecs + switch (mt) { + case ::cricket::MediaType::MEDIA_TYPE_AUDIO: { + oContent.rtp.media = gloox::Jingle::audio; + auto audio_desc = mediaDescription->as_audio(); + auto codecs = audio_desc->codecs(); + + for (auto& codec : codecs) { + gloox::Jingle::RTP::PayloadType type; + type.id = codec.id; + type.name = codec.name; + type.channels = codec.channels; + type.clockrate = codec.clockrate; + type.bitrate = codec.bitrate; + + auto cps = codec.ToCodecParameters(); + for (auto& it : cps.parameters) { + gloox::Jingle::RTP::Parameter parameter; + if (parameter.name.empty()) continue; + parameter.name = it.first; + parameter.value = it.second; + type.parameters.emplace_back(parameter); + } + + // rtcp-fb + for (auto& it : codec.feedback_params.params()) { + gloox::Jingle::RTP::Feedback fb = {it.id(), it.param()}; + type.feedbacks.push_back(fb); + } + + oContent.rtp.payloadTypes.emplace_back(type); + } + + break; + } + case ::cricket::MediaType::MEDIA_TYPE_VIDEO: { + oContent.rtp.media = (gloox::Jingle::video); + auto video_desc = mediaDescription->as_video(); + for (auto& codec : video_desc->codecs()) { + // PayloadType + gloox::Jingle::RTP::PayloadType type; + type.id = codec.id; + type.name = codec.name; + type.clockrate = codec.clockrate; + + // PayloadType parameter + auto cps = codec.ToCodecParameters(); + for (auto& it : cps.parameters) { + gloox::Jingle::RTP::Parameter parameter; + parameter.name = it.first; + parameter.value = it.second; + type.parameters.emplace_back(parameter); + } + + // rtcp-fb + for (auto& it : codec.feedback_params.params()) { + gloox::Jingle::RTP::Feedback fb = {it.id(), it.param()}; + type.feedbacks.push_back(fb); + } + + oContent.rtp.payloadTypes.emplace_back(type); + } + break; + } + case ::cricket::MediaType::MEDIA_TYPE_DATA: { + break; + } + case cricket::MEDIA_TYPE_UNSUPPORTED: + break; } - oContent.rtp.payloadTypes.emplace_back(type); - } - break; - } - case ::cricket::MediaType::MEDIA_TYPE_DATA: { - break; - } - case cricket::MEDIA_TYPE_UNSUPPORTED: - break; + osdp.contents.push_back(oContent); } - osdp.contents.push_back(oContent); - } - - return osdp; + return osdp; } -void Conductor::OnSuccess() { - RTC_LOG(LS_INFO) << __FUNCTION__; -} +void Conductor::OnSuccess() { RTC_LOG(LS_INFO) << __FUNCTION__; } -void Conductor::OnSuccess(webrtc::SessionDescriptionInterface *desc) { - RTC_LOG(LS_INFO) << __FUNCTION__; +void Conductor::OnSuccess(webrtc::SessionDescriptionInterface* desc) { + RTC_LOG(LS_INFO) << __FUNCTION__; - std::string sdp; - desc->ToString(&sdp); + std::string sdp; + desc->ToString(&sdp); - RTC_LOG(LS_INFO) << "sdp:" << sdp; - peer_connection_->SetLocalDescription(this, desc); + RTC_LOG(LS_INFO) << "sdp:" << sdp; + peer_connection_->SetLocalDescription(this, desc); - if(webRtc->getHandler()){ - auto osdp = webRtc->convertFromSdp(desc); - webRtc->getHandler()->onRTP(sId, peerId, osdp); - } + if (webRtc->getHandler()) { + auto osdp = webRtc->convertFromSdp(desc); + webRtc->getHandler()->onRTP(sId, peerId, osdp); + } } void Conductor::OnFailure(webrtc::RTCError error) { - RTC_LOG(LS_INFO) << __FUNCTION__ << error.message(); + RTC_LOG(LS_INFO) << __FUNCTION__ << error.message(); } void Conductor::OnSetRemoteDescriptionComplete(webrtc::RTCError error) { - RTC_LOG(LS_INFO) << __FUNCTION__ <<" : " << error.message(); + RTC_LOG(LS_INFO) << __FUNCTION__ << " : " << error.message(); } void Conductor::OnConnectionChange(webrtc::PeerConnectionInterface::PeerConnectionState new_state) { - RTC_LOG(LS_INFO) << __FUNCTION__ <<" : " << webrtc::PeerConnectionInterface::AsString(new_state).data(); + RTC_LOG(LS_INFO) << __FUNCTION__ << " : " + << webrtc::PeerConnectionInterface::AsString(new_state).data(); } -void Conductor::OnSessionAccept( - std::unique_ptr desc) { - // qDebug(("type:%1").arg(qstring(desc->type()))); - SetRemoteDescription(std::move(desc)); +void Conductor::OnSessionAccept(std::unique_ptr desc) { + // qDebug(("type:%1").arg(qstring(desc->type()))); + SetRemoteDescription(std::move(desc)); } -} // namespace ortc -} // namespace lib +} // namespace ortc +} // namespace lib diff --git a/src/lib/ortc/webrtc/ok_conductor.h b/src/lib/ortc/webrtc/ok_conductor.h index faf70e0a..3218a62d 100644 --- a/src/lib/ortc/webrtc/ok_conductor.h +++ b/src/lib/ortc/webrtc/ok_conductor.h @@ -41,139 +41,123 @@ namespace ortc { class Conductor : public webrtc::PeerConnectionObserver, public webrtc::CreateSessionDescriptionObserver, public webrtc::SetSessionDescriptionObserver, - public webrtc::SetRemoteDescriptionObserverInterface -{ + public webrtc::SetRemoteDescriptionObserverInterface { public: - Conductor(WebRTC* webrtc, const std::string &peerId_, const std::string &sId); + Conductor(WebRTC* webrtc, const std::string& peerId_, const std::string& sId); - ~Conductor() ; + ~Conductor(); - void CreateAnswer(); + void CreateAnswer(); - void CreateOffer(); + void CreateOffer(); - void sessionTerminate(); + void sessionTerminate(); - void setTransportInfo(std::unique_ptr candidate); + void setTransportInfo(std::unique_ptr candidate); - virtual void OnContentAdd(std::map sdMap, ortc::OkRTCHandler *handler); + virtual void OnContentAdd(std::map sdMap, + ortc::OkRTCHandler* handler); - virtual void OnContentRemove(std::map sdMap, - ortc::OkRTCHandler *handler); + virtual void OnContentRemove(std::map sdMap, + ortc::OkRTCHandler* handler); - virtual void OnSessionTerminate(const std::string &sid, - ortc::OkRTCHandler *handler); + virtual void OnSessionTerminate(const std::string& sid, ortc::OkRTCHandler* handler); + void SetRemoteDescription(std::unique_ptr desc); - void SetRemoteDescription( - std::unique_ptr desc); + void setMute(bool mute); + void setRemoteMute(bool mute); - void setMute(bool mute); - void setRemoteMute(bool mute); + inline ortc::JoinOptions joinOptions() { return _joinOptions; } - inline ortc::JoinOptions joinOptions() { return _joinOptions; } + size_t getVideoCaptureSize(); - size_t getVideoCaptureSize(); + OJingleContentAv toJingleSdp(const webrtc::SessionDescriptionInterface* desc); - OJingleContentAv toJingleSdp(const webrtc::SessionDescriptionInterface *desc); + virtual void AddRef() const override {}; + virtual rtc::RefCountReleaseStatus Release() const override { + return rtc::RefCountReleaseStatus::kDroppedLastRef; + }; - virtual void AddRef() const override {}; - virtual rtc::RefCountReleaseStatus Release() const override { - return rtc::RefCountReleaseStatus::kDroppedLastRef; - }; - - void OnSessionAccept(std::unique_ptr desc); - - bool AddAudioTrack(webrtc::AudioSourceInterface* _audioSource); - bool RemoveAudioTrack(); - - bool AddVideoTrack(webrtc::VideoTrackSourceInterface* _videoTrackSource); - bool RemoveVideoTrack(); + void OnSessionAccept(std::unique_ptr desc); + bool AddAudioTrack(webrtc::AudioSourceInterface* _audioSource); + bool RemoveAudioTrack(); + bool AddVideoTrack(webrtc::VideoTrackSourceInterface* _videoTrackSource); + bool RemoveVideoTrack(); protected: - void CreatePeerConnection(); - void DestroyPeerConnection(); - - // - // PeerConnectionObserver implementation. - // - void OnSignalingChange( - webrtc::PeerConnectionInterface::SignalingState state) override; - - void OnConnectionChange( - webrtc::PeerConnectionInterface::PeerConnectionState new_state) override; - - void - OnAddTrack(rtc::scoped_refptr receiver, - const std::vector> - &streams) override; - void OnTrack(rtc::scoped_refptr transceiver) override; - void OnRemoveTrack( - rtc::scoped_refptr receiver) override; - void OnDataChannel( - rtc::scoped_refptr channel) override; - void OnRenegotiationNeeded() override; - void OnIceConnectionChange( - webrtc::PeerConnectionInterface::IceConnectionState state) override; - void OnIceGatheringChange( - webrtc::PeerConnectionInterface::IceGatheringState state) override; - void OnIceCandidate(const webrtc::IceCandidateInterface *ice) override; - void OnIceConnectionReceivingChange(bool receiving) override; - void OnSetRemoteDescriptionComplete(webrtc::RTCError error) override; - - /** - * SetSessionDescriptionObserver - * implementation. - * - */ - void OnSuccess() override; - - /** - * CreateSessionDescriptionObserver - * @param desc - */ - virtual void OnSuccess(webrtc::SessionDescriptionInterface *desc) override; - - /** - * CreateSessionDescriptionObserver and SetSessionDescriptionObserver - * @param error - */ - virtual void OnFailure(webrtc::RTCError error) override; - - virtual bool started() const { return _started; } + void CreatePeerConnection(); + void DestroyPeerConnection(); + + // + // PeerConnectionObserver implementation. + // + void OnSignalingChange(webrtc::PeerConnectionInterface::SignalingState state) override; + + void OnConnectionChange( + webrtc::PeerConnectionInterface::PeerConnectionState new_state) override; + + void OnAddTrack( + rtc::scoped_refptr receiver, + const std::vector>& streams) override; + void OnTrack(rtc::scoped_refptr transceiver) override; + void OnRemoveTrack(rtc::scoped_refptr receiver) override; + void OnDataChannel(rtc::scoped_refptr channel) override; + void OnRenegotiationNeeded() override; + void OnIceConnectionChange(webrtc::PeerConnectionInterface::IceConnectionState state) override; + void OnIceGatheringChange(webrtc::PeerConnectionInterface::IceGatheringState state) override; + void OnIceCandidate(const webrtc::IceCandidateInterface* ice) override; + void OnIceConnectionReceivingChange(bool receiving) override; + void OnSetRemoteDescriptionComplete(webrtc::RTCError error) override; + + /** + * SetSessionDescriptionObserver + * implementation. + * + */ + void OnSuccess() override; + + /** + * CreateSessionDescriptionObserver + * @param desc + */ + virtual void OnSuccess(webrtc::SessionDescriptionInterface* desc) override; + + /** + * CreateSessionDescriptionObserver and SetSessionDescriptionObserver + * @param error + */ + virtual void OnFailure(webrtc::RTCError error) override; + + virtual bool started() const { return _started; } private: + bool _started = false; + std::mutex _session_mutex; - bool _started = false; - std::mutex _session_mutex; - - - std::string peerId; - std::string sId; - - - - WebRTC * webRtc; + std::string peerId; + std::string sId; - ortc::JoinOptions _joinOptions; + WebRTC* webRtc; - rtc::scoped_refptr peer_connection_; + ortc::JoinOptions _joinOptions; + rtc::scoped_refptr peer_connection_; - std::unique_ptr _videoSink; + std::unique_ptr _videoSink; - rtc::scoped_refptr _audioTrack; - rtc::scoped_refptr _videoTrack; + rtc::scoped_refptr _audioTrack; + rtc::scoped_refptr _videoTrack; - webrtc::AudioTrackInterface * _remote_audio_track; - webrtc::VideoTrackInterface * _remote_video_track; + webrtc::AudioTrackInterface* _remote_audio_track; + webrtc::VideoTrackInterface* _remote_video_track; - rtc::scoped_refptr _audioRtpSender; - rtc::scoped_refptr _videoRtpSender; -// rtc::scoped_refptr _videoTrackSource; + rtc::scoped_refptr _audioRtpSender; + rtc::scoped_refptr _videoRtpSender; + // rtc::scoped_refptr _videoTrackSource; }; -} // namespace ortc -} // namespace lib +} // namespace ortc +} // namespace lib diff --git a/src/lib/ortc/webrtc/ok_video_sink.cpp b/src/lib/ortc/webrtc/ok_video_sink.cpp index 3a05fd0d..3dacb0e5 100644 --- a/src/lib/ortc/webrtc/ok_video_sink.cpp +++ b/src/lib/ortc/webrtc/ok_video_sink.cpp @@ -20,61 +20,67 @@ namespace lib { namespace ortc { -VideoSink::VideoSink(OkRTCHandler *handler, std::string peerId) : handler(handler), _peer_id(std::move(peerId)) { RTC_DCHECK(handler); } +VideoSink::VideoSink(OkRTCHandler* handler, std::string peerId) + : handler(handler), _peer_id(std::move(peerId)) { + RTC_DCHECK(handler); +} VideoSink::~VideoSink() {} -void VideoSink::OnFrame(const webrtc::VideoFrame &frame) { - bool conv = false; - ortc::RendererImage _image{}; +void VideoSink::OnFrame(const webrtc::VideoFrame& frame) { + bool conv = false; + ortc::RendererImage _image{}; - auto v_buffer = frame.video_frame_buffer(); - switch (v_buffer->type()) { - case webrtc::VideoFrameBuffer::Type::kI420: { - auto i420 = v_buffer->GetI420(); - if (frame.rotation() != webrtc::kVideoRotation_0) { - webrtc::VideoFrame rotated_frame = webrtc::VideoFrame::Builder() - .set_video_frame_buffer(webrtc::I420Buffer::Rotate(*v_buffer, frame.rotation())) - .set_rotation(webrtc::kVideoRotation_0) - .set_timestamp_us(frame.timestamp_us()) - .set_id(frame.id()) - .build(); - auto i420_ = rotated_frame.video_frame_buffer()->GetI420(); - _image.width_ = static_cast(i420_->width()); - _image.height_ = static_cast(i420_->height()); - _image.y = const_cast(i420_->DataY()); - _image.u = const_cast(i420_->DataU()); - _image.v = const_cast(i420_->DataV()); - _image.ystride = i420_->StrideY(); - _image.ustride = i420_->StrideU(); - _image.vstride = i420_->StrideV(); - } else { - _image.width_ = static_cast(i420->width()); - _image.height_ = static_cast(i420->height()); - _image.y = const_cast(i420->DataY()); - _image.u = const_cast(i420->DataU()); - _image.v = const_cast(i420->DataV()); - _image.ystride = i420->StrideY(); - _image.ustride = i420->StrideU(); - _image.vstride = i420->StrideV(); + auto v_buffer = frame.video_frame_buffer(); + switch (v_buffer->type()) { + case webrtc::VideoFrameBuffer::Type::kI420: { + auto i420 = v_buffer->GetI420(); + if (frame.rotation() != webrtc::kVideoRotation_0) { + webrtc::VideoFrame rotated_frame = + webrtc::VideoFrame::Builder() + .set_video_frame_buffer( + webrtc::I420Buffer::Rotate(*v_buffer, frame.rotation())) + .set_rotation(webrtc::kVideoRotation_0) + .set_timestamp_us(frame.timestamp_us()) + .set_id(frame.id()) + .build(); + auto i420_ = rotated_frame.video_frame_buffer()->GetI420(); + _image.width_ = static_cast(i420_->width()); + _image.height_ = static_cast(i420_->height()); + _image.y = const_cast(i420_->DataY()); + _image.u = const_cast(i420_->DataU()); + _image.v = const_cast(i420_->DataV()); + _image.ystride = i420_->StrideY(); + _image.ustride = i420_->StrideU(); + _image.vstride = i420_->StrideV(); + } else { + _image.width_ = static_cast(i420->width()); + _image.height_ = static_cast(i420->height()); + _image.y = const_cast(i420->DataY()); + _image.u = const_cast(i420->DataU()); + _image.v = const_cast(i420->DataV()); + _image.ystride = i420->StrideY(); + _image.ustride = i420->StrideU(); + _image.vstride = i420->StrideV(); + } + } + conv = true; + break; + default: + RTC_LOG(LS_WARNING) << "Not supported frame type: " + << webrtc::VideoFrameBufferTypeToString(v_buffer->type()); + break; } - } - conv = true; - break; - default: - RTC_LOG(LS_WARNING) << "Not supported frame type: " << webrtc::VideoFrameBufferTypeToString(v_buffer->type()); - break; - } - if (!conv) { - return; - } + if (!conv) { + return; + } - handler->onRender(_peer_id, _image); + handler->onRender(_peer_id, _image); - // 渲染次数计数 - _renderCount++; + // 渲染次数计数 + _renderCount++; } -} // namespace ortc -} // namespace lib +} // namespace ortc +} // namespace lib diff --git a/src/lib/ortc/webrtc/ok_video_sink.h b/src/lib/ortc/webrtc/ok_video_sink.h index a01d4a0d..6c8409fe 100644 --- a/src/lib/ortc/webrtc/ok_video_sink.h +++ b/src/lib/ortc/webrtc/ok_video_sink.h @@ -12,29 +12,28 @@ #pragma once - -#include "../ok_rtc_renderer.h" -#include -#include -#include #include +#include +#include +#include +#include "../ok_rtc_renderer.h" namespace lib { namespace ortc { class VideoSink : public rtc::VideoSinkInterface { public: - VideoSink(OkRTCHandler *handler, std::string peerId = {}); + VideoSink(OkRTCHandler* handler, std::string peerId = {}); - virtual ~VideoSink() override; + virtual ~VideoSink() override; - virtual void OnFrame(const webrtc::VideoFrame &frame) override; + virtual void OnFrame(const webrtc::VideoFrame& frame) override; private: - uint64_t _renderCount; - std::string _peer_id; - OkRTCHandler *handler; + uint64_t _renderCount; + std::string _peer_id; + OkRTCHandler* handler; }; -} // namespace ortc -} // namespace lib +} // namespace ortc +} // namespace lib diff --git a/src/lib/ortc/webrtc/platform/PlatformContext.h b/src/lib/ortc/webrtc/platform/PlatformContext.h index 8f70a474..96f9720a 100644 --- a/src/lib/ortc/webrtc/platform/PlatformContext.h +++ b/src/lib/ortc/webrtc/platform/PlatformContext.h @@ -4,12 +4,10 @@ namespace lib::ortc { class PlatformContext { - public: virtual ~PlatformContext() = default; - }; -} // namespace lib::ortc +} // namespace lib::ortc #endif diff --git a/src/lib/ortc/webrtc/platform/PlatformInterface.h b/src/lib/ortc/webrtc/platform/PlatformInterface.h index 5d638425..9e5cf7f3 100644 --- a/src/lib/ortc/webrtc/platform/PlatformInterface.h +++ b/src/lib/ortc/webrtc/platform/PlatformInterface.h @@ -1,15 +1,15 @@ #ifndef ORTC_PLATFORM_INTERFACE_H #define ORTC_PLATFORM_INTERFACE_H -#include "rtc_base/thread.h" -#include "api/video_codecs/video_encoder_factory.h" -#include "api/video_codecs/video_decoder_factory.h" +#include +#include #include "api/media_stream_interface.h" -#include "rtc_base/network_monitor_factory.h" +#include "api/video_codecs/video_decoder_factory.h" +#include "api/video_codecs/video_encoder_factory.h" #include "modules/audio_device/include/audio_device.h" +#include "rtc_base/network_monitor_factory.h" #include "rtc_base/ref_counted_object.h" -#include -#include +#include "rtc_base/thread.h" namespace lib::ortc { @@ -30,49 +30,38 @@ class WrappedAudioDeviceModule : public webrtc::AudioDeviceModule { class DefaultWrappedAudioDeviceModule : public WrappedAudioDeviceModule { public: - DefaultWrappedAudioDeviceModule(rtc::scoped_refptr impl) : - _impl(impl) { - } + DefaultWrappedAudioDeviceModule(rtc::scoped_refptr impl) + : _impl(impl) {} - virtual ~DefaultWrappedAudioDeviceModule() { - } + virtual ~DefaultWrappedAudioDeviceModule() {} - virtual void Stop() override { - } + virtual void Stop() override {} - virtual int32_t ActiveAudioLayer(AudioLayer *audioLayer) const override { + virtual int32_t ActiveAudioLayer(AudioLayer* audioLayer) const override { return _impl->ActiveAudioLayer(audioLayer); } - virtual int32_t RegisterAudioCallback(webrtc::AudioTransport *audioCallback) override { + virtual int32_t RegisterAudioCallback(webrtc::AudioTransport* audioCallback) override { return _impl->RegisterAudioCallback(audioCallback); } - virtual int32_t Init() override { - return _impl->Init(); - } + virtual int32_t Init() override { return _impl->Init(); } - virtual int32_t Terminate() override { - return _impl->Terminate(); - } + virtual int32_t Terminate() override { return _impl->Terminate(); } - virtual bool Initialized() const override { - return _impl->Initialized(); - } + virtual bool Initialized() const override { return _impl->Initialized(); } - virtual int16_t PlayoutDevices() override { - return _impl->PlayoutDevices(); - } + virtual int16_t PlayoutDevices() override { return _impl->PlayoutDevices(); } - virtual int16_t RecordingDevices() override { - return _impl->RecordingDevices(); - } + virtual int16_t RecordingDevices() override { return _impl->RecordingDevices(); } - virtual int32_t PlayoutDeviceName(uint16_t index, char name[webrtc::kAdmMaxDeviceNameSize], char guid[webrtc::kAdmMaxGuidSize]) override { + virtual int32_t PlayoutDeviceName(uint16_t index, char name[webrtc::kAdmMaxDeviceNameSize], + char guid[webrtc::kAdmMaxGuidSize]) override { return _impl->PlayoutDeviceName(index, name, guid); } - virtual int32_t RecordingDeviceName(uint16_t index, char name[webrtc::kAdmMaxDeviceNameSize], char guid[webrtc::kAdmMaxGuidSize]) override { + virtual int32_t RecordingDeviceName(uint16_t index, char name[webrtc::kAdmMaxDeviceNameSize], + char guid[webrtc::kAdmMaxGuidSize]) override { return _impl->RecordingDeviceName(index, name, guid); } @@ -92,71 +81,45 @@ class DefaultWrappedAudioDeviceModule : public WrappedAudioDeviceModule { return _impl->SetRecordingDevice(device); } - virtual int32_t PlayoutIsAvailable(bool *available) override { + virtual int32_t PlayoutIsAvailable(bool* available) override { return _impl->PlayoutIsAvailable(available); } - virtual int32_t InitPlayout() override { - return _impl->InitPlayout(); - } + virtual int32_t InitPlayout() override { return _impl->InitPlayout(); } - virtual bool PlayoutIsInitialized() const override { - return _impl->PlayoutIsInitialized(); - } + virtual bool PlayoutIsInitialized() const override { return _impl->PlayoutIsInitialized(); } - virtual int32_t RecordingIsAvailable(bool *available) override { + virtual int32_t RecordingIsAvailable(bool* available) override { return _impl->RecordingIsAvailable(available); } - virtual int32_t InitRecording() override { - return _impl->InitRecording(); - } + virtual int32_t InitRecording() override { return _impl->InitRecording(); } - virtual bool RecordingIsInitialized() const override { - return _impl->RecordingIsInitialized(); - } + virtual bool RecordingIsInitialized() const override { return _impl->RecordingIsInitialized(); } - virtual int32_t StartPlayout() override { - return _impl->StartPlayout(); - } + virtual int32_t StartPlayout() override { return _impl->StartPlayout(); } - virtual int32_t StopPlayout() override { - return _impl->StopPlayout(); - } + virtual int32_t StopPlayout() override { return _impl->StopPlayout(); } - virtual bool Playing() const override { - return _impl->Playing(); - } + virtual bool Playing() const override { return _impl->Playing(); } - virtual int32_t StartRecording() override { - return _impl->StartRecording(); - } + virtual int32_t StartRecording() override { return _impl->StartRecording(); } - virtual int32_t StopRecording() override { - return _impl->StopRecording(); - } + virtual int32_t StopRecording() override { return _impl->StopRecording(); } - virtual bool Recording() const override { - return _impl->Recording(); - } + virtual bool Recording() const override { return _impl->Recording(); } - virtual int32_t InitSpeaker() override { - return _impl->InitSpeaker(); - } + virtual int32_t InitSpeaker() override { return _impl->InitSpeaker(); } - virtual bool SpeakerIsInitialized() const override { - return _impl->SpeakerIsInitialized(); - } + virtual bool SpeakerIsInitialized() const override { return _impl->SpeakerIsInitialized(); } - virtual int32_t InitMicrophone() override { - return _impl->InitMicrophone(); - } + virtual int32_t InitMicrophone() override { return _impl->InitMicrophone(); } virtual bool MicrophoneIsInitialized() const override { return _impl->MicrophoneIsInitialized(); } - virtual int32_t SpeakerVolumeIsAvailable(bool *available) override { + virtual int32_t SpeakerVolumeIsAvailable(bool* available) override { return _impl->SpeakerVolumeIsAvailable(available); } @@ -168,15 +131,15 @@ class DefaultWrappedAudioDeviceModule : public WrappedAudioDeviceModule { return _impl->SpeakerVolume(volume); } - virtual int32_t MaxSpeakerVolume(uint32_t *maxVolume) const override { + virtual int32_t MaxSpeakerVolume(uint32_t* maxVolume) const override { return _impl->MaxSpeakerVolume(maxVolume); } - virtual int32_t MinSpeakerVolume(uint32_t *minVolume) const override { + virtual int32_t MinSpeakerVolume(uint32_t* minVolume) const override { return _impl->MinSpeakerVolume(minVolume); } - virtual int32_t MicrophoneVolumeIsAvailable(bool *available) override { + virtual int32_t MicrophoneVolumeIsAvailable(bool* available) override { return _impl->MicrophoneVolumeIsAvailable(available); } @@ -184,31 +147,29 @@ class DefaultWrappedAudioDeviceModule : public WrappedAudioDeviceModule { return _impl->SetMicrophoneVolume(volume); } - virtual int32_t MicrophoneVolume(uint32_t *volume) const override { + virtual int32_t MicrophoneVolume(uint32_t* volume) const override { return _impl->MicrophoneVolume(volume); } - virtual int32_t MaxMicrophoneVolume(uint32_t *maxVolume) const override { + virtual int32_t MaxMicrophoneVolume(uint32_t* maxVolume) const override { return _impl->MaxMicrophoneVolume(maxVolume); } - virtual int32_t MinMicrophoneVolume(uint32_t *minVolume) const override { + virtual int32_t MinMicrophoneVolume(uint32_t* minVolume) const override { return _impl->MinMicrophoneVolume(minVolume); } - virtual int32_t SpeakerMuteIsAvailable(bool *available) override { + virtual int32_t SpeakerMuteIsAvailable(bool* available) override { return _impl->SpeakerMuteIsAvailable(available); } - virtual int32_t SetSpeakerMute(bool enable) override { - return _impl->SetSpeakerMute(enable); - } + virtual int32_t SetSpeakerMute(bool enable) override { return _impl->SetSpeakerMute(enable); } - virtual int32_t SpeakerMute(bool *enabled) const override { + virtual int32_t SpeakerMute(bool* enabled) const override { return _impl->SpeakerMute(enabled); } - virtual int32_t MicrophoneMuteIsAvailable(bool *available) override { + virtual int32_t MicrophoneMuteIsAvailable(bool* available) override { return _impl->MicrophoneMuteIsAvailable(available); } @@ -216,11 +177,11 @@ class DefaultWrappedAudioDeviceModule : public WrappedAudioDeviceModule { return _impl->SetMicrophoneMute(enable); } - virtual int32_t MicrophoneMute(bool *enabled) const override { + virtual int32_t MicrophoneMute(bool* enabled) const override { return _impl->MicrophoneMute(enabled); } - virtual int32_t StereoPlayoutIsAvailable(bool *available) const override { + virtual int32_t StereoPlayoutIsAvailable(bool* available) const override { return _impl->StereoPlayoutIsAvailable(available); } @@ -228,11 +189,11 @@ class DefaultWrappedAudioDeviceModule : public WrappedAudioDeviceModule { return _impl->SetStereoPlayout(enable); } - virtual int32_t StereoPlayout(bool *enabled) const override { + virtual int32_t StereoPlayout(bool* enabled) const override { return _impl->StereoPlayout(enabled); } - virtual int32_t StereoRecordingIsAvailable(bool *available) const override { + virtual int32_t StereoRecordingIsAvailable(bool* available) const override { return _impl->StereoRecordingIsAvailable(available); } @@ -240,7 +201,7 @@ class DefaultWrappedAudioDeviceModule : public WrappedAudioDeviceModule { return _impl->SetStereoRecording(enable); } - virtual int32_t StereoRecording(bool *enabled) const override { + virtual int32_t StereoRecording(bool* enabled) const override { return _impl->StereoRecording(enabled); } @@ -248,17 +209,11 @@ class DefaultWrappedAudioDeviceModule : public WrappedAudioDeviceModule { return _impl->PlayoutDelay(delayMS); } - virtual bool BuiltInAECIsAvailable() const override { - return _impl->BuiltInAECIsAvailable(); - } + virtual bool BuiltInAECIsAvailable() const override { return _impl->BuiltInAECIsAvailable(); } - virtual bool BuiltInAGCIsAvailable() const override { - return _impl->BuiltInAGCIsAvailable(); - } + virtual bool BuiltInAGCIsAvailable() const override { return _impl->BuiltInAGCIsAvailable(); } - virtual bool BuiltInNSIsAvailable() const override { - return _impl->BuiltInNSIsAvailable(); - } + virtual bool BuiltInNSIsAvailable() const override { return _impl->BuiltInNSIsAvailable(); } virtual int32_t EnableBuiltInAEC(bool enable) override { return _impl->EnableBuiltInAEC(enable); @@ -268,26 +223,22 @@ class DefaultWrappedAudioDeviceModule : public WrappedAudioDeviceModule { return _impl->EnableBuiltInAGC(enable); } - virtual int32_t EnableBuiltInNS(bool enable) override { - return _impl->EnableBuiltInNS(enable); - } + virtual int32_t EnableBuiltInNS(bool enable) override { return _impl->EnableBuiltInNS(enable); } virtual int32_t GetPlayoutUnderrunCount() const override { return _impl->GetPlayoutUnderrunCount(); } #if defined(WEBRTC_IOS) - virtual int GetPlayoutAudioParameters(webrtc::AudioParameters *params) const override { + virtual int GetPlayoutAudioParameters(webrtc::AudioParameters* params) const override { return _impl->GetPlayoutAudioParameters(params); } - virtual int GetRecordAudioParameters(webrtc::AudioParameters *params) const override { + virtual int GetRecordAudioParameters(webrtc::AudioParameters* params) const override { return _impl->GetRecordAudioParameters(params); } #endif // WEBRTC_IOS - rtc::scoped_refptr WrappedInstance() { - return _impl; - } + rtc::scoped_refptr WrappedInstance() { return _impl; } private: rtc::scoped_refptr _impl; @@ -295,23 +246,29 @@ class DefaultWrappedAudioDeviceModule : public WrappedAudioDeviceModule { class PlatformInterface { public: - static PlatformInterface *SharedInstance(); - virtual ~PlatformInterface() = default; + static PlatformInterface* SharedInstance(); + virtual ~PlatformInterface() = default; - virtual void configurePlatformAudio() { - } + virtual void configurePlatformAudio() {} virtual std::unique_ptr createNetworkMonitorFactory() { return nullptr; } - - virtual std::unique_ptr makeVideoEncoderFactory(bool preferHardwareEncoding = false, bool isScreencast = false) = 0; - virtual std::unique_ptr makeVideoDecoderFactory() = 0; - virtual bool supportsEncoding(const std::string &codecName) = 0; - virtual rtc::scoped_refptr makeVideoSource(rtc::Thread *signalingThread, rtc::Thread *workerThread) = 0; - virtual void adaptVideoSource(rtc::scoped_refptr videoSource, int width, int height, int fps) = 0; - virtual std::unique_ptr makeVideoCapturer(rtc::scoped_refptr source, std::string deviceId, std::function stateUpdated, std::function captureInfoUpdated, std::shared_ptr platformContext, std::pair &outResolution) = 0; + virtual std::unique_ptr makeVideoEncoderFactory( + bool preferHardwareEncoding = false, bool isScreencast = false) = 0; + virtual std::unique_ptr makeVideoDecoderFactory() = 0; + virtual bool supportsEncoding(const std::string& codecName) = 0; + virtual rtc::scoped_refptr makeVideoSource( + rtc::Thread* signalingThread, rtc::Thread* workerThread) = 0; + virtual void adaptVideoSource(rtc::scoped_refptr videoSource, + int width, int height, int fps) = 0; + virtual std::unique_ptr makeVideoCapturer( + rtc::scoped_refptr source, std::string deviceId, + std::function stateUpdated, + std::function captureInfoUpdated, + std::shared_ptr platformContext, + std::pair& outResolution) = 0; public: bool preferX264 = false; @@ -319,11 +276,11 @@ class PlatformInterface { std::unique_ptr CreatePlatformInterface(); -inline PlatformInterface *PlatformInterface::SharedInstance() { - static const auto result = CreatePlatformInterface(); - return result.get(); +inline PlatformInterface* PlatformInterface::SharedInstance() { + static const auto result = CreatePlatformInterface(); + return result.get(); } -} // namespace lib::ortc +} // namespace lib::ortc #endif diff --git a/src/lib/ortc/webrtc/platform/desktop_capturer/DesktopCaptureSource.cpp b/src/lib/ortc/webrtc/platform/desktop_capturer/DesktopCaptureSource.cpp index 0b10950a..126895fb 100644 --- a/src/lib/ortc/webrtc/platform/desktop_capturer/DesktopCaptureSource.cpp +++ b/src/lib/ortc/webrtc/platform/desktop_capturer/DesktopCaptureSource.cpp @@ -1,14 +1,14 @@ /* -* Copyright (c) 2022 船山信息 chuanshaninfo.com -* The project is licensed under Mulan PubL v2. -* You can use this software according to the terms and conditions of the Mulan -* PubL v2. You may obtain a copy of Mulan PubL v2 at: -* http://license.coscl.org.cn/MulanPubL-2.0 -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -* See the Mulan PubL v2 for more details. -*/ + * Copyright (c) 2022 船山信息 chuanshaninfo.com + * The project is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan + * PubL v2. You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ #include "DesktopCaptureSource.h" #include @@ -16,46 +16,26 @@ namespace lib::ortc { std::string DesktopCaptureSourceData::cachedKey() const { - return std::to_string(aspectSize.width) - + 'x' - + std::to_string(aspectSize.height) - + ':' - + std::to_string(fps) - + ':' - + (captureMouse ? '1' : '0'); + return std::to_string(aspectSize.width) + 'x' + std::to_string(aspectSize.height) + ':' + + std::to_string(fps) + ':' + (captureMouse ? '1' : '0'); } -DesktopCaptureSource::DesktopCaptureSource( - long long uniqueId, - std::string title, - bool isWindow) -: _uniqueId(uniqueId) -, _title(std::move(title)) -, _isWindow(isWindow) { -} +DesktopCaptureSource::DesktopCaptureSource(long long uniqueId, std::string title, bool isWindow) + : _uniqueId(uniqueId), _title(std::move(title)), _isWindow(isWindow) {} -long long DesktopCaptureSource::uniqueId() const { - return _uniqueId; -} +long long DesktopCaptureSource::uniqueId() const { return _uniqueId; } -bool DesktopCaptureSource::isWindow() const { - return _isWindow; -} +bool DesktopCaptureSource::isWindow() const { return _isWindow; } std::string DesktopCaptureSource::deviceIdKey() const { - return std::string("desktop_capturer_") - + (_isWindow ? "window_" : "screen_") - + std::to_string(uniqueId()); + return std::string("desktop_capturer_") + (_isWindow ? "window_" : "screen_") + + std::to_string(uniqueId()); } -std::string DesktopCaptureSource::title() const { - return _isWindow ? _title : "Screen"; -} +std::string DesktopCaptureSource::title() const { return _isWindow ? _title : "Screen"; } std::string DesktopCaptureSource::uniqueKey() const { - return std::to_string(_uniqueId) - + ':' - + (_isWindow ? "Window" : "Screen"); + return std::to_string(_uniqueId) + ':' + (_isWindow ? "Window" : "Screen"); } std::string DesktopCaptureSource::deviceIdKey() { @@ -63,11 +43,11 @@ std::string DesktopCaptureSource::deviceIdKey() { } std::string DesktopCaptureSource::title() { - return static_cast(this)->title(); + return static_cast(this)->title(); } std::string DesktopCaptureSource::uniqueKey() { - return static_cast(this)->uniqueKey(); + return static_cast(this)->uniqueKey(); } -} // namespace lib::ortc +} // namespace lib::ortc diff --git a/src/lib/ortc/webrtc/platform/desktop_capturer/DesktopCaptureSource.h b/src/lib/ortc/webrtc/platform/desktop_capturer/DesktopCaptureSource.h index 70adb1f1..4fa040fa 100644 --- a/src/lib/ortc/webrtc/platform/desktop_capturer/DesktopCaptureSource.h +++ b/src/lib/ortc/webrtc/platform/desktop_capturer/DesktopCaptureSource.h @@ -1,14 +1,14 @@ /* -* Copyright (c) 2022 船山信息 chuanshaninfo.com -* The project is licensed under Mulan PubL v2. -* You can use this software according to the terms and conditions of the Mulan -* PubL v2. You may obtain a copy of Mulan PubL v2 at: -* http://license.coscl.org.cn/MulanPubL-2.0 -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -* See the Mulan PubL v2 for more details. -*/ + * Copyright (c) 2022 船山信息 chuanshaninfo.com + * The project is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan + * PubL v2. You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ #ifndef OkMSG_DESKTOP_CAPTURE_SOURCE_H__ #define OkMSG_DESKTOP_CAPTURE_SOURCE_H__ @@ -18,73 +18,62 @@ #ifdef WEBRTC_WIN // Compiler errors in conflicting Windows headers if not included here. #include -#endif // WEBRTC_WIN +#endif // WEBRTC_WIN namespace lib::ortc { class VideoSource { public: - virtual ~VideoSource() = default; + virtual ~VideoSource() = default; - virtual std::string deviceIdKey() = 0; - virtual std::string title() = 0; - virtual std::string uniqueKey() = 0; + virtual std::string deviceIdKey() = 0; + virtual std::string title() = 0; + virtual std::string uniqueKey() = 0; }; struct DesktopSize { - int width = 0; - int height = 0; + int width = 0; + int height = 0; }; struct DesktopCaptureSourceData { - DesktopSize aspectSize; - double fps = 24.; - bool captureMouse = true; + DesktopSize aspectSize; + double fps = 24.; + bool captureMouse = true; - std::string cachedKey() const; + std::string cachedKey() const; }; class DesktopCaptureSource : public VideoSource { public: - DesktopCaptureSource( - long long uniqueId, - std::string title, - bool isWindow); + DesktopCaptureSource(long long uniqueId, std::string title, bool isWindow); - static DesktopCaptureSource Invalid() { - return InvalidTag{}; - } + static DesktopCaptureSource Invalid() { return InvalidTag{}; } - long long uniqueId() const; - bool isWindow() const; + long long uniqueId() const; + bool isWindow() const; - std::string deviceIdKey() const; - std::string title() const; - std::string uniqueKey() const; + std::string deviceIdKey() const; + std::string title() const; + std::string uniqueKey() const; - bool valid() const { - return _valid; - } - explicit operator bool() const { - return _valid; - } + bool valid() const { return _valid; } + explicit operator bool() const { return _valid; } private: - struct InvalidTag {}; - DesktopCaptureSource(InvalidTag) : _valid(false) { - } + struct InvalidTag {}; + DesktopCaptureSource(InvalidTag) : _valid(false) {} - std::string deviceIdKey() override; - std::string title() override; - std::string uniqueKey() override; - - long long _uniqueId = 0; - std::string _title; - bool _isWindow = false; - bool _valid = true; + std::string deviceIdKey() override; + std::string title() override; + std::string uniqueKey() override; + long long _uniqueId = 0; + std::string _title; + bool _isWindow = false; + bool _valid = true; }; -} // namespace lib::ortc +} // namespace lib::ortc -#endif // TGCALLS_DESKTOP_CAPTURE_SOURCE_H__ +#endif // TGCALLS_DESKTOP_CAPTURE_SOURCE_H__ diff --git a/src/lib/ortc/webrtc/platform/desktop_capturer/DesktopCaptureSourceHelper.cpp b/src/lib/ortc/webrtc/platform/desktop_capturer/DesktopCaptureSourceHelper.cpp index 6e877acf..c02800d3 100644 --- a/src/lib/ortc/webrtc/platform/desktop_capturer/DesktopCaptureSourceHelper.cpp +++ b/src/lib/ortc/webrtc/platform/desktop_capturer/DesktopCaptureSourceHelper.cpp @@ -8,27 +8,26 @@ #include "DesktopCaptureSourceHelper.h" -#include -#include #include #include +#include #include +#include #include -#include #include "DesktopCaptureSourceManager.h" -#include "rtc_base/thread.h" -#include "api/video/video_sink_interface.h" +#include "api/video/i420_buffer.h" #include "api/video/video_frame.h" +#include "api/video/video_sink_interface.h" #include "modules/desktop_capture/desktop_and_cursor_composer.h" #include "modules/desktop_capture/desktop_capturer.h" +#include "rtc_base/thread.h" #include "system_wrappers/include/clock.h" -#include "api/video/i420_buffer.h" #include "third_party/libyuv/include/libyuv.h" #ifdef WEBRTC_MAC #import -#endif // WEBRTC_MAC +#endif // WEBRTC_MAC namespace lib::ortc { namespace { @@ -37,21 +36,20 @@ namespace { class CaptureScheduler { public: void runAsync(std::function method) { - dispatch_async(dispatch_get_main_queue(), ^{ - method(); - }); + dispatch_async(dispatch_get_main_queue(), ^{ + method(); + }); } void runDelayed(int delayMs, std::function method) { - const auto time = dispatch_time( - DISPATCH_TIME_NOW, - ((long long)delayMs * NSEC_PER_SEC) / 1000); + const auto time = + dispatch_time(DISPATCH_TIME_NOW, ((long long)delayMs * NSEC_PER_SEC) / 1000); dispatch_after(time, dispatch_get_main_queue(), ^{ - method(); + method(); }); } }; -#else // WEBRTC_MAC -rtc::Thread *GlobalCapturerThread() { +#else // WEBRTC_MAC +rtc::Thread* GlobalCapturerThread() { static auto result = [] { auto thread = rtc::Thread::Create(); thread->SetName("WebRTC-DesktopCapturer", nullptr); @@ -63,61 +61,55 @@ rtc::Thread *GlobalCapturerThread() { class CaptureScheduler { public: - CaptureScheduler() : _thread(GlobalCapturerThread()) { - } + CaptureScheduler() : _thread(GlobalCapturerThread()) {} - void runAsync(std::function method) { - _thread->PostTask(std::move(method)); - } + void runAsync(std::function method) { _thread->PostTask(std::move(method)); } void runDelayed(int delayMs, std::function method) { -// _thread->PostDelayedTask(std::move(method), delayMs); + // _thread->PostDelayedTask(std::move(method), delayMs); } private: - rtc::Thread *_thread; - + rtc::Thread* _thread; }; -#endif // WEBRTC_MAC +#endif // WEBRTC_MAC class SourceFrameCallbackImpl : public webrtc::DesktopCapturer::Callback { public: SourceFrameCallbackImpl(DesktopSize size, int fps); - void OnCaptureResult( - webrtc::DesktopCapturer::Result result, - std::unique_ptr frame) override; - void setOutput( - std::shared_ptr> sink); - void setSecondaryOutput( - std::shared_ptr> sink); - void setOnFatalError(std::function); - void setOnPause(std::function); + void OnCaptureResult(webrtc::DesktopCapturer::Result result, + std::unique_ptr + frame) override; + void setOutput(std::shared_ptr> sink); + void setSecondaryOutput(std::shared_ptr> sink); + void setOnFatalError(std::function); + void setOnPause(std::function); + private: rtc::scoped_refptr i420_buffer_; - std::shared_ptr> _sink; - std::shared_ptr< - rtc::VideoSinkInterface> _secondarySink; + std::shared_ptr> _sink; + std::shared_ptr> _secondarySink; DesktopSize size_; - std::function _onFatalError; - std::function _onPause; + std::function _onFatalError; + std::function _onPause; }; class DesktopSourceRenderer { public: - DesktopSourceRenderer( - CaptureScheduler &scheduler, - DesktopCaptureSource source, - DesktopCaptureSourceData data); + DesktopSourceRenderer(CaptureScheduler& scheduler, + DesktopCaptureSource source, + DesktopCaptureSourceData data); void start(); void stop(); void setOutput(std::shared_ptr> sink); void setSecondaryOutput(std::shared_ptr> sink); void loop(); - void setOnFatalError(std::function); - void setOnPause(std::function); + void setOnFatalError(std::function); + void setOnPause(std::function); + private: - CaptureScheduler &_scheduler; + CaptureScheduler& _scheduler; std::unique_ptr _capturer; SourceFrameCallbackImpl _callback; std::shared_ptr _timerGuard; @@ -127,20 +119,14 @@ class DesktopSourceRenderer { bool _fatalError = false; bool _currentlyOnPause = false; double _delayMs = 0.; - }; -SourceFrameCallbackImpl::SourceFrameCallbackImpl(DesktopSize size, int fps) -: size_(size) { -} - -void SourceFrameCallbackImpl::OnCaptureResult( - webrtc::DesktopCapturer::Result result, - std::unique_ptr frame) { +SourceFrameCallbackImpl::SourceFrameCallbackImpl(DesktopSize size, int fps) : size_(size) {} - const auto failed = (result != webrtc::DesktopCapturer::Result::SUCCESS) - || !frame - || frame->size().equals({ 1, 1 }); +void SourceFrameCallbackImpl::OnCaptureResult(webrtc::DesktopCapturer::Result result, + std::unique_ptr frame) { + const auto failed = (result != webrtc::DesktopCapturer::Result::SUCCESS) || !frame || + frame->size().equals({1, 1}); if (failed) { if (result == webrtc::DesktopCapturer::Result::ERROR_PERMANENT) { if (_onFatalError) { @@ -155,80 +141,60 @@ void SourceFrameCallbackImpl::OnCaptureResult( } const auto frameSize = frame->size(); - auto fittedSize = (frameSize.width() >= size_.width * 2 - || frameSize.height() >= size_.height * 2) - ? DesktopSize{ frameSize.width() / 2, frameSize.height() / 2 } - : DesktopSize{ frameSize.width(), frameSize.height() }; + auto fittedSize = + (frameSize.width() >= size_.width * 2 || frameSize.height() >= size_.height * 2) + ? DesktopSize{frameSize.width() / 2, frameSize.height() / 2} + : DesktopSize{frameSize.width(), frameSize.height()}; fittedSize.width -= (fittedSize.width % 4); fittedSize.height -= (fittedSize.height % 4); - const auto outputSize = webrtc::DesktopSize{ - fittedSize.width, - fittedSize.height - }; - - webrtc::BasicDesktopFrame outputFrame{ outputSize }; - - const auto outputRect = webrtc::DesktopRect::MakeSize(outputSize); - - const auto outputRectData = outputFrame.data() + - outputFrame.stride() * outputRect.top() + - webrtc::DesktopFrame::kBytesPerPixel * outputRect.left(); - - - libyuv::ARGBScale( - frame->data(), - frame->stride(), - frame->size().width(), - frame->size().height(), - outputRectData, - outputFrame.stride(), - outputSize.width(), - outputSize.height(), - libyuv::kFilterBilinear); - - int width = outputFrame.size().width(); - int height = outputFrame.size().height(); - int stride_y = width; - int stride_uv = (width + 1) / 2; - - if (!i420_buffer_ - || i420_buffer_->width() != width - || i420_buffer_->height() != height) { - i420_buffer_ = webrtc::I420Buffer::Create( - width, - height, - stride_y, - stride_uv, - stride_uv); - } - - int i420Result = libyuv::ConvertToI420( - outputFrame.data(), - width * height, - i420_buffer_->MutableDataY(), i420_buffer_->StrideY(), - i420_buffer_->MutableDataU(), i420_buffer_->StrideU(), - i420_buffer_->MutableDataV(), i420_buffer_->StrideV(), - 0, 0, - width, height, - width, height, - libyuv::kRotate0, - libyuv::FOURCC_ARGB); - - - assert(i420Result == 0); - (void)i420Result; - webrtc::VideoFrame nativeVideoFrame = webrtc::VideoFrame( - i420_buffer_, - webrtc::kVideoRotation_0, - webrtc::Clock::GetRealTimeClock()->CurrentTime().us()); - if (const auto sink = _sink.get()) { - _sink->OnFrame(nativeVideoFrame); - } - if (const auto sink = _secondarySink.get()) { - sink->OnFrame(nativeVideoFrame); - } + const auto outputSize = webrtc::DesktopSize{fittedSize.width, fittedSize.height}; + + webrtc::BasicDesktopFrame outputFrame{outputSize}; + + const auto outputRect = webrtc::DesktopRect::MakeSize(outputSize); + + const auto outputRectData = outputFrame.data() + outputFrame.stride() * outputRect.top() + + webrtc::DesktopFrame::kBytesPerPixel * outputRect.left(); + + libyuv::ARGBScale(frame->data(), + frame->stride(), + frame->size().width(), + frame->size().height(), + outputRectData, + outputFrame.stride(), + outputSize.width(), + outputSize.height(), + libyuv::kFilterBilinear); + + int width = outputFrame.size().width(); + int height = outputFrame.size().height(); + int stride_y = width; + int stride_uv = (width + 1) / 2; + + if (!i420_buffer_ || i420_buffer_->width() != width || i420_buffer_->height() != height) { + i420_buffer_ = webrtc::I420Buffer::Create(width, height, stride_y, stride_uv, stride_uv); + } + + int i420Result = libyuv::ConvertToI420( + outputFrame.data(), width * height, i420_buffer_->MutableDataY(), + i420_buffer_->StrideY(), i420_buffer_->MutableDataU(), i420_buffer_->StrideU(), + i420_buffer_->MutableDataV(), i420_buffer_->StrideV(), 0, 0, width, height, width, + height, libyuv::kRotate0, libyuv::FOURCC_ARGB); + + assert(i420Result == 0); + (void)i420Result; + webrtc::VideoFrame nativeVideoFrame = + webrtc::VideoFrame(i420_buffer_, + webrtc::kVideoRotation_0, + webrtc::Clock::GetRealTimeClock()->CurrentTime().us()); + if (const auto sink = _sink.get()) { + _sink->OnFrame(nativeVideoFrame); + } + if (const auto sink = _secondarySink.get()) { + sink->OnFrame(nativeVideoFrame); + } } void SourceFrameCallbackImpl::setOutput( @@ -236,32 +202,27 @@ void SourceFrameCallbackImpl::setOutput( _sink = std::move(sink); } -void SourceFrameCallbackImpl::setOnFatalError(std::function error) { +void SourceFrameCallbackImpl::setOnFatalError(std::function error) { _onFatalError = error; } -void SourceFrameCallbackImpl::setOnPause(std::function pause) { - _onPause = pause; -} +void SourceFrameCallbackImpl::setOnPause(std::function pause) { _onPause = pause; } void SourceFrameCallbackImpl::setSecondaryOutput( std::shared_ptr> sink) { _secondarySink = std::move(sink); } -DesktopSourceRenderer::DesktopSourceRenderer( - CaptureScheduler &scheduler, - DesktopCaptureSource source, - DesktopCaptureSourceData data) -: _scheduler(scheduler) -, _callback(data.aspectSize, data.fps) -, _delayMs(1000. / data.fps) { - _callback.setOnFatalError([this] { - stop(); - _fatalError = true; - if (_onFatalError) _onFatalError(); - }); - - _callback.setOnPause([this] (bool pause) { +DesktopSourceRenderer::DesktopSourceRenderer(CaptureScheduler& scheduler, + DesktopCaptureSource source, + DesktopCaptureSourceData data) + : _scheduler(scheduler), _callback(data.aspectSize, data.fps), _delayMs(1000. / data.fps) { + _callback.setOnFatalError([this] { + stop(); + _fatalError = true; + if (_onFatalError) _onFatalError(); + }); + + _callback.setOnPause([this](bool pause) { bool previousOnPause = _currentlyOnPause; _currentlyOnPause = pause; if (previousOnPause != _currentlyOnPause) { @@ -280,7 +241,7 @@ DesktopSourceRenderer::DesktopSourceRenderer( options.set_allow_iosurface(true); #elif defined WEBRTC_USE_PIPEWIRE options.set_allow_pipewire(true); -#endif // WEBRTC_WIN || WEBRTC_MAC +#endif // WEBRTC_WIN || WEBRTC_MAC if (source.isWindow()) { _capturer = webrtc::DesktopCapturer::CreateWindowCapturer(options); @@ -292,9 +253,8 @@ DesktopSourceRenderer::DesktopSourceRenderer( return; } if (data.captureMouse) { - _capturer = std::make_unique( - std::move(_capturer), - options); + _capturer = + std::make_unique(std::move(_capturer), options); } _capturer->SelectSource(source.uniqueId()); _capturer->Start(&_callback); @@ -304,10 +264,10 @@ void DesktopSourceRenderer::start() { if (!_capturer || _isRunning) { return; } -// ++GlobalCount; -//#ifdef WEBRTC_MAC -// NSLog(@"current capture count: %d", GlobalCount); -//#endif // WEBRTC_MAC + // ++GlobalCount; + // #ifdef WEBRTC_MAC + // NSLog(@"current capture count: %d", GlobalCount); + // #endif // WEBRTC_MAC _isRunning = true; _timerGuard = std::make_shared(true); @@ -315,13 +275,13 @@ void DesktopSourceRenderer::start() { } void DesktopSourceRenderer::stop() { -// if (_isRunning) { -// GlobalCount--; -// -//#ifdef WEBRTC_MAC -// NSLog(@"current capture count: %d", GlobalCount); -//#endif // WEBRTC_MAC -// } + // if (_isRunning) { + // GlobalCount--; + // + // #ifdef WEBRTC_MAC + // NSLog(@"current capture count: %d", GlobalCount); + // #endif // WEBRTC_MAC + // } _isRunning = false; _timerGuard = nullptr; } @@ -333,14 +293,14 @@ void DesktopSourceRenderer::loop() { _capturer->CaptureFrame(); const auto guard = std::weak_ptr(_timerGuard); - _scheduler.runDelayed(_delayMs, [this,guard] { + _scheduler.runDelayed(_delayMs, [this, guard] { if (guard.lock()) { loop(); } }); } -void DesktopSourceRenderer::setOnFatalError(std::function error) { +void DesktopSourceRenderer::setOnFatalError(std::function error) { if (_fatalError) { error(); } else { @@ -348,7 +308,7 @@ void DesktopSourceRenderer::setOnFatalError(std::function error) { } } -void DesktopSourceRenderer::setOnPause(std::function pause) { +void DesktopSourceRenderer::setOnPause(std::function pause) { if (_currentlyOnPause) { pause(true); } @@ -365,31 +325,29 @@ void DesktopSourceRenderer::setSecondaryOutput( _callback.setSecondaryOutput(std::move(sink)); } -} // namespace +} // namespace struct DesktopCaptureSourceHelper::Renderer { CaptureScheduler scheduler; std::unique_ptr renderer; }; -DesktopCaptureSource DesktopCaptureSourceForKey( - const std::string &uniqueKey) { +DesktopCaptureSource DesktopCaptureSourceForKey(const std::string& uniqueKey) { if (!ShouldBeDesktopCapture(uniqueKey)) { - return DesktopCaptureSource::Invalid(); + return DesktopCaptureSource::Invalid(); } if (uniqueKey == "desktop_capturer_pipewire") { return DesktopCaptureSource(0, "pipewire", false); } const auto windowPrefix = std::string("desktop_capturer_window_"); const auto isWindow = (uniqueKey.find(windowPrefix) == 0); - DesktopCaptureSourceManager manager(isWindow - ? DesktopCaptureType::Window - : DesktopCaptureType::Screen); - const auto sources = manager.sources(); + DesktopCaptureSourceManager manager(isWindow ? DesktopCaptureType::Window + : DesktopCaptureType::Screen); + const auto sources = manager.sources(); // "desktop_capturer_window_".size() == "desktop_capturer_screen_".size() const auto keyId = std::stoll(uniqueKey.substr(windowPrefix.size())); - for (const auto &source : sources) { + for (const auto& source : sources) { if (source.uniqueId() == keyId) { return source; } @@ -397,63 +355,49 @@ DesktopCaptureSource DesktopCaptureSourceForKey( return DesktopCaptureSource::Invalid(); } -bool ShouldBeDesktopCapture(const std::string &uniqueKey) { +bool ShouldBeDesktopCapture(const std::string& uniqueKey) { return (uniqueKey.find("desktop_capturer_") == 0); } -DesktopCaptureSourceHelper::DesktopCaptureSourceHelper( - DesktopCaptureSource source, - DesktopCaptureSourceData data) -: _renderer(std::make_shared()) { +DesktopCaptureSourceHelper::DesktopCaptureSourceHelper(DesktopCaptureSource source, + DesktopCaptureSourceData data) + : _renderer(std::make_shared()) { _renderer->scheduler.runAsync([renderer = _renderer, source, data] { - renderer->renderer = std::make_unique( - renderer->scheduler, - source, - data); + renderer->renderer = + std::make_unique(renderer->scheduler, source, data); }); } DesktopCaptureSourceHelper::~DesktopCaptureSourceHelper() { - _renderer->scheduler.runAsync([renderer = _renderer] { - }); + _renderer->scheduler.runAsync([renderer = _renderer] {}); } void DesktopCaptureSourceHelper::setOutput( - std::shared_ptr< - rtc::VideoSinkInterface> sink) const { - _renderer->scheduler.runAsync([renderer = _renderer, sink] { - renderer->renderer->setOutput(sink); - }); + std::shared_ptr> sink) const { + _renderer->scheduler.runAsync( + [renderer = _renderer, sink] { renderer->renderer->setOutput(sink); }); } void DesktopCaptureSourceHelper::setSecondaryOutput( - std::shared_ptr< - rtc::VideoSinkInterface> sink) const { - _renderer->scheduler.runAsync([renderer = _renderer, sink] { - renderer->renderer->setSecondaryOutput(sink); - }); + std::shared_ptr> sink) const { + _renderer->scheduler.runAsync( + [renderer = _renderer, sink] { renderer->renderer->setSecondaryOutput(sink); }); } void DesktopCaptureSourceHelper::start() const { - _renderer->scheduler.runAsync([renderer = _renderer] { - renderer->renderer->start(); - }); + _renderer->scheduler.runAsync([renderer = _renderer] { renderer->renderer->start(); }); } -void DesktopCaptureSourceHelper::setOnFatalError(std::function error) const { - _renderer->scheduler.runAsync([renderer = _renderer, error = error] { - renderer->renderer->setOnFatalError(error); - }); +void DesktopCaptureSourceHelper::setOnFatalError(std::function error) const { + _renderer->scheduler.runAsync( + [renderer = _renderer, error = error] { renderer->renderer->setOnFatalError(error); }); } -void DesktopCaptureSourceHelper::setOnPause(std::function pause) const { - _renderer->scheduler.runAsync([renderer = _renderer, pause = pause] { - renderer->renderer->setOnPause(pause); - }); +void DesktopCaptureSourceHelper::setOnPause(std::function pause) const { + _renderer->scheduler.runAsync( + [renderer = _renderer, pause = pause] { renderer->renderer->setOnPause(pause); }); } void DesktopCaptureSourceHelper::stop() const { - _renderer->scheduler.runAsync([renderer = _renderer] { - renderer->renderer->stop(); - }); + _renderer->scheduler.runAsync([renderer = _renderer] { renderer->renderer->stop(); }); } -} // namespace lib::ortc +} // namespace lib::ortc diff --git a/src/lib/ortc/webrtc/platform/desktop_capturer/DesktopCaptureSourceHelper.h b/src/lib/ortc/webrtc/platform/desktop_capturer/DesktopCaptureSourceHelper.h index 5a44e9df..42e48807 100644 --- a/src/lib/ortc/webrtc/platform/desktop_capturer/DesktopCaptureSourceHelper.h +++ b/src/lib/ortc/webrtc/platform/desktop_capturer/DesktopCaptureSourceHelper.h @@ -10,47 +10,40 @@ #include "DesktopCaptureSource.h" -#include #include +#include namespace webrtc { class VideoFrame; -} // namespace webrtc +} // namespace webrtc namespace rtc { -template -class VideoSinkInterface; -} // namespace rtc +template class VideoSinkInterface; +} // namespace rtc namespace lib::ortc { -DesktopCaptureSource DesktopCaptureSourceForKey( - const std::string &uniqueKey); -bool ShouldBeDesktopCapture(const std::string &uniqueKey); +DesktopCaptureSource DesktopCaptureSourceForKey(const std::string& uniqueKey); +bool ShouldBeDesktopCapture(const std::string& uniqueKey); class DesktopCaptureSourceHelper { public: - DesktopCaptureSourceHelper( - DesktopCaptureSource source, - DesktopCaptureSourceData data); - ~DesktopCaptureSourceHelper(); - - void setOutput( - std::shared_ptr< - rtc::VideoSinkInterface> sink) const; - void setSecondaryOutput( - std::shared_ptr< - rtc::VideoSinkInterface> sink) const; - void start() const; - void stop() const; - void setOnFatalError(std::function) const; - void setOnPause(std::function) const; -private: - struct Renderer; - std::shared_ptr _renderer; + DesktopCaptureSourceHelper(DesktopCaptureSource source, DesktopCaptureSourceData data); + ~DesktopCaptureSourceHelper(); + void setOutput(std::shared_ptr> sink) const; + void setSecondaryOutput( + std::shared_ptr> sink) const; + void start() const; + void stop() const; + void setOnFatalError(std::function) const; + void setOnPause(std::function) const; + +private: + struct Renderer; + std::shared_ptr _renderer; }; -} // namespace lib::ortc +} // namespace lib::ortc -#endif // TGCALLS_DESKTOP_CAPTURE_SOURCE_HELPER_H__ +#endif // TGCALLS_DESKTOP_CAPTURE_SOURCE_HELPER_H__ diff --git a/src/lib/ortc/webrtc/platform/desktop_capturer/DesktopCaptureSourceManager.cpp b/src/lib/ortc/webrtc/platform/desktop_capturer/DesktopCaptureSourceManager.cpp index a10538b9..47e2221a 100644 --- a/src/lib/ortc/webrtc/platform/desktop_capturer/DesktopCaptureSourceManager.cpp +++ b/src/lib/ortc/webrtc/platform/desktop_capturer/DesktopCaptureSourceManager.cpp @@ -8,25 +8,20 @@ #include "DesktopCaptureSourceManager.h" +#include "DesktopCaptureSourceHelper.h" +#include "api/video/i420_buffer.h" #include "modules/desktop_capture/desktop_and_cursor_composer.h" #include "modules/desktop_capture/desktop_capturer_differ_wrapper.h" #include "third_party/libyuv/include/libyuv.h" -#include "api/video/i420_buffer.h" -#include "DesktopCaptureSourceHelper.h" - namespace lib::ortc { -DesktopCaptureSourceManager::DesktopCaptureSourceManager( - DesktopCaptureType type) -: _capturer(CreateForType(type)) - , _type(type) { -} +DesktopCaptureSourceManager::DesktopCaptureSourceManager(DesktopCaptureType type) + : _capturer(CreateForType(type)), _type(type) {} DesktopCaptureSourceManager::~DesktopCaptureSourceManager() = default; -webrtc::DesktopCaptureOptions DesktopCaptureSourceManager::OptionsForType( - DesktopCaptureType type) { +webrtc::DesktopCaptureOptions DesktopCaptureSourceManager::OptionsForType(DesktopCaptureType type) { auto result = webrtc::DesktopCaptureOptions::CreateDefault(); #ifdef WEBRTC_WIN result.set_allow_directx_capturer(true); @@ -35,29 +30,29 @@ webrtc::DesktopCaptureOptions DesktopCaptureSourceManager::OptionsForType( result.set_allow_iosurface(type == DesktopCaptureType::Screen); #elif defined WEBRTC_USE_PIPEWIRE result.set_allow_pipewire(true); -#endif // WEBRTC_WIN || WEBRTC_MAC +#endif // WEBRTC_WIN || WEBRTC_MAC result.set_detect_updated_region(true); return result; } auto DesktopCaptureSourceManager::CreateForType(DesktopCaptureType type) --> std::unique_ptr { + -> std::unique_ptr { const auto options = OptionsForType(type); return (type == DesktopCaptureType::Screen) - ? webrtc::DesktopCapturer::CreateScreenCapturer(options) - : webrtc::DesktopCapturer::CreateWindowCapturer(options); + ? webrtc::DesktopCapturer::CreateScreenCapturer(options) + : webrtc::DesktopCapturer::CreateWindowCapturer(options); } std::vector DesktopCaptureSourceManager::sources() { auto result = std::vector(); - auto list = webrtc::DesktopCapturer::SourceList(); + auto list = webrtc::DesktopCapturer::SourceList(); if (_capturer && _capturer->GetSourceList(&list)) { const auto isWindow = (_type == DesktopCaptureType::Window); - for (const auto &source : list) { + for (const auto& source : list) { result.emplace_back(source.id, source.title, isWindow); } } return result; } -} // namespace lib::ortc +} // namespace lib::ortc diff --git a/src/lib/ortc/webrtc/platform/desktop_capturer/DesktopCaptureSourceManager.h b/src/lib/ortc/webrtc/platform/desktop_capturer/DesktopCaptureSourceManager.h index e809a62c..842c252b 100644 --- a/src/lib/ortc/webrtc/platform/desktop_capturer/DesktopCaptureSourceManager.h +++ b/src/lib/ortc/webrtc/platform/desktop_capturer/DesktopCaptureSourceManager.h @@ -17,33 +17,30 @@ namespace webrtc { class DesktopCapturer; class DesktopCaptureOptions; -} // namespace webrtc +} // namespace webrtc namespace lib::ortc { enum class DesktopCaptureType { - Screen, - Window, + Screen, + Window, }; class DesktopCaptureSourceManager { public: - explicit DesktopCaptureSourceManager(DesktopCaptureType type); - ~DesktopCaptureSourceManager(); + explicit DesktopCaptureSourceManager(DesktopCaptureType type); + ~DesktopCaptureSourceManager(); - std::vector sources(); + std::vector sources(); private: - static webrtc::DesktopCaptureOptions OptionsForType( - DesktopCaptureType type); - static std::unique_ptr CreateForType( - DesktopCaptureType type); - - std::unique_ptr _capturer; - DesktopCaptureType _type = DesktopCaptureType::Screen; + static webrtc::DesktopCaptureOptions OptionsForType(DesktopCaptureType type); + static std::unique_ptr CreateForType(DesktopCaptureType type); + std::unique_ptr _capturer; + DesktopCaptureType _type = DesktopCaptureType::Screen; }; -} // namespace lib::ortc +} // namespace lib::ortc -#endif // TGCALLS_DESKTOP_CAPTURE_SOURCE_MANAGER_H__ +#endif // TGCALLS_DESKTOP_CAPTURE_SOURCE_MANAGER_H__ diff --git a/src/lib/ortc/webrtc/platform/tdesktop/DesktopInterface.cpp b/src/lib/ortc/webrtc/platform/tdesktop/DesktopInterface.cpp index 91e73e6c..338d494e 100644 --- a/src/lib/ortc/webrtc/platform/tdesktop/DesktopInterface.cpp +++ b/src/lib/ortc/webrtc/platform/tdesktop/DesktopInterface.cpp @@ -3,8 +3,8 @@ #include "VideoCapturerInterfaceImpl.h" #include "VideoCapturerTrackSource.h" -#include "api/video_codecs/builtin_video_encoder_factory.h" #include "api/video_codecs/builtin_video_decoder_factory.h" +#include "api/video_codecs/builtin_video_encoder_factory.h" #include "pc/video_track_source_proxy.h" #if TGCALLS_UWP_DESKTOP @@ -13,46 +13,58 @@ namespace lib::ortc { -std::unique_ptr DesktopInterface::makeVideoEncoderFactory(bool preferHardwareEncoding, bool isScreencast) { +std::unique_ptr DesktopInterface::makeVideoEncoderFactory( + bool preferHardwareEncoding, bool isScreencast) { #if TGCALLS_UWP_DESKTOP - return std::make_unique(); + return std::make_unique(); #else - return webrtc::CreateBuiltinVideoEncoderFactory(); + return webrtc::CreateBuiltinVideoEncoderFactory(); #endif } std::unique_ptr DesktopInterface::makeVideoDecoderFactory() { #if TGCALLS_UWP_DESKTOP - return std::make_unique(); + return std::make_unique(); #else - return webrtc::CreateBuiltinVideoDecoderFactory(); + return webrtc::CreateBuiltinVideoDecoderFactory(); #endif } rtc::scoped_refptr DesktopInterface::makeVideoSource( - rtc::Thread *signalingThread, - rtc::Thread *workerThread) -{ - const auto videoTrackSource = rtc::scoped_refptr( - new rtc::RefCountedObject()); - return videoTrackSource ? webrtc::VideoTrackSourceProxy::Create(signalingThread, workerThread, videoTrackSource) - : nullptr; + rtc::Thread* signalingThread, rtc::Thread* workerThread) { + const auto videoTrackSource = rtc::scoped_refptr( + new rtc::RefCountedObject()); + return videoTrackSource ? webrtc::VideoTrackSourceProxy::Create( + signalingThread, workerThread, videoTrackSource) + : nullptr; } -bool DesktopInterface::supportsEncoding(const std::string &codecName) { - return (codecName == cricket::kH264CodecName) - || (codecName == cricket::kVp8CodecName); +bool DesktopInterface::supportsEncoding(const std::string& codecName) { + return (codecName == cricket::kH264CodecName) || (codecName == cricket::kVp8CodecName); } -void DesktopInterface::adaptVideoSource(rtc::scoped_refptr videoSource, int width, int height, int fps) { -} +void DesktopInterface::adaptVideoSource( + rtc::scoped_refptr videoSource, + int width, + int height, + int fps) {} -std::unique_ptr DesktopInterface::makeVideoCapturer(rtc::scoped_refptr source, std::string deviceId, std::function stateUpdated, std::function captureInfoUpdated, std::shared_ptr platformContext, std::pair &outResolution) { - return std::make_unique(source, deviceId, stateUpdated, platformContext, outResolution); +std::unique_ptr DesktopInterface::makeVideoCapturer( + rtc::scoped_refptr source, + std::string deviceId, + std::function + stateUpdated, + std::function + captureInfoUpdated, + std::shared_ptr + platformContext, + std::pair& outResolution) { + return std::make_unique( + source, deviceId, stateUpdated, platformContext, outResolution); } std::unique_ptr CreatePlatformInterface() { - return std::make_unique(); + return std::make_unique(); } -} // namespace lib::ortc +} // namespace lib::ortc diff --git a/src/lib/ortc/webrtc/platform/tdesktop/DesktopInterface.h b/src/lib/ortc/webrtc/platform/tdesktop/DesktopInterface.h index 4db67fe8..5f1d208f 100644 --- a/src/lib/ortc/webrtc/platform/tdesktop/DesktopInterface.h +++ b/src/lib/ortc/webrtc/platform/tdesktop/DesktopInterface.h @@ -1,24 +1,31 @@ #ifndef TGCALLS_DESKTOP_INTERFACE_H #define TGCALLS_DESKTOP_INTERFACE_H +#include #include "../../VideoCapturerInterface.h" #include "../PlatformInterface.h" #include "webrtc/platform/PlatformInterface.h" -#include namespace lib::ortc { class DesktopInterface : public PlatformInterface { public: - std::unique_ptr makeVideoEncoderFactory(bool preferHardwareEncoding = false, bool isScreencast = false) override; - std::unique_ptr makeVideoDecoderFactory() override; - bool supportsEncoding(const std::string &codecName) override; - rtc::scoped_refptr makeVideoSource(rtc::Thread *signalingThread, rtc::Thread *workerThread) override; - void adaptVideoSource(rtc::scoped_refptr videoSource, int width, int height, int fps) override; - std::unique_ptr makeVideoCapturer(rtc::scoped_refptr source, std::string deviceId, std::function stateUpdated, std::function captureInfoUpdated, std::shared_ptr platformContext, std::pair &outResolution) override; - + std::unique_ptr makeVideoEncoderFactory( + bool preferHardwareEncoding = false, bool isScreencast = false) override; + std::unique_ptr makeVideoDecoderFactory() override; + bool supportsEncoding(const std::string& codecName) override; + rtc::scoped_refptr makeVideoSource( + rtc::Thread* signalingThread, rtc::Thread* workerThread) override; + void adaptVideoSource(rtc::scoped_refptr videoSource, + int width, int height, int fps) override; + std::unique_ptr makeVideoCapturer( + rtc::scoped_refptr source, std::string deviceId, + std::function stateUpdated, + std::function captureInfoUpdated, + std::shared_ptr platformContext, + std::pair& outResolution) override; }; -} // namespace lib::ortc +} // namespace lib::ortc -#endif // TGCALLS_DESKTOP_INTERFACE_H +#endif // TGCALLS_DESKTOP_INTERFACE_H diff --git a/src/lib/ortc/webrtc/platform/tdesktop/VideoCameraCapturer.cpp b/src/lib/ortc/webrtc/platform/tdesktop/VideoCameraCapturer.cpp index 4fdf5b63..af059942 100644 --- a/src/lib/ortc/webrtc/platform/tdesktop/VideoCameraCapturer.cpp +++ b/src/lib/ortc/webrtc/platform/tdesktop/VideoCameraCapturer.cpp @@ -8,8 +8,8 @@ #include "rtc_base/logging.h" #include -#include #include +#include namespace lib::ortc { namespace { @@ -18,203 +18,179 @@ constexpr auto kPreferredWidth = 1280; constexpr auto kPreferredHeight = 720; constexpr auto kPreferredFps = 30; -} // namespace +} // namespace VideoCameraCapturer::VideoCameraCapturer( - std::shared_ptr> sink) -: _sink(sink) { -} + std::shared_ptr> sink) + : _sink(sink) {} -VideoCameraCapturer::~VideoCameraCapturer() { - destroy(); -} +VideoCameraCapturer::~VideoCameraCapturer() { destroy(); } void VideoCameraCapturer::create() { - _failed = false; - const auto info = std::unique_ptr( - webrtc::VideoCaptureFactory::CreateDeviceInfo()); - if (!info) { - failed(); - return; - } - const auto count = info->NumberOfDevices(); - if (count <= 0) { - failed(); - return; - } - const auto getId = [&](int index) { - constexpr auto kLengthLimit = 256; - char name[kLengthLimit] = { 0 }; - char id[kLengthLimit] = { 0 }; - return (info->GetDeviceName(index, name, kLengthLimit, id, kLengthLimit) == 0) - ? std::string(id) - : std::string(); - }; - auto preferredId = std::string(); - for (auto i = 0; i != count; ++i) { - const auto id = getId(i); - if ((_requestedDeviceId == id) - || (preferredId.empty() - && (_requestedDeviceId.empty() || _requestedDeviceId == "default"))) { - preferredId = id; - } - } - if (create(info.get(), preferredId)) { - return; - } - for (auto i = 0; i != count; ++i) { - if (create(info.get(), getId(i))) { - return; - } - } - failed(); + _failed = false; + const auto info = std::unique_ptr( + webrtc::VideoCaptureFactory::CreateDeviceInfo()); + if (!info) { + failed(); + return; + } + const auto count = info->NumberOfDevices(); + if (count <= 0) { + failed(); + return; + } + const auto getId = [&](int index) { + constexpr auto kLengthLimit = 256; + char name[kLengthLimit] = {0}; + char id[kLengthLimit] = {0}; + return (info->GetDeviceName(index, name, kLengthLimit, id, kLengthLimit) == 0) + ? std::string(id) + : std::string(); + }; + auto preferredId = std::string(); + for (auto i = 0; i != count; ++i) { + const auto id = getId(i); + if ((_requestedDeviceId == id) || + (preferredId.empty() && + (_requestedDeviceId.empty() || _requestedDeviceId == "default"))) { + preferredId = id; + } + } + if (create(info.get(), preferredId)) { + return; + } + for (auto i = 0; i != count; ++i) { + if (create(info.get(), getId(i))) { + return; + } + } + failed(); } void VideoCameraCapturer::failed() { - _failed = true; - if (_error) { - _error(); - } + _failed = true; + if (_error) { + _error(); + } } -bool VideoCameraCapturer::create( - webrtc::VideoCaptureModule::DeviceInfo *info, - const std::string &deviceId) { - _module = webrtc::VideoCaptureFactory::Create(deviceId.c_str()); - if (!_module) { - RTC_LOG(LS_ERROR) - << "Failed to create VideoCameraCapturer '" << deviceId << "'."; - return false; - } - _module->RegisterCaptureDataCallback(this); - - auto requested = webrtc::VideoCaptureCapability(); - requested.videoType = webrtc::VideoType::kI420; - requested.width = kPreferredWidth; - requested.height = kPreferredHeight; - requested.maxFPS = kPreferredFps; - info->GetBestMatchedCapability( - _module->CurrentDeviceName(), - requested, - _capability); - if (!_capability.width || !_capability.height || !_capability.maxFPS) { - _capability.width = kPreferredWidth; - _capability.height = kPreferredHeight; - _capability.maxFPS = kPreferredFps; - } +bool VideoCameraCapturer::create(webrtc::VideoCaptureModule::DeviceInfo* info, + const std::string& deviceId) { + _module = webrtc::VideoCaptureFactory::Create(deviceId.c_str()); + if (!_module) { + RTC_LOG(LS_ERROR) << "Failed to create VideoCameraCapturer '" << deviceId << "'."; + return false; + } + _module->RegisterCaptureDataCallback(this); + + auto requested = webrtc::VideoCaptureCapability(); + requested.videoType = webrtc::VideoType::kI420; + requested.width = kPreferredWidth; + requested.height = kPreferredHeight; + requested.maxFPS = kPreferredFps; + info->GetBestMatchedCapability(_module->CurrentDeviceName(), requested, _capability); + if (!_capability.width || !_capability.height || !_capability.maxFPS) { + _capability.width = kPreferredWidth; + _capability.height = kPreferredHeight; + _capability.maxFPS = kPreferredFps; + } #ifndef WEBRTC_WIN - _capability.videoType = webrtc::VideoType::kI420; -#endif // WEBRTC_WIN - if (_module->StartCapture(_capability) != 0) { - RTC_LOG(LS_ERROR) - << "Failed to start VideoCameraCapturer '" << _requestedDeviceId << "'."; - destroy(); - return false; - } - _dimensions = std::make_pair(_capability.width, _capability.height); - return true; + _capability.videoType = webrtc::VideoType::kI420; +#endif // WEBRTC_WIN + if (_module->StartCapture(_capability) != 0) { + RTC_LOG(LS_ERROR) << "Failed to start VideoCameraCapturer '" << _requestedDeviceId << "'."; + destroy(); + return false; + } + _dimensions = std::make_pair(_capability.width, _capability.height); + return true; } void VideoCameraCapturer::setState(VideoState state) { - if (_state == state) { - return; - } - _state = state; - if (_state == VideoState::Active) { - create(); - } else { - destroy(); - } + if (_state == state) { + return; + } + _state = state; + if (_state == VideoState::Active) { + create(); + } else { + destroy(); + } } void VideoCameraCapturer::setDeviceId(std::string deviceId) { - if (_requestedDeviceId == deviceId) { - return; - } - destroy(); - _requestedDeviceId = deviceId; - if (_state == VideoState::Active) { - create(); - } + if (_requestedDeviceId == deviceId) { + return; + } + destroy(); + _requestedDeviceId = deviceId; + if (_state == VideoState::Active) { + create(); + } } void VideoCameraCapturer::setPreferredCaptureAspectRatio(float aspectRatio) { - _aspectRatio = aspectRatio; + _aspectRatio = aspectRatio; } void VideoCameraCapturer::setOnFatalError(std::function error) { - _error = std::move(error); - if (_failed && _error) { - _error(); - } + _error = std::move(error); + if (_failed && _error) { + _error(); + } } -std::pair VideoCameraCapturer::resolution() const { - return _dimensions; -} +std::pair VideoCameraCapturer::resolution() const { return _dimensions; } void VideoCameraCapturer::destroy() { - _failed = false; - if (!_module) { - return; - } - - _module->StopCapture(); - _module->DeRegisterCaptureDataCallback(); - _module = nullptr; + _failed = false; + if (!_module) { + return; + } + + _module->StopCapture(); + _module->DeRegisterCaptureDataCallback(); + _module = nullptr; } -void VideoCameraCapturer::OnFrame(const webrtc::VideoFrame &frame) { - if (_state != VideoState::Active) { - return; - } else if (_aspectRatio <= 0.001) { - if(_sink) - _sink->OnFrame(frame); - return; - } - const auto originalWidth = frame.width(); - const auto originalHeight = frame.height(); - auto width = (originalWidth > _aspectRatio * originalHeight) - ? int(std::round(_aspectRatio * originalHeight)) - : originalWidth; - auto height = (originalWidth > _aspectRatio * originalHeight) - ? originalHeight - : int(std::round(originalHeight / _aspectRatio)); - if ((width >= originalWidth && height >= originalHeight) || !width || !height) { - _sink->OnFrame(frame); - return; - } - - width &= ~int(1); - height &= ~int(1); - const auto left = (originalWidth - width) / 2; - const auto top = (originalHeight - height) / 2; - rtc::scoped_refptr croppedBuffer = - webrtc::I420Buffer::Create(width, height); - croppedBuffer->CropAndScaleFrom( - *frame.video_frame_buffer()->ToI420(), - left, - top, - width, - height); - webrtc::VideoFrame::Builder croppedBuilder = - webrtc::VideoFrame::Builder() - .set_video_frame_buffer(croppedBuffer) - .set_rotation(webrtc::kVideoRotation_0) - .set_timestamp_us(frame.timestamp_us()) - .set_id(frame.id()); - if (frame.has_update_rect()) { - croppedBuilder.set_update_rect(frame.update_rect().ScaleWithFrame( - frame.width(), - frame.height(), - left, - top, - width, - height, - width, - height)); - } - _sink->OnFrame(croppedBuilder.build()); +void VideoCameraCapturer::OnFrame(const webrtc::VideoFrame& frame) { + if (_state != VideoState::Active) { + return; + } else if (_aspectRatio <= 0.001) { + if (_sink) _sink->OnFrame(frame); + return; + } + const auto originalWidth = frame.width(); + const auto originalHeight = frame.height(); + auto width = (originalWidth > _aspectRatio * originalHeight) + ? int(std::round(_aspectRatio * originalHeight)) + : originalWidth; + auto height = (originalWidth > _aspectRatio * originalHeight) + ? originalHeight + : int(std::round(originalHeight / _aspectRatio)); + if ((width >= originalWidth && height >= originalHeight) || !width || !height) { + _sink->OnFrame(frame); + return; + } + + width &= ~int(1); + height &= ~int(1); + const auto left = (originalWidth - width) / 2; + const auto top = (originalHeight - height) / 2; + rtc::scoped_refptr croppedBuffer = + webrtc::I420Buffer::Create(width, height); + croppedBuffer->CropAndScaleFrom( + *frame.video_frame_buffer()->ToI420(), left, top, width, height); + webrtc::VideoFrame::Builder croppedBuilder = webrtc::VideoFrame::Builder() + .set_video_frame_buffer(croppedBuffer) + .set_rotation(webrtc::kVideoRotation_0) + .set_timestamp_us(frame.timestamp_us()) + .set_id(frame.id()); + if (frame.has_update_rect()) { + croppedBuilder.set_update_rect(frame.update_rect().ScaleWithFrame( + frame.width(), frame.height(), left, top, width, height, width, height)); + } + _sink->OnFrame(croppedBuilder.build()); } } // namespace lib::ortc diff --git a/src/lib/ortc/webrtc/platform/tdesktop/VideoCameraCapturer.h b/src/lib/ortc/webrtc/platform/tdesktop/VideoCameraCapturer.h index 3f608e2d..1d1048a4 100644 --- a/src/lib/ortc/webrtc/platform/tdesktop/VideoCameraCapturer.h +++ b/src/lib/ortc/webrtc/platform/tdesktop/VideoCameraCapturer.h @@ -9,47 +9,42 @@ #include "../../VideoCaptureInterface.h" +#include #include #include -#include namespace lib::ortc { -class VideoCameraCapturer - : public rtc::VideoSinkInterface { +class VideoCameraCapturer : public rtc::VideoSinkInterface { public: - explicit VideoCameraCapturer( - std::shared_ptr> sink); - ~VideoCameraCapturer(); + explicit VideoCameraCapturer(std::shared_ptr> sink); + ~VideoCameraCapturer(); - void setState(VideoState state); - void setDeviceId(std::string deviceId); - void setPreferredCaptureAspectRatio(float aspectRatio); - void setOnFatalError(std::function error); + void setState(VideoState state); + void setDeviceId(std::string deviceId); + void setPreferredCaptureAspectRatio(float aspectRatio); + void setOnFatalError(std::function error); - std::pair resolution() const; + std::pair resolution() const; - void OnFrame(const webrtc::VideoFrame &frame) override; + void OnFrame(const webrtc::VideoFrame& frame) override; private: - void create(); - bool create( - webrtc::VideoCaptureModule::DeviceInfo *info, - const std::string &deviceId); - void destroy(); - void failed(); - - std::shared_ptr> _sink; - rtc::scoped_refptr _module; - webrtc::VideoCaptureCapability _capability; - - VideoState _state = VideoState::Inactive; - std::string _requestedDeviceId; - std::pair _dimensions; - std::function _error; - float _aspectRatio = 0.; - bool _failed = false; - + void create(); + bool create(webrtc::VideoCaptureModule::DeviceInfo* info, const std::string& deviceId); + void destroy(); + void failed(); + + std::shared_ptr> _sink; + rtc::scoped_refptr _module; + webrtc::VideoCaptureCapability _capability; + + VideoState _state = VideoState::Inactive; + std::string _requestedDeviceId; + std::pair _dimensions; + std::function _error; + float _aspectRatio = 0.; + bool _failed = false; }; } // namespace lib::ortc diff --git a/src/lib/ortc/webrtc/platform/tdesktop/VideoCapturerInterfaceImpl.cpp b/src/lib/ortc/webrtc/platform/tdesktop/VideoCapturerInterfaceImpl.cpp index ca0d6af9..593f620d 100644 --- a/src/lib/ortc/webrtc/platform/tdesktop/VideoCapturerInterfaceImpl.cpp +++ b/src/lib/ortc/webrtc/platform/tdesktop/VideoCapturerInterfaceImpl.cpp @@ -1,7 +1,7 @@ #include "VideoCapturerInterfaceImpl.h" -#include "VideoCapturerTrackSource.h" #include "VideoCameraCapturer.h" +#include "VideoCapturerTrackSource.h" #include "pc/video_track_source_proxy.h" #include "webrtc/platform/desktop_capturer/DesktopCaptureSourceHelper.h" @@ -10,120 +10,113 @@ namespace lib::ortc { namespace { std::shared_ptr> GetSink( - const rtc::scoped_refptr &nativeSource) { + const rtc::scoped_refptr& nativeSource) { const auto proxy = static_cast(nativeSource.get()); const auto internal = static_cast(proxy->internal()); return internal->sink(); } -} // namespace +} // namespace VideoCapturerInterfaceImpl::VideoCapturerInterfaceImpl( - rtc::scoped_refptr source, - std::string deviceId, - std::function stateUpdated, - std::shared_ptr platformContext, - std::pair &outResolution) -: _source(source) -, _sink(GetSink(source)) -, _stateUpdated(stateUpdated) { + rtc::scoped_refptr source, + std::string deviceId, + std::function + stateUpdated, + std::shared_ptr + platformContext, + std::pair& outResolution) + : _source(source), _sink(GetSink(source)), _stateUpdated(stateUpdated) { + if (const auto source = DesktopCaptureSourceForKey(deviceId)) { + const auto data = DesktopCaptureSourceData{ + {1280, 720}, /*.aspectSize = */ + 24., /*.fps = */ + (deviceId != "desktop_capturer_pipewire"), /*.captureMouse = */ + }; + _desktopCapturer = std::make_unique(source, data); + _desktopCapturer->setOutput(_sink); + _desktopCapturer->start(); + outResolution = {1280, 960}; + } else if (!ShouldBeDesktopCapture(deviceId)) - if (const auto source = DesktopCaptureSourceForKey(deviceId)) { - const auto data = DesktopCaptureSourceData{ - { 1280, 720 },/*.aspectSize = */ - 24. ,/*.fps = */ - (deviceId != "desktop_capturer_pipewire"),/*.captureMouse = */ - }; - _desktopCapturer = std::make_unique( - source, - data); - _desktopCapturer->setOutput(_sink); - _desktopCapturer->start(); - outResolution = { 1280, 960 }; - } else if (!ShouldBeDesktopCapture(deviceId)) - - { - _cameraCapturer = std::make_unique(_sink); - _cameraCapturer->setDeviceId(deviceId); - _cameraCapturer->setState(VideoState::Active); - outResolution = _cameraCapturer->resolution(); - } + { + _cameraCapturer = std::make_unique(_sink); + _cameraCapturer->setDeviceId(deviceId); + _cameraCapturer->setState(VideoState::Active); + outResolution = _cameraCapturer->resolution(); + } } -VideoCapturerInterfaceImpl::~VideoCapturerInterfaceImpl() { -} +VideoCapturerInterfaceImpl::~VideoCapturerInterfaceImpl() {} void VideoCapturerInterfaceImpl::setState(VideoState state) { #ifdef TGCALLS_UWP_DESKTOP - if (_screenCapturer) { - _screenCapturer->setState(state); - } else + if (_screenCapturer) { + _screenCapturer->setState(state); + } else #else - if (_desktopCapturer) { - if (state == VideoState::Active) { - _desktopCapturer->start(); - } else { - _desktopCapturer->stop(); - } - } else -#endif // TGCALLS_UWP_DESKTOP - if (_cameraCapturer) { - _cameraCapturer->setState(state); - } - if (_stateUpdated) { - _stateUpdated(state); - } + if (_desktopCapturer) { + if (state == VideoState::Active) { + _desktopCapturer->start(); + } else { + _desktopCapturer->stop(); + } + } else +#endif // TGCALLS_UWP_DESKTOP + if (_cameraCapturer) { + _cameraCapturer->setState(state); + } + if (_stateUpdated) { + _stateUpdated(state); + } } -void VideoCapturerInterfaceImpl::setPreferredCaptureAspectRatio( - float aspectRatio) { - if (_cameraCapturer) { - _cameraCapturer->setPreferredCaptureAspectRatio(aspectRatio); - } +void VideoCapturerInterfaceImpl::setPreferredCaptureAspectRatio(float aspectRatio) { + if (_cameraCapturer) { + _cameraCapturer->setPreferredCaptureAspectRatio(aspectRatio); + } } void VideoCapturerInterfaceImpl::setUncroppedOutput( - std::shared_ptr> sink) { - if (_uncroppedSink != nullptr) { - _source->RemoveSink(_uncroppedSink.get()); - } - _uncroppedSink = sink; - if (_uncroppedSink != nullptr) { - _source->AddOrUpdateSink( - _uncroppedSink.get(), - rtc::VideoSinkWants()); - } + std::shared_ptr> sink) { + if (_uncroppedSink != nullptr) { + _source->RemoveSink(_uncroppedSink.get()); + } + _uncroppedSink = sink; + if (_uncroppedSink != nullptr) { + _source->AddOrUpdateSink(_uncroppedSink.get(), rtc::VideoSinkWants()); + } } void VideoCapturerInterfaceImpl::setOnFatalError(std::function error) { #ifdef TGCALLS_UWP_DESKTOP - if (_screenCapturer) { - _screenCapturer->setOnFatalError(std::move(error)); - } else if (!_screenCapturer && !_cameraCapturer && error) { - error(); - } -#else // TGCALLS_UWP_DESKTOP - if (_desktopCapturer) { - _desktopCapturer->setOnFatalError(std::move(error)); - } else if (!_desktopCapturer && !_cameraCapturer && error) { - error(); - } -#endif // TGCALLS_UWP_DESKTOP - if (_cameraCapturer) { - _cameraCapturer->setOnFatalError(std::move(error)); - } + if (_screenCapturer) { + _screenCapturer->setOnFatalError(std::move(error)); + } else if (!_screenCapturer && !_cameraCapturer && error) { + error(); + } +#else // TGCALLS_UWP_DESKTOP + if (_desktopCapturer) { + _desktopCapturer->setOnFatalError(std::move(error)); + } else if (!_desktopCapturer && !_cameraCapturer && error) { + error(); + } +#endif // TGCALLS_UWP_DESKTOP + if (_cameraCapturer) { + _cameraCapturer->setOnFatalError(std::move(error)); + } } void VideoCapturerInterfaceImpl::setOnPause(std::function pause) { #ifdef TGCALLS_UWP_DESKTOP - if (_screenCapturer) { - _screenCapturer->setOnPause(std::move(pause)); - } -#else // TGCALLS_UWP_DESKTOP - if (_desktopCapturer) { - _desktopCapturer->setOnPause(std::move(pause)); - } -#endif // TGCALLS_UWP_DESKTOP + if (_screenCapturer) { + _screenCapturer->setOnPause(std::move(pause)); + } +#else // TGCALLS_UWP_DESKTOP + if (_desktopCapturer) { + _desktopCapturer->setOnPause(std::move(pause)); + } +#endif // TGCALLS_UWP_DESKTOP } -} // namespace lib::ortc +} // namespace lib::ortc diff --git a/src/lib/ortc/webrtc/platform/tdesktop/VideoCapturerInterfaceImpl.h b/src/lib/ortc/webrtc/platform/tdesktop/VideoCapturerInterfaceImpl.h index 5f855706..0c319945 100644 --- a/src/lib/ortc/webrtc/platform/tdesktop/VideoCapturerInterfaceImpl.h +++ b/src/lib/ortc/webrtc/platform/tdesktop/VideoCapturerInterfaceImpl.h @@ -6,7 +6,7 @@ #ifdef TGCALLS_UWP_DESKTOP #include "platform/uwp/UwpContext.h" #include "platform/uwp/UwpScreenCapturer.h" -#endif // TGCALLS_UWP_DESKTOP +#endif // TGCALLS_UWP_DESKTOP #include "api/media_stream_interface.h" @@ -18,38 +18,37 @@ class PlatformContext; class VideoCapturerInterfaceImpl final : public VideoCapturerInterface { public: - VideoCapturerInterfaceImpl( - rtc::scoped_refptr source, - std::string deviceId, - std::function stateUpdated, - std::shared_ptr platformContext, - std::pair &outResolution); - ~VideoCapturerInterfaceImpl() override; - - void setState(VideoState state) override; - void setPreferredCaptureAspectRatio(float aspectRatio) override; - void setUncroppedOutput(std::shared_ptr> sink) override; - int getRotation() override { - return 0; - } - void setOnFatalError(std::function error) override; - void setOnPause(std::function pause) override; + VideoCapturerInterfaceImpl(rtc::scoped_refptr source, + std::string deviceId, + std::function + stateUpdated, + std::shared_ptr + platformContext, + std::pair& outResolution); + ~VideoCapturerInterfaceImpl() override; + + void setState(VideoState state) override; + void setPreferredCaptureAspectRatio(float aspectRatio) override; + void setUncroppedOutput( + std::shared_ptr> sink) override; + int getRotation() override { return 0; } + void setOnFatalError(std::function error) override; + void setOnPause(std::function pause) override; private: - rtc::scoped_refptr _source; - std::shared_ptr> _sink; + rtc::scoped_refptr _source; + std::shared_ptr> _sink; #ifdef TGCALLS_UWP_DESKTOP - std::unique_ptr _screenCapturer; -#else // TGCALLS_UWP_DESKTOP - std::unique_ptr _desktopCapturer; -#endif // TGCALLS_UWP_DESKTOP - std::unique_ptr _cameraCapturer; - std::shared_ptr> _uncroppedSink; - std::function _stateUpdated; - std::function _onFatalError; - + std::unique_ptr _screenCapturer; +#else // TGCALLS_UWP_DESKTOP + std::unique_ptr _desktopCapturer; +#endif // TGCALLS_UWP_DESKTOP + std::unique_ptr _cameraCapturer; + std::shared_ptr> _uncroppedSink; + std::function _stateUpdated; + std::function _onFatalError; }; -} // namespace lib::ortc +} // namespace lib::ortc #endif diff --git a/src/lib/ortc/webrtc/platform/tdesktop/VideoCapturerTrackSource.cpp b/src/lib/ortc/webrtc/platform/tdesktop/VideoCapturerTrackSource.cpp index 3188d73f..d01a5df5 100644 --- a/src/lib/ortc/webrtc/platform/tdesktop/VideoCapturerTrackSource.cpp +++ b/src/lib/ortc/webrtc/platform/tdesktop/VideoCapturerTrackSource.cpp @@ -3,17 +3,16 @@ namespace lib::ortc { VideoCapturerTrackSource::VideoCapturerTrackSource() -: VideoTrackSource(/*remote=*/false) -, _broadcaster(std::make_shared()) { -} + : VideoTrackSource(/*remote=*/false) + , _broadcaster(std::make_shared()) {} auto VideoCapturerTrackSource::sink() --> std::shared_ptr> { - return _broadcaster; + -> std::shared_ptr> { + return _broadcaster; } -rtc::VideoSourceInterface *VideoCapturerTrackSource::source() { - return _broadcaster.get(); +rtc::VideoSourceInterface* VideoCapturerTrackSource::source() { + return _broadcaster.get(); } -} // namespace lib::ortc +} // namespace lib::ortc diff --git a/src/lib/ortc/webrtc/platform/tdesktop/VideoCapturerTrackSource.h b/src/lib/ortc/webrtc/platform/tdesktop/VideoCapturerTrackSource.h index 7434df22..94bdb253 100644 --- a/src/lib/ortc/webrtc/platform/tdesktop/VideoCapturerTrackSource.h +++ b/src/lib/ortc/webrtc/platform/tdesktop/VideoCapturerTrackSource.h @@ -1,9 +1,9 @@ #ifndef TGCALLS_VIDEO_CAPTURER_TRACK_SOURCE_H #define TGCALLS_VIDEO_CAPTURER_TRACK_SOURCE_H -#include "pc/video_track_source.h" #include "api/video/video_sink_interface.h" #include "media/base/video_broadcaster.h" +#include "pc/video_track_source.h" #include "VideoCameraCapturer.h" @@ -14,17 +14,16 @@ class DesktopCapturer; class VideoCapturerTrackSource : public webrtc::VideoTrackSource { public: - VideoCapturerTrackSource(); + VideoCapturerTrackSource(); - std::shared_ptr> sink(); + std::shared_ptr> sink(); private: - rtc::VideoSourceInterface *source() override; - - std::shared_ptr _broadcaster; + rtc::VideoSourceInterface* source() override; + std::shared_ptr _broadcaster; }; -} // namespace lib::ortc +} // namespace lib::ortc #endif diff --git a/src/lib/ortc/webrtc/platform/uwp/UwpContext.h b/src/lib/ortc/webrtc/platform/uwp/UwpContext.h index b65a67b9..82f4d5f8 100644 --- a/src/lib/ortc/webrtc/platform/uwp/UwpContext.h +++ b/src/lib/ortc/webrtc/platform/uwp/UwpContext.h @@ -1,27 +1,22 @@ #ifndef TGCALLS_UWP_PLATFORM_CONTEXT_H #define TGCALLS_UWP_PLATFORM_CONTEXT_H -#include "../PlatformContext.h" #include +#include "../PlatformContext.h" using namespace winrt::Windows::Graphics::Capture; namespace lib::ortc { - class UwpContext : public PlatformContext { - - public: - UwpContext(GraphicsCaptureItem item) - : item(item) - { - - } +class UwpContext : public PlatformContext { +public: + UwpContext(GraphicsCaptureItem item) : item(item) {} - virtual ~UwpContext() = default; + virtual ~UwpContext() = default; - GraphicsCaptureItem item; - }; + GraphicsCaptureItem item; +}; -} // namespace lib::ortc +} // namespace lib::ortc #endif diff --git a/src/lib/ortc/webrtc/platform/uwp/UwpScreenCapturer.cpp b/src/lib/ortc/webrtc/platform/uwp/UwpScreenCapturer.cpp index f3cabe44..24b731e3 100644 --- a/src/lib/ortc/webrtc/platform/uwp/UwpScreenCapturer.cpp +++ b/src/lib/ortc/webrtc/platform/uwp/UwpScreenCapturer.cpp @@ -7,11 +7,11 @@ #include "rtc_base/checks.h" #include "rtc_base/logging.h" +#include +#include #include -#include #include -#include -#include +#include namespace lib::ortc { namespace { @@ -22,276 +22,279 @@ constexpr auto kPreferredFps = 30; // We must use a BGRA pixel format that has 4 bytes per pixel, as required by // the DesktopFrame interface. -constexpr auto kPixelFormat = winrt::Windows::Graphics::DirectX::DirectXPixelFormat::B8G8R8A8UIntNormalized; +constexpr auto kPixelFormat = + winrt::Windows::Graphics::DirectX::DirectXPixelFormat::B8G8R8A8UIntNormalized; // We only want 1 buffer in our frame pool to reduce latency. If we had more, // they would sit in the pool for longer and be stale by the time we are asked // for a new frame. constexpr int kNumBuffers = 1; -} // namespace +} // namespace UwpScreenCapturer::UwpScreenCapturer( - std::shared_ptr> sink, GraphicsCaptureItem item) -: _sink(sink), -item_(item) { -} + std::shared_ptr> sink, GraphicsCaptureItem item) + : _sink(sink), item_(item) {} -UwpScreenCapturer::~UwpScreenCapturer() { - destroy(); -} +UwpScreenCapturer::~UwpScreenCapturer() { destroy(); } void UwpScreenCapturer::create() { - winrt::slim_lock_guard const guard(lock_); - - RTC_DCHECK(!is_capture_started_); - - if (item_closed_) { - RTC_LOG(LS_ERROR) << "The target source has been closed."; - //RecordStartCaptureResult(StartCaptureResult::kSourceClosed); - onFatalError(); - return; - } - - HRESULT hr = D3D11CreateDevice( - /*adapter=*/nullptr, D3D_DRIVER_TYPE_HARDWARE, - /*software_rasterizer=*/nullptr, D3D11_CREATE_DEVICE_BGRA_SUPPORT, - /*feature_levels=*/nullptr, /*feature_levels_size=*/0, D3D11_SDK_VERSION, - d3d11_device_.put(), /*feature_level=*/nullptr, /*device_context=*/nullptr); - if (hr == DXGI_ERROR_UNSUPPORTED) { - // If a hardware device could not be created, use WARP which is a high speed - // software device. - hr = D3D11CreateDevice( - /*adapter=*/nullptr, D3D_DRIVER_TYPE_WARP, - /*software_rasterizer=*/nullptr, D3D11_CREATE_DEVICE_BGRA_SUPPORT, - /*feature_levels=*/nullptr, /*feature_levels_size=*/0, - D3D11_SDK_VERSION, d3d11_device_.put(), /*feature_level=*/nullptr, - /*device_context=*/nullptr); - } - - RTC_DCHECK(d3d11_device_); - RTC_DCHECK(item_); - - // Listen for the Closed event, to detect if the source we are capturing is - // closed (e.g. application window is closed or monitor is disconnected). If - // it is, we should abort the capture. - item_.Closed({ this, &UwpScreenCapturer::OnClosed }); - - winrt::com_ptr dxgi_device; - hr = d3d11_device_->QueryInterface(IID_PPV_ARGS(&dxgi_device)); - if (FAILED(hr)) { - //RecordStartCaptureResult(StartCaptureResult::kDxgiDeviceCastFailed); - onFatalError(); - return; - } - - hr = CreateDirect3D11DeviceFromDXGIDevice(dxgi_device.get(), direct3d_device_.put()); - if (FAILED(hr)) { - //RecordStartCaptureResult(StartCaptureResult::kD3dDeviceCreationFailed); - onFatalError(); - return; - } - - // Cast to FramePoolStatics2 so we can use CreateFreeThreaded and avoid the - // need to have a DispatcherQueue. We don't listen for the FrameArrived event, - // so there's no difference. - - previous_size_ = item_.Size(); - _dimensions = std::make_pair(previous_size_.Width, previous_size_.Height); - - winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice directDevice; - direct3d_device_->QueryInterface(winrt::guid_of(), winrt::put_abi(directDevice)); - - frame_pool_ = Direct3D11CaptureFramePool::CreateFreeThreaded(directDevice, kPixelFormat, kNumBuffers, previous_size_); - //frame_pool_.FrameArrived({ this, &UwpScreenCapturer::OnFrameArrived }); - - session_ = frame_pool_.CreateCaptureSession(item_); - session_.StartCapture(); - - is_capture_started_ = true; - queueController_ = DispatcherQueueController::CreateOnDedicatedThread(); - queue_ = queueController_.DispatcherQueue(); - - repeatingTimer_ = queue_.CreateTimer(); - repeatingTimer_.Interval(std::chrono::milliseconds{ 1000 / kPreferredFps }); - repeatingTimer_.Tick({this, &UwpScreenCapturer::OnFrameArrived}); - repeatingTimer_.Start(); + winrt::slim_lock_guard const guard(lock_); + + RTC_DCHECK(!is_capture_started_); + + if (item_closed_) { + RTC_LOG(LS_ERROR) << "The target source has been closed."; + // RecordStartCaptureResult(StartCaptureResult::kSourceClosed); + onFatalError(); + return; + } + + HRESULT hr = D3D11CreateDevice( + /*adapter=*/nullptr, D3D_DRIVER_TYPE_HARDWARE, + /*software_rasterizer=*/nullptr, D3D11_CREATE_DEVICE_BGRA_SUPPORT, + /*feature_levels=*/nullptr, /*feature_levels_size=*/0, D3D11_SDK_VERSION, + d3d11_device_.put(), /*feature_level=*/nullptr, /*device_context=*/nullptr); + if (hr == DXGI_ERROR_UNSUPPORTED) { + // If a hardware device could not be created, use WARP which is a high speed + // software device. + hr = D3D11CreateDevice( + /*adapter=*/nullptr, D3D_DRIVER_TYPE_WARP, + /*software_rasterizer=*/nullptr, D3D11_CREATE_DEVICE_BGRA_SUPPORT, + /*feature_levels=*/nullptr, /*feature_levels_size=*/0, D3D11_SDK_VERSION, + d3d11_device_.put(), /*feature_level=*/nullptr, + /*device_context=*/nullptr); + } + + RTC_DCHECK(d3d11_device_); + RTC_DCHECK(item_); + + // Listen for the Closed event, to detect if the source we are capturing is + // closed (e.g. application window is closed or monitor is disconnected). If + // it is, we should abort the capture. + item_.Closed({this, &UwpScreenCapturer::OnClosed}); + + winrt::com_ptr dxgi_device; + hr = d3d11_device_->QueryInterface(IID_PPV_ARGS(&dxgi_device)); + if (FAILED(hr)) { + // RecordStartCaptureResult(StartCaptureResult::kDxgiDeviceCastFailed); + onFatalError(); + return; + } + + hr = CreateDirect3D11DeviceFromDXGIDevice(dxgi_device.get(), direct3d_device_.put()); + if (FAILED(hr)) { + // RecordStartCaptureResult(StartCaptureResult::kD3dDeviceCreationFailed); + onFatalError(); + return; + } + + // Cast to FramePoolStatics2 so we can use CreateFreeThreaded and avoid the + // need to have a DispatcherQueue. We don't listen for the FrameArrived event, + // so there's no difference. + + previous_size_ = item_.Size(); + _dimensions = std::make_pair(previous_size_.Width, previous_size_.Height); + + winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice directDevice; + direct3d_device_->QueryInterface( + winrt::guid_of(), + winrt::put_abi(directDevice)); + + frame_pool_ = Direct3D11CaptureFramePool::CreateFreeThreaded(directDevice, kPixelFormat, + kNumBuffers, previous_size_); + // frame_pool_.FrameArrived({ this, &UwpScreenCapturer::OnFrameArrived }); + + session_ = frame_pool_.CreateCaptureSession(item_); + session_.StartCapture(); + + is_capture_started_ = true; + queueController_ = DispatcherQueueController::CreateOnDedicatedThread(); + queue_ = queueController_.DispatcherQueue(); + + repeatingTimer_ = queue_.CreateTimer(); + repeatingTimer_.Interval(std::chrono::milliseconds{1000 / kPreferredFps}); + repeatingTimer_.Tick({this, &UwpScreenCapturer::OnFrameArrived}); + repeatingTimer_.Start(); } -//void UwpScreenCapturer::OnFrameArrived(Direct3D11CaptureFramePool const& sender, winrt::Windows::Foundation::IInspectable const&) { -void UwpScreenCapturer::OnFrameArrived(DispatcherQueueTimer const& sender, winrt::Windows::Foundation::IInspectable const& args) { - winrt::slim_lock_guard const guard(lock_); - - if (item_closed_ || _state != VideoState::Active) { - RTC_LOG(LS_ERROR) << "The target source has been closed."; - onFatalError(); - return; - } - - RTC_DCHECK(is_capture_started_); - - auto capture_frame = frame_pool_.TryGetNextFrame(); - if (!capture_frame) { - // When resuming the capture after minimizing a window there seems to be a subsequent - // frame drop, as I'm lazing to deal with this from here this event is debounced in C# code. - if (!_paused) { - _paused = true; - - if (_onPause){ - _onPause(true); - } - } - - //RecordGetFrameResult(GetFrameResult::kFrameDropped); - return /*hr*/; - } - - if (_paused) { - _paused = false; - - if (_onPause){ - _onPause(false); - } - } - - // We need to get this CaptureFrame as an ID3D11Texture2D so that we can get - // the raw image data in the format required by the DesktopFrame interface. - auto d3d_surface = capture_frame.Surface(); - - auto direct3DDxgiInterfaceAccess - = d3d_surface.as(); - - winrt::com_ptr texture_2D; - auto hr = direct3DDxgiInterfaceAccess->GetInterface(IID_PPV_ARGS(&texture_2D)); - if (FAILED(hr)) { - //RecordGetFrameResult(GetFrameResult::kTexture2dCastFailed); - onFatalError(); - return; - } - - if (!mapped_texture_) { - hr = CreateMappedTexture(texture_2D); - if (FAILED(hr)) { - //RecordGetFrameResult(GetFrameResult::kCreateMappedTextureFailed); - onFatalError(); - return; - } - } - - //// We need to copy |texture_2D| into |mapped_texture_| as the latter has the - //// D3D11_CPU_ACCESS_READ flag set, which lets us access the image data. - //// Otherwise it would only be readable by the GPU. - winrt::com_ptr d3d_context; - d3d11_device_->GetImmediateContext(d3d_context.put()); - d3d_context->CopyResource(mapped_texture_.get(), texture_2D.get()); - - D3D11_MAPPED_SUBRESOURCE map_info; - hr = d3d_context->Map(mapped_texture_.get(), /*subresource_index=*/0, - D3D11_MAP_READ, /*D3D11_MAP_FLAG_DO_NOT_WAIT=*/0, - &map_info); - if (FAILED(hr)) { - //RecordGetFrameResult(GetFrameResult::kMapFrameFailed); - onFatalError(); - return; - } - - auto new_size = capture_frame.ContentSize(); - - // If the size has changed since the last capture, we must be sure to use - // the smaller dimensions. Otherwise we might overrun our buffer, or - // read stale data from the last frame. - int image_height = std::min(previous_size_.Height, new_size.Height); - int image_width = std::min(previous_size_.Width, new_size.Width); - int row_data_length = image_width * 4; - - // Make a copy of the data pointed to by |map_info.pData| so we are free to - // unmap our texture. - uint8_t* src_data = static_cast(map_info.pData); - std::vector image_data; - image_data.reserve(image_height * row_data_length); - uint8_t* image_data_ptr = image_data.data(); - for (int i = 0; i < image_height; i++) { - memcpy(image_data_ptr, src_data, row_data_length); - image_data_ptr += row_data_length; - src_data += map_info.RowPitch; - } - - // Transfer ownership of |image_data| to the output_frame. - OnFrame(std::move(image_data), image_width, image_height); - - d3d_context->Unmap(mapped_texture_.get(), 0); - - // If the size changed, we must resize the texture and frame pool to fit the - // new size. - if (previous_size_.Height != new_size.Height || - previous_size_.Width != new_size.Width) { - hr = CreateMappedTexture(texture_2D, new_size.Width, new_size.Height); - if (FAILED(hr)) { - //RecordGetFrameResult(GetFrameResult::kResizeMappedTextureFailed); - onFatalError(); - return; - } - - winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice directDevice; - direct3d_device_->QueryInterface(winrt::guid_of(), winrt::put_abi(directDevice)); - - frame_pool_.Recreate(directDevice, kPixelFormat, kNumBuffers, new_size); - } - - //RecordGetFrameResult(GetFrameResult::kSuccess); - - previous_size_ = new_size; +// void UwpScreenCapturer::OnFrameArrived(Direct3D11CaptureFramePool const& sender, +// winrt::Windows::Foundation::IInspectable const&) { +void UwpScreenCapturer::OnFrameArrived(DispatcherQueueTimer const& sender, + winrt::Windows::Foundation::IInspectable const& args) { + winrt::slim_lock_guard const guard(lock_); + + if (item_closed_ || _state != VideoState::Active) { + RTC_LOG(LS_ERROR) << "The target source has been closed."; + onFatalError(); + return; + } + + RTC_DCHECK(is_capture_started_); + + auto capture_frame = frame_pool_.TryGetNextFrame(); + if (!capture_frame) { + // When resuming the capture after minimizing a window there seems to be a subsequent + // frame drop, as I'm lazing to deal with this from here this event is debounced in C# code. + if (!_paused) { + _paused = true; + + if (_onPause) { + _onPause(true); + } + } + + // RecordGetFrameResult(GetFrameResult::kFrameDropped); + return /*hr*/; + } + + if (_paused) { + _paused = false; + + if (_onPause) { + _onPause(false); + } + } + + // We need to get this CaptureFrame as an ID3D11Texture2D so that we can get + // the raw image data in the format required by the DesktopFrame interface. + auto d3d_surface = capture_frame.Surface(); + + auto direct3DDxgiInterfaceAccess = + d3d_surface.as(); + + winrt::com_ptr texture_2D; + auto hr = direct3DDxgiInterfaceAccess->GetInterface(IID_PPV_ARGS(&texture_2D)); + if (FAILED(hr)) { + // RecordGetFrameResult(GetFrameResult::kTexture2dCastFailed); + onFatalError(); + return; + } + + if (!mapped_texture_) { + hr = CreateMappedTexture(texture_2D); + if (FAILED(hr)) { + // RecordGetFrameResult(GetFrameResult::kCreateMappedTextureFailed); + onFatalError(); + return; + } + } + + //// We need to copy |texture_2D| into |mapped_texture_| as the latter has the + //// D3D11_CPU_ACCESS_READ flag set, which lets us access the image data. + //// Otherwise it would only be readable by the GPU. + winrt::com_ptr d3d_context; + d3d11_device_->GetImmediateContext(d3d_context.put()); + d3d_context->CopyResource(mapped_texture_.get(), texture_2D.get()); + + D3D11_MAPPED_SUBRESOURCE map_info; + hr = d3d_context->Map(mapped_texture_.get(), /*subresource_index=*/0, D3D11_MAP_READ, + /*D3D11_MAP_FLAG_DO_NOT_WAIT=*/0, &map_info); + if (FAILED(hr)) { + // RecordGetFrameResult(GetFrameResult::kMapFrameFailed); + onFatalError(); + return; + } + + auto new_size = capture_frame.ContentSize(); + + // If the size has changed since the last capture, we must be sure to use + // the smaller dimensions. Otherwise we might overrun our buffer, or + // read stale data from the last frame. + int image_height = std::min(previous_size_.Height, new_size.Height); + int image_width = std::min(previous_size_.Width, new_size.Width); + int row_data_length = image_width * 4; + + // Make a copy of the data pointed to by |map_info.pData| so we are free to + // unmap our texture. + uint8_t* src_data = static_cast(map_info.pData); + std::vector image_data; + image_data.reserve(image_height * row_data_length); + uint8_t* image_data_ptr = image_data.data(); + for (int i = 0; i < image_height; i++) { + memcpy(image_data_ptr, src_data, row_data_length); + image_data_ptr += row_data_length; + src_data += map_info.RowPitch; + } + + // Transfer ownership of |image_data| to the output_frame. + OnFrame(std::move(image_data), image_width, image_height); + + d3d_context->Unmap(mapped_texture_.get(), 0); + + // If the size changed, we must resize the texture and frame pool to fit the + // new size. + if (previous_size_.Height != new_size.Height || previous_size_.Width != new_size.Width) { + hr = CreateMappedTexture(texture_2D, new_size.Width, new_size.Height); + if (FAILED(hr)) { + // RecordGetFrameResult(GetFrameResult::kResizeMappedTextureFailed); + onFatalError(); + return; + } + + winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice directDevice; + direct3d_device_->QueryInterface( + winrt::guid_of(), + winrt::put_abi(directDevice)); + + frame_pool_.Recreate(directDevice, kPixelFormat, kNumBuffers, new_size); + } + + // RecordGetFrameResult(GetFrameResult::kSuccess); + + previous_size_ = new_size; } -void UwpScreenCapturer::OnClosed(GraphicsCaptureItem const& sender, winrt::Windows::Foundation::IInspectable const&) -{ - winrt::slim_lock_guard const guard(lock_); +void UwpScreenCapturer::OnClosed(GraphicsCaptureItem const& sender, + winrt::Windows::Foundation::IInspectable const&) { + winrt::slim_lock_guard const guard(lock_); - RTC_LOG(LS_INFO) << "Capture target has been closed."; - item_closed_ = true; - is_capture_started_ = false; + RTC_LOG(LS_INFO) << "Capture target has been closed."; + item_closed_ = true; + is_capture_started_ = false; - onFatalError(); + onFatalError(); } -HRESULT UwpScreenCapturer::CreateMappedTexture(winrt::com_ptr src_texture, UINT width, UINT height) { - if (mapped_texture_ != nullptr) { - mapped_texture_ = nullptr; - } - - D3D11_TEXTURE2D_DESC src_desc; - src_texture->GetDesc(&src_desc); - D3D11_TEXTURE2D_DESC map_desc; - map_desc.Width = width == 0 ? src_desc.Width : width; - map_desc.Height = height == 0 ? src_desc.Height : height; - map_desc.MipLevels = src_desc.MipLevels; - map_desc.ArraySize = src_desc.ArraySize; - map_desc.Format = src_desc.Format; - map_desc.SampleDesc = src_desc.SampleDesc; - map_desc.Usage = D3D11_USAGE_STAGING; - map_desc.BindFlags = 0; - map_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - map_desc.MiscFlags = 0; - return d3d11_device_->CreateTexture2D(&map_desc, nullptr, mapped_texture_.put()); +HRESULT UwpScreenCapturer::CreateMappedTexture(winrt::com_ptr src_texture, + UINT width, UINT height) { + if (mapped_texture_ != nullptr) { + mapped_texture_ = nullptr; + } + + D3D11_TEXTURE2D_DESC src_desc; + src_texture->GetDesc(&src_desc); + D3D11_TEXTURE2D_DESC map_desc; + map_desc.Width = width == 0 ? src_desc.Width : width; + map_desc.Height = height == 0 ? src_desc.Height : height; + map_desc.MipLevels = src_desc.MipLevels; + map_desc.ArraySize = src_desc.ArraySize; + map_desc.Format = src_desc.Format; + map_desc.SampleDesc = src_desc.SampleDesc; + map_desc.Usage = D3D11_USAGE_STAGING; + map_desc.BindFlags = 0; + map_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + map_desc.MiscFlags = 0; + return d3d11_device_->CreateTexture2D(&map_desc, nullptr, mapped_texture_.put()); } void UwpScreenCapturer::setState(VideoState state) { - if (_state == state) { - return; - } - _state = state; - if (_state == VideoState::Active) { - create(); - } else { - destroy(); - } + if (_state == state) { + return; + } + _state = state; + if (_state == VideoState::Active) { + create(); + } else { + destroy(); + } } void UwpScreenCapturer::setPreferredCaptureAspectRatio(float aspectRatio) { - _aspectRatio = aspectRatio; + _aspectRatio = aspectRatio; } -void UwpScreenCapturer::setOnFatalError(std::function error) { +void UwpScreenCapturer::setOnFatalError(std::function error) { if (_fatalError) { error(); } else { @@ -300,96 +303,90 @@ void UwpScreenCapturer::setOnFatalError(std::function error) { } void UwpScreenCapturer::setOnPause(std::function pause) { - if (_paused) { - pause(true); - } + if (_paused) { + pause(true); + } - _onPause = std::move(pause); + _onPause = std::move(pause); } -std::pair UwpScreenCapturer::resolution() const { - return _dimensions; -} +std::pair UwpScreenCapturer::resolution() const { return _dimensions; } void UwpScreenCapturer::onFatalError() { - if (repeatingTimer_ != nullptr) { - repeatingTimer_.Stop(); - repeatingTimer_ = nullptr; - queue_ = nullptr; - queueController_ = nullptr; - } - - if (session_ != nullptr) { - session_.Close(); - item_ = nullptr; - item_closed_ = true; - } - - if (frame_pool_ != nullptr) { - frame_pool_.Close(); - } - - mapped_texture_ = nullptr; - frame_pool_ = nullptr; - session_ = nullptr; - direct3d_device_ = nullptr; - d3d11_device_ = nullptr; - - _fatalError = true; - if (_onFatalError) { - _onFatalError(); - } + if (repeatingTimer_ != nullptr) { + repeatingTimer_.Stop(); + repeatingTimer_ = nullptr; + queue_ = nullptr; + queueController_ = nullptr; + } + + if (session_ != nullptr) { + session_.Close(); + item_ = nullptr; + item_closed_ = true; + } + + if (frame_pool_ != nullptr) { + frame_pool_.Close(); + } + + mapped_texture_ = nullptr; + frame_pool_ = nullptr; + session_ = nullptr; + direct3d_device_ = nullptr; + d3d11_device_ = nullptr; + + _fatalError = true; + if (_onFatalError) { + _onFatalError(); + } } void UwpScreenCapturer::destroy() { - winrt::slim_lock_guard const guard(lock_); + winrt::slim_lock_guard const guard(lock_); - _onFatalError = nullptr; - onFatalError(); + _onFatalError = nullptr; + onFatalError(); } void UwpScreenCapturer::OnFrame(std::vector bytes, int width, int height) { - if (_state != VideoState::Active) { - return; - } - - int dst_width = width & ~1; - int dst_height = abs(height) & ~1; - int dst_stride_y = dst_width; - int dst_stride_uv = (dst_width + 1) / 2; - - uint8_t* plane_y = bytes.data(); - size_t videoFrameLength = bytes.size(); - int32_t stride_y = width * 4; - uint8_t* plane_uv = plane_y + videoFrameLength; - int32_t stride_uv = stride_y / 2; - - rtc::scoped_refptr buffer = webrtc::I420Buffer::Create( - dst_width, dst_height, dst_stride_y, dst_stride_uv, dst_stride_uv); - - const int conversionResult = libyuv::ConvertToI420( - plane_y, videoFrameLength, stride_y, plane_uv, stride_uv, - buffer.get()->MutableDataY(), buffer.get()->StrideY(), - buffer.get()->MutableDataU(), buffer.get()->StrideU(), - buffer.get()->MutableDataV(), buffer.get()->StrideV(), - 0, 0, // No Cropping - width, height, dst_width, dst_height, libyuv::kRotate0, - libyuv::FOURCC_ARGB); - if (conversionResult < 0) { - RTC_LOG(LS_ERROR) << "Failed to convert capture frame from type " - << static_cast(libyuv::FOURCC_ARGB) << "to I420."; - return; - } - - webrtc::VideoFrame captureFrame = - webrtc::VideoFrame::Builder() - .set_video_frame_buffer(buffer) - .set_timestamp_rtp(0) - .set_timestamp_ms(rtc::TimeMillis()) - .set_rotation(webrtc::kVideoRotation_0) - .build(); - - _sink->OnFrame(captureFrame); + if (_state != VideoState::Active) { + return; + } + + int dst_width = width & ~1; + int dst_height = abs(height) & ~1; + int dst_stride_y = dst_width; + int dst_stride_uv = (dst_width + 1) / 2; + + uint8_t* plane_y = bytes.data(); + size_t videoFrameLength = bytes.size(); + int32_t stride_y = width * 4; + uint8_t* plane_uv = plane_y + videoFrameLength; + int32_t stride_uv = stride_y / 2; + + rtc::scoped_refptr buffer = webrtc::I420Buffer::Create( + dst_width, dst_height, dst_stride_y, dst_stride_uv, dst_stride_uv); + + const int conversionResult = libyuv::ConvertToI420( + plane_y, videoFrameLength, stride_y, plane_uv, stride_uv, buffer.get()->MutableDataY(), + buffer.get()->StrideY(), buffer.get()->MutableDataU(), buffer.get()->StrideU(), + buffer.get()->MutableDataV(), buffer.get()->StrideV(), 0, 0, // No Cropping + width, height, dst_width, dst_height, libyuv::kRotate0, libyuv::FOURCC_ARGB); + if (conversionResult < 0) { + RTC_LOG(LS_ERROR) << "Failed to convert capture frame from type " + << static_cast(libyuv::FOURCC_ARGB) << "to I420."; + return; + } + + webrtc::VideoFrame captureFrame = webrtc::VideoFrame::Builder() + .set_video_frame_buffer(buffer) + .set_timestamp_rtp(0) + .set_timestamp_ms(rtc::TimeMillis()) + .set_rotation(webrtc::kVideoRotation_0) + .build(); + + _sink->OnFrame(captureFrame); } } // namespace lib::ortc diff --git a/src/lib/ortc/webrtc/platform/uwp/UwpScreenCapturer.h b/src/lib/ortc/webrtc/platform/uwp/UwpScreenCapturer.h index 8d1d518b..326ed45b 100644 --- a/src/lib/ortc/webrtc/platform/uwp/UwpScreenCapturer.h +++ b/src/lib/ortc/webrtc/platform/uwp/UwpScreenCapturer.h @@ -9,13 +9,13 @@ #include "VideoCaptureInterface.h" +#include #include #include -#include #include -#include #include +#include #include #include @@ -29,53 +29,57 @@ namespace lib::ortc { class UwpScreenCapturer { public: - explicit UwpScreenCapturer( - std::shared_ptr> sink, GraphicsCaptureItem item); - ~UwpScreenCapturer(); + explicit UwpScreenCapturer(std::shared_ptr> sink, + GraphicsCaptureItem item); + ~UwpScreenCapturer(); - void setState(VideoState state); - void setPreferredCaptureAspectRatio(float aspectRatio); - void setOnFatalError(std::function error); - void setOnPause(std::function pause); + void setState(VideoState state); + void setPreferredCaptureAspectRatio(float aspectRatio); + void setOnFatalError(std::function error); + void setOnPause(std::function pause); - std::pair resolution() const; + std::pair resolution() const; private: - void create(); - void destroy(); - - void onFatalError(); - - void OnFrame(std::vector bytes, int width, int height); - - bool item_closed_; - bool is_capture_started_; - SizeInt32 previous_size_; - Direct3D11CaptureFramePool frame_pool_ = nullptr; - GraphicsCaptureItem item_; - GraphicsCaptureSession session_ = nullptr; - winrt::com_ptr d3d11_device_; - winrt::com_ptr direct3d_device_; - winrt::com_ptr mapped_texture_ = nullptr; - winrt::slim_mutex lock_; - DispatcherQueue queue_= nullptr; - DispatcherQueueController queueController_= nullptr; - DispatcherQueueTimer repeatingTimer_= nullptr; - HRESULT CreateMappedTexture(winrt::com_ptr src_texture, UINT width = 0, UINT height = 0); - - //void OnFrameArrived(Direct3D11CaptureFramePool const& sender, winrt::Windows::Foundation::IInspectable const& args); - void OnFrameArrived(DispatcherQueueTimer const& sender, winrt::Windows::Foundation::IInspectable const& args); - void OnClosed(GraphicsCaptureItem const& sender, winrt::Windows::Foundation::IInspectable const& args); - - std::shared_ptr> _sink; - - VideoState _state = VideoState::Inactive; - std::pair _dimensions; - std::function _onFatalError; - bool _fatalError = false; - std::function _onPause; - bool _paused = false; - float _aspectRatio = 0.; + void create(); + void destroy(); + + void onFatalError(); + + void OnFrame(std::vector bytes, int width, int height); + + bool item_closed_; + bool is_capture_started_; + SizeInt32 previous_size_; + Direct3D11CaptureFramePool frame_pool_ = nullptr; + GraphicsCaptureItem item_; + GraphicsCaptureSession session_ = nullptr; + winrt::com_ptr d3d11_device_; + winrt::com_ptr direct3d_device_; + winrt::com_ptr mapped_texture_ = nullptr; + winrt::slim_mutex lock_; + DispatcherQueue queue_ = nullptr; + DispatcherQueueController queueController_ = nullptr; + DispatcherQueueTimer repeatingTimer_ = nullptr; + HRESULT CreateMappedTexture(winrt::com_ptr src_texture, UINT width = 0, + UINT height = 0); + + // void OnFrameArrived(Direct3D11CaptureFramePool const& sender, + // winrt::Windows::Foundation::IInspectable const& args); + void OnFrameArrived(DispatcherQueueTimer const& sender, + winrt::Windows::Foundation::IInspectable const& args); + void OnClosed(GraphicsCaptureItem const& sender, + winrt::Windows::Foundation::IInspectable const& args); + + std::shared_ptr> _sink; + + VideoState _state = VideoState::Inactive; + std::pair _dimensions; + std::function _onFatalError; + bool _fatalError = false; + std::function _onPause; + bool _paused = false; + float _aspectRatio = 0.; }; } // namespace lib::ortc diff --git a/src/lib/ortc/webrtc/webrtc.cpp b/src/lib/ortc/webrtc/webrtc.cpp index 20cf8399..920b94a6 100644 --- a/src/lib/ortc/webrtc/webrtc.cpp +++ b/src/lib/ortc/webrtc/webrtc.cpp @@ -17,62 +17,53 @@ #include #include -#include -#include -#include -#include -#include #include #include #include +#include #include #include -#include #include - +#include +#include +#include +#include +#include namespace lib { namespace ortc { -WebRTC::WebRTC() - : peer_connection_factory{nullptr}, _rtcHandler{nullptr} -{ +WebRTC::WebRTC() : peer_connection_factory{nullptr}, _rtcHandler{nullptr} { _rtcConfig.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan; _rtcConfig.enable_implicit_rollback = false; _rtcConfig.enable_ice_renomination = true; } WebRTC::~WebRTC() { - - - for(auto it : _pcMap){ + for (auto it : _pcMap) { auto c = it.second; delete c; } - - if(isStarted()){ + if (isStarted()) { stop(); } } -bool WebRTC::start() -{ +bool WebRTC::start() { RTC_LOG(LS_INFO) << "Starting the WebRTC..."; // lock start_mtx.lock(); // _logSink(std::make_unique()) // rtc::LogMessage::AddLogToStream(_logSink.get(), rtc::LS_INFO); - rtc::LogMessage::LogToDebug(rtc::LS_INFO); + rtc::LogMessage::LogToDebug(rtc::LS_INFO); // rtc::LogMessage::SetLogToStderr(false); + RTC_LOG(LS_INFO) << "InitializeSSL=>" << rtc::InitializeSSL(); + ; - RTC_LOG(LS_INFO) << "InitializeSSL=>"<SetName("network_thread", this); RTC_LOG(LS_INFO) << "Network thread is started=>" << network_thread->Start(); -// network_thread = std::unique_ptr( threads->getNetworkThread()); + // network_thread = std::unique_ptr( threads->getNetworkThread()); RTC_LOG(LS_INFO) << "Creating worker thread"; worker_thread = rtc::Thread::Create(); RTC_LOG(LS_INFO) << "Worker thread=>" << worker_thread; worker_thread->SetName("worker_thread", this); RTC_LOG(LS_INFO) << "Worker thread is started=>" << worker_thread->Start(); -// network_thread = std::unique_ptr( threads->getWorkerThread()); - + // network_thread = std::unique_ptr( threads->getWorkerThread()); RTC_LOG(LS_INFO) << "Creating signaling thread"; signaling_thread = rtc::Thread::Create(); - RTC_LOG(LS_INFO) << "Signaling thread=>" << signaling_thread;; + RTC_LOG(LS_INFO) << "Signaling thread=>" << signaling_thread; + ; signaling_thread->SetName("signaling_thread", this); RTC_LOG(LS_INFO) << "Signaling thread is started=>" << signaling_thread->Start(); -// signaling_thread = std::unique_ptr( threads->getMediaThread() ); + // signaling_thread = std::unique_ptr( threads->getMediaThread() ); - peer_connection_factory = webrtc::CreatePeerConnectionFactory( - network_thread.get(), /* network_thread */ - worker_thread.get(), /* worker_thread */ - signaling_thread.get(), /* signaling_thread */ - nullptr, /* default_adm */ - webrtc::CreateBuiltinAudioEncoderFactory(), // - webrtc::CreateBuiltinAudioDecoderFactory(), // - webrtc::CreateBuiltinVideoEncoderFactory(), // - webrtc::CreateBuiltinVideoDecoderFactory(), // - nullptr /* audio_mixer */, // - nullptr /* audio_processing */); + peer_connection_factory = + webrtc::CreatePeerConnectionFactory(network_thread.get(), /* network_thread */ + worker_thread.get(), /* worker_thread */ + signaling_thread.get(), /* signaling_thread */ + nullptr, /* default_adm */ + webrtc::CreateBuiltinAudioEncoderFactory(), // + webrtc::CreateBuiltinAudioDecoderFactory(), // + webrtc::CreateBuiltinVideoEncoderFactory(), // + webrtc::CreateBuiltinVideoDecoderFactory(), // + nullptr /* audio_mixer */, // + nullptr /* audio_processing */); - RTC_LOG(LS_INFO) << "peer_connection_factory:" << peer_connection_factory.get(); - - webrtc::PeerConnectionFactoryInterface::Options options; - options.disable_encryption = false; - peer_connection_factory->SetOptions(options); + RTC_LOG(LS_INFO) << "peer_connection_factory:" << peer_connection_factory.get(); + webrtc::PeerConnectionFactoryInterface::Options options; + options.disable_encryption = false; + peer_connection_factory->SetOptions(options); RTC_LOG(LS_INFO) << "Create audio source..."; audioSource = peer_connection_factory->CreateAudioSource(::cricket::AudioOptions()); - RTC_LOG(LS_INFO) << "Audio source is:"<< audioSource.get(); - + RTC_LOG(LS_INFO) << "Audio source is:" << audioSource.get(); RTC_LOG(LS_INFO) << "Create video device..."; auto vdi = webrtc::VideoCaptureFactory::CreateDeviceInfo(); - RTC_LOG(LS_INFO) << "Video capture numbers:"<< vdi->NumberOfDevices(); - + RTC_LOG(LS_INFO) << "Video capture numbers:" << vdi->NumberOfDevices(); + start_mtx.unlock(); - start_mtx.unlock(); - - RTC_LOG(LS_INFO) << "WebRTC has be started."; - return true; + RTC_LOG(LS_INFO) << "WebRTC has be started."; + return true; } -bool WebRTC::stop() -{ +bool WebRTC::stop() { RTC_LOG(LS_INFO) << "WebRTC will be destroy..."; std::lock_guard lock(start_mtx); - - //销毁factory + // 销毁factory peer_connection_factory = nullptr; - //清除ssl + // 清除ssl rtc::CleanupSSL(); RTC_LOG(LS_INFO) << "WebRTC has be destroyed."; return true; } -bool WebRTC::isStarted() -{ - return peer_connection_factory.get(); -} +bool WebRTC::isStarted() { return peer_connection_factory.get(); } -bool WebRTC::ensureStart() -{ - std::lock_guard lock(start_mtx); - return isStarted()? true: start(); +bool WebRTC::ensureStart() { + std::lock_guard lock(start_mtx); + return isStarted() ? true : start(); } -void WebRTC::addRTCHandler( OkRTCHandler *hand) -{ - _rtcHandler = hand; -} +void WebRTC::addRTCHandler(OkRTCHandler* hand) { _rtcHandler = hand; } -bool WebRTC::call(const std::string &peerId, const std::string &sId, - bool video) { - RTC_LOG(LS_INFO) <<"peerId:" << peerId; - return createConductor(peerId, sId, video); +bool WebRTC::call(const std::string& peerId, const std::string& sId, bool video) { + RTC_LOG(LS_INFO) << "peerId:" << peerId; + return createConductor(peerId, sId, video); } -bool WebRTC::quit(const string &peerId) -{ - return false; -} +bool WebRTC::quit(const string& peerId) { return false; } -void WebRTC::setIceOptions(std::list &ices) -{ - for(auto ice: ices){ +void WebRTC::setIceOptions(std::list& ices) { + for (auto ice : ices) { addIceServer(ice); } } -webrtc::SdpType WebRTC::convertToSdpType(JingleSdpType sdpType_) -{ +webrtc::SdpType WebRTC::convertToSdpType(JingleSdpType sdpType_) { webrtc::SdpType t; switch (sdpType_) { - case JingleSdpType::Answer:{ - t = webrtc::SdpType::kAnswer; - break; - } - case JingleSdpType::Offer:{ - t = webrtc::SdpType::kOffer; - break; - } - case JingleSdpType::Rollback:{ - t = webrtc::SdpType::kRollback; - break; - } + case JingleSdpType::Answer: { + t = webrtc::SdpType::kAnswer; + break; + } + case JingleSdpType::Offer: { + t = webrtc::SdpType::kOffer; + break; + } + case JingleSdpType::Rollback: { + t = webrtc::SdpType::kRollback; + break; + } } return t; } -JingleSdpType WebRTC::convertFromSdpType(webrtc::SdpType sdpType) -{ +JingleSdpType WebRTC::convertFromSdpType(webrtc::SdpType sdpType) { JingleSdpType jingleSdpType; switch (sdpType) { - case webrtc::SdpType::kAnswer: - jingleSdpType = JingleSdpType::Answer; - break; - case webrtc::SdpType::kOffer: - jingleSdpType = JingleSdpType::Offer; - break; - case webrtc::SdpType::kPrAnswer: - jingleSdpType = JingleSdpType::Answer; - break; - case webrtc::SdpType::kRollback: - jingleSdpType = JingleSdpType::Rollback; - break; + case webrtc::SdpType::kAnswer: + jingleSdpType = JingleSdpType::Answer; + break; + case webrtc::SdpType::kOffer: + jingleSdpType = JingleSdpType::Offer; + break; + case webrtc::SdpType::kPrAnswer: + jingleSdpType = JingleSdpType::Answer; + break; + case webrtc::SdpType::kRollback: + jingleSdpType = JingleSdpType::Rollback; + break; } return jingleSdpType; } -std::unique_ptr WebRTC::convertToSdp(const OJingleContentAv &context) -{ +std::unique_ptr WebRTC::convertToSdp( + const OJingleContentAv& context) { auto sdpType = convertToSdpType(context.sdpType); auto sessionDescription = std::make_unique<::cricket::SessionDescription>(); - auto &contents = context.contents; - - cricket::ContentGroup group(cricket::GROUP_TYPE_BUNDLE); - - for (const auto &content : contents) { + auto& contents = context.contents; + cricket::ContentGroup group(cricket::GROUP_TYPE_BUNDLE); + for (const auto& content : contents) { group.AddContentName(content.name); - auto &rtp = content.rtp; - auto &iceUdp = content.iceUdp; + auto& rtp = content.rtp; + auto& iceUdp = content.iceUdp; // iceUdp ::cricket::TransportInfo ti; @@ -245,144 +214,134 @@ std::unique_ptr WebRTC::convertToSdp(const ti.description.ice_ufrag = content.iceUdp.ufrag; ti.description.ice_pwd = content.iceUdp.pwd; - - ti.description.identity_fingerprint.reset( - ::cricket::TransportDescription::CopyFingerprint( - rtc::SSLFingerprint::CreateFromRfc4572(content.iceUdp.dtls.hash, content.iceUdp.dtls.fingerprint)) - ); + ti.description.identity_fingerprint.reset(::cricket::TransportDescription::CopyFingerprint( + rtc::SSLFingerprint::CreateFromRfc4572(content.iceUdp.dtls.hash, + content.iceUdp.dtls.fingerprint))); if (iceUdp.dtls.setup == "actpass") { - ti.description.connection_role = ::cricket::CONNECTIONROLE_ACTPASS; + ti.description.connection_role = ::cricket::CONNECTIONROLE_ACTPASS; } else if (iceUdp.dtls.setup == "active") { - ti.description.connection_role = ::cricket::CONNECTIONROLE_ACTIVE; + ti.description.connection_role = ::cricket::CONNECTIONROLE_ACTIVE; } else if (iceUdp.dtls.setup == "passive") { - ti.description.connection_role = ::cricket::CONNECTIONROLE_PASSIVE; + ti.description.connection_role = ::cricket::CONNECTIONROLE_PASSIVE; } else if (iceUdp.dtls.setup == "holdconn") { - ti.description.connection_role = ::cricket::CONNECTIONROLE_HOLDCONN; + ti.description.connection_role = ::cricket::CONNECTIONROLE_HOLDCONN; } else { - ti.description.connection_role = ::cricket::CONNECTIONROLE_NONE; + ti.description.connection_role = ::cricket::CONNECTIONROLE_NONE; } sessionDescription->AddTransportInfo(ti); switch (rtp.media) { - case gloox::Jingle::audio: { - auto acd = std::make_unique<::cricket::AudioContentDescription>(); - for (auto &pt : rtp.payloadTypes) { - ::cricket::AudioCodec ac(pt.id, pt.name, pt.clockrate, pt.bitrate,pt.channels); - for (auto &e : pt.parameters) { - ac.SetParam(e.name, e.value); + case gloox::Jingle::audio: { + auto acd = std::make_unique<::cricket::AudioContentDescription>(); + for (auto& pt : rtp.payloadTypes) { + ::cricket::AudioCodec ac(pt.id, pt.name, pt.clockrate, pt.bitrate, pt.channels); + for (auto& e : pt.parameters) { + ac.SetParam(e.name, e.value); + } + for (auto& e : pt.feedbacks) { + ::cricket::FeedbackParam fb(e.type, e.subtype); + ac.AddFeedbackParam(fb); + } + acd->AddCodec(ac); + } + + for (auto& hdrext : rtp.hdrExts) { + webrtc::RtpExtension ext(hdrext.uri, hdrext.id); + acd->AddRtpHeaderExtension(ext); + } + + ::cricket::StreamParams streamParams; + for (auto& src : rtp.sources) { + streamParams.ssrcs.push_back(std::stoul(src.ssrc)); + for (auto& p : src.parameters) { + if (p.name == "cname") { + streamParams.cname = p.value; + } else if (p.name == "label") { + streamParams.id = p.value; + } else if (p.name == "mslabel") { + streamParams.set_stream_ids({p.value}); + } + }; + } + + auto g = rtp.ssrcGroup; + std::vector ssrcs; + std::transform(g.ssrcs.begin(), g.ssrcs.end(), std::back_inserter(ssrcs), + [](auto s) -> uint32_t { return std::stoul(s); }); + ::cricket::SsrcGroup ssrcGroup(g.semantics, ssrcs); + + // ssrc-groups + streamParams.ssrc_groups.emplace_back(ssrcGroup); + + // ssrc + acd->AddStream(streamParams); + + // rtcp-mux + acd->set_rtcp_mux(rtp.rtcpMux); + + sessionDescription->AddContent(content.name, ::cricket::MediaProtocolType::kRtp, + std::move(acd)); + break; } - for (auto &e : pt.feedbacks) { - ::cricket::FeedbackParam fb(e.type, e.subtype); - ac.AddFeedbackParam(fb); + case gloox::Jingle::video: { + auto vcd = std::make_unique<::cricket::VideoContentDescription>(); + for (auto& pt : rtp.payloadTypes) { + auto vc = ::cricket::VideoCodec(pt.id, pt.name); + for (auto& e : pt.parameters) { + vc.SetParam(e.name, e.value); + } + for (auto& e : pt.feedbacks) { + ::cricket::FeedbackParam fb(e.type, e.subtype); + vc.AddFeedbackParam(fb); + } + vcd->AddCodec(vc); + } + for (auto& hdrExt : rtp.hdrExts) { + webrtc::RtpExtension ext(hdrExt.uri, hdrExt.id); + vcd->AddRtpHeaderExtension(ext); + } + vcd->set_rtcp_mux(rtp.rtcpMux); + + ::cricket::StreamParams streamParams; + for (auto& src : rtp.sources) { + streamParams.ssrcs.push_back(std::stoul(src.ssrc)); + for (auto& p : src.parameters) { + if (p.name == "cname") { + streamParams.cname = p.value; + } else if (p.name == "label") { + streamParams.id = p.value; + } else if (p.name == "mslabel") { + streamParams.set_stream_ids({p.value}); + } + }; + } + + // ssrc-group + auto g = rtp.ssrcGroup; + std::vector ssrcs; + std::transform(g.ssrcs.begin(), g.ssrcs.end(), std::back_inserter(ssrcs), + [](auto s) -> uint32_t { return std::stoul(s); }); + ::cricket::SsrcGroup ssrcGroup(g.semantics, ssrcs); + streamParams.ssrc_groups.emplace_back(ssrcGroup); + vcd->AddStream(streamParams); + + sessionDescription->AddContent(content.name, ::cricket::MediaProtocolType::kRtp, + std::move(vcd)); + break; } - acd->AddCodec(ac); - } - - for (auto &hdrext : rtp.hdrExts) { - webrtc::RtpExtension ext(hdrext.uri, hdrext.id); - acd->AddRtpHeaderExtension(ext); - } - - ::cricket::StreamParams streamParams; - for (auto &src : rtp.sources) { - streamParams.ssrcs.push_back(std::stoul(src.ssrc)); - for (auto &p : src.parameters) { - if (p.name == "cname") { - streamParams.cname = p.value; - } else if (p.name == "label") { - streamParams.id = p.value; - } else if (p.name == "mslabel") { - streamParams.set_stream_ids({p.value}); - } - }; - } - - auto g = rtp.ssrcGroup; - std::vector ssrcs; - std::transform(g.ssrcs.begin(), g.ssrcs.end(), - std::back_inserter(ssrcs), - [](auto s) -> uint32_t { return std::stoul(s); }); - ::cricket::SsrcGroup ssrcGroup(g.semantics, ssrcs); - - // ssrc-groups - streamParams.ssrc_groups.emplace_back(ssrcGroup); - - // ssrc - acd->AddStream(streamParams); - - // rtcp-mux - acd->set_rtcp_mux(rtp.rtcpMux); - - sessionDescription->AddContent(content.name, - ::cricket::MediaProtocolType::kRtp, - std::move(acd)); - break; + default: + break; } - case gloox::Jingle::video: { - auto vcd = std::make_unique<::cricket::VideoContentDescription>(); - for (auto &pt : rtp.payloadTypes) { - auto vc = ::cricket::VideoCodec (pt.id, pt.name); - for (auto &e : pt.parameters) { - vc.SetParam(e.name, e.value); - } - for (auto &e : pt.feedbacks) { - ::cricket::FeedbackParam fb(e.type, e.subtype); - vc.AddFeedbackParam(fb); - } - vcd->AddCodec(vc); - } - for (auto &hdrExt : rtp.hdrExts) { - webrtc::RtpExtension ext(hdrExt.uri, hdrExt.id); - vcd->AddRtpHeaderExtension(ext); - } - vcd->set_rtcp_mux(rtp.rtcpMux); - - ::cricket::StreamParams streamParams; - for (auto &src : rtp.sources) { - streamParams.ssrcs.push_back(std::stoul(src.ssrc)); - for (auto &p : src.parameters) { - if (p.name == "cname") { - streamParams.cname = p.value; - } else if (p.name == "label") { - streamParams.id = p.value; - } else if (p.name == "mslabel") { - streamParams.set_stream_ids({p.value}); - } - }; - } - - // ssrc-group - auto g = rtp.ssrcGroup; - std::vector ssrcs; - std::transform(g.ssrcs.begin(), g.ssrcs.end(), std::back_inserter(ssrcs), - [](auto s) -> uint32_t { return std::stoul(s); }); - ::cricket::SsrcGroup ssrcGroup(g.semantics, ssrcs); - streamParams.ssrc_groups.emplace_back(ssrcGroup); - vcd->AddStream(streamParams); - - sessionDescription->AddContent(content.name, - ::cricket::MediaProtocolType::kRtp, - std::move(vcd)); - break; - } - default: - break; - } - } - - sessionDescription->AddGroup(group); - return webrtc::CreateSessionDescription( - sdpType, - context.sessionId, - context.sessionVersion, - std::move(sessionDescription)); + } + sessionDescription->AddGroup(group); + return webrtc::CreateSessionDescription(sdpType, context.sessionId, context.sessionVersion, + std::move(sessionDescription)); } -OJingleContentAv WebRTC::convertFromSdp(webrtc::SessionDescriptionInterface* desc) -{ +OJingleContentAv WebRTC::convertFromSdp(webrtc::SessionDescriptionInterface* desc) { OJingleContentAv osdp; osdp.sessionId = desc->session_id(); osdp.sessionVersion = desc->session_version(); @@ -392,395 +351,377 @@ OJingleContentAv WebRTC::convertFromSdp(webrtc::SessionDescriptionInterface* des auto sd = desc->description(); for (auto rtcContent : sd->contents()) { - OSdp oContent; - - const std::string &name = rtcContent.mid(); - // qDebug(("Content name: %1").arg(qstring(name))); - - oContent.name = name; - - auto mediaDescription = rtcContent.media_description(); - // media type - auto mt = mediaDescription->type(); - - // rtcp_mux - oContent.rtp.rtcpMux = mediaDescription->rtcp_mux(); - - // Transport - auto ti = sd->GetTransportInfoByName(name); - - // pwd ufrag - oContent.iceUdp.pwd = ti->description.ice_pwd; - oContent.iceUdp.ufrag = ti->description.ice_ufrag; - - // fingerprint - if (ti->description.identity_fingerprint) { - oContent.iceUdp.dtls.fingerprint = - ti->description.identity_fingerprint->GetRfc4572Fingerprint(); - oContent.iceUdp.dtls.hash = - ti->description.identity_fingerprint->algorithm; - - // connection_role - std::string setup; - ::cricket::ConnectionRoleToString(ti->description.connection_role, &setup); - oContent.iceUdp.dtls.setup = setup; - } - - // hdrext - auto hdrs = mediaDescription->rtp_header_extensions(); - - for (auto &hdr : hdrs) { - gloox::Jingle::RTP::HdrExt hdrExt = {hdr.id, hdr.uri}; - oContent.rtp.hdrExts.push_back(hdrExt); - } - - // ssrc - for (auto &stream : mediaDescription->streams()) { - // "{id:5e9a64d8-b9d3-4fc7-a8eb-0ee6dec72138; //track id - // ssrcs:[1679428189,751024037]; - // ssrc_groups:{semantics:FID; ssrcs:[1679428189,751024037]}; - // cname:dBhnE4FRSAUq1FZp; - // stream_ids:okedu-video-id; - // }" - RTC_LOG(LS_INFO) << "stream: " << (stream.ToString()); - - // label - const std::string &first_stream_id = stream.first_stream_id(); - - for (auto &ssrc : stream.ssrcs) { - RTC_LOG(LS_INFO) << "stream_id:" << first_stream_id - << " label:" << stream.id - << " ssrc:" << ssrc; - - gloox::Jingle::RTP::Parameter cname = {"cname", stream.cname}; - gloox::Jingle::RTP::Parameter label = {"label", stream.id}; - gloox::Jingle::RTP::Parameter mslabel = {"mslabel", first_stream_id}; - gloox::Jingle::RTP::Parameter msid = {"msid", first_stream_id + " " + - stream.id}; - - // msid = mslabel+ label(stream.id) - RTP::Parameters parameters; - parameters.emplace_back(cname); - parameters.emplace_back(msid); - parameters.emplace_back(mslabel); - parameters.emplace_back(label); - - gloox::Jingle::RTP::Source source = {std::to_string(ssrc), parameters}; - oContent.rtp.sources.emplace_back(source); + OSdp oContent; + + const std::string& name = rtcContent.mid(); + // qDebug(("Content name: %1").arg(qstring(name))); + + oContent.name = name; + + auto mediaDescription = rtcContent.media_description(); + // media type + auto mt = mediaDescription->type(); + + // rtcp_mux + oContent.rtp.rtcpMux = mediaDescription->rtcp_mux(); + + // Transport + auto ti = sd->GetTransportInfoByName(name); + + // pwd ufrag + oContent.iceUdp.pwd = ti->description.ice_pwd; + oContent.iceUdp.ufrag = ti->description.ice_ufrag; + + // fingerprint + if (ti->description.identity_fingerprint) { + oContent.iceUdp.dtls.fingerprint = + ti->description.identity_fingerprint->GetRfc4572Fingerprint(); + oContent.iceUdp.dtls.hash = ti->description.identity_fingerprint->algorithm; + + // connection_role + std::string setup; + ::cricket::ConnectionRoleToString(ti->description.connection_role, &setup); + oContent.iceUdp.dtls.setup = setup; } - } - // ssrc-group - if (oContent.rtp.sources.size() >= 2) { - oContent.rtp.ssrcGroup.semantics = "FID"; - for (auto &ssrc : oContent.rtp.sources) { - oContent.rtp.ssrcGroup.ssrcs.emplace_back(ssrc.ssrc); + // hdrext + auto hdrs = mediaDescription->rtp_header_extensions(); + + for (auto& hdr : hdrs) { + gloox::Jingle::RTP::HdrExt hdrExt = {hdr.id, hdr.uri}; + oContent.rtp.hdrExts.push_back(hdrExt); } - } - - // codecs - switch (mt) { - case ::cricket::MediaType::MEDIA_TYPE_AUDIO: { - oContent.rtp.media = gloox::Jingle::audio; - auto audio_desc = mediaDescription->as_audio(); - auto codecs = audio_desc->codecs(); - - for (auto &codec : codecs) { - gloox::Jingle::RTP::PayloadType type; - type.id = codec.id; - type.name = codec.name; - type.channels = codec.channels; - type.clockrate = codec.clockrate; - type.bitrate = codec.bitrate; - - auto cps = codec.ToCodecParameters(); - for (auto &it : cps.parameters) { - gloox::Jingle::RTP::Parameter parameter; - if (parameter.name.empty()) - continue; - parameter.name = it.first; - parameter.value = it.second; - type.parameters.emplace_back(parameter); - } - - // rtcp-fb - for (auto &it : codec.feedback_params.params()) { - gloox::Jingle::RTP::Feedback fb = {it.id(), it.param()}; - type.feedbacks.push_back(fb); - } - - oContent.rtp.payloadTypes.emplace_back(type); + + // ssrc + for (auto& stream : mediaDescription->streams()) { + // "{id:5e9a64d8-b9d3-4fc7-a8eb-0ee6dec72138; //track id + // ssrcs:[1679428189,751024037]; + // ssrc_groups:{semantics:FID; ssrcs:[1679428189,751024037]}; + // cname:dBhnE4FRSAUq1FZp; + // stream_ids:okedu-video-id; + // }" + RTC_LOG(LS_INFO) << "stream: " << (stream.ToString()); + + // label + const std::string& first_stream_id = stream.first_stream_id(); + + for (auto& ssrc : stream.ssrcs) { + RTC_LOG(LS_INFO) << "stream_id:" << first_stream_id << " label:" << stream.id + << " ssrc:" << ssrc; + + gloox::Jingle::RTP::Parameter cname = {"cname", stream.cname}; + gloox::Jingle::RTP::Parameter label = {"label", stream.id}; + gloox::Jingle::RTP::Parameter mslabel = {"mslabel", first_stream_id}; + gloox::Jingle::RTP::Parameter msid = {"msid", first_stream_id + " " + stream.id}; + + // msid = mslabel+ label(stream.id) + RTP::Parameters parameters; + parameters.emplace_back(cname); + parameters.emplace_back(msid); + parameters.emplace_back(mslabel); + parameters.emplace_back(label); + + gloox::Jingle::RTP::Source source = {std::to_string(ssrc), parameters}; + oContent.rtp.sources.emplace_back(source); + } } - break; - } - case ::cricket::MediaType::MEDIA_TYPE_VIDEO: { - oContent.rtp.media = (gloox::Jingle::video); - auto video_desc = mediaDescription->as_video(); - for (auto &codec : video_desc->codecs()) { - // PayloadType - gloox::Jingle::RTP::PayloadType type; - type.id = codec.id; - type.name = codec.name; - type.clockrate = codec.clockrate; - - // PayloadType parameter - auto cps = codec.ToCodecParameters(); - for (auto &it : cps.parameters) { - gloox::Jingle::RTP::Parameter parameter; - parameter.name = it.first; - parameter.value = it.second; - type.parameters.emplace_back(parameter); - } - - // rtcp-fb - for (auto &it : codec.feedback_params.params()) { - gloox::Jingle::RTP::Feedback fb = {it.id(), it.param()}; - type.feedbacks.push_back(fb); - } - - oContent.rtp.payloadTypes.emplace_back(type); + // ssrc-group + if (oContent.rtp.sources.size() >= 2) { + oContent.rtp.ssrcGroup.semantics = "FID"; + for (auto& ssrc : oContent.rtp.sources) { + oContent.rtp.ssrcGroup.ssrcs.emplace_back(ssrc.ssrc); + } } - break; - } - case ::cricket::MediaType::MEDIA_TYPE_DATA: { - break; - } - case cricket::MEDIA_TYPE_UNSUPPORTED: - break; - } - - osdp.contents.push_back(oContent); + + // codecs + switch (mt) { + case ::cricket::MediaType::MEDIA_TYPE_AUDIO: { + oContent.rtp.media = gloox::Jingle::audio; + auto audio_desc = mediaDescription->as_audio(); + auto codecs = audio_desc->codecs(); + + for (auto& codec : codecs) { + gloox::Jingle::RTP::PayloadType type; + type.id = codec.id; + type.name = codec.name; + type.channels = codec.channels; + type.clockrate = codec.clockrate; + type.bitrate = codec.bitrate; + + auto cps = codec.ToCodecParameters(); + for (auto& it : cps.parameters) { + gloox::Jingle::RTP::Parameter parameter; + if (parameter.name.empty()) continue; + parameter.name = it.first; + parameter.value = it.second; + type.parameters.emplace_back(parameter); + } + + // rtcp-fb + for (auto& it : codec.feedback_params.params()) { + gloox::Jingle::RTP::Feedback fb = {it.id(), it.param()}; + type.feedbacks.push_back(fb); + } + + oContent.rtp.payloadTypes.emplace_back(type); + } + + break; + } + case ::cricket::MediaType::MEDIA_TYPE_VIDEO: { + oContent.rtp.media = (gloox::Jingle::video); + auto video_desc = mediaDescription->as_video(); + for (auto& codec : video_desc->codecs()) { + // PayloadType + gloox::Jingle::RTP::PayloadType type; + type.id = codec.id; + type.name = codec.name; + type.clockrate = codec.clockrate; + + // PayloadType parameter + auto cps = codec.ToCodecParameters(); + for (auto& it : cps.parameters) { + gloox::Jingle::RTP::Parameter parameter; + parameter.name = it.first; + parameter.value = it.second; + type.parameters.emplace_back(parameter); + } + + // rtcp-fb + for (auto& it : codec.feedback_params.params()) { + gloox::Jingle::RTP::Feedback fb = {it.id(), it.param()}; + type.feedbacks.push_back(fb); + } + + oContent.rtp.payloadTypes.emplace_back(type); + } + break; + } + case ::cricket::MediaType::MEDIA_TYPE_DATA: { + break; + } + case cricket::MEDIA_TYPE_UNSUPPORTED: + break; + } + + osdp.contents.push_back(oContent); } return osdp; } - -void WebRTC::addIceServer(const IceServer &ice) -{ +void WebRTC::addIceServer(const IceServer& ice) { // Add the ice server. webrtc::PeerConnectionInterface::IceServer ss; ss.urls.push_back(ice.uri); ss.tls_cert_policy = webrtc::PeerConnectionInterface::kTlsCertPolicyInsecureNoCheck; if (!ice.username.empty()) { - ss.username = ice.username; - ss.password = ice.password; + ss.username = ice.username; + ss.password = ice.password; } _rtcConfig.servers.push_back(ss); } -Conductor *WebRTC::getConductor(const std::string &peerId) { - return _pcMap[peerId]; -} - -Conductor *WebRTC::createConductor(const std::string &peerId, const std::string &sId, bool video) { - - RTC_LOG_F(LS_INFO) << "peer:" << peerId << " sid:" << sId << " video:" << video; - - auto conductor = _pcMap[peerId]; - if(conductor){ - return conductor; - } - - conductor = new Conductor(this, peerId, sId); - _pcMap[peerId]= conductor; - - if (!video) { - //audio - RTC_DLOG_V(rtc::LS_INFO) << "AddTrack audio..." << audioSource.get(); - conductor->AddAudioTrack(audioSource.get()); - } else { - //video - RTC_DLOG_V(rtc::LS_INFO) << "AddTrack audio..." << audioSource.get(); - conductor->AddAudioTrack(audioSource.get()); - - auto vdi = webrtc::VideoCaptureFactory::CreateDeviceInfo(); - int num_devices = vdi->NumberOfDevices(); - RTC_LOG(LS_INFO) << "Get number of video devices:" << num_devices; +Conductor* WebRTC::getConductor(const std::string& peerId) { return _pcMap[peerId]; } - if(0 < num_devices){ - //获取第一个视频设备 - int selected = 0; +Conductor* WebRTC::createConductor(const std::string& peerId, const std::string& sId, bool video) { + RTC_LOG_F(LS_INFO) << "peer:" << peerId << " sid:" << sId << " video:" << video; - char name[50] = {0}; - char uid[50] = {0}; - char puid[50] = {0}; - vdi->GetDeviceName(selected, name, 50, uid, 50, puid, 50); - RTC_LOG(LS_INFO) << "Video device:" << name; - RTC_LOG(LS_INFO) << "Video device uid:" << uid; + auto conductor = _pcMap[peerId]; + if (conductor) { + return conductor; + } - videoCapture = createVideoCapture(uid); - conductor->AddVideoTrack(videoCapture->source().get()); + conductor = new Conductor(this, peerId, sId); + _pcMap[peerId] = conductor; - sink = std::make_shared (_rtcHandler); - videoCapture->setOutput(sink); + if (!video) { + // audio + RTC_DLOG_V(rtc::LS_INFO) << "AddTrack audio..." << audioSource.get(); + conductor->AddAudioTrack(audioSource.get()); + } else { + // video + RTC_DLOG_V(rtc::LS_INFO) << "AddTrack audio..." << audioSource.get(); + conductor->AddAudioTrack(audioSource.get()); + + auto vdi = webrtc::VideoCaptureFactory::CreateDeviceInfo(); + int num_devices = vdi->NumberOfDevices(); + RTC_LOG(LS_INFO) << "Get number of video devices:" << num_devices; + + if (0 < num_devices) { + // 获取第一个视频设备 + int selected = 0; + + char name[50] = {0}; + char uid[50] = {0}; + char puid[50] = {0}; + vdi->GetDeviceName(selected, name, 50, uid, 50, puid, 50); + RTC_LOG(LS_INFO) << "Video device:" << name; + RTC_LOG(LS_INFO) << "Video device uid:" << uid; + + videoCapture = createVideoCapture(uid); + conductor->AddVideoTrack(videoCapture->source().get()); + + sink = std::make_shared(_rtcHandler); + videoCapture->setOutput(sink); + } } - } - return conductor; + return conductor; } -void WebRTC::setRemoteDescription(const std::string &peerId, const OJingleContentAv &jingleContext) { - auto conductor = getConductor(peerId); - conductor->SetRemoteDescription(std::move(convertToSdp(jingleContext))); +void WebRTC::setRemoteDescription(const std::string& peerId, + const OJingleContentAv& jingleContext) { + auto conductor = getConductor(peerId); + conductor->SetRemoteDescription(std::move(convertToSdp(jingleContext))); } -void WebRTC::setTransportInfo(const std::string &peerId, - const std::string &sId, - const ortc::OIceUdp &iceUdp) { +void WebRTC::setTransportInfo(const std::string& peerId, + const std::string& sId, + const ortc::OIceUdp& iceUdp) { + RTC_LOG_F(LS_INFO) << "peerId:" << peerId; - RTC_LOG_F(LS_INFO) << "peerId:"<< peerId; - - Conductor *conductor = createConductor(peerId, sId, false); + Conductor* conductor = createConductor(peerId, sId, false); if (!conductor) { - RTC_LOG_F(LS_WARNING) << "conductor is null!"; - return; + RTC_LOG_F(LS_WARNING) << "conductor is null!"; + return; } - int i = 0; - for (auto &_candidate : iceUdp.candidates) { - ::cricket::Candidate candidate; - if (!_candidate.id.empty()) { - candidate.set_id(_candidate.id); - } else { - candidate.set_id(std::to_string(i)); - } - if (_candidate.component.empty()) { - return; - } - if (_candidate.generation.empty()) { - return; - } + int i = 0; + for (auto& _candidate : iceUdp.candidates) { + ::cricket::Candidate candidate; + if (!_candidate.id.empty()) { + candidate.set_id(_candidate.id); + } else { + candidate.set_id(std::to_string(i)); + } + if (_candidate.component.empty()) { + return; + } + if (_candidate.generation.empty()) { + return; + } - candidate.set_foundation(_candidate.foundation); - candidate.set_component(std::stoi(_candidate.component)); - candidate.set_tcptype(_candidate.tcptype); // passive - candidate.set_protocol(_candidate.protocol); // udp,ssltcp - candidate.set_priority(_candidate.priority); - candidate.set_generation(std::stoi(_candidate.generation)); + candidate.set_foundation(_candidate.foundation); + candidate.set_component(std::stoi(_candidate.component)); + candidate.set_tcptype(_candidate.tcptype); // passive + candidate.set_protocol(_candidate.protocol); // udp,ssltcp + candidate.set_priority(_candidate.priority); + candidate.set_generation(std::stoi(_candidate.generation)); - if (!_candidate.network.empty()) { - candidate.set_network_id(std::stoi(_candidate.network)); - } else { - candidate.set_network_id(i); - } + if (!_candidate.network.empty()) { + candidate.set_network_id(std::stoi(_candidate.network)); + } else { + candidate.set_network_id(i); + } - candidate.set_address(::rtc::SocketAddress(_candidate.ip, _candidate.port)); - - /** - * const auto& host = LOCAL_PORT_TYPE; - const auto& srflx = STUN_PORT_TYPE; - const auto& relay = RELAY_PORT_TYPE; - const auto& prflx = PRFLX_PORT_TYPE; - */ - - switch (_candidate.type) { - case gloox::Jingle::ICEUDP::Type::Host: - candidate.set_type(::cricket::LOCAL_PORT_TYPE); - break; - case gloox::Jingle::ICEUDP::Type::PeerReflexive: - candidate.set_type(::cricket::PRFLX_PORT_TYPE); - break; - case gloox::Jingle::ICEUDP::Type::Relayed: - candidate.set_type(::cricket::RELAY_PORT_TYPE); - break; - case gloox::Jingle::ICEUDP::Type::ServerReflexive: - candidate.set_type(::cricket::STUN_PORT_TYPE); - break; - } - if (!_candidate.rel_addr.empty()) { - rtc::SocketAddress raddr; - raddr.SetIP(_candidate.rel_addr); - raddr.SetPort(_candidate.rel_port); - candidate.set_related_address(raddr); - } + candidate.set_address(::rtc::SocketAddress(_candidate.ip, _candidate.port)); + + /** + * const auto& host = LOCAL_PORT_TYPE; + const auto& srflx = STUN_PORT_TYPE; + const auto& relay = RELAY_PORT_TYPE; + const auto& prflx = PRFLX_PORT_TYPE; + */ + + switch (_candidate.type) { + case gloox::Jingle::ICEUDP::Type::Host: + candidate.set_type(::cricket::LOCAL_PORT_TYPE); + break; + case gloox::Jingle::ICEUDP::Type::PeerReflexive: + candidate.set_type(::cricket::PRFLX_PORT_TYPE); + break; + case gloox::Jingle::ICEUDP::Type::Relayed: + candidate.set_type(::cricket::RELAY_PORT_TYPE); + break; + case gloox::Jingle::ICEUDP::Type::ServerReflexive: + candidate.set_type(::cricket::STUN_PORT_TYPE); + break; + } + if (!_candidate.rel_addr.empty()) { + rtc::SocketAddress raddr; + raddr.SetIP(_candidate.rel_addr); + raddr.SetPort(_candidate.rel_port); + candidate.set_related_address(raddr); + } - auto jsep_candidate = webrtc::CreateIceCandidate(iceUdp.mid, iceUdp.mline, candidate); - conductor->setTransportInfo(std::move(jsep_candidate)); - i++; - } + auto jsep_candidate = webrtc::CreateIceCandidate(iceUdp.mid, iceUdp.mline, candidate); + conductor->setTransportInfo(std::move(jsep_candidate)); + i++; + } } void WebRTC::ContentAdd(std::map sdMap, - OkRTCHandler *handler) { -// _c->OnContentAdd(sdMap, handler); + OkRTCHandler* handler) { + // _c->OnContentAdd(sdMap, handler); } void WebRTC::ContentRemove(std::map sdMap, - OkRTCHandler *handler) { - -// _c->OnContentRemove(sdMap, handler); + OkRTCHandler* handler) { + // _c->OnContentRemove(sdMap, handler); } void WebRTC::setMute(bool mute) { - for (auto it : _pcMap) { - it.second->setMute(mute); - } + for (auto it : _pcMap) { + it.second->setMute(mute); + } } void WebRTC::setRemoteMute(bool mute) { - for (auto it : _pcMap) { - it.second->setRemoteMute(mute); - } + for (auto it : _pcMap) { + it.second->setRemoteMute(mute); + } } -void WebRTC::CreateOffer(const std::string &peerId) { - Conductor *conductor = getConductor(peerId); - conductor->CreateOffer(); +void WebRTC::CreateOffer(const std::string& peerId) { + Conductor* conductor = getConductor(peerId); + conductor->CreateOffer(); } -void WebRTC::SessionTerminate(const std::string &peerId) { -// quit(peerId); +void WebRTC::SessionTerminate(const std::string& peerId) { + // quit(peerId); } -void WebRTC::CreateAnswer(const std::string &peerId, - const OJingleContentAv &ca) { - - RTC_LOG_F(LS_INFO) << "peerId:"<< peerId ; - - Conductor *conductor = createConductor(peerId, ca.sessionId, ca.isVideo()); - if (!conductor) { - RTC_LOG_F(LS_WARNING) << "conductor is null!"; - return; - } - //webrtc::SdpType::kOffer, - auto sdp = convertToSdp(ca); - conductor->SetRemoteDescription(std::move(sdp)); - conductor->CreateAnswer(); +void WebRTC::CreateAnswer(const std::string& peerId, const OJingleContentAv& ca) { + RTC_LOG_F(LS_INFO) << "peerId:" << peerId; + Conductor* conductor = createConductor(peerId, ca.sessionId, ca.isVideo()); + if (!conductor) { + RTC_LOG_F(LS_WARNING) << "conductor is null!"; + return; + } + // webrtc::SdpType::kOffer, + auto sdp = convertToSdp(ca); + conductor->SetRemoteDescription(std::move(sdp)); + conductor->CreateAnswer(); } - size_t WebRTC::getVideoSize() { RTC_LOG(LS_INFO) << "Create video device..."; auto vdi = webrtc::VideoCaptureFactory::CreateDeviceInfo(); - RTC_LOG(LS_INFO) << "Video capture numbers:"<< vdi->NumberOfDevices(); + RTC_LOG(LS_INFO) << "Video capture numbers:" << vdi->NumberOfDevices(); return vdi->NumberOfDevices(); } std::shared_ptr WebRTC::createVideoCapture( - std::optional deviceId, - bool isScreenCapture) { - + std::optional deviceId, bool isScreenCapture) { RTC_LOG(LS_INFO) << __FUNCTION__ << " deviceId:" << *deviceId; - if(deviceId->empty()){ + if (deviceId->empty()) { return {}; } -// if (auto result = videoCapture.get()) { -// if (deviceId) { -// result->switchToDevice(*deviceId, isScreenCapture); -// } -// return videoCapture; -// } - - - return VideoCaptureInterface::Create(signaling_thread.get(), worker_thread.get(), *deviceId); + // if (auto result = videoCapture.get()) { + // if (deviceId) { + // result->switchToDevice(*deviceId, isScreenCapture); + // } + // return videoCapture; + // } + return VideoCaptureInterface::Create(signaling_thread.get(), worker_thread.get(), *deviceId); } -} // namespace ortc -} // namespace lib +} // namespace ortc +} // namespace lib diff --git a/src/lib/ortc/webrtc/webrtc.h b/src/lib/ortc/webrtc/webrtc.h index f865e1cf..36a69406 100644 --- a/src/lib/ortc/webrtc/webrtc.h +++ b/src/lib/ortc/webrtc/webrtc.h @@ -13,12 +13,12 @@ #pragma once #include -#include #include +#include #include -#include #include +#include #include "../ok_rtc.h" #include "../ok_rtc_defs.h" @@ -32,7 +32,7 @@ class AudioEncoderFactory; class AudioDecoderFactory; class VideoEncoderFactory; class VideoDecoderFactory; -} // namespace webrtc +} // namespace webrtc namespace lib { namespace ortc { @@ -41,113 +41,103 @@ class Conductor; class WebRTC : public OkRTC { public: - WebRTC(); + WebRTC(); - ~WebRTC(); + ~WebRTC(); - bool start() override; + bool start() override; - bool stop() override; + bool stop() override; - bool isStarted() override; + bool isStarted() override; - bool ensureStart() override; + bool ensureStart() override; - void addRTCHandler(OkRTCHandler* hand) override; + void addRTCHandler(OkRTCHandler* hand) override; - void setRemoteDescription(const std::string &peerId, const OJingleContentAv &context) override; + void setRemoteDescription(const std::string& peerId, const OJingleContentAv& context) override; - void CreateOffer(const std::string &peerId) override; + void CreateOffer(const std::string& peerId) override; - void CreateAnswer(const std::string &peerId, - const OJingleContentAv &content) override; + void CreateAnswer(const std::string& peerId, const OJingleContentAv& content) override; - void setTransportInfo(const std::string &peerId, - const std::string &sId, - const ortc::OIceUdp &iceUdp) override; + void setTransportInfo(const std::string& peerId, + const std::string& sId, + const ortc::OIceUdp& iceUdp) override; - void ContentAdd(std::map sdMap, - ortc::OkRTCHandler *handler) override; + void ContentAdd(std::map sdMap, + ortc::OkRTCHandler* handler) override; - void ContentRemove(std::map sdMap, - OkRTCHandler *handler) override; + void ContentRemove(std::map sdMap, + OkRTCHandler* handler) override; - void SessionTerminate(const std::string &peerId) override; + void SessionTerminate(const std::string& peerId) override; - void setMute(bool mute) override; + void setMute(bool mute) override; - void setRemoteMute(bool mute) override; + void setRemoteMute(bool mute) override; + size_t getVideoSize() override; - size_t getVideoSize() override; + [[nodiscard]] auto createVideoCapture(std::optional deviceId = std::nullopt, + bool isScreenCapture = false) + -> std::shared_ptr; - [[nodiscard]] auto createVideoCapture( - std::optional deviceId = std::nullopt, - bool isScreenCapture = false) - -> std::shared_ptr; + bool call(const std::string& peerId, const std::string& sId, bool video) override; - bool call(const std::string &peerId, - const std::string &sId, - bool video) override; + bool quit(const std::string& peerId) override; - bool quit(const std::string &peerId) override; + void setIceOptions(std::list& ices) override; - void setIceOptions(std::list& ices) override; + webrtc::SdpType convertToSdpType(JingleSdpType sdpType); - webrtc::SdpType convertToSdpType(JingleSdpType sdpType); + JingleSdpType convertFromSdpType(webrtc::SdpType sdpType); - JingleSdpType convertFromSdpType(webrtc::SdpType sdpType); + std::unique_ptr convertToSdp( + const OJingleContentAv& context); - std::unique_ptr convertToSdp(const OJingleContentAv &context); + OJingleContentAv convertFromSdp(webrtc::SessionDescriptionInterface* sdp); - OJingleContentAv convertFromSdp( webrtc::SessionDescriptionInterface* sdp); + OkRTCHandler* getHandler() const { return _rtcHandler; } + const webrtc::PeerConnectionInterface::RTCConfiguration& getConfig() const { + return _rtcConfig; + } - OkRTCHandler* getHandler()const { - return _rtcHandler; - } - - const webrtc::PeerConnectionInterface::RTCConfiguration& getConfig() const { - return _rtcConfig; - } - - rtc::scoped_refptr getFactory(){ - return peer_connection_factory; - } + rtc::scoped_refptr getFactory() { + return peer_connection_factory; + } private: -// std::unique_ptr _logSink; - void addIceServer(const IceServer &ice); - - Conductor *createConductor(const std::string &peerId, - const std::string &sId, - bool video); + // std::unique_ptr _logSink; + void addIceServer(const IceServer& ice); - Conductor *getConductor(const std::string &peerId); + Conductor* createConductor(const std::string& peerId, const std::string& sId, bool video); - std::recursive_mutex start_mtx; + Conductor* getConductor(const std::string& peerId); - webrtc::PeerConnectionInterface::RTCConfiguration _rtcConfig; + std::recursive_mutex start_mtx; + webrtc::PeerConnectionInterface::RTCConfiguration _rtcConfig; - std::unique_ptr network_thread; - std::unique_ptr worker_thread; - std::unique_ptr signaling_thread; + std::unique_ptr network_thread; + std::unique_ptr worker_thread; + std::unique_ptr signaling_thread; - std::map _pcMap; + std::map _pcMap; - OkRTCHandler *_rtcHandler; + OkRTCHandler* _rtcHandler; - // 音频源 - rtc::scoped_refptr audioSource; + // 音频源 + rtc::scoped_refptr audioSource; - //视频源 - std::shared_ptr videoCapture; + // 视频源 + std::shared_ptr videoCapture; - //sink - std::shared_ptr> sink; + // sink + std::shared_ptr> sink; - rtc::scoped_refptr peer_connection_factory; + rtc::scoped_refptr peer_connection_factory; }; -} // namespace ortc -} // namespace lib +} // namespace ortc +} // namespace lib diff --git a/src/lib/plugin/OkOptions.cpp b/src/lib/plugin/OkOptions.cpp index 1b08a78b..f8a97f5c 100644 --- a/src/lib/plugin/OkOptions.cpp +++ b/src/lib/plugin/OkOptions.cpp @@ -18,13 +18,12 @@ namespace ok { namespace plugin { -OkOptions *OkOptions::instance() { - - static OkOptions *instance = nullptr; - if (!instance) { - instance = new OkOptions(); - } - return instance; +OkOptions* OkOptions::instance() { + static OkOptions* instance = nullptr; + if (!instance) { + instance = new OkOptions(); + } + return instance; } -} // namespace plugin -} // namespace ok \ No newline at end of file +} // namespace plugin +} // namespace ok \ No newline at end of file diff --git a/src/lib/plugin/OkOptions.h b/src/lib/plugin/OkOptions.h index 801fc1a3..8029598e 100644 --- a/src/lib/plugin/OkOptions.h +++ b/src/lib/plugin/OkOptions.h @@ -17,16 +17,14 @@ #pragma once #include "optionstree.h" - namespace ok { namespace plugin { class OkOptions : public OptionsTree { - Q_OBJECT + Q_OBJECT public: - static OkOptions * instance(); - + static OkOptions* instance(); }; -} // namespace plugin -} // namespace ok +} // namespace plugin +} // namespace ok diff --git a/src/lib/plugin/PluginInfo.cpp b/src/lib/plugin/PluginInfo.cpp index 215436e3..2b89cfa2 100644 --- a/src/lib/plugin/PluginInfo.cpp +++ b/src/lib/plugin/PluginInfo.cpp @@ -15,4 +15,3 @@ // #include "PluginInfo.h" - diff --git a/src/lib/plugin/PluginInfo.h b/src/lib/plugin/PluginInfo.h index 49fec291..91edd0e9 100644 --- a/src/lib/plugin/PluginInfo.h +++ b/src/lib/plugin/PluginInfo.h @@ -17,7 +17,5 @@ #pragma once namespace ok { -namespace plugin { - -} // namespace plugin -} // namespace ok +namespace plugin {} // namespace plugin +} // namespace ok diff --git a/src/lib/plugin/coloropt.cpp b/src/lib/plugin/coloropt.cpp index 60ba0ba9..620b06c9 100644 --- a/src/lib/plugin/coloropt.cpp +++ b/src/lib/plugin/coloropt.cpp @@ -18,48 +18,48 @@ using namespace ok::plugin; -ColorOpt::ColorOpt() : QObject(nullptr) -{ - connect(OkOptions::instance(), SIGNAL(optionChanged(const QString &)), SLOT(optionChanged(const QString &))); +ColorOpt::ColorOpt() : QObject(nullptr) { + connect(OkOptions::instance(), SIGNAL(optionChanged(const QString&)), + SLOT(optionChanged(const QString&))); connect(OkOptions::instance(), SIGNAL(destroyed()), SLOT(reset())); typedef struct { - const char * opt; + const char* opt; QPalette::ColorRole role; } SourceType; - SourceType source[] = { { "contactlist.status.online", QPalette::Text }, - { "contactlist.status.offline", QPalette::Text }, - { "contactlist.status.away", QPalette::Text }, - { "contactlist.status.do-not-disturb", QPalette::Text }, - { "contactlist.profile.header-foreground", QPalette::Text }, - { "contactlist.profile.header-background", QPalette::Dark }, - { "contactlist.grouping.header-foreground", QPalette::Text }, - { "contactlist.grouping.header-background", QPalette::Base }, - { "contactlist.background", QPalette::Base }, - { "contactlist.status-change-animation1", QPalette::Text }, - { "contactlist.status-change-animation2", QPalette::Base }, - { "contactlist.status-messages", QPalette::Text }, - { "tooltip.background", QPalette::ToolTipBase }, - { "tooltip.text", QPalette::ToolTipText }, - { "messages.received", QPalette::Text }, - { "messages.sent", QPalette::Text }, - { "messages.informational", QPalette::Text }, - { "messages.usertext", QPalette::Text }, - { "messages.highlighting", QPalette::Text }, - { "messages.link", QPalette::Link }, - { "messages.link-visited", QPalette::Link }, - { "passive-popup.border", QPalette::Window } }; + SourceType source[] = {{"contactlist.status.online", QPalette::Text}, + {"contactlist.status.offline", QPalette::Text}, + {"contactlist.status.away", QPalette::Text}, + {"contactlist.status.do-not-disturb", QPalette::Text}, + {"contactlist.profile.header-foreground", QPalette::Text}, + {"contactlist.profile.header-background", QPalette::Dark}, + {"contactlist.grouping.header-foreground", QPalette::Text}, + {"contactlist.grouping.header-background", QPalette::Base}, + {"contactlist.background", QPalette::Base}, + {"contactlist.status-change-animation1", QPalette::Text}, + {"contactlist.status-change-animation2", QPalette::Base}, + {"contactlist.status-messages", QPalette::Text}, + {"tooltip.background", QPalette::ToolTipBase}, + {"tooltip.text", QPalette::ToolTipText}, + {"messages.received", QPalette::Text}, + {"messages.sent", QPalette::Text}, + {"messages.informational", QPalette::Text}, + {"messages.usertext", QPalette::Text}, + {"messages.highlighting", QPalette::Text}, + {"messages.link", QPalette::Link}, + {"messages.link-visited", QPalette::Link}, + {"passive-popup.border", QPalette::Window}}; for (unsigned int i = 0; i < sizeof(source) / sizeof(SourceType); i++) { QString opt = QString("options.ui.look.colors.%1").arg(source[i].opt); - colors.insert(opt, ColorData(OkOptions::instance()->getOption(opt).value(), source[i].role)); + colors.insert(opt, ColorData(OkOptions::instance()->getOption(opt).value(), + source[i].role)); } } -QColor ColorOpt::color(const QString &opt, const QColor &defaultColor) const -{ +QColor ColorOpt::color(const QString& opt, const QColor& defaultColor) const { ColorData cd = colors.value(opt); - // qDebug("get option: %s from data %s", qPrintable(opt), qPrintable(cd.color.isValid()? cd.color.name() : "Invalid - // " + cd.color.name())); + // qDebug("get option: %s from data %s", qPrintable(opt), qPrintable(cd.color.isValid()? + // cd.color.name() : "Invalid " + cd.color.name())); if (!cd.valid) { return OkOptions::instance()->getOption(opt, defaultColor).value(); } @@ -69,14 +69,13 @@ QColor ColorOpt::color(const QString &opt, const QColor &defaultColor) const return QApplication::palette().color(cd.role); } -QPalette::ColorRole ColorOpt::colorRole(const QString &opt) const { return colors.value(opt).role; } +QPalette::ColorRole ColorOpt::colorRole(const QString& opt) const { return colors.value(opt).role; } -void ColorOpt::optionChanged(const QString &opt) -{ +void ColorOpt::optionChanged(const QString& opt) { if (opt.startsWith(QLatin1String("options.ui.look.colors")) && colors.contains(opt)) { colors[opt].color = OkOptions::instance()->getOption(opt).value(); - // qDebug("%s changed to %s", qPrintable(opt), qPrintable(colors[opt].color.isValid()? colors[opt].color.name() - // : "Invalid " + colors[opt].color.name())); + // qDebug("%s changed to %s", qPrintable(opt), qPrintable(colors[opt].color.isValid()? + // colors[opt].color.name() : "Invalid " + colors[opt].color.name())); emit changed(opt); } } @@ -85,10 +84,8 @@ void ColorOpt::optionChanged(const QString &opt) * Returns the singleton instance of this class * \return Instance of OkOptions */ -ColorOpt *ColorOpt::instance() -{ - if (!instance_) - instance_.reset(new ColorOpt()); +ColorOpt* ColorOpt::instance() { + if (!instance_) instance_.reset(new ColorOpt()); return instance_.data(); } diff --git a/src/lib/plugin/coloropt.h b/src/lib/plugin/coloropt.h index ba777007..e172cbbe 100644 --- a/src/lib/plugin/coloropt.h +++ b/src/lib/plugin/coloropt.h @@ -17,23 +17,24 @@ class ColorData { public: - ColorData() : role(QPalette::NoRole), valid(false) { } - ColorData(const QColor &color, QPalette::ColorRole role) : color(color), role(role), valid(true) { } + ColorData() : role(QPalette::NoRole), valid(false) {} + ColorData(const QColor& color, QPalette::ColorRole role) + : color(color), role(role), valid(true) {} - QColor color; + QColor color; QPalette::ColorRole role; - bool valid; + bool valid; }; class ColorOpt : public QObject { Q_OBJECT public: - static ColorOpt * instance(); - QColor color(const QString &opt, const QColor &defaultColor = QColor()) const; - QPalette::ColorRole colorRole(const QString &opt) const; + static ColorOpt* instance(); + QColor color(const QString& opt, const QColor& defaultColor = QColor()) const; + QPalette::ColorRole colorRole(const QString& opt) const; signals: - void changed(const QString &opt); + void changed(const QString& opt); private: ColorOpt(); @@ -42,9 +43,9 @@ public slots: static void reset(); private slots: - void optionChanged(const QString &opt); + void optionChanged(const QString& opt); private: static QScopedPointer instance_; - QHash colors; + QHash colors; }; diff --git a/src/lib/plugin/common.cpp b/src/lib/plugin/common.cpp index bd0ee6a9..349cd660 100644 --- a/src/lib/plugin/common.cpp +++ b/src/lib/plugin/common.cpp @@ -43,7 +43,7 @@ #endif #include #ifdef Q_OS_MAC -#include // for HIToolbox/InternetConfig +#include // for HIToolbox/InternetConfig #include #include #include @@ -58,22 +58,20 @@ Qt::WindowFlags psi_dialog_flags = (Qt::WindowSystemMenuHint | Qt::WindowMinMaxB // FIXME find it a new home! int common_smallFontSize = 0; -QString CAP(const QString &str) { return QString("%1: %2").arg(ApplicationInfo::name(), str); } +QString CAP(const QString& str) { return QString("%1: %2").arg(ApplicationInfo::name(), str); } // clips plain text -QString clipStatus(const QString &str, int width, int height) -{ +QString clipStatus(const QString& str, int width, int height) { QString out = ""; - int at = 0; - int len = str.length(); - if (len == 0) - return out; + int at = 0; + int len = str.length(); + if (len == 0) return out; // only take the first "height" lines for (int n2 = 0; n2 < height; ++n2) { // only take the first "width" chars QString line; - bool hasNewline = false; + bool hasNewline = false; for (int n = 0; at < len; ++n, ++at) { if (str.at(at) == '\n') { hasNewline = true; @@ -99,17 +97,16 @@ QString clipStatus(const QString &str, int width, int height) return out; } -QString encodePassword(const QString &pass, const QString &key) -{ +QString encodePassword(const QString& pass, const QString& key) { QString result; - int n1, n2; + int n1, n2; if (key.length() == 0) { return pass; } for (n1 = 0, n2 = 0; n1 < pass.length(); ++n1) { - ushort x = pass.at(n1).unicode() ^ key.at(n2++).unicode(); + ushort x = pass.at(n1).unicode() ^ key.at(n2++).unicode(); QString hex = QString::asprintf("%04x", x); result += hex; if (n2 >= key.length()) { @@ -119,10 +116,9 @@ QString encodePassword(const QString &pass, const QString &key) return result; } -QString decodePassword(const QString &pass, const QString &key) -{ +QString decodePassword(const QString& pass, const QString& key) { QString result; - int n1, n2; + int n1, n2; if (key.length() == 0) { return pass; @@ -147,23 +143,20 @@ QString decodePassword(const QString &pass, const QString &key) } #ifdef HAVE_KEYCHAIN -bool isKeychainEnabled() -{ - return !ApplicationInfo::isPortable() - && PsiOptions::instance()->getOption("options.keychain.enabled", true).toBool(); +bool isKeychainEnabled() { + return !ApplicationInfo::isPortable() && + PsiOptions::instance()->getOption("options.keychain.enabled", true).toBool(); } #endif -QString logencode(QString str) -{ - str.replace(QRegExp("\\\\"), "\\\\"); // backslash to double-backslash - str.replace(QRegExp("\\|"), "\\p"); // pipe to \p - str.replace(QRegExp("\n"), "\\n"); // newline to \n +QString logencode(QString str) { + str.replace(QRegExp("\\\\"), "\\\\"); // backslash to double-backslash + str.replace(QRegExp("\\|"), "\\p"); // pipe to \p + str.replace(QRegExp("\n"), "\\n"); // newline to \n return str; } -QString logdecode(const QString &str) -{ +QString logdecode(const QString& str) { QString ret; for (int n = 0; n < str.length(); ++n) { @@ -189,8 +182,7 @@ QString logdecode(const QString &str) return ret; } -bool fileCopy(const QString &src, const QString &dest) -{ +bool fileCopy(const QString& src, const QString& dest) { QFile in(src); QFile out(dest); @@ -201,8 +193,8 @@ bool fileCopy(const QString &src, const QString &dest) return false; } - char *dat = new char[16384]; - int n = 0; + char* dat = new char[16384]; + int n = 0; while (!in.atEnd()) { n = int(in.read(dat, 16384)); if (n == -1) { @@ -221,8 +213,7 @@ bool fileCopy(const QString &src, const QString &dest) /** Detect default player helper on unix like systems */ -QString soundDetectPlayer() -{ +QString soundDetectPlayer() { // prefer ALSA on linux if (QFile("/proc/asound").exists()) { return "aplay -q"; @@ -232,15 +223,14 @@ QString soundDetectPlayer() } #include -QLayout *rw_recurseFindLayout(QLayout *lo, QWidget *w) -{ +QLayout* rw_recurseFindLayout(QLayout* lo, QWidget* w) { // printf("scanning layout: %p\n", lo); for (int index = 0; index < lo->count(); ++index) { - QLayoutItem *i = lo->itemAt(index); + QLayoutItem* i = lo->itemAt(index); // printf("found: %p,%p\n", i->layout(), i->widget()); - QLayout *slo = i->layout(); + QLayout* slo = i->layout(); if (slo) { - QLayout *tlo = rw_recurseFindLayout(slo, w); + QLayout* tlo = rw_recurseFindLayout(slo, w); if (tlo) { return tlo; } @@ -251,49 +241,48 @@ QLayout *rw_recurseFindLayout(QLayout *lo, QWidget *w) return nullptr; } -QLayout *rw_findLayoutOf(QWidget *w) { return rw_recurseFindLayout(w->parentWidget()->layout(), w); } +QLayout* rw_findLayoutOf(QWidget* w) { + return rw_recurseFindLayout(w->parentWidget()->layout(), w); +} -void replaceWidget(QWidget *a, QWidget *b) -{ +void replaceWidget(QWidget* a, QWidget* b) { if (!a) { return; } - QLayout *lo = rw_findLayoutOf(a); + QLayout* lo = rw_findLayoutOf(a); if (!lo) { return; } // printf("decided on this: %p\n", lo); if (lo->inherits("QBoxLayout")) { - QBoxLayout *bo = static_cast(lo); - int n = bo->indexOf(a); + QBoxLayout* bo = static_cast(lo); + int n = bo->indexOf(a); bo->insertWidget(n + 1, b); delete a; } } -void closeDialogs(QWidget *w) -{ +void closeDialogs(QWidget* w) { // close qmessagebox? - QList dialogs; - QObjectList list = w->children(); + QList dialogs; + QObjectList list = w->children(); for (QObjectList::Iterator it = list.begin(); it != list.end(); ++it) { if ((*it)->inherits("QDialog")) { - dialogs.append(static_cast(*it)); + dialogs.append(static_cast(*it)); } } - for (QDialog *w : dialogs) { + for (QDialog* w : dialogs) { w->close(); } } -void reorderGridLayout(QGridLayout *layout, int maxCols) -{ - QList items; +void reorderGridLayout(QGridLayout* layout, int maxCols) { + QList items; for (int i = 0; i < layout->rowCount(); i++) { for (int j = 0; j < layout->columnCount(); j++) { - QLayoutItem *item = layout->itemAtPosition(i, j); + QLayoutItem* item = layout->itemAtPosition(i, j); if (item) { layout->removeItem(item); if (item->isEmpty()) { @@ -306,7 +295,7 @@ void reorderGridLayout(QGridLayout *layout, int maxCols) } int col = 0, row = 0; while (!items.isEmpty()) { - QLayoutItem *item = items.takeAt(0); + QLayoutItem* item = items.takeAt(0); layout->addItem(item, row, col); col++; if (col >= maxCols) { @@ -316,38 +305,36 @@ void reorderGridLayout(QGridLayout *layout, int maxCols) } } -void clearMenu(QMenu *m) -{ +void clearMenu(QMenu* m) { m->clear(); QObjectList l = m->children(); - for (QObject *obj : l) { - QMenu *child = dynamic_cast(obj); + for (QObject* obj : l) { + QMenu* child = dynamic_cast(obj); if (child) { delete child; } } } -bool isKde() -{ - return qgetenv("XDG_SESSION_DESKTOP") == "KDE" || qgetenv("DESKTOP_SESSION").endsWith("plasma") - || qgetenv("DESKTOP_SESSION").endsWith("plasma5"); +bool isKde() { + return qgetenv("XDG_SESSION_DESKTOP") == "KDE" || + qgetenv("DESKTOP_SESSION").endsWith("plasma") || + qgetenv("DESKTOP_SESSION").endsWith("plasma5"); } -void bringToFront(QWidget *widget, bool) -{ +void bringToFront(QWidget* widget, bool) { Q_ASSERT(widget); - QWidget *w = widget->window(); + QWidget* w = widget->window(); #ifdef HAVE_X11 if (QX11Info::isPlatformX11()) { // If we're not on the current desktop, do the hide/show trick - long dsk, curr_dsk; + long dsk, curr_dsk; Window win = w->winId(); - if (X11WindowSystem::instance()->desktopOfWindow(&win, &dsk) - && X11WindowSystem::instance()->currentDesktop(&curr_dsk)) { + if (X11WindowSystem::instance()->desktopOfWindow(&win, &dsk) && + X11WindowSystem::instance()->currentDesktop(&curr_dsk)) { // qDebug() << "bringToFront current desktop=" << curr_dsk << " windowDesktop=" << dsk; - if ((dsk != curr_dsk) && (dsk != -1)) { // second condition for sticky windows + if ((dsk != curr_dsk) && (dsk != -1)) { // second condition for sticky windows w->hide(); } } @@ -385,10 +372,8 @@ void bringToFront(QWidget *widget, bool) #endif } -bool operator!=(const QMap &m1, const QMap &m2) -{ - if (m1.size() != m2.size()) - return true; +bool operator!=(const QMap& m1, const QMap& m2) { + if (m1.size() != m2.size()) return true; QMap::ConstIterator it = m1.begin(), it2; for (; it != m1.end(); ++it) { @@ -408,33 +393,30 @@ bool operator!=(const QMap &m1, const QMap & // ToolbarPrefs //---------------------------------------------------------------------------- -ToolbarPrefs::ToolbarPrefs() : - dock(Qt3Dock_Top) - // , dirty(true) - , - on(false), locked(false) - // , stretchable(false) - // , index(0) - , - nl(true) +ToolbarPrefs::ToolbarPrefs() + : dock(Qt3Dock_Top) + // , dirty(true) + , on(false) + , locked(false) + // , stretchable(false) + // , index(0) + , nl(true) // , extraOffset(0) { id = QUuid::createUuid().toString(); } -bool ToolbarPrefs::operator==(const ToolbarPrefs &other) -{ +bool ToolbarPrefs::operator==(const ToolbarPrefs& other) { return id == other.id && name == other.name && keys == other.keys && dock == other.dock && - // dirty == other.dirty && - on == other.on && locked == other.locked && - // stretchable == other.stretchable && - // index == other.index && - nl == other.nl; + // dirty == other.dirty && + on == other.on && locked == other.locked && + // stretchable == other.stretchable && + // index == other.index && + nl == other.nl; // extraOffset == other.extraOffset; } -int versionStringToInt(const char *version) -{ +int versionStringToInt(const char* version) { QString str = QString::fromLatin1(version); #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) QStringList parts = str.split('.', Qt::KeepEmptyParts); @@ -448,7 +430,7 @@ int versionStringToInt(const char *version) int versionInt = 0; for (int n = 0; n < 3; ++n) { bool ok; - int x = parts[n].toInt(&ok); + int x = parts[n].toInt(&ok); if (ok && x >= 0 && x <= 0xff) { versionInt <<= 8; versionInt += x; @@ -459,8 +441,7 @@ int versionStringToInt(const char *version) return versionInt; } -int qVersionInt() -{ +int qVersionInt() { static int out = -1; if (out == -1) { out = versionStringToInt(qVersion()); diff --git a/src/lib/plugin/common.h b/src/lib/plugin/common.h index 0036fd12..7af4dea4 100644 --- a/src/lib/plugin/common.h +++ b/src/lib/plugin/common.h @@ -40,11 +40,11 @@ enum { dcClose, dcHour, dcDay, dcNever }; enum Qt3Dock { Qt3Dock_Unmanaged = 0, - Qt3Dock_TornOff = 1, - Qt3Dock_Top = 2, - Qt3Dock_Bottom = 3, - Qt3Dock_Right = 4, - Qt3Dock_Left = 5, + Qt3Dock_TornOff = 1, + Qt3Dock_Top = 2, + Qt3Dock_Bottom = 3, + Qt3Dock_Right = 4, + Qt3Dock_Left = 5, Qt3Dock_Minimized = 6 }; @@ -52,10 +52,10 @@ class ToolbarPrefs { public: ToolbarPrefs(); - QString id; - QString name; + QString id; + QString name; QStringList keys; - Qt3Dock dock; + Qt3Dock dock; // bool dirty; bool on; @@ -66,11 +66,10 @@ class ToolbarPrefs { bool nl; // int extraOffset; - bool operator==(const ToolbarPrefs &other); + bool operator==(const ToolbarPrefs& other); }; struct lateMigrationOptions { - QMap serviceRosterIconset; QMap customRosterIconset; QMap> toolbars; @@ -86,15 +85,15 @@ extern int common_smallFontSize; enum { EventPriorityDontCare = -1 }; // coofficients icon-size / font-size signalling where icon needs to be scaled-down -constexpr double HugeIconRosterK = 2.0; -constexpr double HugeIconButtonK = 2.0; +constexpr double HugeIconRosterK = 2.0; +constexpr double HugeIconButtonK = 2.0; constexpr double HugeIconTextViewK = 1.5; -constexpr double EqTextIconK = 0.93; // icon size equal to text +constexpr double EqTextIconK = 0.93; // icon size equal to text constexpr double BiggerTextIconK = 1.5; // icon visually bigger than text but still looks good int pointToPixel(qreal points); -int computeScaleFactor(QPaintDevice *pd); +int computeScaleFactor(QPaintDevice* pd); // ----------------------------------------------------------------------------- // Status @@ -112,58 +111,57 @@ int computeScaleFactor(QPaintDevice *pd); #define STATUS_NOAUTH 101 #define STATUS_ERROR 102 -QString status2txt(int status); -bool lastPriorityNotEmpty(); -QString clipStatus(const QString &str, int width, int height); +QString status2txt(int status); +bool lastPriorityNotEmpty(); +QString clipStatus(const QString& str, int width, int height); // ----------------------------------------------------------------------------- // Widget tools // ----------------------------------------------------------------------------- -bool isKde(); -void clearMenu(QMenu *m); // deletes all items, including submenus, from given QMenu -void bringToFront(QWidget *w, bool grabFocus = true); -void replaceWidget(QWidget *, QWidget *); -void closeDialogs(QWidget *); -TabbableWidget *findActiveTab(); +bool isKde(); +void clearMenu(QMenu* m); // deletes all items, including submenus, from given QMenu +void bringToFront(QWidget* w, bool grabFocus = true); +void replaceWidget(QWidget*, QWidget*); +void closeDialogs(QWidget*); +TabbableWidget* findActiveTab(); #ifdef HAVE_X11 #include "x11windowsystem.h" -#define X11WM_CLASS(x) \ - { \ - if (QX11Info::isPlatformX11()) \ - X11WindowSystem::instance()->x11wmClass(winId(), (x)); \ +#define X11WM_CLASS(x) \ + { \ + if (QX11Info::isPlatformX11()) X11WindowSystem::instance()->x11wmClass(winId(), (x)); \ }; #else #define X11WM_CLASS(x) /* dummy */ #endif -void reorderGridLayout(QGridLayout *layout, int maxCols); +void reorderGridLayout(QGridLayout* layout, int maxCols); // ----------------------------------------------------------------------------- // History utilities // ----------------------------------------------------------------------------- QString logencode(QString); -QString logdecode(const QString &); +QString logdecode(const QString&); // ----------------------------------------------------------------------------- // Misc. // ----------------------------------------------------------------------------- -QString CAP(const QString &str); +QString CAP(const QString& str); -QString encodePassword(const QString &, const QString &); -QString decodePassword(const QString &, const QString &); +QString encodePassword(const QString&, const QString&); +QString decodePassword(const QString&, const QString&); #ifdef HAVE_KEYCHAIN bool isKeychainEnabled(); #endif -bool operator!=(const QMap &, const QMap &); +bool operator!=(const QMap&, const QMap&); -bool fileCopy(const QString &src, const QString &dest); +bool fileCopy(const QString& src, const QString& dest); extern Qt::WindowFlags psi_dialog_flags; // like QT_VERSION, but runtime int qVersionInt(); -#endif // COMMON_H +#endif // COMMON_H diff --git a/src/lib/plugin/iconset/anim.cpp b/src/lib/plugin/iconset/anim.cpp index cfc979fc..aa0a73ad 100644 --- a/src/lib/plugin/iconset/anim.cpp +++ b/src/lib/plugin/iconset/anim.cpp @@ -1,4 +1,4 @@ - /* +/* * Copyright (c) 2022 船山信息 chuanshaninfo.com * The project is licensed under Mulan PubL v2. * You can use this software according to the terms and conditions of the Mulan @@ -14,7 +14,7 @@ #include "iconset.h" -//#include +// #include #include #include #include @@ -32,13 +32,13 @@ * Each frame of Anim is stored as Impix. */ -static QThread *animMainThread = nullptr; +static QThread* animMainThread = nullptr; //! \if _hide_doc_ class Anim::Private : public QObject, public QSharedData { Q_OBJECT public: - QTimer *frametimer; + QTimer* frametimer; bool empty; bool paused; @@ -51,15 +51,14 @@ class Anim::Private : public QObject, public QSharedData { class Frame { public: Impix impix; - int period = 100; + int period = 100; }; QList frames; - int frame; + int frame; public: - void init() - { + void init() { frametimer = new QTimer(); if (animMainThread && animMainThread != QThread::currentThread()) { frametimer->moveToThread(animMainThread); @@ -67,38 +66,35 @@ class Anim::Private : public QObject, public QSharedData { } QObject::connect(frametimer, SIGNAL(timeout()), this, SLOT(refresh())); - speed = 120; + speed = 120; lasttimerinterval = -1; - looping = 0; // MNG movies doesn't have loop flag? - loop = 0; - frame = 0; - paused = true; + looping = 0; // MNG movies doesn't have loop flag? + loop = 0; + frame = 0; + paused = true; } Private() { init(); } - Private(const Private &from) : QObject(), QSharedData() - { + Private(const Private& from) : QObject(), QSharedData() { init(); - speed = from.speed; + speed = from.speed; lasttimerinterval = from.lasttimerinterval; - looping = from.looping; - loop = from.loop; - frame = from.frame; - paused = from.paused; - frames = from.frames; - - if (!paused) - unpause(); + looping = from.looping; + loop = from.loop; + frame = from.frame; + paused = from.paused; + frames = from.frames; + + if (!paused) unpause(); } - Private(const QByteArray *ba) - { + Private(const QByteArray* ba) { init(); - QBuffer buffer(const_cast(ba)); + QBuffer buffer(const_cast(ba)); buffer.open(QBuffer::ReadOnly); QImageReader reader(&buffer); @@ -106,7 +102,7 @@ class Anim::Private : public QObject, public QSharedData { QImage image = reader.read(); if (!image.isNull()) { Frame newFrame; - newFrame.impix = Impix(image); + newFrame.impix = Impix(image); newFrame.period = reader.nextImageDelay(); frames.append(newFrame); } else { @@ -122,54 +118,47 @@ class Anim::Private : public QObject, public QSharedData { // we're gonna slice the single image we've got if we're absolutely sure // that it's can be cut into multiple frames if ((frame.width() / frame.height() > 0) && !(frame.width() % frame.height())) { - int h = frame.height(); + int h = frame.height(); QList newFrames; for (int i = 0; i < frame.width() / frame.height(); i++) { Frame newFrame; - newFrame.impix = Impix(frame.copy(i * h, 0, h, h)); + newFrame.impix = Impix(frame.copy(i * h, 0, h, h)); newFrame.period = 120; newFrames.append(newFrame); } - frames = newFrames; + frames = newFrames; looping = 0; } } } - ~Private() - { - if (frametimer) - delete frametimer; + ~Private() { + if (frametimer) delete frametimer; } - void pause() - { + void pause() { paused = true; frametimer->stop(); } - void unpause() - { + void unpause() { paused = false; restartTimer(); } - void restart() - { + void restart() { frame = 0; - if (!paused) - restartTimer(); + if (!paused) restartTimer(); } int numFrames() const { return frames.count(); } - void restartTimer() - { + void restartTimer() { if (!paused && speed > 0) { int frameperiod = frames[frame].period; - int i = frameperiod >= 0 ? frameperiod * 100 / speed : 0; + int i = frameperiod >= 0 ? frameperiod * 100 / speed : 0; if (i != lasttimerinterval || !frametimer->isActive()) { lasttimerinterval = i; frametimer->start(i); @@ -183,8 +172,7 @@ class Anim::Private : public QObject, public QSharedData { void areaChanged(); public slots: - void refresh() - { + void refresh() { frame++; if (frame >= numFrames()) { frame = 0; @@ -211,32 +199,32 @@ Anim::Anim() { d = new Private(); } /** * Creates animation from QByteArray \a data. */ -Anim::Anim(const QByteArray &data) { d = new Private(&data); } +Anim::Anim(const QByteArray& data) { d = new Private(&data); } /** * Creates shared copy of Anim \a anim. */ -Anim::Anim(const Anim &anim) { d = anim.d; } +Anim::Anim(const Anim& anim) { d = anim.d; } /** * Deletes animation. */ -Anim::~Anim() { } +Anim::~Anim() {} /** * Returns QPixmap of current frame. */ -const QPixmap &Anim::framePixmap() const { return d->frames[d->frame].impix.pixmap(); } +const QPixmap& Anim::framePixmap() const { return d->frames[d->frame].impix.pixmap(); } /** * Returns QImage of current frame. */ -const QImage &Anim::frameImage() const { return d->frames[d->frame].impix.image(); } +const QImage& Anim::frameImage() const { return d->frames[d->frame].impix.image(); } /** * Returns Impix of current frame. */ -const Impix &Anim::frameImpix() const { return d->frames[d->frame].impix; } +const Impix& Anim::frameImpix() const { return d->frames[d->frame].impix; } /** * Returns total number of frames in animation. @@ -251,7 +239,7 @@ int Anim::frameNumber() const { return d->frame; } /** * Returns Impix of animation frame number \a n. */ -const Impix &Anim::frame(int n) const { return d->frames[n].impix; } +const Impix& Anim::frame(int n) const { return d->frames[n].impix; } /** * Returns \c true if numFrames() == 0 and \c false otherwise. @@ -266,28 +254,22 @@ bool Anim::paused() const { return d->paused; } /** * Continues the animation playback. */ -void Anim::unpause() -{ - if (!isNull() && paused()) - d->unpause(); +void Anim::unpause() { + if (!isNull() && paused()) d->unpause(); } /** * Pauses the animation. */ -void Anim::pause() -{ - if (!isNull() && !paused()) - d->pause(); +void Anim::pause() { + if (!isNull() && !paused()) d->pause(); } /** * Starts animation from the very beginning. */ -void Anim::restart() -{ - if (!isNull()) - d->restart(); +void Anim::restart() { + if (!isNull()) d->restart(); } /** @@ -311,8 +293,7 @@ void Anim::restart() * * \sa disconnectUpdate() */ -void Anim::connectUpdate(QObject *receiver, const char *member) -{ +void Anim::connectUpdate(QObject* receiver, const char* member) { QObject::connect(d, SIGNAL(areaChanged()), receiver, member); } @@ -320,20 +301,17 @@ void Anim::connectUpdate(QObject *receiver, const char *member) * Disconnects slot \a member, which was prevously connected with connectUpdate(). * \sa connectUpdate() */ -void Anim::disconnectUpdate(QObject *receiver, const char *member) -{ +void Anim::disconnectUpdate(QObject* receiver, const char* member) { QObject::disconnect(d, SIGNAL(areaChanged()), receiver, member); } -Anim &Anim::operator=(const Anim &from) -{ +Anim& Anim::operator=(const Anim& from) { d = from.d; return *this; } -Anim Anim::copy() const -{ +Anim Anim::copy() const { Anim anim(*this); anim.d = new Private(*this->d.data()); @@ -345,14 +323,12 @@ void Anim::detach() { d.detach(); } /** * Strips the first animation frame, if there is more than one frame. */ -void Anim::stripFirstFrame() -{ +void Anim::stripFirstFrame() { detach(); if (numFrames() > 1) { d->frames.takeFirst(); - if (!paused()) - restart(); + if (!paused()) restart(); } } @@ -360,11 +336,11 @@ void Anim::stripFirstFrame() * Sets the main thread that will be used to create objects. Useful if you want * to create Anim in non-main thread. */ -void Anim::setMainThread(QThread *thread) { animMainThread = thread; } +void Anim::setMainThread(QThread* thread) { animMainThread = thread; } /** * Get the Anim's main thread. */ -QThread *Anim::mainThread() { return animMainThread; } +QThread* Anim::mainThread() { return animMainThread; } #include "anim.moc" diff --git a/src/lib/plugin/iconset/anim.h b/src/lib/plugin/iconset/anim.h index 9ec715be..195a0e64 100644 --- a/src/lib/plugin/iconset/anim.h +++ b/src/lib/plugin/iconset/anim.h @@ -25,18 +25,18 @@ class QThread; class Anim { public: Anim(); - Anim(const QByteArray &data); - Anim(const Anim &anim); + Anim(const QByteArray& data); + Anim(const Anim& anim); ~Anim(); - const QPixmap &framePixmap() const; - const QImage & frameImage() const; - const Impix & frameImpix() const; - bool isNull() const; + const QPixmap& framePixmap() const; + const QImage& frameImage() const; + const Impix& frameImpix() const; + bool isNull() const; - int frameNumber() const; - int numFrames() const; - const Impix &frame(int n) const; + int frameNumber() const; + int numFrames() const; + const Impix& frame(int n) const; bool paused() const; void unpause(); @@ -46,15 +46,15 @@ class Anim { void stripFirstFrame(); - static QThread *mainThread(); - static void setMainThread(QThread *); + static QThread* mainThread(); + static void setMainThread(QThread*); - void connectUpdate(QObject *receiver, const char *member); - void disconnectUpdate(QObject *receiver, const char *member = nullptr); + void connectUpdate(QObject* receiver, const char* member); + void disconnectUpdate(QObject* receiver, const char* member = nullptr); - Anim &operator=(const Anim &); - Anim copy() const; - void detach(); + Anim& operator=(const Anim&); + Anim copy() const; + void detach(); class Private; @@ -62,4 +62,4 @@ class Anim { QSharedDataPointer d; }; -#endif // ANIM_H +#endif // ANIM_H diff --git a/src/lib/plugin/iconset/iconset.cpp b/src/lib/plugin/iconset/iconset.cpp index b27e6d3a..415da6e3 100644 --- a/src/lib/plugin/iconset/iconset.cpp +++ b/src/lib/plugin/iconset/iconset.cpp @@ -42,8 +42,7 @@ #include "zip/zip.h" #endif -static void moveToMainThread(QObject *obj) -{ +static void moveToMainThread(QObject* obj) { if (Anim::mainThread() && Anim::mainThread() != QThread::currentThread()) obj->moveToThread(Anim::mainThread()); } @@ -89,9 +88,8 @@ Impix::Impix() { d = new Private; } * Constructs an Impix by making a copy of a QPixmap and creating a QImage from it. * \param from - source QPixmap */ -Impix::Impix(const QPixmap &from) -{ - d = new Private; +Impix::Impix(const QPixmap& from) { + d = new Private; *this = from; } @@ -101,17 +99,15 @@ Impix::Impix(const QPixmap &from) * Constructs an Impix by making a copy of a QImage and creating a QPixmap from it. * \param from - source QImage */ -Impix::Impix(const QImage &from) -{ - d = new Private; +Impix::Impix(const QImage& from) { + d = new Private; *this = from; } /** * Unloads image data, making it null. */ -void Impix::unload() -{ +void Impix::unload() { if (isNull()) { return; } @@ -121,8 +117,7 @@ void Impix::unload() bool Impix::isNull() const { return !(!d->image.isNull() || d->pixmap); } -const QPixmap &Impix::pixmap() const -{ +const QPixmap& Impix::pixmap() const { if (!d->pixmap) { d->pixmap = new QPixmap(); if (!d->image.isNull()) { @@ -132,37 +127,30 @@ const QPixmap &Impix::pixmap() const return *d->pixmap; } -const QImage &Impix::image() const -{ +const QImage& Impix::image() const { if (d->image.isNull() && d->pixmap) { d->image = d->pixmap->toImage(); } return d->image; } -void Impix::setPixmap(const QPixmap &x) -{ +void Impix::setPixmap(const QPixmap& x) { d->unload(); d->pixmap = new QPixmap(x); } -void Impix::setImage(const QImage &x) -{ +void Impix::setImage(const QImage& x) { d->unload(); d->image = x; } -QSize Impix::size() const -{ - if (d->pixmap) - return d->pixmap->size(); - if (!d->image.isNull()) - return d->image.size(); +QSize Impix::size() const { + if (d->pixmap) return d->pixmap->size(); + if (!d->image.isNull()) return d->image.size(); return {}; } -bool Impix::loadFromData(const QByteArray &ba) -{ +bool Impix::loadFromData(const QByteArray& ba) { bool ret = false; delete d->pixmap; @@ -189,8 +177,7 @@ class IconSharedObject : public QObject { public: IconSharedObject() #ifdef ICONSET_SOUND - : - QObject(qApp) + : QObject(qApp) #endif { setObjectName("IconSharedObject"); @@ -205,7 +192,7 @@ class IconSharedObject : public QObject { friend class PsiIcon; }; -static IconSharedObject *iconSharedObject = nullptr; +static IconSharedObject* iconSharedObject = nullptr; //---------------------------------------------------------------------------- // PsiIcon @@ -228,16 +215,14 @@ static IconSharedObject *iconSharedObject = nullptr; class PsiIcon::Private : public QObject, public QSharedData { Q_OBJECT public: - Private() - { + Private() { moveToMainThread(this); - icon = nullptr; + icon = nullptr; activatedCount = 0; } - ~Private() - { + ~Private() { anim.reset(); if (icon) { delete icon; @@ -245,32 +230,29 @@ class PsiIcon::Private : public QObject, public QSharedData { } // copy all stuff, this constructor is called when detaching - Private(const Private &from) : QObject(), QSharedData() - { + Private(const Private& from) : QObject(), QSharedData() { moveToMainThread(this); - name = from.name; - mime = from.mime; - regExp = from.regExp; - text = from.text; - sound = from.sound; - impix = from.impix; - rawData = from.rawData; - scalable = from.scalable; + name = from.name; + mime = from.mime; + regExp = from.regExp; + text = from.text; + sound = from.sound; + impix = from.impix; + rawData = from.rawData; + scalable = from.scalable; svgRenderer = from.svgRenderer; anim.reset(from.anim ? new Anim(*from.anim) : nullptr); - icon = nullptr; + icon = nullptr; activatedCount = from.activatedCount; } - void connectInstance(PsiIcon *icon) - { + void connectInstance(PsiIcon* icon) { connect(this, SIGNAL(pixmapChanged()), icon, SIGNAL(pixmapChanged())); connect(this, SIGNAL(iconModified()), icon, SIGNAL(iconModified())); } - void disconnectInstance(PsiIcon *icon) - { + void disconnectInstance(PsiIcon* icon) { disconnect(this, SIGNAL(pixmapChanged()), icon, SIGNAL(pixmapChanged())); disconnect(this, SIGNAL(iconModified()), icon, SIGNAL(iconModified())); } @@ -280,11 +262,11 @@ class PsiIcon::Private : public QObject, public QSharedData { void iconModified(); public: - QPixmap pixmap(const QSize &desiredSize = QSize()) const - { + QPixmap pixmap(const QSize& desiredSize = QSize()) const { if (svgRenderer) { - QSize sz = desiredSize.isEmpty() ? svgRenderer->defaultSize() - : svgRenderer->defaultSize().scaled(desiredSize, Qt::KeepAspectRatio); + QSize sz = desiredSize.isEmpty() ? svgRenderer->defaultSize() + : svgRenderer->defaultSize().scaled( + desiredSize, Qt::KeepAspectRatio); QPixmap pix(sz); pix.fill(Qt::transparent); QPainter p(&pix); @@ -293,8 +275,7 @@ class PsiIcon::Private : public QObject, public QSharedData { } QPixmap pix = anim ? anim->framePixmap() : impix.pixmap(); - if (scalable) - return pix.scaled(desiredSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); + if (scalable) return pix.scaled(desiredSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); return pix; } @@ -302,18 +283,18 @@ public slots: void animUpdate() { emit pixmapChanged(); } public: - QString name; - QRegExp regExp; + QString name; + QRegExp regExp; QList text; - QString sound; - QString mime; + QString sound; + QString mime; - Impix impix; - std::unique_ptr anim; + Impix impix; + std::unique_ptr anim; std::shared_ptr svgRenderer; - QIcon * icon = nullptr; - mutable QByteArray rawData; - bool scalable = false; + QIcon* icon = nullptr; + mutable QByteArray rawData; + bool scalable = false; int activatedCount = 0; friend class PsiIcon; @@ -323,8 +304,7 @@ public slots: /** * Constructs empty PsiIcon. */ -PsiIcon::PsiIcon() : QObject(nullptr) -{ +PsiIcon::PsiIcon() : QObject(nullptr) { moveToMainThread(this); d = new Private; @@ -334,14 +314,13 @@ PsiIcon::PsiIcon() : QObject(nullptr) /** * Destroys PsiIcon. */ -PsiIcon::~PsiIcon() { } +PsiIcon::~PsiIcon() {} /** * Creates new icon, that is a copy of \a from. Note, that if one icon will be changed, * other will be changed as well. (that's because image data is shared) */ -PsiIcon::PsiIcon(const PsiIcon &from) : QObject(nullptr), d(from.d) -{ +PsiIcon::PsiIcon(const PsiIcon& from) : QObject(nullptr), d(from.d) { moveToMainThread(this); d->connectInstance(this); @@ -351,8 +330,7 @@ PsiIcon::PsiIcon(const PsiIcon &from) : QObject(nullptr), d(from.d) * Creates new icon, that is a copy of \a from. Note, that if one icon will be changed, * other will be changed as well. (that's because image data is shared) */ -PsiIcon &PsiIcon::operator=(const PsiIcon &from) -{ +PsiIcon& PsiIcon::operator=(const PsiIcon& from) { d->disconnectInstance(this); d = from.d; d->connectInstance(this); @@ -360,10 +338,9 @@ PsiIcon &PsiIcon::operator=(const PsiIcon &from) return *this; } -PsiIcon *PsiIcon::copy() const -{ - PsiIcon *icon = new PsiIcon; - icon->d = new Private(*this->d.data()); +PsiIcon* PsiIcon::copy() const { + PsiIcon* icon = new PsiIcon; + icon->d = new Private(*this->d.data()); icon->d->connectInstance(icon); return icon; @@ -379,13 +356,12 @@ bool PsiIcon::isAnimated() const { return d->anim != nullptr; } /** * Returns QPixmap of current frame. */ -QPixmap PsiIcon::pixmap(const QSize &desiredSize) const { return d->pixmap(desiredSize); } +QPixmap PsiIcon::pixmap(const QSize& desiredSize) const { return d->pixmap(desiredSize); } /** * Returns QImage of current frame. */ -QImage PsiIcon::image(const QSize &desiredSize) const -{ +QImage PsiIcon::image(const QSize& desiredSize) const { if (d->anim) { return d->anim->frameImage(); } @@ -393,8 +369,7 @@ QImage PsiIcon::image(const QSize &desiredSize) const auto img = d->impix.image(); if (d->svgRenderer) { QSize sz = d->svgRenderer->defaultSize().scaled(desiredSize, Qt::KeepAspectRatio); - if (!img.isNull() && img.size() == sz) - return img; + if (!img.isNull() && img.size() == sz) return img; img = QImage(sz, QImage::Format_ARGB32_Premultiplied); img.fill(Qt::transparent); QPainter p(&img); @@ -408,14 +383,13 @@ QImage PsiIcon::image(const QSize &desiredSize) const * Returns Impix of first animation frame. * \sa setImpix() */ -const Impix &PsiIcon::impix() const { return d->impix; } +const Impix& PsiIcon::impix() const { return d->impix; } /** * Returns Impix of current animation frame. * \sa impix() */ -const Impix &PsiIcon::frameImpix() const -{ +const Impix& PsiIcon::frameImpix() const { if (d->anim) { return d->anim->frameImpix(); } @@ -426,8 +400,7 @@ const Impix &PsiIcon::frameImpix() const * Returns QIcon of first animation frame. * TODO: Add automatic greyscale icon generation. */ -QIcon PsiIcon::icon() const -{ +QIcon PsiIcon::icon() const { if (d->icon) { return *d->icon; } @@ -436,15 +409,14 @@ QIcon PsiIcon::icon() const auto eng = new SvgIconEngine(d->name, d->svgRenderer); return QIcon(eng); } - const_cast(d.data())->icon = new QIcon(d->impix.pixmap()); + const_cast(d.data())->icon = new QIcon(d->impix.pixmap()); return *d->icon; } /** * Returns original image data */ -const QByteArray &PsiIcon::raw() const -{ +const QByteArray& PsiIcon::raw() const { if (d->rawData.isEmpty()) { QPixmap pix = impix().pixmap(); if (!pix.isNull()) { @@ -456,12 +428,10 @@ const QByteArray &PsiIcon::raw() const return d->rawData; } -QSize PsiIcon::size(const QSize &desiredSize) const -{ +QSize PsiIcon::size(const QSize& desiredSize) const { if (d->scalable) { QSize origSize = d->svgRenderer ? d->svgRenderer->defaultSize() : d->impix.size(); - if (!desiredSize.width() && !desiredSize.height()) - return origSize; + if (!desiredSize.width() && !desiredSize.height()) return origSize; if (!desiredSize.width()) { return origSize.scaled(origSize.width(), desiredSize.height(), Qt::KeepAspectRatio); } @@ -475,14 +445,13 @@ QSize PsiIcon::size(const QSize &desiredSize) const bool PsiIcon::isScalable() const { return d->scalable; } -const QString &PsiIcon::mimeType() const { return d->mime; } +const QString& PsiIcon::mimeType() const { return d->mime; } /** * Sets the PsiIcon impix to \a impix. * \sa impix() */ -void PsiIcon::setImpix(const Impix &impix, bool doDetach) -{ +void PsiIcon::setImpix(const Impix& impix, bool doDetach) { if (doDetach) { detach(); } @@ -500,15 +469,14 @@ void PsiIcon::setImpix(const Impix &impix, bool doDetach) /** * Returns pointer to Anim object, or \a 0 if PsiIcon doesn't contain an animation. */ -const Anim *PsiIcon::anim() const { return d->anim.get(); } +const Anim* PsiIcon::anim() const { return d->anim.get(); } /** * Sets the animation for icon to \a anim. Also sets Impix to be the first frame of animation. * If animation have less than two frames, it is deleted. * \sa anim() */ -void PsiIcon::setAnim(const Anim &anim, bool doDetach) -{ +void PsiIcon::setAnim(const Anim& anim, bool doDetach) { if (doDetach) { detach(); } @@ -525,7 +493,7 @@ void PsiIcon::setAnim(const Anim &anim, bool doDetach) if (d->anim && d->activatedCount > 0) { d->activatedCount = 0; - activated(false); // restart the animation, but don't play the sound + activated(false); // restart the animation, but don't play the sound } emit d->pixmapChanged(); @@ -536,8 +504,7 @@ void PsiIcon::setAnim(const Anim &anim, bool doDetach) * Removes animation from icon. * \sa setAnim() */ -void PsiIcon::removeAnim(bool doDetach) -{ +void PsiIcon::removeAnim(bool doDetach) { if (doDetach) { detach(); } @@ -559,8 +526,7 @@ void PsiIcon::removeAnim(bool doDetach) * Returns the number of current animation frame. * \sa setAnim() */ -int PsiIcon::frameNumber() const -{ +int PsiIcon::frameNumber() const { if (d->anim) { return d->anim->frameNumber(); } @@ -572,14 +538,13 @@ int PsiIcon::frameNumber() const * Returns name of the PsiIcon. * \sa setName() */ -const QString &PsiIcon::name() const { return d->name; } +const QString& PsiIcon::name() const { return d->name; } /** * Sets the PsiIcon name to \a name * \sa name() */ -void PsiIcon::setName(const QString &name) -{ +void PsiIcon::setName(const QString& name) { detach(); d->name = name; @@ -589,15 +554,14 @@ void PsiIcon::setName(const QString &name) * Returns PsiIcon's QRegExp. It is used to store information for emoticons. * \sa setRegExp() */ -const QRegExp &PsiIcon::regExp() const { return d->regExp; } +const QRegExp& PsiIcon::regExp() const { return d->regExp; } /** * Sets the PsiIcon QRegExp to \a regExp. * \sa regExp() * \sa text() */ -void PsiIcon::setRegExp(const QRegExp ®Exp) -{ +void PsiIcon::setRegExp(const QRegExp& regExp) { detach(); d->regExp = regExp; @@ -608,14 +572,13 @@ void PsiIcon::setRegExp(const QRegExp ®Exp) * \sa setText() * \sa regExp() */ -const QList &PsiIcon::text() const { return d->text; } +const QList& PsiIcon::text() const { return d->text; } /** * Sets the PsiIcon text to \a t. * \sa text() */ -void PsiIcon::setText(const QList &t) -{ +void PsiIcon::setText(const QList& t) { detach(); d->text = t; @@ -625,21 +588,20 @@ void PsiIcon::setText(const QList &t) * Returns default icon text that could be used as a default value * for e.g. emoticon selector. */ -QString PsiIcon::defaultText() const -{ +QString PsiIcon::defaultText() const { if (text().isEmpty()) { return QString(); } // first, try to get the text by priorities - QStringList lang { QLocale().name().section('_', 0, 0), // most prioritent, is the local language - "", // and then the language without name goes (international?) - "en" }; // then real English + QStringList lang{QLocale().name().section('_', 0, 0), // most prioritent, is the local language + "", // and then the language without name goes (international?) + "en"}; // then real English - QString str; + QString str; QStringList::Iterator it = lang.begin(); for (; it != lang.end(); ++it) { - for (const IconText &t : text()) { + for (const IconText& t : text()) { if (t.lang == *it) { str = t.text; break; @@ -649,7 +611,7 @@ QString PsiIcon::defaultText() const // if all fails, just get the first text if (str.isEmpty()) { - for (const IconText &t : text()) { + for (const IconText& t : text()) { if (!t.text.isEmpty()) { str = t.text; break; @@ -665,15 +627,14 @@ QString PsiIcon::defaultText() const * \sa setSound() * \sa activated() */ -const QString &PsiIcon::sound() const { return d->sound; } +const QString& PsiIcon::sound() const { return d->sound; } /** * Sets the sound file name to be associated with this PsiIcon. * \sa sound() * \sa activated() */ -void PsiIcon::setSound(const QString &sound) -{ +void PsiIcon::setSound(const QString& sound) { detach(); d->sound = sound; @@ -688,15 +649,14 @@ bool PsiIcon::blockSignals(bool b) { return d->blockSignals(b); } * Initializes PsiIcon's Impix (or Anim, if \a isAnim equals \c true). * Iconset::load uses this function. */ -bool PsiIcon::loadFromData(const QString &mime, const QByteArray &ba, bool isAnim, bool isScalable) -{ +bool PsiIcon::loadFromData(const QString& mime, const QByteArray& ba, bool isAnim, + bool isScalable) { bool ret = false; - if (ba.isEmpty()) - return ret; + if (ba.isEmpty()) return ret; detach(); - d->rawData = ba; - d->scalable = isScalable; + d->rawData = ba; + d->scalable = isScalable; d->svgRenderer = nullptr; if (d->scalable) { d->svgRenderer = std::make_shared(ba); @@ -709,14 +669,13 @@ bool PsiIcon::loadFromData(const QString &mime, const QByteArray &ba, bool isAni ret = true; } else { if (isAnim) { - Anim *anim = new Anim(ba); + Anim* anim = new Anim(ba); setAnim(*anim); ret = anim->numFrames() > 0; - delete anim; // shared data rules ;) + delete anim; // shared data rules ;) } - if (!ret && d->impix.loadFromData(ba)) - ret = true; + if (!ret && d->impix.loadFromData(ba)) ret = true; } if (ret) { @@ -737,8 +696,7 @@ bool PsiIcon::loadFromData(const QString &mime, const QByteArray &ba, bool isAni * If \a playSound equals \c true, PsiIcon will play associated sound file. * \sa stop() */ -void PsiIcon::activated(bool playSound) -{ +void PsiIcon::activated(bool playSound) { d->activatedCount++; #ifdef ICONSET_SOUND @@ -757,7 +715,8 @@ void PsiIcon::activated(bool playSound) if (d->anim) { d->anim->unpause(); - d->anim->disconnectUpdate(d, SLOT(animUpdate())); // ensure, that we're connected to signal exactly one time + d->anim->disconnectUpdate( + d, SLOT(animUpdate())); // ensure, that we're connected to signal exactly one time d->anim->connectUpdate(d, SLOT(animUpdate())); } } @@ -769,8 +728,7 @@ void PsiIcon::activated(bool playSound) * animation will go crazy. You've been warned. * \sa activated() */ -void PsiIcon::stop() -{ +void PsiIcon::stop() { d->activatedCount--; if (d->activatedCount <= 0) { @@ -786,8 +744,7 @@ void PsiIcon::stop() * As the name says, this function removes the first animation frame. This is used to * create system Psi iconsets, where first frame is used separately for menus. */ -void PsiIcon::stripFirstAnimFrame() -{ +void PsiIcon::stripFirstAnimFrame() { detach(); if (d->anim) { @@ -812,13 +769,12 @@ void PsiIcon::stripFirstAnimFrame() //! \if _hide_doc_ class IconsetFactoryPrivate : public QObject { private: - IconsetFactoryPrivate() : QObject(QCoreApplication::instance()), iconsets_(nullptr), emptyPixmap_(nullptr) { } + IconsetFactoryPrivate() + : QObject(QCoreApplication::instance()), iconsets_(nullptr), emptyPixmap_(nullptr) {} - ~IconsetFactoryPrivate() - { + ~IconsetFactoryPrivate() { if (iconsets_) { - while (!iconsets_->empty()) - delete iconsets_->takeFirst(); + while (!iconsets_->empty()) delete iconsets_->takeFirst(); delete iconsets_; iconsets_ = nullptr; } @@ -829,25 +785,23 @@ class IconsetFactoryPrivate : public QObject { } } - static IconsetFactoryPrivate *instance_; - QList * iconsets_; - mutable QPixmap * emptyPixmap_; + static IconsetFactoryPrivate* instance_; + QList* iconsets_; + mutable QPixmap* emptyPixmap_; public: - const QPixmap &emptyPixmap() const - { + const QPixmap& emptyPixmap() const { if (!emptyPixmap_) { emptyPixmap_ = new QPixmap(); } return *emptyPixmap_; } - const QStringList icons() const - { + const QStringList icons() const { QStringList list; - for (const Iconset *iconset : qAsConst(*iconsets_)) { - QListIterator it = iconset->iterator(); + for (const Iconset* iconset : qAsConst(*iconsets_)) { + QListIterator it = iconset->iterator(); while (it.hasNext()) { list << it.next()->name(); } @@ -856,56 +810,51 @@ class IconsetFactoryPrivate : public QObject { return list; } - void registerIconset(const Iconset *); - void unregisterIconset(const Iconset *); + void registerIconset(const Iconset*); + void unregisterIconset(const Iconset*); public: - static IconsetFactoryPrivate *instance() - { + static IconsetFactoryPrivate* instance() { if (!instance_) { instance_ = new IconsetFactoryPrivate(); } return instance_; } - const PsiIcon *icon(const QString &name) const; + const PsiIcon* icon(const QString& name) const; - static void reset() - { + static void reset() { delete instance_; instance_ = nullptr; } }; //! \endif -IconsetFactoryPrivate *IconsetFactoryPrivate::instance_ = nullptr; +IconsetFactoryPrivate* IconsetFactoryPrivate::instance_ = nullptr; -void IconsetFactoryPrivate::registerIconset(const Iconset *i) -{ +void IconsetFactoryPrivate::registerIconset(const Iconset* i) { if (!iconsets_) { - iconsets_ = new QList; + iconsets_ = new QList; } - if (!iconsets_->contains(const_cast(i))) { - iconsets_->append(const_cast(i)); + if (!iconsets_->contains(const_cast(i))) { + iconsets_->append(const_cast(i)); } } -void IconsetFactoryPrivate::unregisterIconset(const Iconset *i) -{ - if (iconsets_ && iconsets_->contains(const_cast(i))) { - iconsets_->removeAll(const_cast(i)); +void IconsetFactoryPrivate::unregisterIconset(const Iconset* i) { + if (iconsets_ && iconsets_->contains(const_cast(i))) { + iconsets_->removeAll(const_cast(i)); } } -const PsiIcon *IconsetFactoryPrivate::icon(const QString &name) const -{ +const PsiIcon* IconsetFactoryPrivate::icon(const QString& name) const { if (!iconsets_) { return nullptr; } - const PsiIcon *out = nullptr; - for (const Iconset *const iconset : qAsConst(*iconsets_)) { + const PsiIcon* out = nullptr; + for (const Iconset* const iconset : qAsConst(*iconsets_)) { if (iconset) { out = iconset->icon(name); } @@ -923,13 +872,12 @@ void IconsetFactory::reset() { IconsetFactoryPrivate::reset(); } * Returns pointer to PsiIcon with name \a name, or \a 0 if PsiIcon with that name wasn't * found in IconsetFactory. */ -const PsiIcon *IconsetFactory::iconPtr(const QString &name) -{ +const PsiIcon* IconsetFactory::iconPtr(const QString& name) { if (name.isEmpty()) { return nullptr; } - const PsiIcon *i = IconsetFactoryPrivate::instance()->icon(name); + const PsiIcon* i = IconsetFactoryPrivate::instance()->icon(name); if (!i) { qDebug("WARNING: IconsetFactory::icon(\"%s\"): icon not found", qPrintable(name)); } @@ -940,9 +888,8 @@ const PsiIcon *IconsetFactory::iconPtr(const QString &name) * Returns PsiIcon with name \a name, or empty PsiIcon if PsiIcon with that name wasn't * found in IconsetFactory. */ -PsiIcon IconsetFactory::icon(const QString &name) -{ - const PsiIcon *i = iconPtr(name); +PsiIcon IconsetFactory::icon(const QString& name) { + const PsiIcon* i = iconPtr(name); if (i) { return *i; } @@ -955,12 +902,10 @@ PsiIcon IconsetFactory::icon(const QString &name) * This function is faster than the call to IconsetFactory::icon() and cast to QPixmap, * because the intermediate PsiIcon object is not created and destroyed. */ -QPixmap IconsetFactory::iconPixmap(const QString &name, const QSize desiredSize) -{ - const PsiIcon *i = iconPtr(name); +QPixmap IconsetFactory::iconPixmap(const QString& name, const QSize desiredSize) { + const PsiIcon* i = iconPtr(name); if (i) { - if (!desiredSize.isEmpty() && i->isScalable()) - return i->pixmap(desiredSize); + if (!desiredSize.isEmpty() && i->isScalable()) return i->pixmap(desiredSize); return i->impix().pixmap(); } @@ -975,9 +920,8 @@ const QStringList IconsetFactory::icons() { return IconsetFactoryPrivate::instan /** * Returs image raw data aka original image */ -const QByteArray IconsetFactory::raw(const QString &name) -{ - const PsiIcon *i = iconPtr(name); +const QByteArray IconsetFactory::raw(const QString& name) { + const PsiIcon* i = iconPtr(name); if (i) { return i->raw(); } @@ -1003,54 +947,50 @@ const QByteArray IconsetFactory::raw(const QString &name) //! \if _hide_doc_ class Iconset::Private : public QSharedData { private: - void init() - { + void init() { name = "Unnamed"; // version = "1.0"; // description = "No description"; // authors << "I. M. Anonymous"; // creation = "1900-01-01"; - homeUrl = QString(); + homeUrl = QString(); iconSize_ = 16; } public: - QString id, name, version, description, creation, homeUrl, filename; - QStringList authors; - QHash dict; // unsorted hash for fast search - QList list; // sorted list - QHash info; - int iconSize_; + QString id, name, version, description, creation, homeUrl, filename; + QStringList authors; + QHash dict; // unsorted hash for fast search + QList list; // sorted list + QHash info; + int iconSize_; QHash zipCache; public: Private() { init(); } - Private(const Private &from) : QSharedData() - { + Private(const Private& from) : QSharedData() { init(); setInformation(from); - QListIterator it(from.list); + QListIterator it(from.list); while (it.hasNext()) { - PsiIcon *icon = new PsiIcon(*it.next()); + PsiIcon* icon = new PsiIcon(*it.next()); append(icon->name(), icon); } } ~Private() { clear(); } - void append(QString n, PsiIcon *icon) - { + void append(QString n, PsiIcon* icon) { // all PsiIcon names in Iconset must be unique remove(dict.find(n)); dict[n] = icon; list.append(icon); } - void clear() - { + void clear() { dict.clear(); while (!list.isEmpty()) { delete list.takeFirst(); @@ -1059,18 +999,16 @@ class Iconset::Private : public QSharedData { void remove(QString name) { remove(dict.find(name)); } - void remove(QHash::iterator it) - { + void remove(QHash::iterator it) { if (it != dict.end()) { - PsiIcon *i = it.value(); + PsiIcon* i = it.value(); dict.erase(it); list.removeAll(i); delete i; } } - QByteArray loadData(const QString &fileName, const QString &dir) - { + QByteArray loadData(const QString& fileName, const QString& dir) { QByteArray ba; QFileInfo fi(dir); @@ -1088,10 +1026,9 @@ class Iconset::Private : public QSharedData { ba = file.readAll(); } #ifdef ICONSET_ZIP - else { // else its zip or jisp file + else { // else its zip or jisp file UnZip z(dir); - if (zipCache.isEmpty()) - zipCache = z.unpackAll(); + if (zipCache.isEmpty()) zipCache = z.unpackAll(); ba = zipCache.value(fi.completeBaseName() + '/' + fileName); } #endif @@ -1099,8 +1036,7 @@ class Iconset::Private : public QSharedData { return ba; } - void loadMeta(const QDomElement &i, const QString &dir) - { + void loadMeta(const QDomElement& i, const QString& dir) { Q_UNUSED(dir); iconSize_ = 16; @@ -1116,13 +1052,13 @@ class Iconset::Private : public QSharedData { name = e.text(); } else if (tag == "size") { QString str = e.text(); - iconSize_ = str.toInt(); + iconSize_ = str.toInt(); } else if (tag == "version") { version = e.text(); } else if (tag == "description") { description = e.text(); } else if (tag == "author") { - QString n = e.text(); + QString n = e.text(); QString tmp = "
  "; if (!e.attribute("email").isEmpty()) { QString s = e.attribute("email"); @@ -1145,13 +1081,12 @@ class Iconset::Private : public QSharedData { } } - static int icon_counter; // used to give unique names to icons + static int icon_counter; // used to give unique names to icons // will return 'true' when icon is loaded ok - bool loadKdeEmoticon(const QDomElement &emot, const QString &dir, QSize &size) - { - static const QStringList exts = { "png", "gif", "svg", "svgz", "mng" }; - auto baseFN = emot.attribute(QLatin1String("file")); + bool loadKdeEmoticon(const QDomElement& emot, const QString& dir, QSize& size) { + static const QStringList exts = {"png", "gif", "svg", "svgz", "mng"}; + auto baseFN = emot.attribute(QLatin1String("file")); PsiIcon icon; icon.blockSignals(true); @@ -1159,8 +1094,8 @@ class Iconset::Private : public QSharedData { QList text; for (QDomElement i = emot.firstChildElement(QLatin1String("string")); !i.isNull(); - i = i.nextSiblingElement(QLatin1String("string"))) { - text.append({ "", i.text() }); + i = i.nextSiblingElement(QLatin1String("string"))) { + text.append({"", i.text()}); } if (text.isEmpty()) { @@ -1168,14 +1103,14 @@ class Iconset::Private : public QSharedData { return false; } - auto baseFNPath = dir + QLatin1String("/") + baseFN; + auto baseFNPath = dir + QLatin1String("/") + baseFN; QFileInfo finfo(baseFNPath); - bool found = finfo.isReadable(); + bool found = finfo.isReadable(); if (!found) - for (auto const &fext : exts) { + for (auto const& fext : exts) { auto tmpFN = baseFNPath + QLatin1String(".") + fext; - finfo = QFileInfo(tmpFN); - found = finfo.isReadable(); + finfo = QFileInfo(tmpFN); + found = finfo.isReadable(); if (found) { break; } @@ -1190,22 +1125,23 @@ class Iconset::Private : public QSharedData { icon.setName(baseFN); QString mime; - bool isScalable = false; - bool isAnimated = false; + bool isScalable = false; + bool isAnimated = false; if (finfo.suffix() == "svg" || finfo.suffix() == "svgz") { isScalable = true; - mime = QLatin1String("image/svg+xml"); + mime = QLatin1String("image/svg+xml"); } else if (finfo.suffix() == "png") { mime = QLatin1String("image/png"); } else if (finfo.suffix() == "gif") { - mime = QLatin1String("image/gif"); + mime = QLatin1String("image/gif"); isAnimated = true; } else { mime = QLatin1String("image/mng"); } QFile file(finfo.filePath()); - if (!(file.open(QIODevice::ReadOnly) && icon.loadFromData(mime, file.readAll(), isAnimated, isScalable))) { + if (!(file.open(QIODevice::ReadOnly) && + icon.loadFromData(mime, file.readAll(), isAnimated, isScalable))) { qWarning("failed to read emoticon: %s", qPrintable(baseFN)); return false; } @@ -1213,7 +1149,7 @@ class Iconset::Private : public QSharedData { // construct RegExp if (text.count()) { QStringList regexp; - for (const PsiIcon::IconText &t : qAsConst(text)) { + for (const PsiIcon::IconText& t : qAsConst(text)) { regexp += QRegExp::escape(t.text); } @@ -1230,18 +1166,17 @@ class Iconset::Private : public QSharedData { } // will return 'true' when icon is loaded ok - bool loadIcon(const QDomElement &i, const QString &dir) - { + bool loadIcon(const QDomElement& i, const QString& dir) { PsiIcon icon; icon.blockSignals(true); QList text; - QHash graphic, sound, object; // mime => filename + QHash graphic, sound, object; // mime => filename - QString name = QString::asprintf("icon_%04d", icon_counter++); - bool isAnimated = false; - bool isImage = false; - bool isScalable = false; + QString name = QString::asprintf("icon_%04d", icon_counter++); + bool isAnimated = false; + bool isImage = false; + bool isScalable = false; for (QDomNode n = i.firstChild(); !n.isNull(); n = n.nextSibling()) { QDomElement e = n.toElement(); @@ -1253,7 +1188,7 @@ class Iconset::Private : public QSharedData { if (tag == "text") { QString lang = e.attribute("xml:lang"); if (lang.isEmpty()) { - lang = ""; // otherwise there would be many warnings :-( + lang = ""; // otherwise there would be many warnings :-( } QString t = e.text(); if (!t.isEmpty()) { @@ -1270,7 +1205,8 @@ class Iconset::Private : public QSharedData { isAnimated = true; } else if (e.text() == "image") { isImage = true; - } else if (e.text() == "scalable") { // force scalability. should work well for big enough images + } else if (e.text() == "scalable") { // force scalability. should work well for + // big enough images isScalable = true; } } @@ -1287,12 +1223,13 @@ class Iconset::Private : public QSharedData { icon.setName(name); // first item have higher priority than latter - static const QStringList graphicMime { "image/svg+xml", "image/png", "image/gif", - "image/x-xpm", "image/bmp", "image/jpeg" }; - static const QStringList scalableMime { "image/svg+xml" }; - static const QStringList soundMime { "audio/x-wav", "audio/x-ogg", "audio/x-mp3", "audio/x-midi" }; + static const QStringList graphicMime{"image/svg+xml", "image/png", "image/gif", + "image/x-xpm", "image/bmp", "image/jpeg"}; + static const QStringList scalableMime{"image/svg+xml"}; + static const QStringList soundMime{"audio/x-wav", "audio/x-ogg", "audio/x-mp3", + "audio/x-midi"}; // MIME-types, that support animations - static const QStringList animationMime { "image/gif" }; + static const QStringList animationMime{"image/gif"}; QStringList preferredGraphic; QStringList preferredSound; @@ -1301,7 +1238,7 @@ class Iconset::Private : public QSharedData { // 'object' entries. inspect the supported mimetypes // and copy mime info and file path to 'graphic' and // 'sound' dictonaries. - for (auto const &mime : graphicMime) { + for (auto const& mime : graphicMime) { auto it = object.find(mime); if (it != object.end()) { graphic.insert(mime, it.value()); @@ -1309,7 +1246,7 @@ class Iconset::Private : public QSharedData { } } - for (auto const &mime : soundMime) { + for (auto const& mime : soundMime) { auto it = object.find(mime); if (it != object.end()) { sound.insert(mime, it.value()); @@ -1318,76 +1255,95 @@ class Iconset::Private : public QSharedData { } } - bool loadSuccess = std::any_of(preferredGraphic.begin(), preferredGraphic.end(), [&, this](const auto &mime) { - QString fileName = graphic.value(mime); - // if format supports animations, then load graphic as animation, and - // if there is only one frame, then later it would be converted to single Impix - QByteArray ba = this->loadData(fileName, dir); - Q_ASSERT(!dir.startsWith(QLatin1String(":/")) || !ba.isEmpty()); - if (!ba.isEmpty() - && icon.loadFromData(mime, ba, isAnimated || (!isImage && animationMime.indexOf(mime) != -1), - isScalable || scalableMime.indexOf(mime) != -1)) - return true; - - qDebug("Iconset::load(): Couldn't load %s (%s) graphic for the %s icon for the %s iconset", - qPrintable(mime), qPrintable(fileName), qPrintable(name), qPrintable(this->name)); - return false; - }); - -#ifdef ICONSET_SOUND - loadSuccess = loadSuccess && (sound.isEmpty() || std::any_of(preferredSound.begin(), preferredSound.end(), [&, this](const auto &mime) { - QFileInfo fi(dir); - QString fileName = sound[mime]; - if (!fi.isDir()) { // it is a .zip file then - if (!iconSharedObject) { - iconSharedObject = new IconSharedObject(); - } - - QString path = iconSharedObject->unpackPath; - if (path.isEmpty()) { - qDebug("Iconset::load(): Couldn't load %s (%s) audio for the %s icon for the %s iconset. " - "unpack path is empty", - qPrintable(mime), qPrintable(fileName), qPrintable(name), qPrintable(this->name)); - return false; - } - - QFileInfo ext(fileName); - path += "/" + lib::base::Hashs::sha1(QString(fi.absoluteFilePath() + '/' + fileName).toUtf8()) - + '.' + ext.suffix(); - - QFile file(path); - file.open(QIODevice::WriteOnly); - QDataStream out(&file); - - QByteArray data = this->loadData(fileName, dir); // "this" for compatibility with old gcc - if (data.isEmpty()) { - qDebug("Iconset::load(): Couldn't load %s (%s) audio for the %s icon for the %s iconset. " - "file is empty", - qPrintable(mime), qPrintable(fileName), qPrintable(name), qPrintable(this->name)); + bool loadSuccess = std::any_of( + preferredGraphic.begin(), preferredGraphic.end(), [&, this](const auto& mime) { + QString fileName = graphic.value(mime); + // if format supports animations, then load graphic as animation, and + // if there is only one frame, then later it would be converted to single Impix + QByteArray ba = this->loadData(fileName, dir); + Q_ASSERT(!dir.startsWith(QLatin1String(":/")) || !ba.isEmpty()); + if (!ba.isEmpty() && + icon.loadFromData( + mime, ba, + isAnimated || (!isImage && animationMime.indexOf(mime) != -1), + isScalable || scalableMime.indexOf(mime) != -1)) + return true; + + qDebug("Iconset::load(): Couldn't load %s (%s) graphic for the %s icon for the " + "%s iconset", + qPrintable(mime), qPrintable(fileName), qPrintable(name), + qPrintable(this->name)); return false; - } + }); - out.writeRawData(data, data.size()); - icon.setSound(path); - return true; - } else { - QString absFN = fi.absoluteFilePath() + '/' + fileName; - if (QFileInfo(absFN).isReadable()) { - icon.setSound(absFN); - return true; - } - qDebug("Iconset::load(): Couldn't load %s (%s) audio for the %s icon for the %s iconset. " - "not readable", - qPrintable(mime), qPrintable(fileName), qPrintable(name), qPrintable(this->name)); - return false; - } - })); +#ifdef ICONSET_SOUND + loadSuccess = + loadSuccess && + (sound.isEmpty() || + std::any_of( + preferredSound.begin(), preferredSound.end(), [&, this](const auto& mime) { + QFileInfo fi(dir); + QString fileName = sound[mime]; + if (!fi.isDir()) { // it is a .zip file then + if (!iconSharedObject) { + iconSharedObject = new IconSharedObject(); + } + + QString path = iconSharedObject->unpackPath; + if (path.isEmpty()) { + qDebug("Iconset::load(): Couldn't load %s (%s) audio for the " + "%s icon for the %s iconset. " + "unpack path is empty", + qPrintable(mime), qPrintable(fileName), + qPrintable(name), qPrintable(this->name)); + return false; + } + + QFileInfo ext(fileName); + path += "/" + + lib::base::Hashs::sha1( + QString(fi.absoluteFilePath() + '/' + fileName) + .toUtf8()) + + '.' + ext.suffix(); + + QFile file(path); + file.open(QIODevice::WriteOnly); + QDataStream out(&file); + + QByteArray data = this->loadData( + fileName, dir); // "this" for compatibility with old gcc + if (data.isEmpty()) { + qDebug("Iconset::load(): Couldn't load %s (%s) audio for the " + "%s icon for the %s iconset. " + "file is empty", + qPrintable(mime), qPrintable(fileName), + qPrintable(name), qPrintable(this->name)); + return false; + } + + out.writeRawData(data, data.size()); + icon.setSound(path); + return true; + } else { + QString absFN = fi.absoluteFilePath() + '/' + fileName; + if (QFileInfo(absFN).isReadable()) { + icon.setSound(absFN); + return true; + } + qDebug("Iconset::load(): Couldn't load %s (%s) audio for the %s " + "icon for the %s iconset. " + "not readable", + qPrintable(mime), qPrintable(fileName), qPrintable(name), + qPrintable(this->name)); + return false; + } + })); #endif // construct RegExp if (text.count()) { QStringList regexp; - for (const PsiIcon::IconText &t : qAsConst(text)) { + for (const PsiIcon::IconText& t : qAsConst(text)) { regexp += QRegExp::escape(t.text); } @@ -1407,8 +1363,7 @@ class Iconset::Private : public QSharedData { return loadSuccess; } - bool loadKdeEmoticons(const QDomDocument &doc, const QString dir) - { + bool loadKdeEmoticons(const QDomDocument& doc, const QString dir) { QDomElement base = doc.documentElement(); if (base.tagName() != "messaging-emoticon-map") { qWarning("failed to load iconset invalid toplevel xml element"); @@ -1416,16 +1371,15 @@ class Iconset::Private : public QSharedData { } bool success = false; - name = QFileInfo(dir).fileName(); - version = "unknown"; - description = "KDE Emoticons"; - iconSize_ = 0; + name = QFileInfo(dir).fileName(); + version = "unknown"; + description = "KDE Emoticons"; + iconSize_ = 0; for (QDomElement i = base.firstChildElement(QLatin1String("emoticon")); !i.isNull(); - i = i.nextSiblingElement(QLatin1String("emoticon"))) { - + i = i.nextSiblingElement(QLatin1String("emoticon"))) { QSize s; - bool ret = loadKdeEmoticon(i, dir, s); + bool ret = loadKdeEmoticon(i, dir, s); if (ret) { success = true; if (s.height() > iconSize_) { @@ -1438,8 +1392,7 @@ class Iconset::Private : public QSharedData { } // would return 'true' on success - bool load(const QDomDocument &doc, const QString dir) - { + bool load(const QDomDocument& doc, const QString dir) { QDomElement base = doc.documentElement(); if (base.tagName() != "icondef") { qWarning("failed to load iconset invalid toplevel xml element"); @@ -1470,17 +1423,16 @@ class Iconset::Private : public QSharedData { return success; } - void setInformation(const Private &from) - { - name = from.name; - version = from.version; + void setInformation(const Private& from) { + name = from.name; + version = from.version; description = from.description; - creation = from.creation; - homeUrl = from.homeUrl; - filename = from.filename; - authors = from.authors; - info = from.info; - iconSize_ = from.iconSize_; + creation = from.creation; + homeUrl = from.homeUrl; + filename = from.filename; + authors = from.authors; + info = from.info; + iconSize_ = from.iconSize_; } }; //! \endif @@ -1492,8 +1444,7 @@ int Iconset::Private::icon_counter = 0; /** * Creates empty Iconset. */ -Iconset::Iconset() -{ +Iconset::Iconset() { // iconset_counter++; d = new Private; @@ -1502,8 +1453,7 @@ Iconset::Iconset() /** * Creates shared copy of Iconset \a from. */ -Iconset::Iconset(const Iconset &from) -{ +Iconset::Iconset(const Iconset& from) { // iconset_counter++; d = from.d; @@ -1517,15 +1467,13 @@ Iconset::~Iconset() { IconsetFactoryPrivate::instance()->unregisterIconset(this) /** * Copies all Icons as well as additional information from Iconset \a from. */ -Iconset &Iconset::operator=(const Iconset &from) -{ +Iconset& Iconset::operator=(const Iconset& from) { d = from.d; return *this; } -Iconset Iconset::copy() const -{ +Iconset Iconset::copy() const { Iconset is; is.d = new Private(*this->d.data()); @@ -1537,13 +1485,12 @@ void Iconset::detach() { d.detach(); } /** * Appends icons from Iconset \a from to this Iconset. */ -Iconset &Iconset::operator+=(const Iconset &i) -{ +Iconset& Iconset::operator+=(const Iconset& i) { detach(); - QListIterator it(i.d->list); + QListIterator it(i.d->list); while (it.hasNext()) { - PsiIcon *icon = new PsiIcon(*it.next()); + PsiIcon* icon = new PsiIcon(*it.next()); d->append(icon->name(), icon); } @@ -1553,8 +1500,7 @@ Iconset &Iconset::operator+=(const Iconset &i) /** * Frees all allocated Icons. */ -void Iconset::clear() -{ +void Iconset::clear() { detach(); d->clear(); @@ -1569,8 +1515,7 @@ int Iconset::count() const { return d->list.count(); } * Loads Icons and additional information from directory \a dir. Directory can usual directory, * or a .zip/.jisp archive. There must exist file named \c icondef.xml in that directory. */ -bool Iconset::load(const QString &dir, Format format) -{ +bool Iconset::load(const QString& dir, Format format) { if (dir.isEmpty()) { return false; } @@ -1588,29 +1533,30 @@ bool Iconset::load(const QString &dir, Format format) QString fileName; switch (format) { - case Format::Psi: - d->id = dir.section('/', -2); - fileName = QLatin1String("icondef.xml"); - break; - case Format::KdeEmoticons: - d->id = dir.section('/', -1); - fileName = QLatin1String("emoticons.xml"); - break; - default: - return false; + case Format::Psi: + d->id = dir.section('/', -2); + fileName = QLatin1String("icondef.xml"); + break; + case Format::KdeEmoticons: + d->id = dir.section('/', -1); + fileName = QLatin1String("emoticons.xml"); + break; + default: + return false; } ba = d->loadData(fileName, dir); if (!ba.isEmpty()) { QDomDocument doc; if (doc.setContent(ba, false)) { - if ((format == Format::Psi && d->load(doc, dir)) - || (format == Format::KdeEmoticons && d->loadKdeEmoticons(doc, dir))) { + if ((format == Format::Psi && d->load(doc, dir)) || + (format == Format::KdeEmoticons && d->loadKdeEmoticons(doc, dir))) { d->filename = dir; - ret = true; + ret = true; } } else { - qWarning("Iconset::load(\"%s\"): Failed to load iconset: icondef.xml is invalid XML", qPrintable(dir)); + qWarning("Iconset::load(\"%s\"): Failed to load iconset: icondef.xml is invalid XML", + qPrintable(dir)); } } else { Q_ASSERT_X(!dir.startsWith(QLatin1String(":/")) || !ba.isEmpty(), qPrintable(dir), @@ -1628,8 +1574,7 @@ bool Iconset::load(const QString &dir, Format format) * Returns pointer to PsiIcon, if PsiIcon with name \a name was found in Iconset, or \a 0 otherwise. * \sa setIcon() */ -const PsiIcon *Iconset::icon(const QString &name) const -{ +const PsiIcon* Iconset::icon(const QString& name) const { if (!d || d->dict.isEmpty()) { return nullptr; } @@ -1640,11 +1585,10 @@ const PsiIcon *Iconset::icon(const QString &name) const /** * Appends PsiIcon to Iconset. If the PsiIcon with that name already exists, it is removed. */ -void Iconset::setIcon(const QString &name, const PsiIcon &icon) -{ +void Iconset::setIcon(const QString& name, const PsiIcon& icon) { detach(); - PsiIcon *newIcon = new PsiIcon(icon); + PsiIcon* newIcon = new PsiIcon(icon); d->remove(name); d->append(name, newIcon); @@ -1653,8 +1597,7 @@ void Iconset::setIcon(const QString &name, const PsiIcon &icon) /** * Removes PsiIcon with the name \a name from Iconset. */ -void Iconset::removeIcon(const QString &name) -{ +void Iconset::removeIcon(const QString& name) { detach(); d->remove(name); @@ -1663,68 +1606,66 @@ void Iconset::removeIcon(const QString &name) /** * Returns the Iconset unique identifier (ex: "system/default"). */ -const QString &Iconset::id() const { return d->id; } +const QString& Iconset::id() const { return d->id; } /** * Returns the Iconset name. */ -const QString &Iconset::name() const { return d->name; } +const QString& Iconset::name() const { return d->name; } /** * Returns the icons size from Iconset. */ -const int &Iconset::iconSize() const { return d->iconSize_; } +const int& Iconset::iconSize() const { return d->iconSize_; } /** * Returns the Iconset version. */ -const QString &Iconset::version() const { return d->version; } +const QString& Iconset::version() const { return d->version; } /** * Returns the Iconset description string. */ -const QString &Iconset::description() const { return d->description; } +const QString& Iconset::description() const { return d->description; } /** * Returns the Iconset authors list. */ -const QStringList &Iconset::authors() const { return d->authors; } +const QStringList& Iconset::authors() const { return d->authors; } /** * Returns the Iconset creation date. */ -const QString &Iconset::creation() const { return d->creation; } +const QString& Iconset::creation() const { return d->creation; } /** * Returns the Iconsets' home URL. */ -const QString &Iconset::homeUrl() const { return d->homeUrl; } +const QString& Iconset::homeUrl() const { return d->homeUrl; } -QListIterator Iconset::iterator() const -{ - QListIterator it(d->list); +QListIterator Iconset::iterator() const { + QListIterator it(d->list); return it; } -QList::const_iterator Iconset::begin() const { return d->list.cbegin(); } +QList::const_iterator Iconset::begin() const { return d->list.cbegin(); } -QList::const_iterator Iconset::end() const { return d->list.cend(); } +QList::const_iterator Iconset::end() const { return d->list.cend(); } /** * Returns directory (or .zip/.jisp archive) name from which Iconset was loaded. */ -const QString &Iconset::fileName() const { return d->filename; } +const QString& Iconset::fileName() const { return d->filename; } /** * Sets the Iconset directory (.zip archive) name. */ -void Iconset::setFileName(const QString &f) { d->filename = f; } +void Iconset::setFileName(const QString& f) { d->filename = f; } /** * Sets the information (meta-data) of this iconset to the information from the given iconset. */ -void Iconset::setInformation(const Iconset &from) -{ +void Iconset::setInformation(const Iconset& from) { detach(); d->setInformation(*(from.d)); } @@ -1739,7 +1680,7 @@ const QHash Iconset::info() const { return d->info; } * Sets additional Iconset information. * \sa info() */ -void Iconset::setInfo(const QHash &i) { d->info = i; } +void Iconset::setInfo(const QHash& i) { d->info = i; } /** * Adds Iconset to IconsetFactory. @@ -1749,13 +1690,13 @@ void Iconset::addToFactory() const { IconsetFactoryPrivate::instance()->register /** * Removes Iconset from IconsetFactory. */ -void Iconset::removeFromFactory() const { IconsetFactoryPrivate::instance()->unregisterIconset(this); } +void Iconset::removeFromFactory() const { + IconsetFactoryPrivate::instance()->unregisterIconset(this); +} -bool Iconset::isSourceAllowed(const QFileInfo &fi) -{ +bool Iconset::isSourceAllowed(const QFileInfo& fi) { #ifdef ICONSET_ZIP - if (fi.isDir()) - return true; + if (fi.isDir()) return true; QString lower = fi.suffix().toLower(); return lower == "jisp" || lower == ".zip"; #else @@ -1779,8 +1720,7 @@ bool Iconset::isSourceAllowed(const QFileInfo &fi) * the signal 'playSound(QString fileName)'. Slot should play the specified sound * file. */ -void Iconset::setSoundPrefs(QString unpackPath, QObject *receiver, const char *slot) -{ +void Iconset::setSoundPrefs(QString unpackPath, QObject* receiver, const char* slot) { #ifdef ICONSET_SOUND if (!iconSharedObject) { iconSharedObject = new IconSharedObject(); diff --git a/src/lib/plugin/iconset/iconset.h b/src/lib/plugin/iconset/iconset.h index 3be90978..bd430219 100644 --- a/src/lib/plugin/iconset/iconset.h +++ b/src/lib/plugin/iconset/iconset.h @@ -30,56 +30,51 @@ class QIcon; class Impix { public: Impix(); - Impix(const QPixmap &); - Impix(const QImage &); + Impix(const QPixmap&); + Impix(const QImage&); void unload(); bool isNull() const; - const QPixmap &pixmap() const; - const QImage & image() const; - void setPixmap(const QPixmap &); - void setImage(const QImage &); + const QPixmap& pixmap() const; + const QImage& image() const; + void setPixmap(const QPixmap&); + void setImage(const QImage&); - operator const QPixmap &() const { return pixmap(); } - operator const QImage &() const { return image(); } - Impix &operator=(const QPixmap &from) - { + operator const QPixmap&() const { return pixmap(); } + operator const QImage&() const { return image(); } + Impix& operator=(const QPixmap& from) { setPixmap(from); return *this; } - Impix &operator=(const QImage &from) - { + Impix& operator=(const QImage& from) { setImage(from); return *this; } QSize size() const; - bool loadFromData(const QByteArray &); + bool loadFromData(const QByteArray&); private: class Private : public QSharedData { public: - QPixmap *pixmap; - QImage image; + QPixmap* pixmap; + QImage image; Private() { pixmap = nullptr; } - Private(const Private &from) : QSharedData(from) - { + Private(const Private& from) : QSharedData(from) { pixmap = from.pixmap ? new QPixmap(*from.pixmap) : nullptr; - image = from.image; + image = from.image; } ~Private() { unload(); } - void unload() - { - if (pixmap) - delete pixmap; + void unload() { + if (pixmap) delete pixmap; pixmap = nullptr; - image = QImage(); + image = QImage(); } }; @@ -90,10 +85,10 @@ class PsiIcon : public QObject { Q_OBJECT public: PsiIcon(); - PsiIcon(const PsiIcon &); + PsiIcon(const PsiIcon&); ~PsiIcon(); - PsiIcon &operator=(const PsiIcon &); + PsiIcon& operator=(const PsiIcon&); //! //! Returns impix().pixmap(). @@ -107,63 +102,65 @@ class PsiIcon : public QObject { //! see icon(). // operator const QIcon &() const { return icon(); } - virtual bool isAnimated() const; - virtual QPixmap pixmap(const QSize &desiredSize = QSize()) const; - virtual QImage image(const QSize &desiredSize = QSize()) const; - virtual QIcon icon() const; - const QByteArray &raw() const; - QSize size(const QSize &desiredSize = QSize()) const; - bool isScalable() const; - const QString & mimeType() const; + virtual bool isAnimated() const; + virtual QPixmap pixmap(const QSize& desiredSize = QSize()) const; + virtual QImage image(const QSize& desiredSize = QSize()) const; + virtual QIcon icon() const; + const QByteArray& raw() const; + QSize size(const QSize& desiredSize = QSize()) const; + bool isScalable() const; + const QString& mimeType() const; - virtual const Impix &impix() const; - virtual const Impix &frameImpix() const; - void setImpix(const Impix &, bool doDetach = true); + virtual const Impix& impix() const; + virtual const Impix& frameImpix() const; + void setImpix(const Impix&, bool doDetach = true); - const Anim *anim() const; - void setAnim(const Anim &, bool doDetach = true); - void removeAnim(bool doDetach = true); + const Anim* anim() const; + void setAnim(const Anim&, bool doDetach = true); + void removeAnim(bool doDetach = true); virtual int frameNumber() const; - virtual const QString &name() const; - void setName(const QString &); + virtual const QString& name() const; + void setName(const QString&); - const QRegExp ®Exp() const; - void setRegExp(const QRegExp &); + const QRegExp& regExp() const; + void setRegExp(const QRegExp&); struct IconText { - IconText(QString _lang, QString _text) : lang(_lang), text(_text) { } + IconText(QString _lang, QString _text) : lang(_lang), text(_text) {} QString lang; QString text; }; - const QList &text() const; - void setText(const QList &); + const QList& text() const; + void setText(const QList&); QString defaultText() const; - const QString &sound() const; - void setSound(const QString &); + const QString& sound() const; + void setSound(const QString&); bool blockSignals(bool); - bool loadFromData(const QString &mime, const QByteArray &, bool isAnimation, bool isScalable = false); + bool loadFromData(const QString& mime, const QByteArray&, bool isAnimation, + bool isScalable = false); void stripFirstAnimFrame(); - virtual PsiIcon *copy() const; - void detach(); + virtual PsiIcon* copy() const; + void detach(); signals: void pixmapChanged(); void iconModified(); public slots: - virtual void activated(bool playSound = true); // it just has been inserted in the text, or now it's being displayed - // by some widget. icon should play sound and start animation + virtual void activated(bool playSound = true); // it just has been inserted in the text, or now + // it's being displayed by some widget. icon + // should play sound and start animation - virtual void stop(); // this icon is no more displaying. stop animation + virtual void stop(); // this icon is no more displaying. stop animation public: class Private; @@ -177,50 +174,50 @@ class Iconset { enum class Format { Psi, KdeEmoticons }; Iconset(); - Iconset(const Iconset &); + Iconset(const Iconset&); ~Iconset(); - Iconset &operator=(const Iconset &); - Iconset &operator+=(const Iconset &); + Iconset& operator=(const Iconset&); + Iconset& operator+=(const Iconset&); void clear(); - int count() const; + int count() const; - bool load(const QString &dir, Format format = Format::Psi); + bool load(const QString& dir, Format format = Format::Psi); - const PsiIcon *icon(const QString &) const; - void setIcon(const QString &, const PsiIcon &); - void removeIcon(const QString &); + const PsiIcon* icon(const QString&) const; + void setIcon(const QString&, const PsiIcon&); + void removeIcon(const QString&); - const QString & id() const; - const QString & name() const; - const QString & version() const; - const QString & description() const; - const QStringList &authors() const; - const QString & creation() const; - const QString & homeUrl() const; - const int & iconSize() const; + const QString& id() const; + const QString& name() const; + const QString& version() const; + const QString& description() const; + const QStringList& authors() const; + const QString& creation() const; + const QString& homeUrl() const; + const int& iconSize() const; - const QString &fileName() const; - void setFileName(const QString &); + const QString& fileName() const; + void setFileName(const QString&); - void setInformation(const Iconset &from); + void setInformation(const Iconset& from); const QHash info() const; - void setInfo(const QHash &); + void setInfo(const QHash&); - QListIterator iterator() const; - QList::const_iterator begin() const; - QList::const_iterator end() const; + QListIterator iterator() const; + QList::const_iterator begin() const; + QList::const_iterator end() const; void addToFactory() const; void removeFromFactory() const; - static bool isSourceAllowed(const QFileInfo &fi); - static void setSoundPrefs(QString unpackPath, QObject *receiver, const char *slot); + static bool isSourceAllowed(const QFileInfo& fi); + static void setSoundPrefs(QString unpackPath, QObject* receiver, const char* slot); Iconset copy() const; - void detach(); + void detach(); private: class Private; @@ -231,18 +228,19 @@ class IconsetFactory { public: static void reset(); - static PsiIcon icon(const QString &name); - static inline PsiIcon icon(const char *name) { return icon(QString(QLatin1String(name))); } // optimization - static QPixmap iconPixmap(const QString &name, const QSize desiredSize = QSize()); - static inline QPixmap iconPixmap(const QString &name, int desiredSize) - { + static PsiIcon icon(const QString& name); + static inline PsiIcon icon(const char* name) { + return icon(QString(QLatin1String(name))); + } // optimization + static QPixmap iconPixmap(const QString& name, const QSize desiredSize = QSize()); + static inline QPixmap iconPixmap(const QString& name, int desiredSize) { return iconPixmap(name, QSize(desiredSize, desiredSize)); } - static const PsiIcon * iconPtr(const QString &name); + static const PsiIcon* iconPtr(const QString& name); static const QStringList icons(); - static const QByteArray raw(const QString &name); + static const QByteArray raw(const QString& name); }; -#endif // ICONSET_H +#endif // ICONSET_H diff --git a/src/lib/plugin/ok_iconset.cpp b/src/lib/plugin/ok_iconset.cpp index 2785b33d..c2fcbb50 100644 --- a/src/lib/plugin/ok_iconset.cpp +++ b/src/lib/plugin/ok_iconset.cpp @@ -25,8 +25,8 @@ using namespace XMPP; struct ClientIconCheck { - QString icon; // icon name w/o client/ part - QStringList inside; // search for texts inside provided name to be sure + QString icon; // icon name w/o client/ part + QStringList inside; // search for texts inside provided name to be sure }; /* @@ -39,9 +39,9 @@ struct ClientIconCheck { * psi-ny psi#ny * * First column is icon name in the iconpack and remaining is a set of caps/clientName search spec. - * This mean for clients with caps node starting with: psi+ and also for nodes starting with psi and having - * word "fork" or "plus" somewhere inside, "psi-plus" icons will be used. For psi-ny (New Year edition) icon - * caps whould start with "psi" and have "ny" somewhere in the middle. + * This mean for clients with caps node starting with: psi+ and also for nodes starting with psi and + * having word "fork" or "plus" somewhere inside, "psi-plus" icons will be used. For psi-ny (New + * Year edition) icon caps whould start with "psi" and have "ny" somewhere in the middle. * * The structire below will look like * @@ -57,15 +57,16 @@ struct ClientIconCheck { * psi-plus/psi-ny - icon name * fork/plus/ny - parts of caps/client name * - * Now for example we need to lookup icon for caps node "psiplus.com". The most still mathing item here is "psi", - * (psi+ won't match because psiplus.com doesn't start with psi+). And we don't have anything like "psip" or "psipl".. - * So we review just "psi" (all its items consequently) - * Both items in "psi" have clarification list. For the first item we take its clarification list ["fork", "plus"] - * and review if any item is in "psiplus.com". The "plus" will be found, so the icon "psi-plus" will be returned. + * Now for example we need to lookup icon for caps node "psiplus.com". The most still mathing item + * here is "psi", (psi+ won't match because psiplus.com doesn't start with psi+). And we don't have + * anything like "psip" or "psipl".. So we review just "psi" (all its items consequently) Both items + * in "psi" have clarification list. For the first item we take its clarification list ["fork", + * "plus"] and review if any item is in "psiplus.com". The "plus" will be found, so the icon + * "psi-plus" will be returned. * - * Note: It's quite regular for caps node to start with "https" but current client_icons.txt almost doesn't have - * such records. It just means it heavily rely on detected client names instead of caps. - * Client name from its side maybe taken from caps node when there is not other way to detect. + * Note: It's quite regular for caps node to start with "https" but current client_icons.txt almost + * doesn't have such records. It just means it heavily rely on detected client names instead of + * caps. Client name from its side maybe taken from caps node when there is not other way to detect. * Example: * caps node = https://www.psi-im.org/helloworld/caps * resulting client name = psi-im.org/helloworld @@ -78,13 +79,13 @@ typedef QMap> ClientIconMap; class PsiIconset::Private { private: - PsiIconset *psi; + PsiIconset* psi; public: - Iconset system, moods, clients, activities, affiliations; - ClientIconMap client2icon; - QString cur_system, cur_status, cur_moods, cur_clients, cur_activity, cur_affiliations; - QStringList cur_emoticons; + Iconset system, moods, clients, activities, affiliations; + ClientIconMap client2icon; + QString cur_system, cur_status, cur_moods, cur_clients, cur_activity, cur_affiliations; + QStringList cur_emoticons; QMap cur_service_status; QMap cur_custom_status; struct StatusIconsets { @@ -92,29 +93,29 @@ class PsiIconset::Private { QRegExp regexp; QString iconset; }; - bool useServicesIcons = false; + bool useServicesIcons = false; QList list; QList customList; } status_icons; - Private(PsiIconset *_psi) { psi = _psi; } + Private(PsiIconset* _psi) { psi = _psi; } - QString iconsetPath(QString name, Iconset::Format format = Iconset::Format::Psi) - { + QString iconsetPath(QString name, Iconset::Format format = Iconset::Format::Psi) { if (format == Iconset::Format::Psi) { - const auto &dataDirs = ApplicationInfo::dataDirs(); - for (const QString &d : dataDirs) { - QString fileName = d + "/iconsets/" + name; + const auto& dataDirs = ApplicationInfo::dataDirs(); + for (const QString& d : dataDirs) { + QString fileName = d + "/iconsets/" + name; QFileInfo fi(fileName); if (fi.exists()) { return fileName; } } } else if (format == Iconset::Format::KdeEmoticons) { - const auto &dataDirs = QStandardPaths::locateAll( - QStandardPaths::GenericDataLocation, QLatin1String("emoticons"), QStandardPaths::LocateDirectory); - for (const QString &d : dataDirs) { - QString fileName = d + "/" + name; + const auto& dataDirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, + QLatin1String("emoticons"), + QStandardPaths::LocateDirectory); + for (const QString& d : dataDirs) { + QString fileName = d + "/" + name; QFileInfo fi(fileName); if (fi.exists()) { return fileName; @@ -126,37 +127,33 @@ class PsiIconset::Private { return QString(); } - void stripFirstAnimFrame(Iconset &is) - { - QListIterator it = is.iterator(); + void stripFirstAnimFrame(Iconset& is) { + QListIterator it = is.iterator(); while (it.hasNext()) { it.next()->stripFirstAnimFrame(); } } - void loadIconset(Iconset *to, Iconset *from) - { + void loadIconset(Iconset* to, Iconset* from) { if (!to) { qWarning("PsiIconset::loadIconset(): 'to' iconset is NULL!"); - if (from) - qWarning("from->name() = '%s'", qPrintable(from->name())); + if (from) qWarning("from->name() = '%s'", qPrintable(from->name())); return; } if (!from) { qWarning("PsiIconset::loadIconset(): 'from' iconset is NULL!"); - if (to) - qWarning("to->name() = '%s'", qPrintable(to->name())); + if (to) qWarning("to->name() = '%s'", qPrintable(to->name())); return; } - QListIterator it = from->iterator(); + QListIterator it = from->iterator(); while (it.hasNext()) { - PsiIcon *icon = it.next(); + PsiIcon* icon = it.next(); if (icon && !icon->name().isEmpty()) { - PsiIcon *toIcon = const_cast(to->icon(icon->name())); + PsiIcon* toIcon = const_cast(to->icon(icon->name())); if (toIcon) { - bool b = toIcon->blockSignals(true); + bool b = toIcon->blockSignals(true); *toIcon = *icon; toIcon->blockSignals(b); } else @@ -167,18 +164,18 @@ class PsiIconset::Private { to->setInformation(*from); } - PsiIcon *jid2icon(const Jid &jid, const QString &iconName) - { + PsiIcon* jid2icon(const Jid& jid, const QString& iconName) { // first level -- global default icon - PsiIcon *icon = const_cast(IconsetFactory::iconPtr(iconName)); + PsiIcon* icon = const_cast(IconsetFactory::iconPtr(iconName)); // second level -- transport icon if (jid.node().isEmpty() || status_icons.useServicesIcons) { - for (const StatusIconsets::IconsetItem &item : qAsConst(status_icons.list)) { - if (item.regexp.isEmpty() ? jid.node().isEmpty() : (item.regexp.indexIn(jid.domain()) != -1)) { - const Iconset *is = psi->roster.value(item.iconset); + for (const StatusIconsets::IconsetItem& item : qAsConst(status_icons.list)) { + if (item.regexp.isEmpty() ? jid.node().isEmpty() + : (item.regexp.indexIn(jid.domain()) != -1)) { + const Iconset* is = psi->roster.value(item.iconset); if (is) { - PsiIcon *i = const_cast(is->icon(iconName)); + PsiIcon* i = const_cast(is->icon(iconName)); if (i) { icon = i; break; @@ -189,11 +186,11 @@ class PsiIconset::Private { } // third level -- custom icons - for (const StatusIconsets::IconsetItem &item : qAsConst(status_icons.customList)) { + for (const StatusIconsets::IconsetItem& item : qAsConst(status_icons.customList)) { if (item.regexp.indexIn(jid.bare()) != -1) { - const Iconset *is = psi->roster.value(item.iconset); + const Iconset* is = psi->roster.value(item.iconset); if (is) { - PsiIcon *i = const_cast(is->icon(iconName)); + PsiIcon* i = const_cast(is->icon(iconName)); if (i) { icon = i; break; @@ -205,83 +202,88 @@ class PsiIconset::Private { return icon; } - Iconset systemIconset(bool *ok) - { + Iconset systemIconset(bool* ok) { Iconset def; *ok = def.load(":/iconsets/system/default"); -// if (PsiOptions::instance()->getOption("options.iconsets.system").toString() != "default") { -// Iconset is; -// is.load(iconsetPath("system/" + PsiOptions::instance()->getOption("options.iconsets.system").toString())); -// -// loadIconset(&def, &is); -// } + // if (PsiOptions::instance()->getOption("options.iconsets.system").toString() != + // "default") { + // Iconset is; + // is.load(iconsetPath("system/" + + // PsiOptions::instance()->getOption("options.iconsets.system").toString())); + // + // loadIconset(&def, &is); + // } stripFirstAnimFrame(def); return def; } - Iconset *defaultRosterIconset(bool *ok) - { - Iconset *def = new Iconset; - *ok = def->load(":/iconsets/roster/default"); + Iconset* defaultRosterIconset(bool* ok) { + Iconset* def = new Iconset; + *ok = def->load(":/iconsets/roster/default"); -// if (PsiOptions::instance()->getOption("options.iconsets.status").toString() != "default") { -// Iconset is; -// is.load(iconsetPath("roster/" + PsiOptions::instance()->getOption("options.iconsets.status").toString())); -// -// loadIconset(def, &is); -// } + // if (PsiOptions::instance()->getOption("options.iconsets.status").toString() != + // "default") { + // Iconset is; + // is.load(iconsetPath("roster/" + + // PsiOptions::instance()->getOption("options.iconsets.status").toString())); + // + // loadIconset(def, &is); + // } stripFirstAnimFrame(*def); return def; } - Iconset moodsIconset(bool *ok) - { + Iconset moodsIconset(bool* ok) { Iconset def; *ok = def.load(iconsetPath("moods/default")); -// if (PsiOptions::instance()->getOption("options.iconsets.moods").toString() != "default") { -// Iconset is; -// is.load(iconsetPath("moods/" + PsiOptions::instance()->getOption("options.iconsets.moods").toString())); -// -// loadIconset(&def, &is); -// } + // if (PsiOptions::instance()->getOption("options.iconsets.moods").toString() != + // "default") { + // Iconset is; + // is.load(iconsetPath("moods/" + + // PsiOptions::instance()->getOption("options.iconsets.moods").toString())); + // + // loadIconset(&def, &is); + // } stripFirstAnimFrame(def); return def; } - Iconset activityIconset(bool *ok) - { + Iconset activityIconset(bool* ok) { Iconset def; *ok = def.load(iconsetPath("activities/default")); -// if (PsiOptions::instance()->getOption("options.iconsets.activities").toString() != "default") { -// Iconset is; -// is.load(iconsetPath("activities/" -// + PsiOptions::instance()->getOption("options.iconsets.activities").toString())); -// -// loadIconset(&def, &is); -// } + // if (PsiOptions::instance()->getOption("options.iconsets.activities").toString() != + // "default") { + // Iconset is; + // is.load(iconsetPath("activities/" + // + + // PsiOptions::instance()->getOption("options.iconsets.activities").toString())); + // + // loadIconset(&def, &is); + // } stripFirstAnimFrame(def); return def; } - Iconset clientsIconset(bool *ok) - { + Iconset clientsIconset(bool* ok) { Iconset def; *ok = def.load(iconsetPath("clients/default")); if (PsiOptions::instance()->getOption("options.iconsets.clients").toString() != "default") { Iconset is; - is.load(iconsetPath("clients/" + PsiOptions::instance()->getOption("options.iconsets.clients").toString())); + is.load(iconsetPath( + "clients/" + + PsiOptions::instance()->getOption("options.iconsets.clients").toString())); loadIconset(&def, &is); } @@ -291,15 +293,16 @@ class PsiIconset::Private { return def; } - Iconset affiliationsIconset(bool *ok) - { + Iconset affiliationsIconset(bool* ok) { Iconset def; *ok = def.load(iconsetPath("affiliations/default")); - if (PsiOptions::instance()->getOption("options.iconsets.affiliations").toString() != "default") { + if (PsiOptions::instance()->getOption("options.iconsets.affiliations").toString() != + "default") { Iconset is; - is.load(iconsetPath("affiliations/" - + PsiOptions::instance()->getOption("options.iconsets.affiliations").toString())); + is.load(iconsetPath( + "affiliations/" + + PsiOptions::instance()->getOption("options.iconsets.affiliations").toString())); loadIconset(&def, &is); } @@ -309,13 +312,13 @@ class PsiIconset::Private { return def; } - QList emoticons() - { - QList emo; + QList emoticons() { + QList emo; - const auto names = PsiOptions::instance()->getOption("options.iconsets.emoticons").toStringList(); - for (const QString &name : names) { - Iconset *is = new Iconset; + const auto names = + PsiOptions::instance()->getOption("options.iconsets.emoticons").toStringList(); + for (const QString& name : names) { + Iconset* is = new Iconset; if (is->load(iconsetPath("emoticons/" + name))) { // PsiIconset::removeAnimation(is); is->addToFactory(); @@ -324,7 +327,8 @@ class PsiIconset::Private { } delete is; is = new Iconset; - if (is->load(iconsetPath(name, Iconset::Format::KdeEmoticons), Iconset::Format::KdeEmoticons)) { + if (is->load(iconsetPath(name, Iconset::Format::KdeEmoticons), + Iconset::Format::KdeEmoticons)) { is->addToFactory(); emo.append(is); } else @@ -335,27 +339,28 @@ class PsiIconset::Private { } }; -PsiIconset::PsiIconset() : QObject(QCoreApplication::instance()) -{ +PsiIconset::PsiIconset() : QObject(QCoreApplication::instance()) { d = new Private(this); - d->status_icons.useServicesIcons - = PsiOptions::instance()->getOption("options.ui.contactlist.use-transport-icons").toBool(); - connect(PsiOptions::instance(), SIGNAL(optionChanged(const QString &)), SLOT(optionChanged(const QString &))); + d->status_icons.useServicesIcons = + PsiOptions::instance() + ->getOption("options.ui.contactlist.use-transport-icons") + .toBool(); + connect(PsiOptions::instance(), + SIGNAL(optionChanged(const QString&)), + SLOT(optionChanged(const QString&))); connect(PsiOptions::instance(), SIGNAL(destroyed()), SLOT(reset())); } PsiIconset::~PsiIconset() { delete d; } -void PsiIconset::reset() -{ +void PsiIconset::reset() { delete instance_; instance_ = nullptr; IconsetFactory::reset(); } -bool PsiIconset::loadSystem() -{ - bool ok = true; +bool PsiIconset::loadSystem() { + bool ok = true; QString cur_system = PsiOptions::instance()->getOption("options.iconsets.system").toString(); if (d->cur_system != cur_system) { Iconset sys = d->systemIconset(&ok); @@ -375,15 +380,14 @@ bool PsiIconset::loadSystem() return ok; } -bool PsiIconset::loadRoster() -{ +bool PsiIconset::loadRoster() { // load roster qDeleteAll(roster); roster.clear(); // default roster iconset - bool ok; - Iconset *def = d->defaultRosterIconset(&ok); + bool ok; + Iconset* def = d->defaultRosterIconset(&ok); def->addToFactory(); roster.insert(PsiOptions::instance()->getOption("options.iconsets.status").toString(), def); @@ -393,33 +397,34 @@ bool PsiIconset::loadRoster() QSet rosterIconsets; d->cur_service_status.clear(); - const auto &services = PsiOptions::instance()->mapKeyList("options.iconsets.service-status"); - for (const QVariant &service : services) { + const auto& services = PsiOptions::instance()->mapKeyList("options.iconsets.service-status"); + for (const QVariant& service : services) { QString val = PsiOptions::instance() - ->getOption(PsiOptions::instance()->mapLookup("options.iconsets.service-status", service) - + ".iconset") - .toString(); - if (val.isEmpty()) - continue; + ->getOption(PsiOptions::instance()->mapLookup( + "options.iconsets.service-status", service) + + ".iconset") + .toString(); + if (val.isEmpty()) continue; rosterIconsets << val; d->cur_service_status.insert(service.toString(), val); } - QStringList customicons = PsiOptions::instance()->getChildOptionNames("options.iconsets.custom-status", true, true); + QStringList customicons = PsiOptions::instance()->getChildOptionNames( + "options.iconsets.custom-status", true, true); d->cur_custom_status.clear(); - for (const QString &base : customicons) { - QString regexp = PsiOptions::instance()->getOption(base + ".regexp").toString(); + for (const QString& base : customicons) { + QString regexp = PsiOptions::instance()->getOption(base + ".regexp").toString(); QString iconset = PsiOptions::instance()->getOption(base + ".iconset").toString(); rosterIconsets << iconset; d->cur_custom_status.insert(regexp, iconset); } - for (const QString &it2 : qAsConst(rosterIconsets)) { + for (const QString& it2 : qAsConst(rosterIconsets)) { if (it2 == PsiOptions::instance()->getOption("options.iconsets.status").toString()) { continue; } - Iconset *is = new Iconset; + Iconset* is = new Iconset; if (is->load(d->iconsetPath("roster/" + it2))) { is->addToFactory(); d->stripFirstAnimFrame(*is); @@ -432,9 +437,9 @@ bool PsiIconset::loadRoster() return ok; } -void PsiIconset::loadEmoticons() -{ - QStringList cur_emoticons = PsiOptions::instance()->getOption("options.iconsets.emoticons").toStringList(); +void PsiIconset::loadEmoticons() { + QStringList cur_emoticons = + PsiOptions::instance()->getOption("options.iconsets.emoticons").toStringList(); if (d->cur_emoticons != cur_emoticons) { qDeleteAll(emoticons); emoticons.clear(); @@ -442,13 +447,12 @@ void PsiIconset::loadEmoticons() d->cur_emoticons = cur_emoticons; emit emoticonsChanged(); - } else if (cur_emoticons.isEmpty()) // enable emoji font emoticons + } else if (cur_emoticons.isEmpty()) // enable emoji font emoticons emit emoticonsChanged(); } -bool PsiIconset::loadMoods() -{ - bool ok = true; +bool PsiIconset::loadMoods() { + bool ok = true; QString cur_moods = PsiOptions::instance()->getOption("options.iconsets.moods").toString(); if (d->cur_moods != cur_moods) { Iconset moods = d->moodsIconset(&ok); @@ -461,10 +465,10 @@ bool PsiIconset::loadMoods() return ok; } -bool PsiIconset::loadActivity() -{ - bool ok = true; - QString cur_activity = PsiOptions::instance()->getOption("options.iconsets.activities").toString(); +bool PsiIconset::loadActivity() { + bool ok = true; + QString cur_activity = + PsiOptions::instance()->getOption("options.iconsets.activities").toString(); if (d->cur_activity != cur_activity) { Iconset activities = d->activityIconset(&ok); d->loadIconset(&d->activities, &activities); @@ -476,9 +480,8 @@ bool PsiIconset::loadActivity() return ok; } -bool PsiIconset::loadClients() -{ - bool ok = true; +bool PsiIconset::loadClients() { + bool ok = true; QString cur_clients = PsiOptions::instance()->getOption("options.iconsets.clients").toString(); if (d->cur_clients != cur_clients) { Iconset clients = d->clientsIconset(&ok); @@ -486,38 +489,37 @@ bool PsiIconset::loadClients() d->clients.addToFactory(); QSet iconNames; - auto it = clients.iterator(); + auto it = clients.iterator(); while (it.hasNext()) { iconNames.insert(it.next()->name().section('/', 1, 1)); } - ClientIconMap cm; // start part, spec[spec2[spec3]] + ClientIconMap cm; // start part, spec[spec2[spec3]] - auto readClientsDesc = [&](const QString &filePath) { + auto readClientsDesc = [&](const QString& filePath) { QFile capsConv(filePath); /* file format: , next line the same. */ - if (!capsConv.open(QIODevice::ReadOnly)) - return false; + if (!capsConv.open(QIODevice::ReadOnly)) return false; QTextStream stream(&capsConv); QString line; while (!(line = stream.readLine()).isNull()) { - line = line.trimmed(); + line = line.trimmed(); QString iconName = line.section(QLatin1Char(' '), 0, 0); if (iconName.isEmpty() || !iconNames.contains(iconName)) { continue; } - ClientIconCheck ic = { iconName, QStringList() }; - QString caps = line.mid(iconName.length()); + ClientIconCheck ic = {iconName, QStringList()}; + QString caps = line.mid(iconName.length()); #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) - const auto &cList = caps.split(QLatin1Char(','), Qt::SkipEmptyParts); + const auto& cList = caps.split(QLatin1Char(','), Qt::SkipEmptyParts); #else - const auto &cList = caps.split(QLatin1Char(','), QString::SkipEmptyParts); + const auto& cList = caps.split(QLatin1Char(','), QString::SkipEmptyParts); #endif - for (const QString &c : cList) { + for (const QString& c : cList) { QString ct = c.trimmed(); if (ct.length()) { QStringList spec = ct.split('#'); @@ -537,9 +539,10 @@ bool PsiIconset::loadClients() } // do some sorting to keep elements with a lot of # first - for (auto &checkList : cm) { - std::sort(checkList.begin(), checkList.end(), - [](const auto &a, const auto &b) { return a.inside.size() > b.inside.size(); }); + for (auto& checkList : cm) { + std::sort(checkList.begin(), checkList.end(), [](const auto& a, const auto& b) { + return a.inside.size() > b.inside.size(); + }); } /* insert end boundry element to make search implementation simple */ @@ -547,12 +550,12 @@ bool PsiIconset::loadClients() return true; }; - auto customPath = PsiOptions::instance()->getOption("options.iconsets.clients-capsfile").toString(); + auto customPath = + PsiOptions::instance()->getOption("options.iconsets.clients-capsfile").toString(); if (customPath.isEmpty() || !readClientsDesc(customPath)) { QStringList dirs = ApplicationInfo::dataDirs(); - for (const auto &dataDir : dirs) - if (readClientsDesc(dataDir + QLatin1String("/client_icons.txt"))) - break; + for (const auto& dataDir : dirs) + if (readClientsDesc(dataDir + QLatin1String("/client_icons.txt"))) break; } if (cm.isEmpty()) { @@ -565,10 +568,10 @@ bool PsiIconset::loadClients() return ok; } -bool PsiIconset::loadAffiliations() -{ - bool ok = true; - QString cur_affiliations = PsiOptions::instance()->getOption("options.iconsets.affiliations").toString(); +bool PsiIconset::loadAffiliations() { + bool ok = true; + QString cur_affiliations = + PsiOptions::instance()->getOption("options.iconsets.affiliations").toString(); if (d->cur_affiliations != cur_affiliations) { Iconset affiliations = d->affiliationsIconset(&ok); d->loadIconset(&d->affiliations, &affiliations); @@ -580,15 +583,14 @@ bool PsiIconset::loadAffiliations() return ok; } -void PsiIconset::loadStatusIconDefinitions() -{ +void PsiIconset::loadStatusIconDefinitions() { d->status_icons.list.clear(); d->status_icons.customList.clear(); - const auto &servicesV = PsiOptions::instance()->mapKeyList("options.iconsets.service-status"); - for (const QVariant &serviceV : servicesV) { - QString service = serviceV.toString(); + const auto& servicesV = PsiOptions::instance()->mapKeyList("options.iconsets.service-status"); + for (const QVariant& serviceV : servicesV) { + QString service = serviceV.toString(); PsiIconset::Private::StatusIconsets::IconsetItem item; - bool find = true; + bool find = true; if (service == "disk") item.regexp = QRegExp("^disk"); else if (service == "gadugadu") @@ -620,24 +622,29 @@ void PsiIconset::loadStatusIconDefinitions() if (find) { item.iconset = PsiOptions::instance() - ->getOption(PsiOptions::instance()->mapLookup("options.iconsets.service-status", service) - + ".iconset") - .toString(); + ->getOption(PsiOptions::instance()->mapLookup( + "options.iconsets.service-status", service) + + ".iconset") + .toString(); d->status_icons.list.append(item); } } // default transport icon set - if (PsiOptions::instance()->mapKeyList("options.iconsets.service-status").contains("transport")) { + if (PsiOptions::instance() + ->mapKeyList("options.iconsets.service-status") + .contains("transport")) { PsiIconset::Private::StatusIconsets::IconsetItem item; item.iconset = PsiOptions::instance() - ->getOption(PsiOptions::instance()->mapLookup("options.iconsets.service-status", "transport") - + ".iconset") - .toString(); + ->getOption(PsiOptions::instance()->mapLookup( + "options.iconsets.service-status", "transport") + + ".iconset") + .toString(); d->status_icons.list.append(item); } // custom icon sets - foreach (const QString &base, - PsiOptions::instance()->getChildOptionNames("options.iconsets.custom-status", true, true)) { + foreach (const QString& base, + PsiOptions::instance()->getChildOptionNames( + "options.iconsets.custom-status", true, true)) { PsiIconset::Private::StatusIconsets::IconsetItem item; item.regexp = QRegExp(PsiOptions::instance()->getOption(base + ".regexp").toString()); if (item.regexp.isValid()) { @@ -647,10 +654,8 @@ void PsiIconset::loadStatusIconDefinitions() } } -bool PsiIconset::loadAll() -{ - if (!loadSystem() || !loadRoster()) - return false; +bool PsiIconset::loadAll() { + if (!loadSystem() || !loadRoster()) return false; loadEmoticons(); loadMoods(); @@ -661,8 +666,7 @@ bool PsiIconset::loadAll() return true; } -void PsiIconset::optionChanged(const QString &option) -{ +void PsiIconset::optionChanged(const QString& option) { if (option == "options.iconsets.system") { loadSystem(); } else if (option == "options.iconsets.emoticons") { @@ -676,8 +680,10 @@ void PsiIconset::optionChanged(const QString &option) } else if (option == "options.iconsets.affiliations") { loadAffiliations(); } else if (option == "options.ui.contactlist.use-transport-icons") { - d->status_icons.useServicesIcons - = PsiOptions::instance()->getOption("options.ui.contactlist.use-transport-icons").toBool(); + d->status_icons.useServicesIcons = + PsiOptions::instance() + ->getOption("options.ui.contactlist.use-transport-icons") + .toBool(); } // currently we rely on PsiCon calling reloadRoster() when @@ -692,14 +698,13 @@ void PsiIconset::optionChanged(const QString &option) // } } -void PsiIconset::reloadRoster() -{ - bool ok; +void PsiIconset::reloadRoster() { + bool ok; QString cur_status = PsiOptions::instance()->getOption("options.iconsets.status").toString(); // default roster iconset if (d->cur_status != cur_status) { - Iconset *newDef = d->defaultRosterIconset(&ok); - Iconset *oldDef = roster[d->cur_status]; + Iconset* newDef = d->defaultRosterIconset(&ok); + Iconset* oldDef = roster[d->cur_status]; if (oldDef->iconSize() != newDef->iconSize()) emit rosterIconsSizeChanged(newDef->iconSize()); @@ -716,47 +721,47 @@ void PsiIconset::reloadRoster() QMap cur_service_status; QMap cur_custom_status; - const auto &services = PsiOptions::instance()->mapKeyList("options.iconsets.service-status"); - for (const QVariant &service : services) { + const auto& services = PsiOptions::instance()->mapKeyList("options.iconsets.service-status"); + for (const QVariant& service : services) { QString val = PsiOptions::instance() - ->getOption(PsiOptions::instance()->mapLookup("options.iconsets.service-status", service) - + ".iconset") - .toString(); - if (val.isEmpty()) - continue; + ->getOption(PsiOptions::instance()->mapLookup( + "options.iconsets.service-status", service) + + ".iconset") + .toString(); + if (val.isEmpty()) continue; cur_service_status.insert(service.toString(), val); } - QStringList customicons = PsiOptions::instance()->getChildOptionNames("options.iconsets.custom-status", true, true); - for (const QString &base : customicons) { - QString regexp = PsiOptions::instance()->getOption(base + ".regexp").toString(); + QStringList customicons = PsiOptions::instance()->getChildOptionNames( + "options.iconsets.custom-status", true, true); + for (const QString& base : customicons) { + QString regexp = PsiOptions::instance()->getOption(base + ".regexp").toString(); QString iconset = PsiOptions::instance()->getOption(base + ".iconset").toString(); cur_custom_status.insert(regexp, iconset); } // service&custom roster iconsets - if (operator!=(d->cur_service_status, cur_service_status) || operator!=(d->cur_custom_status, cur_custom_status)) { + if (operator!=(d->cur_service_status, cur_service_status) || operator!=(d->cur_custom_status, + cur_custom_status)) { QStringList rosterIconsets; QMap::Iterator it = cur_service_status.begin(); for (; it != cur_service_status.end(); ++it) - if (!rosterIconsets.contains(it.value())) - rosterIconsets << it.value(); + if (!rosterIconsets.contains(it.value())) rosterIconsets << it.value(); it = cur_custom_status.begin(); for (; it != cur_custom_status.end(); ++it) - if (!rosterIconsets.contains(it.value())) - rosterIconsets << it.value(); + if (!rosterIconsets.contains(it.value())) rosterIconsets << it.value(); QStringList::Iterator it2 = rosterIconsets.begin(); for (; it2 != rosterIconsets.end(); ++it2) { if (*it2 == PsiOptions::instance()->getOption("options.iconsets.status").toString()) continue; - Iconset *is = new Iconset; + Iconset* is = new Iconset; if (is->load(d->iconsetPath("roster/" + *it2))) { d->stripFirstAnimFrame(*is); - Iconset *oldis = roster[*it2]; + Iconset* oldis = roster[*it2]; if (oldis) d->loadIconset(oldis, is); @@ -772,7 +777,7 @@ void PsiIconset::reloadRoster() while (!clear) { clear = true; - QMutableHashIterator it3(roster); + QMutableHashIterator it3(roster); while (it3.hasNext()) { it3.next(); QString name = it3.key(); @@ -790,16 +795,15 @@ void PsiIconset::reloadRoster() } d->cur_service_status = cur_service_status; - d->cur_custom_status = cur_custom_status; + d->cur_custom_status = cur_custom_status; } } -PsiIcon *PsiIconset::event2icon(const PsiEvent::Ptr &e) -{ +PsiIcon* PsiIconset::event2icon(const PsiEvent::Ptr& e) { QString icon; if (e->type() == PsiEvent::Message) { MessageEvent::Ptr me = e.staticCast(); - const Message & m = me->message(); + const Message& m = me->message(); if (m.type() == "headline") icon = "psi/headline"; else if (m.type() == "chat" || m.type() == "groupchat") @@ -819,131 +823,124 @@ PsiIcon *PsiIconset::event2icon(const PsiEvent::Ptr &e) return d->jid2icon(e->from(), icon); } -QString status2name(int s) -{ +QString status2name(int s) { QString name; switch (s) { - case STATUS_OFFLINE: - name = "status/offline"; - break; - case STATUS_AWAY: - name = "status/away"; - break; - case STATUS_XA: - name = "status/xa"; - break; - case STATUS_DND: - name = "status/dnd"; - break; - case STATUS_INVISIBLE: - name = "status/invisible"; - break; - case STATUS_CHAT: - name = "status/chat"; - break; - - case STATUS_ASK: - name = "status/ask"; - break; - case STATUS_NOAUTH: - name = "status/noauth"; - break; - case STATUS_ERROR: - name = "status/error"; - break; - - case -1: - name = "psi/connect"; - break; - - case STATUS_ONLINE: - default: - name = "status/online"; + case STATUS_OFFLINE: + name = "status/offline"; + break; + case STATUS_AWAY: + name = "status/away"; + break; + case STATUS_XA: + name = "status/xa"; + break; + case STATUS_DND: + name = "status/dnd"; + break; + case STATUS_INVISIBLE: + name = "status/invisible"; + break; + case STATUS_CHAT: + name = "status/chat"; + break; + + case STATUS_ASK: + name = "status/ask"; + break; + case STATUS_NOAUTH: + name = "status/noauth"; + break; + case STATUS_ERROR: + name = "status/error"; + break; + + case -1: + name = "psi/connect"; + break; + + case STATUS_ONLINE: + default: + name = "status/online"; } return name; } -PsiIcon *PsiIconset::statusPtr(int s) { return const_cast(IconsetFactory::iconPtr(status2name(s))); } +PsiIcon* PsiIconset::statusPtr(int s) { + return const_cast(IconsetFactory::iconPtr(status2name(s))); +} -PsiIcon PsiIconset::status(int s) -{ - PsiIcon *icon = statusPtr(s); - if (icon) - return *icon; +PsiIcon PsiIconset::status(int s) { + PsiIcon* icon = statusPtr(s); + if (icon) return *icon; return PsiIcon(); } -PsiIcon *PsiIconset::statusPtr(const XMPP::Status &s) { return statusPtr(makeSTATUS(s)); } +PsiIcon* PsiIconset::statusPtr(const XMPP::Status& s) { return statusPtr(makeSTATUS(s)); } -PsiIcon PsiIconset::status(const XMPP::Status &s) { return status(makeSTATUS(s)); } +PsiIcon PsiIconset::status(const XMPP::Status& s) { return status(makeSTATUS(s)); } -PsiIcon *PsiIconset::transportStatusPtr(QString name, int s) -{ - PsiIcon *icon = nullptr; +PsiIcon* PsiIconset::transportStatusPtr(QString name, int s) { + PsiIcon* icon = nullptr; - QVariantList serviceicons = PsiOptions::instance()->mapKeyList("options.iconsets.service-status"); + QVariantList serviceicons = + PsiOptions::instance()->mapKeyList("options.iconsets.service-status"); if (serviceicons.contains(name)) { - const Iconset *is = roster.value( - PsiOptions::instance() - ->getOption(PsiOptions::instance()->mapLookup("options.iconsets.service-status", name) + ".iconset") - .toString()); + const Iconset* is = + roster.value(PsiOptions::instance() + ->getOption(PsiOptions::instance()->mapLookup( + "options.iconsets.service-status", name) + + ".iconset") + .toString()); if (is) { - icon = const_cast(is->icon(status2name(s))); + icon = const_cast(is->icon(status2name(s))); } } - if (!icon) - icon = statusPtr(s); + if (!icon) icon = statusPtr(s); return icon; } -PsiIcon *PsiIconset::transportStatusPtr(QString name, const XMPP::Status &s) -{ +PsiIcon* PsiIconset::transportStatusPtr(QString name, const XMPP::Status& s) { return transportStatusPtr(name, makeSTATUS(s)); } -PsiIcon PsiIconset::transportStatus(QString name, int s) -{ - PsiIcon *icon = transportStatusPtr(name, s); - if (icon) - return *icon; +PsiIcon PsiIconset::transportStatus(QString name, int s) { + PsiIcon* icon = transportStatusPtr(name, s); + if (icon) return *icon; return PsiIcon(); } -PsiIcon PsiIconset::transportStatus(QString name, const XMPP::Status &s) -{ - PsiIcon *icon = transportStatusPtr(name, s); - if (icon) - return *icon; +PsiIcon PsiIconset::transportStatus(QString name, const XMPP::Status& s) { + PsiIcon* icon = transportStatusPtr(name, s); + if (icon) return *icon; return PsiIcon(); } -PsiIcon *PsiIconset::statusPtr(const XMPP::Jid &jid, int s) { return d->jid2icon(jid, status2name(s)); } +PsiIcon* PsiIconset::statusPtr(const XMPP::Jid& jid, int s) { + return d->jid2icon(jid, status2name(s)); +} -PsiIcon *PsiIconset::statusPtr(const XMPP::Jid &jid, const XMPP::Status &s) { return statusPtr(jid, makeSTATUS(s)); } +PsiIcon* PsiIconset::statusPtr(const XMPP::Jid& jid, const XMPP::Status& s) { + return statusPtr(jid, makeSTATUS(s)); +} -PsiIcon PsiIconset::status(const XMPP::Jid &jid, int s) -{ - PsiIcon *icon = statusPtr(jid, s); - if (icon) - return *icon; +PsiIcon PsiIconset::status(const XMPP::Jid& jid, int s) { + PsiIcon* icon = statusPtr(jid, s); + if (icon) return *icon; return PsiIcon(); } -PsiIcon PsiIconset::status(const XMPP::Jid &jid, const XMPP::Status &s) -{ - PsiIcon *icon = statusPtr(jid, s); - if (icon) - return *icon; +PsiIcon PsiIconset::status(const XMPP::Jid& jid, const XMPP::Status& s) { + PsiIcon* icon = statusPtr(jid, s); + if (icon) return *icon; return PsiIcon(); } -PsiIcon *PsiIconset::statusPtr(UserListItem *u) -{ - if (!u) - return nullptr; +PsiIcon* PsiIconset::statusPtr(UserListItem* u) { + if (!u) return nullptr; int s = 0; if (!u->presenceError().isEmpty()) @@ -955,8 +952,9 @@ PsiIcon *PsiIconset::statusPtr(UserListItem *u) s = STATUS_OFFLINE; } else if (u->ask() == "subscribe" && !u->isAvailable() && !u->isTransport()) s = STATUS_ASK; - else if ((u->subscription().type() == Subscription::From || u->subscription().type() == Subscription::None) - && !u->isAvailable() && !u->isPrivate()) + else if ((u->subscription().type() == Subscription::From || + u->subscription().type() == Subscription::None) && + !u->isAvailable() && !u->isPrivate()) s = STATUS_NOAUTH; else if (!u->isAvailable()) s = STATUS_OFFLINE; @@ -966,50 +964,43 @@ PsiIcon *PsiIconset::statusPtr(UserListItem *u) return statusPtr(u->jid(), s); } -PsiIcon PsiIconset::status(UserListItem *u) -{ - PsiIcon *icon = statusPtr(u); - if (icon) - return *icon; +PsiIcon PsiIconset::status(UserListItem* u) { + PsiIcon* icon = statusPtr(u); + if (icon) return *icon; return PsiIcon(); } -const Iconset &PsiIconset::system() const { return d->system; } +const Iconset& PsiIconset::system() const { return d->system; } -void PsiIconset::stripFirstAnimFrame(Iconset *is) -{ - if (is) - d->stripFirstAnimFrame(*is); +void PsiIconset::stripFirstAnimFrame(Iconset* is) { + if (is) d->stripFirstAnimFrame(*is); } -void PsiIconset::removeAnimation(Iconset *is) -{ +void PsiIconset::removeAnimation(Iconset* is) { if (is) { - QListIterator it = is->iterator(); + QListIterator it = is->iterator(); while (it.hasNext()) { it.next()->removeAnim(false); } } } -QString PsiIconset::caps2client(const QString &name) -{ +QString PsiIconset::caps2client(const QString& name) { if (d->client2icon.isEmpty()) { return QString(); } auto it = d->client2icon.lowerBound(name); // if name starts with found key or with key of previous item - if ((it != d->client2icon.end() && name.startsWith(it.key())) - || (it != d->client2icon.begin() && name.startsWith((--it).key()))) { - - const auto &ics = it.value(); - for (const ClientIconCheck &ic : ics) { + if ((it != d->client2icon.end() && name.startsWith(it.key())) || + (it != d->client2icon.begin() && name.startsWith((--it).key()))) { + const auto& ics = it.value(); + for (const ClientIconCheck& ic : ics) { if (ic.inside.isEmpty()) { return ic.icon; } bool matched = true; - for (const QString &s : ic.inside) { + for (const QString& s : ic.inside) { if (name.indexOf(s, it.key().size()) == -1) { matched = false; break; @@ -1023,11 +1014,9 @@ QString PsiIconset::caps2client(const QString &name) return QString(); } -PsiIconset *PsiIconset::instance() -{ - if (!instance_) - instance_ = new PsiIconset(); +PsiIconset* PsiIconset::instance() { + if (!instance_) instance_ = new PsiIconset(); return instance_; } -PsiIconset *PsiIconset::instance_ = nullptr; +PsiIconset* PsiIconset::instance_ = nullptr; diff --git a/src/lib/plugin/ok_iconset.h b/src/lib/plugin/ok_iconset.h index 167b438f..01ff4ebe 100644 --- a/src/lib/plugin/ok_iconset.h +++ b/src/lib/plugin/ok_iconset.h @@ -15,7 +15,6 @@ #include "iconset.h" - #include class UserListItem; @@ -23,53 +22,53 @@ class UserListItem; namespace XMPP { class Jid; class Status; -} +} // namespace XMPP class PsiIconset : public QObject { Q_OBJECT public: - static PsiIconset *instance(); + static PsiIconset* instance(); bool loadSystem(); void reloadRoster(); bool loadAll(); - QHash roster; - QList emoticons; - Iconset moods; - Iconset activities; - Iconset clients; - Iconset affiliations; - const Iconset & system() const; - void stripFirstAnimFrame(Iconset *); - static void removeAnimation(Iconset *); + QHash roster; + QList emoticons; + Iconset moods; + Iconset activities; + Iconset clients; + Iconset affiliations; + const Iconset& system() const; + void stripFirstAnimFrame(Iconset*); + static void removeAnimation(Iconset*); // these two can possibly fail (and return 0) - PsiIcon *statusPtr(int); - PsiIcon *statusPtr(const XMPP::Status &); + PsiIcon* statusPtr(int); + PsiIcon* statusPtr(const XMPP::Status&); // these two return empty PsiIcon on failure and are safe PsiIcon status(int); - PsiIcon status(const XMPP::Status &); + PsiIcon status(const XMPP::Status&); // JID-enabled status functions - PsiIcon *statusPtr(const XMPP::Jid &, int); - PsiIcon *statusPtr(const XMPP::Jid &, const XMPP::Status &); + PsiIcon* statusPtr(const XMPP::Jid&, int); + PsiIcon* statusPtr(const XMPP::Jid&, const XMPP::Status&); - PsiIcon status(const XMPP::Jid &, int); - PsiIcon status(const XMPP::Jid &, const XMPP::Status &); + PsiIcon status(const XMPP::Jid&, int); + PsiIcon status(const XMPP::Jid&, const XMPP::Status&); // functions to get status icon by transport name - PsiIcon *transportStatusPtr(QString name, int); - PsiIcon *transportStatusPtr(QString name, const XMPP::Status &); + PsiIcon* transportStatusPtr(QString name, int); + PsiIcon* transportStatusPtr(QString name, const XMPP::Status&); PsiIcon transportStatus(QString name, int); - PsiIcon transportStatus(QString name, const XMPP::Status &); + PsiIcon transportStatus(QString name, const XMPP::Status&); - PsiIcon *statusPtr(UserListItem *); - PsiIcon status(UserListItem *); + PsiIcon* statusPtr(UserListItem*); + PsiIcon status(UserListItem*); - QString caps2client(const QString &name); + QString caps2client(const QString& name); signals: void emoticonsChanged(); void systemIconsSizeChanged(int); @@ -79,16 +78,16 @@ public slots: static void reset(); private slots: - void optionChanged(const QString &option); + void optionChanged(const QString& option); private: PsiIconset(); ~PsiIconset(); class Private; - Private *d; + Private* d; - static PsiIconset *instance_; + static PsiIconset* instance_; bool loadRoster(); void loadEmoticons(); @@ -101,4 +100,4 @@ private slots: QString status2name(int s); -#endif // PSIICONSET_H +#endif // PSIICONSET_H diff --git a/src/lib/plugin/optionstree.cpp b/src/lib/plugin/optionstree.cpp index 38dd4af2..30dc4150 100644 --- a/src/lib/plugin/optionstree.cpp +++ b/src/lib/plugin/optionstree.cpp @@ -12,7 +12,6 @@ #include "optionstree.h" - #include #include #include @@ -20,20 +19,19 @@ /** * Default constructor */ -OptionsTree::OptionsTree(QObject *parent) : QObject(parent) { } +OptionsTree::OptionsTree(QObject* parent) : QObject(parent) {} /** * Destructor */ -OptionsTree::~OptionsTree() { } +OptionsTree::~OptionsTree() {} /** * Returns the value of the specified option * \param name 'Path' to the option ("appearance.emoticons.useSmilies") * \return value of the option. Will be invalid if non-existent. */ -QVariant OptionsTree::getOption(const QString &name, const QVariant &defaultValue) const -{ +QVariant OptionsTree::getOption(const QString& name, const QVariant& defaultValue) const { QVariant value = tree_.getValue(name); if (value == VariantTree::missingValue) { value = defaultValue; @@ -54,9 +52,8 @@ QVariant OptionsTree::getOption(const QString &name, const QVariant &defaultValu * \param name "Path" to the option * \param value Value of the option */ -void OptionsTree::setOption(const QString &name, const QVariant &value) -{ - const QVariant &prev = tree_.getValue(name); +void OptionsTree::setOption(const QString& name, const QVariant& value) { + const QVariant& prev = tree_.getValue(name); if (prev == value) { return; } @@ -73,23 +70,24 @@ void OptionsTree::setOption(const QString &name, const QVariant &value) /** * @brief returns true if the node @a node is an internal node. */ -bool OptionsTree::isInternalNode(const QString &node) const { return tree_.isInternalNode(node); } +bool OptionsTree::isInternalNode(const QString& node) const { return tree_.isInternalNode(node); } /** * \brief Sets the comment of the named option. * \param name "Path" to the option * \param comment the comment to store */ -void OptionsTree::setComment(const QString &name, const QString &comment) { tree_.setComment(name, comment); } +void OptionsTree::setComment(const QString& name, const QString& comment) { + tree_.setComment(name, comment); +} /** * \brief Returns the comment of the specified option. * \param name "Path" to the option */ -QString OptionsTree::getComment(const QString &name) const { return tree_.getComment(name); } +QString OptionsTree::getComment(const QString& name) const { return tree_.getComment(name); } -bool OptionsTree::removeOption(const QString &name, bool internal_nodes) -{ +bool OptionsTree::removeOption(const QString& name, bool internal_nodes) { emit optionAboutToBeRemoved(name); bool ok = tree_.remove(name, internal_nodes); emit optionRemoved(name); @@ -108,41 +106,38 @@ QStringList OptionsTree::allOptionNames() const { return tree_.nodeChildren(); } * \param internal_nodes include internal (non-final) nodes * \return Full names of options */ -QStringList OptionsTree::getChildOptionNames(const QString &parent, bool direct, bool internal_nodes) const -{ +QStringList OptionsTree::getChildOptionNames(const QString& parent, bool direct, + bool internal_nodes) const { return tree_.nodeChildren(parent, direct, internal_nodes); } -bool OptionsTree::isValidName(const QString &name) -{ - const auto &parts = name.split('.'); - for (const QString &part : parts) { - if (!VariantTree::isValidNodeName(part)) - return false; +bool OptionsTree::isValidName(const QString& name) { + const auto& parts = name.split('.'); + for (const QString& part : parts) { + if (!VariantTree::isValidNodeName(part)) return false; } return true; } -QString OptionsTree::mapLookup(const QString &basename, const QVariant &key) const -{ +QString OptionsTree::mapLookup(const QString& basename, const QVariant& key) const { QStringList children = getChildOptionNames(basename, true, true); - for (const QString &path : children) { + for (const QString& path : children) { if (getOption(path + ".key") == key) { return path; } } - qWarning("Accessing missing key '%s' in option map '%s'", qPrintable(key.toString()), qPrintable(basename)); + qWarning("Accessing missing key '%s' in option map '%s'", qPrintable(key.toString()), + qPrintable(basename)); return basename + "XXX"; } -QVariant OptionsTree::mapGet(const QString &basename, const QVariant &key, const QString &node) const -{ +QVariant OptionsTree::mapGet(const QString& basename, const QVariant& key, + const QString& node) const { return getOption(mapLookup(basename, key) + '.' + node); } -QVariant OptionsTree::mapGet(const QString &basename, const QVariant &key, const QString &node, - const QVariant &def) const -{ +QVariant OptionsTree::mapGet(const QString& basename, const QVariant& key, const QString& node, + const QVariant& def) const { QVariantList keys = mapKeyList(basename); if (keys.contains(key)) { return getOption(mapLookup(basename, key) + '.' + node); @@ -151,10 +146,9 @@ QVariant OptionsTree::mapGet(const QString &basename, const QVariant &key, const } } -QString OptionsTree::mapPut(const QString &basename, const QVariant &key) -{ +QString OptionsTree::mapPut(const QString& basename, const QVariant& key) { QStringList children = getChildOptionNames(basename, true, true); - for (const QString &path : children) { + for (const QString& path : children) { if (getOption(path + ".key") == key) { return path; } @@ -163,7 +157,7 @@ QString OptionsTree::mapPut(const QString &basename, const QVariant &key) // allocate first unused index QString path; - int i = 0; + int i = 0; do { path = basename + ".m" + QString::number(i); ++i; @@ -172,18 +166,17 @@ QString OptionsTree::mapPut(const QString &basename, const QVariant &key) return path; } -void OptionsTree::mapPut(const QString &basename, const QVariant &key, const QString &node, const QVariant &value) -{ +void OptionsTree::mapPut(const QString& basename, const QVariant& key, const QString& node, + const QVariant& value) { setOption(mapPut(basename, key) + '.' + node, value); } -bool mapKeyListLessThanByNumber(const QString &s1, const QString &s2) -{ +bool mapKeyListLessThanByNumber(const QString& s1, const QString& s2) { int dotpos = s1.lastIndexOf('.'); if (s1.leftRef(dotpos + 1).compare(s2.leftRef(dotpos + 1)) == 0) { QString name1 = s1.mid(dotpos + 1), name2 = s2.mid(dotpos + 1); if (name1[0] == 'm' && name2[0] == 'm') { - bool ok1 = false, ok2 = false; + bool ok1 = false, ok2 = false; unsigned int n1 = name1.midRef(1).toUInt(&ok1), n2 = name2.midRef(1).toUInt(&ok2); if (ok1 && ok2) { return n1 < n2; @@ -194,14 +187,13 @@ bool mapKeyListLessThanByNumber(const QString &s1, const QString &s2) return s1 < s2; } -QVariantList OptionsTree::mapKeyList(const QString &basename, bool sortedByNumbers) const -{ +QVariantList OptionsTree::mapKeyList(const QString& basename, bool sortedByNumbers) const { QVariantList ret; - QStringList children = getChildOptionNames(basename, true, true); + QStringList children = getChildOptionNames(basename, true, true); if (sortedByNumbers) { std::sort(children.begin(), children.end(), mapKeyListLessThanByNumber); } - for (const QString &path : children) { + for (const QString& path : children) { ret << getOption(path + ".key"); } return ret; @@ -215,27 +207,27 @@ QVariantList OptionsTree::mapKeyList(const QString &basename, bool sortedByNumbe * \param configNS Namespace of the config format * \return 'true' if the file saves, 'false' if it fails */ -bool OptionsTree::saveOptions(const QString &fileName, const QString &configName, const QString &configNS, - const QString &configVersion, bool streamWriter) const -{ -// AtomicXmlFile f(fileName); -// if (streamWriter) { -// OptionsTreeWriter writer(this); -// writer.setName(configName); -// writer.setNameSpace(configNS); -// writer.setVersion(configVersion); -// return f.saveDocument(&writer); -// } -// QDomDocument doc(configName); -// -// QDomElement base = doc.createElement(configName); -// base.setAttribute("version", configVersion); -// if (!configNS.isEmpty()) -// base.setAttribute("xmlns", configNS); -// doc.appendChild(base); -// -// tree_.toXml(doc, base); -// return f.saveDocument(doc); +bool OptionsTree::saveOptions(const QString& fileName, const QString& configName, + const QString& configNS, const QString& configVersion, + bool streamWriter) const { + // AtomicXmlFile f(fileName); + // if (streamWriter) { + // OptionsTreeWriter writer(this); + // writer.setName(configName); + // writer.setNameSpace(configNS); + // writer.setVersion(configVersion); + // return f.saveDocument(&writer); + // } + // QDomDocument doc(configName); + // + // QDomElement base = doc.createElement(configName); + // base.setAttribute("version", configVersion); + // if (!configNS.isEmpty()) + // base.setAttribute("xmlns", configNS); + // doc.appendChild(base); + // + // tree_.toXml(doc, base); + // return f.saveDocument(doc); return false; } @@ -247,20 +239,20 @@ bool OptionsTree::saveOptions(const QString &fileName, const QString &configName * \param configNS Namespace of the config format * \return 'true' if the file loads, 'false' if it fails */ -bool OptionsTree::loadOptions(const QString &fileName, const QString &configName, const QString &configNS, - const QString &configVersion, bool streamReader) -{ -// AtomicXmlFile f(fileName); -// if (streamReader) { -// OptionsTreeReader reader(this); -// return f.loadDocument(&reader); -// } -// -// QDomDocument doc; -// if (!f.loadDocument(&doc)) -// return false; +bool OptionsTree::loadOptions(const QString& fileName, const QString& configName, + const QString& configNS, const QString& configVersion, + bool streamReader) { + // AtomicXmlFile f(fileName); + // if (streamReader) { + // OptionsTreeReader reader(this); + // return f.loadDocument(&reader); + // } + // + // QDomDocument doc; + // if (!f.loadDocument(&doc)) + // return false; -// return loadOptions(doc.documentElement(), configName, configVersion, configNS); + // return loadOptions(doc.documentElement(), configName, configVersion, configNS); return false; } @@ -270,7 +262,7 @@ bool OptionsTree::loadOptions(const QString &fileName, const QString &configName */ bool OptionsTree::exists(QString fileName) { return false; -// return AtomicXmlFile::exists(fileName); + // return AtomicXmlFile::exists(fileName); } /** @@ -280,9 +272,8 @@ bool OptionsTree::exists(QString fileName) { * \param configNS Namespace of the config format * \param configVersion If specified, the function will fail if the file version doesn't match */ -bool OptionsTree::loadOptions(const QDomElement &base, const QString &configName, const QString &configNS, - const QString &configVersion) -{ +bool OptionsTree::loadOptions(const QDomElement& base, const QString& configName, + const QString& configNS, const QString& configVersion) { Q_UNUSED(configName); Q_UNUSED(configNS); Q_UNUSED(configVersion); diff --git a/src/lib/plugin/optionstree.h b/src/lib/plugin/optionstree.h index e810a627..7589d62f 100644 --- a/src/lib/plugin/optionstree.h +++ b/src/lib/plugin/optionstree.h @@ -24,51 +24,54 @@ class OptionsTree : public QObject { Q_OBJECT public: - OptionsTree(QObject *parent = nullptr); + OptionsTree(QObject* parent = nullptr); ~OptionsTree(); - QVariant getOption(const QString &name, const QVariant &defaultValue = QVariant::Invalid) const; - inline QVariant getOption(const char *name, const QVariant &defaultValue = QVariant::Invalid) const - { + QVariant getOption(const QString& name, const QVariant& defaultValue = QVariant::Invalid) const; + inline QVariant getOption(const char* name, + const QVariant& defaultValue = QVariant::Invalid) const { return getOption(QString(QString::fromLatin1(name)), defaultValue); } - // Warning: when inserting Map/Hash be very careful with keys. They are going to become xml element names. - // full set of supported types can be found in VariantTree::variantToElement() - void setOption(const QString &name, const QVariant &value); - bool isInternalNode(const QString &node) const; - void setComment(const QString &name, const QString &comment); - QString getComment(const QString &name) const; + // Warning: when inserting Map/Hash be very careful with keys. They are going to become xml + // element names. full set of supported types can be found in VariantTree::variantToElement() + void setOption(const QString& name, const QVariant& value); + bool isInternalNode(const QString& node) const; + void setComment(const QString& name, const QString& comment); + QString getComment(const QString& name) const; QStringList allOptionNames() const; - QStringList getChildOptionNames(const QString & = QString(""), bool direct = false, + QStringList getChildOptionNames(const QString& = QString(""), bool direct = false, bool internal_nodes = false) const; - bool removeOption(const QString &name, bool internal_nodes = false); + bool removeOption(const QString& name, bool internal_nodes = false); - static bool isValidName(const QString &name); + static bool isValidName(const QString& name); // Map helpers - QString mapLookup(const QString &basename, const QVariant &key) const; - QString mapPut(const QString &basename, const QVariant &key); - void mapPut(const QString &basename, const QVariant &key, const QString &node, const QVariant &value); - QVariant mapGet(const QString &basename, const QVariant &key, const QString &node) const; - QVariant mapGet(const QString &basename, const QVariant &key, const QString &node, const QVariant &def) const; - QVariantList mapKeyList(const QString &basename, bool sortedByNumbers = false) const; + QString mapLookup(const QString& basename, const QVariant& key) const; + QString mapPut(const QString& basename, const QVariant& key); + void mapPut(const QString& basename, const QVariant& key, const QString& node, + const QVariant& value); + QVariant mapGet(const QString& basename, const QVariant& key, const QString& node) const; + QVariant mapGet(const QString& basename, const QVariant& key, const QString& node, + const QVariant& def) const; + QVariantList mapKeyList(const QString& basename, bool sortedByNumbers = false) const; - bool saveOptions(const QString &fileName, const QString &configName, const QString &configNS, - const QString &configVersion, bool streamWriter = false) const; - bool loadOptions(const QString &fileName, const QString &configName, const QString &configNS = "", - const QString &configVersion = "", bool streamReader = false); - bool loadOptions(const QDomElement &name, const QString &configName, const QString &configNS = "", - const QString &configVersion = ""); + bool saveOptions(const QString& fileName, const QString& configName, const QString& configNS, + const QString& configVersion, bool streamWriter = false) const; + bool loadOptions(const QString& fileName, const QString& configName, + const QString& configNS = "", const QString& configVersion = "", + bool streamReader = false); + bool loadOptions(const QDomElement& name, const QString& configName, + const QString& configNS = "", const QString& configVersion = ""); static bool exists(QString fileName); signals: - void optionChanged(const QString &option); - void optionAboutToBeInserted(const QString &option); - void optionInserted(const QString &option); - void optionAboutToBeRemoved(const QString &option); - void optionRemoved(const QString &option); + void optionChanged(const QString& option); + void optionAboutToBeInserted(const QString& option); + void optionInserted(const QString& option); + void optionAboutToBeRemoved(const QString& option); + void optionRemoved(const QString& option); private: VariantTree tree_; @@ -76,4 +79,4 @@ class OptionsTree : public QObject { friend class OptionsTreeWriter; }; -#endif // OPTIONSTREE_H +#endif // OPTIONSTREE_H diff --git a/src/lib/plugin/pluginhost.cpp b/src/lib/plugin/pluginhost.cpp index 1c4f0bd4..49f1d620 100644 --- a/src/lib/plugin/pluginhost.cpp +++ b/src/lib/plugin/pluginhost.cpp @@ -79,12 +79,18 @@ namespace plugin { * \param manager PluginManager instance that manages all plugins * \param pluginFile path to plugin file */ -PluginHost::PluginHost(PluginManager *manager, const QString &pluginFile) - : manager_(manager), plugin_(nullptr), file_(pluginFile), - priority_(OkPlugin::PriorityNormal), loader_(nullptr), valid_(false), - connected_(false), enabled_(false), hasInfo_(false), - infoString_(QString()) { - updateMetadata(); +PluginHost::PluginHost(PluginManager* manager, const QString& pluginFile) + : manager_(manager) + , plugin_(nullptr) + , file_(pluginFile) + , priority_(OkPlugin::PriorityNormal) + , loader_(nullptr) + , valid_(false) + , connected_(false) + , enabled_(false) + , hasInfo_(false) + , infoString_(QString()) { + updateMetadata(); } /** @@ -93,8 +99,8 @@ PluginHost::PluginHost(PluginManager *manager, const QString &pluginFile) * Plugin is disabled and unloaded if needed. */ PluginHost::~PluginHost() { - disable(); - unload(); + disable(); + unload(); } /** @@ -107,35 +113,35 @@ bool PluginHost::isValid() const { return valid_; } /** * \brief Returns full path to plugin file. */ -const QString &PluginHost::path() const { return file_; } +const QString& PluginHost::path() const { return file_; } /** * \brief Returns plugin short name. * * Data is available also when plugin is not loaded. */ -const QString &PluginHost::shortName() const { return shortName_; } +const QString& PluginHost::shortName() const { return shortName_; } /** * \brief Returns plugin version string. * * Data is available also when plugin is not loaded. */ -const QString &PluginHost::version() const { return version_; } +const QString& PluginHost::version() const { return version_; } /** * \brief Returns plugin vendor string. * * Data is available also when plugin is not loaded. */ -const QString &PluginHost::vendor() const { return vendor_; } +const QString& PluginHost::vendor() const { return vendor_; } /** * \brief Returns plugin description string. * * Data is available also when plugin is not loaded. */ -const QString &PluginHost::description() const { return description_; } +const QString& PluginHost::description() const { return description_; } /** * \brief Returns plugin priority. @@ -149,13 +155,13 @@ int PluginHost::priority() const { return priority_; } * * Data is available also when plugin is not loaded. */ -const QIcon &PluginHost::icon() const { return icon_; } +const QIcon& PluginHost::icon() const { return icon_; } QStringList PluginHost::pluginFeatures() const { - if (plugin_) { - return qobject_cast(plugin_)->pluginFeatures(); - } - return QStringList(); + if (plugin_) { + return qobject_cast(plugin_)->pluginFeatures(); + } + return QStringList(); } /** @@ -163,69 +169,64 @@ QStringList PluginHost::pluginFeatures() const { * * Always returns null if plugin is not currently loaded. */ -QWidget *PluginHost::optionsWidget() const { - QWidget *widget = nullptr; - if (plugin_) { - widget = qobject_cast(plugin_)->options(); - } - return widget; +QWidget* PluginHost::optionsWidget() const { + QWidget* widget = nullptr; + if (plugin_) { + widget = qobject_cast(plugin_)->options(); + } + return widget; } //-- loading and enabling ------------------------------------------- void PluginHost::updateMetadata() { - if (plugin_) { - return; - } - qDebug() << "Plugin file:" << file_; - QPluginLoader loader(file_); - if (!loader.load()) { - qWarning() << "Can not load the plugin:" << file_ << loader.errorString(); - return; - } - auto md = loader.metaData(); - if (!md.isEmpty()) - md = md.value("MetaData").toObject(); - - // TODO: TranslationManager::instance()->currentLanguage(); - QString curLangFull = ":zh_CN"; - QString curLang = curLangFull.section('_', 0, 0); - - name_ = md.value(QLatin1String("name:") + curLangFull).toString(); - if (name_.isEmpty()) - name_ = md.value(QLatin1String("name:") + curLang).toString(); - if (name_.isEmpty()) - name_ = md.value(QLatin1String("name")).toString(); - - shortName_ = md.value(QLatin1String("shortname")).toString(); - vendor_ = md.value(QLatin1String("vendor")).toString(); - version_ = md.value(QLatin1String("version")).toString(); - priority_ = md.value(QLatin1String("priority")).toInt(2); - - description_ = - md.value(QLatin1String("description") + curLangFull).toString(); - if (description_.isEmpty()) - description_ = md.value(QLatin1String("description") + curLang).toString(); - if (description_.isEmpty()) - description_ = md.value(QLatin1String("description")).toString(); - // description_ = TextUtil::plain2rich(description_); - - QString data = md.value(QLatin1String("icon")).toString(); - if (data.startsWith("base64:")) { - rawIcon_ = QByteArray::fromBase64(data.midRef(6).toLatin1()); - QPixmap pix; - pix.loadFromData(rawIcon_); - icon_ = QIcon(pix); - } else if (data.startsWith("iconset:")) { - // icon_ = IconsetFactory::icon(data.mid(8)).icon(); - } else - icon_ = QIcon(data); // assuming file name or resource - - qDebug("Loaded plugin name is:%s shortName is:%s", // - qPrintable(name_), qPrintable(shortName_)); - - qDebug("Loaded metadata for plugin %s", qPrintable(file_)); - valid_ = true; - loader.unload(); + if (plugin_) { + return; + } + qDebug() << "Plugin file:" << file_; + QPluginLoader loader(file_); + if (!loader.load()) { + qWarning() << "Can not load the plugin:" << file_ << loader.errorString(); + return; + } + auto md = loader.metaData(); + if (!md.isEmpty()) md = md.value("MetaData").toObject(); + + // TODO: TranslationManager::instance()->currentLanguage(); + QString curLangFull = ":zh_CN"; + QString curLang = curLangFull.section('_', 0, 0); + + name_ = md.value(QLatin1String("name:") + curLangFull).toString(); + if (name_.isEmpty()) name_ = md.value(QLatin1String("name:") + curLang).toString(); + if (name_.isEmpty()) name_ = md.value(QLatin1String("name")).toString(); + + shortName_ = md.value(QLatin1String("shortname")).toString(); + vendor_ = md.value(QLatin1String("vendor")).toString(); + version_ = md.value(QLatin1String("version")).toString(); + priority_ = md.value(QLatin1String("priority")).toInt(2); + + description_ = md.value(QLatin1String("description") + curLangFull).toString(); + if (description_.isEmpty()) + description_ = md.value(QLatin1String("description") + curLang).toString(); + if (description_.isEmpty()) description_ = md.value(QLatin1String("description")).toString(); + // description_ = TextUtil::plain2rich(description_); + + QString data = md.value(QLatin1String("icon")).toString(); + if (data.startsWith("base64:")) { + rawIcon_ = QByteArray::fromBase64(data.midRef(6).toLatin1()); + QPixmap pix; + pix.loadFromData(rawIcon_); + icon_ = QIcon(pix); + } else if (data.startsWith("iconset:")) { + // icon_ = IconsetFactory::icon(data.mid(8)).icon(); + } else + icon_ = QIcon(data); // assuming file name or resource + + qDebug("Loaded plugin name is:%s shortName is:%s", // + qPrintable(name_), qPrintable(shortName_)); + + qDebug("Loaded metadata for plugin %s", qPrintable(file_)); + valid_ = true; + loader.unload(); } /** @@ -241,59 +242,56 @@ void PluginHost::updateMetadata() { * before. */ bool PluginHost::load() { - qDebug() << "Loading plugin" << file_; - if (plugin_) { - qWarning() << QString("Plugin %1 was already loaded.").arg(file_); - return true; - } - - loader_ = new QPluginLoader(file_, this); - loader_->setLoadHints(QLibrary::ResolveAllSymbolsHint); - bool loaded = loader_->load(); - qDebug() << "The plugin is loaded?=>" << loaded; - if (!loaded) { - delete loader_; - loader_.clear(); - qWarning() << "Can not to load plugin:" << name(); - return false; - } + qDebug() << "Loading plugin" << file_; + if (plugin_) { + qWarning() << QString("Plugin %1 was already loaded.").arg(file_); + return true; + } + loader_ = new QPluginLoader(file_, this); + loader_->setLoadHints(QLibrary::ResolveAllSymbolsHint); + bool loaded = loader_->load(); + qDebug() << "The plugin is loaded?=>" << loaded; + if (!loaded) { + delete loader_; + loader_.clear(); + qWarning() << "Can not to load plugin:" << name(); + return false; + } - QObject *plugin = loader_->instance(); - qDebug() << "Plugin address is:" << plugin; - OkPlugin *pPlugin = qobject_cast(plugin); - if (!pPlugin) { - qWarning("File is a plugin but a valid OkPlugin"); - unload(); - return false; - } + QObject* plugin = loader_->instance(); + qDebug() << "Plugin address is:" << plugin; + OkPlugin* pPlugin = qobject_cast(plugin); + if (!pPlugin) { + qWarning("File is a plugin but a valid OkPlugin"); + unload(); + return false; + } - plugin_ = plugin; - valid_ = true; - name_ = pPlugin->name(); - qDebug() << "Loaded the plugin sortName is" << shortName_; + plugin_ = plugin; + valid_ = true; + name_ = pPlugin->name(); + qDebug() << "Loaded the plugin sortName is" << shortName_; - // shortName_ = psiPlugin->shortName(); - // version_ = psiPlugin->version(); - // priority_ = psiPlugin->priority(); - // icon_ = QIcon(psiPlugin->icon()); + // shortName_ = psiPlugin->shortName(); + // version_ = psiPlugin->version(); + // priority_ = psiPlugin->priority(); + // icon_ = QIcon(psiPlugin->icon()); - plugin->setProperty("metadata", selfMetadata()); + plugin->setProperty("metadata", selfMetadata()); - hasToolBarButton_ = - qobject_cast(plugin_) ? true : false; - hasGCToolBarButton_ = - qobject_cast(plugin_) ? true : false; + hasToolBarButton_ = qobject_cast(plugin_) ? true : false; + hasGCToolBarButton_ = qobject_cast(plugin_) ? true : false; - PluginInfoProvider *pip = qobject_cast(plugin_); - if (pip) { - hasInfo_ = true; - infoString_ = pip->pluginInfo(); - qDebug() << "The plugin Info is:" << infoString_; - } + PluginInfoProvider* pip = qobject_cast(plugin_); + if (pip) { + hasInfo_ = true; + infoString_ = pip->pluginInfo(); + qDebug() << "The plugin Info is:" << infoString_; + } - qDebug("Plugin loaded: %s", qPrintable(name_)); - return plugin_ != nullptr; + qDebug("Plugin loaded: %s", qPrintable(name_)); + return plugin_ != nullptr; } /** @@ -309,40 +307,39 @@ bool PluginHost::load() { * all. */ bool PluginHost::unload() { - qDebug() << "Unloading plugin" << shortName(); - if (!plugin_) { - qWarning() << QString("Plugin %1 was already unloaded.").arg(shortName()); - return true; - } - - qDebug() << "Plugin address is:" << plugin_.data(); - disable(); + qDebug() << "Unloading plugin" << shortName(); + if (!plugin_) { + qWarning() << QString("Plugin %1 was already unloaded.").arg(shortName()); + return true; + } - if(!loader_){ - qWarning() << "The plugin was unloaded."; - return false; - } + qDebug() << "Plugin address is:" << plugin_.data(); + disable(); - if (loader_->isLoaded()) { - bool unloaded = loader_->unload(); - qDebug() << "Unload plugin" << name_ << "?=>" << unloaded; - loader_->deleteLater(); - } + if (!loader_) { + qWarning() << "The plugin was unloaded."; + return false; + } + if (loader_->isLoaded()) { + bool unloaded = loader_->unload(); + qDebug() << "Unload plugin" << name_ << "?=>" << unloaded; + loader_->deleteLater(); + } - // loader will delete it automatically - delete plugin_; - plugin_.clear(); + // loader will delete it automatically + delete plugin_; + plugin_.clear(); - // delete iconset_; - // iconset_ = nullptr; - delete loader_; - loader_.clear(); + // delete iconset_; + // iconset_ = nullptr; + delete loader_; + loader_.clear(); - connected_ = false; + connected_ = false; - qDebug() << "Plugin unloaded:" << name_; - return plugin_ == nullptr; + qDebug() << "Plugin unloaded:" << name_; + return plugin_ == nullptr; } /** @@ -366,132 +363,130 @@ bool PluginHost::isLoaded() const { return plugin_ != nullptr; } * before. */ bool PluginHost::enable() { - qDebug() << "To enabling plugin" << file_; - - QMutexLocker locker(&mutex_); - - if (!enabled_ && load()) { - if (!connected_) { - qDebug() << "connecting plugin " << name_; - - StanzaSender *s = qobject_cast(plugin_); - if (s) { - qDebug("connecting stanza sender"); - s->setStanzaSendingHost(this); - } - - IqFilter *f = qobject_cast(plugin_); - if (f) { - qDebug("connecting iq filter"); - f->setIqFilteringHost(this); - } - - OptionAccessor *o = qobject_cast(plugin_); - if (o) { - qDebug("connecting option accessor"); - o->setOptionAccessingHost(this); - } - - ShortcutAccessor *sa = qobject_cast(plugin_); - if (sa) { - qDebug("connecting shortcut accessor"); - sa->setShortcutAccessingHost(this); - } - PopupAccessor *pa = qobject_cast(plugin_); - if (pa) { - qDebug("connecting popup accessor"); - pa->setPopupAccessingHost(this); - } - - IconFactoryAccessor *ia = qobject_cast(plugin_); - if (ia) { - qDebug("connecting iconfactory accessor"); - ia->setIconFactoryAccessingHost(this); - } - ActiveTabAccessor *ta = qobject_cast(plugin_); - if (ta) { - qDebug("connecting activetab accessor"); - ta->setActiveTabAccessingHost(this); - } - ApplicationInfoAccessor *aia = - qobject_cast(plugin_); - if (aia) { - qDebug("connecting applicationinfo accessor"); - aia->setApplicationInfoAccessingHost(this); - } - AccountInfoAccessor *ai = qobject_cast(plugin_); - if (ai) { - qDebug("connecting accountinfo accessor"); - ai->setAccountInfoAccessingHost(this); - } - ToolbarIconAccessor *tia = qobject_cast(plugin_); - if (tia) { - qDebug("load toolbaricon param"); - buttons_ = tia->getButtonParam(); - } - GCToolbarIconAccessor *gtia = - qobject_cast(plugin_); - if (gtia) { - qDebug("load gctoolbaricon param"); - gcbuttons_ = gtia->getGCButtonParam(); - } - MenuAccessor *ma = qobject_cast(plugin_); - if (ma) { - qDebug("load menu actions param"); - accMenu_ = ma->getAccountMenuParam(); - contactMenu_ = ma->getContactMenuParam(); - } - ContactStateAccessor *csa = qobject_cast(plugin_); - if (csa) { - qDebug("connecting contactstate accessor"); - csa->setContactStateAccessingHost(this); - } - PsiAccountController *pac = qobject_cast(plugin_); - if (pac) { - qDebug("connectint psiaccount controller"); - pac->setPsiAccountControllingHost(this); - } - EventCreator *ecr = qobject_cast(plugin_); - if (ecr) { - qDebug("connectint event creator"); - ecr->setEventCreatingHost(this); - } - ContactInfoAccessor *cia = qobject_cast(plugin_); - if (cia) { - qDebug("connecting contactinfo accessor"); - cia->setContactInfoAccessingHost(this); - } - SoundAccessor *soa = qobject_cast(plugin_); - if (soa) { - qDebug("connecting sound accessor"); - soa->setSoundAccessingHost(this); - } - PluginAccessor *pla = qobject_cast(plugin_); - if (pla) { - qDebug("connecting plugin accessor"); - pla->setPluginAccessingHost(this); - } - auto wka = qobject_cast(plugin_); - if (wka) { - wka->setWebkitAccessingHost(this); - } - auto pma = qobject_cast(plugin_); - if (pma) { - pma->setPsiMediaHost(this); - } - - connected_ = true; - } + qDebug() << "To enabling plugin" << file_; + + QMutexLocker locker(&mutex_); + + if (!enabled_ && load()) { + if (!connected_) { + qDebug() << "connecting plugin " << name_; + + StanzaSender* s = qobject_cast(plugin_); + if (s) { + qDebug("connecting stanza sender"); + s->setStanzaSendingHost(this); + } + + IqFilter* f = qobject_cast(plugin_); + if (f) { + qDebug("connecting iq filter"); + f->setIqFilteringHost(this); + } + + OptionAccessor* o = qobject_cast(plugin_); + if (o) { + qDebug("connecting option accessor"); + o->setOptionAccessingHost(this); + } + + ShortcutAccessor* sa = qobject_cast(plugin_); + if (sa) { + qDebug("connecting shortcut accessor"); + sa->setShortcutAccessingHost(this); + } + PopupAccessor* pa = qobject_cast(plugin_); + if (pa) { + qDebug("connecting popup accessor"); + pa->setPopupAccessingHost(this); + } + + IconFactoryAccessor* ia = qobject_cast(plugin_); + if (ia) { + qDebug("connecting iconfactory accessor"); + ia->setIconFactoryAccessingHost(this); + } + ActiveTabAccessor* ta = qobject_cast(plugin_); + if (ta) { + qDebug("connecting activetab accessor"); + ta->setActiveTabAccessingHost(this); + } + ApplicationInfoAccessor* aia = qobject_cast(plugin_); + if (aia) { + qDebug("connecting applicationinfo accessor"); + aia->setApplicationInfoAccessingHost(this); + } + AccountInfoAccessor* ai = qobject_cast(plugin_); + if (ai) { + qDebug("connecting accountinfo accessor"); + ai->setAccountInfoAccessingHost(this); + } + ToolbarIconAccessor* tia = qobject_cast(plugin_); + if (tia) { + qDebug("load toolbaricon param"); + buttons_ = tia->getButtonParam(); + } + GCToolbarIconAccessor* gtia = qobject_cast(plugin_); + if (gtia) { + qDebug("load gctoolbaricon param"); + gcbuttons_ = gtia->getGCButtonParam(); + } + MenuAccessor* ma = qobject_cast(plugin_); + if (ma) { + qDebug("load menu actions param"); + accMenu_ = ma->getAccountMenuParam(); + contactMenu_ = ma->getContactMenuParam(); + } + ContactStateAccessor* csa = qobject_cast(plugin_); + if (csa) { + qDebug("connecting contactstate accessor"); + csa->setContactStateAccessingHost(this); + } + PsiAccountController* pac = qobject_cast(plugin_); + if (pac) { + qDebug("connectint psiaccount controller"); + pac->setPsiAccountControllingHost(this); + } + EventCreator* ecr = qobject_cast(plugin_); + if (ecr) { + qDebug("connectint event creator"); + ecr->setEventCreatingHost(this); + } + ContactInfoAccessor* cia = qobject_cast(plugin_); + if (cia) { + qDebug("connecting contactinfo accessor"); + cia->setContactInfoAccessingHost(this); + } + SoundAccessor* soa = qobject_cast(plugin_); + if (soa) { + qDebug("connecting sound accessor"); + soa->setSoundAccessingHost(this); + } + PluginAccessor* pla = qobject_cast(plugin_); + if (pla) { + qDebug("connecting plugin accessor"); + pla->setPluginAccessingHost(this); + } + auto wka = qobject_cast(plugin_); + if (wka) { + wka->setWebkitAccessingHost(this); + } + auto pma = qobject_cast(plugin_); + if (pma) { + pma->setPsiMediaHost(this); + } + + connected_ = true; + } - enabled_ = qobject_cast(plugin_)->enable(); - if (enabled_) { - enableHandler = new QObject(this); - emit enabled(); - qDebug() << "Enable plugin" << shortName() << "successfully."; + enabled_ = qobject_cast(plugin_)->enable(); + if (enabled_) { + enableHandler = new QObject(this); + emit enabled(); + qDebug() << "Enable plugin" << shortName() << "successfully."; + } } - } - return enabled_; + return enabled_; } /** @@ -504,22 +499,22 @@ bool PluginHost::enable() { * all. */ bool PluginHost::disable() { - QMutexLocker locker(&mutex_); - qDebug() << "Disable plugin" << shortName(); - if (!enabled_) { - qWarning() << "The plugin" << shortName() << "is disabled already."; - return true; - } - - if (plugin_) { - enabled_ = !qobject_cast(plugin_)->disable(); + QMutexLocker locker(&mutex_); + qDebug() << "Disable plugin" << shortName(); if (!enabled_) { - delete enableHandler; - emit disabled(); - qDebug() << "Disable plugin" << shortName() << "successfully."; + qWarning() << "The plugin" << shortName() << "is disabled already."; + return true; } - } - return true; + + if (plugin_) { + enabled_ = !qobject_cast(plugin_)->disable(); + if (!enabled_) { + delete enableHandler; + emit disabled(); + qDebug() << "Disable plugin" << shortName() << "successfully."; + } + } + return true; } /** @@ -541,76 +536,75 @@ bool PluginHost::isEnabled() const { return enabled_; } * \return Continue processing the XML stanza; true if the stanza should be * silently discarded. */ -bool PluginHost::incomingXml(int account, const QDomElement &e) { - QMutexLocker locker(&mutex_); - if (!plugin_) { - qWarning() << "The plugin has be unloaded."; - return false; - } - bool handled = false; - // try stanza filter first - StanzaFilter *sf = qobject_cast(plugin_); - if (sf && sf->incomingStanza(account, e)) { - handled = true; - } - // try iq filters - else if (e.tagName() == "iq") { - // get iq namespace - QString ns; - for (QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling()) { - QDomElement i = n.toElement(); - if (!i.isNull() && !i.namespaceURI().isNull()) { - ns = i.namespaceURI(); - break; - } +bool PluginHost::incomingXml(int account, const QDomElement& e) { + QMutexLocker locker(&mutex_); + if (!plugin_) { + qWarning() << "The plugin has be unloaded."; + return false; } - - // choose handler function depending on iq type - bool (IqNamespaceFilter::*handler)(int account, const QDomElement &xml) = - nullptr; - const QString type = e.attribute("type"); - if (type == "get") { - handler = &IqNamespaceFilter::iqGet; - } else if (type == "set") { - handler = &IqNamespaceFilter::iqSet; - } else if (type == "result") { - handler = &IqNamespaceFilter::iqResult; - } else if (type == "error") { - handler = &IqNamespaceFilter::iqError; + bool handled = false; + // try stanza filter first + StanzaFilter* sf = qobject_cast(plugin_); + if (sf && sf->incomingStanza(account, e)) { + handled = true; } + // try iq filters + else if (e.tagName() == "iq") { + // get iq namespace + QString ns; + for (QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling()) { + QDomElement i = n.toElement(); + if (!i.isNull() && !i.namespaceURI().isNull()) { + ns = i.namespaceURI(); + break; + } + } - if (handler) { - // normal filters - const auto &items = iqNsFilters_.values(ns); - for (IqNamespaceFilter *f : items) { - if ((f->*handler)(account, e)) { - handled = true; - break; + // choose handler function depending on iq type + bool (IqNamespaceFilter::*handler)(int account, const QDomElement& xml) = nullptr; + const QString type = e.attribute("type"); + if (type == "get") { + handler = &IqNamespaceFilter::iqGet; + } else if (type == "set") { + handler = &IqNamespaceFilter::iqSet; + } else if (type == "result") { + handler = &IqNamespaceFilter::iqResult; + } else if (type == "error") { + handler = &IqNamespaceFilter::iqError; } - } - // regex filters - QMapIterator i(iqNsxFilters_); - while (!handled && i.hasNext()) { - if (i.key().indexIn(ns) >= 0 && (i.value()->*handler)(account, e)) { - handled = true; + if (handler) { + // normal filters + const auto& items = iqNsFilters_.values(ns); + for (IqNamespaceFilter* f : items) { + if ((f->*handler)(account, e)) { + handled = true; + break; + } + } + + // regex filters + QMapIterator i(iqNsxFilters_); + while (!handled && i.hasNext()) { + if (i.key().indexIn(ns) >= 0 && (i.value()->*handler)(account, e)) { + handled = true; + } + } } - } } - } - return handled; + return handled; } -bool PluginHost::outgoingXml(int account, QDomElement &e) { - QMutexLocker locker(&mutex_); +bool PluginHost::outgoingXml(int account, QDomElement& e) { + QMutexLocker locker(&mutex_); - bool handled = false; - StanzaFilter *ef = qobject_cast(plugin_); - if (ef && ef->outgoingStanza(account, e)) { - handled = true; - } - return handled; + bool handled = false; + StanzaFilter* ef = qobject_cast(plugin_); + if (ef && ef->outgoingStanza(account, e)) { + handled = true; + } + return handled; } //-- for EventFilter ------------------------------------------------ @@ -628,13 +622,13 @@ bool PluginHost::outgoingXml(int account, QDomElement &e) { * \return Continue processing the event; true if the stanza should be silently * discarded. */ -bool PluginHost::processEvent(int account, QDomElement &e) { - bool handled = false; - EventFilter *ef = qobject_cast(plugin_); - if (ef && ef->processEvent(account, e)) { - handled = true; - } - return handled; +bool PluginHost::processEvent(int account, QDomElement& e) { + bool handled = false; + EventFilter* ef = qobject_cast(plugin_); + if (ef && ef->processEvent(account, e)) { + handled = true; + } + return handled; } /** @@ -653,32 +647,31 @@ bool PluginHost::processEvent(int account, QDomElement &e) { * \return Continue processing the event; true if the stanza should be silently * discarded. */ -bool PluginHost::processMessage(int account, const QString &jidFrom, - const QString &body, const QString &subject) { - bool handled = false; - EventFilter *ef = qobject_cast(plugin_); - if (ef && ef->processMessage(account, jidFrom, body, subject)) { - handled = true; - } - return handled; -} - -bool PluginHost::processOutgoingMessage(int account, const QString &jidTo, - QString &body, const QString &type, - QString &subject) { - bool handled = false; - EventFilter *ef = qobject_cast(plugin_); - if (ef && ef->processOutgoingMessage(account, jidTo, body, type, subject)) { - handled = true; - } - return handled; +bool PluginHost::processMessage(int account, const QString& jidFrom, const QString& body, + const QString& subject) { + bool handled = false; + EventFilter* ef = qobject_cast(plugin_); + if (ef && ef->processMessage(account, jidFrom, body, subject)) { + handled = true; + } + return handled; +} + +bool PluginHost::processOutgoingMessage(int account, const QString& jidTo, QString& body, + const QString& type, QString& subject) { + bool handled = false; + EventFilter* ef = qobject_cast(plugin_); + if (ef && ef->processOutgoingMessage(account, jidTo, body, type, subject)) { + handled = true; + } + return handled; } void PluginHost::logout(int account) { - EventFilter *ef = qobject_cast(plugin_); - if (ef) { - ef->logout(account); - } + EventFilter* ef = qobject_cast(plugin_); + if (ef) { + ef->logout(account); + } } //-- StanzaSender --------------------------------------------------- @@ -689,11 +682,11 @@ void PluginHost::logout(int account) { * \param account Identifier of the PsiAccount responsible * \param stanza The stanza to be sent */ -void PluginHost::sendStanza(int account, const QDomElement &stanza) { - QTextStream stream; - stream.setString(new QString()); - stanza.save(stream, QDomElement::EncodingFromDocument); - manager_->sendXml(account, *stream.string()); +void PluginHost::sendStanza(int account, const QDomElement& stanza) { + QTextStream stream; + stream.setString(new QString()); + stanza.save(stream, QDomElement::EncodingFromDocument); + manager_->sendXml(account, *stream.string()); } /** @@ -702,8 +695,8 @@ void PluginHost::sendStanza(int account, const QDomElement &stanza) { * \param account Identifier of the PsiAccount responsible * \param stanza The stanza to be sent. */ -void PluginHost::sendStanza(int account, const QString &stanza) { - manager_->sendXml(account, stanza); +void PluginHost::sendStanza(int account, const QString& stanza) { + manager_->sendXml(account, stanza); } /** @@ -716,27 +709,27 @@ void PluginHost::sendStanza(int account, const QString &stanza) { * \param type Message type (XMPP message type) * \param stanza The stanza to be sent. */ -void PluginHost::sendMessage(int account, // - const QString &to, // - const QString &body, // - const QString &subject, // - const QString &type) { - // XMPP::Message m; - // m.setTo(to); - // m.setBody(body); - // m.setSubject(subject); - // if (type =="chat" || type == "error" || type == "groupchat" || type == - // "headline" || type == "normal") { - // m.setType(type); - //} - // manager_->sendXml(account, m.toStanza(...).toString()); - - // TODO(mck): yeah, that's sick.. - // manager_->sendXml(account, - // QString("%3%2") - // .arg(escape(to), escape(body), escape(subject), - // escape(type))); +void PluginHost::sendMessage(int account, // + const QString& to, // + const QString& body, // + const QString& subject, // + const QString& type) { + // XMPP::Message m; + // m.setTo(to); + // m.setBody(body); + // m.setSubject(subject); + // if (type =="chat" || type == "error" || type == "groupchat" || type == + // "headline" || type == "normal") { + // m.setType(type); + //} + // manager_->sendXml(account, m.toStanza(...).toString()); + + // TODO(mck): yeah, that's sick.. + // manager_->sendXml(account, + // QString("%3%2") + // .arg(escape(to), escape(body), escape(subject), + // escape(type))); } /** @@ -745,11 +738,9 @@ void PluginHost::sendMessage(int account, // * \param account Identifier of the PsiAccount responsible * \return Unique stanza id, or empty string if account id is invalid. */ -QString PluginHost::uniqueId(int account) { - return manager_->uniqueId(account); -} +QString PluginHost::uniqueId(int account) { return manager_->uniqueId(account); } -QString PluginHost::escape(const QString &str) { return TextUtil::escape(str); } +QString PluginHost::escape(const QString& str) { return TextUtil::escape(str); } //-- IqFilter ------------------------------------------------------- @@ -770,15 +761,14 @@ QString PluginHost::escape(const QString &str) { return TextUtil::escape(str); } * \param ns Iq namespace * \param filter Filter to be registered */ -void PluginHost::addIqNamespaceFilter(const QString &ns, - IqNamespaceFilter *filter) { - if (iqNsFilters_.values(ns).contains(filter)) { +void PluginHost::addIqNamespaceFilter(const QString& ns, IqNamespaceFilter* filter) { + if (iqNsFilters_.values(ns).contains(filter)) { #ifndef PLUGINS_NO_DEBUG - qDebug("pluginmanager: blocked attempt to register the same filter again"); + qDebug("pluginmanager: blocked attempt to register the same filter again"); #endif - } else { - iqNsFilters_.insert(ns, filter); - } + } else { + iqNsFilters_.insert(ns, filter); + } } /** @@ -798,19 +788,18 @@ void PluginHost::addIqNamespaceFilter(const QString &ns, * \param ns Iq namespace defined by a regular expression * \param filter Filter to be registered */ -void PluginHost::addIqNamespaceFilter(const QRegExp &ns, - IqNamespaceFilter *filter) { - // #ifndef PLUGINS_NO_DEBUG - // qDebug("add nsx"); - // #endif - // if (iqNsxFilters_.values(ns).contains(filter)) { - // #ifndef PLUGINS_NO_DEBUG - // qDebug("pluginmanager: blocked attempt to register the same filter - // again"); - // #endif - // } else { - // iqNsxFilters_.insert(ns, filter); - // } +void PluginHost::addIqNamespaceFilter(const QRegExp& ns, IqNamespaceFilter* filter) { + // #ifndef PLUGINS_NO_DEBUG + // qDebug("add nsx"); + // #endif + // if (iqNsxFilters_.values(ns).contains(filter)) { + // #ifndef PLUGINS_NO_DEBUG + // qDebug("pluginmanager: blocked attempt to register the same filter + // again"); + // #endif + // } else { + // iqNsxFilters_.insert(ns, filter); + // } } /** @@ -819,9 +808,8 @@ void PluginHost::addIqNamespaceFilter(const QRegExp &ns, * Breaks connection made by addIqNamespaceFilter(). * Note that \a filter object is never deleted by this function. */ -void PluginHost::removeIqNamespaceFilter(const QString &ns, - IqNamespaceFilter *filter) { - iqNsFilters_.remove(ns, filter); +void PluginHost::removeIqNamespaceFilter(const QString& ns, IqNamespaceFilter* filter) { + iqNsFilters_.remove(ns, filter); } /** @@ -830,9 +818,8 @@ void PluginHost::removeIqNamespaceFilter(const QString &ns, * Breaks connection made by addIqNamespaceFilter(). * Note that \a filter object is never deleted by this function. */ -void PluginHost::removeIqNamespaceFilter(const QRegExp &ns, - IqNamespaceFilter *filter) { - // iqNsxFilters_.remove(ns, filter); +void PluginHost::removeIqNamespaceFilter(const QRegExp& ns, IqNamespaceFilter* filter) { + // iqNsxFilters_.remove(ns, filter); } //-- OptionAccessor ------------------------------------------------- @@ -847,17 +834,16 @@ void PluginHost::removeIqNamespaceFilter(const QRegExp &ns, * \param option Option to set * \param value New option value */ -void PluginHost::setPluginOption(const QString &option, const QVariant &value) { - // TODO(mck) +void PluginHost::setPluginOption(const QString& option, const QVariant& value) { + // TODO(mck) - // PsiPlugin* plugin=nullptr; - // - // if (!plugin) - // return; - QString optionKey = - QString("%1.%2.%3") - .arg(PluginManager::pluginOptionPrefix, shortName(), option); - OkOptions::instance()->setOption(optionKey, value); + // PsiPlugin* plugin=nullptr; + // + // if (!plugin) + // return; + QString optionKey = + QString("%1.%2.%3").arg(PluginManager::pluginOptionPrefix, shortName(), option); + OkOptions::instance()->setOption(optionKey, value); } /** @@ -870,13 +856,11 @@ void PluginHost::setPluginOption(const QString &option, const QVariant &value) { * \param option Option to set * \param value Return value */ -QVariant PluginHost::getPluginOption(const QString &option, - const QVariant &defValue) { - QString pluginName = name(); - QString optionKey = - QString("%1.%2.%3") - .arg(PluginManager::pluginOptionPrefix, shortName(), option); - return OkOptions::instance()->getOption(optionKey, defValue); +QVariant PluginHost::getPluginOption(const QString& option, const QVariant& defValue) { + QString pluginName = name(); + QString optionKey = + QString("%1.%2.%3").arg(PluginManager::pluginOptionPrefix, shortName(), option); + return OkOptions::instance()->getOption(optionKey, defValue); } /** @@ -887,16 +871,16 @@ QVariant PluginHost::getPluginOption(const QString &option, * \param option Option to set * \param value New option value */ -void PluginHost::setGlobalOption(const QString &option, const QVariant &value) { - OkOptions::instance()->setOption(option, value); +void PluginHost::setGlobalOption(const QString& option, const QVariant& value) { + OkOptions::instance()->setOption(option, value); } -void PluginHost::addSettingPage(OAH_PluginOptionsTab *tab) { - // manager_->addSettingPage(tab); +void PluginHost::addSettingPage(OAH_PluginOptionsTab* tab) { + // manager_->addSettingPage(tab); } -void PluginHost::removeSettingPage(OAH_PluginOptionsTab *tab) { - // manager_->removeSettingPage(tab); +void PluginHost::removeSettingPage(OAH_PluginOptionsTab* tab) { + // manager_->removeSettingPage(tab); } /** @@ -907,119 +891,114 @@ void PluginHost::removeSettingPage(OAH_PluginOptionsTab *tab) { * \param option Option to set * \param value Return value */ -QVariant PluginHost::getGlobalOption(const QString &option) { - return OkOptions::instance()->getOption(option); +QVariant PluginHost::getGlobalOption(const QString& option) { + return OkOptions::instance()->getOption(option); } -void PluginHost::optionChanged(const QString &option) { - OptionAccessor *oa = qobject_cast(plugin_); - if (oa) - oa->optionChanged(option); +void PluginHost::optionChanged(const QString& option) { + OptionAccessor* oa = qobject_cast(plugin_); + if (oa) oa->optionChanged(option); } void PluginHost::applyOptions() { - OkPlugin *pp = qobject_cast(plugin_); - if (pp) - pp->applyOptions(); + OkPlugin* pp = qobject_cast(plugin_); + if (pp) pp->applyOptions(); } void PluginHost::restoreOptions() { - OkPlugin *pp = qobject_cast(plugin_); - if (pp) - pp->restoreOptions(); + OkPlugin* pp = qobject_cast(plugin_); + if (pp) pp->restoreOptions(); } /** * Shortcut accessing host */ void PluginHost::setShortcuts() { - ShortcutAccessor *sa = qobject_cast(plugin_); - if (sa) { - sa->setShortcuts(); - } + ShortcutAccessor* sa = qobject_cast(plugin_); + if (sa) { + sa->setShortcuts(); + } } -void PluginHost::connectShortcut(const QKeySequence &shortcut, - QObject *receiver, const char *slot) { - // GlobalShortcutManager::instance()->connect(shortcut, receiver, slot); +void PluginHost::connectShortcut(const QKeySequence& shortcut, QObject* receiver, + const char* slot) { + // GlobalShortcutManager::instance()->connect(shortcut, receiver, slot); } -void PluginHost::disconnectShortcut(const QKeySequence &shortcut, - QObject *receiver, const char *slot) { - // GlobalShortcutManager::instance()->disconnect(shortcut, receiver, slot); +void PluginHost::disconnectShortcut(const QKeySequence& shortcut, QObject* receiver, + const char* slot) { + // GlobalShortcutManager::instance()->disconnect(shortcut, receiver, slot); } -void PluginHost::requestNewShortcut(QObject *receiver, const char *slot) { - // GrepShortcutKeyDialog *grep = new GrepShortcutKeyDialog(); - // connect(grep, SIGNAL(newShortcutKey(QKeySequence)), receiver, slot); - // grep->show(); +void PluginHost::requestNewShortcut(QObject* receiver, const char* slot) { + // GrepShortcutKeyDialog *grep = new GrepShortcutKeyDialog(); + // connect(grep, SIGNAL(newShortcutKey(QKeySequence)), receiver, slot); + // grep->show(); } /** * IconFactory accessing host */ -QIcon PluginHost::getIcon(const QString &name) { - return IconsetFactory::icon(name).icon(); -} - -void PluginHost::addIcon(const QString &name, const QByteArray &ba) { - QPixmap pm; - pm.loadFromData(ba); - // PsiIcon icon; - // icon.setImpix(pm); - // icon.setName(name); - // if (!iconset_) { - // iconset_ = new Iconset(); - // } - // iconset_->setIcon(name, icon); - // iconset_->addToFactory(); -} - -QTextEdit *PluginHost::getEditBox() { - QTextEdit *ed = nullptr; - // TabbableWidget *tw = findActiveTab(); - // if (tw) { - // QWidget *chatEditProxy = tw->findChild("mle"); - // if (chatEditProxy) { - // ed = static_cast(chatEditProxy->children().at(1)); - // } - // } - - return ed; +QIcon PluginHost::getIcon(const QString& name) { return IconsetFactory::icon(name).icon(); } + +void PluginHost::addIcon(const QString& name, const QByteArray& ba) { + QPixmap pm; + pm.loadFromData(ba); + // PsiIcon icon; + // icon.setImpix(pm); + // icon.setName(name); + // if (!iconset_) { + // iconset_ = new Iconset(); + // } + // iconset_->setIcon(name, icon); + // iconset_->addToFactory(); +} + +QTextEdit* PluginHost::getEditBox() { + QTextEdit* ed = nullptr; + // TabbableWidget *tw = findActiveTab(); + // if (tw) { + // QWidget *chatEditProxy = tw->findChild("mle"); + // if (chatEditProxy) { + // ed = static_cast(chatEditProxy->children().at(1)); + // } + // } + + return ed; } QString PluginHost::getJid() { - QString jid; - // TabbableWidget *tw = findActiveTab(); - // if (tw) { - // jid = tw->jid().full(); - // } + QString jid; + // TabbableWidget *tw = findActiveTab(); + // if (tw) { + // jid = tw->jid().full(); + // } - return jid; + return jid; } QString PluginHost::getYourJid() { - QString jid; - // TabbableWidget *tw = findActiveTab(); - // if (tw) { - // jid = tw->account()->jid().full(); - // } + QString jid; + // TabbableWidget *tw = findActiveTab(); + // if (tw) { + // jid = tw->account()->jid().full(); + // } - return jid; + return jid; } /** * ApplicationInfo accessing host */ -Proxy PluginHost::getProxyFor(const QString &obj) { - Proxy prx; - // ProxyItem it = ProxyManager::instance()->getItemForObject(obj); - // prx.type = it.type; - // prx.host = it.settings.host; - // prx.port = it.settings.port; - // prx.user = it.settings.user; - // prx.pass = it.settings.pass; - return prx; +Proxy PluginHost::getProxyFor(const QString& obj) { + Proxy prx; + // ProxyItem it = ProxyManager::instance()->getItemForObject(obj); + // prx.type = it.type; + // prx.host = it.settings.host; + // prx.port = it.settings.port; + // prx.user = it.settings.user; + // prx.pass = it.settings.pass; + return prx; } QString PluginHost::appName() { return ApplicationInfo::name(); } @@ -1028,69 +1007,54 @@ QString PluginHost::appVersion() { return ApplicationInfo::version(); } QString PluginHost::appCapsNode() { return ApplicationInfo::capsNode(); } -QString -PluginHost::appCapsVersion() { // this stuff is incompatible with new caps 1.5 - return QString(); // return ApplicationInfo::capsVersion(); +QString PluginHost::appCapsVersion() { // this stuff is incompatible with new caps 1.5 + return QString(); // return ApplicationInfo::capsVersion(); } QString PluginHost::appOsName() { return ApplicationInfo::osName(); } -QString PluginHost::appOsVersion() { - return ok::base::SystemInfo::instance()->osVersion(); -} +QString PluginHost::appOsVersion() { return ok::base::SystemInfo::instance()->osVersion(); } QString PluginHost::appHomeDir(ApplicationInfoAccessingHost::HomedirType type) { - return ApplicationInfo::homeDir(ApplicationInfo::HomedirType(type)); + return ApplicationInfo::homeDir(ApplicationInfo::HomedirType(type)); } -QString PluginHost::appResourcesDir() { - return ApplicationInfo::resourcesDir(); -} +QString PluginHost::appResourcesDir() { return ApplicationInfo::resourcesDir(); } QString PluginHost::appLibDir() { return ApplicationInfo::libDir(); } -QString -PluginHost::appProfilesDir(ApplicationInfoAccessingHost::HomedirType type) { - return ApplicationInfo::profilesDir(ApplicationInfo::HomedirType(type)); +QString PluginHost::appProfilesDir(ApplicationInfoAccessingHost::HomedirType type) { + return ApplicationInfo::profilesDir(ApplicationInfo::HomedirType(type)); } QString PluginHost::appHistoryDir() { return ApplicationInfo::historyDir(); } -QString PluginHost::appCurrentProfileDir( - ApplicationInfoAccessingHost::HomedirType type) { - return ApplicationInfo::currentProfileDir(ApplicationInfo::HomedirType(type)); +QString PluginHost::appCurrentProfileDir(ApplicationInfoAccessingHost::HomedirType type) { + return ApplicationInfo::currentProfileDir(ApplicationInfo::HomedirType(type)); } QString PluginHost::appVCardDir() { return ApplicationInfo::vCardDir(); } // AccountInfoAcsessingHost QString PluginHost::getStatus(int account) { - // return manager_->getStatus(account); - return {}; + // return manager_->getStatus(account); + return {}; } QString PluginHost::getStatusMessage(int account) { - // return manager_->getStatusMessage(account); - return {}; + // return manager_->getStatusMessage(account); + return {}; } -QString PluginHost::proxyHost(int account) { - return manager_->proxyHost(account); -} +QString PluginHost::proxyHost(int account) { return manager_->proxyHost(account); } int PluginHost::proxyPort(int account) { return manager_->proxyPort(account); } -QString PluginHost::proxyUser(int account) { - return manager_->proxyUser(account); -} +QString PluginHost::proxyUser(int account) { return manager_->proxyUser(account); } -QString PluginHost::proxyPassword(int account) { - return manager_->proxyPassword(account); -} +QString PluginHost::proxyPassword(int account) { return manager_->proxyPassword(account); } -QStringList PluginHost::getRoster(int account) { - return manager_->getRoster(account); -} +QStringList PluginHost::getRoster(int account) { return manager_->getRoster(account); } QString PluginHost::getJid(int account) { return manager_->getJid(account); } @@ -1098,408 +1062,379 @@ QString PluginHost::getId(int account) { return manager_->getId(account); } QString PluginHost::getName(int account) { return manager_->getName(account); } -int PluginHost::findOnlineAccountForContact(const QString &jid) const { - return manager_->findOnlineAccountForContact(jid); +int PluginHost::findOnlineAccountForContact(const QString& jid) const { + return manager_->findOnlineAccountForContact(jid); } -QString PluginHost::getPgpKey(int account) { - return manager_->getPgpKey(account); -} +QString PluginHost::getPgpKey(int account) { return manager_->getPgpKey(account); } QMap PluginHost::getKnownPgpKeys(int account) { - return manager_->getKnownPgpKeys(account); + return manager_->getKnownPgpKeys(account); } -void PluginHost::subscribeBeforeLogin(QObject *context, - std::function callback) { - connect(manager_, &PluginManager::accountBeforeLogin, context, callback); +void PluginHost::subscribeBeforeLogin(QObject* context, std::function callback) { + connect(manager_, &PluginManager::accountBeforeLogin, context, callback); } -void PluginHost::subscribeLogout(QObject *context, - std::function callback) { - connect(manager_, &PluginManager::accountLoggedOut, context, callback); +void PluginHost::subscribeLogout(QObject* context, std::function callback) { + connect(manager_, &PluginManager::accountLoggedOut, context, callback); } -void PluginHost::setPgpKey(int account, const QString &keyId) { - manager_->setPgpKey(account, keyId); +void PluginHost::setPgpKey(int account, const QString& keyId) { + manager_->setPgpKey(account, keyId); } -void PluginHost::removeKnownPgpKey(int account, const QString &jid) { - manager_->removeKnownPgpKey(account, jid); +void PluginHost::removeKnownPgpKey(int account, const QString& jid) { + manager_->removeKnownPgpKey(account, jid); } -void PluginHost::setClientVersionInfo(int account, const QVariantMap &info) { - manager_->setClientVersionInfo(account, info); +void PluginHost::setClientVersionInfo(int account, const QVariantMap& info) { + manager_->setClientVersionInfo(account, info); } -bool PluginHost::setActivity(int account, const QString &Jid, QDomElement xml) { - return manager_->setActivity(account, Jid, xml); +bool PluginHost::setActivity(int account, const QString& Jid, QDomElement xml) { + return manager_->setActivity(account, Jid, xml); } -bool PluginHost::setMood(int account, const QString &Jid, QDomElement xml) { - return manager_->setMood(account, Jid, xml); +bool PluginHost::setMood(int account, const QString& Jid, QDomElement xml) { + return manager_->setMood(account, Jid, xml); } -bool PluginHost::setTune(int account, const QString &Jid, QString tune) { - return manager_->setTune(account, Jid, tune); +bool PluginHost::setTune(int account, const QString& Jid, QString tune) { + return manager_->setTune(account, Jid, tune); } -void PluginHost::addToolBarButton(QObject *parent, QWidget *toolbar, - int account, const QString &contact) { - ToolbarIconAccessor *ta = qobject_cast(plugin_); - if (ta) { - if (!buttons_.isEmpty()) { - for (int i = 0; i < buttons_.size(); ++i) { - QVariantHash param = buttons_.at(i); - QString th = param.value("tooltip").value(); - // TODO:插件头像 - // IconAction * button = new IconAction(th, - // param.value("icon").value(), th, 0, parent); - // connect(button, SIGNAL(triggered()), - // param.value("reciver").value(), - // param.value("slot").value().toLatin1()); - // connect(enableHandler, &QObject::destroyed, button, - // &QObject::deleteLater); toolbar->addAction(button); - } - } - QAction *act = ta->getAction(parent, account, contact); - if (act) { - act->setObjectName(shortName_); - connect(enableHandler, &QObject::destroyed, act, &QObject::deleteLater); - toolbar->addAction(act); +void PluginHost::addToolBarButton(QObject* parent, QWidget* toolbar, int account, + const QString& contact) { + ToolbarIconAccessor* ta = qobject_cast(plugin_); + if (ta) { + if (!buttons_.isEmpty()) { + for (int i = 0; i < buttons_.size(); ++i) { + QVariantHash param = buttons_.at(i); + QString th = param.value("tooltip").value(); + // TODO:插件头像 + // IconAction * button = new IconAction(th, + // param.value("icon").value(), th, 0, parent); + // connect(button, SIGNAL(triggered()), + // param.value("reciver").value(), + // param.value("slot").value().toLatin1()); + // connect(enableHandler, &QObject::destroyed, button, + // &QObject::deleteLater); toolbar->addAction(button); + } + } + QAction* act = ta->getAction(parent, account, contact); + if (act) { + act->setObjectName(shortName_); + connect(enableHandler, &QObject::destroyed, act, &QObject::deleteLater); + toolbar->addAction(act); + } } - } } bool PluginHost::hasToolBarButton() { return hasToolBarButton_; } -void PluginHost::addGCToolBarButton(QObject *parent, QWidget *toolbar, - int account, const QString &contact) { - GCToolbarIconAccessor *ta = qobject_cast(plugin_); - if (ta) { - if (!gcbuttons_.isEmpty()) { - for (int i = 0; i < gcbuttons_.size(); ++i) { - QVariantHash param = gcbuttons_.at(i); - QString th = param.value("tooltip").value(); - // IconAction * button = new IconAction(th, - // param.value("icon").value(), th, 0, parent); - // connect(button, SIGNAL(triggered()), - // param.value("reciver").value(), - // param.value("slot").value().toLatin1()); - // connect(enableHandler, &QObject::destroyed, button, - // &QObject::deleteLater); toolbar->addAction(button); - } - } - QAction *act = ta->getGCAction(parent, account, contact); - if (act) { - act->setObjectName(shortName_); - connect(enableHandler, &QObject::destroyed, act, &QObject::deleteLater); - toolbar->addAction(act); +void PluginHost::addGCToolBarButton(QObject* parent, QWidget* toolbar, int account, + const QString& contact) { + GCToolbarIconAccessor* ta = qobject_cast(plugin_); + if (ta) { + if (!gcbuttons_.isEmpty()) { + for (int i = 0; i < gcbuttons_.size(); ++i) { + QVariantHash param = gcbuttons_.at(i); + QString th = param.value("tooltip").value(); + // IconAction * button = new IconAction(th, + // param.value("icon").value(), th, 0, parent); + // connect(button, SIGNAL(triggered()), + // param.value("reciver").value(), + // param.value("slot").value().toLatin1()); + // connect(enableHandler, &QObject::destroyed, button, + // &QObject::deleteLater); toolbar->addAction(button); + } + } + QAction* act = ta->getGCAction(parent, account, contact); + if (act) { + act->setObjectName(shortName_); + connect(enableHandler, &QObject::destroyed, act, &QObject::deleteLater); + toolbar->addAction(act); + } } - } } bool PluginHost::hasGCToolBarButton() { return hasGCToolBarButton_; } -void PluginHost::initPopup(const QString &text, const QString &title, - const QString &icon, int type) { - manager_->initPopup(text, title, icon, type); +void PluginHost::initPopup(const QString& text, const QString& title, const QString& icon, + int type) { + manager_->initPopup(text, title, icon, type); } -void PluginHost::initPopupForJid(int account, const QString &jid, - const QString &text, const QString &title, - const QString &icon, int type) { - manager_->initPopupForJid(account, jid, text, title, icon, type); +void PluginHost::initPopupForJid(int account, const QString& jid, const QString& text, + const QString& title, const QString& icon, int type) { + manager_->initPopupForJid(account, jid, text, title, icon, type); } -int PluginHost::registerOption(const QString &name, int initValue, - const QString &path) { - return manager_->registerOption(name, initValue, path); +int PluginHost::registerOption(const QString& name, int initValue, const QString& path) { + return manager_->registerOption(name, initValue, path); } -void PluginHost::unregisterOption(const QString &name) { - manager_->unregisterOption(name); -} +void PluginHost::unregisterOption(const QString& name) { manager_->unregisterOption(name); } -int PluginHost::popupDuration(const QString &name) { - return manager_->popupDuration(name); -} +int PluginHost::popupDuration(const QString& name) { return manager_->popupDuration(name); } -void PluginHost::setPopupDuration(const QString &name, int value) { - manager_->setPopupDuration(name, value); +void PluginHost::setPopupDuration(const QString& name, int value) { + manager_->setPopupDuration(name, value); } -void PluginHost::addAccountMenu(QMenu *menu, int account) { - MenuAccessor *ma = qobject_cast(plugin_); - if (ma) { - if (!accMenu_.isEmpty()) { - for (int i = 0; i < accMenu_.size(); ++i) { - QVariantHash param = accMenu_.at(i); - // IconAction * act - // = new - // IconAction(param.value("name").value(), - // menu, param.value("icon").value()); - // act->setProperty("account", QVariant(account)); - // connect(act, SIGNAL(triggered()), - // param.value("reciver").value(), - // param.value("slot").value().toLatin1()); - // menu->addAction(act); - } - } - QAction *act = ma->getAccountAction(menu, account); - if (act) - menu->addAction(act); - } -} - -void PluginHost::addContactMenu(QMenu *menu, int account, const QString &jid) { - MenuAccessor *ma = qobject_cast(plugin_); - if (ma) { - if (!contactMenu_.isEmpty()) { - for (int i = 0; i < contactMenu_.size(); ++i) { - QVariantHash param = contactMenu_.at(i); - // IconAction * act - // = new - // IconAction(param.value("name").value(), - // menu, param.value("icon").value()); - // act->setProperty("account", QVariant(account)); - // act->setProperty("jid", QVariant(jid)); - // connect(act, SIGNAL(triggered()), - // param.value("reciver").value(), - // param.value("slot").value().toLatin1()); - // menu->addAction(act); - } +void PluginHost::addAccountMenu(QMenu* menu, int account) { + MenuAccessor* ma = qobject_cast(plugin_); + if (ma) { + if (!accMenu_.isEmpty()) { + for (int i = 0; i < accMenu_.size(); ++i) { + QVariantHash param = accMenu_.at(i); + // IconAction * act + // = new + // IconAction(param.value("name").value(), + // menu, param.value("icon").value()); + // act->setProperty("account", QVariant(account)); + // connect(act, SIGNAL(triggered()), + // param.value("reciver").value(), + // param.value("slot").value().toLatin1()); + // menu->addAction(act); + } + } + QAction* act = ma->getAccountAction(menu, account); + if (act) menu->addAction(act); } - QAction *act = ma->getContactAction(menu, account, jid); - if (act) - menu->addAction(act); - } } -void PluginHost::setupChatTab(QWidget *tab, int account, - const QString &contact) { - ChatTabAccessor *cta = qobject_cast(plugin_); - if (cta) { - cta->setupChatTab(tab, account, contact); - } +void PluginHost::addContactMenu(QMenu* menu, int account, const QString& jid) { + MenuAccessor* ma = qobject_cast(plugin_); + if (ma) { + if (!contactMenu_.isEmpty()) { + for (int i = 0; i < contactMenu_.size(); ++i) { + QVariantHash param = contactMenu_.at(i); + // IconAction * act + // = new + // IconAction(param.value("name").value(), + // menu, param.value("icon").value()); + // act->setProperty("account", QVariant(account)); + // act->setProperty("jid", QVariant(jid)); + // connect(act, SIGNAL(triggered()), + // param.value("reciver").value(), + // param.value("slot").value().toLatin1()); + // menu->addAction(act); + } + } + QAction* act = ma->getContactAction(menu, account, jid); + if (act) menu->addAction(act); + } } -void PluginHost::setupGCTab(QWidget *tab, int account, const QString &contact) { - ChatTabAccessor *cta = qobject_cast(plugin_); - if (cta) { - cta->setupGCTab(tab, account, contact); - } +void PluginHost::setupChatTab(QWidget* tab, int account, const QString& contact) { + ChatTabAccessor* cta = qobject_cast(plugin_); + if (cta) { + cta->setupChatTab(tab, account, contact); + } } -bool PluginHost::appendingChatMessage(int account, const QString &contact, - QString &body, QDomElement &html, - bool local) { - ChatTabAccessor *cta = qobject_cast(plugin_); - if (cta) { - return cta->appendingChatMessage(account, contact, body, html, local); - } - return false; +void PluginHost::setupGCTab(QWidget* tab, int account, const QString& contact) { + ChatTabAccessor* cta = qobject_cast(plugin_); + if (cta) { + cta->setupGCTab(tab, account, contact); + } } -bool PluginHost::isSelf(int account, const QString &jid) { - return manager_->isSelf(account, jid); +bool PluginHost::appendingChatMessage(int account, const QString& contact, QString& body, + QDomElement& html, bool local) { + ChatTabAccessor* cta = qobject_cast(plugin_); + if (cta) { + return cta->appendingChatMessage(account, contact, body, html, local); + } + return false; } -bool PluginHost::isAgent(int account, const QString &jid) { - return manager_->isAgent(account, jid); -} +bool PluginHost::isSelf(int account, const QString& jid) { return manager_->isSelf(account, jid); } -bool PluginHost::inList(int account, const QString &jid) { - return manager_->inList(account, jid); +bool PluginHost::isAgent(int account, const QString& jid) { + return manager_->isAgent(account, jid); } -bool PluginHost::isPrivate(int account, const QString &jid) { - return manager_->isPrivate(account, jid); -} +bool PluginHost::inList(int account, const QString& jid) { return manager_->inList(account, jid); } -bool PluginHost::isConference(int account, const QString &jid) { - return manager_->isConference(account, jid); +bool PluginHost::isPrivate(int account, const QString& jid) { + return manager_->isPrivate(account, jid); } -QString PluginHost::name(int account, const QString &jid) { - return manager_->name(account, jid); +bool PluginHost::isConference(int account, const QString& jid) { + return manager_->isConference(account, jid); } -QString PluginHost::status(int account, const QString &jid) { - return manager_->status(account, jid); +QString PluginHost::name(int account, const QString& jid) { return manager_->name(account, jid); } + +QString PluginHost::status(int account, const QString& jid) { + return manager_->status(account, jid); } -QString PluginHost::statusMessage(int account, const QString &jid) { - return manager_->statusMessage(account, jid); +QString PluginHost::statusMessage(int account, const QString& jid) { + return manager_->statusMessage(account, jid); } -QStringList PluginHost::resources(int account, const QString &jid) { - return manager_->resources(account, jid); +QStringList PluginHost::resources(int account, const QString& jid) { + return manager_->resources(account, jid); } -QString PluginHost::realJid(int account, const QString &jid) { - return manager_->realJid(account, jid); +QString PluginHost::realJid(int account, const QString& jid) { + return manager_->realJid(account, jid); } -QString PluginHost::mucNick(int account, const QString &mucJid) { - return manager_->mucNick(account, mucJid); +QString PluginHost::mucNick(int account, const QString& mucJid) { + return manager_->mucNick(account, mucJid); } -QStringList PluginHost::mucNicks(int account, const QString &mucJid) { - return manager_->mucNicks(account, mucJid); +QStringList PluginHost::mucNicks(int account, const QString& mucJid) { + return manager_->mucNicks(account, mucJid); } -bool PluginHost::hasCaps(int account, const QString &jid, - const QStringList &caps) { - return manager_->hasCaps(account, jid, caps); +bool PluginHost::hasCaps(int account, const QString& jid, const QStringList& caps) { + return manager_->hasCaps(account, jid, caps); } bool PluginHost::hasInfoProvider() { return hasInfo_; } QString PluginHost::pluginInfo() { return infoString_; } -void PluginHost::setStatus(int account, const QString &status, - const QString &statusMessage) { - manager_->setStatus(account, status, statusMessage); +void PluginHost::setStatus(int account, const QString& status, const QString& statusMessage) { + manager_->setStatus(account, status, statusMessage); } -bool PluginHost::appendSysMsg(int account, const QString &jid, - const QString &message) { - return manager_->appendSysMsg(account, jid, message); +bool PluginHost::appendSysMsg(int account, const QString& jid, const QString& message) { + return manager_->appendSysMsg(account, jid, message); } -bool PluginHost::appendSysHtmlMsg(int account, const QString &jid, - const QString &message) { - return manager_->appendSysHtmlMsg(account, jid, message); +bool PluginHost::appendSysHtmlMsg(int account, const QString& jid, const QString& message) { + return manager_->appendSysHtmlMsg(account, jid, message); } -void PluginHost::createNewEvent(int account, const QString &jid, - const QString &descr, QObject *receiver, - const char *slot) { - manager_->createNewEvent(account, jid, descr, receiver, slot); +void PluginHost::createNewEvent(int account, const QString& jid, const QString& descr, + QObject* receiver, const char* slot) { + manager_->createNewEvent(account, jid, descr, receiver, slot); } -void PluginHost::createNewMessageEvent(int account, - QDomElement const &element) { - manager_->createNewMessageEvent(account, element); +void PluginHost::createNewMessageEvent(int account, QDomElement const& element) { + manager_->createNewMessageEvent(account, element); } -void PluginHost::playSound(const QString &fileName) { - // soundPlay(fileName); +void PluginHost::playSound(const QString& fileName) { + // soundPlay(fileName); } /** * EncryptionSupport */ -bool PluginHost::decryptMessageElement(int account, QDomElement &message) { - QMutexLocker locker(&mutex_); +bool PluginHost::decryptMessageElement(int account, QDomElement& message) { + QMutexLocker locker(&mutex_); - qDebug() << "decryptMessageElement account:" << account << "msg:" << &message; - auto es = qobject_cast(plugin_); - bool decrypted = es && es->decryptMessageElement(account, message); - qDebug() << "decryptMessageElement account:" << account << decrypted; - return decrypted; + qDebug() << "decryptMessageElement account:" << account << "msg:" << &message; + auto es = qobject_cast(plugin_); + bool decrypted = es && es->decryptMessageElement(account, message); + qDebug() << "decryptMessageElement account:" << account << decrypted; + return decrypted; } -bool PluginHost::encryptMessageElement(int account, QDomElement &message) { - QMutexLocker locker(&mutex_); +bool PluginHost::encryptMessageElement(int account, QDomElement& message) { + QMutexLocker locker(&mutex_); - if (plugin_.isNull()) { - qWarning() << "Unable find plugin"; - return false; - } + if (plugin_.isNull()) { + qWarning() << "Unable find plugin"; + return false; + } - auto es = qobject_cast(plugin_); - if (!es) { - qWarning() << "Unable find plugin for EncryptionSupport"; - return false; - } + auto es = qobject_cast(plugin_); + if (!es) { + qWarning() << "Unable find plugin for EncryptionSupport"; + return false; + } - qDebug() << "encryptMessageElement account:" << account - << "msg:" << message.ownerDocument().toString(); - auto encrypted = es->encryptMessageElement(account, message); - qDebug() << "encryptMessageElement account:" << account << encrypted; - return true; + qDebug() << "encryptMessageElement account:" << account + << "msg:" << message.ownerDocument().toString(); + auto encrypted = es->encryptMessageElement(account, message); + qDebug() << "encryptMessageElement account:" << account << encrypted; + return true; } /** * PluginAccessingHost */ -QObject *PluginHost::getPlugin(const QString &shortName) { - for (PluginHost *plugin : qAsConst(manager_->pluginsByPriority_)) { - if (plugin->shortName() == shortName || plugin->name() == shortName) { - return plugin->plugin_; +QObject* PluginHost::getPlugin(const QString& shortName) { + for (PluginHost* plugin : qAsConst(manager_->pluginsByPriority_)) { + if (plugin->shortName() == shortName || plugin->name() == shortName) { + return plugin->plugin_; + } } - } - return nullptr; + return nullptr; } QVariantMap PluginHost::selfMetadata() const { - QVariantMap md; - md.insert(QLatin1String("name"), name_); - md.insert(QLatin1String("shortname"), shortName_); - md.insert(QLatin1String("version"), version_); - md.insert(QLatin1String("priority"), priority_); - md.insert(QLatin1String("icon"), icon_); - md.insert(QLatin1String("rawIcon"), rawIcon_); - md.insert(QLatin1String("description"), description_); - return md; + QVariantMap md; + md.insert(QLatin1String("name"), name_); + md.insert(QLatin1String("shortname"), shortName_); + md.insert(QLatin1String("version"), version_); + md.insert(QLatin1String("priority"), priority_); + md.insert(QLatin1String("icon"), icon_); + md.insert(QLatin1String("rawIcon"), rawIcon_); + md.insert(QLatin1String("description"), description_); + return md; } WebkitAccessingHost::RenderType PluginHost::chatLogRenderType() const { #ifdef WEBKIT #ifdef WEBENGINE - return WebkitAccessingHost::RT_WebEngine; + return WebkitAccessingHost::RT_WebEngine; #else - return WebkitAccessingHost::RT_WebKit; + return WebkitAccessingHost::RT_WebKit; #endif #else - return WebkitAccessingHost::RT_TextEdit; + return WebkitAccessingHost::RT_TextEdit; #endif } -QString PluginHost::installChatLogJSDataFilter(const QString &js, - OkPlugin::Priority priority) { - return {}; // manager_->installChatLogJSDataFilter(js, priority); +QString PluginHost::installChatLogJSDataFilter(const QString& js, OkPlugin::Priority priority) { + return {}; // manager_->installChatLogJSDataFilter(js, priority); } // void PluginHost::uninstallChatLogJSDataFilter(const QString &id) { // manager_->uninstallChatLogJSDataFilter(id); // } -void PluginHost::executeChatLogJavaScript(QWidget *log, const QString &js) { +void PluginHost::executeChatLogJavaScript(QWidget* log, const QString& js) { #ifdef WEBKIT - auto cv = qobject_cast(log); - if (!cv) { - cv = log->findChild("log"); - } - if (cv) { - cv->sendJsCode(js); - } + auto cv = qobject_cast(log); + if (!cv) { + cv = log->findChild("log"); + } + if (cv) { + cv->sendJsCode(js); + } #else - Q_UNUSED(log); - Q_UNUSED(js) + Q_UNUSED(log); + Q_UNUSED(js) #endif } -void PluginHost::selectMediaDevices(const QString &audioInput, - const QString &audioOutput, - const QString &videoInput) { - qDebug() << "selectMediaDevices"; - // MediaDeviceWatcher::instance()->selectDevices(audioInput, audioOutput, - // videoInput); +void PluginHost::selectMediaDevices(const QString& audioInput, + const QString& audioOutput, + const QString& videoInput) { + qDebug() << "selectMediaDevices"; + // MediaDeviceWatcher::instance()->selectDevices(audioInput, audioOutput, + // videoInput); } -void PluginHost::setMediaProvider(PsiMedia::Provider *provider) { - // PsiMedia::setProvider(provider); - // MediaDeviceWatcher::instance()->setup(); +void PluginHost::setMediaProvider(PsiMedia::Provider* provider) { + // PsiMedia::setProvider(provider); + // MediaDeviceWatcher::instance()->setup(); } //-- helpers -------------------------------------------------------- -static bool operator<(const QRegExp &a, const QRegExp &b) { - return a.pattern() < b.pattern(); -} -} // namespace plugin -} // namespace ok +static bool operator<(const QRegExp& a, const QRegExp& b) { return a.pattern() < b.pattern(); } +} // namespace plugin +} // namespace ok diff --git a/src/lib/plugin/pluginhost.h b/src/lib/plugin/pluginhost.h index 55f3928a..41d03297 100644 --- a/src/lib/plugin/pluginhost.h +++ b/src/lib/plugin/pluginhost.h @@ -16,12 +16,12 @@ #include "accountinfoaccessinghost.h" #include "activetabaccessinghost.h" #include "applicationinfoaccessinghost.h" -#include "lib/settings/applicationinfo.h" #include "contactinfoaccessinghost.h" #include "contactstateaccessinghost.h" #include "encryptionsupport.h" #include "eventcreatinghost.h" #include "iconfactoryaccessinghost.h" +#include "lib/settings/applicationinfo.h" // #include "iconset.h" #include "iqfilteringhost.h" #include "optionaccessinghost.h" @@ -77,287 +77,269 @@ class PluginHost : public QObject, public PluginAccessingHost, public WebkitAccessingHost, public PsiMediaHost { - Q_OBJECT - Q_INTERFACES( - StanzaSendingHost IqFilteringHost ok::plugin::OptionAccessingHost - ShortcutAccessingHost IconFactoryAccessingHost ActiveTabAccessingHost - ApplicationInfoAccessingHost AccountInfoAccessingHost - PopupAccessingHost ContactStateAccessingHost - PsiAccountControllingHost EventCreatingHost - ContactInfoAccessingHost SoundAccessingHost - ok::plugin::EncryptionSupport PluginAccessingHost - ok::plugin::WebkitAccessingHost - ok::plugin::PsiMediaHost) + Q_OBJECT + Q_INTERFACES( + StanzaSendingHost IqFilteringHost ok::plugin::OptionAccessingHost ShortcutAccessingHost + IconFactoryAccessingHost ActiveTabAccessingHost ApplicationInfoAccessingHost + AccountInfoAccessingHost PopupAccessingHost ContactStateAccessingHost + PsiAccountControllingHost EventCreatingHost + ContactInfoAccessingHost SoundAccessingHost ok::plugin:: + EncryptionSupport PluginAccessingHost + ok::plugin::WebkitAccessingHost + ok::plugin::PsiMediaHost) public: - PluginHost(PluginManager *manager, const QString &pluginFile); - virtual ~PluginHost(); - - PluginHost(const PluginHost &) = delete; - PluginHost &operator=(const PluginHost &) = delete; - - bool isValid() const; - const QString &path() const; - QWidget *optionsWidget() const; - - // cached basic info - inline const QString &name() const{ - return name_; - }; - - const QString &shortName() const; - const QString &version() const; - const QString &vendor() const; - const QString &description() const; - const QIcon &icon() const; - int priority() const; - - QStringList pluginFeatures() const; - - // loading - void updateMetadata(); - bool load(); - bool unload(); - bool isLoaded() const; - - // enabling - bool enable(); - bool disable(); - bool isEnabled() const; - - // for StanzaFilter and IqNamespaceFilter - bool incomingXml(int account, const QDomElement &e); - bool outgoingXml(int account, QDomElement &e); - - // for EventFilter - bool processEvent(int account, QDomElement &e); - bool processMessage(int account, const QString &jidFrom, const QString &body, - const QString &subject); - bool processOutgoingMessage(int account, const QString &jidTo, QString &body, - const QString &type, QString &subject); - void logout(int account); - - // StanzaSendingHost - void sendStanza(int account, const QDomElement &xml) override; - void sendStanza(int account, const QString &xml) override; - void sendMessage(int account, const QString &to, const QString &body, - const QString &subject, const QString &type) override; - QString uniqueId(int account) override; - QString escape(const QString &str) override; - - // IqFilteringHost - void addIqNamespaceFilter(const QString &ns, - IqNamespaceFilter *filter) override; - void addIqNamespaceFilter(const QRegExp &ns, - IqNamespaceFilter *filter) override; - void removeIqNamespaceFilter(const QString &ns, - IqNamespaceFilter *filter) override; - void removeIqNamespaceFilter(const QRegExp &ns, - IqNamespaceFilter *filter) override; - - // OptionAccessingHost - void setPluginOption(const QString &option, const QVariant &value) override; - QVariant - getPluginOption(const QString &option, - const QVariant &defValue = QVariant::Invalid) override; - void setGlobalOption(const QString &option, const QVariant &value) override; - QVariant getGlobalOption(const QString &option) override; - void optionChanged(const QString &option); - void addSettingPage(OAH_PluginOptionsTab *tab) override; - void removeSettingPage(OAH_PluginOptionsTab *tab) override; - - // ShortcutAccessingHost - void setShortcuts(); - void connectShortcut(const QKeySequence &shortcut, QObject *receiver, - const char *slot) override; - void disconnectShortcut(const QKeySequence &shortcut, QObject *receiver, - const char *slot) override; - void requestNewShortcut(QObject *receiver, const char *slot) override; - - // IconFactoryAccessingHost - QIcon getIcon(const QString &name) override; - void addIcon(const QString &name, const QByteArray &icon) override; - - // ActiveTabHost - QTextEdit *getEditBox() override; - QString getJid() override; - QString getYourJid() override; - - // ApplicationInfoAccessingHost - Proxy getProxyFor(const QString &obj) override; - QString appName() override; - QString appVersion() override; - QString appCapsNode() override; - QString appCapsVersion() override; - QString appOsName() override; - QString appOsVersion() override; - QString appHomeDir(HomedirType type) override; - QString appResourcesDir() override; - QString appLibDir() override; - QString appProfilesDir(HomedirType type) override; - QString appHistoryDir() override; - QString appCurrentProfileDir(HomedirType type) override; - QString appVCardDir() override; - - // AccountInfoAcsessingHost - QString getStatus(int account) override; - QString getStatusMessage(int account) override; - QString proxyHost(int account) override; - int proxyPort(int account) override; - QString proxyUser(int account) override; - QString proxyPassword(int account) override; - QString getJid(int account) override; - QString getId(int account) override; - QString getName(int account) override; - QStringList getRoster(int account) override; - int findOnlineAccountForContact(const QString &jid) const override; - QString getPgpKey(int account) override; - QMap getKnownPgpKeys(int account) override; - - // ContactInfoAccessingHost - bool isSelf(int account, const QString &jid) override; - bool isAgent(int account, const QString &jid) override; - bool inList(int account, const QString &jid) override; - bool isPrivate(int account, const QString &jid) override; - bool isConference(int account, const QString &jid) override; - QString name(int account, const QString &jid) override; - QString status(int account, const QString &jid) override; - QString statusMessage(int account, const QString &jid) override; - QStringList resources(int account, const QString &jid) override; - QString realJid(int account, const QString &jid) override; - QString mucNick(int account, const QString &mucJid) override; - QStringList mucNicks(int account, const QString &mucJid) override; - bool hasCaps(int account, const QString &jid, - const QStringList &caps) override; - - // ContactStateAccessor - bool setActivity(int account, const QString &Jid, QDomElement xml) override; - bool setMood(int account, const QString &Jid, QDomElement xml) override; - bool setTune(int account, const QString &Jid, QString tune) override; - - // PopupAccessingHost - void initPopup(const QString &text, const QString &title, const QString &icon, - int type) override; - void initPopupForJid(int account, const QString &jid, const QString &text, - const QString &title, const QString &icon, - int type) override; - int registerOption(const QString &name, int initValue = 5, - const QString &path = QString()) override; - int popupDuration(const QString &name) override; - void setPopupDuration(const QString &name, int value) override; - void unregisterOption(const QString &name) override; - - void addToolBarButton(QObject *parent, QWidget *toolbar, int account, - const QString &contact); - bool hasToolBarButton(); - - void addGCToolBarButton(QObject *parent, QWidget *toolbar, int account, - const QString &contact); - bool hasGCToolBarButton(); - - void addAccountMenu(QMenu *menu, int account); - void addContactMenu(QMenu *menu, int account, const QString &jid); - - // ChatTabAccessor - void setupChatTab(QWidget *tab, int account, const QString &contact); - - // GCTabAccessor - void setupGCTab(QWidget *tab, int account, const QString &contact); - - bool appendingChatMessage(int account, const QString &contact, QString &body, - QDomElement &html, bool local); - - void applyOptions(); - void restoreOptions(); - - QString pluginInfo(); - bool hasInfoProvider(); - - // PsiAccountControllingHost - void setStatus(int account, const QString &status, - const QString &statusMessage) override; - bool appendSysMsg(int account, const QString &jid, - const QString &message) override; - bool appendSysHtmlMsg(int account, const QString &jid, - const QString &message) override; - void subscribeBeforeLogin(QObject *context, - std::function callback) override; - void subscribeLogout(QObject *context, - std::function callback) override; - void setPgpKey(int account, const QString &keyId) override; - void removeKnownPgpKey(int account, const QString &jid) override; - void setClientVersionInfo(int account, const QVariantMap &info) override; - - void createNewEvent(int account, const QString &jid, const QString &descr, - QObject *receiver, const char *slot) override; - void createNewMessageEvent(int account, QDomElement const &element) override; - - void playSound(const QString &fileName) override; - - // EncryptionSupport - bool decryptMessageElement(int account, QDomElement &message) override; - bool encryptMessageElement(int account, QDomElement &message) override; - - // PluginAccessingHost - QObject *getPlugin(const QString &name) override; - QVariantMap selfMetadata() const override; - - // WebkitAccessingHost - RenderType chatLogRenderType() const override; - QString installChatLogJSDataFilter( - const QString &js, - OkPlugin::Priority priority = OkPlugin::PriorityNormal) override; - // void uninstallChatLogJSDataFilter(const QString &id) override; - void executeChatLogJavaScript(QWidget *log, const QString &js) override; - - // PsiMediaHost (calls from plugin to psi) - void selectMediaDevices(const QString &audioInput, const QString &audioOutput, - const QString &videoInput) override; - void setMediaProvider(PsiMedia::Provider *provider) override; + PluginHost(PluginManager* manager, const QString& pluginFile); + virtual ~PluginHost(); + + PluginHost(const PluginHost&) = delete; + PluginHost& operator=(const PluginHost&) = delete; + + bool isValid() const; + const QString& path() const; + QWidget* optionsWidget() const; + + // cached basic info + inline const QString& name() const { return name_; }; + + const QString& shortName() const; + const QString& version() const; + const QString& vendor() const; + const QString& description() const; + const QIcon& icon() const; + int priority() const; + + QStringList pluginFeatures() const; + + // loading + void updateMetadata(); + bool load(); + bool unload(); + bool isLoaded() const; + + // enabling + bool enable(); + bool disable(); + bool isEnabled() const; + + // for StanzaFilter and IqNamespaceFilter + bool incomingXml(int account, const QDomElement& e); + bool outgoingXml(int account, QDomElement& e); + + // for EventFilter + bool processEvent(int account, QDomElement& e); + bool processMessage(int account, const QString& jidFrom, const QString& body, + const QString& subject); + bool processOutgoingMessage(int account, const QString& jidTo, QString& body, + const QString& type, QString& subject); + void logout(int account); + + // StanzaSendingHost + void sendStanza(int account, const QDomElement& xml) override; + void sendStanza(int account, const QString& xml) override; + void sendMessage(int account, const QString& to, const QString& body, const QString& subject, + const QString& type) override; + QString uniqueId(int account) override; + QString escape(const QString& str) override; + + // IqFilteringHost + void addIqNamespaceFilter(const QString& ns, IqNamespaceFilter* filter) override; + void addIqNamespaceFilter(const QRegExp& ns, IqNamespaceFilter* filter) override; + void removeIqNamespaceFilter(const QString& ns, IqNamespaceFilter* filter) override; + void removeIqNamespaceFilter(const QRegExp& ns, IqNamespaceFilter* filter) override; + + // OptionAccessingHost + void setPluginOption(const QString& option, const QVariant& value) override; + QVariant getPluginOption(const QString& option, + const QVariant& defValue = QVariant::Invalid) override; + void setGlobalOption(const QString& option, const QVariant& value) override; + QVariant getGlobalOption(const QString& option) override; + void optionChanged(const QString& option); + void addSettingPage(OAH_PluginOptionsTab* tab) override; + void removeSettingPage(OAH_PluginOptionsTab* tab) override; + + // ShortcutAccessingHost + void setShortcuts(); + void connectShortcut(const QKeySequence& shortcut, QObject* receiver, + const char* slot) override; + void disconnectShortcut(const QKeySequence& shortcut, QObject* receiver, + const char* slot) override; + void requestNewShortcut(QObject* receiver, const char* slot) override; + + // IconFactoryAccessingHost + QIcon getIcon(const QString& name) override; + void addIcon(const QString& name, const QByteArray& icon) override; + + // ActiveTabHost + QTextEdit* getEditBox() override; + QString getJid() override; + QString getYourJid() override; + + // ApplicationInfoAccessingHost + Proxy getProxyFor(const QString& obj) override; + QString appName() override; + QString appVersion() override; + QString appCapsNode() override; + QString appCapsVersion() override; + QString appOsName() override; + QString appOsVersion() override; + QString appHomeDir(HomedirType type) override; + QString appResourcesDir() override; + QString appLibDir() override; + QString appProfilesDir(HomedirType type) override; + QString appHistoryDir() override; + QString appCurrentProfileDir(HomedirType type) override; + QString appVCardDir() override; + + // AccountInfoAcsessingHost + QString getStatus(int account) override; + QString getStatusMessage(int account) override; + QString proxyHost(int account) override; + int proxyPort(int account) override; + QString proxyUser(int account) override; + QString proxyPassword(int account) override; + QString getJid(int account) override; + QString getId(int account) override; + QString getName(int account) override; + QStringList getRoster(int account) override; + int findOnlineAccountForContact(const QString& jid) const override; + QString getPgpKey(int account) override; + QMap getKnownPgpKeys(int account) override; + + // ContactInfoAccessingHost + bool isSelf(int account, const QString& jid) override; + bool isAgent(int account, const QString& jid) override; + bool inList(int account, const QString& jid) override; + bool isPrivate(int account, const QString& jid) override; + bool isConference(int account, const QString& jid) override; + QString name(int account, const QString& jid) override; + QString status(int account, const QString& jid) override; + QString statusMessage(int account, const QString& jid) override; + QStringList resources(int account, const QString& jid) override; + QString realJid(int account, const QString& jid) override; + QString mucNick(int account, const QString& mucJid) override; + QStringList mucNicks(int account, const QString& mucJid) override; + bool hasCaps(int account, const QString& jid, const QStringList& caps) override; + + // ContactStateAccessor + bool setActivity(int account, const QString& Jid, QDomElement xml) override; + bool setMood(int account, const QString& Jid, QDomElement xml) override; + bool setTune(int account, const QString& Jid, QString tune) override; + + // PopupAccessingHost + void initPopup(const QString& text, const QString& title, const QString& icon, + int type) override; + void initPopupForJid(int account, const QString& jid, const QString& text, const QString& title, + const QString& icon, int type) override; + int registerOption(const QString& name, int initValue = 5, + const QString& path = QString()) override; + int popupDuration(const QString& name) override; + void setPopupDuration(const QString& name, int value) override; + void unregisterOption(const QString& name) override; + + void addToolBarButton(QObject* parent, QWidget* toolbar, int account, const QString& contact); + bool hasToolBarButton(); + + void addGCToolBarButton(QObject* parent, QWidget* toolbar, int account, const QString& contact); + bool hasGCToolBarButton(); + + void addAccountMenu(QMenu* menu, int account); + void addContactMenu(QMenu* menu, int account, const QString& jid); + + // ChatTabAccessor + void setupChatTab(QWidget* tab, int account, const QString& contact); + + // GCTabAccessor + void setupGCTab(QWidget* tab, int account, const QString& contact); + + bool appendingChatMessage(int account, const QString& contact, QString& body, QDomElement& html, + bool local); + + void applyOptions(); + void restoreOptions(); + + QString pluginInfo(); + bool hasInfoProvider(); + + // PsiAccountControllingHost + void setStatus(int account, const QString& status, const QString& statusMessage) override; + bool appendSysMsg(int account, const QString& jid, const QString& message) override; + bool appendSysHtmlMsg(int account, const QString& jid, const QString& message) override; + void subscribeBeforeLogin(QObject* context, std::function callback) override; + void subscribeLogout(QObject* context, std::function callback) override; + void setPgpKey(int account, const QString& keyId) override; + void removeKnownPgpKey(int account, const QString& jid) override; + void setClientVersionInfo(int account, const QVariantMap& info) override; + + void createNewEvent(int account, const QString& jid, const QString& descr, QObject* receiver, + const char* slot) override; + void createNewMessageEvent(int account, QDomElement const& element) override; + + void playSound(const QString& fileName) override; + + // EncryptionSupport + bool decryptMessageElement(int account, QDomElement& message) override; + bool encryptMessageElement(int account, QDomElement& message) override; + + // PluginAccessingHost + QObject* getPlugin(const QString& name) override; + QVariantMap selfMetadata() const override; + + // WebkitAccessingHost + RenderType chatLogRenderType() const override; + QString installChatLogJSDataFilter( + const QString& js, OkPlugin::Priority priority = OkPlugin::PriorityNormal) override; + // void uninstallChatLogJSDataFilter(const QString &id) override; + void executeChatLogJavaScript(QWidget* log, const QString& js) override; + + // PsiMediaHost (calls from plugin to psi) + void selectMediaDevices(const QString& audioInput, const QString& audioOutput, + const QString& videoInput) override; + void setMediaProvider(PsiMedia::Provider* provider) override; private: - bool loadPlugin(QObject *pluginObject); + bool loadPlugin(QObject* pluginObject); signals: - void enabled(); - void disabled(); + void enabled(); + void disabled(); private: - PluginManager *manager_ = nullptr; - QString file_; - QString name_; - QString shortName_; - QString version_; - QString vendor_; - QString description_; - int priority_ = 0; - QByteArray rawIcon_; - QIcon icon_; - - QPointer plugin_ = nullptr; - QPointer loader_ = nullptr; - QPointer enableHandler = nullptr; - - // Iconset * iconset_ = nullptr; - bool hasToolBarButton_ = false; - bool hasGCToolBarButton_ = false; - - bool valid_ = false; - bool connected_ = false; - bool enabled_ = false; - bool hasInfo_ = false; - QString infoString_; - - QMultiMap iqNsFilters_; - QMultiMap iqNsxFilters_; - - QList buttons_; - QList gcbuttons_; - QList accMenu_; - QList contactMenu_; - - QMutex mutex_; + PluginManager* manager_ = nullptr; + QString file_; + QString name_; + QString shortName_; + QString version_; + QString vendor_; + QString description_; + int priority_ = 0; + QByteArray rawIcon_; + QIcon icon_; + + QPointer plugin_ = nullptr; + QPointer loader_ = nullptr; + QPointer enableHandler = nullptr; + + // Iconset * iconset_ = nullptr; + bool hasToolBarButton_ = false; + bool hasGCToolBarButton_ = false; + + bool valid_ = false; + bool connected_ = false; + bool enabled_ = false; + bool hasInfo_ = false; + QString infoString_; + + QMultiMap iqNsFilters_; + QMultiMap iqNsxFilters_; + + QList buttons_; + QList gcbuttons_; + QList accMenu_; + QList contactMenu_; + + QMutex mutex_; }; -} // namespace plugin -} // namespace ok -#endif // PLUGINHOST_H +} // namespace plugin +} // namespace ok +#endif // PLUGINHOST_H diff --git a/src/lib/plugin/pluginmanager.cpp b/src/lib/plugin/pluginmanager.cpp index 54cc9aa0..2d9815f2 100644 --- a/src/lib/plugin/pluginmanager.cpp +++ b/src/lib/plugin/pluginmanager.cpp @@ -12,23 +12,23 @@ #include "pluginmanager.h" +#include +#include +#include +#include +#include +#include #include "OkOptions.h" -#include "base/basic_types.h" #include "base/OkAccount.h" -#include "lib/settings/applicationinfo.h" +#include "base/OkSettings.h" +#include "base/basic_types.h" #include "base/task.h" #include "files.h" #include "iqnamespacefilter.h" #include "lib/messenger/messenger.h" -#include "base/OkSettings.h" +#include "lib/settings/applicationinfo.h" #include "okplugin.h" #include "pluginhost.h" -#include -#include -#include -#include -#include -#include /** * Helper class used to process incoming XML in plugins. * This task should work as long as the related account exists, @@ -46,241 +46,235 @@ namespace plugin { class PluginManager::StreamWatcher : public QObject { public: - StreamWatcher(::lib::messenger::Messenger *messenger, PluginManager *pluginManager, int account_) // - : manager(pluginManager), account(account_), m_messenger(messenger) { - // ignore - connect(m_messenger, &::lib::messenger::Messenger::incoming, // - this, &StreamWatcher::doDom, Qt::QueuedConnection); - } + StreamWatcher(::lib::messenger::Messenger* messenger, PluginManager* pluginManager, + int account_) // + : manager(pluginManager), account(account_), m_messenger(messenger) { + // ignore + connect(m_messenger, &::lib::messenger::Messenger::incoming, // + this, &StreamWatcher::doDom, Qt::QueuedConnection); + } - ~StreamWatcher() {} + ~StreamWatcher() {} - PluginManager *manager; - ::lib::messenger::Messenger *m_messenger; - int account; + PluginManager* manager; + ::lib::messenger::Messenger* m_messenger; + int account; public slots: - void doDom(QString xml) { -// qDebug() << "incomingXml=>" << xml; - QDomDocument document; - if (!document.setContent(xml, true)) { - return; - } - auto ele = document.documentElement(); - manager->incomingXml(account, ele); -// bool y = -// qDebug() << "incomingXml=>" << y; - }; + void doDom(QString xml) { + // qDebug() << "incomingXml=>" << xml; + QDomDocument document; + if (!document.setContent(xml, true)) { + return; + } + auto ele = document.documentElement(); + manager->incomingXml(account, ele); + // bool y = + // qDebug() << "incomingXml=>" << y; + }; }; /** * Function to obtain all the directories in which plugins can be stored * \return List of plugin directories */ -QStringList PluginManager::pluginDirs() { - return ApplicationInfo::pluginDirs(); -} +QStringList PluginManager::pluginDirs() { return ApplicationInfo::pluginDirs(); } /** * Method for accessing the singleton instance of the class. * Instanciates if no instance yet exists. * \return Pointer to the plugin manager. */ -PluginManager *PluginManager::instance() { - if (!instance_) { - instance_ = new PluginManager(); - } - return instance_; +PluginManager* PluginManager::instance() { + if (!instance_) { + instance_ = new PluginManager(); + } + return instance_; } /** * Default constructor. Locates all plugins, sets watchers on those directories * to locate new ones and loads those enabled in the config. */ -PluginManager::PluginManager() : QObject(nullptr), // - psi_(nullptr) , // - m_thread(std::make_unique()){ - updatePluginsList(); - if (!m_thread) { - qCritical() << "could not allocate PluginManager thread"; - return; - } - m_thread->setObjectName("PluginManager"); - this->moveToThread(m_thread.get()); - m_thread->start(); - - auto const &dirs = pluginDirs(); - for (const QString &path : dirs) { - qDebug() << "path " << path; - // QCA::DirWatch *dw = new QCA::DirWatch(path, this); - // connect(dw, SIGNAL(changed()), SLOT(dirsChanged())); - // dirWatchers_.append(dw); - } - - _messageViewJSFiltersTimer = new QTimer(this); - _messageViewJSFiltersTimer->setSingleShot(true); - _messageViewJSFiltersTimer->setInterval(10); - // to be able to restart in case of batch events - connect(_messageViewJSFiltersTimer, &QTimer::timeout, this, - &PluginManager::jsFiltersUpdated); - - // connect(PsiOptions::instance(), &PsiOptions::optionChanged, this, - // &PluginManager::optionChanged); -} - -void PluginManager::initNewSession(PsiCon *psi) { - psi_ = psi; - clients_.clear(); - accountIds_.clear(); - loadEnabledPlugins(); +PluginManager::PluginManager() + : QObject(nullptr) + , // + psi_(nullptr) + , // + m_thread(std::make_unique()) { + updatePluginsList(); + if (!m_thread) { + qCritical() << "could not allocate PluginManager thread"; + return; + } + m_thread->setObjectName("PluginManager"); + this->moveToThread(m_thread.get()); + m_thread->start(); + + auto const& dirs = pluginDirs(); + for (const QString& path : dirs) { + qDebug() << "path " << path; + // QCA::DirWatch *dw = new QCA::DirWatch(path, this); + // connect(dw, SIGNAL(changed()), SLOT(dirsChanged())); + // dirWatchers_.append(dw); + } + + _messageViewJSFiltersTimer = new QTimer(this); + _messageViewJSFiltersTimer->setSingleShot(true); + _messageViewJSFiltersTimer->setInterval(10); + // to be able to restart in case of batch events + connect(_messageViewJSFiltersTimer, &QTimer::timeout, this, &PluginManager::jsFiltersUpdated); + + // connect(PsiOptions::instance(), &PsiOptions::optionChanged, this, + // &PluginManager::optionChanged); +} + +void PluginManager::initNewSession(PsiCon* psi) { + psi_ = psi; + clients_.clear(); + accountIds_.clear(); + loadEnabledPlugins(); } /** * Updates list of known plugins by reading all plugin directories * and returns the list of new plugins */ -QList PluginManager::updatePluginsList() { - QList newPlugins; - - auto const &dirs = pluginDirs(); - for (const QString &d : dirs) { - QDir dir(d); - auto const &entries = dir.entryInfoList(QDir::Files); - for (const QFileInfo &fileInfo : entries) { - QString file = fileInfo.canonicalFilePath(); - auto pp = addHostFile(file); - if (pp) { - newPlugins.append(pp); - } +QList PluginManager::updatePluginsList() { + QList newPlugins; + + auto const& dirs = pluginDirs(); + for (const QString& d : dirs) { + QDir dir(d); + auto const& entries = dir.entryInfoList(QDir::Files); + for (const QFileInfo& fileInfo : entries) { + QString file = fileInfo.canonicalFilePath(); + auto pp = addHostFile(file); + if (pp) { + newPlugins.append(pp); + } + } } - } - return newPlugins; + return newPlugins; +} + +bool PluginManager::uninstallPlugin(const QString& shortName) { + for (const auto& plugin : availablePlugins()) { + auto host = this->plugin(plugin); + if (host) { + if (host->shortName() == shortName) { + qDebug() << "Uninstall plugin:" << shortName; + if (host->unload()) { + removeHostFile(host); + host->deleteLater(); + return true; + }; + } + } + } + return false; } -bool PluginManager::uninstallPlugin(const QString &shortName) { - for (const auto &plugin : availablePlugins()) { - auto host = this->plugin(plugin); - if (host) { - if (host->shortName() == shortName) { - qDebug() << "Uninstall plugin:" << shortName; - if (host->unload()) { - removeHostFile(host); - host->deleteLater(); - return true; - }; - } +bool PluginManager::installPlugin(const QString& filePath, const QString& shortName) { + // 移动到插件目录 + qDebug() << "Plugin is:" << filePath << shortName; + QFile file(filePath); + if (!file.exists()) { + qWarning() << "Plugin is not exist!"; + return false; } - } - return false; + + auto pluginFile = ok::base::OkSettings().getAppPluginPath().path() + '/' + shortName; + auto moved = ok::base::Files::moveFile(filePath, pluginFile); + if (!moved) { + qWarning() << "Plugin move failed!"; + return false; + } + + qDebug() << "Plugin at:" << pluginFile; + auto ph = addHostFile(pluginFile); + if (ph == nullptr) { + return false; + } + return ph->load(); } -bool PluginManager::installPlugin(const QString &filePath, - const QString &shortName) { - // 移动到插件目录 - qDebug() << "Plugin is:" << filePath << shortName; - QFile file(filePath); - if(!file.exists()){ - qWarning()<<"Plugin is not exist!"; - return false; - } +PluginHost* PluginManager::addHostFile(const QString& file) { + qDebug() << "addHostFile:" << file; + if (!QLibrary::isLibrary(file)) { + qDebug("Is not a library: %s", qPrintable(file)); + return nullptr; + } + qDebug("Found plugin: %s", qPrintable(file)); + // if (pluginByFile_.contains(file)) { + // qDebug() << "The plugin:" << file << "is be contained."; + // return nullptr; + // } + + auto* host = new PluginHost(this, file); + connect(host, &PluginHost::enabled, this, + [this, shortName = host->shortName()]() { emit pluginEnabled(shortName); }); + connect(host, &PluginHost::disabled, this, + [this, shortName = host->shortName()]() { emit pluginDisabled(shortName); }); + if (!host->isValid()) { + qDebug() << "The plugin is invalid."; + return nullptr; + } - auto pluginFile = ok::base::OkSettings().getAppPluginPath().path()+'/'+shortName; - auto moved = ok::base::Files::moveFile(filePath, pluginFile); - if(!moved){ - qWarning()<<"Plugin move failed!"; - return false; - } + if (host->shortName().isEmpty()) { + qWarning() << "The plugin:" << host->name() << " is empty."; + return nullptr; + } - qDebug() << "Plugin at:" << pluginFile; - auto ph = addHostFile(pluginFile); - if (ph == nullptr) { - return false; - } - return ph->load(); -} - -PluginHost *PluginManager::addHostFile(const QString &file) { - qDebug()<<"addHostFile:"<shortName()]() { - emit pluginEnabled(shortName); - }); - connect(host, &PluginHost::disabled, this, - [this, shortName = host->shortName()]() { - emit pluginDisabled(shortName); - }); - if (!host->isValid()) { - qDebug() << "The plugin is invalid."; - return nullptr; - } - - if(host->shortName().isEmpty()) { - qWarning() << "The plugin:" << host->name() << " is empty."; - return nullptr; - } - - if (hosts_.contains(host->shortName())) { - qWarning() << "The plugin:" << host->name() << "is loaded."; - return nullptr; - } - - hosts_[host->shortName()] = host; - pluginByFile_[file] = host; - - if (host->priority() == OkPlugin::PriorityHighest || - !pluginsByPriority_.size()) { - pluginsByPriority_.push_front(host); - } else { - // find position for insertion - int i = pluginsByPriority_.size(); - while (i && host->priority() > pluginsByPriority_[i - 1]->priority()) { - i--; + if (hosts_.contains(host->shortName())) { + qWarning() << "The plugin:" << host->name() << "is loaded."; + return nullptr; } - pluginsByPriority_.insert(i, host); - } - host->enable(); - return host; + hosts_[host->shortName()] = host; + pluginByFile_[file] = host; + + if (host->priority() == OkPlugin::PriorityHighest || !pluginsByPriority_.size()) { + pluginsByPriority_.push_front(host); + } else { + // find position for insertion + int i = pluginsByPriority_.size(); + while (i && host->priority() > pluginsByPriority_[i - 1]->priority()) { + i--; + } + pluginsByPriority_.insert(i, host); + } + + host->enable(); + return host; } -void PluginManager::removeHostFile(PluginHost *host) { - if(!host) - { - qWarning() <<"Plugin is not installed."; - return; - } +void PluginManager::removeHostFile(PluginHost* host) { + if (!host) { + qWarning() << "Plugin is not installed."; + return; + } - if(host->isEnabled()){ - qWarning() <<"Plugin is not disabled."; - return; - } + if (host->isEnabled()) { + qWarning() << "Plugin is not disabled."; + return; + } - auto file = pathToPlugin(host->shortName()); - qDebug()<<"Plugin file:"<< file; + auto file = pathToPlugin(host->shortName()); + qDebug() << "Plugin file:" << file; - int host_removed = hosts_.remove(host->shortName()); - qDebug() << "Remove plugin from host:" << host->shortName() << "=>" << host_removed; + int host_removed = hosts_.remove(host->shortName()); + qDebug() << "Remove plugin from host:" << host->shortName() << "=>" << host_removed; - int file_removed2 = pluginByFile_.remove(file); - qDebug() << "Remove plugin from file:" << file << "=>" << file_removed2; + int file_removed2 = pluginByFile_.remove(file); + qDebug() << "Remove plugin from file:" << file << "=>" << file_removed2; - pluginsByPriority_.removeAll(host); - qDebug() << "Remove plugin from pluginsByPriority"; + pluginsByPriority_.removeAll(host); + qDebug() << "Remove plugin from pluginsByPriority"; - auto removed = ok::base::Files::removeFile(file); - qDebug() << "Remove plugin local file:" << file << "=>" << removed; + auto removed = ok::base::Files::removeFile(file); + qDebug() << "Remove plugin local file:" << file << "=>" << removed; } /** @@ -288,15 +282,15 @@ void PluginManager::removeHostFile(PluginHost *host) { * It causes the available plugin list to be refreshed. */ void PluginManager::dirsChanged() { - auto const &pl = updatePluginsList(); - for (PluginHost *plugin : pl) { - loadPluginIfEnabled(plugin); - } + auto const& pl = updatePluginsList(); + for (PluginHost* plugin : pl) { + loadPluginIfEnabled(plugin); + } } void PluginManager::accountDestroyed() { - auto *pa = static_cast(sender()); - accountIds_.removeAccount(pa); + auto* pa = static_cast(sender()); + accountIds_.removeAccount(pa); } /** @@ -305,23 +299,23 @@ void PluginManager::accountDestroyed() { */ void PluginManager::loadEnabledPlugins() { #ifndef PLUGINS_NO_DEBUG - qDebug("Loading enabled plugins"); + qDebug("Loading enabled plugins"); #endif - for (PluginHost *plugin : qAsConst(pluginsByPriority_)) { - loadPluginIfEnabled(plugin); - } + for (PluginHost* plugin : qAsConst(pluginsByPriority_)) { + loadPluginIfEnabled(plugin); + } } -void PluginManager::loadPluginIfEnabled(PluginHost *host) { - // const QString option = QString("%1.%2").arg(loadOptionPrefix, - // plugin->shortName()); QVariant load = - // PsiOptions::instance()->getOption(option, false); if (load.toBool()) { - // #ifndef PLUGINS_NO_DEBUG - // qDebug("Plugin %s is enabled in config: loading", - // qPrintable(plugin->shortName())); - // #endif - // plugin->enable(); - // } +void PluginManager::loadPluginIfEnabled(PluginHost* host) { + // const QString option = QString("%1.%2").arg(loadOptionPrefix, + // plugin->shortName()); QVariant load = + // PsiOptions::instance()->getOption(option, false); if (load.toBool()) { + // #ifndef PLUGINS_NO_DEBUG + // qDebug("Plugin %s is enabled in config: loading", + // qPrintable(plugin->shortName())); + // #endif + // plugin->enable(); + // } } /** @@ -329,50 +323,48 @@ void PluginManager::loadPluginIfEnabled(PluginHost *host) { * option * \param option Option changed */ -void PluginManager::optionChanged(const QString &option) { - bool pluginOpt = option.startsWith(loadOptionPrefix); - const QString shortName = option.split(".").last(); - for (PluginHost *plugin : qAsConst(pluginByFile_)) { - plugin->optionChanged(option); - if (pluginOpt && plugin->shortName() == shortName) { - bool shouldUpdateFeatures; - if (OkOptions::instance()->getOption(option).toBool()) { - plugin->enable(); - shouldUpdateFeatures = !plugin->pluginFeatures().isEmpty(); - } else { - shouldUpdateFeatures = !plugin->pluginFeatures().isEmpty(); - if (optionsWidget_) - delete optionsWidget_; - plugin->unload(); - } - if (shouldUpdateFeatures) { - updateFeatures(); - } +void PluginManager::optionChanged(const QString& option) { + bool pluginOpt = option.startsWith(loadOptionPrefix); + const QString shortName = option.split(".").last(); + for (PluginHost* plugin : qAsConst(pluginByFile_)) { + plugin->optionChanged(option); + if (pluginOpt && plugin->shortName() == shortName) { + bool shouldUpdateFeatures; + if (OkOptions::instance()->getOption(option).toBool()) { + plugin->enable(); + shouldUpdateFeatures = !plugin->pluginFeatures().isEmpty(); + } else { + shouldUpdateFeatures = !plugin->pluginFeatures().isEmpty(); + if (optionsWidget_) delete optionsWidget_; + plugin->unload(); + } + if (shouldUpdateFeatures) { + updateFeatures(); + } + } } - } } void PluginManager::updateFeatures() { - // for (int acc_id = 0; accountIds_.isValidRange(acc_id); ++acc_id) { - // OkAccount *pa = accountIds_.account(acc_id); - // pa->updateFeatures(); - // if (pa->isConnected()) { - // pa->setStatusActual(pa->status()); - // } - // } + // for (int acc_id = 0; accountIds_.isValidRange(acc_id); ++acc_id) { + // OkAccount *pa = accountIds_.account(acc_id); + // pa->updateFeatures(); + // if (pa->isConnected()) { + // pa->setStatusActual(pa->status()); + // } + // } } /** * Loads all available plugins */ void PluginManager::loadAllPlugins() { - qDebug("Loading all plugins"); - // Now look for external plugins - for (PluginHost *plugin : qAsConst(hosts_)) { - plugin->load(); - if (plugin->enable()) - emit pluginEnabled(plugin->shortName()); - } + qDebug("Loading all plugins"); + // Now look for external plugins + for (PluginHost* plugin : qAsConst(hosts_)) { + plugin->load(); + if (plugin->enable()) emit pluginEnabled(plugin->shortName()); + } } /** @@ -382,27 +374,25 @@ void PluginManager::loadAllPlugins() { */ bool PluginManager::unloadAllPlugins() { #ifndef PLUGINS_NO_DEBUG - qDebug("Unloading all plugins"); + qDebug("Unloading all plugins"); #endif - bool ok = true; - for (PluginHost *plugin : qAsConst(hosts_)) { - if (!plugin->unload()) { - ok = false; + bool ok = true; + for (PluginHost* plugin : qAsConst(hosts_)) { + if (!plugin->unload()) { + ok = false; + } } - } - return ok; + return ok; } -bool PluginManager::isAvailable(const QString &plugin) const { - return hosts_.contains(plugin); -} +bool PluginManager::isAvailable(const QString& plugin) const { return hosts_.contains(plugin); } -bool PluginManager::isEnabled(const QString &plugin) const { - bool enabled = false; - if (hosts_.contains(plugin)) { - enabled = hosts_[plugin]->isEnabled(); - } - return enabled; +bool PluginManager::isEnabled(const QString& plugin) const { + bool enabled = false; + if (hosts_.contains(plugin)) { + enabled = hosts_[plugin]->isEnabled(); + } + return enabled; } /** @@ -411,12 +401,12 @@ bool PluginManager::isEnabled(const QString &plugin) const { * \param plugin Name of the plugin. * \return Path to the plugin file. */ -QString PluginManager::pathToPlugin(const QString &plugin) const { - QString path; - if (hosts_.contains(plugin)) { - path = hosts_[plugin]->path(); - } - return path; +QString PluginManager::pathToPlugin(const QString& plugin) const { + QString path; + if (hosts_.contains(plugin)) { + path = hosts_[plugin]->path(); + } + return path; } /** @@ -425,35 +415,35 @@ QString PluginManager::pathToPlugin(const QString &plugin) const { * \param plugin Name of the plugin. * \return Path to the plugin file. */ -QString PluginManager::shortName(const QString &plugin) const { - QString name; - if (hosts_.contains(plugin)) { - name = hosts_[plugin]->shortName(); - } - return name; +QString PluginManager::shortName(const QString& plugin) const { + QString name; + if (hosts_.contains(plugin)) { + name = hosts_[plugin]->shortName(); + } + return name; } -QString PluginManager::pluginName(const QString &shortName) const { - auto host = hosts_.value(shortName); - return host ? host->name() : QString(); +QString PluginManager::pluginName(const QString& shortName) const { + auto host = hosts_.value(shortName); + return host ? host->name() : QString(); } -QString PluginManager::version(const QString &plugin) const { - QString name; - if (hosts_.contains(plugin)) { - name = hosts_[plugin]->version(); - } - return name; +QString PluginManager::version(const QString& plugin) const { + QString name; + if (hosts_.contains(plugin)) { + name = hosts_[plugin]->version(); + } + return name; } -QString PluginManager::vendor(const QString &plugin) const { - auto it = hosts_.find(plugin); - return it == hosts_.end() ? QString() : it.value()->vendor(); +QString PluginManager::vendor(const QString& plugin) const { + auto it = hosts_.find(plugin); + return it == hosts_.end() ? QString() : it.value()->vendor(); } -QString PluginManager::description(const QString &plugin) const { - auto it = hosts_.find(plugin); - return it == hosts_.end() ? QString() : it.value()->description(); +QString PluginManager::description(const QString& plugin) const { + auto it = hosts_.find(plugin); + return it == hosts_.end() ? QString() : it.value()->description(); } /** @@ -467,24 +457,22 @@ QStringList PluginManager::availablePlugins() const { return hosts_.keys(); } * \param plugin Name of the plugin. * \return Pointer to the options widget for the named plugin. */ -QWidget *PluginManager::optionsWidget(const QString &plugin) { - if (optionsWidget_) { - delete optionsWidget_; - } +QWidget* PluginManager::optionsWidget(const QString& plugin) { + if (optionsWidget_) { + delete optionsWidget_; + } - if (hosts_.contains(plugin)) { - optionsWidget_ = hosts_[plugin]->optionsWidget(); - } + if (hosts_.contains(plugin)) { + optionsWidget_ = hosts_[plugin]->optionsWidget(); + } - if (!optionsWidget_) { + if (!optionsWidget_) { #ifndef PLUGINS_NO_DEBUG - qWarning("Attempting to get options for %s which doesn't exist", - qPrintable(plugin)); + qWarning("Attempting to get options for %s which doesn't exist", qPrintable(plugin)); #endif - optionsWidget_ = - new QLabel(tr("This plugin has no user configurable options")); - } - return optionsWidget_; + optionsWidget_ = new QLabel(tr("This plugin has no user configurable options")); + } + return optionsWidget_; } /** @@ -493,9 +481,9 @@ QWidget *PluginManager::optionsWidget(const QString &plugin) { * Each plugin can set its own global shortcuts */ void PluginManager::setShortcuts() { - for (PluginHost *host : qAsConst(pluginByFile_)) { - host->setShortcuts(); - } + for (PluginHost* host : qAsConst(pluginByFile_)) { + host->setShortcuts(); + } } /** @@ -509,17 +497,16 @@ void PluginManager::setShortcuts() { * \return Continue processing the event; true if the event should be silently * discarded. */ -bool PluginManager::processMessage(OkAccount *account, const QString &jidFrom, - const QString &body, - const QString &subject) { - bool handled = false; - for (PluginHost *host : qAsConst(pluginsByPriority_)) { - if (host->processMessage(accountIds_.id(account), jidFrom, body, subject)) { - handled = true; - break; +bool PluginManager::processMessage(OkAccount* account, const QString& jidFrom, const QString& body, + const QString& subject) { + bool handled = false; + for (PluginHost* host : qAsConst(pluginsByPriority_)) { + if (host->processMessage(accountIds_.id(account), jidFrom, body, subject)) { + handled = true; + break; + } } - } - return handled; + return handled; } /** @@ -533,87 +520,82 @@ bool PluginManager::processMessage(OkAccount *account, const QString &jidFrom, * \return Continue processing the event; true if the event should be silently * discarded. */ -bool PluginManager::processEvent(OkAccount *account, QDomElement &event) { - bool handled = false; - const int acc_id = accountIds_.id(account); - for (PluginHost *host : qAsConst(pluginsByPriority_)) { - if (host->processEvent(acc_id, event)) { - handled = true; - break; +bool PluginManager::processEvent(OkAccount* account, QDomElement& event) { + bool handled = false; + const int acc_id = accountIds_.id(account); + for (PluginHost* host : qAsConst(pluginsByPriority_)) { + if (host->processEvent(acc_id, event)) { + handled = true; + break; + } } - } - return handled; + return handled; } /** * process an outgoing message */ -bool PluginManager::processOutgoingMessage(OkAccount *account, - const QString &jidTo, QString &body, - const QString &type, - QString &subject) { - bool handled = false; - const int acc_id = accountIds_.id(account); - for (PluginHost *host : qAsConst(pluginByFile_)) { - if (host->processOutgoingMessage(acc_id, jidTo, body, type, subject)) { - handled = true; - break; +bool PluginManager::processOutgoingMessage(OkAccount* account, const QString& jidTo, QString& body, + const QString& type, QString& subject) { + bool handled = false; + const int acc_id = accountIds_.id(account); + for (PluginHost* host : qAsConst(pluginByFile_)) { + if (host->processOutgoingMessage(acc_id, jidTo, body, type, subject)) { + handled = true; + break; + } } - } - return handled; + return handled; } -void PluginManager::processOutgoingStanza(OkAccount *account, - QDomElement &stanza) { - const int acc_id = accountIds_.id(account); - for (PluginHost *host : qAsConst(pluginByFile_)) { - if (host->outgoingXml(acc_id, stanza)) { - break; +void PluginManager::processOutgoingStanza(OkAccount* account, QDomElement& stanza) { + const int acc_id = accountIds_.id(account); + for (PluginHost* host : qAsConst(pluginByFile_)) { + if (host->outgoingXml(acc_id, stanza)) { + break; + } } - } } /** * Notify to plugins that an account is going to connect. */ -void PluginManager::startLogin(OkAccount *account) { - const int acc_id = accountIds_.id(account); - for (PluginHost *host : qAsConst(pluginByFile_)) { - host->logout(acc_id); - emit accountBeforeLogin(acc_id); - } +void PluginManager::startLogin(OkAccount* account) { + const int acc_id = accountIds_.id(account); + for (PluginHost* host : qAsConst(pluginByFile_)) { + host->logout(acc_id); + emit accountBeforeLogin(acc_id); + } } /** * Notify to plugins that an account will go offline now. */ -void PluginManager::logout(OkAccount *account) { - const int acc_id = accountIds_.id(account); - for (PluginHost *host : qAsConst(pluginByFile_)) { - host->logout(acc_id); - emit accountLoggedOut(acc_id); - } +void PluginManager::logout(OkAccount* account) { + const int acc_id = accountIds_.id(account); + for (PluginHost* host : qAsConst(pluginByFile_)) { + host->logout(acc_id); + emit accountLoggedOut(acc_id); + } } -void PluginManager::addSettingPage(OAH_PluginOptionsTab *tab) { - settingsTabs_.append(tab); - // OptionsDlg *w = qobject_cast(psi_->dialogFind("OptionsDlg")); if (w) { - // w->addPluginWrapperTab(tab); - // } +void PluginManager::addSettingPage(OAH_PluginOptionsTab* tab) { + settingsTabs_.append(tab); + // OptionsDlg *w = qobject_cast(psi_->dialogFind("OptionsDlg")); if (w) { + // w->addPluginWrapperTab(tab); + // } } -void PluginManager::removeSettingPage(OAH_PluginOptionsTab *tab) { - // OptionsDlg *w = qobject_cast(psi_->dialogFind("OptionsDlg")); if (w) { - // w->removeTab(tab->id()); - // } - // settingsTabs_.removeOne(tab); +void PluginManager::removeSettingPage(OAH_PluginOptionsTab* tab) { + // OptionsDlg *w = qobject_cast(psi_->dialogFind("OptionsDlg")); if (w) { + // w->removeTab(tab->id()); + // } + // settingsTabs_.removeOne(tab); } -QList PluginManager::settingsPages() const { - return settingsTabs_; -} +QList PluginManager::settingsPages() const { return settingsTabs_; } /** * \brief Give each plugin the opportunity to process the incoming xml @@ -628,15 +610,15 @@ QList PluginManager::settingsPages() const { * \return Continue processing the event; true if the event should be silently * discarded. */ -bool PluginManager::incomingXml(int account, const QDomElement &xml) { - bool handled = false; - for (PluginHost *host : qAsConst(pluginsByPriority_)) { - if (host->incomingXml(account, xml)) { - handled = true; - break; +bool PluginManager::incomingXml(int account, const QDomElement& xml) { + bool handled = false; + for (PluginHost* host : qAsConst(pluginsByPriority_)) { + if (host->incomingXml(account, xml)) { + handled = true; + break; + } } - } - return handled; + return handled; } /** @@ -645,15 +627,15 @@ bool PluginManager::incomingXml(int account, const QDomElement &xml) { * \param account Identifier of the OkAccount responsible * \param xml XML stanza to be sent */ -void PluginManager::sendXml(int account, const QString &xml) { - if (account < 0) { - qWarning() << "account is" << account << " that is invalid"; - return; - } +void PluginManager::sendXml(int account, const QString& xml) { + if (account < 0) { + qWarning() << "account is" << account << " that is invalid"; + return; + } - if (account < clients_.size()) { - clients_[account]->send(xml); - } + if (account < clients_.size()) { + clients_[account]->send(xml); + } } /** @@ -663,723 +645,682 @@ void PluginManager::sendXml(int account, const QString &xml) { * \return Unique ID to be used for when sending a stanza */ QString PluginManager::uniqueId(int account) const { - QString id; - if (account < clients_.size()) { - id = clients_[account]->genUniqueId(); - } - return id; + QString id; + if (account < clients_.size()) { + id = clients_[account]->genUniqueId(); + } + return id; } QString PluginManager::getStatus(int account) const { - // Status S; - // OkAccount *pa = accountIds_.account(account); - // if (pa) - // S = pa->status(); - // return S.typeString(); - return {}; + // Status S; + // OkAccount *pa = accountIds_.account(account); + // if (pa) + // S = pa->status(); + // return S.typeString(); + return {}; } QString PluginManager::getStatusMessage(int account) const { - // Status S; - // OkAccount *pa = accountIds_.account(account); - // if (pa) - // S = pa->status(); - // return S.status(); - return {}; + // Status S; + // OkAccount *pa = accountIds_.account(account); + // if (pa) + // S = pa->status(); + // return S.status(); + return {}; } -static inline const QString getProxyId(OkAccount *pa) { - // return pa->accountOptions().proxyID; +static inline const QString getProxyId(OkAccount* pa) { + // return pa->accountOptions().proxyID; return {}; } QString PluginManager::proxyHost(int account) const { - QString host; - // OkAccount *pa = accountIds_.account(account); - // if (pa) - // host = ProxyManager::instance()->getItem(getProxyId(pa)).settings.host; - return host; + QString host; + // OkAccount *pa = accountIds_.account(account); + // if (pa) + // host = ProxyManager::instance()->getItem(getProxyId(pa)).settings.host; + return host; } int PluginManager::proxyPort(int account) const { - int port = -1; - // OkAccount *pa = accountIds_.account(account); - // if (pa) - // port = ProxyManager::instance()->getItem(getProxyId(pa)).settings.port; - return port; + int port = -1; + // OkAccount *pa = accountIds_.account(account); + // if (pa) + // port = ProxyManager::instance()->getItem(getProxyId(pa)).settings.port; + return port; } QString PluginManager::proxyUser(int account) const { - QString user; - // OkAccount *pa = accountIds_.account(account); - // if (pa) - // user = ProxyManager::instance()->getItem(getProxyId(pa)).settings.user; - return user; + QString user; + // OkAccount *pa = accountIds_.account(account); + // if (pa) + // user = ProxyManager::instance()->getItem(getProxyId(pa)).settings.user; + return user; } QString PluginManager::proxyPassword(int account) const { - QString pass; - // OkAccount *pa = accountIds_.account(account); - // if (pa) - // pass = ProxyManager::instance()->getItem(getProxyId(pa)).settings.pass; - return pass; + QString pass; + // OkAccount *pa = accountIds_.account(account); + // if (pa) + // pass = ProxyManager::instance()->getItem(getProxyId(pa)).settings.pass; + return pass; } QStringList PluginManager::getRoster(int account) const { - QStringList list; - // list << "-1"; - // if (accountIds_.isValidRange(account)) { - // list.clear(); - // OkAccount *pa = accountIds_.account(account); - // if (pa) { - // QList roster = pa->contactList(); - // for (int i = 0; i < roster.size(); i++) { - // list.push_back(roster.at(i)->jid().bare()); - // } - // } - // } - return list; + QStringList list; + // list << "-1"; + // if (accountIds_.isValidRange(account)) { + // list.clear(); + // OkAccount *pa = accountIds_.account(account); + // if (pa) { + // QList roster = pa->contactList(); + // for (int i = 0; i < roster.size(); i++) { + // list.push_back(roster.at(i)->jid().bare()); + // } + // } + // } + return list; } QString PluginManager::getJid(int account) const { - QString jid = ""; - if (accountIds_.isValidRange(account)) { - jid.clear(); - OkAccount *pa = accountIds_.account(account); - if (pa) - jid = pa->jid().bare(); - } - return jid; + QString jid = ""; + if (accountIds_.isValidRange(account)) { + jid.clear(); + OkAccount* pa = accountIds_.account(account); + if (pa) jid = pa->jid().bare(); + } + return jid; } QString PluginManager::getId(int account) const { - QString id = "-1"; - if (accountIds_.isValidRange(account)) { - id.clear(); - OkAccount *pa = accountIds_.account(account); - if (pa) - id = pa->id(); - } - qDebug() << "account" << account << "=>id" << id; - return id; + QString id = "-1"; + if (accountIds_.isValidRange(account)) { + id.clear(); + OkAccount* pa = accountIds_.account(account); + if (pa) id = pa->id(); + } + qDebug() << "account" << account << "=>id" << id; + return id; } QString PluginManager::getName(int account) const { - QString nm; - OkAccount *pa = accountIds_.account(account); - if (pa) - nm = pa->name(); - return nm; + QString nm; + OkAccount* pa = accountIds_.account(account); + if (pa) nm = pa->name(); + return nm; } QString PluginManager::getPgpKey(int account) const { - QString keyId; - // OkAccount *pa = accountIds_.account(account); - // if (pa) - // keyId = pa->pgpKeyId(); - return keyId; + QString keyId; + // OkAccount *pa = accountIds_.account(account); + // if (pa) + // keyId = pa->pgpKeyId(); + return keyId; } QMap PluginManager::getKnownPgpKeys(int account) const { - QMap out; - // OkAccount *pa = accountIds_.account(account); - // if (pa) { - // UserAccount acc = pa->userAccount(); - // for (const auto &item : qAsConst(acc.pgpKnownKeys)) { - // out[item.key()] = item.data(); - // } - // } - return out; -} - -int PluginManager::findOnlineAccountForContact(const QString &jid) const { - // Jid j(jid); - // for (int acc_id = 0; accountIds_.isValidRange(acc_id); ++acc_id) { - // OkAccount *pa = accountIds_.account(acc_id); - // if (pa && pa->isAvailable() && pa->findContact(j)) - // return acc_id; - // } - return -1; -} - -bool PluginManager::setActivity(int account, const QString &jid, - QDomElement xml) { - // OkAccount *pa = accountIds_.account(account); - // if (!pa) - // return false; - // - // XMPP::Jid userJid(jid); - // UserListItem *item = pa->userList()->find(userJid); - // - // if (!item) - // return false; - // - // Activity act = Activity(); - // if (!xml.isNull()) - // act = Activity(xml); - // item->setActivity(act); - return true; -} - -bool PluginManager::setMood(int account, const QString &jid, QDomElement xml) { - // OkAccount *pa = accountIds_.account(account); - // if (!pa) - // return false; - // - // XMPP::Jid userJid(jid); - // UserListItem *item = pa->userList()->find(userJid); - // - // if (!item) - // return false; - // - // Mood mood = Mood(); - // if (!xml.isNull()) - // mood = Mood(xml); - // item->setMood(mood); - return true; -} - -bool PluginManager::setTune(int account, const QString &jid, - const QString &tune) { - // OkAccount *pa = accountIds_.account(account); - // if (!pa) - // return false; - // - // XMPP::Jid userJid(jid); - // UserListItem *item = pa->userList()->find(userJid); - // - // if (!item) - // return false; - // - // item->setTune(tune); - return true; -} - -void PluginManager::initPopup(const QString &text, const QString &title, - const QString &icon, int type) { - // const PsiIcon *ico = IconsetFactory::iconPtr(icon); - // psi_->popupManager()->doPopup(nullptr, Jid(), ico, title, QPixmap(), - // nullptr, - // text, true, PopupManager::PopupType(type)); -} - -void PluginManager::initPopupForJid(int account, const QString &jid, - const QString &text, const QString &title, - const QString &icon, int type) { - // XMPP::Jid j(jid); - // const PsiIcon *ico = IconsetFactory::iconPtr(icon); - // OkAccount *pa = accountIds_.account(account); - // if (pa) { - // UserListItem *i = pa->findFirstRelevant(j); - // PsiIcon *statusIco = PsiIconset::instance()->statusPtr(i); - // const QPixmap pix = pa->avatarFactory()->getAvatar(j); - // psi_->popupManager()->doPopup(pa, j, ico, title, pix, statusIco, text, - // true, - // PopupManager::PopupType(type)); - // return; - // } - // psi_->popupManager()->doPopup(nullptr, Jid(), ico, title, QPixmap(), - // nullptr, - // text, true, PopupManager::PopupType(type)); -} - -int PluginManager::registerOption(const QString &name, int initValue, - const QString &path) { - // return psi_->popupManager()->registerOption(name, initValue, path); - return 0; -} - -void PluginManager::unregisterOption(const QString &name) { - // psi_->popupManager()->unregisterOption(name); -} - -int PluginManager::popupDuration(const QString &name) const { - return 0; - // return psi_->popupManager()->value(name); -} - -void PluginManager::setPopupDuration(const QString &name, int value) { - // psi_->popupManager()->setValue(name, value); -} - -void PluginManager::addAccountMenu(QMenu *menu, OkAccount *account) { - int i = accountIds_.id(account); - for (PluginHost *host : qAsConst(pluginsByPriority_)) { - host->addAccountMenu(menu, i); - } -} - -void PluginManager::addContactMenu(QMenu *menu, OkAccount *account, - QString jid) { - int i = accountIds_.id(account); - for (PluginHost *host : qAsConst(pluginsByPriority_)) { - host->addContactMenu(menu, i, jid); - } -} - -void PluginManager::setupChatTab(QWidget *tab, OkAccount *account, - const QString &contact) { - int i = accountIds_.id(account); - for (PluginHost *host : qAsConst(pluginsByPriority_)) { - host->setupChatTab(tab, i, contact); - } -} - -void PluginManager::setupGCTab(QWidget *tab, OkAccount *account, - const QString &contact) { - int i = accountIds_.id(account); - for (PluginHost *host : qAsConst(pluginsByPriority_)) { - host->setupGCTab(tab, i, contact); - } -} - -bool PluginManager::appendingChatMessage(OkAccount *account, - const QString &contact, QString &body, - QDomElement &html, bool local) { - bool handled = false; - for (PluginHost *host : qAsConst(pluginsByPriority_)) { - if (host->appendingChatMessage(accountIds_.id(account), contact, body, html, - local)) { - handled = true; - break; + QMap out; + // OkAccount *pa = accountIds_.account(account); + // if (pa) { + // UserAccount acc = pa->userAccount(); + // for (const auto &item : qAsConst(acc.pgpKnownKeys)) { + // out[item.key()] = item.data(); + // } + // } + return out; +} + +int PluginManager::findOnlineAccountForContact(const QString& jid) const { + // Jid j(jid); + // for (int acc_id = 0; accountIds_.isValidRange(acc_id); ++acc_id) { + // OkAccount *pa = accountIds_.account(acc_id); + // if (pa && pa->isAvailable() && pa->findContact(j)) + // return acc_id; + // } + return -1; +} + +bool PluginManager::setActivity(int account, const QString& jid, QDomElement xml) { + // OkAccount *pa = accountIds_.account(account); + // if (!pa) + // return false; + // + // XMPP::Jid userJid(jid); + // UserListItem *item = pa->userList()->find(userJid); + // + // if (!item) + // return false; + // + // Activity act = Activity(); + // if (!xml.isNull()) + // act = Activity(xml); + // item->setActivity(act); + return true; +} + +bool PluginManager::setMood(int account, const QString& jid, QDomElement xml) { + // OkAccount *pa = accountIds_.account(account); + // if (!pa) + // return false; + // + // XMPP::Jid userJid(jid); + // UserListItem *item = pa->userList()->find(userJid); + // + // if (!item) + // return false; + // + // Mood mood = Mood(); + // if (!xml.isNull()) + // mood = Mood(xml); + // item->setMood(mood); + return true; +} + +bool PluginManager::setTune(int account, const QString& jid, const QString& tune) { + // OkAccount *pa = accountIds_.account(account); + // if (!pa) + // return false; + // + // XMPP::Jid userJid(jid); + // UserListItem *item = pa->userList()->find(userJid); + // + // if (!item) + // return false; + // + // item->setTune(tune); + return true; +} + +void PluginManager::initPopup(const QString& text, const QString& title, const QString& icon, + int type) { + // const PsiIcon *ico = IconsetFactory::iconPtr(icon); + // psi_->popupManager()->doPopup(nullptr, Jid(), ico, title, QPixmap(), + // nullptr, + // text, true, PopupManager::PopupType(type)); +} + +void PluginManager::initPopupForJid(int account, const QString& jid, const QString& text, + const QString& title, const QString& icon, int type) { + // XMPP::Jid j(jid); + // const PsiIcon *ico = IconsetFactory::iconPtr(icon); + // OkAccount *pa = accountIds_.account(account); + // if (pa) { + // UserListItem *i = pa->findFirstRelevant(j); + // PsiIcon *statusIco = PsiIconset::instance()->statusPtr(i); + // const QPixmap pix = pa->avatarFactory()->getAvatar(j); + // psi_->popupManager()->doPopup(pa, j, ico, title, pix, statusIco, text, + // true, + // PopupManager::PopupType(type)); + // return; + // } + // psi_->popupManager()->doPopup(nullptr, Jid(), ico, title, QPixmap(), + // nullptr, + // text, true, PopupManager::PopupType(type)); +} + +int PluginManager::registerOption(const QString& name, int initValue, const QString& path) { + // return psi_->popupManager()->registerOption(name, initValue, path); + return 0; +} + +void PluginManager::unregisterOption(const QString& name) { + // psi_->popupManager()->unregisterOption(name); +} + +int PluginManager::popupDuration(const QString& name) const { + return 0; + // return psi_->popupManager()->value(name); +} + +void PluginManager::setPopupDuration(const QString& name, int value) { + // psi_->popupManager()->setValue(name, value); +} + +void PluginManager::addAccountMenu(QMenu* menu, OkAccount* account) { + int i = accountIds_.id(account); + for (PluginHost* host : qAsConst(pluginsByPriority_)) { + host->addAccountMenu(menu, i); + } +} + +void PluginManager::addContactMenu(QMenu* menu, OkAccount* account, QString jid) { + int i = accountIds_.id(account); + for (PluginHost* host : qAsConst(pluginsByPriority_)) { + host->addContactMenu(menu, i, jid); } - } - return handled; } -bool PluginManager::hasInfoProvider(const QString &plugin) const { - if (hosts_.contains(plugin)) - return hosts_[plugin]->hasInfoProvider(); +void PluginManager::setupChatTab(QWidget* tab, OkAccount* account, const QString& contact) { + int i = accountIds_.id(account); + for (PluginHost* host : qAsConst(pluginsByPriority_)) { + host->setupChatTab(tab, i, contact); + } +} - return false; +void PluginManager::setupGCTab(QWidget* tab, OkAccount* account, const QString& contact) { + int i = accountIds_.id(account); + for (PluginHost* host : qAsConst(pluginsByPriority_)) { + host->setupGCTab(tab, i, contact); + } } -QString PluginManager::pluginInfo(const QString &plugin) const { - auto it = hosts_.find(plugin); - if (it == hosts_.end()) - return QString(); - QString info = it.value()->pluginInfo(); - if (info.isEmpty()) - info = it.value()->description(); - return info; +bool PluginManager::appendingChatMessage(OkAccount* account, const QString& contact, QString& body, + QDomElement& html, bool local) { + bool handled = false; + for (PluginHost* host : qAsConst(pluginsByPriority_)) { + if (host->appendingChatMessage(accountIds_.id(account), contact, body, html, local)) { + handled = true; + break; + } + } + return handled; +} + +bool PluginManager::hasInfoProvider(const QString& plugin) const { + if (hosts_.contains(plugin)) return hosts_[plugin]->hasInfoProvider(); + + return false; +} + +QString PluginManager::pluginInfo(const QString& plugin) const { + auto it = hosts_.find(plugin); + if (it == hosts_.end()) return QString(); + QString info = it.value()->pluginInfo(); + if (info.isEmpty()) info = it.value()->description(); + return info; } -QIcon PluginManager::icon(const QString &plugin) const { - QIcon icon; - if (hosts_.contains(plugin)) { - icon = hosts_[plugin]->icon(); - } +QIcon PluginManager::icon(const QString& plugin) const { + QIcon icon; + if (hosts_.contains(plugin)) { + icon = hosts_[plugin]->icon(); + } - return icon; + return icon; } QStringList PluginManager::pluginFeatures() const { - QStringList features; - for (PluginHost *host : pluginByFile_) { - features << host->pluginFeatures(); - } - return features; + QStringList features; + for (PluginHost* host : pluginByFile_) { + features << host->pluginFeatures(); + } + return features; } /** * Tells the plugin manager about add the client OkAccount */ -int PluginManager::addAccount(OkAccount *account, - ::lib::messenger::Messenger *messenger) { - - if(QThread::currentThread() != m_thread.get()){ - int ret; - QMetaObject::invokeMethod(this, "addAccount", - Qt::BlockingQueuedConnection, - Q_RETURN_ARG(int, ret), - Q_ARG(OkAccount *, account), - Q_ARG(::lib::messenger::Messenger *, messenger)); - return ret; - } - - if (clients_.isEmpty()) { - clients_.append(messenger); - const int id = accountIds_.appendAccount(account); - if (!streamWatcher) { - streamWatcher = new StreamWatcher(messenger, this, id); - // this StreamWatcher instance isn't stored anywhere - // and probably leaks (if go(true) isn't called somewhere else) - connect(account, SIGNAL(accountDestroyed()), this, SLOT(accountDestroyed())); +int PluginManager::addAccount(OkAccount* account, ::lib::messenger::Messenger* messenger) { + if (QThread::currentThread() != m_thread.get()) { + int ret; + QMetaObject::invokeMethod(this, "addAccount", Qt::BlockingQueuedConnection, + Q_RETURN_ARG(int, ret), Q_ARG(OkAccount*, account), + Q_ARG(::lib::messenger::Messenger*, messenger)); + return ret; } - return id; - } - return 0; + + if (clients_.isEmpty()) { + clients_.append(messenger); + const int id = accountIds_.appendAccount(account); + if (!streamWatcher) { + streamWatcher = new StreamWatcher(messenger, this, id); + // this StreamWatcher instance isn't stored anywhere + // and probably leaks (if go(true) isn't called somewhere else) + connect(account, SIGNAL(accountDestroyed()), this, SLOT(accountDestroyed())); + } + return id; + } + return 0; } /** * Performs basic validity checking on a stanza * TODO : populate verifyStanza method and use it */ -bool PluginManager::verifyStanza(const QString &stanza) { - Q_UNUSED(stanza); - return true; +bool PluginManager::verifyStanza(const QString& stanza) { + Q_UNUSED(stanza); + return true; +} + +void PluginManager::applyOptions(const QString& plugin) { + auto host = hosts_.value(plugin); + if (host) { + host->applyOptions(); + } +} + +void PluginManager::restoreOptions(const QString& plugin) { + auto host = hosts_.value(plugin); + if (host) { + host->restoreOptions(); + } +} + +void PluginManager::addToolBarButton(QObject* parent, QWidget* toolbar, OkAccount* account, + const QString& contact, const QString& plugin) { + const int acc_id = accountIds_.id(account); + for (PluginHost* host : qAsConst(pluginsByPriority_)) { + if ((plugin.isEmpty() || (host->shortName() == plugin)) && host->isEnabled()) { + host->addToolBarButton(parent, toolbar, acc_id, contact); + } + } +} + +bool PluginManager::hasToolBarButton(const QString& plugin) const { + auto host = hosts_.value(plugin); + if (host && host->isEnabled()) return host->hasToolBarButton(); + return false; +} + +void PluginManager::addGCToolBarButton(QObject* parent, QWidget* toolbar, OkAccount* account, + const QString& contact, const QString& plugin) { + const int acc_id = accountIds_.id(account); + for (PluginHost* host : qAsConst(pluginsByPriority_)) { + if ((plugin.isEmpty() || (host->shortName() == plugin)) && host->isEnabled()) { + host->addGCToolBarButton(parent, toolbar, acc_id, contact); + } + } +} + +bool PluginManager::hasGCToolBarButton(const QString& plugin) const { + auto host = hosts_.value(plugin); + if (host && host->isEnabled()) return host->hasGCToolBarButton(); + return false; +} + +void PluginManager::setStatus(int account, const QString& status, const QString& statusMessage) { + // OkAccount *acc = accountIds_.account(account); + // if (acc) { + // XMPP::Status s(status, statusMessage); + // acc->setStatus(s, false, true); + // } +} + +void PluginManager::setPgpKey(int account, const QString& keyId) { + // OkAccount *pa = accountIds_.account(account); + // if (pa) { + // UserAccount acc = pa->userAccount(); + // acc.pgpSecretKey = keyId; + // pa->setUserAccount(acc); + // } +} + +void PluginManager::removeKnownPgpKey(int account, const QString& jid) { + // OkAccount *pa = accountIds_.account(account); + // if (pa) { + // pa->removeKnownPgpKey(jid); + // } +} + +void PluginManager::setClientVersionInfo(int account, const QVariantMap& info) { + // OkAccount *pa = accountIds_.account(account); + // if (pa) { + // pa->setClientVersionInfoMap(info); + // } +} + +bool PluginManager::appendSysMsg(int account, const QString& jid, const QString& message) { + // return appendMsgView(account, jid, MessageView::fromPlainText(message, + // MessageView::System)); + return false; +} + +bool PluginManager::appendSysHtmlMsg(int account, const QString& jid, const QString& message) { + // return appendMsgView(account, jid, MessageView::fromHtml(message, + // MessageView::System)); + return false; +} + +bool PluginManager::appendMsgView(int account, const QString& jid, const MessageView& message) { + // OkAccount *acc = accountIds_.account(account); + // if (acc) { + // XMPP::Jid j(jid); + // ChatDlg * chatDlg = acc->findChatDialogEx(j); + // if (!chatDlg) { + // chatDlg = acc->findChatDialog(j, false); + // } + // if (chatDlg) { + // chatDlg->dispatchMessage(message); + // return true; + // } + // auto gcDlg = acc->findDialog(jid); + // if (gcDlg) { + // gcDlg->dispatchMessage(message); + // return true; + // } + // } + return false; +} + +void PluginManager::createNewEvent(int account, const QString& jid, const QString& descr, + QObject* receiver, const char* slot) { + // OkAccount *acc = accountIds_.account(account); + // if (acc) { + // acc->createNewPluginEvent(account, jid, descr, receiver, slot); + // } +} + +void PluginManager::createNewMessageEvent(int account, QDomElement const& element) { + // OkAccount *acc = accountIds_.account(account); + // if (acc) { + // acc->createNewMessageEvent(element); + // } } -void PluginManager::applyOptions(const QString &plugin) { - auto host = hosts_.value(plugin); - if (host) { - host->applyOptions(); - } +QList PluginManager::globalAboutMenuActions() const { return QList(); } + +bool PluginManager::isSelf(int account, const QString& jid) const { + // OkAccount *acc = accountIds_.account(account); + // if (acc) { + // PsiContact *pc = acc->findContact(XMPP::Jid(jid)); + // if (pc) + // return pc->isSelf(); + // } + return false; +} + +bool PluginManager::isAgent(int account, const QString& jid) const { + // OkAccount *acc = accountIds_.account(account); + // if (acc) { + // PsiContact *pc = acc->findContact(XMPP::Jid(jid)); + // if (pc) + // return pc->isAgent(); + // } + return false; } -void PluginManager::restoreOptions(const QString &plugin) { - auto host = hosts_.value(plugin); - if (host) { - host->restoreOptions(); - } +bool PluginManager::inList(int account, const QString& jid) const { + // OkAccount *acc = accountIds_.account(account); + // if (acc) { + // PsiContact *pc = acc->findContact(XMPP::Jid(jid)); + // if (pc) + // return pc->inList(); + // } + return false; +} + +bool PluginManager::isPrivate(int account, const QString& jid) const { + // OkAccount *acc = accountIds_.account(account); + // if (acc) { + // PsiContact *pc = acc->findContact(XMPP::Jid(jid)); + // if (pc) + // return pc->isPrivate(); + // } + return false; +} + +bool PluginManager::isConference(int account, const QString& jid) const { + // OkAccount *acc = accountIds_.account(account); + // if (acc) { + // PsiContact *pc = acc->findContact(XMPP::Jid(jid)); + // if (pc) + // return pc->isConference(); + // } + return false; +} + +QString PluginManager::name(int account, const QString& jid) const { + // OkAccount *acc = accountIds_.account(account); + // if (acc) { + // PsiContact *pc = acc->findContact(XMPP::Jid(jid)); + // if (pc) + // return pc->name(); + // } + return QString(); } -void PluginManager::addToolBarButton(QObject *parent, QWidget *toolbar, - OkAccount *account, const QString &contact, - const QString &plugin) { - const int acc_id = accountIds_.id(account); - for (PluginHost *host : qAsConst(pluginsByPriority_)) { - if ((plugin.isEmpty() || (host->shortName() == plugin)) && - host->isEnabled()) { - host->addToolBarButton(parent, toolbar, acc_id, contact); +QString PluginManager::status(int account, const QString& jid) const { + // OkAccount *acc = accountIds_.account(account); + // if (acc) { + // PsiContact *pc = acc->findContact(XMPP::Jid(jid)); + // if (pc) + // return pc->status().typeString(); + // } + return QString(); +} + +QString PluginManager::statusMessage(int account, const QString& jid) const { + // OkAccount *acc = accountIds_.account(account); + // if (acc) { + // PsiContact *pc = acc->findContact(XMPP::Jid(jid)); + // if (pc) + // return pc->status().status(); + // } + return QString(); +} + +QStringList PluginManager::resources(int account, const QString& jid) const { + QStringList l; + // OkAccount *pa = accountIds_.account(account); + // if (pa) { + // UserListItem *u = pa->findFirstRelevant(XMPP::Jid(jid)); + // if (u) { + // QMutableListIterator i(u->userResourceList()); + // while (i.hasNext()) { + // l.push_back(i.next().name()); + // } + // } + // } + return l; +} + +QString PluginManager::realJid(int account, const QString& jid) const { + OkAccount* acc = accountIds_.account(account); + if (acc) { + ::base::Jid realJid = acc->realJid(::base::Jid(jid)); + return realJid.isNull() ? jid : realJid.full(); } - } + return jid; +} + +QString PluginManager::mucNick(int account, const QString& mucJid) const { + // OkAccount *acc = accountIds_.account(account); + // if (acc) { + // auto gcDlg = acc->findDialog(mucJid); + // if (gcDlg) { + // return gcDlg->nick(); + // } + // } + return ""; +} + +QStringList PluginManager::mucNicks(int account, const QString& mucJid) const { + // OkAccount *acc = accountIds_.account(account); + // if (acc) { + // auto gcDlg = acc->findDialog(mucJid); + // if (gcDlg) { + // return gcDlg->mucRosterContent(); + // } + // } + return {}; } -bool PluginManager::hasToolBarButton(const QString &plugin) const { - auto host = hosts_.value(plugin); - if (host && host->isEnabled()) - return host->hasToolBarButton(); - return false; +bool PluginManager::hasCaps(int account, const QString& jid, const QStringList& caps) { + // QStringList l; + // OkAccount *pa = accountIds_.account(account); + // if (pa) { + // return pa->client()->capsManager()->features(jid).test(caps); + // } + return false; } -void PluginManager::addGCToolBarButton(QObject *parent, QWidget *toolbar, - OkAccount *account, - const QString &contact, - const QString &plugin) { - const int acc_id = accountIds_.id(account); - for (PluginHost *host : qAsConst(pluginsByPriority_)) { - if ((plugin.isEmpty() || (host->shortName() == plugin)) && - host->isEnabled()) { - host->addGCToolBarButton(parent, toolbar, acc_id, contact); +bool PluginManager::decryptMessageElement(OkAccount* account, QDomElement& message) { + if (QThread::currentThread() != m_thread.get()) { + bool ret; + QMetaObject::invokeMethod(this, + "decryptMessageElement", + Qt::BlockingQueuedConnection, + Q_RETURN_ARG(bool, ret), + Q_ARG(OkAccount*, account), + Q_ARG(QDomElement&, message)); + return ret; + } + + for (auto const host : pluginByFile_) { + if (host->decryptMessageElement(accountIds_.id(account), message)) { + return true; + } } - } -} - -bool PluginManager::hasGCToolBarButton(const QString &plugin) const { - auto host = hosts_.value(plugin); - if (host && host->isEnabled()) - return host->hasGCToolBarButton(); - return false; -} - -void PluginManager::setStatus(int account, const QString &status, - const QString &statusMessage) { - // OkAccount *acc = accountIds_.account(account); - // if (acc) { - // XMPP::Status s(status, statusMessage); - // acc->setStatus(s, false, true); - // } -} - -void PluginManager::setPgpKey(int account, const QString &keyId) { - // OkAccount *pa = accountIds_.account(account); - // if (pa) { - // UserAccount acc = pa->userAccount(); - // acc.pgpSecretKey = keyId; - // pa->setUserAccount(acc); - // } -} - -void PluginManager::removeKnownPgpKey(int account, const QString &jid) { - // OkAccount *pa = accountIds_.account(account); - // if (pa) { - // pa->removeKnownPgpKey(jid); - // } -} - -void PluginManager::setClientVersionInfo(int account, const QVariantMap &info) { - // OkAccount *pa = accountIds_.account(account); - // if (pa) { - // pa->setClientVersionInfoMap(info); - // } -} - -bool PluginManager::appendSysMsg(int account, const QString &jid, - const QString &message) { - // return appendMsgView(account, jid, MessageView::fromPlainText(message, - // MessageView::System)); - return false; -} - -bool PluginManager::appendSysHtmlMsg(int account, const QString &jid, - const QString &message) { - // return appendMsgView(account, jid, MessageView::fromHtml(message, - // MessageView::System)); - return false; -} - -bool PluginManager::appendMsgView(int account, const QString &jid, - const MessageView &message) { - // OkAccount *acc = accountIds_.account(account); - // if (acc) { - // XMPP::Jid j(jid); - // ChatDlg * chatDlg = acc->findChatDialogEx(j); - // if (!chatDlg) { - // chatDlg = acc->findChatDialog(j, false); - // } - // if (chatDlg) { - // chatDlg->dispatchMessage(message); - // return true; - // } - // auto gcDlg = acc->findDialog(jid); - // if (gcDlg) { - // gcDlg->dispatchMessage(message); - // return true; - // } - // } - return false; -} - -void PluginManager::createNewEvent(int account, const QString &jid, - const QString &descr, QObject *receiver, - const char *slot) { - // OkAccount *acc = accountIds_.account(account); - // if (acc) { - // acc->createNewPluginEvent(account, jid, descr, receiver, slot); - // } -} - -void PluginManager::createNewMessageEvent(int account, - QDomElement const &element) { - // OkAccount *acc = accountIds_.account(account); - // if (acc) { - // acc->createNewMessageEvent(element); - // } -} - -QList PluginManager::globalAboutMenuActions() const { - return QList(); -} - -bool PluginManager::isSelf(int account, const QString &jid) const { - // OkAccount *acc = accountIds_.account(account); - // if (acc) { - // PsiContact *pc = acc->findContact(XMPP::Jid(jid)); - // if (pc) - // return pc->isSelf(); - // } - return false; -} - -bool PluginManager::isAgent(int account, const QString &jid) const { - // OkAccount *acc = accountIds_.account(account); - // if (acc) { - // PsiContact *pc = acc->findContact(XMPP::Jid(jid)); - // if (pc) - // return pc->isAgent(); - // } - return false; -} - -bool PluginManager::inList(int account, const QString &jid) const { - // OkAccount *acc = accountIds_.account(account); - // if (acc) { - // PsiContact *pc = acc->findContact(XMPP::Jid(jid)); - // if (pc) - // return pc->inList(); - // } - return false; -} - -bool PluginManager::isPrivate(int account, const QString &jid) const { - // OkAccount *acc = accountIds_.account(account); - // if (acc) { - // PsiContact *pc = acc->findContact(XMPP::Jid(jid)); - // if (pc) - // return pc->isPrivate(); - // } - return false; -} - -bool PluginManager::isConference(int account, const QString &jid) const { - // OkAccount *acc = accountIds_.account(account); - // if (acc) { - // PsiContact *pc = acc->findContact(XMPP::Jid(jid)); - // if (pc) - // return pc->isConference(); - // } - return false; -} - -QString PluginManager::name(int account, const QString &jid) const { - // OkAccount *acc = accountIds_.account(account); - // if (acc) { - // PsiContact *pc = acc->findContact(XMPP::Jid(jid)); - // if (pc) - // return pc->name(); - // } - return QString(); -} - -QString PluginManager::status(int account, const QString &jid) const { - // OkAccount *acc = accountIds_.account(account); - // if (acc) { - // PsiContact *pc = acc->findContact(XMPP::Jid(jid)); - // if (pc) - // return pc->status().typeString(); - // } - return QString(); -} - -QString PluginManager::statusMessage(int account, const QString &jid) const { - // OkAccount *acc = accountIds_.account(account); - // if (acc) { - // PsiContact *pc = acc->findContact(XMPP::Jid(jid)); - // if (pc) - // return pc->status().status(); - // } - return QString(); -} - -QStringList PluginManager::resources(int account, const QString &jid) const { - QStringList l; - // OkAccount *pa = accountIds_.account(account); - // if (pa) { - // UserListItem *u = pa->findFirstRelevant(XMPP::Jid(jid)); - // if (u) { - // QMutableListIterator i(u->userResourceList()); - // while (i.hasNext()) { - // l.push_back(i.next().name()); - // } - // } - // } - return l; -} - -QString PluginManager::realJid(int account, const QString &jid) const { - OkAccount *acc = accountIds_.account(account); - if (acc) { - ::base::Jid realJid = acc->realJid(::base::Jid(jid)); - return realJid.isNull() ? jid : realJid.full(); - } - return jid; -} - -QString PluginManager::mucNick(int account, const QString &mucJid) const { - // OkAccount *acc = accountIds_.account(account); - // if (acc) { - // auto gcDlg = acc->findDialog(mucJid); - // if (gcDlg) { - // return gcDlg->nick(); - // } - // } - return ""; -} - -QStringList PluginManager::mucNicks(int account, const QString &mucJid) const { - // OkAccount *acc = accountIds_.account(account); - // if (acc) { - // auto gcDlg = acc->findDialog(mucJid); - // if (gcDlg) { - // return gcDlg->mucRosterContent(); - // } - // } - return {}; -} - -bool PluginManager::hasCaps(int account, const QString &jid, - const QStringList &caps) { - // QStringList l; - // OkAccount *pa = accountIds_.account(account); - // if (pa) { - // return pa->client()->capsManager()->features(jid).test(caps); - // } - return false; -} - -bool PluginManager::decryptMessageElement(OkAccount *account, - QDomElement &message) { - - if(QThread::currentThread() != m_thread.get()){ - bool ret; - QMetaObject::invokeMethod(this, - "decryptMessageElement", - Qt::BlockingQueuedConnection, - Q_RETURN_ARG(bool, ret), - Q_ARG(OkAccount *, account), - Q_ARG(QDomElement&, message)); - return ret; - } - - for (auto const host : pluginByFile_) { - if (host->decryptMessageElement(accountIds_.id(account), message)) { - return true; + return false; +} + +bool PluginManager::encryptMessageElement(OkAccount* account, QDomElement& message) { + if (QThread::currentThread() != m_thread.get()) { + bool ret; + QMetaObject::invokeMethod(this, + "encryptMessageElement", + Qt::BlockingQueuedConnection, + Q_RETURN_ARG(bool, ret), + Q_ARG(OkAccount*, account), + Q_ARG(QDomElement&, message)); + return ret; } - } - return false; -} - -bool PluginManager::encryptMessageElement(OkAccount *account, - QDomElement &message) { - if(QThread::currentThread() != m_thread.get()){ - bool ret; - QMetaObject::invokeMethod(this, - "encryptMessageElement", - Qt::BlockingQueuedConnection, - Q_RETURN_ARG(bool, ret), - Q_ARG(OkAccount *, account), - Q_ARG(QDomElement &, message)); - return ret; - } - - qDebug() << "encryptMessageElement:" << account->getUsername() << message.ownerDocument().toString(); - for (auto const host : pluginByFile_) { - if (host->encryptMessageElement(accountIds_.id(account), message)) { - qDebug() <<"Using plugin:"<shortName()<<"encryptMessageElement completed."; - return true; + + qDebug() << "encryptMessageElement:" << account->getUsername() + << message.ownerDocument().toString(); + for (auto const host : pluginByFile_) { + if (host->encryptMessageElement(accountIds_.id(account), message)) { + qDebug() << "Using plugin:" << host->shortName() << "encryptMessageElement completed."; + return true; + } } - } - qDebug() <<"Would not find suitable plugin!"; - return false; + qDebug() << "Would not find suitable plugin!"; + return false; } -int AccountIds::appendAccount(OkAccount *acc) { - int id = -1; - if (acc) { - id = id_keys.size(); - id_keys[id] = acc; - acc_keys[acc] = id; - } - return id; +int AccountIds::appendAccount(OkAccount* acc) { + int id = -1; + if (acc) { + id = id_keys.size(); + id_keys[id] = acc; + acc_keys[acc] = id; + } + return id; } -void AccountIds::removeAccount(ok::base::OkAccount *acc) { - int id = acc_keys.value(acc, -1); - if (id != -1) { - acc_keys.remove(acc); - id_keys[id] = nullptr; - } +void AccountIds::removeAccount(ok::base::OkAccount* acc) { + int id = acc_keys.value(acc, -1); + if (id != -1) { + acc_keys.remove(acc); + id_keys[id] = nullptr; + } } void AccountIds::clear() { - acc_keys.clear(); - id_keys.clear(); + acc_keys.clear(); + id_keys.clear(); } -OkAccount *AccountIds::account(int id) const { - return id_keys.value(id, nullptr); -} +OkAccount* AccountIds::account(int id) const { return id_keys.value(id, nullptr); } -int AccountIds::id(OkAccount *acc) const { return acc_keys.value(acc, -1); } +int AccountIds::id(OkAccount* acc) const { return acc_keys.value(acc, -1); } -PluginManager *PluginManager::instance_ = nullptr; +PluginManager* PluginManager::instance_ = nullptr; const QString PluginManager::loadOptionPrefix = "plugins.auto-load"; const QString PluginManager::pluginOptionPrefix = "plugins.options"; -PluginHost *PluginManager::plugin(const QString &name) const { - return hosts_.value(name); -} +PluginHost* PluginManager::plugin(const QString& name) const { return hosts_.value(name); } -} // namespace plugin -} // namespace ok +} // namespace plugin +} // namespace ok diff --git a/src/lib/plugin/pluginmanager.h b/src/lib/plugin/pluginmanager.h index c715601b..5c0b00f0 100644 --- a/src/lib/plugin/pluginmanager.h +++ b/src/lib/plugin/pluginmanager.h @@ -27,7 +27,7 @@ namespace lib { namespace messenger { class Messenger; } -} // namespace lib +} // namespace lib namespace ok { @@ -57,239 +57,223 @@ namespace PsiMedia { class Provider; } - - using namespace ok::base; class AccountIds { public: - int appendAccount(OkAccount *acc); - void removeAccount(OkAccount *acc); - void clear(); - bool isValidRange(int id) const { - return id_keys.contains(id); - } - OkAccount *account(int id) const; - int id(OkAccount *acc) const; + int appendAccount(OkAccount* acc); + void removeAccount(OkAccount* acc); + void clear(); + bool isValidRange(int id) const { return id_keys.contains(id); } + OkAccount* account(int id) const; + int id(OkAccount* acc) const; private: - QHash acc_keys; - QHash id_keys; + QHash acc_keys; + QHash id_keys; }; class PluginManager : public QObject { - Q_OBJECT + Q_OBJECT public: - static PluginManager *instance(); - void initNewSession(PsiCon *psi); - - QStringList pluginDirs(); - QStringList availablePlugins() const; - PluginHost *plugin(const QString &name) const; - - /** - * install & uninstall plugins - * @param file - * @return - */ - bool installPlugin(const QString &filePath, - const QString &fileName); - - bool uninstallPlugin(const QString &shortName); - - - void loadEnabledPlugins(); - bool unloadAllPlugins(); - - bool isAvailable(const QString &plugin) const; - bool isEnabled(const QString &plugin) const; - QString pathToPlugin(const QString &plugin) const; - QString shortName(const QString &plugin) const; - QString pluginName(const QString &shortName) const; - QString version(const QString &plugin) const; - QString vendor(const QString &plugin) const; - QString description(const QString &plugin) const; - QWidget *optionsWidget(const QString &plugin); - - void setShortcuts(); - - bool processEvent(OkAccount *account, QDomElement &eventXml); - bool processMessage(OkAccount *account, const QString &jidFrom, - const QString &body, const QString &subject); - bool processOutgoingMessage(OkAccount *account, const QString &jidTo, - QString &body, const QString &type, - QString &subject); - void processOutgoingStanza(OkAccount *account, QDomElement &stanza); - void startLogin(OkAccount *account); - void logout(OkAccount *account); - - void addSettingPage(OAH_PluginOptionsTab *tab); - void removeSettingPage(OAH_PluginOptionsTab *tab); - QList settingsPages() const; - void applyOptions(const QString &plugin); - void restoreOptions(const QString &plugin); - void addToolBarButton(QObject *parent, QWidget *toolbar, OkAccount *account, - const QString &contact, const QString &plugin = ""); - bool hasToolBarButton(const QString &plugin) const; - void addGCToolBarButton(QObject *parent, QWidget *toolbar, OkAccount *account, - const QString &contact, const QString &plugin = ""); - bool hasGCToolBarButton(const QString &plugin) const; - void addAccountMenu(QMenu *menu, OkAccount *account); - void addContactMenu(QMenu *menu, OkAccount *account, QString jid); - - void setupChatTab(QWidget *tab, OkAccount *account, const QString &contact); - void setupGCTab(QWidget *tab, OkAccount *account, const QString &contact); - bool appendingChatMessage(OkAccount *account, const QString &contact, - QString &body, QDomElement &html, bool local); - - QString pluginInfo(const QString &plugin) const; - bool hasInfoProvider(const QString &plugin) const; - QIcon icon(const QString &plugin) const; - QStringList pluginFeatures() const; - - - - QList globalAboutMenuActions() const; - - static const QString loadOptionPrefix; - static const QString pluginOptionPrefix; + static PluginManager* instance(); + void initNewSession(PsiCon* psi); + + QStringList pluginDirs(); + QStringList availablePlugins() const; + PluginHost* plugin(const QString& name) const; + + /** + * install & uninstall plugins + * @param file + * @return + */ + bool installPlugin(const QString& filePath, const QString& fileName); + + bool uninstallPlugin(const QString& shortName); + + void loadEnabledPlugins(); + bool unloadAllPlugins(); + + bool isAvailable(const QString& plugin) const; + bool isEnabled(const QString& plugin) const; + QString pathToPlugin(const QString& plugin) const; + QString shortName(const QString& plugin) const; + QString pluginName(const QString& shortName) const; + QString version(const QString& plugin) const; + QString vendor(const QString& plugin) const; + QString description(const QString& plugin) const; + QWidget* optionsWidget(const QString& plugin); + + void setShortcuts(); + + bool processEvent(OkAccount* account, QDomElement& eventXml); + bool processMessage(OkAccount* account, const QString& jidFrom, const QString& body, + const QString& subject); + bool processOutgoingMessage(OkAccount* account, const QString& jidTo, QString& body, + const QString& type, QString& subject); + void processOutgoingStanza(OkAccount* account, QDomElement& stanza); + void startLogin(OkAccount* account); + void logout(OkAccount* account); + + void addSettingPage(OAH_PluginOptionsTab* tab); + void removeSettingPage(OAH_PluginOptionsTab* tab); + QList settingsPages() const; + void applyOptions(const QString& plugin); + void restoreOptions(const QString& plugin); + void addToolBarButton(QObject* parent, QWidget* toolbar, OkAccount* account, + const QString& contact, const QString& plugin = ""); + bool hasToolBarButton(const QString& plugin) const; + void addGCToolBarButton(QObject* parent, QWidget* toolbar, OkAccount* account, + const QString& contact, const QString& plugin = ""); + bool hasGCToolBarButton(const QString& plugin) const; + void addAccountMenu(QMenu* menu, OkAccount* account); + void addContactMenu(QMenu* menu, OkAccount* account, QString jid); + + void setupChatTab(QWidget* tab, OkAccount* account, const QString& contact); + void setupGCTab(QWidget* tab, OkAccount* account, const QString& contact); + bool appendingChatMessage(OkAccount* account, const QString& contact, QString& body, + QDomElement& html, bool local); + + QString pluginInfo(const QString& plugin) const; + bool hasInfoProvider(const QString& plugin) const; + QIcon icon(const QString& plugin) const; + QStringList pluginFeatures() const; + + QList globalAboutMenuActions() const; + + static const QString loadOptionPrefix; + static const QString pluginOptionPrefix; signals: - void jsFiltersUpdated(); - void accountBeforeLogin(int account_id); - void accountLoggedOut(int account_id); - void pluginEnabled(const QString &shortName); - void pluginDisabled(const QString &shortName); + void jsFiltersUpdated(); + void accountBeforeLogin(int account_id); + void accountLoggedOut(int account_id); + void pluginEnabled(const QString& shortName); + void pluginDisabled(const QString& shortName); private: - PluginManager(); - PsiCon *psi_; - void loadAllPlugins(); - bool verifyStanza(const QString &stanza); - QList updatePluginsList(); - void loadPluginIfEnabled(PluginHost *host); - PluginHost * addHostFile(const QString &file); - void removeHostFile(PluginHost *host); - - static PluginManager *instance_; - - //plugin manager thread - std::unique_ptr m_thread; - - // account id, client - QVector<::lib::messenger::Messenger *> clients_; - - // account, account id - AccountIds accountIds_; - - // shortName, host - QMap hosts_; - // file, host - QMap pluginByFile_; - // sorted by priority - QList pluginsByPriority_; - - QList dirWatchers_; - - // Options widget provides by plugin on opt_plugins - QPointer optionsWidget_; - QList - settingsTabs_; // to be inserted into global list - - // QMultiMap> - // _messageViewJSFilters; // priority -> - QTimer *_messageViewJSFiltersTimer = nullptr; - - class StreamWatcher; - - StreamWatcher* streamWatcher = nullptr; - - bool incomingXml(int account, const QDomElement &xml); - void sendXml(int account, const QString &xml); - QString uniqueId(int account) const; - - QString getStatus(int account) const; - QString getStatusMessage(int account) const; - QString proxyHost(int account) const; - int proxyPort(int account) const; - QString proxyUser(int account) const; - QString proxyPassword(int account) const; - QStringList getRoster(int account) const; - QString getJid(int account) const; - QString getId(int account) const; - QString getName(int account) const; - int findOnlineAccountForContact(const QString &jid) const; - QString getPgpKey(int account) const; - QMap getKnownPgpKeys(int account) const; - - bool isSelf(int account, const QString &jid) const; - bool isAgent(int account, const QString &jid) const; - bool inList(int account, const QString &jid) const; - bool isPrivate(int account, const QString &jid) const; - bool isConference(int account, const QString &jid) const; - QString name(int account, const QString &jid) const; - QString status(int account, const QString &jid) const; - QString statusMessage(int account, const QString &jid) const; - QStringList resources(int account, const QString &jid) const; - QString realJid(int account, const QString &jid) const; - QString mucNick(int account, const QString &mucJid) const; - QStringList mucNicks(int account, const QString &mucJid) const; - bool hasCaps(int account, const QString &jid, const QStringList &caps); - - bool setActivity(int account, const QString &Jid, QDomElement xml); - bool setMood(int account, const QString &Jid, QDomElement xml); - bool setTune(int account, const QString &Jid, const QString &tune); - - void initPopup(const QString &text, const QString &title, const QString &icon, - int type); - void initPopupForJid(int account, const QString &jid, const QString &text, - const QString &title, const QString &icon, int tipe); - int registerOption(const QString &name, int initValue = 5, - const QString &path = QString()); - void unregisterOption(const QString &name); - int popupDuration(const QString &name) const; - void setPopupDuration(const QString &name, int value); - - void setStatus(int account, const QString &status, - const QString &statusMessage); - void setPgpKey(int account, const QString &keyId); - void removeKnownPgpKey(int account, const QString &jid); - void setClientVersionInfo(int account, const QVariantMap &info); - - bool appendSysMsg(int account, const QString &jid, const QString &message); - bool appendSysHtmlMsg(int account, const QString &jid, - const QString &message); - - void createNewEvent(int account, const QString &jid, const QString &descr, - QObject *receiver, const char *slot); - void createNewMessageEvent(int account, QDomElement const &element); - - void updateFeatures(); - - // QString installChatLogJSDataFilter( - // const QString &js, - // OkPlugin::Priority priority = OkPlugin::PriorityNormal); - - void uninstallChatLogJSDataFilter(const QString &id); - - friend class PluginHost; + PluginManager(); + PsiCon* psi_; + void loadAllPlugins(); + bool verifyStanza(const QString& stanza); + QList updatePluginsList(); + void loadPluginIfEnabled(PluginHost* host); + PluginHost* addHostFile(const QString& file); + void removeHostFile(PluginHost* host); + + static PluginManager* instance_; + + // plugin manager thread + std::unique_ptr m_thread; + + // account id, client + QVector<::lib::messenger::Messenger*> clients_; + + // account, account id + AccountIds accountIds_; + + // shortName, host + QMap hosts_; + // file, host + QMap pluginByFile_; + // sorted by priority + QList pluginsByPriority_; + + QList dirWatchers_; + + // Options widget provides by plugin on opt_plugins + QPointer optionsWidget_; + QList settingsTabs_; // to be inserted into global list + + // QMultiMap> + // _messageViewJSFilters; // priority -> + QTimer* _messageViewJSFiltersTimer = nullptr; + + class StreamWatcher; + + StreamWatcher* streamWatcher = nullptr; + + bool incomingXml(int account, const QDomElement& xml); + void sendXml(int account, const QString& xml); + QString uniqueId(int account) const; + + QString getStatus(int account) const; + QString getStatusMessage(int account) const; + QString proxyHost(int account) const; + int proxyPort(int account) const; + QString proxyUser(int account) const; + QString proxyPassword(int account) const; + QStringList getRoster(int account) const; + QString getJid(int account) const; + QString getId(int account) const; + QString getName(int account) const; + int findOnlineAccountForContact(const QString& jid) const; + QString getPgpKey(int account) const; + QMap getKnownPgpKeys(int account) const; + + bool isSelf(int account, const QString& jid) const; + bool isAgent(int account, const QString& jid) const; + bool inList(int account, const QString& jid) const; + bool isPrivate(int account, const QString& jid) const; + bool isConference(int account, const QString& jid) const; + QString name(int account, const QString& jid) const; + QString status(int account, const QString& jid) const; + QString statusMessage(int account, const QString& jid) const; + QStringList resources(int account, const QString& jid) const; + QString realJid(int account, const QString& jid) const; + QString mucNick(int account, const QString& mucJid) const; + QStringList mucNicks(int account, const QString& mucJid) const; + bool hasCaps(int account, const QString& jid, const QStringList& caps); + + bool setActivity(int account, const QString& Jid, QDomElement xml); + bool setMood(int account, const QString& Jid, QDomElement xml); + bool setTune(int account, const QString& Jid, const QString& tune); + + void initPopup(const QString& text, const QString& title, const QString& icon, int type); + void initPopupForJid(int account, const QString& jid, const QString& text, const QString& title, + const QString& icon, int tipe); + int registerOption(const QString& name, int initValue = 5, const QString& path = QString()); + void unregisterOption(const QString& name); + int popupDuration(const QString& name) const; + void setPopupDuration(const QString& name, int value); + + void setStatus(int account, const QString& status, const QString& statusMessage); + void setPgpKey(int account, const QString& keyId); + void removeKnownPgpKey(int account, const QString& jid); + void setClientVersionInfo(int account, const QVariantMap& info); + + bool appendSysMsg(int account, const QString& jid, const QString& message); + bool appendSysHtmlMsg(int account, const QString& jid, const QString& message); + + void createNewEvent(int account, const QString& jid, const QString& descr, QObject* receiver, + const char* slot); + void createNewMessageEvent(int account, QDomElement const& element); + + void updateFeatures(); + + // QString installChatLogJSDataFilter( + // const QString &js, + // OkPlugin::Priority priority = OkPlugin::PriorityNormal); + + void uninstallChatLogJSDataFilter(const QString& id); + + friend class PluginHost; private: - bool appendMsgView(int account, const QString &jid, - const MessageView &message); + bool appendMsgView(int account, const QString& jid, const MessageView& message); signals: private slots: - void dirsChanged(); - void optionChanged(const QString &option); - void accountDestroyed(); + void dirsChanged(); + void optionChanged(const QString& option); + void accountDestroyed(); public slots: - int addAccount(OkAccount* account, ::lib::messenger::Messenger *messenger); - bool decryptMessageElement(OkAccount *account, QDomElement &message) ; - bool encryptMessageElement(OkAccount *account, QDomElement &message) ; - + int addAccount(OkAccount* account, ::lib::messenger::Messenger* messenger); + bool decryptMessageElement(OkAccount* account, QDomElement& message); + bool encryptMessageElement(OkAccount* account, QDomElement& message); }; -} // namespace plugin -} // namespace ok -#endif // PLUGINMANAGER_H +} // namespace plugin +} // namespace ok +#endif // PLUGINMANAGER_H diff --git a/src/lib/plugin/textutil.cpp b/src/lib/plugin/textutil.cpp index 45406355..530802b7 100644 --- a/src/lib/plugin/textutil.cpp +++ b/src/lib/plugin/textutil.cpp @@ -15,17 +15,15 @@ #include "coloropt.h" #include "common.h" -#include "ok_iconset.h" #include "OkOptions.h" +#include "ok_iconset.h" - -#include // for escape() +#include // for escape() // With Qt4 this func was more complex. Now we don't need it -QString TextUtil::escape(const QString &plain) { return plain.toHtmlEscaped(); } +QString TextUtil::escape(const QString& plain) { return plain.toHtmlEscaped(); } -QString TextUtil::unescape(const QString &escaped) -{ +QString TextUtil::unescape(const QString& escaped) { QString plain = escaped; plain.replace("<", "<"); plain.replace(">", ">"); @@ -34,21 +32,20 @@ QString TextUtil::unescape(const QString &escaped) return plain; } -QString TextUtil::quote(const QString &toquote, int width, bool quoteEmpty) -{ +QString TextUtil::quote(const QString& toquote, int width, bool quoteEmpty) { int ql = 0, col = 0, atstart = 1, ls = 0; - QString quoted = "> " + toquote; // quote first line - QString rxs = quoteEmpty ? "\n" : "\n(?!\\s*\n)"; - QRegExp rx(rxs); // quote following lines + QString quoted = "> " + toquote; // quote first line + QString rxs = quoteEmpty ? "\n" : "\n(?!\\s*\n)"; + QRegExp rx(rxs); // quote following lines quoted.replace(rx, "\n> "); - rx.setPattern("> +>"); // compress > > > > quotes to >>>> + rx.setPattern("> +>"); // compress > > > > quotes to >>>> quoted.replace(rx, ">>"); quoted.replace(rx, ">>"); - quoted.replace(QRegExp(" +\n"), "\n"); // remove trailing spaces + quoted.replace(QRegExp(" +\n"), "\n"); // remove trailing spaces if (!quoteEmpty) { - quoted.replace(QRegExp("^>+\n"), "\n\n"); // unquote empty lines + quoted.replace(QRegExp("^>+\n"), "\n\n"); // unquote empty lines quoted.replace(QRegExp("\n>+\n"), "\n\n"); } @@ -60,26 +57,25 @@ QString TextUtil::quote(const QString &toquote, int width, bool quoteEmpty) atstart = 0; switch (quoted[i].toLatin1()) { - case '\n': - ql = col = 0; - atstart = 1; - break; - case ' ': - case '\t': - ls = i; - break; + case '\n': + ql = col = 0; + atstart = 1; + break; + case ' ': + case '\t': + ls = i; + break; } if (quoted[i] == '\n') { - ql = 0; + ql = 0; atstart = 1; } if (col > width) { if ((ls + width) < i) { ls = i; - i = quoted.length(); - while ((ls < i) && !quoted[ls].isSpace()) - ls++; + i = quoted.length(); + while ((ls < i) && !quoted[ls].isSpace()) ls++; i = ls; } if ((i < int(quoted.length())) && (quoted[ls] != '\n')) { @@ -91,26 +87,25 @@ QString TextUtil::quote(const QString &toquote, int width, bool quoteEmpty) } } } - quoted += "\n\n"; // add two empty lines to quoted text - the cursor - // will be positioned at the end of those. + quoted += "\n\n"; // add two empty lines to quoted text - the cursor + // will be positioned at the end of those. return quoted; } -QString TextUtil::plain2rich(const QString &plain) -{ +QString TextUtil::plain2rich(const QString& plain) { QString rich; - int col = 0; + int col = 0; for (int i = 0; i < int(plain.length()); ++i) { #ifdef Q_OS_WIN if (plain[i] == '\r' && i + 1 < (int)plain.length() && plain[i + 1] == '\n') - ++i; // Qt/Win sees \r\n as two new line chars + ++i; // Qt/Win sees \r\n as two new line chars #endif if (plain[i] == '\n') { rich += "
"; col = 0; } else if (plain[i] == ' ' && !rich.isEmpty() && rich[rich.size() - 1] == ' ') - rich += " "; // instead of pre-wrap, which prewraps \n as well + rich += " "; // instead of pre-wrap, which prewraps \n as well else if (plain[i] == '\t') rich += "      "; else if (plain[i] == '<') @@ -132,8 +127,7 @@ QString TextUtil::plain2rich(const QString &plain) // return "" + rich + ""; } -QString TextUtil::rich2plain(const QString &in, bool collapseSpaces) -{ +QString TextUtil::rich2plain(const QString& in, bool collapseSpaces) { QString out; for (int i = 0; i < int(in.length()); ++i) { @@ -142,10 +136,9 @@ QString TextUtil::rich2plain(const QString &in, bool collapseSpaces) // find end of tag ++i; int n = in.indexOf('>', i); - if (n == -1) - break; + if (n == -1) break; QString str = in.mid(i, (n - i)); - i = n; + i = n; QString tagName; n = str.indexOf(' '); @@ -154,8 +147,7 @@ QString TextUtil::rich2plain(const QString &in, bool collapseSpaces) else tagName = str; - if (tagName == "br") - out += '\n'; + if (tagName == "br") out += '\n'; // handle output of Qt::convertFromPlainText() correctly if ((tagName == "p" || tagName == "/p" || tagName == "div") && out.length() > 0) @@ -166,10 +158,9 @@ QString TextUtil::rich2plain(const QString &in, bool collapseSpaces) // find a semicolon ++i; int n = in.indexOf(';', i); - if (n == -1) - break; + if (n == -1) break; QString type = in.mid(i, (n - i)); - i = n; // should be n+1, but we'll let the loop increment do it + i = n; // should be n+1, but we'll let the loop increment do it if (type == "amp") out += '&'; @@ -189,11 +180,9 @@ QString TextUtil::rich2plain(const QString &in, bool collapseSpaces) out += ' '; else { QChar last = out.at(out.length() - 1); - bool ok = true; - if (last.isSpace() && last != '\n') - ok = false; - if (ok) - out += ' '; + bool ok = true; + if (last.isSpace() && last != '\n') ok = false; + if (ok) out += ' '; } } } else { @@ -204,8 +193,7 @@ QString TextUtil::rich2plain(const QString &in, bool collapseSpaces) return out; } -QString TextUtil::resolveEntities(const QStringRef &in) -{ +QString TextUtil::resolveEntities(const QStringRef& in) { QString out; for (int i = 0; i < int(in.length()); ++i) { @@ -213,11 +201,10 @@ QString TextUtil::resolveEntities(const QStringRef &in) // find a semicolon ++i; int n = in.indexOf(';', i); - if (n == -1) - break; + if (n == -1) break; QStringRef type = in.mid(i, (n - i)); - i = n; // should be n+1, but we'll let the loop increment do it + i = n; // should be n+1, but we'll let the loop increment do it if (type == "amp") out += '&'; @@ -239,32 +226,26 @@ QString TextUtil::resolveEntities(const QStringRef &in) return out; } -static bool linkify_pmatch(const QString &str1, int at, const QString &str2) -{ - if (str2.length() > (str1.length() - at)) - return false; +static bool linkify_pmatch(const QString& str1, int at, const QString& str2) { + if (str2.length() > (str1.length() - at)) return false; for (int n = 0; n < int(str2.length()); ++n) { - if (str1.at(n + at).toLower() != str2.at(n).toLower()) - return false; + if (str1.at(n + at).toLower() != str2.at(n).toLower()) return false; } return true; } -static bool linkify_isOneOf(const QChar &c, const QString &charlist) -{ +static bool linkify_isOneOf(const QChar& c, const QString& charlist) { for (int i = 0; i < int(charlist.length()); ++i) { - if (c == charlist.at(i)) - return true; + if (c == charlist.at(i)) return true; } return false; } // encodes a few dangerous html characters -static QString linkify_htmlsafe(const QString &in) -{ +static QString linkify_htmlsafe(const QString& in) { QString out; for (int n = 0; n < in.length(); ++n) { @@ -280,20 +261,16 @@ static QString linkify_htmlsafe(const QString &in) return out; } -static bool linkify_okUrl(const QString &url) { return !(url.at(url.length() - 1) == '.'); } +static bool linkify_okUrl(const QString& url) { return !(url.at(url.length() - 1) == '.'); } -static bool linkify_okEmail(const QString &addy) -{ +static bool linkify_okEmail(const QString& addy) { // this makes sure that there is an '@' and a '.' after it, and that there is // at least one char for each of the three sections int n = addy.indexOf('@'); - if (n == -1 || n == 0) - return false; + if (n == -1 || n == 0) return false; int d = addy.indexOf('.', n + 1); - if (d == -1 || d == 0) - return false; - if ((addy.length() - 1) - d <= 0) - return false; + if (d == -1 || d == 0) return false; + if ((addy.length() - 1) - d <= 0) return false; return addy.indexOf("..") == -1; } @@ -301,111 +278,109 @@ static bool linkify_okEmail(const QString &addy) * takes a richtext string and heuristically adds links for uris of common protocols * @return a richtext string with link markup added */ -QString TextUtil::linkify(const QString &in) -{ +QString TextUtil::linkify(const QString& in) { QString out = in; - int x1, x2; - bool isUrl, isAtStyle; + int x1, x2; + bool isUrl, isAtStyle; QString linked, link, href; for (int n = 0; n < int(out.length()); ++n) { - isUrl = false; + isUrl = false; isAtStyle = false; - x1 = n; + x1 = n; if (linkify_pmatch(out, n, "xmpp:")) { n += 5; isUrl = true; - href = ""; + href = ""; } else if (linkify_pmatch(out, n, "mailto:")) { n += 7; isUrl = true; - href = ""; + href = ""; } else if (linkify_pmatch(out, n, "http://")) { n += 7; isUrl = true; - href = ""; + href = ""; } else if (linkify_pmatch(out, n, "https://")) { n += 8; isUrl = true; - href = ""; + href = ""; } else if (linkify_pmatch(out, n, "git://")) { n += 6; isUrl = true; - href = ""; + href = ""; } else if (linkify_pmatch(out, n, "ftp://")) { n += 6; isUrl = true; - href = ""; + href = ""; } else if (linkify_pmatch(out, n, "ftps://")) { n += 7; isUrl = true; - href = ""; + href = ""; } else if (linkify_pmatch(out, n, "sftp://")) { n += 7; isUrl = true; - href = ""; + href = ""; } else if (linkify_pmatch(out, n, "news://")) { n += 7; isUrl = true; - href = ""; + href = ""; } else if (linkify_pmatch(out, n, "ed2k://")) { n += 7; isUrl = true; - href = ""; + href = ""; } else if (linkify_pmatch(out, n, "file://")) { n += 7; isUrl = true; - href = ""; + href = ""; } else if (linkify_pmatch(out, n, "magnet:")) { n += 7; isUrl = true; - href = ""; + href = ""; } else if (linkify_pmatch(out, n, "www.")) { isUrl = true; - href = "https://"; + href = "https://"; } else if (linkify_pmatch(out, n, "ftp.")) { isUrl = true; - href = "ftp://"; + href = "ftp://"; } else if (linkify_pmatch(out, n, "@")) { isAtStyle = true; - href = "x-psi-atstyle:"; + href = "x-psi-atstyle:"; } if (isUrl) { // make sure the previous char is not alphanumeric - if (x1 > 0 && out.at(x1 - 1).isLetterOrNumber()) - continue; + if (x1 > 0 && out.at(x1 - 1).isLetterOrNumber()) continue; // find whitespace (or end) QMap brackets; - brackets['('] = brackets[')'] = brackets['['] = brackets[']'] = brackets['{'] = brackets['}'] = 0; + brackets['('] = brackets[')'] = brackets['['] = brackets[']'] = brackets['{'] = + brackets['}'] = 0; QMap openingBracket; openingBracket[')'] = '('; openingBracket[']'] = '['; openingBracket['}'] = '{'; for (x2 = n; x2 < int(out.length()); ++x2) { - if (out.at(x2).isSpace() || linkify_isOneOf(out.at(x2), "\"\'`<>") || linkify_pmatch(out, x2, """) - || linkify_pmatch(out, x2, "'") || linkify_pmatch(out, x2, ">") - || linkify_pmatch(out, x2, "<")) { + if (out.at(x2).isSpace() || linkify_isOneOf(out.at(x2), "\"\'`<>") || + linkify_pmatch(out, x2, """) || linkify_pmatch(out, x2, "'") || + linkify_pmatch(out, x2, ">") || linkify_pmatch(out, x2, "<")) { break; } if (brackets.contains(out.at(x2))) { ++brackets[out.at(x2)]; } } - int len = x2 - x1; + int len = x2 - x1; QString pre = out.mid(x1, x2 - x1); - pre = resolveEntities(&pre); + pre = resolveEntities(&pre); // go backward hacking off unwanted punctuation int cutoff; for (cutoff = pre.length() - 1; cutoff >= 0; --cutoff) { - if (!linkify_isOneOf(pre.at(cutoff), "!?,.()[]{}<>\"")) - break; - if (linkify_isOneOf(pre.at(cutoff), ")]}") - && brackets[pre.at(cutoff)] - brackets[openingBracket[pre.at(cutoff)]] <= 0) { - break; // in theory, there could be == above, but these are urls, not math ;) + if (!linkify_isOneOf(pre.at(cutoff), "!?,.()[]{}<>\"")) break; + if (linkify_isOneOf(pre.at(cutoff), ")]}") && + brackets[pre.at(cutoff)] - brackets[openingBracket[pre.at(cutoff)]] <= 0) { + break; // in theory, there could be == above, but these are urls, not math ;) } if (brackets.contains(pre.at(cutoff))) { --brackets[pre.at(cutoff)]; @@ -428,7 +403,8 @@ QString TextUtil::linkify(const QString &in) linked = QString("").arg(href); #else auto linkColor = ColorOpt::instance()->color("options.ui.look.colors.messages.link"); - // we have visited link as well but it's no applicable to QTextEdit or we have to track visited manually + // we have visited link as well but it's no applicable to QTextEdit or we have to track + // visited manually linked = QString("").arg(href, linkColor.name()); #endif linked += (escape(link) + "" + escape(pre.mid(cutoff))); @@ -436,24 +412,21 @@ QString TextUtil::linkify(const QString &in) n = x1 + linked.length() - 1; } else if (isAtStyle) { // go backward till we find the beginning - if (x1 == 0) - continue; + if (x1 == 0) continue; --x1; for (; x1 >= 0; --x1) { - if (!linkify_isOneOf(out.at(x1), "_.-+") && !out.at(x1).isLetterOrNumber()) - break; + if (!linkify_isOneOf(out.at(x1), "_.-+") && !out.at(x1).isLetterOrNumber()) break; } ++x1; // go forward till we find the end x2 = n + 1; for (; x2 < int(out.length()); ++x2) { - if (!linkify_isOneOf(out.at(x2), "_.-+") && !out.at(x2).isLetterOrNumber()) - break; + if (!linkify_isOneOf(out.at(x2), "_.-+") && !out.at(x2).isLetterOrNumber()) break; } int len = x2 - x1; - link = out.mid(x1, len); + link = out.mid(x1, len); // link = resolveEntities(link); if (!linkify_okEmail(link)) { @@ -472,18 +445,16 @@ QString TextUtil::linkify(const QString &in) return out; } -QString TextUtil::img2title(const QString &in) -{ +QString TextUtil::img2title(const QString& in) { QString ret = in; - QRegExp rxq("]+title\\s*=\\s*'([^']+)'[^>]*>"), rxdq("]+title\\s*=\\s*\"([^\"]+)\"[^>]*>"); + QRegExp rxq("]+title\\s*=\\s*'([^']+)'[^>]*>"), + rxdq("]+title\\s*=\\s*\"([^\"]+)\"[^>]*>"); ret.replace(rxq, "\\1"); ret.replace(rxdq, "\\1"); return ret; } -QString TextUtil::legacyFormat(const QString &in) -{ - +QString TextUtil::legacyFormat(const QString& in) { // enable *bold* stuff // //old code // out=out.replace(QRegExp("(^[^<>\\s]*|\\s[^<>\\s]*)\\*(\\S+)\\*([^<>\\s]*\\s|[^<>\\s]*$)"),"\\1*\\2*\\3"); @@ -491,49 +462,49 @@ QString TextUtil::legacyFormat(const QString &in) // out=out.replace(QRegExp("(^[^<>\\s]*|\\s[^<>\\s]*)_(\\S+)_([^<>\\s]*\\s|[^<>\\s]*$)"),"\\1_\\2_\\3"); QString out = in; - out = out.replace(QRegExp("(^|\\s|>)_(\\S+)_(?=<|\\s|$)"), "\\1_\\2_"); // underline inside _text_ - out = out.replace(QRegExp("(^|\\s|>)\\*(\\S+)\\*(?=<|\\s|$)"), "\\1*\\2*"); // bold *text* - out = out.replace(QRegExp("(^|\\s|>)\\/(\\S+)\\/(?=<|\\s|$)"), "\\1/\\2/"); // italic /text/ + out = out.replace(QRegExp("(^|\\s|>)_(\\S+)_(?=<|\\s|$)"), + "\\1_\\2_"); // underline inside _text_ + out = out.replace(QRegExp("(^|\\s|>)\\*(\\S+)\\*(?=<|\\s|$)"), + "\\1*\\2*"); // bold *text* + out = out.replace(QRegExp("(^|\\s|>)\\/(\\S+)\\/(?=<|\\s|$)"), + "\\1/\\2/"); // italic /text/ return out; } -QString TextUtil::sizeUnit(qlonglong n, qlonglong *div) -{ +QString TextUtil::sizeUnit(qlonglong n, qlonglong* div) { qlonglong gb = 1024 * 1024 * 1024; qlonglong mb = 1024 * 1024; qlonglong kb = 1024; - QString unit; + QString unit; qlonglong d; if (n >= gb) { - d = gb; + d = gb; unit = QString("GB"); } else if (n >= mb) { - d = mb; + d = mb; unit = QString("MB"); } else if (n >= kb) { - d = kb; + d = kb; unit = QString("KB"); } else { - d = 1; + d = 1; unit = QString("B"); } - if (div) - *div = d; + if (div) *div = d; return unit; } -QString TextUtil::roundedNumber(qlonglong n, qlonglong div) -{ +QString TextUtil::roundedNumber(qlonglong n, qlonglong div) { bool decimal = false; if (div >= 1024) { div /= 10; decimal = true; } qlonglong x_long = n / div; - int x = int(x_long); + int x = int(x_long); if (decimal) { double f = double(x); f /= 10; diff --git a/src/lib/plugin/textutil.h b/src/lib/plugin/textutil.h index 6901d2e8..5e9f3c8f 100644 --- a/src/lib/plugin/textutil.h +++ b/src/lib/plugin/textutil.h @@ -20,23 +20,23 @@ class QStringRef; namespace TextUtil { -QString escape(const QString &plain); -QString unescape(const QString &escaped); +QString escape(const QString& plain); +QString unescape(const QString& escaped); -QString quote(const QString &, int width = 60, bool quoteEmpty = false); -QString plain2rich(const QString &); -QString rich2plain(const QString &, bool collapseSpaces = true); -QString resolveEntities(const QStringRef &); -QString linkify(const QString &); -QString legacyFormat(const QString &); -QString emoticonify(const QString &in); -QString img2title(const QString &in); +QString quote(const QString&, int width = 60, bool quoteEmpty = false); +QString plain2rich(const QString&); +QString rich2plain(const QString&, bool collapseSpaces = true); +QString resolveEntities(const QStringRef&); +QString linkify(const QString&); +QString legacyFormat(const QString&); +QString emoticonify(const QString& in); +QString img2title(const QString& in); -QString prepareMessageText(const QString &text, bool isEmote = false, bool isHtml = false); +QString prepareMessageText(const QString& text, bool isEmote = false, bool isHtml = false); -QString sizeUnit(qlonglong n, qlonglong *div = nullptr); +QString sizeUnit(qlonglong n, qlonglong* div = nullptr); QString roundedNumber(qlonglong n, qlonglong div); -} // namespace TextUtil +} // namespace TextUtil -#endif // TEXTUTIL_H +#endif // TEXTUTIL_H diff --git a/src/lib/plugin/varianttree.cpp b/src/lib/plugin/varianttree.cpp index f08a2eda..667959f0 100644 --- a/src/lib/plugin/varianttree.cpp +++ b/src/lib/plugin/varianttree.cpp @@ -25,21 +25,20 @@ // void VariantTree::variantToElement(const QVariant& var, QDomElement& e) // void VariantTree::elementToVariant(const QVariant& var, QDomElement& e) -QDomDocument *VariantTree::unknownsDoc = nullptr; +QDomDocument* VariantTree::unknownsDoc = nullptr; /** * Default Constructor */ -VariantTree::VariantTree(QObject *parent) : QObject(parent) { } +VariantTree::VariantTree(QObject* parent) : QObject(parent) {} /** * Default Destructor */ -VariantTree::~VariantTree() -{ - const auto &vTrees = trees_.values(); - for (VariantTree *vt : vTrees) { +VariantTree::~VariantTree() { + const auto& vTrees = trees_.values(); + for (VariantTree* vt : vTrees) { delete vt; } } @@ -51,36 +50,33 @@ VariantTree::~VariantTree() * @param rest part of the @a node after first dot * @return */ -bool VariantTree::getKeyRest(const QString &node, QString &key, QString &rest) -{ +bool VariantTree::getKeyRest(const QString& node, QString& key, QString& rest) { int idx = node.indexOf(QChar('.')); if (idx != -1) { - key = node.left(idx); + key = node.left(idx); rest = node.mid(idx + 1); return true; } return false; } -bool VariantTree::isValidNodeName(const QString &name) -{ +bool VariantTree::isValidNodeName(const QString& name) { /* XML backend: - [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' | CombiningChar | Extender - [5] Name ::= (Letter | '_' | ':') (NameChar)* - but we don't want to have namespaces in the node names.... + [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' | CombiningChar | + Extender [5] Name ::= (Letter | '_' | ':') (NameChar)* but we don't want to + have namespaces in the node names.... but for now just allow ascii subset of this: */ - if (name.isEmpty()) - return false; - int len = name.length(); + if (name.isEmpty()) return false; + int len = name.length(); QString other(".-_"); - QChar ch = name[0]; - if (!((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch == '_'))) - return false; + QChar ch = name[0]; + if (!((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch == '_'))) return false; for (int i = 1; i < len; i++) { ch = name[i]; - if (!((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (other.contains(ch)) || (ch >= '0' && ch <= '9'))) + if (!((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (other.contains(ch)) || + (ch >= '0' && ch <= '9'))) return false; } return true; @@ -89,15 +85,15 @@ bool VariantTree::isValidNodeName(const QString &name) /** * Set @a node to value @a value */ -void VariantTree::setValue(QString node, QVariant value) -{ +void VariantTree::setValue(QString node, QVariant value) { QString key, subnode; if (getKeyRest(node, key, subnode)) { // not this tier Q_ASSERT(isValidNodeName(key)); if (!trees_.contains(key)) { if (values_.contains(key)) { - qWarning("Error: Trying to add option node %s but it already exists as a value", qPrintable(key)); + qWarning("Error: Trying to add option node %s but it already exists as a value", + qPrintable(key)); return; } // create a new tier @@ -109,7 +105,8 @@ void VariantTree::setValue(QString node, QVariant value) // this tier Q_ASSERT(isValidNodeName(node)); if (trees_.contains(node)) { - qWarning("Error: Trying to add option value %s but it already exists as a subtree", qPrintable(node)); + qWarning("Error: Trying to add option value %s but it already exists as a subtree", + qPrintable(node)); return; } values_[node] = value; @@ -120,8 +117,7 @@ void VariantTree::setValue(QString node, QVariant value) * Get value at @a node * @return the value of @a node if @a node exists, otherwise VariantTree::missingValue */ -QVariant VariantTree::getValue(const QString &node) const -{ +QVariant VariantTree::getValue(const QString& node) const { QString key, subnode; if (getKeyRest(node, key, subnode)) { // not this tier @@ -132,14 +128,12 @@ QVariant VariantTree::getValue(const QString &node) const } else { // this tier auto it = values_.constFind(node); - if (it != values_.constEnd()) - return it.value(); + if (it != values_.constEnd()) return it.value(); } return missingValue; } -bool VariantTree::remove(const QString &node, bool internal_nodes) -{ +bool VariantTree::remove(const QString& node, bool internal_nodes) { QString key, subnode; if (getKeyRest(node, key, subnode)) { // not this tier @@ -147,7 +141,7 @@ bool VariantTree::remove(const QString &node, bool internal_nodes) return trees_[key]->remove(subnode, internal_nodes); } } else { - VariantTree *tree; + VariantTree* tree; // this tier if (values_.contains(node)) { values_.remove(node); @@ -163,8 +157,7 @@ bool VariantTree::remove(const QString &node, bool internal_nodes) /** * @return true iff the node @a node is an internal node (i.e. has a child tree). */ -bool VariantTree::isInternalNode(QString node) const -{ +bool VariantTree::isInternalNode(QString node) const { QString key, subnode; if (getKeyRest(node, key, subnode)) { // not this tier @@ -184,16 +177,16 @@ bool VariantTree::isInternalNode(QString node) const * \param name "Path" to the node * \param comment the comment to store */ -void VariantTree::setComment(QString node, QString comment) -{ +void VariantTree::setComment(QString node, QString comment) { if (node.contains(QChar('.'))) { // not this tier - QString key = node.left(node.indexOf(QChar('.'))); + QString key = node.left(node.indexOf(QChar('.'))); QString subnode = node.remove(0, node.indexOf(QChar('.')) + 1); Q_ASSERT(isValidNodeName(key)); if (!trees_.contains(key)) { if (values_.contains(key)) { - qWarning("Error: Trying to add option node %s but it already exists as a value", qPrintable(key)); + qWarning("Error: Trying to add option node %s but it already exists as a value", + qPrintable(key)); return; } // create a new tier @@ -212,14 +205,13 @@ void VariantTree::setComment(QString node, QString comment) * Returns the comment associated with a node. * (or a null QString if the node has no comment) */ -QString VariantTree::getComment(QString node) const -{ +QString VariantTree::getComment(QString node) const { int dotIdx = node.indexOf(QChar('.')); if (dotIdx != -1) { // not this tier - QString key = node.left(dotIdx); + QString key = node.left(dotIdx); QString subnode = node.remove(0, dotIdx + 1); - auto it = trees_.constFind(key); + auto it = trees_.constFind(key); if (it != trees_.constEnd()) { return it.value()->getComment(subnode); } @@ -236,16 +228,15 @@ QString VariantTree::getComment(QString node) const * \param direct only return direct children * \param internal_nodes include internal (non-final) nodes */ -QStringList VariantTree::nodeChildren(const QString &node, bool direct, bool internal_nodes) const -{ +QStringList VariantTree::nodeChildren(const QString& node, bool direct, bool internal_nodes) const { QStringList children; - QString key = node; + QString key = node; if (!node.isEmpty()) { // Go down further QString subnode; - int dotIdx = node.indexOf(QChar('.')); + int dotIdx = node.indexOf(QChar('.')); if (dotIdx != -1) { - key = node.left(dotIdx); + key = node.left(dotIdx); subnode = node.right(node.length() - dotIdx - 1); } if (trees_.contains(key)) { @@ -254,11 +245,9 @@ QStringList VariantTree::nodeChildren(const QString &node, bool direct, bool int } else { // Current tree for (auto it = trees_.constBegin(); it != trees_.constEnd(); ++it) { - if (internal_nodes) - children << it.key(); + if (internal_nodes) children << it.key(); - if (!direct) - children += nodeChildren(it.key(), direct, internal_nodes); + if (!direct) children += nodeChildren(it.key(), direct, internal_nodes); } for (auto it = values_.constBegin(); it != values_.constEnd(); ++it) { @@ -270,7 +259,7 @@ QStringList VariantTree::nodeChildren(const QString &node, bool direct, bool int return children; } else { QStringList long_children; - for (const QString &child : qAsConst(children)) { + for (const QString& child : qAsConst(children)) { QString long_child = QString("%1.%2").arg(key, child); long_children << long_child; } @@ -281,33 +270,30 @@ QStringList VariantTree::nodeChildren(const QString &node, bool direct, bool int /** * */ -void VariantTree::toXml(QDomDocument &doc, QDomElement &ele) const -{ +void VariantTree::toXml(QDomDocument& doc, QDomElement& ele) const { // Subtrees for (auto it = trees_.constBegin(); it != trees_.constEnd(); ++it) { Q_ASSERT(!it.key().isEmpty()); QDomElement nodeEle = doc.createElement(it.key()); it.value()->toXml(doc, nodeEle); auto cit = comments_.constFind(it.key()); - if (cit != comments_.constEnd()) - nodeEle.setAttribute("comment", cit.value()); + if (cit != comments_.constEnd()) nodeEle.setAttribute("comment", cit.value()); ele.appendChild(nodeEle); } // Values for (auto it = values_.constBegin(); it != values_.constEnd(); ++it) { Q_ASSERT(!it.key().isEmpty()); - QVariant var = it.value(); + QVariant var = it.value(); QDomElement valEle = doc.createElement(it.key()); variantToElement(var, valEle); ele.appendChild(valEle); auto cit = comments_.constFind(it.key()); - if (cit != comments_.constEnd()) - valEle.setAttribute("comment", cit.value()); + if (cit != comments_.constEnd()) valEle.setAttribute("comment", cit.value()); } // unknown types passthrough - for (const QDomDocumentFragment &df : unknowns_) { + for (const QDomDocumentFragment& df : unknowns_) { ele.appendChild(doc.importNode(df, true)); } } @@ -316,17 +302,15 @@ void VariantTree::toXml(QDomDocument &doc, QDomElement &ele) const * * @param ele */ -void VariantTree::fromXml(const QDomElement &ele) -{ +void VariantTree::fromXml(const QDomElement& ele) { QDomElement child = ele.firstChildElement(); while (!child.isNull()) { - bool isunknown = false; - QString name = child.nodeName(); + bool isunknown = false; + QString name = child.nodeName(); Q_ASSERT(!name.isEmpty()); if (!child.hasAttribute("type")) { // Subnode - if (!trees_.contains(name)) - trees_[name] = new VariantTree(this); + if (!trees_.contains(name)) trees_[name] = new VariantTree(this); trees_[name]->fromXml(child); } else { // Value @@ -336,8 +320,7 @@ void VariantTree::fromXml(const QDomElement &ele) values_[name] = val; } else { isunknown = true; - if (!unknownsDoc) - unknownsDoc = new QDomDocument(); + if (!unknownsDoc) unknownsDoc = new QDomDocument(); QDomDocumentFragment frag(unknownsDoc->createDocumentFragment()); frag.appendChild(unknownsDoc->importNode(child, true)); unknowns_[name] = frag; @@ -358,8 +341,7 @@ void VariantTree::fromXml(const QDomElement &ele) * The attribute of the element is used to determine the type. * The tagname of the element is ignored. */ -QVariant VariantTree::elementToVariant(const QDomElement &e) -{ +QVariant VariantTree::elementToVariant(const QDomElement& e) { // next declaration sorted from most popular static QString boolType(QString::fromLatin1("bool")); static QString stringType(QString::fromLatin1("QString")); @@ -378,11 +360,11 @@ QVariant VariantTree::elementToVariant(const QDomElement &e) static QString typeAttr(QString::fromLatin1("type")); QVariant value; - QString type = e.attribute(typeAttr); + QString type = e.attribute(typeAttr); - { // let's start from basic most popular types + { // let's start from basic most popular types QVariant::Type varianttype; - bool known = true; + bool known = true; if (type == boolType) { varianttype = QVariant::Bool; @@ -402,12 +384,10 @@ QVariant VariantTree::elementToVariant(const QDomElement &e) if (known) { for (QDomNode node = e.firstChild(); !node.isNull(); node = node.nextSibling()) { - if (node.isText()) - value = node.toText().data(); + if (node.isText()) value = node.toText().data(); } - if (!value.isValid()) - value = QString(""); + if (!value.isValid()) value = QString(""); value.convert(int(varianttype)); return value; @@ -429,25 +409,24 @@ QVariant VariantTree::elementToVariant(const QDomElement &e) QDomElement e = node.toElement(); if (!e.isNull() && e.tagName() == QLatin1String("item")) { QVariant v = elementToVariant(e); - if (v.isValid()) - list.append(v); + if (v.isValid()) list.append(v); } } value = list; } else if (type == variantMapType) { QVariantMap map; - for (QDomElement ine = e.firstChildElement(); !ine.isNull(); ine = ine.nextSiblingElement()) { + for (QDomElement ine = e.firstChildElement(); !ine.isNull(); + ine = ine.nextSiblingElement()) { QVariant v = elementToVariant(ine); - if (v.isValid()) - map.insert(ine.tagName(), v); + if (v.isValid()) map.insert(ine.tagName(), v); } value = map; } else if (type == variantHashType) { QVariantHash map; - for (QDomElement ine = e.firstChildElement(); !ine.isNull(); ine = ine.nextSiblingElement()) { + for (QDomElement ine = e.firstChildElement(); !ine.isNull(); + ine = ine.nextSiblingElement()) { QVariant v = elementToVariant(ine); - if (v.isValid()) - map.insert(ine.tagName(), v); + if (v.isValid()) map.insert(ine.tagName(), v); } value = map; } else if (type == sizeType) { @@ -497,97 +476,100 @@ QVariant VariantTree::elementToVariant(const QDomElement &e) * Modifies the element e to represent the variant var. * This method adds an attribute 'type' and contents to the element. */ -void VariantTree::variantToElement(const QVariant &var, QDomElement &e) -{ +void VariantTree::variantToElement(const QVariant& var, QDomElement& e) { switch (var.type()) { - case QVariant::List: { - const auto &variants = var.toList(); - for (const QVariant &v : variants) { - QDomElement item_element = e.ownerDocument().createElement(QLatin1String("item")); - variantToElement(v, item_element); - e.appendChild(item_element); - } - break; - } - case QVariant::Map: { - QVariantMap map = var.toMap(); - QVariantMap::ConstIterator it = map.constBegin(); - for (; it != map.constEnd(); ++it) { - QDomElement item_element = e.ownerDocument().createElement(it.key()); - variantToElement(it.value(), item_element); - e.appendChild(item_element); - } - break; - } - case QVariant::Hash: { - QVariantHash map = var.toHash(); - QVariantHash::ConstIterator it = map.constBegin(); - for (; it != map.constEnd(); ++it) { - QDomElement item_element = e.ownerDocument().createElement(it.key()); - variantToElement(it.value(), item_element); - e.appendChild(item_element); - } - break; - } - case QVariant::StringList: { - const auto &strings = var.toStringList(); - for (const QString &s : strings) { - QDomElement item_element = e.ownerDocument().createElement(QLatin1String("item")); - QDomText text = e.ownerDocument().createTextNode(s); - item_element.appendChild(text); - e.appendChild(item_element); - } - break; - } - case QVariant::Size: { - QSize size = var.toSize(); - QDomElement width_element = e.ownerDocument().createElement(QLatin1String("width")); - width_element.appendChild(e.ownerDocument().createTextNode(QString::number(size.width()))); - e.appendChild(width_element); - QDomElement height_element = e.ownerDocument().createElement(QLatin1String("height")); - height_element.appendChild(e.ownerDocument().createTextNode(QString::number(size.height()))); - e.appendChild(height_element); - break; - } - case QVariant::Rect: { - QRect rect = var.toRect(); - QDomElement x_element = e.ownerDocument().createElement(QLatin1String("x")); - x_element.appendChild(e.ownerDocument().createTextNode(QString::number(rect.x()))); - e.appendChild(x_element); - QDomElement y_element = e.ownerDocument().createElement(QLatin1String("y")); - y_element.appendChild(e.ownerDocument().createTextNode(QString::number(rect.y()))); - e.appendChild(y_element); - QDomElement width_element = e.ownerDocument().createElement(QLatin1String("width")); - width_element.appendChild(e.ownerDocument().createTextNode(QString::number(rect.width()))); - e.appendChild(width_element); - QDomElement height_element = e.ownerDocument().createElement(QLatin1String("height")); - height_element.appendChild(e.ownerDocument().createTextNode(QString::number(rect.height()))); - e.appendChild(height_element); - break; - } - case QVariant::ByteArray: { - QDomText text = e.ownerDocument().createTextNode(var.toByteArray().toBase64()); - e.appendChild(text); - break; - } - case QVariant::KeySequence: { - QKeySequence k = var.value(); - QDomText text = e.ownerDocument().createTextNode(k.toString()); - e.appendChild(text); - break; - } - case QVariant::Color: { // save invalid colors as empty string - if (var.value().isValid()) { + case QVariant::List: { + const auto& variants = var.toList(); + for (const QVariant& v : variants) { + QDomElement item_element = e.ownerDocument().createElement(QLatin1String("item")); + variantToElement(v, item_element); + e.appendChild(item_element); + } + break; + } + case QVariant::Map: { + QVariantMap map = var.toMap(); + QVariantMap::ConstIterator it = map.constBegin(); + for (; it != map.constEnd(); ++it) { + QDomElement item_element = e.ownerDocument().createElement(it.key()); + variantToElement(it.value(), item_element); + e.appendChild(item_element); + } + break; + } + case QVariant::Hash: { + QVariantHash map = var.toHash(); + QVariantHash::ConstIterator it = map.constBegin(); + for (; it != map.constEnd(); ++it) { + QDomElement item_element = e.ownerDocument().createElement(it.key()); + variantToElement(it.value(), item_element); + e.appendChild(item_element); + } + break; + } + case QVariant::StringList: { + const auto& strings = var.toStringList(); + for (const QString& s : strings) { + QDomElement item_element = e.ownerDocument().createElement(QLatin1String("item")); + QDomText text = e.ownerDocument().createTextNode(s); + item_element.appendChild(text); + e.appendChild(item_element); + } + break; + } + case QVariant::Size: { + QSize size = var.toSize(); + QDomElement width_element = e.ownerDocument().createElement(QLatin1String("width")); + width_element.appendChild( + e.ownerDocument().createTextNode(QString::number(size.width()))); + e.appendChild(width_element); + QDomElement height_element = e.ownerDocument().createElement(QLatin1String("height")); + height_element.appendChild( + e.ownerDocument().createTextNode(QString::number(size.height()))); + e.appendChild(height_element); + break; + } + case QVariant::Rect: { + QRect rect = var.toRect(); + QDomElement x_element = e.ownerDocument().createElement(QLatin1String("x")); + x_element.appendChild(e.ownerDocument().createTextNode(QString::number(rect.x()))); + e.appendChild(x_element); + QDomElement y_element = e.ownerDocument().createElement(QLatin1String("y")); + y_element.appendChild(e.ownerDocument().createTextNode(QString::number(rect.y()))); + e.appendChild(y_element); + QDomElement width_element = e.ownerDocument().createElement(QLatin1String("width")); + width_element.appendChild( + e.ownerDocument().createTextNode(QString::number(rect.width()))); + e.appendChild(width_element); + QDomElement height_element = e.ownerDocument().createElement(QLatin1String("height")); + height_element.appendChild( + e.ownerDocument().createTextNode(QString::number(rect.height()))); + e.appendChild(height_element); + break; + } + case QVariant::ByteArray: { + QDomText text = e.ownerDocument().createTextNode(var.toByteArray().toBase64()); + e.appendChild(text); + break; + } + case QVariant::KeySequence: { + QKeySequence k = var.value(); + QDomText text = e.ownerDocument().createTextNode(k.toString()); + e.appendChild(text); + break; + } + case QVariant::Color: { // save invalid colors as empty string + if (var.value().isValid()) { + QDomText text = e.ownerDocument().createTextNode(var.toString()); + e.appendChild(text); + } + break; + } + default: { QDomText text = e.ownerDocument().createTextNode(var.toString()); e.appendChild(text); + break; } - break; - } - default: { - QDomText text = e.ownerDocument().createTextNode(var.toString()); - e.appendChild(text); - break; - } } e.setAttribute(QLatin1String("type"), var.typeName()); diff --git a/src/lib/plugin/varianttree.h b/src/lib/plugin/varianttree.h index 6e684bf1..3a5dbad4 100644 --- a/src/lib/plugin/varianttree.h +++ b/src/lib/plugin/varianttree.h @@ -41,46 +41,47 @@ class QDomElement; class VariantTree : public QObject { Q_OBJECT public: - VariantTree(QObject *parent = nullptr); + VariantTree(QObject* parent = nullptr); ~VariantTree(); - void setValue(QString node, QVariant value); - QVariant getValue(const QString &node) const; + void setValue(QString node, QVariant value); + QVariant getValue(const QString& node) const; bool isInternalNode(QString node) const; - void setComment(QString node, QString comment); + void setComment(QString node, QString comment); QString getComment(QString node) const; - bool remove(const QString &node, bool internal_nodes = false); + bool remove(const QString& node, bool internal_nodes = false); - QStringList nodeChildren(const QString &node = "", bool direct = false, bool internal_nodes = false) const; + QStringList nodeChildren(const QString& node = "", bool direct = false, + bool internal_nodes = false) const; - void toXml(QDomDocument &doc, QDomElement &ele) const; - void fromXml(const QDomElement &ele); + void toXml(QDomDocument& doc, QDomElement& ele) const; + void fromXml(const QDomElement& ele); - static bool isValidNodeName(const QString &name); + static bool isValidNodeName(const QString& name); static const QVariant missingValue; - static const QString missingComment; + static const QString missingComment; protected: - static QVariant elementToVariant(const QDomElement &); - static void variantToElement(const QVariant &, QDomElement &); + static QVariant elementToVariant(const QDomElement&); + static void variantToElement(const QVariant&, QDomElement&); - static bool getKeyRest(const QString &node, QString &key, QString &rest); + static bool getKeyRest(const QString& node, QString& key, QString& rest); private: - QHash trees_; - QHash values_; - QHash comments_; + QHash trees_; + QHash values_; + QHash comments_; QHash unknowns_; // unknown types preservation - QHash unknowns2_; // unknown types preservation + QHash unknowns2_; // unknown types preservation // needed to have a document for the fragments. - static QDomDocument *unknownsDoc; + static QDomDocument* unknownsDoc; friend class OptionsTreeReader; friend class OptionsTreeWriter; }; -#endif // VARIANTTREE_H +#endif // VARIANTTREE_H diff --git a/src/lib/session/AccountItem.cpp b/src/lib/session/AccountItem.cpp index 195dd155..473f563d 100644 --- a/src/lib/session/AccountItem.cpp +++ b/src/lib/session/AccountItem.cpp @@ -13,13 +13,10 @@ #include "AccountItem.h" namespace ok { -namespace session{ +namespace session { -AccountItem::AccountItem(const QString &username_, - const QString &password_): - username(username_), password(password_) -{} +AccountItem::AccountItem(const QString& username_, const QString& password_) + : username(username_), password(password_) {} - -} -} // namespace session \ No newline at end of file +} // namespace session +} // namespace ok \ No newline at end of file diff --git a/src/lib/session/AccountItem.h b/src/lib/session/AccountItem.h index 46a06cf3..cb9ad8f7 100644 --- a/src/lib/session/AccountItem.h +++ b/src/lib/session/AccountItem.h @@ -15,18 +15,17 @@ #include namespace ok { -namespace session{ +namespace session { class AccountItem { public: - AccountItem(const QString &username, - const QString &password); + AccountItem(const QString& username, const QString& password); - //账号 - const QString &username; - //密码 - const QString &password; + // 账号 + const QString& username; + // 密码 + const QString& password; }; -} +} // namespace session -} // namespace session \ No newline at end of file +} // namespace ok \ No newline at end of file diff --git a/src/lib/session/AuthSession.cpp b/src/lib/session/AuthSession.cpp index a304c834..fc62d5c9 100644 --- a/src/lib/session/AuthSession.cpp +++ b/src/lib/session/AuthSession.cpp @@ -4,26 +4,18 @@ * You can use this software according to the terms and conditions of the Mulan * PubL v2. You may obtain a copy of Mulan PubL v2 at: * http://license.coscl.org.cn/MulanPubL-2.0 - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY - * KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO - * NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the - * Mulan PubL v2 for more details. + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. */ #include "AuthSession.h" -#include -#include -#include -#include - #include #include -#include "base/logs.h" #include "lib/backend/PassportService.h" -#include "lib/messenger/IM.h" -#include "lib/network/NetworkHttp.h" namespace ok { namespace session { @@ -31,162 +23,106 @@ namespace session { using namespace network; using namespace ok::backend; -AuthSession::AuthSession(QObject *parent) - : QObject(parent), m_networkManager(std::make_unique(this)), // - _status(Status::NONE) // +AuthSession::AuthSession(QObject* parent) + : QObject(parent) + , m_networkManager(std::make_unique(this)) + , _status(Status::NONE) // { - qRegisterMetaType("SignInInfo"); - qRegisterMetaType("LoginResult"); - qRegisterMetaType<::lib::messenger::IMConnectStatus>("IMConnectStatus"); - connect(this, &AuthSession::loginSuccessed, this, &AuthSession::onLoginSuccessed); + qRegisterMetaType("SignInInfo"); + qRegisterMetaType("LoginResult"); + qRegisterMetaType<::lib::messenger::IMConnectStatus>("IMConnectStatus"); } AuthSession::~AuthSession() { qDebug() << "~AuthSession"; } -AuthSession *AuthSession::Instance() { - static AuthSession *self = nullptr; - if (!self) { - self = new AuthSession; - } - return self; -} - Status AuthSession::status() const { return _status; } -void AuthSession::onLoginSuccessed() { - qDebug() << __func__ << "username" << m_signInInfo.username; - - okAccount = std::make_unique(m_signInInfo.username); - okAccount->setJid(::base::Jid(m_signInInfo.username, m_signInInfo.host)); +void AuthSession::doSignIn() { + qDebug() << __func__; - _im = new ::lib::messenger::IM(m_signInInfo.host, - m_signInInfo.username, - m_signInInfo.password, - l); - - connect(_im, &::lib::messenger::IM::connectResult, - this, &AuthSession::onIMConnectStatus); - qRegisterMetaType("ok::session::SignInInfo"); - - connect(_im, &::lib::messenger::IM::started, this, &AuthSession::onIMStarted); + _status = Status::CONNECTING; + LoginResult result{_status, tr("...")}; + emit loginResult(m_signInInfo, result); - _im->start(); + passportService = std::make_unique(m_signInInfo.stackUrl); + passportService->signIn( + m_signInInfo.account, m_signInInfo.password, + [&](Res& res) { + qDebug() << "username:" << res.data->username; + if (res.code != 0) { + _status = Status::FAILURE; + LoginResult result{_status, res.msg, 200}; + emit loginResult(m_signInInfo, result); + return; + } + + if (!res.success()) { + _status = Status::FAILURE; + LoginResult result{_status, res.msg, 200}; + emit loginResult(m_signInInfo, result); + return; + } + + qDebug() << "Set token:" << res.data; + setToken(*res.data); + + _status = Status::SUCCESS; + LoginResult result{Status::SUCCESS, ""}; + emit loginResult(m_signInInfo, result); + }, + [&](int statusCode, const QString& msg) { + _status = Status::FAILURE; + LoginResult result{Status::FAILURE, msg, statusCode}; + emit loginResult(m_signInInfo, result); + }); } -void AuthSession::onIMStarted() -{ - emit imStarted(m_signInInfo); +void AuthSession::doLogin(const SignInInfo& signInInfo) { + qDebug() << __func__ << signInInfo.account; + QMutexLocker locker(&_mutex); + m_signInInfo = signInInfo; + if (_status == ok::session::Status::CONNECTING) { + qDebug(("The connection is connecting.")); + return; + } + + if (_status == ok::session::Status::SUCCESS) { + qDebug(("The connection is connected.")); + return; + } + + qDebug() << "account:" << signInInfo.account << "password:" << signInInfo.password; + qDebug() << "stackUrl:" << signInInfo.stackUrl; + doSignIn(); } -void AuthSession::doConnect() { - qDebug() << __func__; - - _status = Status::CONNECTING; - LoginResult result{_status, tr("...")}; - emit loginResult(m_signInInfo, result); - - passportService->getAccount( m_signInInfo.account, [&](Res &res) { - qDebug() << "Res.code:" << res.code; - - if (res.code != 0) { - _status = Status::FAILURE; - LoginResult result{_status, res.msg, 200}; - emit loginResult(m_signInInfo, result); - return; - } - - if (!res.success()) { - _status = Status::FAILURE; - LoginResult result{_status, res.msg, 200}; - emit loginResult(m_signInInfo, result); - return; - } - - qDebug() << "Res.data=>" << res.data->toString(); - m_signInInfo.username = res.data->username.toLower(); - emit loginSuccessed(); - }, - [&](int statusCode, const QString &msg) { - _status = Status::FAILURE; - LoginResult result{Status::FAILURE, msg, statusCode}; - emit loginResult(m_signInInfo, result); - }); +void AuthSession::setToken(const SysToken& token) { + m_token = token; + m_signInInfo.username = token.username.toLower(); + QTimer::singleShot((token.expiresIn - 10) * 1000, this, &AuthSession::doRefreshToken); + emit tokenSet(); } -void AuthSession::doLogin(const SignInInfo &signInInfo) { - QMutexLocker locker(&_mutex); - - m_signInInfo = signInInfo; - - if (_status == ok::session::Status::CONNECTING) { - qDebug(("The connection is connecting.")); - return; - } - - if (_status == ok::session::Status::SUCCESS) { - qDebug(("The connection is connected.")); - return; - } +void AuthSession::setRefreshToken(const SysRefreshToken& token) { + m_token.accessToken = token.accessToken; + m_token.refreshToken = token.refreshToken; + m_token.expiresIn = token.expiresIn; - qDebug() << "account:" << signInInfo.account << "password:" << signInInfo.password; - - qDebug() << "stackUrl:" << signInInfo.stackUrl; - passportService = std::make_unique(signInInfo.stackUrl); - - // 建立连接 - doConnect(); + QTimer::singleShot((token.expiresIn - 10) * 1000, this, &AuthSession::doRefreshToken); + emit refreshTokenSet(token); } -void AuthSession::onIMConnectStatus(::lib::messenger::IMConnectStatus status) { - QString msg; - if (status == ::lib::messenger::IMConnectStatus::CONNECTED) { - _status = Status::SUCCESS; - LoginResult result{Status::SUCCESS, msg}; - emit loginResult(m_signInInfo, result); - return; - } - - // 错误处理 - _status = Status::FAILURE; - switch (status) { - case ::lib::messenger::IMConnectStatus::NO_SUPPORT: { - msg = tr("NO_SUPPORT"); - break; - } - case ::lib::messenger::IMConnectStatus::AUTH_FAILED: { - msg = tr("AUTH_FAILED"); - break; - } - case ::lib::messenger::IMConnectStatus::DISCONNECTED: { - msg = tr("DISCONNECTED"); - break; - } - case ::lib::messenger::IMConnectStatus::CONN_ERROR: { - msg = tr("CONN_ERROR"); - break; - } - case ::lib::messenger::IMConnectStatus::CONNECTING: { - msg = tr("..."); - break; - } - case ::lib::messenger::IMConnectStatus::TLS_ERROR: { - msg = tr("TLS_ERROR"); - break; - } - case ::lib::messenger::IMConnectStatus::OUT_OF_RESOURCE: { - msg = tr("OUT_OF_RESOURCE"); - break; - } - case ::lib::messenger::IMConnectStatus::TIMEOUT: { - msg = tr("TIMEOUT"); - break; - } - } - - LoginResult result{Status::FAILURE, msg}; - emit loginResult(m_signInInfo, result); +void AuthSession::doRefreshToken() { + qDebug() << __func__; + passportService = std::make_unique(m_signInInfo.stackUrl); + passportService->refresh(m_token, [&](Res& res) { + if (res.code != 0) { + qWarning() << "Refresh token error" << res.msg; + return; + } + setRefreshToken(*res.data); + }); } - -} // namespace session -} // namespace ok +} // namespace session +} // namespace ok diff --git a/src/lib/session/AuthSession.h b/src/lib/session/AuthSession.h index df4401f7..30b2a2a2 100644 --- a/src/lib/session/AuthSession.h +++ b/src/lib/session/AuthSession.h @@ -24,139 +24,84 @@ #include "base/basic_types.h" #include "base/jsons.h" +#include "lib/backend/PassportService.h" #include "lib/messenger/messenger.h" -#include "lib/network/NetworkHttp.h" -#include "lib/network/network.h" - -namespace lib::messenger { -class IM; -} - -namespace ok::backend { -class PassportService; -} namespace ok { namespace session { enum class Status { - NONE = 0, - CONNECTING, - SUCCESS, - FAILURE, + NONE = 0, + CONNECTING, + SUCCESS, + FAILURE, }; class LoginResult { public: - Status status = Status::NONE; - QString msg; - int statusCode; -}; - -class AuthInfo { -public: - AuthInfo() = default; - - AuthInfo(AuthInfo &info) { - token_ = info.getToken(); - clientName_ = info.getClientName(); - } - - ~AuthInfo() = default; - - const QString &getToken() const { return token_; } - - const QString &getClientName() const { return clientName_; } - - void fromJSON(const QJsonObject &data) { - token_ = data.value("token").toString(); - clientName_ = data.value("clientName").toString(); - } - - QJsonObject toJSON() { - QJsonObject qo; - qo.insert("token", token_); - qo.insert("clientName", clientName_); - return qo; - } - -private: - QString token_; - QString clientName_; + Status status = Status::NONE; + QString msg; + int statusCode; }; /** * 登录信息 */ struct SignInInfo { - // 账号 - QString account; - // 密码 - QString password; - - // username - QString username; - // xmpp host - QString host; - // stack url - QString stackUrl; + // 账号 + QString account; + // 密码 + QString password; + + // username + QString username; + // xmpp host + QString host; + // stack url + QString stackUrl; }; class AuthSession : public QObject { - Q_OBJECT + Q_OBJECT public: - AuthSession(QObject *parent = nullptr); - ~AuthSession() override; - - static AuthSession *Instance(); + AuthSession(QObject* parent = nullptr); + ~AuthSession() override; - Status status() const; + Status status() const; - void doLogin(const SignInInfo &signInInfo); + void doLogin(const SignInInfo& signInInfo); - [[nodiscard]] const SignInInfo &getSignInInfo() const { - return m_signInInfo; - }; + [[nodiscard]] const SignInInfo& getSignInInfo() const { return m_signInInfo; }; - // [[nodiscard]] const QString &getToken() const { return token_; }; + [[nodiscard]] const ok::backend::SysToken& getToken() const { return m_token; }; - [[nodiscard]] const AuthInfo &authInfo() const { return _authInfo; } - - [[nodiscard]] ok::base::OkAccount *account() const { return okAccount.get(); } - - ::lib::messenger::IM *im() { return _im; } + [[nodiscard]] ok::base::OkAccount* account() const { return okAccount.get(); } protected: - void doConnect(); + // 执行登录 + void doSignIn(); -private: - QStringList l; +protected slots: + // 刷新token + void doRefreshToken(); - SignInInfo m_signInInfo; - - std::shared_ptr _session; - - - std::unique_ptr m_networkManager; - AuthInfo _authInfo; - - QMutex _mutex; +private: + QMutex _mutex; + SignInInfo m_signInInfo; + ok::backend::SysToken m_token; - std::unique_ptr okAccount; - std::unique_ptr passportService; + std::unique_ptr m_networkManager; + std::unique_ptr okAccount; + std::unique_ptr passportService; - ::lib::messenger::IM *_im; - Status _status; + Status _status; + void setToken(const ok::backend::SysToken& token); + void setRefreshToken(const backend::SysRefreshToken& token); signals: - void loginResult(SignInInfo, LoginResult); // LoginResult - void loginSuccessed(); - void imStarted(SignInInfo); - -public slots: - void onLoginSuccessed(); - void onIMConnectStatus(::lib::messenger::IMConnectStatus status); - void onIMStarted(); + void loginResult(SignInInfo, LoginResult); + void tokenSet(); + void refreshTokenSet(const ok::backend::SysRefreshToken& token); }; -} // namespace session -} // namespace ok +} // namespace session +} // namespace ok diff --git a/src/lib/settings/applicationinfo.cpp b/src/lib/settings/applicationinfo.cpp index cf5f3c4c..649a4195 100644 --- a/src/lib/settings/applicationinfo.cpp +++ b/src/lib/settings/applicationinfo.cpp @@ -15,11 +15,10 @@ #ifdef OK_HAVE_CONFIG #include "ok_config.h" #endif +#include "base/OkSettings.h" #include "base/r.h" #include "base/system/sys_info.h" -#include "base/OkSettings.h" -#include #include #include #include @@ -32,10 +31,10 @@ #include #ifdef Q_OS_MAC #include -#include // chmod +#include // chmod #endif #ifdef Q_OS_UNIX -#include // chmod +#include // chmod #endif // #ifdef Q_OS_WIN // #include @@ -48,14 +47,13 @@ #define xstr(a) str(a) #define str(a) #a - #define PROG_NAME APPLICATION_NAME #define PROG_SNAME APPLICATION_ALIAS #define PROG_VERSION GIT_VERSION #define PROG_DESCRIBE GIT_DESCRIBE #define PROG_CAPS_NODE CLIENT_CAPS_NODE -#define PROG_IPC_NAME "org.okstar.msg" // must not contain '\\' character on Windows +#define PROG_IPC_NAME "org.okstar.msg" // must not contain '\\' character on Windows #define PROG_OPTIONS_NS "http://okstar.org/options" #define PROG_STORAGE_NS "http://okstar.org/storage" #define PROG_FILECACHE_NS "http://okstar.org/filecache" @@ -90,60 +88,49 @@ QString ApplicationInfo::storageNS() { return PROG_STORAGE_NS; } QString ApplicationInfo::fileCacheNS() { return PROG_FILECACHE_NS; } -QStringList ApplicationInfo::getCertificateStoreDirs() -{ +QStringList ApplicationInfo::getCertificateStoreDirs() { #if defined(Q_OS_LINUX) && defined(SHARE_SUFF) // Special hack for correct work of AppImage, snap and flatpak builds - static const QString &&additionalPath - = QDir().absoluteFilePath(qApp->applicationDirPath() + "/../share/" SHARE_SUFF "/certs"); + static const QString&& additionalPath = + QDir().absoluteFilePath(qApp->applicationDirPath() + "/../share/" SHARE_SUFF "/certs"); #endif - static const QStringList &&dirs = { + static const QStringList&& dirs = { #if defined(Q_OS_LINUX) && defined(SHARE_SUFF) - additionalPath, + additionalPath, #endif - ApplicationInfo::resourcesDir() + "/certs", - ApplicationInfo::homeDir(ApplicationInfo::DataLocation) + "/certs" - }; + ApplicationInfo::resourcesDir() + "/certs", + ApplicationInfo::homeDir(ApplicationInfo::DataLocation) + "/certs"}; return dirs; } -QStringList ApplicationInfo::dataDirs() -{ +QStringList ApplicationInfo::dataDirs() { #if defined(Q_OS_LINUX) && defined(SHARE_SUFF) // Special hack for correct work of AppImage, snap and flatpak builds - static const QString &&additionalPath - = QDir().absoluteFilePath(qApp->applicationDirPath() + "/../share/" SHARE_SUFF); + static const QString&& additionalPath = + QDir().absoluteFilePath(qApp->applicationDirPath() + "/../share/" SHARE_SUFF); #endif - static const QStringList &&dirs = { + static const QStringList&& dirs = { #if defined(Q_OS_LINUX) && defined(SHARE_SUFF) - additionalPath, + additionalPath, #endif - ":", - ".", - homeDir(DataLocation), - resourcesDir() - }; + ":", ".", homeDir(DataLocation), resourcesDir()}; return dirs; } -QStringList ApplicationInfo::pluginDirs() -{ +QStringList ApplicationInfo::pluginDirs() { #if defined(Q_OS_LINUX) && defined(SHARE_SUFF) // Special hack for correct work of AppImage, snap and flatpak builds - static const QString &&additionalPath - = QDir().absoluteFilePath(qApp->applicationDirPath() + "/../lib/" SHARE_SUFF "/plugins"); + static const QString&& additionalPath = + QDir().absoluteFilePath(qApp->applicationDirPath() + "/../lib/" SHARE_SUFF "/plugins"); #endif - static const QStringList &&dirs = { - ok::base::OkSettings().getAppPluginPath().path() - }; + static const QStringList&& dirs = {ok::base::OkSettings().getAppPluginPath().path()}; return dirs; } -QString ApplicationInfo::getCertificateStoreSaveDir() -{ +QString ApplicationInfo::getCertificateStoreSaveDir() { QDir certsave(homeDir(DataLocation) + "/certs"); if (!certsave.exists()) { QDir home(homeDir(DataLocation)); @@ -153,39 +140,43 @@ QString ApplicationInfo::getCertificateStoreSaveDir() return certsave.path(); } -QString ApplicationInfo::resourcesDir() -{ +QString ApplicationInfo::resourcesDir() { #if defined(Q_OS_WIN) return qApp->applicationDirPath(); #elif defined(Q_OS_MAC) // FIXME: Clean this up (remko) // System routine locates resource files. We "know" that Psi.icns is // in the Resources directory. - QString resourcePath; - CFBundleRef mainBundle = CFBundleGetMainBundle(); + QString resourcePath; + CFBundleRef mainBundle = CFBundleGetMainBundle(); #ifdef PSI_PLUS - const char *appIconName = "application-plus.icns"; + const char* appIconName = "application-plus.icns"; #else - const char *appIconName = "application.icns"; + const char* appIconName = "application.icns"; #endif - CFStringRef resourceCFStringRef = CFStringCreateWithCString(nullptr, appIconName, kCFStringEncodingASCII); - CFURLRef resourceURLRef = CFBundleCopyResourceURL(mainBundle, resourceCFStringRef, nullptr, nullptr); + CFStringRef resourceCFStringRef = + CFStringCreateWithCString(nullptr, appIconName, kCFStringEncodingASCII); + CFURLRef resourceURLRef = + CFBundleCopyResourceURL(mainBundle, resourceCFStringRef, nullptr, nullptr); if (resourceURLRef) { - CFStringRef resourcePathStringRef = CFURLCopyFileSystemPath(resourceURLRef, kCFURLPOSIXPathStyle); - const char *resourcePathCString = CFStringGetCStringPtr(resourcePathStringRef, kCFStringEncodingASCII); + CFStringRef resourcePathStringRef = + CFURLCopyFileSystemPath(resourceURLRef, kCFURLPOSIXPathStyle); + const char* resourcePathCString = + CFStringGetCStringPtr(resourcePathStringRef, kCFStringEncodingASCII); if (resourcePathCString) { resourcePath = resourcePathCString; - } else { // CFStringGetCStringPtr failed; use fallback conversion - CFIndex bufferLength = CFStringGetLength(resourcePathStringRef) + 1; - char * resourcePathCString = new char[bufferLength]; - Boolean conversionSuccess - = CFStringGetCString(resourcePathStringRef, resourcePathCString, bufferLength, kCFStringEncodingASCII); + } else { // CFStringGetCStringPtr failed; use fallback conversion + CFIndex bufferLength = CFStringGetLength(resourcePathStringRef) + 1; + char* resourcePathCString = new char[bufferLength]; + Boolean conversionSuccess = + CFStringGetCString(resourcePathStringRef, resourcePathCString, bufferLength, + kCFStringEncodingASCII); if (conversionSuccess) { resourcePath = resourcePathCString; } - delete[] resourcePathCString; // I own this + delete[] resourcePathCString; // I own this } - CFRelease(resourcePathStringRef); // I own this + CFRelease(resourcePathStringRef); // I own this } // Remove the tail component of the path if (!resourcePath.isNull()) { @@ -198,8 +189,7 @@ QString ApplicationInfo::resourcesDir() #endif } -QString ApplicationInfo::libDir() -{ +QString ApplicationInfo::libDir() { #if defined(Q_OS_UNIX) && !defined(Q_OS_HAIKU) return OK_LIBDIR; #else @@ -211,22 +201,20 @@ QString ApplicationInfo::libDir() * unix+mac: $HOME/.psi * environment variable "DATADIR" overrides */ -QString ApplicationInfo::homeDir(ApplicationInfo::HomedirType type) -{ +QString ApplicationInfo::homeDir(ApplicationInfo::HomedirType type) { switch (type) { - case ApplicationInfo::ConfigLocation: - return ok::base::OkSettings::configDir().path(); - case ApplicationInfo::DataLocation: - return ok::base::OkSettings::dataDir().path(); - case ApplicationInfo::CacheLocation: - return ok::base::OkSettings::cacheDir().path(); + case ApplicationInfo::ConfigLocation: + return ok::base::OkSettings::configDir().path(); + case ApplicationInfo::DataLocation: + return ok::base::OkSettings::dataDir().path(); + case ApplicationInfo::CacheLocation: + return ok::base::OkSettings::cacheDir().path(); } return {}; } -QString ApplicationInfo::makeSubhomePath(const QString &path, ApplicationInfo::HomedirType type) -{ - if (path.indexOf("..") == -1) { // ensure its in home dir +QString ApplicationInfo::makeSubhomePath(const QString& path, ApplicationInfo::HomedirType type) { + if (path.indexOf("..") == -1) { // ensure its in home dir QDir dir(homeDir(type) + "/" + path); if (!dir.exists()) { dir.mkpath("."); @@ -236,51 +224,57 @@ QString ApplicationInfo::makeSubhomePath(const QString &path, ApplicationInfo::H return QString(); } -QString ApplicationInfo::makeSubprofilePath(const QString &path, ApplicationInfo::HomedirType type) -{ +QString ApplicationInfo::makeSubprofilePath(const QString& path, + ApplicationInfo::HomedirType type) { return QString(); } -QString ApplicationInfo::historyDir() { return makeSubprofilePath("history", ApplicationInfo::DataLocation); } +QString ApplicationInfo::historyDir() { + return makeSubprofilePath("history", ApplicationInfo::DataLocation); +} -QString ApplicationInfo::vCardDir() { return makeSubprofilePath("vcard", ApplicationInfo::CacheLocation); } +QString ApplicationInfo::vCardDir() { + return makeSubprofilePath("vcard", ApplicationInfo::CacheLocation); +} QString ApplicationInfo::bobDir() { return makeSubhomePath("bob", ApplicationInfo::CacheLocation); } -QString ApplicationInfo::documentsDir() -{ - QString docDir(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/" + name()); - QDir d(docDir); +QString ApplicationInfo::documentsDir() { + QString docDir(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/" + + name()); + QDir d(docDir); if (!d.exists()) { - if (!d.mkpath(".")) - return QString(); + if (!d.mkpath(".")) return QString(); } return docDir; } -QString ApplicationInfo::profilesDir(ApplicationInfo::HomedirType type) { return makeSubhomePath("profiles", type); } +QString ApplicationInfo::profilesDir(ApplicationInfo::HomedirType type) { + return makeSubhomePath("profiles", type); +} -QString ApplicationInfo::currentProfileDir(ApplicationInfo::HomedirType type) -{ +QString ApplicationInfo::currentProfileDir(ApplicationInfo::HomedirType type) { return homeDir(type); } -QString ApplicationInfo::desktopFileBaseName() { return QLatin1String(xstr(APP_BIN_NAME) ".desktop"); } +QString ApplicationInfo::desktopFileBaseName() { + return QLatin1String(xstr(APP_BIN_NAME) ".desktop"); +} -QString ApplicationInfo::desktopFile() -{ +QString ApplicationInfo::desktopFile() { QString dFile; - auto _desktopFile = QString(xstr(APP_PREFIX) "/share/applications/") + desktopFileBaseName(); - QFile f(_desktopFile); + auto _desktopFile = QString(xstr(APP_PREFIX) "/share/applications/") + desktopFileBaseName(); + QFile f(_desktopFile); if (f.open(QIODevice::ReadOnly)) { dFile = QString::fromUtf8(f.readAll()); } return dFile; } -bool ApplicationInfo::isPortable() -{ - static bool portable - = QFileInfo(QCoreApplication::applicationFilePath()).fileName().toLower().indexOf("portable") != -1; +bool ApplicationInfo::isPortable() { + static bool portable = QFileInfo(QCoreApplication::applicationFilePath()) + .fileName() + .toLower() + .indexOf("portable") != -1; return portable; } diff --git a/src/lib/settings/applicationinfo.h b/src/lib/settings/applicationinfo.h index 48123110..73b2c7cb 100644 --- a/src/lib/settings/applicationinfo.h +++ b/src/lib/settings/applicationinfo.h @@ -22,30 +22,30 @@ class ApplicationInfo { enum HomedirType { ConfigLocation, DataLocation, CacheLocation }; // Version info - static QString name(); + static QString name(); static QLatin1String sname(); - static QString version(); - static QString capsNode(); - static QString osName(); - static QString IPCName(); + static QString version(); + static QString capsNode(); + static QString osName(); + static QString IPCName(); // URLs static QString getAppCastURL(); // Directories - static QString homeDir(HomedirType type); - static QString resourcesDir(); - static QString libDir(); - static QString profilesDir(ApplicationInfo::HomedirType); - static QString currentProfileDir(HomedirType type); - static QString makeSubhomePath(const QString &, HomedirType type); - static QString makeSubprofilePath(const QString &, HomedirType type); - static QString historyDir(); - static QString vCardDir(); - static QString bobDir(); - static QString documentsDir(); + static QString homeDir(HomedirType type); + static QString resourcesDir(); + static QString libDir(); + static QString profilesDir(ApplicationInfo::HomedirType); + static QString currentProfileDir(HomedirType type); + static QString makeSubhomePath(const QString&, HomedirType type); + static QString makeSubprofilePath(const QString&, HomedirType type); + static QString historyDir(); + static QString vCardDir(); + static QString bobDir(); + static QString documentsDir(); static QStringList getCertificateStoreDirs(); - static QString getCertificateStoreSaveDir(); + static QString getCertificateStoreSaveDir(); static QStringList dataDirs(); static QStringList pluginDirs(); @@ -57,7 +57,7 @@ class ApplicationInfo { // Common static QString desktopFileBaseName(); static QString desktopFile(); - static bool isPortable(); + static bool isPortable(); }; -#endif // APPLICATIONINFO_H +#endif // APPLICATIONINFO_H diff --git a/src/lib/settings/settings.cpp b/src/lib/settings/settings.cpp index ea640fa1..b6b43396 100644 --- a/src/lib/settings/settings.cpp +++ b/src/lib/settings/settings.cpp @@ -23,8 +23,8 @@ #include "src/widget/gui.h" #include "style.h" -#include "base/compatiblerecursivemutex.h" #include "base/OkSettings.h" +#include "base/compatiblerecursivemutex.h" #include #include @@ -48,41 +48,38 @@ * which have widget->saveX() and widget->loadX() methods. */ -const QString Settings::globalSettingsFile = - APPLICATION_ALIAS "-" OK_IM_MODULE ".ini"; +const QString Settings::globalSettingsFile = APPLICATION_ALIAS "-" OK_IM_MODULE ".ini"; CompatibleRecursiveMutex Settings::bigLock; -QThread *Settings::settingsThread{nullptr}; +QThread* Settings::settingsThread{nullptr}; -Settings::Settings() - : loaded(false), useCustomDhtList{false}, makeToxPortable{false} { - settingsThread = new QThread(); - settingsThread->setObjectName(globalSettingsFile); - settingsThread->start(QThread::LowPriority); - moveToThread(settingsThread); - loadGlobal(); +Settings::Settings() : loaded(false), useCustomDhtList{false}, makeToxPortable{false} { + settingsThread = new QThread(); + settingsThread->setObjectName(globalSettingsFile); + settingsThread->start(QThread::LowPriority); + moveToThread(settingsThread); + loadGlobal(); } Settings::~Settings() { - sync(); - settingsThread->exit(0); - settingsThread->wait(); - delete settingsThread; + sync(); + settingsThread->exit(0); + settingsThread->wait(); + delete settingsThread; } /** * @brief Returns the singleton instance. */ -Settings &Settings::getInstance() { - static Settings *settings = nullptr; - if (!settings) - settings = new Settings(); - return *settings; +Settings& Settings::getInstance() { + static Settings* settings = nullptr; + if (!settings) settings = new Settings(); + return *settings; } void Settings::destroyInstance() { - // delete settings; - // settings = nullptr; + // delete settings; + // settings = nullptr; } // 国际化下拉框 @@ -91,196 +88,182 @@ void Settings::destroyInstance() { // } void Settings::loadGlobal() { - QMutexLocker locker{&bigLock}; - - if (loaded) - return; - - createSettingsDir(); - - makeToxPortable = Settings::isToxPortable(); - - QDir dir(getSettingsDirPath()); - QString filePath = dir.filePath(globalSettingsFile); - - // If no settings file exist -- use the default one - if (!QFile(filePath).exists()) { - qDebug() << "No settings file found, using defaults"; - filePath = ":/conf/" + globalSettingsFile; - } - - qDebug() << "Loading settings from " + filePath; - - QSettings s(filePath, QSettings::IniFormat); - s.setIniCodec("UTF-8"); - - // 自动登录 - s.beginGroup("Login"); - { autoLogin = s.value("autoLogin", false).toBool(); } - s.endGroup(); - // 语言 - s.beginGroup("General"); - { - - autoAwayTime = s.value("autoAwayTime", 10).toInt(); - checkUpdates = s.value("checkUpdates", true).toBool(); - // note: notifySound and busySound UI elements are now under UI settings - // page, but kept under General in settings file to be backwards compatible - notifySound = s.value("notifySound", true).toBool(); - notifyHide = s.value("notifyHide", false).toBool(); - busySound = s.value("busySound", false).toBool(); - globalAutoAcceptDir = - s.value("globalAutoAcceptDir", - QStandardPaths::locate(QStandardPaths::HomeLocation, QString(), - QStandardPaths::LocateDirectory)) - .toString(); - autoAcceptMaxSize = static_cast( - s.value("autoAcceptMaxSize", 20 << 20 /*20 MB*/).toLongLong()); - stylePreference = - static_cast(s.value("stylePreference", 1).toInt()); - } - s.endGroup(); - - s.beginGroup("Advanced"); - { - makeToxPortable = s.value("makeToxPortable", false).toBool(); - enableIPv6 = s.value("enableIPv6", true).toBool(); - forceTCP = s.value("forceTCP", false).toBool(); - enableLanDiscovery = s.value("enableLanDiscovery", true).toBool(); - } - s.endGroup(); - - s.beginGroup("Widgets"); - { - QList objectNames = s.childKeys(); - for (const QString &name : objectNames) - widgetSettings[name] = s.value(name).toByteArray(); - } - s.endGroup(); - - s.beginGroup("GUI"); - { - showWindow = s.value("showWindow", true).toBool(); - notify = s.value("notify", true).toBool(); - desktopNotify = s.value("desktopNotify", true).toBool(); - groupAlwaysNotify = s.value("groupAlwaysNotify", true).toBool(); - groupchatPosition = s.value("groupchatPosition", true).toBool(); - separateWindow = s.value("separateWindow", false).toBool(); - dontGroupWindows = s.value("dontGroupWindows", false).toBool(); - showIdenticons = s.value("showIdenticons", true).toBool(); - - const QString DEFAULT_SMILEYS = ":/smileys/emojione/emoticons.xml"; - smileyPack = s.value("smileyPack", DEFAULT_SMILEYS).toString(); - if (!QFile::exists(smileyPack)) { - smileyPack = DEFAULT_SMILEYS; - } - - emojiFontPointSize = s.value("emojiFontPointSize", 24).toInt(); - firstColumnHandlePos = s.value("firstColumnHandlePos", 50).toInt(); - secondColumnHandlePosFromRight = - s.value("secondColumnHandlePosFromRight", 50).toInt(); - timestampFormat = s.value("timestampFormat", "hh:mm:ss").toString(); - dateFormat = s.value("dateFormat", "yyyy-MM-dd").toString(); - lightTrayIcon = s.value("lightTrayIcon", false).toBool(); - useEmoticons = s.value("useEmoticons", true).toBool(); - statusChangeNotificationEnabled = - s.value("statusChangeNotificationEnabled", false).toBool(); - showGroupJoinLeaveMessages = - s.value("showGroupJoinLeaveMessages", false).toBool(); - spellCheckingEnabled = s.value("spellCheckingEnabled", true).toBool(); - themeColor = s.value("themeColor", 0).toInt(); - style = s.value("style", "").toString(); - if (style == "") // Default to Fusion if available, otherwise no style + QMutexLocker locker{&bigLock}; + + if (loaded) return; + + createSettingsDir(); + + makeToxPortable = Settings::isToxPortable(); + + QDir dir(getSettingsDirPath()); + QString filePath = dir.filePath(globalSettingsFile); + + // If no settings file exist -- use the default one + if (!QFile(filePath).exists()) { + qDebug() << "No settings file found, using defaults"; + filePath = ":/conf/" + globalSettingsFile; + } + + qDebug() << "Loading settings from " + filePath; + + QSettings s(filePath, QSettings::IniFormat); + s.setIniCodec("UTF-8"); + + // 自动登录 + s.beginGroup("Login"); + { autoLogin = s.value("autoLogin", false).toBool(); } + s.endGroup(); + // 语言 + s.beginGroup("General"); + { + autoAwayTime = s.value("autoAwayTime", 10).toInt(); + checkUpdates = s.value("checkUpdates", true).toBool(); + // note: notifySound and busySound UI elements are now under UI settings + // page, but kept under General in settings file to be backwards compatible + notifySound = s.value("notifySound", true).toBool(); + notifyHide = s.value("notifyHide", false).toBool(); + busySound = s.value("busySound", false).toBool(); + globalAutoAcceptDir = + s.value("globalAutoAcceptDir", + QStandardPaths::locate(QStandardPaths::HomeLocation, QString(), + QStandardPaths::LocateDirectory)) + .toString(); + autoAcceptMaxSize = + static_cast(s.value("autoAcceptMaxSize", 20 << 20 /*20 MB*/).toLongLong()); + stylePreference = static_cast(s.value("stylePreference", 1).toInt()); + } + s.endGroup(); + + s.beginGroup("Advanced"); + { + makeToxPortable = s.value("makeToxPortable", false).toBool(); + enableIPv6 = s.value("enableIPv6", true).toBool(); + forceTCP = s.value("forceTCP", false).toBool(); + enableLanDiscovery = s.value("enableLanDiscovery", true).toBool(); + } + s.endGroup(); + + s.beginGroup("Widgets"); + { + QList objectNames = s.childKeys(); + for (const QString& name : objectNames) widgetSettings[name] = s.value(name).toByteArray(); + } + s.endGroup(); + + s.beginGroup("GUI"); + { + showWindow = s.value("showWindow", true).toBool(); + notify = s.value("notify", true).toBool(); + desktopNotify = s.value("desktopNotify", true).toBool(); + groupAlwaysNotify = s.value("groupAlwaysNotify", true).toBool(); + groupchatPosition = s.value("groupchatPosition", true).toBool(); + separateWindow = s.value("separateWindow", false).toBool(); + dontGroupWindows = s.value("dontGroupWindows", false).toBool(); + showIdenticons = s.value("showIdenticons", true).toBool(); + + const QString DEFAULT_SMILEYS = ":/smileys/emojione/emoticons.xml"; + smileyPack = s.value("smileyPack", DEFAULT_SMILEYS).toString(); + if (!QFile::exists(smileyPack)) { + smileyPack = DEFAULT_SMILEYS; + } + + emojiFontPointSize = s.value("emojiFontPointSize", 24).toInt(); + firstColumnHandlePos = s.value("firstColumnHandlePos", 50).toInt(); + secondColumnHandlePosFromRight = s.value("secondColumnHandlePosFromRight", 50).toInt(); + timestampFormat = s.value("timestampFormat", "hh:mm:ss").toString(); + dateFormat = s.value("dateFormat", "yyyy-MM-dd").toString(); + lightTrayIcon = s.value("lightTrayIcon", false).toBool(); + useEmoticons = s.value("useEmoticons", true).toBool(); + statusChangeNotificationEnabled = + s.value("statusChangeNotificationEnabled", false).toBool(); + showGroupJoinLeaveMessages = s.value("showGroupJoinLeaveMessages", false).toBool(); + spellCheckingEnabled = s.value("spellCheckingEnabled", true).toBool(); + themeColor = s.value("themeColor", 0).toInt(); + style = s.value("style", "").toString(); + if (style == "") // Default to Fusion if available, otherwise no style + { + if (QStyleFactory::keys().contains("Fusion")) + style = "Fusion"; + else + style = "None"; + } + nameColors = s.value("nameColors", false).toBool(); + } + s.endGroup(); + + s.beginGroup("Chat"); + { chatMessageFont = s.value("chatMessageFont", Style::getFont(Style::Big)).value(); } + s.endGroup(); + // 隐私 + s.beginGroup("State"); + { + windowGeometry = s.value("windowGeometry", QByteArray()).toByteArray(); + windowState = s.value("windowState", QByteArray()).toByteArray(); + splitterState = s.value("splitterState", QByteArray()).toByteArray(); + dialogGeometry = s.value("dialogGeometry", QByteArray()).toByteArray(); + dialogSplitterState = s.value("dialogSplitterState", QByteArray()).toByteArray(); + dialogSettingsGeometry = s.value("dialogSettingsGeometry", QByteArray()).toByteArray(); + } + s.endGroup(); + + s.beginGroup("Audio"); + { + inDev = s.value("inDev", "").toString(); + audioInDevEnabled = s.value("audioInDevEnabled", true).toBool(); + outDev = s.value("outDev", "").toString(); + audioOutDevEnabled = s.value("audioOutDevEnabled", true).toBool(); + audioInGainDecibel = s.value("inGain", 0).toReal(); + audioThreshold = s.value("audioThreshold", 0).toReal(); + outVolume = s.value("outVolume", 100).toInt(); + enableTestSound = s.value("enableTestSound", true).toBool(); + audioBitrate = s.value("audioBitrate", 64).toInt(); + } + s.endGroup(); + + s.beginGroup("Video"); { - if (QStyleFactory::keys().contains("Fusion")) - style = "Fusion"; - else - style = "None"; - } - nameColors = s.value("nameColors", false).toBool(); - } - s.endGroup(); - - s.beginGroup("Chat"); - { - chatMessageFont = - s.value("chatMessageFont", Style::getFont(Style::Big)).value(); - } - s.endGroup(); - // 隐私 - s.beginGroup("State"); - { - windowGeometry = s.value("windowGeometry", QByteArray()).toByteArray(); - windowState = s.value("windowState", QByteArray()).toByteArray(); - splitterState = s.value("splitterState", QByteArray()).toByteArray(); - dialogGeometry = s.value("dialogGeometry", QByteArray()).toByteArray(); - dialogSplitterState = - s.value("dialogSplitterState", QByteArray()).toByteArray(); - dialogSettingsGeometry = - s.value("dialogSettingsGeometry", QByteArray()).toByteArray(); - } - s.endGroup(); - - s.beginGroup("Audio"); - { - inDev = s.value("inDev", "").toString(); - audioInDevEnabled = s.value("audioInDevEnabled", true).toBool(); - outDev = s.value("outDev", "").toString(); - audioOutDevEnabled = s.value("audioOutDevEnabled", true).toBool(); - audioInGainDecibel = s.value("inGain", 0).toReal(); - audioThreshold = s.value("audioThreshold", 0).toReal(); - outVolume = s.value("outVolume", 100).toInt(); - enableTestSound = s.value("enableTestSound", true).toBool(); - audioBitrate = s.value("audioBitrate", 64).toInt(); - } - s.endGroup(); - - s.beginGroup("Video"); - { - videoDev = s.value("videoDev", "").toString(); - camVideoRes = s.value("camVideoRes", QRect()).toRect(); - screenRegion = s.value("screenRegion", QRect()).toRect(); - screenGrabbed = s.value("screenGrabbed", false).toBool(); - camVideoFPS = static_cast(s.value("camVideoFPS", 0).toUInt()); - } - s.endGroup(); - - loaded = true; + videoDev = s.value("videoDev", "").toString(); + camVideoRes = s.value("camVideoRes", QRect()).toRect(); + screenRegion = s.value("screenRegion", QRect()).toRect(); + screenGrabbed = s.value("screenGrabbed", false).toBool(); + camVideoFPS = static_cast(s.value("camVideoFPS", 0).toUInt()); + } + s.endGroup(); + + loaded = true; } bool Settings::isToxPortable() { - QString localSettingsPath = - qApp->applicationDirPath() + QDir::separator() + globalSettingsFile; - if (!QFile(localSettingsPath).exists()) { - return false; - } - QSettings ps(localSettingsPath, QSettings::IniFormat); - ps.setIniCodec("UTF-8"); - ps.beginGroup("Advanced"); - bool result = ps.value("makeToxPortable", false).toBool(); - ps.endGroup(); - return result; + QString localSettingsPath = qApp->applicationDirPath() + QDir::separator() + globalSettingsFile; + if (!QFile(localSettingsPath).exists()) { + return false; + } + QSettings ps(localSettingsPath, QSettings::IniFormat); + ps.setIniCodec("UTF-8"); + ps.beginGroup("Advanced"); + bool result = ps.value("makeToxPortable", false).toBool(); + ps.endGroup(); + return result; } -void Settings::updateProfileData(Profile *profile, - const QCommandLineParser *parser) { - QMutexLocker locker{&bigLock}; +void Settings::updateProfileData(Profile* profile, const QCommandLineParser* parser) { + QMutexLocker locker{&bigLock}; - if (profile == nullptr) { - qWarning() << QString( - "Could not load new settings (profile change to nullptr)"); - return; - } - auto &ok = ok::base::OkSettings::getInstance(); - ok.setCurrentProfile(profile->getName()); - ok.saveGlobal(); + if (profile == nullptr) { + qWarning() << QString("Could not load new settings (profile change to nullptr)"); + return; + } + auto& ok = ok::base::OkSettings::getInstance(); + ok.setCurrentProfile(profile->getName()); + ok.saveGlobal(); - saveGlobal(); + saveGlobal(); - loadPersonal(profile->getName(), profile->getPasskey()); - if (parser) { - applyCommandLineOptions(*parser); - } + loadPersonal(profile->getName(), profile->getPasskey()); + if (parser) { + applyCommandLineOptions(*parser); + } } /** @@ -290,88 +273,87 @@ void Settings::updateProfileData(Profile *profile, * removed in a future refactor. * @param parser QCommandLineParser instance */ -bool Settings::verifyProxySettings(const QCommandLineParser &parser) { - QString IPv6SettingString = parser.value("I").toLower(); - QString LANSettingString = parser.value("L").toLower(); - QString UDPSettingString = parser.value("U").toLower(); - QString proxySettingString = parser.value("proxy").toLower(); - QStringList proxySettingStrings = proxySettingString.split(":"); - - const QString SOCKS5 = QStringLiteral("socks5"); - const QString HTTP = QStringLiteral("http"); - const QString NONE = QStringLiteral("none"); - const QString ON = QStringLiteral("on"); - const QString OFF = QStringLiteral("off"); - - // Check for incompatible settings - bool activeProxyType = false; - - if (parser.isSet("P")) { - activeProxyType = - proxySettingStrings[0] == SOCKS5 || proxySettingStrings[0] == HTTP; - } - - if (parser.isSet("I")) { - if (!(IPv6SettingString == ON || IPv6SettingString == OFF)) { - qCritical() << "Unable to parse IPv6 setting."; - return false; - } - } - - if (parser.isSet("U")) { - if (!(UDPSettingString == ON || UDPSettingString == OFF)) { - qCritical() << "Unable to parse UDP setting."; - return false; - } - } - - if (parser.isSet("L")) { - if (!(LANSettingString == ON || LANSettingString == OFF)) { - qCritical() << "Unable to parse LAN setting."; - return false; - } - } - if (activeProxyType && UDPSettingString == ON) { - qCritical() << "Cannot set UDP on with proxy."; - return false; - } +bool Settings::verifyProxySettings(const QCommandLineParser& parser) { + QString IPv6SettingString = parser.value("I").toLower(); + QString LANSettingString = parser.value("L").toLower(); + QString UDPSettingString = parser.value("U").toLower(); + QString proxySettingString = parser.value("proxy").toLower(); + QStringList proxySettingStrings = proxySettingString.split(":"); + + const QString SOCKS5 = QStringLiteral("socks5"); + const QString HTTP = QStringLiteral("http"); + const QString NONE = QStringLiteral("none"); + const QString ON = QStringLiteral("on"); + const QString OFF = QStringLiteral("off"); + + // Check for incompatible settings + bool activeProxyType = false; + + if (parser.isSet("P")) { + activeProxyType = proxySettingStrings[0] == SOCKS5 || proxySettingStrings[0] == HTTP; + } - if (activeProxyType && LANSettingString == ON) { - qCritical() << "Cannot set LAN discovery on with proxy."; - return false; - } + if (parser.isSet("I")) { + if (!(IPv6SettingString == ON || IPv6SettingString == OFF)) { + qCritical() << "Unable to parse IPv6 setting."; + return false; + } + } - if (LANSettingString == ON && UDPSettingString == OFF) { - qCritical() << "Incompatible UDP/LAN settings."; - return false; - } + if (parser.isSet("U")) { + if (!(UDPSettingString == ON || UDPSettingString == OFF)) { + qCritical() << "Unable to parse UDP setting."; + return false; + } + } - if (parser.isSet("P")) { - if (proxySettingStrings[0] == NONE) { - // slightly lazy check here, accepting 'NONE[:.*]' is fine since no other - // arguments will be investigated when proxy settings are applied. - return true; + if (parser.isSet("L")) { + if (!(LANSettingString == ON || LANSettingString == OFF)) { + qCritical() << "Unable to parse LAN setting."; + return false; + } } - // Since the first argument isn't 'none', verify format of remaining - // arguments - if (proxySettingStrings.size() != 3) { - qCritical() << "Invalid number of proxy arguments."; - return false; + if (activeProxyType && UDPSettingString == ON) { + qCritical() << "Cannot set UDP on with proxy."; + return false; } - if (!(proxySettingStrings[0] == SOCKS5 || proxySettingStrings[0] == HTTP)) { - qCritical() << "Unable to parse proxy type."; - return false; + if (activeProxyType && LANSettingString == ON) { + qCritical() << "Cannot set LAN discovery on with proxy."; + return false; } - // TODO(Kriby): Sanity check IPv4/IPv6 addresses/hostnames? + if (LANSettingString == ON && UDPSettingString == OFF) { + qCritical() << "Incompatible UDP/LAN settings."; + return false; + } - int portNumber = proxySettingStrings[2].toInt(); - if (!(portNumber > 0 && portNumber < 65536)) { - qCritical() << "Invalid port number range."; + if (parser.isSet("P")) { + if (proxySettingStrings[0] == NONE) { + // slightly lazy check here, accepting 'NONE[:.*]' is fine since no other + // arguments will be investigated when proxy settings are applied. + return true; + } + // Since the first argument isn't 'none', verify format of remaining + // arguments + if (proxySettingStrings.size() != 3) { + qCritical() << "Invalid number of proxy arguments."; + return false; + } + + if (!(proxySettingStrings[0] == SOCKS5 || proxySettingStrings[0] == HTTP)) { + qCritical() << "Unable to parse proxy type."; + return false; + } + + // TODO(Kriby): Sanity check IPv4/IPv6 addresses/hostnames? + + int portNumber = proxySettingStrings[2].toInt(); + if (!(portNumber > 0 && portNumber < 65536)) { + qCritical() << "Invalid port number range."; + } } - } - return true; + return true; } /** @@ -380,230 +362,225 @@ bool Settings::verifyProxySettings(const QCommandLineParser &parser) { * @param parser QCommandLineParser instance * @return Success indicator (success = true) */ -bool Settings::applyCommandLineOptions(const QCommandLineParser &parser) { - if (!verifyProxySettings(parser)) { - return false; - }; - - QString IPv6Setting = parser.value("I").toUpper(); - QString LANSetting = parser.value("L").toUpper(); - QString UDPSetting = parser.value("U").toUpper(); - QString proxySettingString = parser.value("proxy").toUpper(); - QStringList proxySettings = proxySettingString.split(":"); - - const QString SOCKS5 = QStringLiteral("SOCKS5"); - const QString HTTP = QStringLiteral("HTTP"); - const QString NONE = QStringLiteral("NONE"); - const QString ON = QStringLiteral("ON"); - const QString OFF = QStringLiteral("OFF"); - - if (parser.isSet("I")) { - enableIPv6 = IPv6Setting == ON; - qDebug() << QString("Setting IPv6 %1.").arg(IPv6Setting); - } - - if (parser.isSet("P")) { - qDebug() << QString("Setting proxy type to %1.").arg(proxySettings[0]); - - quint16 portNumber = 0; - QString address = ""; - - if (proxySettings[0] == NONE) { - proxyType = ICoreSettings::ProxyType::ptNone; - } else { - if (proxySettings[0] == SOCKS5) { - proxyType = ICoreSettings::ProxyType::ptSOCKS5; - } else if (proxySettings[0] == HTTP) { - proxyType = ICoreSettings::ProxyType::ptHTTP; - } else { - qCritical() << "Failed to set valid proxy type"; - assert(false); // verifyProxySettings should've made this impossible - } - - forceTCP = true; - enableLanDiscovery = false; - - address = proxySettings[1]; - portNumber = static_cast(proxySettings[2].toInt()); - } - - proxyAddr = address; - qDebug() << QString("Setting proxy address to %1.").arg(address); - proxyPort = portNumber; - qDebug() << QString("Setting port number to %1.").arg(portNumber); - } - - if (parser.isSet("U")) { - bool shouldForceTCP = UDPSetting == OFF; - if (!shouldForceTCP && proxyType != ICoreSettings::ProxyType::ptNone) { - qDebug() << "Cannot use UDP with proxy; disable proxy explicitly with " - "'-P none'."; - } else { - forceTCP = shouldForceTCP; - qDebug() << QString("Setting UDP %1.").arg(UDPSetting); - } - - // LANSetting == ON is caught by verifyProxySettings, the OFF check removes - // needless debug - if (shouldForceTCP && !(LANSetting == OFF) && enableLanDiscovery) { - qDebug() << "Cannot perform LAN discovery without UDP; disabling LAN " - "discovery."; - enableLanDiscovery = false; - } - } - - if (parser.isSet("L")) { - bool shouldEnableLAN = LANSetting == ON; - - if (shouldEnableLAN && proxyType != ICoreSettings::ProxyType::ptNone) { - qDebug() << "Cannot use LAN discovery with proxy; disable proxy " - "explicitly with '-P none'."; - } else if (shouldEnableLAN && forceTCP) { - qDebug() << "Cannot use LAN discovery without UDP; enable UDP explicitly " - "with '-U on'."; - } else { - enableLanDiscovery = shouldEnableLAN; - qDebug() << QString("Setting LAN Discovery %1.").arg(LANSetting); - } - } - return true; +bool Settings::applyCommandLineOptions(const QCommandLineParser& parser) { + if (!verifyProxySettings(parser)) { + return false; + }; + + QString IPv6Setting = parser.value("I").toUpper(); + QString LANSetting = parser.value("L").toUpper(); + QString UDPSetting = parser.value("U").toUpper(); + QString proxySettingString = parser.value("proxy").toUpper(); + QStringList proxySettings = proxySettingString.split(":"); + + const QString SOCKS5 = QStringLiteral("SOCKS5"); + const QString HTTP = QStringLiteral("HTTP"); + const QString NONE = QStringLiteral("NONE"); + const QString ON = QStringLiteral("ON"); + const QString OFF = QStringLiteral("OFF"); + + if (parser.isSet("I")) { + enableIPv6 = IPv6Setting == ON; + qDebug() << QString("Setting IPv6 %1.").arg(IPv6Setting); + } + + if (parser.isSet("P")) { + qDebug() << QString("Setting proxy type to %1.").arg(proxySettings[0]); + + quint16 portNumber = 0; + QString address = ""; + + if (proxySettings[0] == NONE) { + proxyType = ICoreSettings::ProxyType::ptNone; + } else { + if (proxySettings[0] == SOCKS5) { + proxyType = ICoreSettings::ProxyType::ptSOCKS5; + } else if (proxySettings[0] == HTTP) { + proxyType = ICoreSettings::ProxyType::ptHTTP; + } else { + qCritical() << "Failed to set valid proxy type"; + assert(false); // verifyProxySettings should've made this impossible + } + + forceTCP = true; + enableLanDiscovery = false; + + address = proxySettings[1]; + portNumber = static_cast(proxySettings[2].toInt()); + } + + proxyAddr = address; + qDebug() << QString("Setting proxy address to %1.").arg(address); + proxyPort = portNumber; + qDebug() << QString("Setting port number to %1.").arg(portNumber); + } + + if (parser.isSet("U")) { + bool shouldForceTCP = UDPSetting == OFF; + if (!shouldForceTCP && proxyType != ICoreSettings::ProxyType::ptNone) { + qDebug() << "Cannot use UDP with proxy; disable proxy explicitly with " + "'-P none'."; + } else { + forceTCP = shouldForceTCP; + qDebug() << QString("Setting UDP %1.").arg(UDPSetting); + } + + // LANSetting == ON is caught by verifyProxySettings, the OFF check removes + // needless debug + if (shouldForceTCP && !(LANSetting == OFF) && enableLanDiscovery) { + qDebug() << "Cannot perform LAN discovery without UDP; disabling LAN " + "discovery."; + enableLanDiscovery = false; + } + } + + if (parser.isSet("L")) { + bool shouldEnableLAN = LANSetting == ON; + + if (shouldEnableLAN && proxyType != ICoreSettings::ProxyType::ptNone) { + qDebug() << "Cannot use LAN discovery with proxy; disable proxy " + "explicitly with '-P none'."; + } else if (shouldEnableLAN && forceTCP) { + qDebug() << "Cannot use LAN discovery without UDP; enable UDP explicitly " + "with '-U on'."; + } else { + enableLanDiscovery = shouldEnableLAN; + qDebug() << QString("Setting LAN Discovery %1.").arg(LANSetting); + } + } + return true; } void Settings::resetToDefault() { - // To stop saving - loaded = false; + // To stop saving + loaded = false; - // Remove file with profile settings - QDir dir(getSettingsDirPath()); - Profile *profile = Nexus::getProfile(); - QString localPath = dir.filePath(profile->getName() + ".ini"); - QFile local(localPath); - if (local.exists()) - local.remove(); + // Remove file with profile settings + QDir dir(getSettingsDirPath()); + Profile* profile = Nexus::getProfile(); + QString localPath = dir.filePath(profile->getName() + ".ini"); + QFile local(localPath); + if (local.exists()) local.remove(); } /** * @brief Asynchronous, saves the global settings. */ void Settings::saveGlobal() { - if (QThread::currentThread() != settingsThread) - return (void)QMetaObject::invokeMethod(&getInstance(), "saveGlobal"); - - QMutexLocker locker{&bigLock}; - if (!loaded) - return; - - QString path = getSettingsDirPath() + globalSettingsFile; - qDebug() << "Saving global settings at " + path; - - QSettings s(path, QSettings::IniFormat); - s.setIniCodec("UTF-8"); - - s.clear(); - - s.beginGroup("Login"); - { s.setValue("autoLogin", autoLogin); } - s.endGroup(); - - s.beginGroup("General"); - { - s.setValue("autoAwayTime", autoAwayTime); - s.setValue("checkUpdates", checkUpdates); - s.setValue("notifySound", notifySound); - s.setValue("notifyHide", notifyHide); - s.setValue("busySound", busySound); - s.setValue("autoAcceptMaxSize", static_cast(autoAcceptMaxSize)); - s.setValue("globalAutoAcceptDir", globalAutoAcceptDir); - s.setValue("stylePreference", static_cast(stylePreference)); - } - s.endGroup(); - - s.beginGroup("Advanced"); - { - s.setValue("makeToxPortable", makeToxPortable); - s.setValue("enableIPv6", enableIPv6); - s.setValue("forceTCP", forceTCP); - s.setValue("enableLanDiscovery", enableLanDiscovery); - s.setValue("dbSyncType", static_cast(dbSyncType)); - } - s.endGroup(); - - s.beginGroup("Widgets"); - { - const QList widgetNames = widgetSettings.keys(); - for (const QString &name : widgetNames) - s.setValue(name, widgetSettings.value(name)); - } - s.endGroup(); - - s.beginGroup("GUI"); - { - s.setValue("showWindow", showWindow); - s.setValue("notify", notify); - s.setValue("desktopNotify", desktopNotify); - s.setValue("groupAlwaysNotify", groupAlwaysNotify); - s.setValue("separateWindow", separateWindow); - s.setValue("dontGroupWindows", dontGroupWindows); - s.setValue("groupchatPosition", groupchatPosition); - s.setValue("showIdenticons", showIdenticons); - - s.setValue("smileyPack", smileyPack); - s.setValue("emojiFontPointSize", emojiFontPointSize); - s.setValue("firstColumnHandlePos", firstColumnHandlePos); - s.setValue("secondColumnHandlePosFromRight", - secondColumnHandlePosFromRight); - s.setValue("timestampFormat", timestampFormat); - s.setValue("dateFormat", dateFormat); - s.setValue("lightTrayIcon", lightTrayIcon); - s.setValue("useEmoticons", useEmoticons); - s.setValue("themeColor", themeColor); - s.setValue("style", style); - s.setValue("nameColors", nameColors); - s.setValue("statusChangeNotificationEnabled", - statusChangeNotificationEnabled); - s.setValue("showGroupJoinLeaveMessages", showGroupJoinLeaveMessages); - s.setValue("spellCheckingEnabled", spellCheckingEnabled); - } - s.endGroup(); - - s.beginGroup("Chat"); - { s.setValue("chatMessageFont", chatMessageFont); } - s.endGroup(); - - s.beginGroup("State"); - { - s.setValue("windowGeometry", windowGeometry); - s.setValue("windowState", windowState); - s.setValue("splitterState", splitterState); - s.setValue("dialogGeometry", dialogGeometry); - s.setValue("dialogSplitterState", dialogSplitterState); - s.setValue("dialogSettingsGeometry", dialogSettingsGeometry); - } - s.endGroup(); - // 音频 - s.beginGroup("Audio"); - { - s.setValue("inDev", inDev); - s.setValue("audioInDevEnabled", audioInDevEnabled); - s.setValue("outDev", outDev); - s.setValue("audioOutDevEnabled", audioOutDevEnabled); - s.setValue("inGain", audioInGainDecibel); - s.setValue("audioThreshold", audioThreshold); - s.setValue("outVolume", outVolume); - s.setValue("enableTestSound", enableTestSound); - s.setValue("audioBitrate", audioBitrate); - } - s.endGroup(); - - s.beginGroup("Video"); - { - s.setValue("videoDev", videoDev); - s.setValue("camVideoRes", camVideoRes); - s.setValue("camVideoFPS", camVideoFPS); - s.setValue("screenRegion", screenRegion); - s.setValue("screenGrabbed", screenGrabbed); - } - s.endGroup(); + if (QThread::currentThread() != settingsThread) + return (void)QMetaObject::invokeMethod(&getInstance(), "saveGlobal"); + + QMutexLocker locker{&bigLock}; + if (!loaded) return; + + QString path = getSettingsDirPath() + globalSettingsFile; + qDebug() << "Saving global settings at " + path; + + QSettings s(path, QSettings::IniFormat); + s.setIniCodec("UTF-8"); + + s.clear(); + + s.beginGroup("Login"); + { s.setValue("autoLogin", autoLogin); } + s.endGroup(); + + s.beginGroup("General"); + { + s.setValue("autoAwayTime", autoAwayTime); + s.setValue("checkUpdates", checkUpdates); + s.setValue("notifySound", notifySound); + s.setValue("notifyHide", notifyHide); + s.setValue("busySound", busySound); + s.setValue("autoAcceptMaxSize", static_cast(autoAcceptMaxSize)); + s.setValue("globalAutoAcceptDir", globalAutoAcceptDir); + s.setValue("stylePreference", static_cast(stylePreference)); + } + s.endGroup(); + + s.beginGroup("Advanced"); + { + s.setValue("makeToxPortable", makeToxPortable); + s.setValue("enableIPv6", enableIPv6); + s.setValue("forceTCP", forceTCP); + s.setValue("enableLanDiscovery", enableLanDiscovery); + s.setValue("dbSyncType", static_cast(dbSyncType)); + } + s.endGroup(); + + s.beginGroup("Widgets"); + { + const QList widgetNames = widgetSettings.keys(); + for (const QString& name : widgetNames) s.setValue(name, widgetSettings.value(name)); + } + s.endGroup(); + + s.beginGroup("GUI"); + { + s.setValue("showWindow", showWindow); + s.setValue("notify", notify); + s.setValue("desktopNotify", desktopNotify); + s.setValue("groupAlwaysNotify", groupAlwaysNotify); + s.setValue("separateWindow", separateWindow); + s.setValue("dontGroupWindows", dontGroupWindows); + s.setValue("groupchatPosition", groupchatPosition); + s.setValue("showIdenticons", showIdenticons); + + s.setValue("smileyPack", smileyPack); + s.setValue("emojiFontPointSize", emojiFontPointSize); + s.setValue("firstColumnHandlePos", firstColumnHandlePos); + s.setValue("secondColumnHandlePosFromRight", secondColumnHandlePosFromRight); + s.setValue("timestampFormat", timestampFormat); + s.setValue("dateFormat", dateFormat); + s.setValue("lightTrayIcon", lightTrayIcon); + s.setValue("useEmoticons", useEmoticons); + s.setValue("themeColor", themeColor); + s.setValue("style", style); + s.setValue("nameColors", nameColors); + s.setValue("statusChangeNotificationEnabled", statusChangeNotificationEnabled); + s.setValue("showGroupJoinLeaveMessages", showGroupJoinLeaveMessages); + s.setValue("spellCheckingEnabled", spellCheckingEnabled); + } + s.endGroup(); + + s.beginGroup("Chat"); + { s.setValue("chatMessageFont", chatMessageFont); } + s.endGroup(); + + s.beginGroup("State"); + { + s.setValue("windowGeometry", windowGeometry); + s.setValue("windowState", windowState); + s.setValue("splitterState", splitterState); + s.setValue("dialogGeometry", dialogGeometry); + s.setValue("dialogSplitterState", dialogSplitterState); + s.setValue("dialogSettingsGeometry", dialogSettingsGeometry); + } + s.endGroup(); + // 音频 + s.beginGroup("Audio"); + { + s.setValue("inDev", inDev); + s.setValue("audioInDevEnabled", audioInDevEnabled); + s.setValue("outDev", outDev); + s.setValue("audioOutDevEnabled", audioOutDevEnabled); + s.setValue("inGain", audioInGainDecibel); + s.setValue("audioThreshold", audioThreshold); + s.setValue("outVolume", outVolume); + s.setValue("enableTestSound", enableTestSound); + s.setValue("audioBitrate", audioBitrate); + } + s.endGroup(); + + s.beginGroup("Video"); + { + s.setValue("videoDev", videoDev); + s.setValue("camVideoRes", camVideoRes); + s.setValue("camVideoFPS", camVideoFPS); + s.setValue("screenRegion", screenRegion); + s.setValue("screenGrabbed", screenGrabbed); + } + s.endGroup(); } /** @@ -613,130 +590,123 @@ void Settings::saveGlobal() { * @note If basename is "profile", settings will be saved in profile.ini */ void Settings::createPersonal(QString basename) { + QMutexLocker locker{&bigLock}; - QMutexLocker locker{&bigLock}; + qDebug() << "Creating new profile for" << basename; + QString path = getSettingsDirPath() + QDir::separator() + basename + ".ini"; + qDebug() << "Creating new profile settings in " << path; - qDebug() << "Creating new profile for" << basename; - QString path = getSettingsDirPath() + QDir::separator() + basename + ".ini"; - qDebug() << "Creating new profile settings in " << path; + QSettings ps(path, QSettings::IniFormat); + ps.setIniCodec("UTF-8"); + ps.beginGroup("Friends"); + // ps.beginWriteArray("IMFriend", 0); + // ps.endArray(); + ps.endGroup(); - QSettings ps(path, QSettings::IniFormat); - ps.setIniCodec("UTF-8"); - ps.beginGroup("Friends"); - // ps.beginWriteArray("IMFriend", 0); - // ps.endArray(); - ps.endGroup(); + ps.beginGroup("Privacy"); + ps.endGroup(); +} - ps.beginGroup("Privacy"); - ps.endGroup(); +void Settings::loadPersonal(QString profileName, const ToxEncrypt* passKey) { + QMutexLocker locker{&bigLock}; -} + QDir dir(getSettingsDirPath()); + QString filePath = dir.filePath(globalSettingsFile); + // load from a profile specific friend data list if possible + QString tmp = dir.filePath(profileName + ".ini"); + if (QFile(tmp).exists()) // otherwise, filePath remains the global file + filePath = tmp; -void Settings::loadPersonal(QString profileName, const ToxEncrypt *passKey) { - QMutexLocker locker{&bigLock}; + qDebug() << "Loading personal settings from" << filePath; - QDir dir(getSettingsDirPath()); - QString filePath = dir.filePath(globalSettingsFile); + QSettings ps(filePath, QSettings::IniFormat); + friendLst.clear(); - // load from a profile specific friend data list if possible - QString tmp = dir.filePath(profileName + ".ini"); - if (QFile(tmp).exists()) // otherwise, filePath remains the global file - filePath = tmp; + ps.beginGroup("Privacy"); + { + typingNotification = ps.value("typingNotification", true).toBool(); + enableLogging = ps.value("enableLogging", true).toBool(); + blackList = ps.value("blackList").toString().split('\n'); + } + ps.endGroup(); - qDebug() << "Loading personal settings from" << filePath; + ps.beginGroup("Friends"); + { + int size = ps.beginReadArray("IMFriend"); + friendLst.reserve(size); + friendLst.clear(); + for (int i = 0; i < size; i++) { + ps.setArrayIndex(i); + friendProp fp{ps.value("addr").toString()}; + fp.alias = ps.value("alias").toString(); + fp.note = ps.value("note").toString(); + fp.autoAcceptDir = ps.value("autoAcceptDir").toString(); + + if (fp.autoAcceptDir == "") fp.autoAcceptDir = ps.value("autoAccept").toString(); + + fp.autoAcceptCall = + Settings::AutoAcceptCallFlags(QFlag(ps.value("autoAcceptCall", 0).toInt())); + fp.autoGroupInvite = ps.value("autoGroupInvite").toBool(); + fp.circleID = ps.value("circle", -1).toInt(); + + if (getEnableLogging()) fp.activity = ps.value("activity", QDateTime()).toDateTime(); + friendLst.insert(ToxId(fp.addr).getPublicKey().getByteArray(), fp); + } + ps.endArray(); + } + ps.endGroup(); - QSettings ps(filePath, QSettings::IniFormat); - friendLst.clear(); + ps.beginGroup("Requests"); + { + int size = ps.beginReadArray("Request"); + friendRequests.clear(); + friendRequests.reserve(size); + for (int i = 0; i < size; i++) { + ps.setArrayIndex(i); + Request request; + request.address = ps.value("addr").toString(); + request.message = ps.value("message").toString(); + request.read = ps.value("read").toBool(); + friendRequests.push_back(request); + } + ps.endArray(); + } + ps.endGroup(); + // 用戶 + ps.beginGroup("GUI"); + { + compactLayout = ps.value("compactLayout", true).toBool(); + sortingMode = static_cast( + ps.value("friendSortingMethod", static_cast(FriendListSortingMode::Name)) + .toInt()); + } + ps.endGroup(); - ps.beginGroup("Privacy"); - { - typingNotification = ps.value("typingNotification", true).toBool(); - enableLogging = ps.value("enableLogging", true).toBool(); - blackList = ps.value("blackList").toString().split('\n'); - } - ps.endGroup(); + ps.beginGroup("Proxy"); + { + proxyType = static_cast(ps.value("proxyType", 0 /* ProxyType::None */).toInt()); + proxyType = fixInvalidProxyType(proxyType); + proxyAddr = ps.value("proxyAddr", proxyAddr).toString(); + proxyPort = static_cast(ps.value("proxyPort", proxyPort).toUInt()); + } + ps.endGroup(); - ps.beginGroup("Friends"); - { - int size = ps.beginReadArray("IMFriend"); - friendLst.reserve(size); - friendLst.clear(); - for (int i = 0; i < size; i++) { - ps.setArrayIndex(i); - friendProp fp{ps.value("addr").toString()}; - fp.alias = ps.value("alias").toString(); - fp.note = ps.value("note").toString(); - fp.autoAcceptDir = ps.value("autoAcceptDir").toString(); - - if (fp.autoAcceptDir == "") - fp.autoAcceptDir = ps.value("autoAccept").toString(); - - fp.autoAcceptCall = Settings::AutoAcceptCallFlags( - QFlag(ps.value("autoAcceptCall", 0).toInt())); - fp.autoGroupInvite = ps.value("autoGroupInvite").toBool(); - fp.circleID = ps.value("circle", -1).toInt(); - - if (getEnableLogging()) - fp.activity = ps.value("activity", QDateTime()).toDateTime(); - friendLst.insert(ToxId(fp.addr).getPublicKey().getByteArray(), fp); - } - ps.endArray(); - } - ps.endGroup(); - - ps.beginGroup("Requests"); - { - int size = ps.beginReadArray("Request"); - friendRequests.clear(); - friendRequests.reserve(size); - for (int i = 0; i < size; i++) { - ps.setArrayIndex(i); - Request request; - request.address = ps.value("addr").toString(); - request.message = ps.value("message").toString(); - request.read = ps.value("read").toBool(); - friendRequests.push_back(request); - } - ps.endArray(); - } - ps.endGroup(); - // 用戶 - ps.beginGroup("GUI"); - { - compactLayout = ps.value("compactLayout", true).toBool(); - sortingMode = static_cast( - ps.value("friendSortingMethod", - static_cast(FriendListSortingMode::Name)) - .toInt()); - } - ps.endGroup(); - - ps.beginGroup("Proxy"); - { - proxyType = static_cast( - ps.value("proxyType", 0 /* ProxyType::None */).toInt()); - proxyType = fixInvalidProxyType(proxyType); - proxyAddr = ps.value("proxyAddr", proxyAddr).toString(); - proxyPort = static_cast(ps.value("proxyPort", proxyPort).toUInt()); - } - ps.endGroup(); - - ps.beginGroup("Circles"); - { - int size = ps.beginReadArray("Circle"); - circleLst.clear(); - circleLst.reserve(size); - for (int i = 0; i < size; i++) { - ps.setArrayIndex(i); - circleProp cp; - cp.name = ps.value("name").toString(); - cp.expanded = ps.value("expanded", true).toBool(); - circleLst.push_back(cp); - } - ps.endArray(); - } - ps.endGroup(); + ps.beginGroup("Circles"); + { + int size = ps.beginReadArray("Circle"); + circleLst.clear(); + circleLst.reserve(size); + for (int i = 0; i < size; i++) { + ps.setArrayIndex(i); + circleProp cp; + cp.name = ps.value("name").toString(); + cp.expanded = ps.value("expanded", true).toBool(); + circleLst.push_back(cp); + } + ps.endArray(); + } + ps.endGroup(); } /** @@ -748,105 +718,102 @@ void Settings::savePersonal() { savePersonal(Nexus::getProfile()); } * @brief Asynchronous, saves the profile. * @param profile Profile to save. */ -void Settings::savePersonal(Profile *profile) { - if (!profile) { - qDebug() << "Could not save personal settings because there is no active " - "profile"; - return; - } - if (QThread::currentThread() != settingsThread) - return (void)QMetaObject::invokeMethod(&getInstance(), "savePersonal", - Q_ARG(Profile *, profile)); - savePersonal(profile->getName(), profile->getPasskey()); -} - -void Settings::savePersonal(QString profileName, - const QString& passkey) { - QMutexLocker locker{&bigLock}; - if (!loaded) - return; - - QString path = getSettingsDirPath() + profileName + ".ini"; - - qDebug() << "Saving personal settings at " << path; - - QSettings ps(path, QSettings::IniFormat); - ps.beginGroup("Friends"); - { - ps.beginWriteArray("IMFriend", friendLst.size()); - int index = 0; - for (auto &frnd : friendLst) { - ps.setArrayIndex(index); - ps.setValue("addr", frnd.addr); - ps.setValue("alias", frnd.alias); - ps.setValue("note", frnd.note); - ps.setValue("autoAcceptDir", frnd.autoAcceptDir); - ps.setValue("autoAcceptCall", static_cast(frnd.autoAcceptCall)); - ps.setValue("autoGroupInvite", frnd.autoGroupInvite); - ps.setValue("circle", frnd.circleID); - - if (getEnableLogging()) - ps.setValue("activity", frnd.activity); - - ++index; - } - ps.endArray(); - } - ps.endGroup(); - - ps.beginGroup("Requests"); - { - ps.beginWriteArray("Request", friendRequests.size()); - int index = 0; - for (auto &request : friendRequests) { - ps.setArrayIndex(index); - ps.setValue("addr", request.address); - ps.setValue("message", request.message); - ps.setValue("read", request.read); - - ++index; - } - ps.endArray(); - } - ps.endGroup(); - - ps.beginGroup("GUI"); - { - ps.setValue("compactLayout", compactLayout); - ps.setValue("friendSortingMethod", static_cast(sortingMode)); - } - ps.endGroup(); - - ps.beginGroup("Proxy"); - { - ps.setValue("proxyType", static_cast(proxyType)); - ps.setValue("proxyAddr", proxyAddr); - ps.setValue("proxyPort", proxyPort); - } - ps.endGroup(); - - ps.beginGroup("Circles"); - { - ps.beginWriteArray("Circle", circleLst.size()); - int index = 0; - for (auto &circle : circleLst) { - ps.setArrayIndex(index); - ps.setValue("name", circle.name); - ps.setValue("expanded", circle.expanded); - ++index; - } - ps.endArray(); - } - ps.endGroup(); - - ps.beginGroup("Privacy"); - { - ps.setValue("typingNotification", typingNotification); - ps.setValue("enableLogging", enableLogging); - ps.setValue("blackList", blackList.join('\n')); - } - ps.endGroup(); - // ps.save(); +void Settings::savePersonal(Profile* profile) { + if (!profile) { + qDebug() << "Could not save personal settings because there is no active " + "profile"; + return; + } + if (QThread::currentThread() != settingsThread) + return (void)QMetaObject::invokeMethod(&getInstance(), "savePersonal", + Q_ARG(Profile*, profile)); + savePersonal(profile->getName(), profile->getPasskey()); +} + +void Settings::savePersonal(QString profileName, const QString& passkey) { + QMutexLocker locker{&bigLock}; + if (!loaded) return; + + QString path = getSettingsDirPath() + profileName + ".ini"; + + qDebug() << "Saving personal settings at " << path; + + QSettings ps(path, QSettings::IniFormat); + ps.beginGroup("Friends"); + { + ps.beginWriteArray("IMFriend", friendLst.size()); + int index = 0; + for (auto& frnd : friendLst) { + ps.setArrayIndex(index); + ps.setValue("addr", frnd.addr); + ps.setValue("alias", frnd.alias); + ps.setValue("note", frnd.note); + ps.setValue("autoAcceptDir", frnd.autoAcceptDir); + ps.setValue("autoAcceptCall", static_cast(frnd.autoAcceptCall)); + ps.setValue("autoGroupInvite", frnd.autoGroupInvite); + ps.setValue("circle", frnd.circleID); + + if (getEnableLogging()) ps.setValue("activity", frnd.activity); + + ++index; + } + ps.endArray(); + } + ps.endGroup(); + + ps.beginGroup("Requests"); + { + ps.beginWriteArray("Request", friendRequests.size()); + int index = 0; + for (auto& request : friendRequests) { + ps.setArrayIndex(index); + ps.setValue("addr", request.address); + ps.setValue("message", request.message); + ps.setValue("read", request.read); + + ++index; + } + ps.endArray(); + } + ps.endGroup(); + + ps.beginGroup("GUI"); + { + ps.setValue("compactLayout", compactLayout); + ps.setValue("friendSortingMethod", static_cast(sortingMode)); + } + ps.endGroup(); + + ps.beginGroup("Proxy"); + { + ps.setValue("proxyType", static_cast(proxyType)); + ps.setValue("proxyAddr", proxyAddr); + ps.setValue("proxyPort", proxyPort); + } + ps.endGroup(); + + ps.beginGroup("Circles"); + { + ps.beginWriteArray("Circle", circleLst.size()); + int index = 0; + for (auto& circle : circleLst) { + ps.setArrayIndex(index); + ps.setValue("name", circle.name); + ps.setValue("expanded", circle.expanded); + ++index; + } + ps.endArray(); + } + ps.endGroup(); + + ps.beginGroup("Privacy"); + { + ps.setValue("typingNotification", typingNotification); + ps.setValue("enableLogging", enableLogging); + ps.setValue("blackList", blackList.join('\n')); + } + ps.endGroup(); + // ps.save(); } /** @@ -854,28 +821,24 @@ void Settings::savePersonal(QString profileName, * @return Path to settings directory, ends with a directory separator. */ QString Settings::getSettingsDirPath() const { - QMutexLocker locker{&bigLock}; - if (makeToxPortable) - return qApp->applicationDirPath() + QDir::separator(); + QMutexLocker locker{&bigLock}; + if (makeToxPortable) return qApp->applicationDirPath() + QDir::separator(); // workaround for https://bugreports.qt-project.org/browse/QTBUG-38845 #ifdef Q_OS_WIN - return QDir::cleanPath( - QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + - QDir::separator() + "AppData" + QDir::separator() + "Roaming" + - QDir::separator() + APPLICATION_ID) + - QDir::separator(); + return QDir::cleanPath(QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + + QDir::separator() + "AppData" + QDir::separator() + "Roaming" + + QDir::separator() + APPLICATION_ID) + + QDir::separator(); #elif defined(Q_OS_OSX) - return QDir::cleanPath( - QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + - QDir::separator() + "Library" + QDir::separator() + - "Application Support" + QDir::separator() + APPLICATION_ID) + - QDir::separator(); + return QDir::cleanPath(QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + + QDir::separator() + "Library" + QDir::separator() + + "Application Support" + QDir::separator() + APPLICATION_ID) + + QDir::separator(); #else - return QDir::cleanPath( - QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + - QDir::separator() + APPLICATION_ID) + - QDir::separator(); + return QDir::cleanPath(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + + QDir::separator() + APPLICATION_ID) + + QDir::separator(); #endif } @@ -884,351 +847,344 @@ QString Settings::getSettingsDirPath() const { * @return Path to application data, ends with a directory separator. */ QString Settings::getAppDataDirPath() const { - QMutexLocker locker{&bigLock}; - if (makeToxPortable) - return qApp->applicationDirPath() + QDir::separator(); + QMutexLocker locker{&bigLock}; + if (makeToxPortable) return qApp->applicationDirPath() + QDir::separator(); // workaround for https://bugreports.qt-project.org/browse/QTBUG-38845 #ifdef Q_OS_WIN - return QDir::cleanPath( - QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + - QDir::separator() + "AppData" + QDir::separator() + "Roaming" + - QDir::separator() + "tox") + - QDir::separator(); + return QDir::cleanPath(QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + + QDir::separator() + "AppData" + QDir::separator() + "Roaming" + + QDir::separator() + "tox") + + QDir::separator(); #elif defined(Q_OS_OSX) - return QDir::cleanPath( - QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + - QDir::separator() + "Library" + QDir::separator() + - "Application Support" + QDir::separator() + "Tox") + - QDir::separator(); + return QDir::cleanPath(QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + + QDir::separator() + "Library" + QDir::separator() + + "Application Support" + QDir::separator() + "Tox") + + QDir::separator(); #else - /* - * TODO: Change QStandardPaths::DataLocation to AppDataLocation when upgrate - * Qt to 5.4+ For now we need support Qt 5.3, so we use deprecated - * DataLocation BTW, it's not a big deal since for linux AppDataLocation and - * DataLocation are equal - */ - return QDir::cleanPath( - QStandardPaths::writableLocation(QStandardPaths::DataLocation)) + - QDir::separator(); + /* + * TODO: Change QStandardPaths::DataLocation to AppDataLocation when upgrate + * Qt to 5.4+ For now we need support Qt 5.3, so we use deprecated + * DataLocation BTW, it's not a big deal since for linux AppDataLocation and + * DataLocation are equal + */ + return QDir::cleanPath(QStandardPaths::writableLocation(QStandardPaths::DataLocation)) + + QDir::separator(); #endif } - bool Settings::getEnableTestSound() const { - QMutexLocker locker{&bigLock}; - return enableTestSound; + QMutexLocker locker{&bigLock}; + return enableTestSound; } void Settings::setEnableTestSound(bool newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != enableTestSound) { - enableTestSound = newValue; - emit enableTestSoundChanged(enableTestSound); - } + if (newValue != enableTestSound) { + enableTestSound = newValue; + emit enableTestSoundChanged(enableTestSound); + } } bool Settings::getEnableIPv6() const { - QMutexLocker locker{&bigLock}; - return enableIPv6; + QMutexLocker locker{&bigLock}; + return enableIPv6; } void Settings::setEnableIPv6(bool enabled) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (enabled != enableIPv6) { - enableIPv6 = enabled; - emit enableIPv6Changed(enableIPv6); - } + if (enabled != enableIPv6) { + enableIPv6 = enabled; + emit enableIPv6Changed(enableIPv6); + } } bool Settings::getMakeToxPortable() const { - QMutexLocker locker{&bigLock}; - return makeToxPortable; + QMutexLocker locker{&bigLock}; + return makeToxPortable; } void Settings::setMakeToxPortable(bool newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != makeToxPortable) { - QFile(getSettingsDirPath() + globalSettingsFile).remove(); - makeToxPortable = newValue; - saveGlobal(); + if (newValue != makeToxPortable) { + QFile(getSettingsDirPath() + globalSettingsFile).remove(); + makeToxPortable = newValue; + saveGlobal(); - emit makeToxPortableChanged(makeToxPortable); - } + emit makeToxPortableChanged(makeToxPortable); + } } QString Settings::getStyle() const { - QMutexLocker locker{&bigLock}; - return style; + QMutexLocker locker{&bigLock}; + return style; } -void Settings::setStyle(const QString &newStyle) { - QMutexLocker locker{&bigLock}; +void Settings::setStyle(const QString& newStyle) { + QMutexLocker locker{&bigLock}; - if (newStyle != style) { - style = newStyle; - emit styleChanged(style); - } + if (newStyle != style) { + style = newStyle; + emit styleChanged(style); + } } void Settings::setUseEmoticons(bool newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != useEmoticons) { - useEmoticons = newValue; - emit useEmoticonsChanged(useEmoticons); - } + if (newValue != useEmoticons) { + useEmoticons = newValue; + emit useEmoticonsChanged(useEmoticons); + } } bool Settings::getUseEmoticons() const { - QMutexLocker locker{&bigLock}; - return useEmoticons; + QMutexLocker locker{&bigLock}; + return useEmoticons; } bool Settings::getLightTrayIcon() const { - QMutexLocker locker{&bigLock}; - return lightTrayIcon; + QMutexLocker locker{&bigLock}; + return lightTrayIcon; } void Settings::setLightTrayIcon(bool newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != lightTrayIcon) { - lightTrayIcon = newValue; - emit lightTrayIconChanged(lightTrayIcon); - } + if (newValue != lightTrayIcon) { + lightTrayIcon = newValue; + emit lightTrayIconChanged(lightTrayIcon); + } } bool Settings::getStatusChangeNotificationEnabled() const { - QMutexLocker locker{&bigLock}; - return statusChangeNotificationEnabled; + QMutexLocker locker{&bigLock}; + return statusChangeNotificationEnabled; } void Settings::setStatusChangeNotificationEnabled(bool newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != statusChangeNotificationEnabled) { - statusChangeNotificationEnabled = newValue; - emit statusChangeNotificationEnabledChanged( - statusChangeNotificationEnabled); - } + if (newValue != statusChangeNotificationEnabled) { + statusChangeNotificationEnabled = newValue; + emit statusChangeNotificationEnabledChanged(statusChangeNotificationEnabled); + } } bool Settings::getShowGroupJoinLeaveMessages() const { - QMutexLocker locker{&bigLock}; - return showGroupJoinLeaveMessages; + QMutexLocker locker{&bigLock}; + return showGroupJoinLeaveMessages; } void Settings::setShowGroupJoinLeaveMessages(bool newValue) { - QMutexLocker locker{&bigLock}; - if (newValue != showGroupJoinLeaveMessages) { - showGroupJoinLeaveMessages = newValue; - emit showGroupJoinLeaveMessagesChanged(showGroupJoinLeaveMessages); - } + QMutexLocker locker{&bigLock}; + if (newValue != showGroupJoinLeaveMessages) { + showGroupJoinLeaveMessages = newValue; + emit showGroupJoinLeaveMessagesChanged(showGroupJoinLeaveMessages); + } } bool Settings::getSpellCheckingEnabled() const { - const QMutexLocker locker{&bigLock}; - return spellCheckingEnabled; + const QMutexLocker locker{&bigLock}; + return spellCheckingEnabled; } void Settings::setSpellCheckingEnabled(bool newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != spellCheckingEnabled) { - spellCheckingEnabled = newValue; - emit statusChangeNotificationEnabledChanged( - statusChangeNotificationEnabled); - } + if (newValue != spellCheckingEnabled) { + spellCheckingEnabled = newValue; + emit statusChangeNotificationEnabledChanged(statusChangeNotificationEnabled); + } } bool Settings::getNotifySound() const { - QMutexLocker locker{&bigLock}; - return notifySound; + QMutexLocker locker{&bigLock}; + return notifySound; } void Settings::setNotifySound(bool newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != notifySound) { - notifySound = newValue; - emit notifySoundChanged(notifySound); - } + if (newValue != notifySound) { + notifySound = newValue; + emit notifySoundChanged(notifySound); + } } bool Settings::getNotifyHide() const { - QMutexLocker locker{&bigLock}; - return notifyHide; + QMutexLocker locker{&bigLock}; + return notifyHide; } void Settings::setNotifyHide(bool newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != notifyHide) { - notifyHide = newValue; - emit notifyHideChanged(notifyHide); - } + if (newValue != notifyHide) { + notifyHide = newValue; + emit notifyHideChanged(notifyHide); + } } bool Settings::getBusySound() const { - QMutexLocker locker{&bigLock}; - return busySound; + QMutexLocker locker{&bigLock}; + return busySound; } void Settings::setBusySound(bool newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != busySound) { - busySound = newValue; - emit busySoundChanged(busySound); - } + if (newValue != busySound) { + busySound = newValue; + emit busySoundChanged(busySound); + } } bool Settings::getGroupAlwaysNotify() const { - QMutexLocker locker{&bigLock}; - return groupAlwaysNotify; + QMutexLocker locker{&bigLock}; + return groupAlwaysNotify; } void Settings::setGroupAlwaysNotify(bool newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != groupAlwaysNotify) { - groupAlwaysNotify = newValue; - emit groupAlwaysNotifyChanged(groupAlwaysNotify); - } + if (newValue != groupAlwaysNotify) { + groupAlwaysNotify = newValue; + emit groupAlwaysNotifyChanged(groupAlwaysNotify); + } } QString Settings::getTranslation() const { - QMutexLocker locker{&bigLock}; - auto &s = ok::base::OkSettings::getInstance(); - return s.getTranslation(); -} - -void Settings::setTranslation(const QString &newValue) { - QMutexLocker locker{&bigLock}; - auto &s = ok::base::OkSettings::getInstance(); - auto translation = s.getTranslation(); - if (newValue != translation) { - translation = newValue; - s.translationChanged(translation); - } + QMutexLocker locker{&bigLock}; + auto& s = ok::base::OkSettings::getInstance(); + return s.getTranslation(); +} + +void Settings::setTranslation(const QString& newValue) { + QMutexLocker locker{&bigLock}; + auto& s = ok::base::OkSettings::getInstance(); + auto translation = s.getTranslation(); + if (newValue != translation) { + translation = newValue; + s.translationChanged(translation); + } } bool Settings::getForceTCP() const { - QMutexLocker locker{&bigLock}; - return forceTCP; + QMutexLocker locker{&bigLock}; + return forceTCP; } void Settings::setForceTCP(bool enabled) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (enabled != forceTCP) { - forceTCP = enabled; - emit forceTCPChanged(forceTCP); - } + if (enabled != forceTCP) { + forceTCP = enabled; + emit forceTCPChanged(forceTCP); + } } bool Settings::getEnableLanDiscovery() const { - QMutexLocker locker{&bigLock}; - return enableLanDiscovery; + QMutexLocker locker{&bigLock}; + return enableLanDiscovery; } void Settings::setEnableLanDiscovery(bool enabled) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (enabled != enableLanDiscovery) { - enableLanDiscovery = enabled; - emit enableLanDiscoveryChanged(enableLanDiscovery); - } + if (enabled != enableLanDiscovery) { + enableLanDiscovery = enabled; + emit enableLanDiscoveryChanged(enableLanDiscovery); + } } QNetworkProxy Settings::getProxy() const { - QMutexLocker locker{&bigLock}; - - QNetworkProxy proxy; - switch (Settings::getProxyType()) { - case ProxyType::ptNone: - proxy.setType(QNetworkProxy::NoProxy); - break; - case ProxyType::ptSOCKS5: - proxy.setType(QNetworkProxy::Socks5Proxy); - break; - case ProxyType::ptHTTP: - proxy.setType(QNetworkProxy::HttpProxy); - break; - default: - proxy.setType(QNetworkProxy::NoProxy); - qWarning() << "Invalid Proxy type, setting to NoProxy"; - break; - } - - proxy.setHostName(Settings::getProxyAddr()); - proxy.setPort(Settings::getProxyPort()); - return proxy; + QMutexLocker locker{&bigLock}; + + QNetworkProxy proxy; + switch (Settings::getProxyType()) { + case ProxyType::ptNone: + proxy.setType(QNetworkProxy::NoProxy); + break; + case ProxyType::ptSOCKS5: + proxy.setType(QNetworkProxy::Socks5Proxy); + break; + case ProxyType::ptHTTP: + proxy.setType(QNetworkProxy::HttpProxy); + break; + default: + proxy.setType(QNetworkProxy::NoProxy); + qWarning() << "Invalid Proxy type, setting to NoProxy"; + break; + } + + proxy.setHostName(Settings::getProxyAddr()); + proxy.setPort(Settings::getProxyPort()); + return proxy; } Settings::ProxyType Settings::getProxyType() const { - QMutexLocker locker{&bigLock}; - return proxyType; + QMutexLocker locker{&bigLock}; + return proxyType; } void Settings::setProxyType(ProxyType newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != proxyType) { - proxyType = newValue; - emit proxyTypeChanged(proxyType); - } + if (newValue != proxyType) { + proxyType = newValue; + emit proxyTypeChanged(proxyType); + } } QString Settings::getProxyAddr() const { - QMutexLocker locker{&bigLock}; - return proxyAddr; + QMutexLocker locker{&bigLock}; + return proxyAddr; } -void Settings::setProxyAddr(const QString &address) { - QMutexLocker locker{&bigLock}; +void Settings::setProxyAddr(const QString& address) { + QMutexLocker locker{&bigLock}; - if (address != proxyAddr) { - proxyAddr = address; - emit proxyAddressChanged(proxyAddr); - } + if (address != proxyAddr) { + proxyAddr = address; + emit proxyAddressChanged(proxyAddr); + } } quint16 Settings::getProxyPort() const { - QMutexLocker locker{&bigLock}; - return proxyPort; + QMutexLocker locker{&bigLock}; + return proxyPort; } void Settings::setProxyPort(quint16 port) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (port != proxyPort) { - proxyPort = port; - emit proxyPortChanged(proxyPort); - } + if (port != proxyPort) { + proxyPort = port; + emit proxyPortChanged(proxyPort); + } } bool Settings::getEnableLogging() const { - QMutexLocker locker{&bigLock}; - return enableLogging; + QMutexLocker locker{&bigLock}; + return enableLogging; } void Settings::setEnableLogging(bool newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != enableLogging) { - enableLogging = newValue; - emit enableLoggingChanged(enableLogging); - } + if (newValue != enableLogging) { + enableLogging = newValue; + emit enableLoggingChanged(enableLogging); + } } int Settings::getAutoAwayTime() const { - QMutexLocker locker{&bigLock}; - return autoAwayTime; + QMutexLocker locker{&bigLock}; + return autoAwayTime; } /** @@ -1238,883 +1194,868 @@ int Settings::getAutoAwayTime() const { * @note Values < 0 default to 10 minutes. */ void Settings::setAutoAwayTime(int newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue < 0) - newValue = 10; + if (newValue < 0) newValue = 10; - if (newValue != autoAwayTime) { - autoAwayTime = newValue; - emit autoAwayTimeChanged(autoAwayTime); - } + if (newValue != autoAwayTime) { + autoAwayTime = newValue; + emit autoAwayTimeChanged(autoAwayTime); + } } -QString Settings::getAutoAcceptDir(const FriendId &id) const { - QMutexLocker locker{&bigLock}; +QString Settings::getAutoAcceptDir(const FriendId& id) const { + QMutexLocker locker{&bigLock}; - auto it = friendLst.find(id.getByteArray()); - if (it != friendLst.end()) - return it->autoAcceptDir; + auto it = friendLst.find(id.getByteArray()); + if (it != friendLst.end()) return it->autoAcceptDir; - return QString(); + return QString(); } -void Settings::setAutoAcceptDir(const FriendId &id, const QString &dir) { - QMutexLocker locker{&bigLock}; +void Settings::setAutoAcceptDir(const FriendId& id, const QString& dir) { + QMutexLocker locker{&bigLock}; - auto &frnd = getOrInsertFriendPropRef(id); + auto& frnd = getOrInsertFriendPropRef(id); - if (frnd.autoAcceptDir != dir) { - frnd.autoAcceptDir = dir; - emit autoAcceptDirChanged(id, dir); - } + if (frnd.autoAcceptDir != dir) { + frnd.autoAcceptDir = dir; + emit autoAcceptDirChanged(id, dir); + } } -Settings::AutoAcceptCallFlags -Settings::getAutoAcceptCall(const FriendId &id) const { - QMutexLocker locker{&bigLock}; +Settings::AutoAcceptCallFlags Settings::getAutoAcceptCall(const FriendId& id) const { + QMutexLocker locker{&bigLock}; - auto it = friendLst.find(id.getByteArray()); - if (it != friendLst.end()) - return it->autoAcceptCall; + auto it = friendLst.find(id.getByteArray()); + if (it != friendLst.end()) return it->autoAcceptCall; - return Settings::AutoAcceptCallFlags(); + return Settings::AutoAcceptCallFlags(); } -void Settings::setAutoAcceptCall(const FriendId &id, AutoAcceptCallFlags accept) { - QMutexLocker locker{&bigLock}; +void Settings::setAutoAcceptCall(const FriendId& id, AutoAcceptCallFlags accept) { + QMutexLocker locker{&bigLock}; - auto &frnd = getOrInsertFriendPropRef(id); + auto& frnd = getOrInsertFriendPropRef(id); - if (frnd.autoAcceptCall != accept) { - frnd.autoAcceptCall = accept; - emit autoAcceptCallChanged(id, accept); - } + if (frnd.autoAcceptCall != accept) { + frnd.autoAcceptCall = accept; + emit autoAcceptCallChanged(id, accept); + } } -bool Settings::getAutoGroupInvite(const FriendId &id) const { - QMutexLocker locker{&bigLock}; +bool Settings::getAutoGroupInvite(const FriendId& id) const { + QMutexLocker locker{&bigLock}; - auto it = friendLst.find(id.getByteArray()); - if (it != friendLst.end()) { - return it->autoGroupInvite; - } + auto it = friendLst.find(id.getByteArray()); + if (it != friendLst.end()) { + return it->autoGroupInvite; + } - return false; + return false; } -void Settings::setAutoGroupInvite(const FriendId &id, bool accept) { - QMutexLocker locker{&bigLock}; +void Settings::setAutoGroupInvite(const FriendId& id, bool accept) { + QMutexLocker locker{&bigLock}; - auto &frnd = getOrInsertFriendPropRef(id); + auto& frnd = getOrInsertFriendPropRef(id); - if (frnd.autoGroupInvite != accept) { - frnd.autoGroupInvite = accept; - emit autoGroupInviteChanged(id, accept); - } + if (frnd.autoGroupInvite != accept) { + frnd.autoGroupInvite = accept; + emit autoGroupInviteChanged(id, accept); + } } -QString Settings::getContactNote(const FriendId &id) const { - QMutexLocker locker{&bigLock}; +QString Settings::getContactNote(const FriendId& id) const { + QMutexLocker locker{&bigLock}; - auto it = friendLst.find(id.getByteArray()); - if (it != friendLst.end()) - return it->note; + auto it = friendLst.find(id.getByteArray()); + if (it != friendLst.end()) return it->note; - return QString(); + return QString(); } -void Settings::setContactNote(const FriendId &id, const QString ¬e) { - QMutexLocker locker{&bigLock}; +void Settings::setContactNote(const FriendId& id, const QString& note) { + QMutexLocker locker{&bigLock}; - auto &frnd = getOrInsertFriendPropRef(id); + auto& frnd = getOrInsertFriendPropRef(id); - if (frnd.note != note) { - frnd.note = note; - emit contactNoteChanged(id, note); - } + if (frnd.note != note) { + frnd.note = note; + emit contactNoteChanged(id, note); + } } QString Settings::getGlobalAutoAcceptDir() const { - QMutexLocker locker{&bigLock}; - return globalAutoAcceptDir; + QMutexLocker locker{&bigLock}; + return globalAutoAcceptDir; } -void Settings::setGlobalAutoAcceptDir(const QString &newValue) { - QMutexLocker locker{&bigLock}; +void Settings::setGlobalAutoAcceptDir(const QString& newValue) { + QMutexLocker locker{&bigLock}; - if (newValue != globalAutoAcceptDir) { - globalAutoAcceptDir = newValue; - emit globalAutoAcceptDirChanged(globalAutoAcceptDir); - } + if (newValue != globalAutoAcceptDir) { + globalAutoAcceptDir = newValue; + emit globalAutoAcceptDirChanged(globalAutoAcceptDir); + } } size_t Settings::getMaxAutoAcceptSize() const { - QMutexLocker locker{&bigLock}; - return autoAcceptMaxSize; + QMutexLocker locker{&bigLock}; + return autoAcceptMaxSize; } void Settings::setMaxAutoAcceptSize(size_t size) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (size != autoAcceptMaxSize) { - autoAcceptMaxSize = size; - emit autoAcceptMaxSizeChanged(autoAcceptMaxSize); - } + if (size != autoAcceptMaxSize) { + autoAcceptMaxSize = size; + emit autoAcceptMaxSizeChanged(autoAcceptMaxSize); + } } -const QFont &Settings::getChatMessageFont() const { - QMutexLocker locker(&bigLock); - return chatMessageFont; +const QFont& Settings::getChatMessageFont() const { + QMutexLocker locker(&bigLock); + return chatMessageFont; } -void Settings::setChatMessageFont(const QFont &font) { - QMutexLocker locker(&bigLock); +void Settings::setChatMessageFont(const QFont& font) { + QMutexLocker locker(&bigLock); - if (font != chatMessageFont) { - chatMessageFont = font; - emit chatMessageFontChanged(chatMessageFont); - } + if (font != chatMessageFont) { + chatMessageFont = font; + emit chatMessageFontChanged(chatMessageFont); + } } -void Settings::setWidgetData(const QString &uniqueName, - const QByteArray &data) { - QMutexLocker locker{&bigLock}; +void Settings::setWidgetData(const QString& uniqueName, const QByteArray& data) { + QMutexLocker locker{&bigLock}; - if (!widgetSettings.contains(uniqueName) || - widgetSettings[uniqueName] != data) { - widgetSettings[uniqueName] = data; - emit widgetDataChanged(uniqueName); - } + if (!widgetSettings.contains(uniqueName) || widgetSettings[uniqueName] != data) { + widgetSettings[uniqueName] = data; + emit widgetDataChanged(uniqueName); + } } -QByteArray Settings::getWidgetData(const QString &uniqueName) const { - QMutexLocker locker{&bigLock}; - return widgetSettings.value(uniqueName); +QByteArray Settings::getWidgetData(const QString& uniqueName) const { + QMutexLocker locker{&bigLock}; + return widgetSettings.value(uniqueName); } QString Settings::getSmileyPack() const { - QMutexLocker locker{&bigLock}; - return smileyPack; + QMutexLocker locker{&bigLock}; + return smileyPack; } -void Settings::setSmileyPack(const QString &value) { - QMutexLocker locker{&bigLock}; +void Settings::setSmileyPack(const QString& value) { + QMutexLocker locker{&bigLock}; - if (value != smileyPack) { - smileyPack = value; - emit smileyPackChanged(smileyPack); - } + if (value != smileyPack) { + smileyPack = value; + emit smileyPackChanged(smileyPack); + } } int Settings::getEmojiFontPointSize() const { - QMutexLocker locker{&bigLock}; - return emojiFontPointSize; + QMutexLocker locker{&bigLock}; + return emojiFontPointSize; } void Settings::setEmojiFontPointSize(int value) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (value != emojiFontPointSize) { - emojiFontPointSize = value; - emit emojiFontPointSizeChanged(emojiFontPointSize); - } + if (value != emojiFontPointSize) { + emojiFontPointSize = value; + emit emojiFontPointSizeChanged(emojiFontPointSize); + } } -const QString &Settings::getTimestampFormat() const { - QMutexLocker locker{&bigLock}; - return timestampFormat; +const QString& Settings::getTimestampFormat() const { + QMutexLocker locker{&bigLock}; + return timestampFormat; } -void Settings::setTimestampFormat(const QString &format) { - QMutexLocker locker{&bigLock}; +void Settings::setTimestampFormat(const QString& format) { + QMutexLocker locker{&bigLock}; - if (format != timestampFormat) { - timestampFormat = format; - emit timestampFormatChanged(timestampFormat); - } + if (format != timestampFormat) { + timestampFormat = format; + emit timestampFormatChanged(timestampFormat); + } } -const QString &Settings::getDateFormat() const { - QMutexLocker locker{&bigLock}; - return dateFormat; +const QString& Settings::getDateFormat() const { + QMutexLocker locker{&bigLock}; + return dateFormat; } -void Settings::setDateFormat(const QString &format) { - QMutexLocker locker{&bigLock}; +void Settings::setDateFormat(const QString& format) { + QMutexLocker locker{&bigLock}; - if (format != dateFormat) { - dateFormat = format; - emit dateFormatChanged(dateFormat); - } + if (format != dateFormat) { + dateFormat = format; + emit dateFormatChanged(dateFormat); + } } Settings::StyleType Settings::getStylePreference() const { - QMutexLocker locker{&bigLock}; - return stylePreference; + QMutexLocker locker{&bigLock}; + return stylePreference; } void Settings::setStylePreference(StyleType newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != stylePreference) { - stylePreference = newValue; - emit stylePreferenceChanged(stylePreference); - } + if (newValue != stylePreference) { + stylePreference = newValue; + emit stylePreferenceChanged(stylePreference); + } } QByteArray Settings::getWindowGeometry() const { - QMutexLocker locker{&bigLock}; - return windowGeometry; + QMutexLocker locker{&bigLock}; + return windowGeometry; } -void Settings::setWindowGeometry(const QByteArray &value) { - QMutexLocker locker{&bigLock}; +void Settings::setWindowGeometry(const QByteArray& value) { + QMutexLocker locker{&bigLock}; - if (value != windowGeometry) { - windowGeometry = value; - emit windowGeometryChanged(windowGeometry); - } + if (value != windowGeometry) { + windowGeometry = value; + emit windowGeometryChanged(windowGeometry); + } } QByteArray Settings::getWindowState() const { - QMutexLocker locker{&bigLock}; - return windowState; + QMutexLocker locker{&bigLock}; + return windowState; } -void Settings::setWindowState(const QByteArray &value) { - QMutexLocker locker{&bigLock}; +void Settings::setWindowState(const QByteArray& value) { + QMutexLocker locker{&bigLock}; - if (value != windowState) { - windowState = value; - emit windowStateChanged(windowState); - } + if (value != windowState) { + windowState = value; + emit windowStateChanged(windowState); + } } bool Settings::getCheckUpdates() const { - QMutexLocker locker{&bigLock}; - return checkUpdates; + QMutexLocker locker{&bigLock}; + return checkUpdates; } void Settings::setCheckUpdates(bool newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != checkUpdates) { - checkUpdates = newValue; - emit checkUpdatesChanged(checkUpdates); - } + if (newValue != checkUpdates) { + checkUpdates = newValue; + emit checkUpdatesChanged(checkUpdates); + } } bool Settings::getNotify() const { - QMutexLocker locker{&bigLock}; - return notify; + QMutexLocker locker{&bigLock}; + return notify; } void Settings::setNotify(bool newValue) { - QMutexLocker locker{&bigLock}; - if (newValue != notify) { - notify = newValue; - emit notifyChanged(notify); - } + QMutexLocker locker{&bigLock}; + if (newValue != notify) { + notify = newValue; + emit notifyChanged(notify); + } } bool Settings::getShowWindow() const { - QMutexLocker locker{&bigLock}; - return showWindow; + QMutexLocker locker{&bigLock}; + return showWindow; } void Settings::setShowWindow(bool newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != showWindow) { - showWindow = newValue; - emit showWindowChanged(showWindow); - } + if (newValue != showWindow) { + showWindow = newValue; + emit showWindowChanged(showWindow); + } } bool Settings::getDesktopNotify() const { - QMutexLocker locker{&bigLock}; - return desktopNotify; + QMutexLocker locker{&bigLock}; + return desktopNotify; } void Settings::setDesktopNotify(bool enabled) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (enabled != desktopNotify) { - desktopNotify = enabled; - emit desktopNotifyChanged(desktopNotify); - } + if (enabled != desktopNotify) { + desktopNotify = enabled; + emit desktopNotifyChanged(desktopNotify); + } } QByteArray Settings::getSplitterState() const { - QMutexLocker locker{&bigLock}; - return splitterState; + QMutexLocker locker{&bigLock}; + return splitterState; } -void Settings::setSplitterState(const QByteArray &value) { - QMutexLocker locker{&bigLock}; +void Settings::setSplitterState(const QByteArray& value) { + QMutexLocker locker{&bigLock}; - if (value != splitterState) { - splitterState = value; - emit splitterStateChanged(splitterState); - } + if (value != splitterState) { + splitterState = value; + emit splitterStateChanged(splitterState); + } } QByteArray Settings::getDialogGeometry() const { - QMutexLocker locker{&bigLock}; - return dialogGeometry; + QMutexLocker locker{&bigLock}; + return dialogGeometry; } -void Settings::setDialogGeometry(const QByteArray &value) { - QMutexLocker locker{&bigLock}; +void Settings::setDialogGeometry(const QByteArray& value) { + QMutexLocker locker{&bigLock}; - if (value != dialogGeometry) { - dialogGeometry = value; - emit dialogGeometryChanged(dialogGeometry); - } + if (value != dialogGeometry) { + dialogGeometry = value; + emit dialogGeometryChanged(dialogGeometry); + } } QByteArray Settings::getDialogSplitterState() const { - QMutexLocker locker{&bigLock}; - return dialogSplitterState; + QMutexLocker locker{&bigLock}; + return dialogSplitterState; } -void Settings::setDialogSplitterState(const QByteArray &value) { - QMutexLocker locker{&bigLock}; +void Settings::setDialogSplitterState(const QByteArray& value) { + QMutexLocker locker{&bigLock}; - if (value != dialogSplitterState) { - dialogSplitterState = value; - emit dialogSplitterStateChanged(dialogSplitterState); - } + if (value != dialogSplitterState) { + dialogSplitterState = value; + emit dialogSplitterStateChanged(dialogSplitterState); + } } QByteArray Settings::getDialogSettingsGeometry() const { - QMutexLocker locker{&bigLock}; - return dialogSettingsGeometry; + QMutexLocker locker{&bigLock}; + return dialogSettingsGeometry; } -void Settings::setDialogSettingsGeometry(const QByteArray &value) { - QMutexLocker locker{&bigLock}; +void Settings::setDialogSettingsGeometry(const QByteArray& value) { + QMutexLocker locker{&bigLock}; - if (value != dialogSettingsGeometry) { - dialogSettingsGeometry = value; - emit dialogSettingsGeometryChanged(dialogSettingsGeometry); - } + if (value != dialogSettingsGeometry) { + dialogSettingsGeometry = value; + emit dialogSettingsGeometryChanged(dialogSettingsGeometry); + } } bool Settings::getTypingNotification() const { - QMutexLocker locker{&bigLock}; - return typingNotification; + QMutexLocker locker{&bigLock}; + return typingNotification; } void Settings::setTypingNotification(bool enabled) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (enabled != typingNotification) { - typingNotification = enabled; - emit typingNotificationChanged(typingNotification); - } + if (enabled != typingNotification) { + typingNotification = enabled; + emit typingNotificationChanged(typingNotification); + } } QStringList Settings::getBlackList() const { - QMutexLocker locker{&bigLock}; - return blackList; + QMutexLocker locker{&bigLock}; + return blackList; } -void Settings::setBlackList(const QStringList &blist) { - QMutexLocker locker{&bigLock}; +void Settings::setBlackList(const QStringList& blist) { + QMutexLocker locker{&bigLock}; - if (blist != blackList) { - blackList = blist; - emit blackListChanged(blackList); - } + if (blist != blackList) { + blackList = blist; + emit blackListChanged(blackList); + } } QString Settings::getInDev() const { - QMutexLocker locker{&bigLock}; - return inDev; + QMutexLocker locker{&bigLock}; + return inDev; } -void Settings::setInDev(const QString &deviceSpecifier) { - QMutexLocker locker{&bigLock}; +void Settings::setInDev(const QString& deviceSpecifier) { + QMutexLocker locker{&bigLock}; - if (deviceSpecifier != inDev) { - inDev = deviceSpecifier; - emit inDevChanged(inDev); - } + if (deviceSpecifier != inDev) { + inDev = deviceSpecifier; + emit inDevChanged(inDev); + } } bool Settings::getAudioInDevEnabled() const { - QMutexLocker locker(&bigLock); - return audioInDevEnabled; + QMutexLocker locker(&bigLock); + return audioInDevEnabled; } void Settings::setAudioInDevEnabled(bool enabled) { - QMutexLocker locker(&bigLock); + QMutexLocker locker(&bigLock); - if (enabled != audioInDevEnabled) { - audioInDevEnabled = enabled; - emit audioInDevEnabledChanged(enabled); - } + if (enabled != audioInDevEnabled) { + audioInDevEnabled = enabled; + emit audioInDevEnabledChanged(enabled); + } } qreal Settings::getAudioInGainDecibel() const { - QMutexLocker locker{&bigLock}; - return audioInGainDecibel; + QMutexLocker locker{&bigLock}; + return audioInGainDecibel; } void Settings::setAudioInGainDecibel(qreal dB) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (dB < audioInGainDecibel || dB > audioInGainDecibel) { - audioInGainDecibel = dB; - emit audioInGainDecibelChanged(audioInGainDecibel); - } + if (dB < audioInGainDecibel || dB > audioInGainDecibel) { + audioInGainDecibel = dB; + emit audioInGainDecibelChanged(audioInGainDecibel); + } } qreal Settings::getAudioThreshold() const { - QMutexLocker locker{&bigLock}; - return audioThreshold; + QMutexLocker locker{&bigLock}; + return audioThreshold; } void Settings::setAudioThreshold(qreal percent) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (percent < audioThreshold || percent > audioThreshold) { - audioThreshold = percent; - emit audioThresholdChanged(audioThreshold); - } + if (percent < audioThreshold || percent > audioThreshold) { + audioThreshold = percent; + emit audioThresholdChanged(audioThreshold); + } } QString Settings::getVideoDev() const { - QMutexLocker locker{&bigLock}; - return videoDev; + QMutexLocker locker{&bigLock}; + return videoDev; } -void Settings::setVideoDev(const QString &deviceSpecifier) { - QMutexLocker locker{&bigLock}; +void Settings::setVideoDev(const QString& deviceSpecifier) { + QMutexLocker locker{&bigLock}; - if (deviceSpecifier != videoDev) { - videoDev = deviceSpecifier; - emit videoDevChanged(videoDev); - } + if (deviceSpecifier != videoDev) { + videoDev = deviceSpecifier; + emit videoDevChanged(videoDev); + } } QString Settings::getOutDev() const { - QMutexLocker locker{&bigLock}; - return outDev; + QMutexLocker locker{&bigLock}; + return outDev; } -void Settings::setOutDev(const QString &deviceSpecifier) { - QMutexLocker locker{&bigLock}; +void Settings::setOutDev(const QString& deviceSpecifier) { + QMutexLocker locker{&bigLock}; - if (deviceSpecifier != outDev) { - outDev = deviceSpecifier; - emit outDevChanged(outDev); - } + if (deviceSpecifier != outDev) { + outDev = deviceSpecifier; + emit outDevChanged(outDev); + } } bool Settings::getAudioOutDevEnabled() const { - QMutexLocker locker(&bigLock); - return audioOutDevEnabled; + QMutexLocker locker(&bigLock); + return audioOutDevEnabled; } void Settings::setAudioOutDevEnabled(bool enabled) { - QMutexLocker locker(&bigLock); + QMutexLocker locker(&bigLock); - if (enabled != audioOutDevEnabled) { - audioOutDevEnabled = enabled; - emit audioOutDevEnabledChanged(audioOutDevEnabled); - } + if (enabled != audioOutDevEnabled) { + audioOutDevEnabled = enabled; + emit audioOutDevEnabledChanged(audioOutDevEnabled); + } } int Settings::getOutVolume() const { - QMutexLocker locker{&bigLock}; - return outVolume; + QMutexLocker locker{&bigLock}; + return outVolume; } void Settings::setOutVolume(int volume) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (volume != outVolume) { - outVolume = volume; - emit outVolumeChanged(outVolume); - } + if (volume != outVolume) { + outVolume = volume; + emit outVolumeChanged(outVolume); + } } int Settings::getAudioBitrate() const { - const QMutexLocker locker{&bigLock}; - return audioBitrate; + const QMutexLocker locker{&bigLock}; + return audioBitrate; } void Settings::setAudioBitrate(int bitrate) { - const QMutexLocker locker{&bigLock}; + const QMutexLocker locker{&bigLock}; - if (bitrate != audioBitrate) { - audioBitrate = bitrate; - emit audioBitrateChanged(audioBitrate); - } + if (bitrate != audioBitrate) { + audioBitrate = bitrate; + emit audioBitrateChanged(audioBitrate); + } } QRect Settings::getScreenRegion() const { - QMutexLocker locker(&bigLock); - return screenRegion; + QMutexLocker locker(&bigLock); + return screenRegion; } -void Settings::setScreenRegion(const QRect &value) { - QMutexLocker locker{&bigLock}; +void Settings::setScreenRegion(const QRect& value) { + QMutexLocker locker{&bigLock}; - if (value != screenRegion) { - screenRegion = value; - emit screenRegionChanged(screenRegion); - } + if (value != screenRegion) { + screenRegion = value; + emit screenRegionChanged(screenRegion); + } } bool Settings::getScreenGrabbed() const { - QMutexLocker locker(&bigLock); - return screenGrabbed; + QMutexLocker locker(&bigLock); + return screenGrabbed; } void Settings::setScreenGrabbed(bool value) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (value != screenGrabbed) { - screenGrabbed = value; - emit screenGrabbedChanged(screenGrabbed); - } + if (value != screenGrabbed) { + screenGrabbed = value; + emit screenGrabbedChanged(screenGrabbed); + } } QRect Settings::getCamVideoRes() const { - QMutexLocker locker{&bigLock}; - return camVideoRes; + QMutexLocker locker{&bigLock}; + return camVideoRes; } void Settings::setCamVideoRes(QRect newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != camVideoRes) { - camVideoRes = newValue; - emit camVideoResChanged(camVideoRes); - } + if (newValue != camVideoRes) { + camVideoRes = newValue; + emit camVideoResChanged(camVideoRes); + } } float Settings::getCamVideoFPS() const { - QMutexLocker locker{&bigLock}; - return camVideoFPS; + QMutexLocker locker{&bigLock}; + return camVideoFPS; } void Settings::setCamVideoFPS(float newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != camVideoFPS) { - camVideoFPS = newValue; - emit camVideoFPSChanged(camVideoFPS); - } + if (newValue != camVideoFPS) { + camVideoFPS = newValue; + emit camVideoFPSChanged(camVideoFPS); + } } -QString Settings::getFriendAddress(const QString &publicKey) const { - QMutexLocker locker{&bigLock}; - // TODO: using ToxId here is a hack - QByteArray key = ToxId(publicKey).getPublicKey().getByteArray(); - auto it = friendLst.find(key); - if (it != friendLst.end()) - return it->addr; +QString Settings::getFriendAddress(const QString& publicKey) const { + QMutexLocker locker{&bigLock}; + // TODO: using ToxId here is a hack + QByteArray key = ToxId(publicKey).getPublicKey().getByteArray(); + auto it = friendLst.find(key); + if (it != friendLst.end()) return it->addr; - return QString(); + return QString(); } -void Settings::updateFriendAddress(const QString &newAddr) { - QMutexLocker locker{&bigLock}; - // TODO: using ToxId here is a hack - auto key = ToxId(newAddr).getPublicKey(); - auto &frnd = getOrInsertFriendPropRef(key); - frnd.addr = newAddr; +void Settings::updateFriendAddress(const QString& newAddr) { + QMutexLocker locker{&bigLock}; + // TODO: using ToxId here is a hack + auto key = ToxId(newAddr).getPublicKey(); + auto& frnd = getOrInsertFriendPropRef(key); + frnd.addr = newAddr; } -QString Settings::getFriendAlias(const ContactId &id) const { - QMutexLocker locker{&bigLock}; - if (friendLst.isEmpty()) - return {}; +QString Settings::getFriendAlias(const ContactId& id) const { + QMutexLocker locker{&bigLock}; + if (friendLst.isEmpty()) return {}; - auto it = friendLst.find(id.getByteArray()); - if (it != friendLst.end()) - return it->alias; + auto it = friendLst.find(id.getByteArray()); + if (it != friendLst.end()) return it->alias; - return {}; + return {}; } -void Settings::setFriendAlias(const FriendId &id, const QString &alias) { - QMutexLocker locker{&bigLock}; - auto &frnd = getOrInsertFriendPropRef(id); - frnd.alias = alias; +void Settings::setFriendAlias(const FriendId& id, const QString& alias) { + QMutexLocker locker{&bigLock}; + auto& frnd = getOrInsertFriendPropRef(id); + frnd.alias = alias; } -int Settings::getFriendCircleID(const FriendId &id) const { - QMutexLocker locker{&bigLock}; - auto it = friendLst.find(id.getByteArray()); - if (it != friendLst.end()) - return it->circleID; +int Settings::getFriendCircleID(const FriendId& id) const { + QMutexLocker locker{&bigLock}; + auto it = friendLst.find(id.getByteArray()); + if (it != friendLst.end()) return it->circleID; - return -1; + return -1; } -void Settings::setFriendCircleID(const FriendId &id, int circleID) { - QMutexLocker locker{&bigLock}; - auto &frnd = getOrInsertFriendPropRef(id); - frnd.circleID = circleID; +void Settings::setFriendCircleID(const FriendId& id, int circleID) { + QMutexLocker locker{&bigLock}; + auto& frnd = getOrInsertFriendPropRef(id); + frnd.circleID = circleID; } -QDateTime Settings::getFriendActivity(const FriendId &id) const { - QMutexLocker locker{&bigLock}; - auto it = friendLst.find(id.getByteArray()); - if (it != friendLst.end()) - return it->activity; +QDateTime Settings::getFriendActivity(const FriendId& id) const { + QMutexLocker locker{&bigLock}; + auto it = friendLst.find(id.getByteArray()); + if (it != friendLst.end()) return it->activity; - return QDateTime(); + return QDateTime(); } -void Settings::setFriendActivity(const FriendId &id, const QDateTime &activity) { - QMutexLocker locker{&bigLock}; - auto &frnd = getOrInsertFriendPropRef(id); - frnd.activity = activity; +void Settings::setFriendActivity(const FriendId& id, const QDateTime& activity) { + QMutexLocker locker{&bigLock}; + auto& frnd = getOrInsertFriendPropRef(id); + frnd.activity = activity; } -void Settings::saveFriendSettings(const FriendId &id) { - Q_UNUSED(id); - savePersonal(); +void Settings::saveFriendSettings(const FriendId& id) { + Q_UNUSED(id); + savePersonal(); } -void Settings::removeFriendSettings(const FriendId &id) { - QMutexLocker locker{&bigLock}; - friendLst.remove(id.getByteArray()); +void Settings::removeFriendSettings(const FriendId& id) { + QMutexLocker locker{&bigLock}; + friendLst.remove(id.getByteArray()); } bool Settings::getCompactLayout() const { - QMutexLocker locker{&bigLock}; - return compactLayout; + QMutexLocker locker{&bigLock}; + return compactLayout; } void Settings::setCompactLayout(bool value) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (value != compactLayout) { - compactLayout = value; - emit compactLayoutChanged(value); - } + if (value != compactLayout) { + compactLayout = value; + emit compactLayoutChanged(value); + } } Settings::FriendListSortingMode Settings::getFriendSortingMode() const { - QMutexLocker locker{&bigLock}; - return sortingMode; + QMutexLocker locker{&bigLock}; + return sortingMode; } void Settings::setFriendSortingMode(FriendListSortingMode mode) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (mode != sortingMode) { - sortingMode = mode; - emit sortingModeChanged(sortingMode); - } + if (mode != sortingMode) { + sortingMode = mode; + emit sortingModeChanged(sortingMode); + } } bool Settings::getSeparateWindow() const { - QMutexLocker locker{&bigLock}; - return separateWindow; + QMutexLocker locker{&bigLock}; + return separateWindow; } void Settings::setSeparateWindow(bool value) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (value != separateWindow) { - separateWindow = value; - emit separateWindowChanged(value); - } + if (value != separateWindow) { + separateWindow = value; + emit separateWindowChanged(value); + } } bool Settings::getDontGroupWindows() const { - QMutexLocker locker{&bigLock}; - return dontGroupWindows; + QMutexLocker locker{&bigLock}; + return dontGroupWindows; } void Settings::setDontGroupWindows(bool value) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (value != dontGroupWindows) { - dontGroupWindows = value; - emit dontGroupWindowsChanged(dontGroupWindows); - } + if (value != dontGroupWindows) { + dontGroupWindows = value; + emit dontGroupWindowsChanged(dontGroupWindows); + } } bool Settings::getGroupchatPosition() const { - QMutexLocker locker{&bigLock}; - return groupchatPosition; + QMutexLocker locker{&bigLock}; + return groupchatPosition; } void Settings::setGroupchatPosition(bool value) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (value != groupchatPosition) { - groupchatPosition = value; - emit groupchatPositionChanged(value); - } + if (value != groupchatPosition) { + groupchatPosition = value; + emit groupchatPositionChanged(value); + } } bool Settings::getShowIdenticons() const { - const QMutexLocker locker{&bigLock}; - return showIdenticons; + const QMutexLocker locker{&bigLock}; + return showIdenticons; } void Settings::setShowIdenticons(bool value) { - const QMutexLocker locker{&bigLock}; + const QMutexLocker locker{&bigLock}; - if (value != showIdenticons) { - showIdenticons = value; - emit showIdenticonsChanged(value); - } + if (value != showIdenticons) { + showIdenticons = value; + emit showIdenticonsChanged(value); + } } int Settings::getCircleCount() const { - QMutexLocker locker{&bigLock}; - return circleLst.size(); + QMutexLocker locker{&bigLock}; + return circleLst.size(); } QString Settings::getCircleName(int id) const { - QMutexLocker locker{&bigLock}; - return circleLst[id].name; + QMutexLocker locker{&bigLock}; + return circleLst[id].name; } -void Settings::setCircleName(int id, const QString &name) { - QMutexLocker locker{&bigLock}; - circleLst[id].name = name; - savePersonal(); +void Settings::setCircleName(int id, const QString& name) { + QMutexLocker locker{&bigLock}; + circleLst[id].name = name; + savePersonal(); } -int Settings::addCircle(const QString &name) { - QMutexLocker locker{&bigLock}; +int Settings::addCircle(const QString& name) { + QMutexLocker locker{&bigLock}; - circleProp cp; - cp.expanded = false; + circleProp cp; + cp.expanded = false; - if (name.isEmpty()) - cp.name = tr("Circle #%1").arg(circleLst.count() + 1); - else - cp.name = name; + if (name.isEmpty()) + cp.name = tr("Circle #%1").arg(circleLst.count() + 1); + else + cp.name = name; - circleLst.append(cp); - savePersonal(); - return circleLst.count() - 1; + circleLst.append(cp); + savePersonal(); + return circleLst.count() - 1; } bool Settings::getCircleExpanded(int id) const { - QMutexLocker locker{&bigLock}; - return circleLst[id].expanded; + QMutexLocker locker{&bigLock}; + return circleLst[id].expanded; } void Settings::setCircleExpanded(int id, bool expanded) { - QMutexLocker locker{&bigLock}; - circleLst[id].expanded = expanded; + QMutexLocker locker{&bigLock}; + circleLst[id].expanded = expanded; } -bool Settings::addFriendRequest(const QString &friendAddress, - const QString &message) { - QMutexLocker locker{&bigLock}; +bool Settings::addFriendRequest(const QString& friendAddress, const QString& message) { + QMutexLocker locker{&bigLock}; - for (auto queued : friendRequests) { - if (queued.address == friendAddress) { - queued.message = message; - queued.read = false; - return false; + for (auto queued : friendRequests) { + if (queued.address == friendAddress) { + queued.message = message; + queued.read = false; + return false; + } } - } - Request request; - request.address = friendAddress; - request.message = message; - request.read = false; - friendRequests.push_back(request); - return true; + Request request; + request.address = friendAddress; + request.message = message; + request.read = false; + friendRequests.push_back(request); + return true; } unsigned int Settings::getUnreadFriendRequests() const { - QMutexLocker locker{&bigLock}; - unsigned int unreadFriendRequests = 0; - for (auto request : friendRequests) - if (!request.read) - ++unreadFriendRequests; + QMutexLocker locker{&bigLock}; + unsigned int unreadFriendRequests = 0; + for (auto request : friendRequests) + if (!request.read) ++unreadFriendRequests; - return unreadFriendRequests; + return unreadFriendRequests; } Settings::Request Settings::getFriendRequest(int index) const { - QMutexLocker locker{&bigLock}; - return friendRequests.at(index); + QMutexLocker locker{&bigLock}; + return friendRequests.at(index); } int Settings::getFriendRequestSize() const { - QMutexLocker locker{&bigLock}; - return friendRequests.size(); + QMutexLocker locker{&bigLock}; + return friendRequests.size(); } void Settings::clearUnreadFriendRequests() { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - for (auto &request : friendRequests) - request.read = true; + for (auto& request : friendRequests) request.read = true; } void Settings::removeFriendRequest(int index) { - QMutexLocker locker{&bigLock}; - friendRequests.removeAt(index); + QMutexLocker locker{&bigLock}; + friendRequests.removeAt(index); } void Settings::readFriendRequest(int index) { - QMutexLocker locker{&bigLock}; - friendRequests[index].read = true; + QMutexLocker locker{&bigLock}; + friendRequests[index].read = true; } int Settings::removeCircle(int id) { - // Replace index with last one and remove last one instead. - // This gives you contiguous ids all the time. - circleLst[id] = circleLst.last(); - circleLst.pop_back(); - savePersonal(); - return circleLst.count(); + // Replace index with last one and remove last one instead. + // This gives you contiguous ids all the time. + circleLst[id] = circleLst.last(); + circleLst.pop_back(); + savePersonal(); + return circleLst.count(); } int Settings::getThemeColor() const { - QMutexLocker locker{&bigLock}; - return themeColor; + QMutexLocker locker{&bigLock}; + return themeColor; } void Settings::setThemeColor(int value) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (value != themeColor) { - themeColor = value; - emit themeColorChanged(themeColor); - } + if (value != themeColor) { + themeColor = value; + emit themeColorChanged(themeColor); + } } bool Settings::getAutoLogin() const { - QMutexLocker locker{&bigLock}; - return autoLogin; + QMutexLocker locker{&bigLock}; + return autoLogin; } void Settings::setAutoLogin(bool state) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (state != autoLogin) { - autoLogin = state; - emit autoLoginChanged(autoLogin); - } + if (state != autoLogin) { + autoLogin = state; + emit autoLoginChanged(autoLogin); + } } void Settings::setEnableGroupChatsColor(bool state) { - QMutexLocker locker{&bigLock}; - if (state != nameColors) { - nameColors = state; - emit nameColorsChanged(nameColors); - } + QMutexLocker locker{&bigLock}; + if (state != nameColors) { + nameColors = state; + emit nameColorsChanged(nameColors); + } } bool Settings::getEnableGroupChatsColor() const { return nameColors; } @@ -2123,39 +2064,37 @@ bool Settings::getEnableGroupChatsColor() const { return nameColors; } * @brief Creates a path to the settings dir, if it doesn't already exist */ void Settings::createSettingsDir() { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - QString dir = Settings::getSettingsDirPath(); - QDir directory(dir); - if (!directory.exists() && !directory.mkpath(directory.absolutePath())) - qCritical() << "Error while creating directory " << dir; + QString dir = Settings::getSettingsDirPath(); + QDir directory(dir); + if (!directory.exists() && !directory.mkpath(directory.absolutePath())) + qCritical() << "Error while creating directory " << dir; } /** * @brief Waits for all asynchronous operations to complete */ void Settings::sync() { - if (QThread::currentThread() != settingsThread) { - QMetaObject::invokeMethod(&getInstance(), "sync", - Qt::BlockingQueuedConnection); - return; - } - - QMutexLocker locker{&bigLock}; - qApp->processEvents(); -} - -ICoreSettings::ProxyType -Settings::fixInvalidProxyType(ICoreSettings::ProxyType proxyType) { - // Repair uninitialized enum that was saved to settings due to bug - // (https://github.com/qTox/qTox/issues/5311) - switch (proxyType) { - case ICoreSettings::ProxyType::ptNone: - case ICoreSettings::ProxyType::ptSOCKS5: - case ICoreSettings::ProxyType::ptHTTP: - return proxyType; - default: - qWarning() << "Repairing invalid ProxyType, UDP will be enabled"; - return ICoreSettings::ProxyType::ptNone; - } + if (QThread::currentThread() != settingsThread) { + QMetaObject::invokeMethod(&getInstance(), "sync", Qt::BlockingQueuedConnection); + return; + } + + QMutexLocker locker{&bigLock}; + qApp->processEvents(); +} + +ICoreSettings::ProxyType Settings::fixInvalidProxyType(ICoreSettings::ProxyType proxyType) { + // Repair uninitialized enum that was saved to settings due to bug + // (https://github.com/qTox/qTox/issues/5311) + switch (proxyType) { + case ICoreSettings::ProxyType::ptNone: + case ICoreSettings::ProxyType::ptSOCKS5: + case ICoreSettings::ProxyType::ptHTTP: + return proxyType; + default: + qWarning() << "Repairing invalid ProxyType, UDP will be enabled"; + return ICoreSettings::ProxyType::ptNone; + } } diff --git a/src/lib/settings/settings.h b/src/lib/settings/settings.h index c6dc5298..13f7be38 100644 --- a/src/lib/settings/settings.h +++ b/src/lib/settings/settings.h @@ -34,88 +34,92 @@ namespace Db { enum class syncType; } -class Settings : public QObject, ICoreSettings -{ +class Settings : public QObject, ICoreSettings { Q_OBJECT Q_ENUMS(StyleType) // general - Q_PROPERTY(bool compactLayout READ getCompactLayout WRITE setCompactLayout NOTIFY compactLayoutChanged FINAL) + Q_PROPERTY(bool compactLayout READ getCompactLayout WRITE setCompactLayout NOTIFY + compactLayoutChanged FINAL) // GUI Q_PROPERTY(bool separateWindow READ getSeparateWindow WRITE setSeparateWindow NOTIFY - separateWindowChanged FINAL) - Q_PROPERTY(QString smileyPack READ getSmileyPack WRITE setSmileyPack NOTIFY smileyPackChanged FINAL) + separateWindowChanged FINAL) + Q_PROPERTY(QString smileyPack READ getSmileyPack WRITE setSmileyPack NOTIFY smileyPackChanged + FINAL) Q_PROPERTY(int emojiFontPointSize READ getEmojiFontPointSize WRITE setEmojiFontPointSize NOTIFY - emojiFontPointSizeChanged FINAL) + emojiFontPointSizeChanged FINAL) Q_PROPERTY(QByteArray windowGeometry READ getWindowGeometry WRITE setWindowGeometry NOTIFY - windowGeometryChanged FINAL) - Q_PROPERTY(QByteArray windowState READ getWindowState WRITE setWindowState NOTIFY windowStateChanged FINAL) + windowGeometryChanged FINAL) + Q_PROPERTY(QByteArray windowState READ getWindowState WRITE setWindowState NOTIFY + windowStateChanged FINAL) Q_PROPERTY(QByteArray splitterState READ getSplitterState WRITE setSplitterState NOTIFY - splitterStateChanged FINAL) + splitterStateChanged FINAL) Q_PROPERTY(QByteArray dialogGeometry READ getDialogGeometry WRITE setDialogGeometry NOTIFY - dialogGeometryChanged FINAL) + dialogGeometryChanged FINAL) Q_PROPERTY(QByteArray dialogSplitterState READ getDialogSplitterState WRITE - setDialogSplitterState NOTIFY dialogSplitterStateChanged FINAL) + setDialogSplitterState NOTIFY dialogSplitterStateChanged FINAL) Q_PROPERTY(QByteArray dialogSettingsGeometry READ getDialogSettingsGeometry WRITE - setDialogSettingsGeometry NOTIFY dialogSettingsGeometryChanged FINAL) + setDialogSettingsGeometry NOTIFY dialogSettingsGeometryChanged FINAL) Q_PROPERTY(QString style READ getStyle WRITE setStyle NOTIFY styleChanged FINAL) Q_PROPERTY(bool showIdenticons READ getShowIdenticons WRITE setShowIdenticons NOTIFY - showIdenticonsChanged FINAL) + showIdenticonsChanged FINAL) // ChatView Q_PROPERTY(bool groupchatPosition READ getGroupchatPosition WRITE setGroupchatPosition NOTIFY - groupchatPositionChanged FINAL) + groupchatPositionChanged FINAL) Q_PROPERTY(QFont chatMessageFont READ getChatMessageFont WRITE setChatMessageFont NOTIFY - chatMessageFontChanged FINAL) + chatMessageFontChanged FINAL) Q_PROPERTY(StyleType stylePreference READ getStylePreference WRITE setStylePreference NOTIFY - stylePreferenceChanged FINAL) + stylePreferenceChanged FINAL) Q_PROPERTY(QString timestampFormat READ getTimestampFormat WRITE setTimestampFormat NOTIFY - timestampFormatChanged FINAL) - Q_PROPERTY(QString dateFormat READ getDateFormat WRITE setDateFormat NOTIFY dateFormatChanged FINAL) + timestampFormatChanged FINAL) + Q_PROPERTY(QString dateFormat READ getDateFormat WRITE setDateFormat NOTIFY dateFormatChanged + FINAL) Q_PROPERTY(bool statusChangeNotificationEnabled READ getStatusChangeNotificationEnabled WRITE - setStatusChangeNotificationEnabled NOTIFY statusChangeNotificationEnabledChanged FINAL) + setStatusChangeNotificationEnabled NOTIFY + statusChangeNotificationEnabledChanged FINAL) Q_PROPERTY(bool spellCheckingEnabled READ getSpellCheckingEnabled WRITE setSpellCheckingEnabled - NOTIFY spellCheckingEnabledChanged FINAL) + NOTIFY spellCheckingEnabledChanged FINAL) // Privacy Q_PROPERTY(bool typingNotification READ getTypingNotification WRITE setTypingNotification NOTIFY - typingNotificationChanged FINAL) - Q_PROPERTY(QStringList blackList READ getBlackList WRITE setBlackList NOTIFY blackListChanged FINAL) + typingNotificationChanged FINAL) + Q_PROPERTY(QStringList blackList READ getBlackList WRITE setBlackList NOTIFY blackListChanged + FINAL) // Audio Q_PROPERTY(QString inDev READ getInDev WRITE setInDev NOTIFY inDevChanged FINAL) Q_PROPERTY(bool audioInDevEnabled READ getAudioInDevEnabled WRITE setAudioInDevEnabled NOTIFY - audioInDevEnabledChanged FINAL) + audioInDevEnabledChanged FINAL) Q_PROPERTY(qreal audioInGainDecibel READ getAudioInGainDecibel WRITE setAudioInGainDecibel - NOTIFY audioInGainDecibelChanged FINAL) + NOTIFY audioInGainDecibelChanged FINAL) Q_PROPERTY(qreal audioThreshold READ getAudioThreshold WRITE setAudioThreshold NOTIFY - audioThresholdChanged FINAL) + audioThresholdChanged FINAL) Q_PROPERTY(QString outDev READ getOutDev WRITE setOutDev NOTIFY outDevChanged FINAL) Q_PROPERTY(bool audioOutDevEnabled READ getAudioOutDevEnabled WRITE setAudioOutDevEnabled NOTIFY - audioOutDevEnabledChanged FINAL) + audioOutDevEnabledChanged FINAL) Q_PROPERTY(int outVolume READ getOutVolume WRITE setOutVolume NOTIFY outVolumeChanged FINAL) - Q_PROPERTY(int audioBitrate READ getAudioBitrate WRITE setAudioBitrate NOTIFY audioBitrateChanged FINAL) + Q_PROPERTY(int audioBitrate READ getAudioBitrate WRITE setAudioBitrate NOTIFY + audioBitrateChanged FINAL) // Video Q_PROPERTY(QString videoDev READ getVideoDev WRITE setVideoDev NOTIFY videoDevChanged FINAL) - Q_PROPERTY(QRect camVideoRes READ getCamVideoRes WRITE setCamVideoRes NOTIFY camVideoResChanged FINAL) - Q_PROPERTY(QRect screenRegion READ getScreenRegion WRITE setScreenRegion NOTIFY screenRegionChanged FINAL) - Q_PROPERTY(bool screenGrabbed READ getScreenGrabbed WRITE setScreenGrabbed NOTIFY screenGrabbedChanged FINAL) - Q_PROPERTY(float camVideoFPS READ getCamVideoFPS WRITE setCamVideoFPS NOTIFY camVideoFPSChanged FINAL) + Q_PROPERTY(QRect camVideoRes READ getCamVideoRes WRITE setCamVideoRes NOTIFY camVideoResChanged + FINAL) + Q_PROPERTY(QRect screenRegion READ getScreenRegion WRITE setScreenRegion NOTIFY + screenRegionChanged FINAL) + Q_PROPERTY(bool screenGrabbed READ getScreenGrabbed WRITE setScreenGrabbed NOTIFY + screenGrabbedChanged FINAL) + Q_PROPERTY(float camVideoFPS READ getCamVideoFPS WRITE setCamVideoFPS NOTIFY camVideoFPSChanged + FINAL) public: - enum class StyleType - { - NONE = 0, - WITH_CHARS = 1, - WITHOUT_CHARS = 2 - }; + enum class StyleType { NONE = 0, WITH_CHARS = 1, WITHOUT_CHARS = 2 }; - enum class FriendListSortingMode - { + enum class FriendListSortingMode { Name, Activity, }; @@ -137,10 +141,9 @@ class Settings : public QObject, ICoreSettings void resetToDefault(); -// QStringList getLocales(); + // QStringList getLocales(); - struct Request - { + struct Request { QString address; QString message; bool read; @@ -165,7 +168,6 @@ public slots: void notifyHideChanged(bool enabled); void groupAlwaysNotifyChanged(bool enabled); - void enableLoggingChanged(bool enabled); void autoAwayTimeChanged(int minutes); void globalAutoAcceptDirChanged(const QString& path); @@ -213,7 +215,6 @@ public slots: bool getMakeToxPortable() const; void setMakeToxPortable(bool newValue); - bool getLightTrayIcon() const; void setLightTrayIcon(bool newValue); @@ -223,28 +224,26 @@ public slots: bool getUseEmoticons() const; void setUseEmoticons(bool newValue); - QString getTranslation() const; void setTranslation(const QString& newValue); // ICoreSettings - bool getEnableIPv6() const ; - void setEnableIPv6(bool enabled) ; - - bool getForceTCP() const ; - void setForceTCP(bool enabled) ; + bool getEnableIPv6() const; + void setEnableIPv6(bool enabled); - bool getEnableLanDiscovery() const ; - void setEnableLanDiscovery(bool enabled) ; + bool getForceTCP() const; + void setForceTCP(bool enabled); - QString getProxyAddr() const ; - void setProxyAddr(const QString& address) ; + bool getEnableLanDiscovery() const; + void setEnableLanDiscovery(bool enabled); + QString getProxyAddr() const; + void setProxyAddr(const QString& address); - quint16 getProxyPort() const ; - void setProxyPort(quint16 port) ; + quint16 getProxyPort() const; + void setProxyPort(quint16 port); - QNetworkProxy getProxy() const ; + QNetworkProxy getProxy() const; SIGNAL_IMPL(Settings, enableIPv6Changed, bool enabled) SIGNAL_IMPL(Settings, forceTCPChanged, bool enabled) @@ -283,58 +282,52 @@ public slots: bool getBusySound() const; void setBusySound(bool newValue); - bool getGroupAlwaysNotify() const ; - void setGroupAlwaysNotify(bool newValue) ; + bool getGroupAlwaysNotify() const; + void setGroupAlwaysNotify(bool newValue); - QString getInDev() const ; - void setInDev(const QString& deviceSpecifier) ; + QString getInDev() const; + void setInDev(const QString& deviceSpecifier); - bool getAudioInDevEnabled() const ; - void setAudioInDevEnabled(bool enabled) ; + bool getAudioInDevEnabled() const; + void setAudioInDevEnabled(bool enabled); - QString getOutDev() const ; - void setOutDev(const QString& deviceSpecifier) ; + QString getOutDev() const; + void setOutDev(const QString& deviceSpecifier); - bool getAudioOutDevEnabled() const ; - void setAudioOutDevEnabled(bool enabled) ; + bool getAudioOutDevEnabled() const; + void setAudioOutDevEnabled(bool enabled); - qreal getAudioInGainDecibel() const ; - void setAudioInGainDecibel(qreal dB) ; + qreal getAudioInGainDecibel() const; + void setAudioInGainDecibel(qreal dB); - qreal getAudioThreshold() const ; - void setAudioThreshold(qreal percent) ; + qreal getAudioThreshold() const; + void setAudioThreshold(qreal percent); - int getOutVolume() const ; - int getOutVolumeMin() const - { - return 0; - } - int getOutVolumeMax() const - { - return 100; - } - void setOutVolume(int volume) ; + int getOutVolume() const; + int getOutVolumeMin() const { return 0; } + int getOutVolumeMax() const { return 100; } + void setOutVolume(int volume); - int getAudioBitrate() const ; - void setAudioBitrate(int bitrate) ; + int getAudioBitrate() const; + void setAudioBitrate(int bitrate); - bool getEnableTestSound() const ; - void setEnableTestSound(bool newValue) ; + bool getEnableTestSound() const; + void setEnableTestSound(bool newValue); - QString getVideoDev() const ; - void setVideoDev(const QString& deviceSpecifier) ; + QString getVideoDev() const; + void setVideoDev(const QString& deviceSpecifier); - QRect getScreenRegion() const ; - void setScreenRegion(const QRect& value) ; + QRect getScreenRegion() const; + void setScreenRegion(const QRect& value); - bool getScreenGrabbed() const ; - void setScreenGrabbed(bool value) ; + bool getScreenGrabbed() const; + void setScreenGrabbed(bool value); - QRect getCamVideoRes() const ; - void setCamVideoRes(QRect newValue) ; + QRect getCamVideoRes() const; + void setCamVideoRes(QRect newValue); - float getCamVideoFPS() const ; - void setCamVideoFPS(float newValue) ; + float getCamVideoFPS() const; + void setCamVideoFPS(float newValue); bool isAnimationEnabled() const; void setAnimationEnabled(bool newValue); @@ -370,7 +363,6 @@ public slots: const QString& getDateFormat() const; void setDateFormat(const QString& format); - bool getStatusChangeNotificationEnabled() const; void setStatusChangeNotificationEnabled(bool newValue); @@ -381,8 +373,8 @@ public slots: bool getTypingNotification() const; void setTypingNotification(bool enabled); - bool getShowGroupJoinLeaveMessages() const ; - void setShowGroupJoinLeaveMessages(bool newValue) ; + bool getShowGroupJoinLeaveMessages() const; + void setShowGroupJoinLeaveMessages(bool newValue); // State QByteArray getWindowGeometry() const; @@ -449,20 +441,15 @@ public slots: // Wrappers around getWidgetData() and setWidgetData() // Assume widget has a unique objectName set - template - void restoreGeometryState(T* widget) const - { + template void restoreGeometryState(T* widget) const { widget->restoreGeometry(getWidgetData(widget->objectName() + "Geometry")); widget->restoreState(getWidgetData(widget->objectName() + "State")); } - template - void saveGeometryState(const T* widget) - { + template void saveGeometryState(const T* widget) { setWidgetData(widget->objectName() + "Geometry", widget->saveGeometry()); setWidgetData(widget->objectName() + "State", widget->saveState()); } - private: struct friendProp; @@ -491,7 +478,7 @@ public slots: bool dontGroupWindows; bool showIdenticons; bool enableIPv6; -// QString translation; + // QString translation; bool makeToxPortable; bool lightTrayIcon; @@ -513,8 +500,6 @@ public slots: QString proxyAddr; quint16 proxyPort; - - bool enableLogging; int autoAwayTime; @@ -571,8 +556,7 @@ public slots: bool screenGrabbed; float camVideoFPS; - struct circleProp - { + struct circleProp { QString name; bool expanded; }; @@ -588,4 +572,4 @@ public slots: static QThread* settingsThread; }; -#endif // SETTINGS_HPP +#endif // SETTINGS_HPP diff --git a/src/lib/settings/style.cpp b/src/lib/settings/style.cpp index e0f85056..03210d3b 100644 --- a/src/lib/settings/style.cpp +++ b/src/lib/settings/style.cpp @@ -12,7 +12,7 @@ #include "style.h" #include "settings.h" -//#include "src/widget/gui.h" +// #include "src/widget/gui.h" #include #include @@ -56,23 +56,24 @@ */ namespace { - const QLatin1String ThemeSubFolder{"themes/"}; - const QLatin1String BuiltinThemeDefaultPath{":themes/default/"}; - const QLatin1String BuiltinThemeDarkPath{":themes/dark/"}; -} +const QLatin1String ThemeSubFolder{"themes/"}; +const QLatin1String BuiltinThemeDefaultPath{":themes/default/"}; +const QLatin1String BuiltinThemeDarkPath{":themes/dark/"}; +} // namespace // helper functions -QFont appFont(int pixelSize, int weight) -{ +QFont appFont(int pixelSize, int weight) { QFont font; font.setPixelSize(pixelSize); font.setWeight(weight); return font; } -QString qssifyFont(QFont font) -{ - return QString("%1 %2px \"%3\"").arg(font.weight() * 8).arg(font.pixelSize()).arg(font.family()); +QString qssifyFont(QFont font) { + return QString("%1 %2px \"%3\"") + .arg(font.weight() * 8) + .arg(font.pixelSize()) + .arg(font.family()); } static QMap palette; @@ -81,53 +82,50 @@ static QMap extPalette; static QMap dictColor; static QMap dictFont; static QMap dictTheme; +static QMap dictExtColor; QList Style::themeNameColors = { - {Style::Light, QObject::tr("Default"), QColor()}, - {Style::Dark, QObject::tr("Dark"), QColor()}, + {Style::Light, QObject::tr("Default"), QColor()}, + {Style::Dark, QObject::tr("Dark"), QColor()}, }; -QStringList Style::getThemeColorNames() -{ +QStringList Style::getThemeColorNames() { QStringList l; - for (auto &t : themeNameColors) { + for (auto& t : themeNameColors) { l << t.name; } return l; } -QString Style::getThemeName() -{ - //TODO: return name of the current theme +QString Style::getThemeName() { + // TODO: return name of the current theme const QString themeName = "default"; return QStringLiteral("default"); } -QString Style::getThemeFolder() -{ +QString Style::getThemeFolder() { const QString themeName = getThemeName(); const QString themeFolder = ThemeSubFolder % themeName; - const QString fullPath = QStandardPaths::locate(QStandardPaths::AppDataLocation, - themeFolder, QStandardPaths::LocateDirectory); + const QString fullPath = QStandardPaths::locate(QStandardPaths::AppDataLocation, themeFolder, + QStandardPaths::LocateDirectory); // No themes available, fallback to builtin - if(fullPath.isEmpty()) { + if (fullPath.isEmpty()) { return getThemePath(); } return fullPath % QDir::separator(); } - QMap Style::aliasColors = {{TransferGood, "transferGood"}, {TransferWait, "transferWait"}, {TransferBad, "transferBad"}, {TransferMiddle, "transferMiddle"}, - {MainText,"mainText"}, + {MainText, "mainText"}, {NameActive, "nameActive"}, - {StatusActive,"statusActive"}, + {StatusActive, "statusActive"}, {GroundExtra, "groundExtra"}, {GroundBase, "groundBase"}, {Orange, "orange"}, @@ -145,13 +143,11 @@ QMap Style::aliasColors = {{TransferGood, "transfe // QString implicit sharing deduplicates stylesheets rather than constructing a new one each time std::map, const QString> Style::stylesheetsCache; -const QString Style::getStylesheet(const QString& filename, const QFont& baseFont) -{ +const QString Style::getStylesheet(const QString& filename, const QFont& baseFont) { const QString fullPath = getThemeFolder() + filename; const std::pair cacheKey(fullPath, baseFont); auto it = stylesheetsCache.find(cacheKey); - if (it != stylesheetsCache.end()) - { + if (it != stylesheetsCache.end()) { // cache hit return it->second; } @@ -162,8 +158,7 @@ const QString Style::getStylesheet(const QString& filename, const QFont& baseFon } static QStringList existingImagesCache; -const QString Style::getImagePath(const QString& filename) -{ +const QString Style::getImagePath(const QString& filename) { QString fullPath = getThemeFolder() + filename; // search for image in cache @@ -188,38 +183,30 @@ const QString Style::getImagePath(const QString& filename) } } -QColor Style::getColor(Style::ColorPalette entry) -{ - return palette[entry]; -} +QColor Style::getColor(Style::ColorPalette entry) { return palette[entry]; } -QColor Style::getExtColor(const QString &key) -{ - return extPalette.value(key, QColor(0,0,0)); -} +QColor Style::getExtColor(const QString& key) { return extPalette.value(key, QColor(0, 0, 0)); } -QFont Style::getFont(Style::Font font) -{ +QFont Style::getFont(Style::Font font) { // fonts as defined in // https://github.com/ItsDuke/Tox-UI/blob/master/UI%20GUIDELINES.md static int defSize = QFontInfo(QFont()).pixelSize(); static QFont fonts[] = { - appFont(defSize + 3, QFont::Bold), // extra big - appFont(defSize + 1, QFont::Normal), // big - appFont(defSize + 1, QFont::Bold), // big bold - appFont(defSize, QFont::Normal), // medium - appFont(defSize, QFont::Bold), // medium bold - appFont(defSize - 1, QFont::Normal), // small - appFont(defSize - 1, QFont::Light), // small light + appFont(defSize + 3, QFont::Bold), // extra big + appFont(defSize + 1, QFont::Normal), // big + appFont(defSize + 1, QFont::Bold), // big bold + appFont(defSize, QFont::Normal), // medium + appFont(defSize, QFont::Bold), // medium bold + appFont(defSize - 1, QFont::Normal), // small + appFont(defSize - 1, QFont::Light), // small light }; return fonts[font]; } -const QString Style::resolve(const QString& filename, const QFont& baseFont) -{ +const QString Style::resolve(const QString& filename, const QFont& baseFont) { QString themePath = getThemeFolder(); QString fullPath = themePath + filename; QString qss; @@ -250,27 +237,45 @@ const QString Style::resolve(const QString& filename, const QFont& baseFont) } if (dictFont.isEmpty()) { - dictFont = { - {"@baseFont", QString::fromUtf8("'%1' %2px").arg(baseFont.family()).arg(QFontInfo(baseFont).pixelSize())}, - {"@extraBig", qssifyFont(Style::getFont(Style::ExtraBig))}, - {"@big", qssifyFont(Style::getFont(Style::Big))}, - {"@bigBold", qssifyFont(Style::getFont(Style::BigBold))}, - {"@medium", qssifyFont(Style::getFont(Style::Medium))}, - {"@mediumBold", qssifyFont(Style::getFont(Style::MediumBold))}, - {"@small", qssifyFont(Style::getFont(Style::Small))}, - {"@smallLight", qssifyFont(Style::getFont(Style::SmallLight))}}; - } - - for (const QString& key : dictColor.keys()) { - qss.replace(QRegularExpression(key % QLatin1String{"\\b"}), dictColor[key]); + dictFont = {{"@baseFont", QString::fromUtf8("'%1' %2px") + .arg(baseFont.family()) + .arg(QFontInfo(baseFont).pixelSize())}, + {"@extraBig", qssifyFont(Style::getFont(Style::ExtraBig))}, + {"@big", qssifyFont(Style::getFont(Style::Big))}, + {"@bigBold", qssifyFont(Style::getFont(Style::BigBold))}, + {"@medium", qssifyFont(Style::getFont(Style::Medium))}, + {"@mediumBold", qssifyFont(Style::getFont(Style::MediumBold))}, + {"@small", qssifyFont(Style::getFont(Style::Small))}, + {"@smallLight", qssifyFont(Style::getFont(Style::SmallLight))}}; } - for (const QString& key : dictFont.keys()) { - qss.replace(QRegularExpression(key % QLatin1String{"\\b"}), dictFont[key]); + if (dictExtColor.isEmpty() && !extPalette.isEmpty()) { + auto it = extPalette.begin(); + while (it != extPalette.end()) { + dictExtColor.insert("@" + it.key(), it.value().name()); + it++; + } } - for (const QString& key : dictTheme.keys()) { - qss.replace(QRegularExpression(key % QLatin1String{"\\b"}), dictTheme[key]); + QRegularExpression anchorReg(R"(@([a-zA-z0-9\.]+))"); + int from = 0; + int index = qss.indexOf('@'); + while (index >= 0) { + QRegularExpressionMatch match = anchorReg.match(qss, from); + if (match.hasMatch()) { + QString key = match.captured(0); + // c++17 + if (auto it = dictColor.find(key); it != dictColor.end()) + qss.replace(key, it.value()); + else if (auto it = dictFont.find(key); it != dictFont.end()) + qss.replace(key, it.value()); + else if (auto it = dictTheme.find(key); it != dictTheme.end()) + qss.replace(key, it.value()); + else if (auto it = dictExtColor.find(key); it != dictExtColor.end()) + qss.replace(key, it.value()); + } + from++; + index = qss.indexOf('@', from); } // @getImagePath() function @@ -302,8 +307,7 @@ const QString Style::resolve(const QString& filename, const QFont& baseFont) return qss; } -void Style::repolish(QWidget* w) -{ +void Style::repolish(QWidget* w) { w->style()->unpolish(w); w->style()->polish(w); @@ -316,11 +320,11 @@ void Style::repolish(QWidget* w) } } -void Style::setThemeColor(int color) -{ - stylesheetsCache.clear(); // clear stylesheet cache which includes color info +void Style::setThemeColor(int color) { + stylesheetsCache.clear(); // clear stylesheet cache which includes color info palette.clear(); dictColor.clear(); + dictExtColor.clear(); initPalette(); initDictColor(); if (color < 0 || color >= themeNameColors.size()) @@ -335,8 +339,7 @@ void Style::setThemeColor(int color) * * Pass an invalid QColor to reset to defaults. */ -void Style::setThemeColor(const QColor& color) -{ +void Style::setThemeColor(const QColor& color) { if (!color.isValid()) { // Reset to default palette[ThemeDark] = getColor(ThemeDark); @@ -359,16 +362,13 @@ void Style::setThemeColor(const QColor& color) /** * @brief Reloads some CCS */ -void Style::applyTheme() -{ -// GUI::reloadTheme(); +void Style::applyTheme() { + // GUI::reloadTheme(); } - -void Style::initPalette() -{ +void Style::initPalette() { QSettings settings(getThemePath() % "palette.ini", QSettings::IniFormat); - + settings.beginGroup("colors"); QMap c; auto keys = aliasColors.keys(); @@ -382,36 +382,32 @@ void Style::initPalette() settings.beginGroup("extends-colors"); for (auto k : settings.childKeys()) { QColor color(settings.value(k).toString()); - if (color.isValid()) - extPalette.insert(k, color); + if (color.isValid()) extPalette.insert(k, color); } settings.endGroup(); } -void Style::initDictColor() -{ - dictColor = { - {"@transferGood", Style::getColor(Style::TransferGood).name()}, - {"@transferWait", Style::getColor(Style::TransferWait).name()}, - {"@transferBad", Style::getColor(Style::TransferBad).name()}, - {"@transferMiddle", Style::getColor(Style::TransferMiddle).name()}, - {"@mainText", Style::getColor(Style::MainText).name()}, - {"@nameActive", Style::getColor(Style::NameActive).name()}, - {"@statusActive", Style::getColor(Style::StatusActive).name()}, - {"@groundExtra", Style::getColor(Style::GroundExtra).name()}, - {"@groundBase", Style::getColor(Style::GroundBase).name()}, - {"@orange", Style::getColor(Style::Orange).name()}, - {"@action", Style::getColor(Style::Action).name()}, - {"@link", Style::getColor(Style::Link).name()}, - {"@searchHighlighted", Style::getColor(Style::SearchHighlighted).name()}, - {"@selectText", Style::getColor(Style::SelectText).name()}}; +void Style::initDictColor() { + dictColor = {{"@transferGood", Style::getColor(Style::TransferGood).name()}, + {"@transferWait", Style::getColor(Style::TransferWait).name()}, + {"@transferBad", Style::getColor(Style::TransferBad).name()}, + {"@transferMiddle", Style::getColor(Style::TransferMiddle).name()}, + {"@mainText", Style::getColor(Style::MainText).name()}, + {"@nameActive", Style::getColor(Style::NameActive).name()}, + {"@statusActive", Style::getColor(Style::StatusActive).name()}, + {"@groundExtra", Style::getColor(Style::GroundExtra).name()}, + {"@groundBase", Style::getColor(Style::GroundBase).name()}, + {"@orange", Style::getColor(Style::Orange).name()}, + {"@action", Style::getColor(Style::Action).name()}, + {"@link", Style::getColor(Style::Link).name()}, + {"@searchHighlighted", Style::getColor(Style::SearchHighlighted).name()}, + {"@selectText", Style::getColor(Style::SelectText).name()}}; } -QString Style::getThemePath() -{ -// const int num = Settings::getInstance().getThemeColor(); -// if (themeNameColors[num].type == Dark) { -// return BuiltinThemeDarkPath; -// } +QString Style::getThemePath() { + // const int num = Settings::getInstance().getThemeColor(); + // if (themeNameColors[num].type == Dark) { + // return BuiltinThemeDarkPath; + // } return BuiltinThemeDefaultPath; } diff --git a/src/lib/settings/style.h b/src/lib/settings/style.h index 2d9bc661..06bd5c8a 100644 --- a/src/lib/settings/style.h +++ b/src/lib/settings/style.h @@ -19,11 +19,9 @@ class QString; class QWidget; -class Style -{ +class Style { public: - enum ColorPalette - { + enum ColorPalette { TransferGood, TransferWait, TransferBad, @@ -45,22 +43,9 @@ class Style SelectText }; - enum Font - { - ExtraBig, - Big, - BigBold, - Medium, - MediumBold, - Small, - SmallLight - }; + enum Font { ExtraBig, Big, BigBold, Medium, MediumBold, Small, SmallLight }; - enum MainTheme - { - Light, - Dark - }; + enum MainTheme { Light, Dark }; struct ThemeNameColor { MainTheme type; @@ -74,7 +59,7 @@ class Style static QString getThemeFolder(); static QString getThemeName(); static QColor getColor(ColorPalette entry); - static QColor getExtColor(const QString & key); + static QColor getExtColor(const QString& key); static QFont getFont(Font font); static const QString resolve(const QString& filename, const QFont& baseFont = QFont()); static void repolish(QWidget* w); @@ -97,4 +82,4 @@ class Style static QMap aliasColors; }; -#endif // STYLE_H +#endif // STYLE_H diff --git a/src/lib/settings/translator.cpp b/src/lib/settings/translator.cpp index c195d7f1..362f5068 100644 --- a/src/lib/settings/translator.cpp +++ b/src/lib/settings/translator.cpp @@ -23,82 +23,78 @@ namespace settings { // module, QTranslator -static QMap m_translatorMap{}; +static QMap m_translatorMap{}; static QVector callbacks{}; -//static QMutex Translator::lock; +// static QMutex Translator::lock; static bool m_loadedQtTranslations{false}; - /** * @brief Loads the translations according to the settings or locale. */ -void Translator::translate(const QString &moduleName, const QString &localeName) { - qDebug() << "translate module:" << moduleName << "locale:" << localeName; - QMutexLocker locker{&lock}; - - qDebug() <<"m_translatorMap" << m_translatorMap.size(); - auto * translator = m_translatorMap.value(moduleName); - if(translator){ - qDebug() << "remove translator:" << translator; - QCoreApplication::removeTranslator(translator); - m_translatorMap.remove(moduleName); - delete translator; - } - - qDebug() << "New translator=>" << moduleName; - translator = new QTranslator(); - - // Load translations - QString locale = localeName.isEmpty() - ? QLocale::system().name().section('_', 0, 0) - : localeName; - qDebug() << "Loaded locale" << locale <<"=>" << moduleName ; - if (locale != "en") { - - if(!m_loadedQtTranslations){ - // system menu translation (Qt国际化配置) - QTranslator *qtTranslator = new QTranslator(); - QString s_locale = "qt_" + locale; - QString location = QLibraryInfo::location(QLibraryInfo::TranslationsPath); - if (qtTranslator->load(s_locale, location)) { - QApplication::installTranslator(qtTranslator); - qDebug() << "System translation loaded" << locale; - } else { - qDebug() << "System translation not loaded" << locale; - } - m_loadedQtTranslations = true; +void Translator::translate(const QString& moduleName, const QString& localeName) { + qDebug() << "translate module:" << moduleName << "locale:" << localeName; + QMutexLocker locker{&lock}; + + qDebug() << "m_translatorMap" << m_translatorMap.size(); + auto* translator = m_translatorMap.value(moduleName); + if (translator) { + qDebug() << "remove translator:" << translator; + QCoreApplication::removeTranslator(translator); + m_translatorMap.remove(moduleName); + delete translator; } - //增加 {translations}/{module} - QString path = ":translations/"+moduleName; - qDebug() << "Loading translation path" << path << "locale" << locale; - if (translator->load(locale+".qm", path)) { - qDebug() << "Loaded translation successful locale" <"<" << moduleName; + translator = new QTranslator(); + + // Load translations + QString locale = + localeName.isEmpty() ? QLocale::system().name().section('_', 0, 0) : localeName; + qDebug() << "Loaded locale" << locale << "=>" << moduleName; + if (locale != "en") { + if (!m_loadedQtTranslations) { + // system menu translation (Qt国际化配置) + QTranslator* qtTranslator = new QTranslator(); + QString s_locale = "qt_" + locale; + QString location = QLibraryInfo::location(QLibraryInfo::TranslationsPath); + if (qtTranslator->load(s_locale, location)) { + QApplication::installTranslator(qtTranslator); + qDebug() << "System translation loaded" << locale; + } else { + qDebug() << "System translation not loaded" << locale; + } + m_loadedQtTranslations = true; + } + + // 增加 {translations}/{module} + QString path = ":translations/" + moduleName; + qDebug() << "Loading translation path" << path << "locale" << locale; + if (translator->load(locale + ".qm", path)) { + qDebug() << "Loaded translation successful locale" << locale << "for" << moduleName; + bool installed = QCoreApplication::installTranslator(translator); + qDebug() << "Installed translator locale" << locale << "for" << moduleName << "=>" + << installed; + + m_translatorMap.insert(moduleName, translator); + } else { + delete translator; + qWarning() << "Error loading translation" << locale << "for" << moduleName; + return; + } } - } + // After the language is changed from RTL to LTR, the layout direction isn't + // always restored + const QString direction = QApplication::tr("LTR", + "Translate this string to the string 'RTL' in" + " right-to-left languages (for example Hebrew and" + " Arabic) to get proper widget layout"); - // After the language is changed from RTL to LTR, the layout direction isn't - // always restored - const QString direction = - QApplication::tr("LTR", "Translate this string to the string 'RTL' in" - " right-to-left languages (for example Hebrew and" - " Arabic) to get proper widget layout"); + QGuiApplication::setLayoutDirection(direction == "RTL" ? Qt::RightToLeft : Qt::LeftToRight); - QGuiApplication::setLayoutDirection(direction == "RTL" ? Qt::RightToLeft - : Qt::LeftToRight); - - for (auto &pair : callbacks){ - pair.second(); - } + for (auto& pair : callbacks) { + pair.second(); + } } /** @@ -106,20 +102,19 @@ void Translator::translate(const QString &moduleName, const QString &localeName) * @param f Function, wich will called. * @param owner Widget to retanslate. */ -void Translator::registerHandler(const std::function &f, void *owner) { - QMutexLocker locker{&lock}; - callbacks.push_back({owner, f}); +void Translator::registerHandler(const std::function& f, void* owner) { + QMutexLocker locker{&lock}; + callbacks.push_back({owner, f}); } /** * @brief Unregisters all handlers of an owner. * @param owner Owner to unregister. */ -void Translator::unregister(void *owner) { - QMutexLocker locker{&lock}; - callbacks.erase( - std::remove_if(begin(callbacks), end(callbacks), - [&](const Callback &c) { return c.first == owner; }), - end(callbacks)); +void Translator::unregister(void* owner) { + QMutexLocker locker{&lock}; + callbacks.erase(std::remove_if(begin(callbacks), end(callbacks), + [&](const Callback& c) { return c.first == owner; }), + end(callbacks)); } -} // namespace main +} // namespace settings diff --git a/src/lib/settings/translator.h b/src/lib/settings/translator.h index d0991123..f899643b 100644 --- a/src/lib/settings/translator.h +++ b/src/lib/settings/translator.h @@ -13,35 +13,31 @@ #ifndef TRANSLATOR_H #define TRANSLATOR_H +#include #include #include #include -#include #include class QTranslator; namespace settings { -using Callback = QPair>; - static QMutex lock; - +using Callback = QPair>; +static QMutex lock; class Translator { - public: - static void translate(const QString &moduleName, const QString &localeName); - static void registerHandler(const std::function &, void *owner); - static void unregister(void *owner); + static void translate(const QString& moduleName, const QString& localeName); + static void registerHandler(const std::function&, void* owner); + static void unregister(void* owner); private: + // static QVector callbacks; -// static QVector callbacks; - - -// static QTranslator *translator; -// static bool m_loadedQtTranslations; + // static QTranslator *translator; + // static bool m_loadedQtTranslations; }; -} // namespace main +} // namespace settings -#endif // TRANSLATOR_H +#endif // TRANSLATOR_H diff --git a/src/main.cpp b/src/main.cpp index 05037a95..2e51c7a2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -9,14 +9,12 @@ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * See the Mulan PubL v2 for more details. */ -#include "lib/log/LogManager.h" -#include "launcher.h" #include +#include "launcher.h" +#include "lib/log/LogManager.h" -int main(int argc, char *argv[]) { - - Q_INIT_RESOURCE(resources); - const auto launcher = ok::Launcher::Create(argc, argv); - return launcher ? launcher->startup() : 1; - +int main(int argc, char* argv[]) { + Q_INIT_RESOURCE(resources); + const auto launcher = ok::Launcher::Create(argc, argv); + return launcher ? launcher->startup() : 1; } diff --git a/src/modules/im/src/audio/audio.cpp b/src/modules/im/src/audio/audio.cpp index 6e191ed1..4b08c1ca 100644 --- a/src/modules/im/src/audio/audio.cpp +++ b/src/modules/im/src/audio/audio.cpp @@ -13,15 +13,14 @@ #include #include "src/audio/audio.h" -#include "src/audio/iaudiosettings.h" #include "src/audio/backend/openal.h" +#include "src/audio/iaudiosettings.h" /** * @brief Select the audio backend * @param settings Audio settings to use * @return Audio backend selection based on settings */ -std::unique_ptr Audio::makeAudio(IAudioSettings& settings) -{ +std::unique_ptr Audio::makeAudio(IAudioSettings& settings) { return std::unique_ptr(new OpenAL()); } diff --git a/src/modules/im/src/audio/audio.h b/src/modules/im/src/audio/audio.h index 0b6a5d60..99870e54 100644 --- a/src/modules/im/src/audio/audio.h +++ b/src/modules/im/src/audio/audio.h @@ -10,7 +10,6 @@ * See the Mulan PubL v2 for more details. */ - #ifndef AUDIO_H #define AUDIO_H @@ -18,10 +17,9 @@ class IAudioControl; class IAudioSettings; -class Audio -{ +class Audio { public: static std::unique_ptr makeAudio(IAudioSettings& settings); }; -#endif // AUDIO_H +#endif // AUDIO_H diff --git a/src/modules/im/src/audio/backend/alsink.cpp b/src/modules/im/src/audio/backend/alsink.cpp index fdaff50f..ba85a395 100644 --- a/src/modules/im/src/audio/backend/alsink.cpp +++ b/src/modules/im/src/audio/backend/alsink.cpp @@ -21,8 +21,7 @@ * and frees the audio ressources internally. */ -AlSink::~AlSink() -{ +AlSink::~AlSink() { QMutexLocker{&killLock}; // unsubscribe only if not already killed @@ -32,8 +31,8 @@ AlSink::~AlSink() } } -void AlSink::playAudioBuffer(const int16_t* data, int samples, unsigned channels, int sampleRate) const -{ +void AlSink::playAudioBuffer(const int16_t* data, int samples, unsigned channels, + int sampleRate) const { QMutexLocker{&killLock}; if (killed) { @@ -43,8 +42,7 @@ void AlSink::playAudioBuffer(const int16_t* data, int samples, unsigned channels } } -void AlSink::playMono16Sound(const IAudioSink::Sound& sound) -{ +void AlSink::playMono16Sound(const IAudioSink::Sound& sound) { QMutexLocker{&killLock}; if (killed) { @@ -54,8 +52,7 @@ void AlSink::playMono16Sound(const IAudioSink::Sound& sound) } } -void AlSink::startLoop() -{ +void AlSink::startLoop() { QMutexLocker{&killLock}; if (killed) { @@ -65,8 +62,7 @@ void AlSink::startLoop() } } -void AlSink::stopLoop() -{ +void AlSink::stopLoop() { QMutexLocker{&killLock}; if (killed) { @@ -76,14 +72,12 @@ void AlSink::stopLoop() } } -uint AlSink::getSourceId() const -{ +uint AlSink::getSourceId() const { uint tmp = sourceId; return tmp; } -void AlSink::kill() -{ +void AlSink::kill() { killLock.lock(); // this flag is only set once here, afterwards the object is considered dead killed = true; @@ -91,13 +85,9 @@ void AlSink::kill() emit invalidated(); } -AlSink::AlSink(OpenAL& al, uint sourceId) - : audio(al) - , sourceId{sourceId} -{} +AlSink::AlSink(OpenAL& al, uint sourceId) : audio(al), sourceId{sourceId} {} -AlSink::operator bool() const -{ +AlSink::operator bool() const { QMutexLocker{&killLock}; return !killed; diff --git a/src/modules/im/src/audio/backend/alsink.h b/src/modules/im/src/audio/backend/alsink.h index b906b73a..b8870329 100644 --- a/src/modules/im/src/audio/backend/alsink.h +++ b/src/modules/im/src/audio/backend/alsink.h @@ -22,8 +22,7 @@ class OpenAL; class QMutex; -class AlSink : public QObject, public IAudioSink -{ +class AlSink : public QObject, public IAudioSink { Q_OBJECT public: AlSink(OpenAL& al, uint sourceId); @@ -33,7 +32,8 @@ class AlSink : public QObject, public IAudioSink AlSink& operator=(AlSink&& other) = delete; ~AlSink(); - void playAudioBuffer(const int16_t* data, int samples, unsigned channels, int sampleRate) const override; + void playAudioBuffer(const int16_t* data, int samples, unsigned channels, + int sampleRate) const override; void playMono16Sound(const IAudioSink::Sound& sound) override; void startLoop() override; void stopLoop() override; @@ -53,4 +53,4 @@ class AlSink : public QObject, public IAudioSink mutable CompatibleRecursiveMutex killLock; }; -#endif // ALSINK_H +#endif // ALSINK_H diff --git a/src/modules/im/src/audio/backend/alsource.cpp b/src/modules/im/src/audio/backend/alsource.cpp index 0e5be2c1..25ef6880 100644 --- a/src/modules/im/src/audio/backend/alsource.cpp +++ b/src/modules/im/src/audio/backend/alsource.cpp @@ -21,12 +21,9 @@ * @brief Reserves ressources for an audio source * @param audio Main audio object, must have longer lifetime than this object. */ -AlSource::AlSource(OpenAL& al) - : audio(al) -{} +AlSource::AlSource(OpenAL& al) : audio(al) {} -AlSource::~AlSource() -{ +AlSource::~AlSource() { QMutexLocker{&killLock}; // unsubscribe only if not already killed @@ -36,14 +33,12 @@ AlSource::~AlSource() } } -AlSource::operator bool() const -{ +AlSource::operator bool() const { QMutexLocker{&killLock}; return !killed; } -void AlSource::kill() -{ +void AlSource::kill() { killLock.lock(); // this flag is only set once here, afterwards the object is considered dead killed = true; diff --git a/src/modules/im/src/audio/backend/alsource.h b/src/modules/im/src/audio/backend/alsource.h index 89672519..a700ed2e 100644 --- a/src/modules/im/src/audio/backend/alsource.h +++ b/src/modules/im/src/audio/backend/alsource.h @@ -13,14 +13,13 @@ #ifndef ALSOURCE_H #define ALSOURCE_H -#include "src/audio/iaudiosource.h" -#include "base/compatiblerecursivemutex.h" #include #include +#include "base/compatiblerecursivemutex.h" +#include "src/audio/iaudiosource.h" class OpenAL; -class AlSource : public IAudioSource -{ +class AlSource : public IAudioSource { Q_OBJECT public: AlSource(OpenAL& al); @@ -40,4 +39,4 @@ class AlSource : public IAudioSource mutable CompatibleRecursiveMutex killLock; }; -#endif // ALSOURCE_H +#endif // ALSOURCE_H diff --git a/src/modules/im/src/audio/backend/openal.cpp b/src/modules/im/src/audio/backend/openal.cpp index a43b87a6..09c60f26 100644 --- a/src/modules/im/src/audio/backend/openal.cpp +++ b/src/modules/im/src/audio/backend/openal.cpp @@ -24,15 +24,15 @@ #include namespace { -void applyGain(int16_t *buffer, uint32_t bufferSize, qreal gainFactor) { - for (quint32 i = 0; i < bufferSize; ++i) { - // gain amplification with clipping to 16-bit boundaries - buffer[i] = qBound(std::numeric_limits::min(), - qRound(buffer[i] * gainFactor), - std::numeric_limits::max()); - } +void applyGain(int16_t* buffer, uint32_t bufferSize, qreal gainFactor) { + for (quint32 i = 0; i < bufferSize; ++i) { + // gain amplification with clipping to 16-bit boundaries + buffer[i] = qBound(std::numeric_limits::min(), + qRound(buffer[i] * gainFactor), + std::numeric_limits::max()); + } } -} // namespace +} // namespace /** * @class OpenAL @@ -49,79 +49,75 @@ static const unsigned int BUFFER_COUNT = 16; static const uint32_t AUDIO_CHANNELS = 2; OpenAL::OpenAL() : audioThread{new QThread} { - // initialize OpenAL error stack - alGetError(); - alcGetError(nullptr); - - audioThread->setObjectName("ok-audio"); - - QObject::connect(audioThread, &QThread::finished, &voiceTimer, &QTimer::stop); - QObject::connect(audioThread, &QThread::finished, &captureTimer, - &QTimer::stop); - QObject::connect(audioThread, &QThread::finished, audioThread, - &QThread::deleteLater); - - moveToThread(audioThread); - - voiceTimer.setSingleShot(true); - voiceTimer.moveToThread(audioThread); - connect(this, // - &OpenAL::startActive, // - &voiceTimer, // - static_cast(&QTimer::start)); - connect(&voiceTimer, &QTimer::timeout, this, &OpenAL::stopActive); - - connect(&captureTimer, &QTimer::timeout, this, &OpenAL::doAudio); - captureTimer.setInterval(AUDIO_FRAME_DURATION / 2); - captureTimer.setSingleShot(false); - captureTimer.moveToThread(audioThread); - // TODO for Qt 5.6+: use qOverload - connect(audioThread, &QThread::started, &captureTimer, - static_cast(&QTimer::start)); - - cleanupTimer.setInterval(1000); - cleanupTimer.setSingleShot(false); - connect(&cleanupTimer, &QTimer::timeout, this, &OpenAL::cleanupSound); - // TODO for Qt 5.6+: use qOverload - connect(audioThread, &QThread::started, &cleanupTimer, - static_cast(&QTimer::start)); - - audioThread->start(); + // initialize OpenAL error stack + alGetError(); + alcGetError(nullptr); + + audioThread->setObjectName("ok-audio"); + + QObject::connect(audioThread, &QThread::finished, &voiceTimer, &QTimer::stop); + QObject::connect(audioThread, &QThread::finished, &captureTimer, &QTimer::stop); + QObject::connect(audioThread, &QThread::finished, audioThread, &QThread::deleteLater); + + moveToThread(audioThread); + + voiceTimer.setSingleShot(true); + voiceTimer.moveToThread(audioThread); + connect(this, // + &OpenAL::startActive, // + &voiceTimer, // + static_cast(&QTimer::start)); + connect(&voiceTimer, &QTimer::timeout, this, &OpenAL::stopActive); + + connect(&captureTimer, &QTimer::timeout, this, &OpenAL::doAudio); + captureTimer.setInterval(AUDIO_FRAME_DURATION / 2); + captureTimer.setSingleShot(false); + captureTimer.moveToThread(audioThread); + // TODO for Qt 5.6+: use qOverload + connect(audioThread, &QThread::started, &captureTimer, + static_cast(&QTimer::start)); + + cleanupTimer.setInterval(1000); + cleanupTimer.setSingleShot(false); + connect(&cleanupTimer, &QTimer::timeout, this, &OpenAL::cleanupSound); + // TODO for Qt 5.6+: use qOverload + connect(audioThread, &QThread::started, &cleanupTimer, + static_cast(&QTimer::start)); + + audioThread->start(); } OpenAL::~OpenAL() { - audioThread->exit(); - audioThread->wait(); - cleanupInput(); - cleanupOutput(); + audioThread->exit(); + audioThread->wait(); + cleanupInput(); + cleanupOutput(); } void OpenAL::checkAlError() noexcept { - const ALenum al_err = alGetError(); - if (al_err != AL_NO_ERROR) - qWarning("OpenAL error: %d", al_err); + const ALenum al_err = alGetError(); + if (al_err != AL_NO_ERROR) qWarning("OpenAL error: %d", al_err); } -void OpenAL::checkAlcError(ALCdevice *device) noexcept { - const ALCenum alc_err = alcGetError(device); - if (alc_err) - qWarning("OpenAL error: %d", alc_err); +void OpenAL::checkAlcError(ALCdevice* device) noexcept { + const ALCenum alc_err = alcGetError(device); + if (alc_err) qWarning("OpenAL error: %d", alc_err); } /** * @brief Returns the current output volume (between 0 and 1) */ qreal OpenAL::outputVolume() const { - QMutexLocker locker(&audioLock); + QMutexLocker locker(&audioLock); - ALfloat volume = 0.0; + ALfloat volume = 0.0; - if (alOutDev) { - alGetListenerf(AL_GAIN, &volume); - checkAlError(); - } + if (alOutDev) { + alGetListenerf(AL_GAIN, &volume); + checkAlError(); + } - return volume; + return volume; } /** @@ -130,12 +126,12 @@ qreal OpenAL::outputVolume() const { * @param[in] volume the master volume (between 0 and 1) */ void OpenAL::setOutputVolume(qreal volume) { - QMutexLocker locker(&audioLock); + QMutexLocker locker(&audioLock); - volume = std::max(0.0, std::min(volume, 1.0)); + volume = std::max(0.0, std::min(volume, 1.0)); - alListenerf(AL_GAIN, static_cast(volume)); - checkAlError(); + alListenerf(AL_GAIN, static_cast(volume)); + checkAlError(); } /** @@ -144,8 +140,8 @@ void OpenAL::setOutputVolume(qreal volume) { * @return minimum gain value in dB */ qreal OpenAL::minInputGain() const { - QMutexLocker locker(&audioLock); - return minInGain; + QMutexLocker locker(&audioLock); + return minInGain; } /** @@ -154,8 +150,8 @@ qreal OpenAL::minInputGain() const { * @note Default is -30dB; usually you don't need to alter this value; */ void OpenAL::setMinInputGain(qreal dB) { - QMutexLocker locker(&audioLock); - minInGain = dB; + QMutexLocker locker(&audioLock); + minInGain = dB; } /** @@ -164,8 +160,8 @@ void OpenAL::setMinInputGain(qreal dB) { * @return maximum gain value in dB */ qreal OpenAL::maxInputGain() const { - QMutexLocker locker(&audioLock); - return maxInGain; + QMutexLocker locker(&audioLock); + return maxInGain; } /** @@ -174,8 +170,8 @@ qreal OpenAL::maxInputGain() const { * @note Default is 30dB; usually you don't need to alter this value. */ void OpenAL::setMaxInputGain(qreal dB) { - QMutexLocker locker(&audioLock); - maxInGain = dB; + QMutexLocker locker(&audioLock); + maxInGain = dB; } /** @@ -184,8 +180,8 @@ void OpenAL::setMaxInputGain(qreal dB) { * @return minimum normalized threshold */ qreal OpenAL::minInputThreshold() const { - QMutexLocker locker(&audioLock); - return minInThreshold; + QMutexLocker locker(&audioLock); + return minInThreshold; } /** @@ -194,45 +190,45 @@ qreal OpenAL::minInputThreshold() const { * @return maximum normalized threshold */ qreal OpenAL::maxInputThreshold() const { - QMutexLocker locker(&audioLock); - return maxInThreshold; + QMutexLocker locker(&audioLock); + return maxInThreshold; } -void OpenAL::reinitInput(const QString &inDevDesc) { - QMutexLocker locker(&audioLock); +void OpenAL::reinitInput(const QString& inDevDesc) { + QMutexLocker locker(&audioLock); - const auto bakSources = sources; - sources.clear(); + const auto bakSources = sources; + sources.clear(); - cleanupInput(); - initInput(inDevDesc); + cleanupInput(); + initInput(inDevDesc); - locker.unlock(); - // this must happen outside `audioLock`, to avoid a deadlock when - // a slot on AlSource::invalidate tries to create a new source immedeately. - for (auto &source : bakSources) { - source->kill(); - } + locker.unlock(); + // this must happen outside `audioLock`, to avoid a deadlock when + // a slot on AlSource::invalidate tries to create a new source immedeately. + for (auto& source : bakSources) { + source->kill(); + } } -bool OpenAL::reinitOutput(const QString &outDevDesc) { - QMutexLocker locker(&audioLock); +bool OpenAL::reinitOutput(const QString& outDevDesc) { + QMutexLocker locker(&audioLock); - const auto bakSinks = sinks; + const auto bakSinks = sinks; - sinks.clear(); + sinks.clear(); - cleanupOutput(); - const bool result = initOutput(outDevDesc); + cleanupOutput(); + const bool result = initOutput(outDevDesc); - locker.unlock(); - // this must happen outside `audioLock`, to avoid a deadlock when - // a slot on AlSink::invalidate tries to create a new source immedeately. - for (auto &sink : bakSinks) { - sink->kill(); - } + locker.unlock(); + // this must happen outside `audioLock`, to avoid a deadlock when + // a slot on AlSink::invalidate tries to create a new source immedeately. + for (auto& sink : bakSinks) { + sink->kill(); + } - return result; + return result; } /** @@ -240,26 +236,25 @@ bool OpenAL::reinitOutput(const QString &outDevDesc) { * @return AudioSink on success, nullptr on failure */ std::unique_ptr OpenAL::makeSink() { - QMutexLocker locker(&audioLock); + QMutexLocker locker(&audioLock); - if (!autoInitOutput()) { - qWarning("Failed to subscribe to audio output device."); - return {}; - } + if (!autoInitOutput()) { + qWarning("Failed to subscribe to audio output device."); + return {}; + } - ALuint sid; - alGenSources(1, &sid); + ALuint sid; + alGenSources(1, &sid); - auto const sink = new AlSink(*this, sid); - if (sink == nullptr) { - return {}; - } + auto const sink = new AlSink(*this, sid); + if (sink == nullptr) { + return {}; + } - sinks.insert(sink); - qDebug() << "Audio source" << sid - << "created. Sources active:" << sinks.size(); + sinks.insert(sink); + qDebug() << "Audio source" << sid << "created. Sources active:" << sinks.size(); - return std::unique_ptr{sink}; + return std::unique_ptr{sink}; } /** @@ -267,32 +262,31 @@ std::unique_ptr OpenAL::makeSink() { * ressources. If no sinks are opened, the output is closed afterwards. * @param sink Audio sink to remove. */ -void OpenAL::destroySink(AlSink &sink) { - QMutexLocker locker(&audioLock); - - const auto sinksErased = sinks.erase(&sink); - const auto soundSinksErased = soundSinks.erase(&sink); - - if (sinksErased == 0 && soundSinksErased == 0) { - qWarning() << "Destroying non-existant source"; - return; - } - - const uint sid = sink.getSourceId(); - - if (alIsSource(sid)) { - // stop playing, marks all buffers as processed - alSourceStop(sid); - cleanupBuffers(sid); - qDebug() << "Audio source" << sid - << "deleted. Sources active:" << sinks.size(); - } else { - qWarning() << "Trying to delete invalid audio source" << sid; - } - - if (sinks.empty() && soundSinks.empty()) { - cleanupOutput(); - } +void OpenAL::destroySink(AlSink& sink) { + QMutexLocker locker(&audioLock); + + const auto sinksErased = sinks.erase(&sink); + const auto soundSinksErased = soundSinks.erase(&sink); + + if (sinksErased == 0 && soundSinksErased == 0) { + qWarning() << "Destroying non-existant source"; + return; + } + + const uint sid = sink.getSourceId(); + + if (alIsSource(sid)) { + // stop playing, marks all buffers as processed + alSourceStop(sid); + cleanupBuffers(sid); + qDebug() << "Audio source" << sid << "deleted. Sources active:" << sinks.size(); + } else { + qWarning() << "Trying to delete invalid audio source" << sid; + } + + if (sinks.empty() && soundSinks.empty()) { + cleanupOutput(); + } } /** @@ -301,24 +295,23 @@ void OpenAL::destroySink(AlSink &sink) { * If the input device is not open, it will be opened before capturing. */ std::unique_ptr OpenAL::makeSource() { - QMutexLocker locker(&audioLock); + QMutexLocker locker(&audioLock); - if (!autoInitInput()) { - qWarning("Failed to subscribe to audio input device."); - return {}; - } + if (!autoInitInput()) { + qWarning("Failed to subscribe to audio input device."); + return {}; + } - auto const source = new AlSource(*this); - if (source == nullptr) { - return {}; - } + auto const source = new AlSource(*this); + if (source == nullptr) { + return {}; + } - sources.insert(source); + sources.insert(source); - qDebug() << "Subscribed to audio input device [" << sources.size() - << "subscriptions ]"; + qDebug() << "Subscribed to audio input device [" << sources.size() << "subscriptions ]"; - return std::unique_ptr{source}; + return std::unique_ptr{source}; } /** @@ -326,23 +319,23 @@ std::unique_ptr OpenAL::makeSource() { * * If the input device has no more subscriptions, it will be closed. */ -void OpenAL::destroySource(AlSource &source) { - QMutexLocker locker(&audioLock); +void OpenAL::destroySource(AlSource& source) { + QMutexLocker locker(&audioLock); - const auto s = sources.find(&source); - if (s == sources.end()) { - qWarning() << "Destroyed non-existant source"; - return; - } + const auto s = sources.find(&source); + if (s == sources.end()) { + qWarning() << "Destroyed non-existant source"; + return; + } - sources.erase(s); + sources.erase(s); - qDebug() << "Unsubscribed from audio input device [" << sources.size() - << "subscriptions left ]"; + qDebug() << "Unsubscribed from audio input device [" << sources.size() + << "subscriptions left ]"; - if (sources.empty()) { - cleanupInput(); - } + if (sources.empty()) { + cleanupInput(); + } } /** @@ -351,7 +344,7 @@ void OpenAL::destroySource(AlSource &source) { * @return true, if device was initialized; false otherwise */ bool OpenAL::autoInitInput() { - return alInDev ? true : initInput(Settings::getInstance().getInDev()); + return alInDev ? true : initInput(Settings::getInstance().getInDev()); } /** @@ -360,239 +353,226 @@ bool OpenAL::autoInitInput() { * @return true, if device was initialized; false otherwise */ bool OpenAL::autoInitOutput() { - return alOutDev ? true : initOutput(Settings::getInstance().getOutDev()); -} - -bool OpenAL::initInput(const QString &deviceName) { - return initInput(deviceName, AUDIO_CHANNELS); + return alOutDev ? true : initOutput(Settings::getInstance().getOutDev()); } -bool OpenAL::initInput(const QString &deviceName, uint32_t channels) { - if (!Settings::getInstance().getAudioInDevEnabled()) { - return false; - } +bool OpenAL::initInput(const QString& deviceName) { return initInput(deviceName, AUDIO_CHANNELS); } - qDebug() << "Opening audio input" << deviceName; - assert(!alInDev); - - // TODO: Try to actually detect if our audio source is stereo - this->channels = channels; - int stereoFlag = channels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16; - const int bytesPerSample = 2; - const int safetyFactor = - 2; // internal OpenAL ring buffer. must be larger than our inputBuffer - // to avoid the ring from overwriting itself between captures. - AUDIO_FRAME_SAMPLE_COUNT_TOTAL = - AUDIO_FRAME_SAMPLE_COUNT_PER_CHANNEL * channels; - const ALCsizei ringBufSize = - AUDIO_FRAME_SAMPLE_COUNT_TOTAL * bytesPerSample * safetyFactor; - - const QByteArray qDevName = deviceName.toUtf8(); - const ALchar *tmpDevName = - qDevName.isEmpty() ? nullptr : qDevName.constData(); - alInDev = alcCaptureOpenDevice(tmpDevName, AUDIO_SAMPLE_RATE, stereoFlag, - ringBufSize); +bool OpenAL::initInput(const QString& deviceName, uint32_t channels) { + if (!Settings::getInstance().getAudioInDevEnabled()) { + return false; + } - // Restart the capture if necessary - if (!alInDev) { - qWarning() << "Failed to initialize audio input device:" << deviceName; - return false; - } + qDebug() << "Opening audio input" << deviceName; + assert(!alInDev); + + // TODO: Try to actually detect if our audio source is stereo + this->channels = channels; + int stereoFlag = channels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16; + const int bytesPerSample = 2; + const int safetyFactor = 2; // internal OpenAL ring buffer. must be larger than our inputBuffer + // to avoid the ring from overwriting itself between captures. + AUDIO_FRAME_SAMPLE_COUNT_TOTAL = AUDIO_FRAME_SAMPLE_COUNT_PER_CHANNEL * channels; + const ALCsizei ringBufSize = AUDIO_FRAME_SAMPLE_COUNT_TOTAL * bytesPerSample * safetyFactor; + + const QByteArray qDevName = deviceName.toUtf8(); + const ALchar* tmpDevName = qDevName.isEmpty() ? nullptr : qDevName.constData(); + alInDev = alcCaptureOpenDevice(tmpDevName, AUDIO_SAMPLE_RATE, stereoFlag, ringBufSize); + + // Restart the capture if necessary + if (!alInDev) { + qWarning() << "Failed to initialize audio input device:" << deviceName; + return false; + } - inputBuffer = new int16_t[AUDIO_FRAME_SAMPLE_COUNT_TOTAL]; - setInputGain(Settings::getInstance().getAudioInGainDecibel()); - setInputThreshold(Settings::getInstance().getAudioThreshold()); + inputBuffer = new int16_t[AUDIO_FRAME_SAMPLE_COUNT_TOTAL]; + setInputGain(Settings::getInstance().getAudioInGainDecibel()); + setInputThreshold(Settings::getInstance().getAudioThreshold()); - qDebug() << "Opened audio input" << deviceName; - alcCaptureStart(alInDev); + qDebug() << "Opened audio input" << deviceName; + alcCaptureStart(alInDev); - return true; + return true; } /** * @brief Open an audio output device */ -bool OpenAL::initOutput(const QString &deviceName) { - // there should be no sinks when initializing the output - assert(sinks.size() == 0); +bool OpenAL::initOutput(const QString& deviceName) { + // there should be no sinks when initializing the output + assert(sinks.size() == 0); - outputInitialized = false; - if (!Settings::getInstance().getAudioOutDevEnabled()) - return false; + outputInitialized = false; + if (!Settings::getInstance().getAudioOutDevEnabled()) return false; - qDebug() << "Opening audio output" << deviceName; - assert(!alOutDev); + qDebug() << "Opening audio output" << deviceName; + assert(!alOutDev); - const QByteArray qDevName = deviceName.toUtf8(); - const ALchar *tmpDevName = - qDevName.isEmpty() ? nullptr : qDevName.constData(); - alOutDev = alcOpenDevice(tmpDevName); + const QByteArray qDevName = deviceName.toUtf8(); + const ALchar* tmpDevName = qDevName.isEmpty() ? nullptr : qDevName.constData(); + alOutDev = alcOpenDevice(tmpDevName); - if (!alOutDev) { - qWarning() << "Cannot open output audio device" << deviceName; - return false; - } + if (!alOutDev) { + qWarning() << "Cannot open output audio device" << deviceName; + return false; + } - qDebug() << "Opened audio output" << deviceName; - alOutContext = alcCreateContext(alOutDev, nullptr); - checkAlcError(alOutDev); + qDebug() << "Opened audio output" << deviceName; + alOutContext = alcCreateContext(alOutDev, nullptr); + checkAlcError(alOutDev); - if (!alcMakeContextCurrent(alOutContext)) { - qWarning() << "Cannot create output audio context"; - return false; - } + if (!alcMakeContextCurrent(alOutContext)) { + qWarning() << "Cannot create output audio context"; + return false; + } - // init master volume - alListenerf(AL_GAIN, Settings::getInstance().getOutVolume() * 0.01f); - checkAlError(); + // init master volume + alListenerf(AL_GAIN, Settings::getInstance().getOutVolume() * 0.01f); + checkAlError(); - outputInitialized = true; - return true; + outputInitialized = true; + return true; } /** * @brief Play a 48kHz mono 16bit PCM sound */ -void OpenAL::playMono16Sound(AlSink &sink, const IAudioSink::Sound &sound) { - const uint sourceId = sink.getSourceId(); - QFile sndFile(IAudioSink::getSound(sound)); - if (!sndFile.exists()) { - qDebug() << "Trying to open non existent sound file"; - return; - } - - sndFile.open(QIODevice::ReadOnly); - const QByteArray data{sndFile.readAll()}; - if (data.isEmpty()) { - qDebug() << "Sound file contained no data"; - return; - } - - QMutexLocker locker(&audioLock); - - // interrupt possibly playing sound, we don't buffer here - alSourceStop(sourceId); - - ALint processed = 0; - alGetSourcei(sourceId, AL_BUFFERS_PROCESSED, &processed); - alSourcei(sourceId, AL_LOOPING, AL_FALSE); - - ALuint bufid; - if (processed == 0) { - // create new buffer - alGenBuffers(1, &bufid); - } else { - // we only reserve space for one buffer - assert(processed == 1); - // unqueue all processed buffers - alSourceUnqueueBuffers(sourceId, processed, &bufid); - } - - alBufferData(bufid, AL_FORMAT_MONO16, data.constData(), data.size(), - AUDIO_SAMPLE_RATE); - alSourcei(sourceId, AL_BUFFER, bufid); - alSourcePlay(sourceId); - soundSinks.insert(&sink); +void OpenAL::playMono16Sound(AlSink& sink, const IAudioSink::Sound& sound) { + const uint sourceId = sink.getSourceId(); + QFile sndFile(IAudioSink::getSound(sound)); + if (!sndFile.exists()) { + qDebug() << "Trying to open non existent sound file"; + return; + } + + sndFile.open(QIODevice::ReadOnly); + const QByteArray data{sndFile.readAll()}; + if (data.isEmpty()) { + qDebug() << "Sound file contained no data"; + return; + } + + QMutexLocker locker(&audioLock); + + // interrupt possibly playing sound, we don't buffer here + alSourceStop(sourceId); + + ALint processed = 0; + alGetSourcei(sourceId, AL_BUFFERS_PROCESSED, &processed); + alSourcei(sourceId, AL_LOOPING, AL_FALSE); + + ALuint bufid; + if (processed == 0) { + // create new buffer + alGenBuffers(1, &bufid); + } else { + // we only reserve space for one buffer + assert(processed == 1); + // unqueue all processed buffers + alSourceUnqueueBuffers(sourceId, processed, &bufid); + } + + alBufferData(bufid, AL_FORMAT_MONO16, data.constData(), data.size(), AUDIO_SAMPLE_RATE); + alSourcei(sourceId, AL_BUFFER, bufid); + alSourcePlay(sourceId); + soundSinks.insert(&sink); } void OpenAL::cleanupSound() { - QMutexLocker locker(&audioLock); + QMutexLocker locker(&audioLock); + + auto sinkIt = soundSinks.begin(); + while (sinkIt != soundSinks.end()) { + auto sink = *sinkIt; + ALuint sourceId = sink->getSourceId(); + ALint state = 0; + + alGetSourcei(sourceId, AL_SOURCE_STATE, &state); + if (state != AL_PLAYING) { + sinkIt = soundSinks.erase(sinkIt); + emit sink->finishedPlaying(); + } else { + ++sinkIt; + } + } +} + +void OpenAL::playAudioBuffer(uint sourceId, const int16_t* data, int samples, unsigned channels, + int sampleRate) { + assert(channels == 1 || channels == 2); + QMutexLocker locker(&audioLock); + + if (!(alOutDev && outputInitialized)) return; - auto sinkIt = soundSinks.begin(); - while (sinkIt != soundSinks.end()) { - auto sink = *sinkIt; - ALuint sourceId = sink->getSourceId(); - ALint state = 0; + ALuint bufids[BUFFER_COUNT]; + ALint processed = 0, queued = 0; + alGetSourcei(sourceId, AL_BUFFERS_PROCESSED, &processed); + alGetSourcei(sourceId, AL_BUFFERS_QUEUED, &queued); + alSourcei(sourceId, AL_LOOPING, AL_FALSE); + + if (processed == 0) { + if (static_cast(queued) >= BUFFER_COUNT) { + // reached limit, drop audio + return; + } + // create new buffer if none got free and we're below the limit + alGenBuffers(1, bufids); + } else { + // unqueue all processed buffers + alSourceUnqueueBuffers(sourceId, processed, bufids); + // delete all but the first buffer, reuse first for new data + alDeleteBuffers(processed - 1, bufids + 1); + } + alBufferData(bufids[0], (channels == 1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, data, + samples * 2 * channels, sampleRate); + alSourceQueueBuffers(sourceId, 1, bufids); + + ALint state; alGetSourcei(sourceId, AL_SOURCE_STATE, &state); if (state != AL_PLAYING) { - sinkIt = soundSinks.erase(sinkIt); - emit sink->finishedPlaying(); - } else { - ++sinkIt; - } - } -} - -void OpenAL::playAudioBuffer(uint sourceId, const int16_t *data, int samples, - unsigned channels, int sampleRate) { - assert(channels == 1 || channels == 2); - QMutexLocker locker(&audioLock); - - if (!(alOutDev && outputInitialized)) - return; - - ALuint bufids[BUFFER_COUNT]; - ALint processed = 0, queued = 0; - alGetSourcei(sourceId, AL_BUFFERS_PROCESSED, &processed); - alGetSourcei(sourceId, AL_BUFFERS_QUEUED, &queued); - alSourcei(sourceId, AL_LOOPING, AL_FALSE); - - if (processed == 0) { - if (static_cast(queued) >= BUFFER_COUNT) { - // reached limit, drop audio - return; - } - // create new buffer if none got free and we're below the limit - alGenBuffers(1, bufids); - } else { - // unqueue all processed buffers - alSourceUnqueueBuffers(sourceId, processed, bufids); - // delete all but the first buffer, reuse first for new data - alDeleteBuffers(processed - 1, bufids + 1); - } - - alBufferData(bufids[0], - (channels == 1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, data, - samples * 2 * channels, sampleRate); - alSourceQueueBuffers(sourceId, 1, bufids); - - ALint state; - alGetSourcei(sourceId, AL_SOURCE_STATE, &state); - if (state != AL_PLAYING) { - alSourcePlay(sourceId); - } + alSourcePlay(sourceId); + } } /** * @brief Close active audio input device. */ void OpenAL::cleanupInput() { - if (!alInDev) - return; + if (!alInDev) return; - qDebug() << "Closing audio input"; - alcCaptureStop(alInDev); - if (alcCaptureCloseDevice(alInDev) == ALC_TRUE) { - alInDev = nullptr; - } else { - qWarning() << "Failed to close input"; - } + qDebug() << "Closing audio input"; + alcCaptureStop(alInDev); + if (alcCaptureCloseDevice(alInDev) == ALC_TRUE) { + alInDev = nullptr; + } else { + qWarning() << "Failed to close input"; + } - delete[] inputBuffer; + delete[] inputBuffer; } /** * @brief Close active audio output device */ void OpenAL::cleanupOutput() { - outputInitialized = false; - - if (alOutDev) { - if (!alcMakeContextCurrent(nullptr)) { - qWarning("Failed to clear audio context."); - } - - alcDestroyContext(alOutContext); - alOutContext = nullptr; - - qDebug() << "Closing audio output"; - if (alcCloseDevice(alOutDev)) { - alOutDev = nullptr; - } else { - qWarning("Failed to close output."); + outputInitialized = false; + + if (alOutDev) { + if (!alcMakeContextCurrent(nullptr)) { + qWarning("Failed to clear audio context."); + } + + alcDestroyContext(alOutContext); + alOutContext = nullptr; + + qDebug() << "Closing audio output"; + if (alcCloseDevice(alOutDev)) { + alOutDev = nullptr; + } else { + qWarning("Failed to close output."); + } } - } } /** @@ -603,20 +583,19 @@ void OpenAL::cleanupOutput() { * @return normalized volume between 0-1 */ float OpenAL::getVolume() { - const quint32 samples = AUDIO_FRAME_SAMPLE_COUNT_TOTAL; - const float rootTwo = 1.414213562; // sqrt(2), but sqrt is not constexpr - // calculate volume as the root mean squared of amplitudes in the sample - float sumOfSquares = 0; - for (quint32 i = 0; i < samples; i++) { - float sample = static_cast(inputBuffer[i]) / - std::numeric_limits::max(); - sumOfSquares += std::pow(sample, 2); - } - const float rms = std::sqrt(sumOfSquares / samples); - // our calculated normalized volume could possibly be above 1 because our RMS - // assumes a sinusoidal wave - const float normalizedVolume = std::min(rms * rootTwo, 1.0f); - return normalizedVolume; + const quint32 samples = AUDIO_FRAME_SAMPLE_COUNT_TOTAL; + const float rootTwo = 1.414213562; // sqrt(2), but sqrt is not constexpr + // calculate volume as the root mean squared of amplitudes in the sample + float sumOfSquares = 0; + for (quint32 i = 0; i < samples; i++) { + float sample = static_cast(inputBuffer[i]) / std::numeric_limits::max(); + sumOfSquares += std::pow(sample, 2); + } + const float rms = std::sqrt(sumOfSquares / samples); + // our calculated normalized volume could possibly be above 1 because our RMS + // assumes a sinusoidal wave + const float normalizedVolume = std::min(rms * rootTwo, 1.0f); + return normalizedVolume; } /** @@ -628,103 +607,100 @@ void OpenAL::stopActive() { isActive = false; } * @brief handles recording of audio frames */ void OpenAL::doInput() { - ALint curSamples = 0; - alcGetIntegerv(alInDev, ALC_CAPTURE_SAMPLES, sizeof(curSamples), &curSamples); - if (curSamples < static_cast(AUDIO_FRAME_SAMPLE_COUNT_PER_CHANNEL)) { - return; - } - - captureSamples(alInDev, inputBuffer, AUDIO_FRAME_SAMPLE_COUNT_PER_CHANNEL); - - applyGain(inputBuffer, AUDIO_FRAME_SAMPLE_COUNT_TOTAL, gainFactor); - - float volume = getVolume(); - if (volume >= inputThreshold) { - isActive = true; - emit startActive(voiceHold); - } else if (!isActive) { - volume = 0; - } - - // NOTE(sudden6): this loop probably doesn't scale too well with many sources - for (auto source : sources) { - emit source->volumeAvailable(volume); - } - if (!isActive) { - return; - } - - // NOTE(sudden6): this loop probably doesn't scale too well with many sources - for (auto source : sources) { - emit source->frameAvailable(inputBuffer, - AUDIO_FRAME_SAMPLE_COUNT_PER_CHANNEL, channels, - AUDIO_SAMPLE_RATE); - } + ALint curSamples = 0; + alcGetIntegerv(alInDev, ALC_CAPTURE_SAMPLES, sizeof(curSamples), &curSamples); + if (curSamples < static_cast(AUDIO_FRAME_SAMPLE_COUNT_PER_CHANNEL)) { + return; + } + + captureSamples(alInDev, inputBuffer, AUDIO_FRAME_SAMPLE_COUNT_PER_CHANNEL); + + applyGain(inputBuffer, AUDIO_FRAME_SAMPLE_COUNT_TOTAL, gainFactor); + + float volume = getVolume(); + if (volume >= inputThreshold) { + isActive = true; + emit startActive(voiceHold); + } else if (!isActive) { + volume = 0; + } + + // NOTE(sudden6): this loop probably doesn't scale too well with many sources + for (auto source : sources) { + emit source->volumeAvailable(volume); + } + if (!isActive) { + return; + } + + // NOTE(sudden6): this loop probably doesn't scale too well with many sources + for (auto source : sources) { + emit source->frameAvailable(inputBuffer, AUDIO_FRAME_SAMPLE_COUNT_PER_CHANNEL, channels, + AUDIO_SAMPLE_RATE); + } } void OpenAL::doOutput() { - // Nothing + // Nothing } /** * @brief Called on the captureTimer events to capture audio */ void OpenAL::doAudio() { - QMutexLocker lock(&audioLock); + QMutexLocker lock(&audioLock); - // Output section does nothing + // Output section does nothing - // Input section - if (alInDev && !sources.empty()) { - doInput(); - } + // Input section + if (alInDev && !sources.empty()) { + doInput(); + } } -void OpenAL::captureSamples(ALCdevice *device, int16_t *buffer, - ALCsizei samples) { - alcCaptureSamples(device, buffer, samples); +void OpenAL::captureSamples(ALCdevice* device, int16_t* buffer, ALCsizei samples) { + alcCaptureSamples(device, buffer, samples); } /** * @brief Returns true if the output device is open */ bool OpenAL::isOutputReady() const { - QMutexLocker locker(&audioLock); - return alOutDev && outputInitialized; + QMutexLocker locker(&audioLock); + return alOutDev && outputInitialized; } QStringList OpenAL::outDeviceNames() { - QStringList list; - const ALchar *pDeviceList = - (alcIsExtensionPresent(nullptr, "ALC_ENUMERATE_ALL_EXT") != AL_FALSE) - ? alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER) - : alcGetString(nullptr, ALC_DEVICE_SPECIFIER); - - if (pDeviceList) { - while (*pDeviceList) { - int len = static_cast(strlen(pDeviceList)); - list << QString::fromUtf8(pDeviceList, len); - pDeviceList += len + 1; + QStringList list; + const ALchar* pDeviceList = + (alcIsExtensionPresent(nullptr, "ALC_ENUMERATE_ALL_EXT") != AL_FALSE) + ? alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER) + : alcGetString(nullptr, ALC_DEVICE_SPECIFIER); + + if (pDeviceList) { + while (*pDeviceList) { + int len = static_cast(strlen(pDeviceList)); + list << QString::fromUtf8(pDeviceList, len); + pDeviceList += len + 1; + } } - } - return list; + return list; } QStringList OpenAL::inDeviceNames() { - QStringList list; - const ALchar *pDeviceList = - alcGetString(nullptr, ALC_CAPTURE_DEVICE_SPECIFIER); - - if (pDeviceList) { - while (*pDeviceList) { - int len = static_cast(strlen(pDeviceList)); - list << QString::fromUtf8(pDeviceList, len); - pDeviceList += len + 1; + QStringList list; + const ALchar* pDeviceList = alcGetString(nullptr, ALC_CAPTURE_DEVICE_SPECIFIER); + + if (pDeviceList) { + while (*pDeviceList) { + int len = static_cast(strlen(pDeviceList)); + list << QString::fromUtf8(pDeviceList, len); + pDeviceList += len + 1; + } } - } - return list; + return list; } /** @@ -732,29 +708,29 @@ QStringList OpenAL::inDeviceNames() { * @param sourceId where to remove the buffers from */ void OpenAL::cleanupBuffers(uint sourceId) { - // unqueue all buffers from the source - ALint processed = 0; - alGetSourcei(sourceId, AL_BUFFERS_PROCESSED, &processed); - std::vector bufids; - // should never be out of range, just to be sure - assert(processed >= 0); - assert(processed <= SIZE_MAX); - bufids.resize(processed); - alSourceUnqueueBuffers(sourceId, processed, bufids.data()); - // delete all buffers - alDeleteBuffers(processed, bufids.data()); + // unqueue all buffers from the source + ALint processed = 0; + alGetSourcei(sourceId, AL_BUFFERS_PROCESSED, &processed); + std::vector bufids; + // should never be out of range, just to be sure + assert(processed >= 0); + assert(processed <= SIZE_MAX); + bufids.resize(processed); + alSourceUnqueueBuffers(sourceId, processed, bufids.data()); + // delete all buffers + alDeleteBuffers(processed, bufids.data()); } void OpenAL::startLoop(uint sourceId) { - QMutexLocker locker(&audioLock); - alSourcei(sourceId, AL_LOOPING, AL_TRUE); + QMutexLocker locker(&audioLock); + alSourcei(sourceId, AL_LOOPING, AL_TRUE); } void OpenAL::stopLoop(uint sourceId) { - QMutexLocker locker(&audioLock); - alSourcei(sourceId, AL_LOOPING, AL_FALSE); - alSourceStop(sourceId); - cleanupBuffers(sourceId); + QMutexLocker locker(&audioLock); + alSourcei(sourceId, AL_LOOPING, AL_FALSE); + alSourceStop(sourceId); + cleanupBuffers(sourceId); } qreal OpenAL::inputGain() const { return gain; } @@ -764,10 +740,8 @@ qreal OpenAL::getInputThreshold() const { return inputThreshold; } qreal OpenAL::inputGainFactor() const { return gainFactor; } void OpenAL::setInputGain(qreal dB) { - gain = qBound(minInGain, dB, maxInGain); - gainFactor = qPow(10.0, (gain / 20.0)); + gain = qBound(minInGain, dB, maxInGain); + gainFactor = qPow(10.0, (gain / 20.0)); } -void OpenAL::setInputThreshold(qreal normalizedThreshold) { - inputThreshold = normalizedThreshold; -} +void OpenAL::setInputThreshold(qreal normalizedThreshold) { inputThreshold = normalizedThreshold; } diff --git a/src/modules/im/src/audio/backend/openal.h b/src/modules/im/src/audio/backend/openal.h index 370c5233..53803506 100644 --- a/src/modules/im/src/audio/backend/openal.h +++ b/src/modules/im/src/audio/backend/openal.h @@ -10,14 +10,13 @@ * See the Mulan PubL v2 for more details. */ +#ifndef OPENAL_H +#define OPENAL_H -#ifndef OK_OPENAL_H -#define OK_OPENAL_H - -#include "src/audio/iaudiocontrol.h" +#include "base/compatiblerecursivemutex.h" #include "src/audio/backend/alsink.h" #include "src/audio/backend/alsource.h" -#include "base/compatiblerecursivemutex.h" +#include "src/audio/iaudiocontrol.h" #include #include @@ -39,22 +38,15 @@ #include #endif -class OpenAL : public IAudioControl -{ +class OpenAL : public IAudioControl { Q_OBJECT public: OpenAL(); virtual ~OpenAL(); - qreal maxOutputVolume() const - { - return 1; - } - qreal minOutputVolume() const - { - return 0; - } + qreal maxOutputVolume() const { return 1; } + qreal minOutputVolume() const { return 0; } qreal outputVolume() const; void setOutputVolume(qreal volume); @@ -159,4 +151,4 @@ class OpenAL : public IAudioControl int16_t* inputBuffer = nullptr; }; -#endif // OPENAL_H +#endif // OPENAL_H diff --git a/src/modules/im/src/audio/iaudiocontrol.h b/src/modules/im/src/audio/iaudiocontrol.h index a02dc67d..4e4cb9df 100644 --- a/src/modules/im/src/audio/iaudiocontrol.h +++ b/src/modules/im/src/audio/iaudiocontrol.h @@ -93,8 +93,7 @@ class IAudioSink; class IAudioSource; -class IAudioControl : public QObject -{ +class IAudioControl : public QObject { Q_OBJECT public: @@ -136,9 +135,8 @@ class IAudioControl : public QObject static constexpr uint32_t AUDIO_SAMPLE_RATE = 48000; static constexpr uint32_t AUDIO_FRAME_DURATION = 20; static constexpr uint32_t AUDIO_FRAME_SAMPLE_COUNT_PER_CHANNEL = - AUDIO_FRAME_DURATION * AUDIO_SAMPLE_RATE / 1000; + AUDIO_FRAME_DURATION * AUDIO_SAMPLE_RATE / 1000; uint32_t AUDIO_FRAME_SAMPLE_COUNT_TOTAL = 0; }; - -#endif // IAUDIOCONTROL_H +#endif // IAUDIOCONTROL_H diff --git a/src/modules/im/src/audio/iaudiosettings.h b/src/modules/im/src/audio/iaudiosettings.h index 67382d8c..7ced85f0 100644 --- a/src/modules/im/src/audio/iaudiosettings.h +++ b/src/modules/im/src/audio/iaudiosettings.h @@ -63,4 +63,4 @@ class IAudioSettings { DECLARE_SIGNAL(enableTestSoundChanged, bool newValue); }; -#endif // I_AUDIO_SETTINGS_H +#endif // I_AUDIO_SETTINGS_H diff --git a/src/modules/im/src/audio/iaudiosink.h b/src/modules/im/src/audio/iaudiosink.h index dafd6532..79a25e1f 100644 --- a/src/modules/im/src/audio/iaudiosink.h +++ b/src/modules/im/src/audio/iaudiosink.h @@ -60,31 +60,22 @@ * */ -class IAudioSink -{ +class IAudioSink { public: - enum class Sound - { - NewMessage, - Test, - IncomingCall, - OutgoingCall, - CallEnd - }; + enum class Sound { NewMessage, Test, IncomingCall, OutgoingCall, CallEnd }; - inline static QString getSound(Sound s) - { + inline static QString getSound(Sound s) { switch (s) { - case Sound::Test: - return QStringLiteral(":/audio/notification.s16le.pcm"); - case Sound::NewMessage: - return QStringLiteral(":/audio/notification.s16le.pcm"); - case Sound::IncomingCall: - return QStringLiteral(":/audio/ToxIncomingCall.s16le.pcm"); - case Sound::OutgoingCall: - return QStringLiteral(":/audio/ToxOutgoingCall.s16le.pcm"); - case Sound::CallEnd: - return QStringLiteral(":/audio/ToxEndCall.s16le.pcm"); + case Sound::Test: + return QStringLiteral(":/audio/notification.s16le.pcm"); + case Sound::NewMessage: + return QStringLiteral(":/audio/notification.s16le.pcm"); + case Sound::IncomingCall: + return QStringLiteral(":/audio/ToxIncomingCall.s16le.pcm"); + case Sound::OutgoingCall: + return QStringLiteral(":/audio/ToxOutgoingCall.s16le.pcm"); + case Sound::CallEnd: + return QStringLiteral(":/audio/ToxEndCall.s16le.pcm"); } assert(false); return {}; @@ -108,4 +99,4 @@ class IAudioSink DECLARE_SIGNAL(invalidated); }; -#endif // IAUDIOSINK_H +#endif // IAUDIOSINK_H diff --git a/src/modules/im/src/audio/iaudiosource.h b/src/modules/im/src/audio/iaudiosource.h index 97346ec8..fd2d041a 100644 --- a/src/modules/im/src/audio/iaudiosource.h +++ b/src/modules/im/src/audio/iaudiosource.h @@ -23,8 +23,7 @@ * Always connect with a blocking queued connection lambda, else the behaviour is undefined */ -class IAudioSource : public QObject -{ +class IAudioSource : public QObject { Q_OBJECT public: virtual ~IAudioSource() = default; @@ -40,4 +39,4 @@ class IAudioSource : public QObject void invalidated(); }; -#endif // IAUDIOSOURCE_H +#endif // IAUDIOSOURCE_H diff --git a/src/modules/im/src/chatlog/chatline.cpp b/src/modules/im/src/chatlog/chatline.cpp index 529263cd..592f2c75 100644 --- a/src/modules/im/src/chatlog/chatline.cpp +++ b/src/modules/im/src/chatlog/chatline.cpp @@ -17,93 +17,70 @@ #include #include -void IChatItem::moveBy(qreal dx, qreal dy) -{ - for(ChatLineContent * content : contents()) - { +void IChatItem::moveBy(qreal dx, qreal dy) { + for (ChatLineContent* content : contents()) { content->moveBy(dx, dy); } } -void IChatItem::addToScene(QGraphicsScene *scene) -{ - for (ChatLineContent *content : contents()) - { +void IChatItem::addToScene(QGraphicsScene* scene) { + for (ChatLineContent* content : contents()) { scene->addItem(content); } } -void IChatItem::removeFromScene() -{ - for (ChatLineContent *content : contents()) - { - if (content->scene()) - content->scene()->removeItem(content); +void IChatItem::removeFromScene() { + for (ChatLineContent* content : contents()) { + if (content->scene()) content->scene()->removeItem(content); } } -void IChatItem::setVisible(bool visible) -{ - for (ChatLineContent *content : contents()) - { +void IChatItem::setVisible(bool visible) { + for (ChatLineContent* content : contents()) { content->setVisible(visible); } } -ChatLineContent *IChatItem::centerContent() const -{ - return nullptr; -} +ChatLineContent* IChatItem::centerContent() const { return nullptr; } -void IChatItem::visibilityChanged(bool visible) -{ - for (ChatLineContent *content : contents()) - { +void IChatItem::visibilityChanged(bool visible) { + for (ChatLineContent* content : contents()) { content->visibilityChanged(visible); } } -void IChatItem::selectionFocusChanged(bool focusIn) -{ - for (ChatLineContent *content : contents()) - { +void IChatItem::selectionFocusChanged(bool focusIn) { + for (ChatLineContent* content : contents()) { content->selectionFocusChanged(focusIn); } } -void IChatItem::selectionCleared() -{ - for (ChatLineContent* content : contents()) - { +void IChatItem::selectionCleared() { + for (ChatLineContent* content : contents()) { content->selectionCleared(); } } -void IChatItem::selectAll() -{ - for (ChatLineContent *content : contents()) - { +void IChatItem::selectAll() { + for (ChatLineContent* content : contents()) { content->selectAll(); } } -void IChatItem::setRow(int row) -{ +void IChatItem::setRow(int row) { this->row = row; auto content = centerContent(); - if (content) - content->setIndex(row, 0); + if (content) content->setIndex(row, 0); } -void IChatItem::fontChanged(const QFont &font) { - for (ChatLineContent *content : contents()) { +void IChatItem::fontChanged(const QFont& font) { + for (ChatLineContent* content : contents()) { content->fontChanged(font); } } void IChatItem::reloadTheme() { - for (ChatLineContent *content : contents()) { + for (ChatLineContent* content : contents()) { content->reloadTheme(); } } - diff --git a/src/modules/im/src/chatlog/chatline.h b/src/modules/im/src/chatlog/chatline.h index f901329a..5e0819ea 100644 --- a/src/modules/im/src/chatlog/chatline.h +++ b/src/modules/im/src/chatlog/chatline.h @@ -13,12 +13,12 @@ #ifndef CHATLINE_H #define CHATLINE_H +#include +#include #include #include #include #include -#include -#include #include "src/persistence/history.h" class ChatLog; @@ -27,60 +27,44 @@ class QGraphicsScene; class QStyleOptionGraphicsItem; class QFont; -class IChatItem -{ +class IChatItem { public: using Ptr = std::shared_ptr; - virtual ~IChatItem(){} + virtual ~IChatItem() {} virtual int itemType() = 0; virtual void layout(qreal width, QPointF scenePos) = 0; virtual QRectF sceneBoundingRect() const = 0; virtual void moveBy(qreal dx, qreal dy); - virtual void addToScene(QGraphicsScene *scene); + virtual void addToScene(QGraphicsScene* scene); virtual void removeFromScene(); virtual void setVisible(bool visible); - virtual void markAsDelivered(const QDateTime &time){}; + virtual void markAsDelivered(const QDateTime& time) {}; - virtual ChatLineContent* contentAtPos(QPointF scenePos) const - { - return nullptr; - } - virtual ChatLineContent *centerContent() const; + virtual ChatLineContent* contentAtPos(QPointF scenePos) const { return nullptr; } + virtual ChatLineContent* centerContent() const; + + virtual bool selectable() const { return false; } - virtual bool selectable() const - { - return false; - } - virtual void visibilityChanged(bool visible); virtual void selectionFocusChanged(bool focusIn); virtual void reloadTheme(); public: - void fontChanged(const QFont &font); + void fontChanged(const QFont& font); void selectionCleared(); void selectAll(); - void setTime(const QDateTime &time) { - datetime = time; - } - QDateTime getTime(){ - return datetime; - } - + void setTime(const QDateTime& time) { datetime = time; } + QDateTime getTime() { return datetime; } + void setRow(int row); - int getRow(){ - return row; - } + int getRow() { return row; } protected: friend class ChatLog; - virtual QList contents() { - return QList{}; - }; + virtual QList contents() { return QList{}; }; QDateTime datetime; int row = -1; }; -#endif // CHATLINE_H - +#endif // CHATLINE_H diff --git a/src/modules/im/src/chatlog/chatlinecontent.cpp b/src/modules/im/src/chatlog/chatlinecontent.cpp index 884b4747..bc8f0710 100644 --- a/src/modules/im/src/chatlog/chatlinecontent.cpp +++ b/src/modules/im/src/chatlog/chatlinecontent.cpp @@ -12,84 +12,41 @@ #include "chatlinecontent.h" -void ChatLineContent::setIndex(int r, int c) -{ +void ChatLineContent::setIndex(int r, int c) { row = r; col = c; } -int ChatLineContent::getColumn() const -{ - return col; -} +int ChatLineContent::getColumn() const { return col; } -int ChatLineContent::getRow() const -{ - return row; -} +int ChatLineContent::getRow() const { return row; } -int ChatLineContent::type() const -{ - return GraphicsItemType::ChatLineContentType; -} +int ChatLineContent::type() const { return GraphicsItemType::ChatLineContentType; } -void ChatLineContent::selectionMouseMove(QPointF) -{ -} +void ChatLineContent::selectionMouseMove(QPointF) {} -void ChatLineContent::selectionStarted(QPointF) -{ -} +void ChatLineContent::selectionStarted(QPointF) {} -void ChatLineContent::selectionCleared() -{ -} +void ChatLineContent::selectionCleared() {} -void ChatLineContent::selectionDoubleClick(QPointF) -{ -} +void ChatLineContent::selectionDoubleClick(QPointF) {} -void ChatLineContent::selectionTripleClick(QPointF) -{ -} +void ChatLineContent::selectionTripleClick(QPointF) {} -void ChatLineContent::selectionFocusChanged(bool) -{ -} +void ChatLineContent::selectionFocusChanged(bool) {} -void ChatLineContent::selectAll() -{ -} +void ChatLineContent::selectAll() {} -bool ChatLineContent::isOverSelection(QPointF) const -{ - return false; -} +bool ChatLineContent::isOverSelection(QPointF) const { return false; } -QString ChatLineContent::getSelectedText() const -{ - return QString(); -} +QString ChatLineContent::getSelectedText() const { return QString(); } -void ChatLineContent::fontChanged(const QFont& font) -{ - Q_UNUSED(font); -} +void ChatLineContent::fontChanged(const QFont& font) { Q_UNUSED(font); } -qreal ChatLineContent::getAscent() const -{ - return 0.0; -} +qreal ChatLineContent::getAscent() const { return 0.0; } -void ChatLineContent::visibilityChanged(bool) -{ -} +void ChatLineContent::visibilityChanged(bool) {} -void ChatLineContent::reloadTheme() -{ -} +void ChatLineContent::reloadTheme() {} -QString ChatLineContent::getText() const -{ - return QString(); -} +QString ChatLineContent::getText() const { return QString(); } diff --git a/src/modules/im/src/chatlog/chatlinecontent.h b/src/modules/im/src/chatlog/chatlinecontent.h index 13bd7e00..32fa4f44 100644 --- a/src/modules/im/src/chatlog/chatlinecontent.h +++ b/src/modules/im/src/chatlog/chatlinecontent.h @@ -15,14 +15,12 @@ #include -class ChatLineContent : public QObject, public QGraphicsItem -{ +class ChatLineContent : public QObject, public QGraphicsItem { Q_OBJECT Q_INTERFACES(QGraphicsItem) public: - enum GraphicsItemType - { + enum GraphicsItemType { ChatLineContentType = QGraphicsItem::UserType + 1, }; @@ -48,7 +46,8 @@ class ChatLineContent : public QObject, public QGraphicsItem virtual qreal getAscent() const; virtual QRectF boundingRect() const = 0; - virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) = 0; + virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, + QWidget* widget) = 0; virtual void visibilityChanged(bool visible); virtual void reloadTheme(); @@ -62,4 +61,4 @@ class ChatLineContent : public QObject, public QGraphicsItem int col = -1; }; -#endif // CHATLINECONTENT_H +#endif // CHATLINECONTENT_H diff --git a/src/modules/im/src/chatlog/chatlinecontentproxy.cpp b/src/modules/im/src/chatlog/chatlinecontentproxy.cpp index 8d128f25..118308be 100644 --- a/src/modules/im/src/chatlog/chatlinecontentproxy.cpp +++ b/src/modules/im/src/chatlog/chatlinecontentproxy.cpp @@ -11,11 +11,11 @@ */ #include "chatlinecontentproxy.h" -#include "src/chatlog/content/filetransferwidget.h" #include #include #include #include +#include "src/chatlog/content/filetransferwidget.h" /** * @enum ChatLineContentProxy::ChatLineContentProxyType @@ -27,55 +27,39 @@ ChatLineContentProxy::ChatLineContentProxy(QWidget* widget, ChatLineContentProxyType type, int minWidth, float widthInPercent) - : widthPercent(widthInPercent) - , widthMin(minWidth) - , widgetType{type} -{ + : widthPercent(widthInPercent), widthMin(minWidth), widgetType{type} { proxy = new QGraphicsProxyWidget(this); proxy->setWidget(widget); } ChatLineContentProxy::ChatLineContentProxy(QWidget* widget, int minWidth, float widthInPercent) - : ChatLineContentProxy(widget, GenericType, minWidth, widthInPercent) -{ -} + : ChatLineContentProxy(widget, GenericType, minWidth, widthInPercent) {} -ChatLineContentProxy::ChatLineContentProxy(FileTransferWidget* widget, int minWidth, float widthInPercent) - : ChatLineContentProxy(widget, FileTransferWidgetType, minWidth, widthInPercent) -{ -} +ChatLineContentProxy::ChatLineContentProxy(FileTransferWidget* widget, int minWidth, + float widthInPercent) + : ChatLineContentProxy(widget, FileTransferWidgetType, minWidth, widthInPercent) {} -QRectF ChatLineContentProxy::boundingRect() const -{ +QRectF ChatLineContentProxy::boundingRect() const { QRectF result = proxy->boundingRect(); result.setHeight(result.height() + 5); return result; } void ChatLineContentProxy::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, - QWidget* widget) -{ + QWidget* widget) { painter->setClipRect(boundingRect()); proxy->paint(painter, option, widget); } -qreal ChatLineContentProxy::getAscent() const -{ - return 7.0; -} +qreal ChatLineContentProxy::getAscent() const { return 7.0; } -QWidget* ChatLineContentProxy::getWidget() const -{ - return proxy->widget(); -} +QWidget* ChatLineContentProxy::getWidget() const { return proxy->widget(); } -void ChatLineContentProxy::setWidth(qreal width) -{ +void ChatLineContentProxy::setWidth(qreal width) { prepareGeometryChange(); proxy->widget()->setFixedWidth(qMax(static_cast(width * widthPercent), widthMin)); } -ChatLineContentProxy::ChatLineContentProxyType ChatLineContentProxy::getWidgetType() const -{ +ChatLineContentProxy::ChatLineContentProxyType ChatLineContentProxy::getWidgetType() const { return widgetType; } diff --git a/src/modules/im/src/chatlog/chatlinecontentproxy.h b/src/modules/im/src/chatlog/chatlinecontentproxy.h index bc9818b8..555ff590 100644 --- a/src/modules/im/src/chatlog/chatlinecontentproxy.h +++ b/src/modules/im/src/chatlog/chatlinecontentproxy.h @@ -13,18 +13,16 @@ #ifndef CHATLINECONTENTPROXY_H #define CHATLINECONTENTPROXY_H -#include "chatlinecontent.h" #include +#include "chatlinecontent.h" class FileTransferWidget; -class ChatLineContentProxy : public ChatLineContent -{ +class ChatLineContentProxy : public ChatLineContent { Q_OBJECT public: - enum ChatLineContentProxyType - { + enum ChatLineContentProxyType { GenericType, FileTransferWidgetType = 0, }; @@ -52,4 +50,4 @@ class ChatLineContentProxy : public ChatLineContent const ChatLineContentProxyType widgetType; }; -#endif // CHATLINECONTENTPROXY_H +#endif // CHATLINECONTENTPROXY_H diff --git a/src/modules/im/src/chatlog/chatlog.cpp b/src/modules/im/src/chatlog/chatlog.cpp index b7583a97..c7f9b33d 100644 --- a/src/modules/im/src/chatlog/chatlog.cpp +++ b/src/modules/im/src/chatlog/chatlog.cpp @@ -35,48 +35,39 @@ * @brief repetition interval sender name (sec) */ -template -T clamp(T x, T min, T max) -{ - if (x > max) - return max; - if (x < min) - return min; +template T clamp(T x, T min, T max) { + if (x > max) return max; + if (x < min) return min; return x; } -static bool lessThanBSRectTop(const IChatItem::Ptr &lhs, const qreal &rhs) { +static bool lessThanBSRectTop(const IChatItem::Ptr& lhs, const qreal& rhs) { return lhs->sceneBoundingRect().top() < rhs; } -static bool lessThanBSRectBottom(const IChatItem::Ptr &lhs, - const qreal &rhs) { +static bool lessThanBSRectBottom(const IChatItem::Ptr& lhs, const qreal& rhs) { return lhs->sceneBoundingRect().bottom() < rhs; } -static bool lessThanRowIndex(const IChatItem::Ptr &lhs, - const IChatItem::Ptr &rhs) -{ +static bool lessThanRowIndex(const IChatItem::Ptr& lhs, const IChatItem::Ptr& rhs) { return lhs->getRow() < rhs->getRow(); } -ChatLog::ChatLog(QWidget* parent) - : QGraphicsView(parent), scrollBarValue{0} -{ +ChatLog::ChatLog(QWidget* parent) : QGraphicsView(parent), scrollBarValue{0} { // Create the scene busyScene = new QGraphicsScene(this); scene = new QGraphicsScene(this); scene->setItemIndexMethod(QGraphicsScene::BspTreeIndex); setScene(scene); // 连接滚动条的 valueChanged 信号到槽函数 - connect(verticalScrollBar(), &QScrollBar::valueChanged, this, &ChatLog::onVScrollBarValueChanged); - + connect(verticalScrollBar(), &QScrollBar::valueChanged, this, + &ChatLog::onVScrollBarValueChanged); // Cfg. setInteractive(true); setAcceptDrops(false); setAlignment(Qt::AlignTop | Qt::AlignLeft); - //setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - //setDragMode(QGraphicsView::NoDrag); + // setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + // setDragMode(QGraphicsView::NoDrag); setViewportUpdateMode(MinimalViewportUpdate); setContextMenuPolicy(Qt::CustomContextMenu); setBackgroundBrush(QBrush(Style::getColor(Style::GroundBase), Qt::SolidPattern)); @@ -131,28 +122,21 @@ ChatLog::ChatLog(QWidget* parent) retranslateUi(); } -ChatLog::~ChatLog() -{ +ChatLog::~ChatLog() { settings::Translator::unregister(this); // Remove chatlines from scene - for (const IChatItem::Ptr& l : lines) - l->removeFromScene(); + for (const IChatItem::Ptr& l : lines) l->removeFromScene(); - if (busyNotification) - busyNotification->removeFromScene(); + if (busyNotification) busyNotification->removeFromScene(); - if (typingNotification) - typingNotification->removeFromScene(); + if (typingNotification) typingNotification->removeFromScene(); } -void ChatLog::clearSelection() -{ - if (selectionMode == SelectionMode::None) - return; +void ChatLog::clearSelection() { + if (selectionMode == SelectionMode::None) return; - for (int i = selFirstRow; i <= selLastRow; ++i) - lines[i]->selectionCleared(); + for (int i = selFirstRow; i <= selLastRow; ++i) lines[i]->selectionCleared(); selFirstRow = -1; selLastRow = -1; @@ -165,41 +149,33 @@ void ChatLog::clearSelection() updateMultiSelectionRect(); } -QRect ChatLog::getVisibleRect() const -{ +QRect ChatLog::getVisibleRect() const { return mapToScene(viewport()->rect()).boundingRect().toRect(); } -void ChatLog::updateSceneRect() -{ - setSceneRect(calculateSceneRect()); -} +void ChatLog::updateSceneRect() { setSceneRect(calculateSceneRect()); } -void ChatLog::layout(int start, int end, qreal width) -{ - if (lines.empty()) - return; +void ChatLog::layout(int start, int end, qreal width) { + if (lines.empty()) return; qreal h = 0.0; // Line at start-1 is considered to have the correct position. All following lines are // positioned in respect to this line. - if (start - 1 >= 0) - h = lines[start - 1]->sceneBoundingRect().bottom() + lineSpacing; + if (start - 1 >= 0) h = lines[start - 1]->sceneBoundingRect().bottom() + lineSpacing; start = clamp(start, 0, lines.size()); end = clamp(end + 1, 0, lines.size()); for (int i = start; i < end; ++i) { - IChatItem * l = lines[i].get(); + IChatItem* l = lines[i].get(); l->layout(width, QPointF(0.0, h)); h += l->sceneBoundingRect().height() + lineSpacing; } } -void ChatLog::mousePressEvent(QMouseEvent* ev) -{ +void ChatLog::mousePressEvent(QMouseEvent* ev) { QGraphicsView::mousePressEvent(ev); if (ev->button() == Qt::LeftButton) { @@ -210,9 +186,8 @@ void ChatLog::mousePressEvent(QMouseEvent* ev) if (lastClickButton == ev->button()) { // Counts only single clicks and first click of doule click clickCount++; - } - else { - clickCount = 1; // restarting counter + } else { + clickCount = 1; // restarting counter lastClickButton = ev->button(); } lastClickPos = ev->pos(); @@ -221,8 +196,7 @@ void ChatLog::mousePressEvent(QMouseEvent* ev) handleMultiClickEvent(); } -void ChatLog::mouseReleaseEvent(QMouseEvent* ev) -{ +void ChatLog::mouseReleaseEvent(QMouseEvent* ev) { QGraphicsView::mouseReleaseEvent(ev); selectionScrollDir = AutoScrollDirection::NoDirection; @@ -230,8 +204,7 @@ void ChatLog::mouseReleaseEvent(QMouseEvent* ev) multiClickTimer->start(); } -void ChatLog::mouseMoveEvent(QMouseEvent* ev) -{ +void ChatLog::mouseMoveEvent(QMouseEvent* ev) { QGraphicsView::mouseMoveEvent(ev); QPointF scenePos = mapToScene(ev->pos()); @@ -246,12 +219,12 @@ void ChatLog::mouseMoveEvent(QMouseEvent* ev) selectionScrollDir = AutoScrollDirection::NoDirection; // select - if (selectionMode == SelectionMode::None - && (clickPos - ev->pos()).manhattanLength() > QApplication::startDragDistance()) { + if (selectionMode == SelectionMode::None && + (clickPos - ev->pos()).manhattanLength() > QApplication::startDragDistance()) { QPointF sceneClickPos = mapToScene(clickPos.toPoint()); IChatItem::Ptr line = findLineByPosY(scenePos.y()); - ChatLineContent *content = (line && - line->selectable()) ? getContentFromPos(sceneClickPos) : nullptr; + ChatLineContent* content = + (line && line->selectable()) ? getContentFromPos(sceneClickPos) : nullptr; if (content) { selClickedRow = content->getRow(); selClickedCol = content->getColumn(); @@ -263,8 +236,7 @@ void ChatLog::mouseMoveEvent(QMouseEvent* ev) selectionMode = SelectionMode::Precise; // ungrab mouse grabber - if (scene->mouseGrabberItem()) - scene->mouseGrabberItem()->ungrabMouse(); + if (scene->mouseGrabberItem()) scene->mouseGrabberItem()->ungrabMouse(); } else if (line.get()) { selClickedRow = line->getRow(); selFirstRow = selClickedRow; @@ -275,7 +247,7 @@ void ChatLog::mouseMoveEvent(QMouseEvent* ev) } if (selectionMode != SelectionMode::None) { - ChatLineContent *content = getContentFromPos(scenePos); + ChatLineContent* content = getContentFromPos(scenePos); IChatItem::Ptr line = findLineByPosY(scenePos.y()); int row; @@ -311,8 +283,7 @@ void ChatLog::mouseMoveEvent(QMouseEvent* ev) int start = std::min(row1, row2) + (down ? 1 : 0); int end = std::max(row1, row2) + (down ? 1 : 0); bool isMore = ((row2 > row1) && down) || ((row2 < row1) && !down); - for (int i = start; i < end; i++) - { + for (int i = start; i < end; i++) { IChatItem::Ptr line = lines.at(i); if (line) { if (isMore) @@ -322,16 +293,14 @@ void ChatLog::mouseMoveEvent(QMouseEvent* ev) } } }; - - if (row >= selClickedRow) - { + + if (row >= selClickedRow) { if (selectionMode == SelectionMode::Multi) selectionLineChange(selLastRow, row, true); selLastRow = row; } - if (row <= selClickedRow) - { + if (row <= selClickedRow) { if (selectionMode == SelectionMode::Multi) selectionLineChange(selFirstRow, row, false); selFirstRow = row; @@ -345,13 +314,10 @@ void ChatLog::mouseMoveEvent(QMouseEvent* ev) } // Much faster than QGraphicsScene::itemAt()! -ChatLineContent* ChatLog::getContentFromPos(QPointF scenePos) const -{ - if (lines.empty()) - return nullptr; +ChatLineContent* ChatLog::getContentFromPos(QPointF scenePos) const { + if (lines.empty()) return nullptr; - auto itr = - std::lower_bound(lines.cbegin(), lines.cend(), scenePos.y(), lessThanBSRectBottom); + auto itr = std::lower_bound(lines.cbegin(), lines.cend(), scenePos.y(), lessThanBSRectBottom); // find content if (itr != lines.cend() && (*itr)->sceneBoundingRect().contains(scenePos)) @@ -360,30 +326,24 @@ ChatLineContent* ChatLog::getContentFromPos(QPointF scenePos) const return nullptr; } -bool ChatLog::isOverSelection(QPointF scenePos) const -{ +bool ChatLog::isOverSelection(QPointF scenePos) const { if (selectionMode == SelectionMode::Precise) { ChatLineContent* content = getContentFromPos(scenePos); - if (content) - return content->isOverSelection(scenePos); + if (content) return content->isOverSelection(scenePos); } else if (selectionMode == SelectionMode::Multi) { - if (selectionBox.contains(scenePos)) - return true; + if (selectionBox.contains(scenePos)) return true; } return false; } -qreal ChatLog::useableWidth() const -{ +qreal ChatLog::useableWidth() const { return width() - verticalScrollBar()->sizeHint().width() - margins.right() - margins.left(); } -void ChatLog::reposition(int start, int end, qreal deltaY) -{ - if (lines.isEmpty()) - return; +void ChatLog::reposition(int start, int end, qreal deltaY) { + if (lines.isEmpty()) return; start = clamp(start, 0, lines.size() - 1); end = clamp(end + 1, 0, lines.size()); @@ -395,9 +355,7 @@ void ChatLog::reposition(int start, int end, qreal deltaY) } void ChatLog::insertChatlineAtBottom(IChatItem::Ptr l) { - if (!l.get()) - return; - + if (!l.get()) return; bool stickToBtm = stickToBottom(); @@ -412,23 +370,20 @@ void ChatLog::insertChatlineAtBottom(IChatItem::Ptr l) { layout(from, lines.size(), useableWidth()); updateSceneRect(); - if (stickToBtm) - scrollToBottom(); + if (stickToBtm) scrollToBottom(); checkVisibility(); updateTypingNotification(); } void ChatLog::insertChatlineOnTop(IChatItem::Ptr l) { - if (!l.get()) - return; + if (!l.get()) return; insertChatlinesOnTop(QList() << l); } -void ChatLog::insertChatlinesOnTop(const QList &newLines) { - if (newLines.isEmpty()) - return; +void ChatLog::insertChatlinesOnTop(const QList& newLines) { + if (newLines.isEmpty()) return; QGraphicsScene::ItemIndexMethod oldIndexMeth = scene->itemIndexMethod(); scene->setItemIndexMethod(QGraphicsScene::NoIndex); @@ -462,42 +417,34 @@ void ChatLog::insertChatlinesOnTop(const QList &newLines) { startResizeWorker(); } -bool ChatLog::stickToBottom() const -{ +bool ChatLog::stickToBottom() const { return verticalScrollBar()->value() == verticalScrollBar()->maximum(); } -void ChatLog::scrollToBottom() -{ +void ChatLog::scrollToBottom() { updateSceneRect(); verticalScrollBar()->setValue(verticalScrollBar()->maximum()); } -void ChatLog::startResizeWorker() -{ - if (lines.empty()) - return; +void ChatLog::startResizeWorker() { + if (lines.empty()) return; // (re)start the worker if (!workerTimer->isActive()) { // these values must not be reevaluated while the worker is running workerStb = stickToBottom(); - if (!visibleLines.empty()) - workerAnchorLine = visibleLines.first(); + if (!visibleLines.empty()) workerAnchorLine = visibleLines.first(); } // switch to busy scene displaying the busy notification if there is a lot // of text to be resized int txt = 0; for (IChatItem::Ptr line : lines) { - if (txt > 500000) - break; - for (ChatLineContent* content : line->contents()) - txt += content->getText().size(); + if (txt > 500000) break; + for (ChatLineContent* content : line->contents()) txt += content->getText().size(); } - if (txt > 500000) - setScene(busyScene); + if (txt > 500000) setScene(busyScene); workerLastIndex = 0; workerTimer->start(); @@ -505,12 +452,10 @@ void ChatLog::startResizeWorker() verticalScrollBar()->hide(); } -void ChatLog::mouseDoubleClickEvent(QMouseEvent* ev) -{ +void ChatLog::mouseDoubleClickEvent(QMouseEvent* ev) { QPointF scenePos = mapToScene(ev->pos()); IChatItem::Ptr line = findLineByPosY(scenePos.y()); - ChatLineContent *content = - line->selectable() ? getContentFromPos(scenePos) : nullptr; + ChatLineContent* content = line->selectable() ? getContentFromPos(scenePos) : nullptr; if (content) { content->selectionDoubleClick(scenePos); @@ -526,9 +471,8 @@ void ChatLog::mouseDoubleClickEvent(QMouseEvent* ev) if (lastClickButton == ev->button()) { // Counts the second click of double click clickCount++; - } - else { - clickCount = 1; // restarting counter + } else { + clickCount = 1; // restarting counter lastClickButton = ev->button(); } lastClickPos = ev->pos(); @@ -537,29 +481,28 @@ void ChatLog::mouseDoubleClickEvent(QMouseEvent* ev) handleMultiClickEvent(); } -QString ChatLog::getSelectedText() const -{ +QString ChatLog::getSelectedText() const { if (selectionMode == SelectionMode::Precise) { auto content = lines[selClickedRow]->centerContent(); - if (content) - return content->getSelectedText(); + if (content) return content->getSelectedText(); return QString(); } else if (selectionMode == SelectionMode::Multi) { // build a nicely formatted message QString out; for (int i = selFirstRow; i <= selLastRow; ++i) { - //if (lines[i]->content[1]->getText().isEmpty()) - // continue; - - //QString timestamp = lines[i]->content[2]->getText().isEmpty() - // ? tr("pending") - // : lines[i]->content[2]->getText(); - //QString author = lines[i]->content[0]->getText(); - //QString msg = lines[i]->content[1]->getText(); - - //out += - // QString(out.isEmpty() ? "[%2] %1: %3" : "\n[%2] %1: %3").arg(author, timestamp, msg); + // if (lines[i]->content[1]->getText().isEmpty()) + // continue; + + // QString timestamp = lines[i]->content[2]->getText().isEmpty() + // ? tr("pending") + // : lines[i]->content[2]->getText(); + // QString author = lines[i]->content[0]->getText(); + // QString msg = lines[i]->content[1]->getText(); + + // out += + // QString(out.isEmpty() ? "[%2] %1: %3" : "\n[%2] %1: %3").arg(author, timestamp, + // msg); } return out; @@ -568,36 +511,22 @@ QString ChatLog::getSelectedText() const return QString(); } -bool ChatLog::isEmpty() const -{ - return lines.isEmpty(); -} +bool ChatLog::isEmpty() const { return lines.isEmpty(); } -bool ChatLog::hasTextToBeCopied() const -{ - return selectionMode != SelectionMode::None; -} +bool ChatLog::hasTextToBeCopied() const { return selectionMode != SelectionMode::None; } -IChatItem::Ptr ChatLog::getTypingNotification() const -{ - return typingNotification; -} +IChatItem::Ptr ChatLog::getTypingNotification() const { return typingNotification; } -QVector ChatLog::getLines() -{ - return lines; -} +QVector ChatLog::getLines() { return lines; } -IChatItem::Ptr ChatLog::getLatestLine() const -{ +IChatItem::Ptr ChatLog::getLatestLine() const { if (!lines.empty()) { return lines.last(); } return nullptr; } -IChatItem::Ptr ChatLog::getFirstLine() const -{ +IChatItem::Ptr ChatLog::getFirstLine() const { if (!lines.empty()) { return lines.first(); } @@ -609,13 +538,11 @@ IChatItem::Ptr ChatLog::getFirstLine() const * @param pos Position on screen in global coordinates * @sa getContentFromPos() */ -ChatLineContent* ChatLog::getContentFromGlobalPos(QPoint pos) const -{ +ChatLineContent* ChatLog::getContentFromGlobalPos(QPoint pos) const { return getContentFromPos(mapToScene(mapFromGlobal(pos))); } -void ChatLog::clear() -{ +void ChatLog::clear() { clearSelection(); QVector savedLines; @@ -629,14 +556,12 @@ void ChatLog::clear() lines.clear(); visibleLines.clear(); - for (IChatItem::Ptr l : savedLines) - insertChatlineAtBottom(l); + for (IChatItem::Ptr l : savedLines) insertChatlineAtBottom(l); updateSceneRect(); } -void ChatLog::copySelectedText(bool toSelectionBuffer) const -{ +void ChatLog::copySelectedText(bool toSelectionBuffer) const { QString text = getSelectedText(); QClipboard* clipboard = QApplication::clipboard(); @@ -644,18 +569,15 @@ void ChatLog::copySelectedText(bool toSelectionBuffer) const clipboard->setText(text, toSelectionBuffer ? QClipboard::Selection : QClipboard::Clipboard); } -void ChatLog::setBusyNotification(IChatItem::Ptr notification) -{ - if (!notification.get()) - return; +void ChatLog::setBusyNotification(IChatItem::Ptr notification) { + if (!notification.get()) return; busyNotification = notification; busyNotification->addToScene(busyScene); busyNotification->visibilityChanged(true); } -void ChatLog::setTypingNotification(IChatItem::Ptr notification) -{ +void ChatLog::setTypingNotification(IChatItem::Ptr notification) { typingNotification = notification; typingNotification->visibilityChanged(true); typingNotification->setVisible(false); @@ -663,27 +585,22 @@ void ChatLog::setTypingNotification(IChatItem::Ptr notification) updateTypingNotification(); } -void ChatLog::setTypingNotificationVisible(bool visible) -{ +void ChatLog::setTypingNotificationVisible(bool visible) { if (typingNotification.get()) { typingNotification->setVisible(visible); updateTypingNotification(); } } -void ChatLog::scrollToLine(IChatItem::Ptr line) -{ - if (!line.get()) - return; +void ChatLog::scrollToLine(IChatItem::Ptr line) { + if (!line.get()) return; updateSceneRect(); verticalScrollBar()->setValue(line->sceneBoundingRect().top()); } -void ChatLog::selectAll() -{ - if (lines.empty()) - return; +void ChatLog::selectAll() { + if (lines.empty()) return; clearSelection(); @@ -695,15 +612,13 @@ void ChatLog::selectAll() updateMultiSelectionRect(); } -void ChatLog::fontChanged(const QFont& font) -{ +void ChatLog::fontChanged(const QFont& font) { for (IChatItem::Ptr l : lines) { l->fontChanged(font); } } -void ChatLog::reloadTheme() -{ +void ChatLog::reloadTheme() { setBackgroundBrush(QBrush(Style::getColor(Style::GroundBase), Qt::SolidPattern)); selectionRectColor = Style::getColor(Style::SelectText); @@ -712,15 +627,10 @@ void ChatLog::reloadTheme() } } -void ChatLog::forceRelayout() -{ - startResizeWorker(); -} +void ChatLog::forceRelayout() { startResizeWorker(); } -void ChatLog::checkVisibility(bool causedByScroll) -{ - if (lines.empty()) - return; +void ChatLog::checkVisibility(bool causedByScroll) { + if (lines.empty()) return; // find first visible line auto lowerBound = std::lower_bound(lines.cbegin(), lines.cend(), getVisibleRect().top(), @@ -730,24 +640,21 @@ void ChatLog::checkVisibility(bool causedByScroll) auto upperBound = std::lower_bound(lowerBound, lines.cend(), getVisibleRect().bottom(), lessThanBSRectTop); - const IChatItem::Ptr lastLineBeforeVisible = lowerBound == lines.cbegin() - ? IChatItem::Ptr() - : *std::prev(lowerBound); + const IChatItem::Ptr lastLineBeforeVisible = + lowerBound == lines.cbegin() ? IChatItem::Ptr() : *std::prev(lowerBound); // set visibilty QList newVisibleLines; for (auto itr = lowerBound; itr != upperBound; ++itr) { newVisibleLines.append(*itr); - if (!visibleLines.contains(*itr)) - (*itr)->visibilityChanged(true); + if (!visibleLines.contains(*itr)) (*itr)->visibilityChanged(true); visibleLines.removeOne(*itr); } // these lines are no longer visible - for (IChatItem::Ptr line : visibleLines) - line->visibilityChanged(false); + for (IChatItem::Ptr line : visibleLines) line->visibilityChanged(false); visibleLines = newVisibleLines; @@ -762,37 +669,32 @@ void ChatLog::checkVisibility(bool causedByScroll) emit firstVisibleLineChanged(lastLineBeforeVisible, visibleLines.at(0)); } - if (causedByScroll && lowerBound != lines.cend() && - lowerBound->get()->getRow() == 0) { + if (causedByScroll && lowerBound != lines.cend() && lowerBound->get()->getRow() == 0) { emit loadHistoryLower(); } } -void ChatLog::scrollContentsBy(int dx, int dy) -{ +void ChatLog::scrollContentsBy(int dx, int dy) { QGraphicsView::scrollContentsBy(dx, dy); checkVisibility(true); } -void ChatLog::resizeEvent(QResizeEvent* ev) -{ +void ChatLog::resizeEvent(QResizeEvent* ev) { bool stb = stickToBottom(); if (ev->size().width() != ev->oldSize().width()) { startResizeWorker(); - stb = false; // let the resize worker handle it + stb = false; // let the resize worker handle it } QGraphicsView::resizeEvent(ev); - if (stb) - scrollToBottom(); + if (stb) scrollToBottom(); updateBusyNotification(); } -void ChatLog::updateMultiSelectionRect() -{ +void ChatLog::updateMultiSelectionRect() { if (selectionMode == SelectionMode::Multi && selFirstRow >= 0 && selLastRow >= 0) { QRectF selBBox; selBBox = selBBox.united(lines[selFirstRow]->sceneBoundingRect()); @@ -803,41 +705,35 @@ void ChatLog::updateMultiSelectionRect() } } -void ChatLog::updateTypingNotification() -{ +void ChatLog::updateTypingNotification() { IChatItem* notification = typingNotification.get(); - if (!notification) - return; + if (!notification) return; qreal posY = 0.0; - if (!lines.empty()) - posY = lines.last()->sceneBoundingRect().bottom() + lineSpacing; + if (!lines.empty()) posY = lines.last()->sceneBoundingRect().bottom() + lineSpacing; notification->layout(useableWidth(), QPointF(0.0, posY)); } -void ChatLog::updateBusyNotification() -{ +void ChatLog::updateBusyNotification() { if (busyNotification.get()) { // repoisition the busy notification (centered) - busyNotification->layout(useableWidth(), getVisibleRect().topLeft() - + QPointF(0, getVisibleRect().height() / 2.0)); + busyNotification->layout( + useableWidth(), + getVisibleRect().topLeft() + QPointF(0, getVisibleRect().height() / 2.0)); } } -IChatItem::Ptr ChatLog::findLineByPosY(qreal yPos) const -{ +IChatItem::Ptr ChatLog::findLineByPosY(qreal yPos) const { auto itr = std::lower_bound(lines.cbegin(), lines.cend(), yPos, lessThanBSRectBottom); - if (itr != lines.cend()) - return *itr; + if (itr != lines.cend()) return *itr; return IChatItem::Ptr(); } -QRectF ChatLog::calculateSceneRect() const -{ +QRectF ChatLog::calculateSceneRect() const { qreal bottom = (lines.empty() ? 0.0 : lines.last()->sceneBoundingRect().bottom()); if (typingNotification.get() != nullptr) @@ -847,24 +743,22 @@ QRectF ChatLog::calculateSceneRect() const bottom + margins.bottom() + margins.top()); } -void ChatLog::onSelectionTimerTimeout() -{ +void ChatLog::onSelectionTimerTimeout() { const int scrollSpeed = 10; switch (selectionScrollDir) { - case AutoScrollDirection::Up: - verticalScrollBar()->setValue(verticalScrollBar()->value() - scrollSpeed); - break; - case AutoScrollDirection::Down: - verticalScrollBar()->setValue(verticalScrollBar()->value() + scrollSpeed); - break; - default: - break; + case AutoScrollDirection::Up: + verticalScrollBar()->setValue(verticalScrollBar()->value() - scrollSpeed); + break; + case AutoScrollDirection::Down: + verticalScrollBar()->setValue(verticalScrollBar()->value() + scrollSpeed); + break; + default: + break; } } -void ChatLog::onWorkerTimeout() -{ +void ChatLog::onWorkerTimeout() { // Fairly arbitrary but // large values will make the UI unresponsive const int stepSize = 50; @@ -901,101 +795,84 @@ void ChatLog::onWorkerTimeout() } } -void ChatLog::onMultiClickTimeout() -{ - clickCount = 0; -} +void ChatLog::onMultiClickTimeout() { clickCount = 0; } -void ChatLog::onVScrollBarValueChanged(int value) -{ - scrollBarValue = value; -// qDebug() <<"height"<< sceneRect().height()<<" value"<maximum(); - if (scrollBarValue == verticalScrollBar()->maximum()) { - // 当垂直滚动条的值改变时触发 -// qDebug() <<"readAll"; - emit readAll(); - } +void ChatLog::onVScrollBarValueChanged(int value) { + scrollBarValue = value; + // qDebug() <<"height"<< sceneRect().height()<<" value"<maximum(); + if (scrollBarValue == verticalScrollBar()->maximum()) { + // 当垂直滚动条的值改变时触发 + // qDebug() <<"readAll"; + emit readAll(); + } } -void ChatLog::handleMultiClickEvent() -{ +void ChatLog::handleMultiClickEvent() { // Ignore single or double clicks - if (clickCount < 2) - return; + if (clickCount < 2) return; switch (clickCount) { - case 3: - QPointF scenePos = mapToScene(lastClickPos); - ChatLineContent* content = getContentFromPos(scenePos); + case 3: + QPointF scenePos = mapToScene(lastClickPos); + ChatLineContent* content = getContentFromPos(scenePos); - if (content) { - content->selectionTripleClick(scenePos); - selClickedCol = content->getColumn(); - selClickedRow = content->getRow(); - selFirstRow = content->getRow(); - selLastRow = content->getRow(); - selectionMode = SelectionMode::Precise; + if (content) { + content->selectionTripleClick(scenePos); + selClickedCol = content->getColumn(); + selClickedRow = content->getRow(); + selFirstRow = content->getRow(); + selLastRow = content->getRow(); + selectionMode = SelectionMode::Precise; - emit selectionChanged(); - } - break; + emit selectionChanged(); + } + break; } } -void ChatLog::showEvent(QShowEvent*) -{ - if(verticalScrollBar()->maximum()==0){ - //没有滚动条,发射“已读完”信号 +void ChatLog::showEvent(QShowEvent*) { + if (verticalScrollBar()->maximum() == 0) { + // 没有滚动条,发射“已读完”信号 emit readAll(); } - if( verticalScrollBar()->maximum()==verticalScrollBar()->value()){ - //有滚动条,但是已经卷动到底部,发射“以读完”信号 - emit readAll(); + if (verticalScrollBar()->maximum() == verticalScrollBar()->value()) { + // 有滚动条,但是已经卷动到底部,发射“以读完”信号 + emit readAll(); } } -void ChatLog::focusInEvent(QFocusEvent* ev) -{ +void ChatLog::focusInEvent(QFocusEvent* ev) { QGraphicsView::focusInEvent(ev); if (selectionMode != SelectionMode::None) { - for (int i = selFirstRow; i <= selLastRow; ++i) - lines[i]->selectionFocusChanged(true); + for (int i = selFirstRow; i <= selLastRow; ++i) lines[i]->selectionFocusChanged(true); } } -void ChatLog::focusOutEvent(QFocusEvent* ev) -{ +void ChatLog::focusOutEvent(QFocusEvent* ev) { QGraphicsView::focusOutEvent(ev); if (selectionMode != SelectionMode::None) { - if (selFirstRow >= 0) - { - for (int i = selFirstRow; i <= selLastRow; ++i) - lines[i]->selectionFocusChanged(false); + if (selFirstRow >= 0) { + for (int i = selFirstRow; i <= selLastRow; ++i) lines[i]->selectionFocusChanged(false); } } } -void ChatLog::retranslateUi() -{ +void ChatLog::retranslateUi() { copyAction->setText(tr("Copy")); selectAllAction->setText(tr("Select all")); } -bool ChatLog::isActiveFileTransfer(IChatItem::Ptr l) -{ - ChatLineContent *content = l->centerContent(); - ChatLineContentProxy *proxy = qobject_cast(content); +bool ChatLog::isActiveFileTransfer(IChatItem::Ptr l) { + ChatLineContent* content = l->centerContent(); + ChatLineContentProxy* proxy = qobject_cast(content); if (proxy) { - - QWidget *widget = proxy->getWidget(); - FileTransferWidget *transferWidget = - qobject_cast(widget); - if (transferWidget && transferWidget->isActive()) - return true; + QWidget* widget = proxy->getWidget(); + FileTransferWidget* transferWidget = qobject_cast(widget); + if (transferWidget && transferWidget->isActive()) return true; } return false; } @@ -1003,12 +880,10 @@ bool ChatLog::isActiveFileTransfer(IChatItem::Ptr l) /** * @brief Adjusts the selection based on chatlog changing lines * @param offset Amount to shift selection rect up by. Must be non-negative. - */ -void ChatLog::moveSelectionRectUpIfSelected(int offset) -{ + */ +void ChatLog::moveSelectionRectUpIfSelected(int offset) { assert(offset >= 0); - switch (selectionMode) - { + switch (selectionMode) { case SelectionMode::None: return; case SelectionMode::Precise: @@ -1023,12 +898,10 @@ void ChatLog::moveSelectionRectUpIfSelected(int offset) /** * @brief Adjusts the selections based on chatlog changing lines * @param offset removed from the lines indexes. Must be non-negative. - */ -void ChatLog::moveSelectionRectDownIfSelected(int offset) -{ + */ +void ChatLog::moveSelectionRectDownIfSelected(int offset) { assert(offset >= 0); - switch (selectionMode) - { + switch (selectionMode) { case SelectionMode::None: return; case SelectionMode::Precise: @@ -1040,8 +913,7 @@ void ChatLog::moveSelectionRectDownIfSelected(int offset) } } -void ChatLog::movePreciseSelectionDown(int offset) -{ +void ChatLog::movePreciseSelectionDown(int offset) { assert(selFirstRow == selLastRow && selFirstRow == selClickedRow); const int lastLine = lines.size() - 1; if (selClickedRow + offset > lastLine) { @@ -1055,8 +927,7 @@ void ChatLog::movePreciseSelectionDown(int offset) } } -void ChatLog::movePreciseSelectionUp(int offset) -{ +void ChatLog::movePreciseSelectionUp(int offset) { assert(selFirstRow == selLastRow && selFirstRow == selClickedRow); if (selClickedRow < offset) { clearSelection(); @@ -1069,9 +940,8 @@ void ChatLog::movePreciseSelectionUp(int offset) } } -void ChatLog::moveMultiSelectionUp(int offset) -{ - if (selLastRow < offset) { // entire selection now out of bounds +void ChatLog::moveMultiSelectionUp(int offset) { + if (selLastRow < offset) { // entire selection now out of bounds clearSelection(); } else { selLastRow -= offset; @@ -1082,10 +952,9 @@ void ChatLog::moveMultiSelectionUp(int offset) } } -void ChatLog::moveMultiSelectionDown(int offset) -{ +void ChatLog::moveMultiSelectionDown(int offset) { const int lastLine = lines.size() - 1; - if (selFirstRow + offset > lastLine) { // entire selection now out of bounds + if (selFirstRow + offset > lastLine) { // entire selection now out of bounds clearSelection(); } else { selFirstRow += offset; diff --git a/src/modules/im/src/chatlog/chatlog.h b/src/modules/im/src/chatlog/chatlog.h index 100c46ea..9772c86b 100644 --- a/src/modules/im/src/chatlog/chatlog.h +++ b/src/modules/im/src/chatlog/chatlog.h @@ -28,8 +28,7 @@ class QTimer; class ChatLineContent; struct ToxFile; -class ChatLog : public QGraphicsView -{ +class ChatLog : public QGraphicsView { Q_OBJECT public: explicit ChatLog(QWidget* parent = nullptr); @@ -37,7 +36,7 @@ class ChatLog : public QGraphicsView void insertChatlineAtBottom(IChatItem::Ptr l); void insertChatlineOnTop(IChatItem::Ptr l); - void insertChatlinesOnTop(const QList &newLines); + void insertChatlinesOnTop(const QList& newLines); void clearSelection(); void clear(); void copySelectedText(bool toSelectionBuffer = false) const; @@ -61,9 +60,7 @@ class ChatLog : public QGraphicsView ChatLineContent* getContentFromGlobalPos(QPoint pos) const; const uint repNameAfter = 5 * 60; - constexpr inline int getVScrollBarValue() const { - return scrollBarValue; - } + constexpr inline int getVScrollBarValue() const { return scrollBarValue; } signals: void selectionChanged(); void workerTimeoutFinished(); @@ -112,7 +109,6 @@ private slots: IChatItem::Ptr findLineByPosY(qreal yPos) const; - private: void retranslateUi(); bool isActiveFileTransfer(IChatItem::Ptr l); @@ -125,15 +121,13 @@ private slots: void moveMultiSelectionDown(int offset); private: - enum class SelectionMode - { + enum class SelectionMode { None, Precise, Multi, }; - enum class AutoScrollDirection - { + enum class AutoScrollDirection { NoDirection, Up, Down, @@ -149,7 +143,7 @@ private slots: IChatItem::Ptr busyNotification; // selection - int selClickedRow = -1; // These 4 are only valid while selectionMode != None + int selClickedRow = -1; // These 4 are only valid while selectionMode != None int selClickedCol = -1; int selFirstRow = -1; int selLastRow = -1; @@ -175,7 +169,7 @@ private slots: QMargins margins = QMargins(10, 10, 10, 10); qreal lineSpacing = 20.0f; - int scrollBarValue = 0; + int scrollBarValue = 0; }; -#endif // CHATLOG_H +#endif // CHATLOG_H diff --git a/src/modules/im/src/chatlog/chatmessage.cpp b/src/modules/im/src/chatlog/chatmessage.cpp index c4ebdab1..afac61fb 100644 --- a/src/modules/im/src/chatlog/chatmessage.cpp +++ b/src/modules/im/src/chatlog/chatmessage.cpp @@ -26,92 +26,87 @@ #include #include +#include "src/chatlog/chatmessageitem.h" +#include "src/nexus.h" #include "src/persistence/history.h" +#include "src/persistence/profile.h" #include "src/persistence/settings.h" #include "src/persistence/smileypack.h" -#include "src/persistence/profile.h" -#include "src/nexus.h" -#include "src/chatlog/chatmessageitem.h" #define NAME_COL_WIDTH 140.0 #define TIME_COL_WIDTH 90.0 -IChatItem::Ptr ChatMessage::createChatMessage( - const ChatLogItem &item, const QString &rawMessage, MessageType type, - bool isMe, MessageState state, const QDateTime &date, bool colorizeName) { - - auto avatar = Nexus::getProfile()->loadAvatar(item.getSender()); - auto *msg = new ChatMessageBox(avatar, - item.getDisplayName(), - rawMessage.toHtmlEscaped(), - isMe); - msg->setMessageState(state); - msg->setTime(date); - return IChatItem::Ptr(msg); +IChatItem::Ptr ChatMessage::createChatMessage(const ChatLogItem& item, const QString& rawMessage, + MessageType type, bool isMe, MessageState state, + const QDateTime& date, bool colorizeName) { + auto avatar = Nexus::getProfile()->loadAvatar(item.getSender()); + auto* msg = new ChatMessageBox(avatar, item.getDisplayName(), rawMessage.toHtmlEscaped(), isMe); + msg->setMessageState(state); + msg->setTime(date); + return IChatItem::Ptr(msg); } -IChatItem::Ptr ChatMessage::createChatInfoMessage(const QString &rawMessage, - SystemMessageType type, - const QDateTime &date) { - QString text = rawMessage.toHtmlEscaped(); - QString img; - switch (type) { - case INFO: - img = Style::getImagePath("chatArea/info.svg"); - break; - case ERROR: - img = Style::getImagePath("chatArea/error.svg"); - break; - case TYPING: - img = Style::getImagePath("chatArea/typing.svg"); - break; - } - - QFont baseFont = Settings::getInstance().getChatMessageFont(); - Image * imgItem = new Image(QSize(18, 18), img); - auto *item = new ChatNotificationBox(text, baseFont); - item->setIcon(imgItem); - item->setTime(date); - return IChatItem::Ptr(item); +IChatItem::Ptr ChatMessage::createChatInfoMessage(const QString& rawMessage, + SystemMessageType type, + const QDateTime& date) { + QString text = rawMessage.toHtmlEscaped(); + QString img; + switch (type) { + case INFO: + img = Style::getImagePath("chatArea/info.svg"); + break; + case ERROR: + img = Style::getImagePath("chatArea/error.svg"); + break; + case TYPING: + img = Style::getImagePath("chatArea/typing.svg"); + break; + } + + QFont baseFont = Settings::getInstance().getChatMessageFont(); + Image* imgItem = new Image(QSize(18, 18), img); + auto* item = new ChatNotificationBox(text, baseFont); + item->setIcon(imgItem); + item->setTime(date); + return IChatItem::Ptr(item); } -IChatItem::Ptr ChatMessage::createFileTransferMessage(const ChatLogItem &item, - ToxFile file, - bool isMe, const QDateTime &date) { - qDebug() << __func__ << file.fileName; - QPixmap avatar; - if (isMe) { - const auto &self = Core::getInstance()->getSelfPeerId().getPublicKey(); - avatar = Nexus::getProfile()->loadAvatar(self); - } else { - avatar = Nexus::getProfile()->loadAvatar(item.getSender()); - } - - auto ftw = new FileTransferWidget(nullptr, file); - ChatLineContent *fileContent = new ChatLineContentProxy(ftw, 320, 0.6f); - - ChatMessageBox *msg = new ChatMessageBox(avatar, item.getDisplayName(), fileContent, isMe); - - msg->setTime(date); - return IChatItem::Ptr(msg); +IChatItem::Ptr ChatMessage::createFileTransferMessage(const ChatLogItem& item, ToxFile file, + bool isMe, const QDateTime& date) { + qDebug() << __func__ << file.fileName; + QPixmap avatar; + if (isMe) { + const auto& self = Core::getInstance()->getSelfPeerId().getPublicKey(); + avatar = Nexus::getProfile()->loadAvatar(self); + } else { + avatar = Nexus::getProfile()->loadAvatar(item.getSender()); + } + + auto ftw = new FileTransferWidget(nullptr, file); + ChatLineContent* fileContent = new ChatLineContentProxy(ftw, 320, 0.6f); + + ChatMessageBox* msg = new ChatMessageBox(avatar, item.getDisplayName(), fileContent, isMe); + + msg->setTime(date); + return IChatItem::Ptr(msg); } IChatItem::Ptr ChatMessage::createTypingNotification() { - ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage); + ChatMessage::Ptr msg = ChatMessage::Ptr(new ChatMessage); - QFont baseFont = Settings::getInstance().getChatMessageFont(); + QFont baseFont = Settings::getInstance().getChatMessageFont(); - // Note: "[user]..." is just a placeholder. The actual text is set in - // ChatForm::setFriendTyping() - // - // FIXME: Due to circumstances, placeholder is being used in a case where - // user received typing notifications constantly since contact came online. - // This causes "[user]..." to be displayed in place of user nick, as long - // as user will keep typing. Issue #1280 + // Note: "[user]..." is just a placeholder. The actual text is set in + // ChatForm::setFriendTyping() + // + // FIXME: Due to circumstances, placeholder is being used in a case where + // user received typing notifications constantly since contact came online. + // This causes "[user]..." to be displayed in place of user nick, as long + // as user will keep typing. Issue #1280 - auto *item = new ChatNotificationBox("", baseFont); - item->setIcon(new NotificationIcon(QSize(18, 18))); - return IChatItem::Ptr(item); + auto* item = new ChatNotificationBox("", baseFont); + item->setIcon(new NotificationIcon(QSize(18, 18))); + return IChatItem::Ptr(item); } /** @@ -122,42 +117,39 @@ IChatItem::Ptr ChatMessage::createTypingNotification() { * * @return created message */ -IChatItem::Ptr ChatMessage::createBusyNotification(){ - +IChatItem::Ptr ChatMessage::createBusyNotification() { QFont baseFont = Settings::getInstance().getChatMessageFont(); baseFont.setPixelSize(baseFont.pixelSize() + 2); baseFont.setBold(true); - auto *item = new ChatNotificationBox( - QObject::tr("Reformatting text in progress.."), baseFont); + auto* item = new ChatNotificationBox(QObject::tr("Reformatting text in progress.."), baseFont); return IChatItem::Ptr(item); } -QString ChatMessage::detectQuotes(const QString &str, MessageType type) { - // detect text quotes - QStringList messageLines = str.split("\n"); - QString quotedText; - for (int i = 0; i < messageLines.size(); ++i) { - // don't quote first line in action message. This makes co-existence of - // quotes and action messages possible, since only first line can cause - // problems in case where there is quote in it used. - if (QRegExp("^(>|>).*").exactMatch(messageLines[i])) { - if (i > 0 || type != ACTION) - quotedText += "" + messageLines[i] + " "; - else - quotedText += messageLines[i]; - } else { - quotedText += messageLines[i]; - } - - if (i < messageLines.size() - 1) { - quotedText += '\n'; +QString ChatMessage::detectQuotes(const QString& str, MessageType type) { + // detect text quotes + QStringList messageLines = str.split("\n"); + QString quotedText; + for (int i = 0; i < messageLines.size(); ++i) { + // don't quote first line in action message. This makes co-existence of + // quotes and action messages possible, since only first line can cause + // problems in case where there is quote in it used. + if (QRegExp("^(>|>).*").exactMatch(messageLines[i])) { + if (i > 0 || type != ACTION) + quotedText += "" + messageLines[i] + " "; + else + quotedText += messageLines[i]; + } else { + quotedText += messageLines[i]; + } + + if (i < messageLines.size() - 1) { + quotedText += '\n'; + } } - } - return quotedText; + return quotedText; } -QString ChatMessage::wrapDiv(const QString &str, const QString &div) { - return QString("

%2

") - .arg(div, /*QChar(0x200E) + */ QString(str)); +QString ChatMessage::wrapDiv(const QString& str, const QString& div) { + return QString("

%2

").arg(div, /*QChar(0x200E) + */ QString(str)); } diff --git a/src/modules/im/src/chatlog/chatmessage.h b/src/modules/im/src/chatlog/chatmessage.h index 19e895e9..bfffae1c 100644 --- a/src/modules/im/src/chatlog/chatmessage.h +++ b/src/modules/im/src/chatlog/chatmessage.h @@ -13,42 +13,39 @@ #ifndef CHATMESSAGE_H #define CHATMESSAGE_H +#include #include "chatline.h" #include "src/core/toxfile.h" -#include "src/persistence/history.h" #include "src/model/chatlogitem.h" -#include +#include "src/persistence/history.h" class QGraphicsScene; -class ChatMessage -{ +class ChatMessage { public: using Ptr = std::shared_ptr; - enum SystemMessageType - { + enum SystemMessageType { INFO, ERROR, TYPING, }; - enum MessageType - { + enum MessageType { NORMAL, ACTION, ALERT, }; - static IChatItem::Ptr createChatMessage(const ChatLogItem &item, const QString &rawMessage, - MessageType type, bool isMe, MessageState state, - const QDateTime &date, bool colorizeName = false); + static IChatItem::Ptr createChatMessage(const ChatLogItem& item, const QString& rawMessage, + MessageType type, bool isMe, MessageState state, + const QDateTime& date, bool colorizeName = false); - static IChatItem::Ptr createChatInfoMessage(const QString &rawMessage, + static IChatItem::Ptr createChatInfoMessage(const QString& rawMessage, SystemMessageType type, - const QDateTime& date); - static IChatItem::Ptr createFileTransferMessage(const ChatLogItem &item, ToxFile file, - bool isMe, const QDateTime& date); + const QDateTime& date); + static IChatItem::Ptr createFileTransferMessage(const ChatLogItem& item, ToxFile file, + bool isMe, const QDateTime& date); static IChatItem::Ptr createTypingNotification(); static IChatItem::Ptr createBusyNotification(); @@ -60,4 +57,4 @@ class ChatMessage bool action = false; }; -#endif // CHATMESSAGE_H +#endif // CHATMESSAGE_H diff --git a/src/modules/im/src/chatlog/chatmessageitem.cpp b/src/modules/im/src/chatlog/chatmessageitem.cpp index 6ed95f06..47fc8a77 100644 --- a/src/modules/im/src/chatlog/chatmessageitem.cpp +++ b/src/modules/im/src/chatlog/chatmessageitem.cpp @@ -1,19 +1,19 @@ #include "chatmessageitem.h" +#include "content/broken.h" #include "content/contactavatar.h" -#include "content/text.h" #include "content/simpletext.h" #include "content/spinner.h" -#include "content/broken.h" +#include "content/text.h" #include "src/persistence/settings.h" -#include #include +#include #include -ChatMessageBox::ChatMessageBox(const QPixmap &avatar, - const QString &contactName, - const QString &message, - bool isSelf) { +ChatMessageBox::ChatMessageBox(const QPixmap& avatar, + const QString& contactName, + const QString& message, + bool isSelf) { _IsSelf = isSelf; avatarItem = new ContactAvatar(avatar); QFont baseFont = Settings::getInstance().getChatMessageFont(); @@ -21,19 +21,19 @@ ChatMessageBox::ChatMessageBox(const QPixmap &avatar, nicknameItem = new SimpleText(contactName, nameFont); nicknameItem->setColor(Style::NameActive); - Text *text = new Text(message, baseFont, false, message); + Text* text = new Text(message, baseFont, false, message); text->setBoundingRadius(4.0); text->setContentsMargins(QMarginsF(3, 3, 3, 3)); messageItem = text; - if (isSelf) - { + if (isSelf) { setLayoutDirection(Qt::RightToLeft); setShowNickname(false); } updateTextTheme(); } -ChatMessageBox::ChatMessageBox(const QPixmap &avatar, const QString &contactName, ChatLineContent *messageItem, bool isSelf) { +ChatMessageBox::ChatMessageBox(const QPixmap& avatar, const QString& contactName, + ChatLineContent* messageItem, bool isSelf) { avatarItem = new ContactAvatar(avatar); QFont baseFont = Settings::getInstance().getChatMessageFont(); QFont nameFont = nicknameFont(baseFont); @@ -41,41 +41,36 @@ ChatMessageBox::ChatMessageBox(const QPixmap &avatar, const QString &contactName nicknameItem->setColor(Style::NameActive); this->messageItem = messageItem; customMsg = true; - _IsSelf = isSelf; - if (isSelf) - { + _IsSelf = isSelf; + if (isSelf) { setLayoutDirection(Qt::RightToLeft); setShowNickname(false); } } void ChatMessageBox::setMessageState(MessageState state) { - if (msgState == state) - return; + if (msgState == state) return; msgState = state; if (stateItem) { - if (stateItem->scene()) - stateItem->scene()->removeItem(stateItem); + if (stateItem->scene()) stateItem->scene()->removeItem(stateItem); delete stateItem; stateItem = nullptr; } switch (state) { - case MessageState::pending: { - stateItem = new Spinner(Style::getImagePath("chatArea/spinner.svg"), - QSize(16, 16), 360.0 / 1.6); - } break; - case MessageState::broken: { - stateItem = new Broken(Style::getImagePath("chatArea/error.svg"), - QSize(16, 16)); - } break; - default: - break; + case MessageState::pending: { + stateItem = new Spinner(Style::getImagePath("chatArea/spinner.svg"), QSize(16, 16), + 360.0 / 1.6); + } break; + case MessageState::broken: { + stateItem = new Broken(Style::getImagePath("chatArea/error.svg"), QSize(16, 16)); + } break; + default: + break; } } void ChatMessageBox::layout(qreal width, QPointF scenePos) { - - auto mirrorPos = [width, scenePos, this](QPointF &pos, qreal offset) { + auto mirrorPos = [width, scenePos, this](QPointF& pos, qreal offset) { if (this->layoutDirection == Qt::RightToLeft) pos.rx() = width + scenePos.x() - pos.x() + scenePos.x() - offset; }; @@ -97,12 +92,10 @@ void ChatMessageBox::layout(qreal width, QPointF scenePos) { qreal width_limit = width * 0.667; messageItem->setWidth(-1); - if (messageItem->boundingRect().width() > width_limit) - messageItem->setWidth(width_limit); + if (messageItem->boundingRect().width() > width_limit) messageItem->setWidth(width_limit); { - QPointF msg_pos = - scenePos + QPointF(avatar_width + 6.0, message_offset); + QPointF msg_pos = scenePos + QPointF(avatar_width + 6.0, message_offset); mirrorPos(msg_pos, messageItem->boundingRect().width()); messageItem->setPos(msg_pos - messageItem->boundingRect().topLeft()); } @@ -110,8 +103,7 @@ void ChatMessageBox::layout(qreal width, QPointF scenePos) { if (stateItem) { QSizeF msg_size = messageItem->boundingRect().size(); QRectF state_rect = stateItem->boundingRect(); - QPointF state_pos = - scenePos + QPointF(avatar_width + 6.0, message_offset); + QPointF state_pos = scenePos + QPointF(avatar_width + 6.0, message_offset); state_pos.rx() += msg_size.width() + 6.0; state_pos.ry() += (msg_size.height() - state_rect.height()) / 2; mirrorPos(state_pos, state_rect.width()); @@ -124,12 +116,11 @@ QRectF ChatMessageBox::sceneBoundingRect() const { QRectF itemRect = avatarItem->sceneBoundingRect(); if (showNickname) itemRect = itemRect.united(messageItem->sceneBoundingRect()) - .united(messageItem->sceneBoundingRect()); + .united(messageItem->sceneBoundingRect()); else itemRect = itemRect.united(messageItem->sceneBoundingRect()); - if (stateItem) - itemRect = itemRect.united(stateItem->sceneBoundingRect()); + if (stateItem) itemRect = itemRect.united(stateItem->sceneBoundingRect()); return itemRect; } @@ -144,19 +135,16 @@ void ChatMessageBox::setVisible(bool visible) { } } -void ChatMessageBox::markAsDelivered(const QDateTime &time) { +void ChatMessageBox::markAsDelivered(const QDateTime& time) { setMessageState(MessageState::complete); } -ChatLineContent *ChatMessageBox::contentAtPos(QPointF scenePos) const { - if (messageItem && messageItem->sceneBoundingRect().contains(scenePos)) - return messageItem; +ChatLineContent* ChatMessageBox::contentAtPos(QPointF scenePos) const { + if (messageItem && messageItem->sceneBoundingRect().contains(scenePos)) return messageItem; return nullptr; } -ChatLineContent *ChatMessageBox::centerContent() const { - return messageItem; -} +ChatLineContent* ChatMessageBox::centerContent() const { return messageItem; } void ChatMessageBox::setLayoutDirection(Qt::LayoutDirection direction) { layoutDirection = direction; @@ -169,60 +157,47 @@ void ChatMessageBox::setShowNickname(bool show) { nicknameItem->visibilityChanged(show); } -QList ChatMessageBox::contents() { - QList result({avatarItem, nicknameItem, messageItem}); - if (stateItem) - result.append(stateItem); +QList ChatMessageBox::contents() { + QList result({avatarItem, nicknameItem, messageItem}); + if (stateItem) result.append(stateItem); return result; } -void ChatMessageBox::reloadTheme() -{ +void ChatMessageBox::reloadTheme() { IChatItem::reloadTheme(); updateTextTheme(); } -QFont ChatMessageBox::nicknameFont(const QFont &baseFont) { - +QFont ChatMessageBox::nicknameFont(const QFont& baseFont) { QFont font = baseFont; font.setPixelSize(font.pixelSize() - 1); return font; } -void ChatMessageBox::updateTextTheme() -{ - if (customMsg) - return; - if (Text* text_item = dynamic_cast(messageItem)) - { - if (_IsSelf) - { +void ChatMessageBox::updateTextTheme() { + if (customMsg) return; + if (Text* text_item = dynamic_cast(messageItem)) { + if (_IsSelf) { text_item->setBackgroundColor(Style::getExtColor("chat.message.self.background")); text_item->setColor(Style::getExtColor("chat.message.self.color")); - } - else - { + } else { text_item->setBackgroundColor(Style::getExtColor("chat.message.background")); text_item->setColor(Style::getExtColor("chat.message.color")); } } } -int ChatMessageBox::itemType() { - return 0; -} +int ChatMessageBox::itemType() { return 0; } -ChatNotificationBox::ChatNotificationBox(const QString &message, - const QFont &font) { +ChatNotificationBox::ChatNotificationBox(const QString& message, const QFont& font) { textItem = new Text(message, font); textItem->setWidth(-1); textItem->setTextSelectable(false); } -void ChatNotificationBox::setIcon(ChatLineContent *item) { +void ChatNotificationBox::setIcon(ChatLineContent* item) { if (iconItem && iconItem != item) { - if (iconItem->scene()) - iconItem->scene()->removeItem(iconItem); + if (iconItem->scene()) iconItem->scene()->removeItem(iconItem); delete iconItem; } iconItem = item; @@ -240,8 +215,7 @@ void ChatNotificationBox::layout(qreal width, QPointF scenePos) { icon_rect.moveCenter(temp.center() - icon_rect.topLeft()); iconItem->setPos(icon_rect.topLeft()); - temp = QRectF(ctx_x + icon_rect.width(), ctx_y, text_rect.width(), - ctx_height); + temp = QRectF(ctx_x + icon_rect.width(), ctx_y, text_rect.width(), ctx_height); text_rect.moveCenter(temp.center() - text_rect.topLeft()); textItem->setPos(text_rect.topLeft()); } else { @@ -252,28 +226,21 @@ void ChatNotificationBox::layout(qreal width, QPointF scenePos) { QRectF ChatNotificationBox::sceneBoundingRect() const { if (iconItem) { - return iconItem->sceneBoundingRect().united( - textItem->sceneBoundingRect()); + return iconItem->sceneBoundingRect().united(textItem->sceneBoundingRect()); } return textItem->sceneBoundingRect(); } -ChatLineContent *ChatNotificationBox::contentAtPos(QPointF scenePos) const { - if (textItem && textItem->sceneBoundingRect().contains(scenePos)) - return textItem; +ChatLineContent* ChatNotificationBox::contentAtPos(QPointF scenePos) const { + if (textItem && textItem->sceneBoundingRect().contains(scenePos)) return textItem; return nullptr; } -ChatLineContent *ChatNotificationBox::centerContent() const { - return textItem; -} +ChatLineContent* ChatNotificationBox::centerContent() const { return textItem; } -int ChatNotificationBox::itemType() { - return 0; -} +int ChatNotificationBox::itemType() { return 0; } -QList ChatNotificationBox::contents() { - if (iconItem) - return QList({iconItem, textItem}); - return QList({textItem}); +QList ChatNotificationBox::contents() { + if (iconItem) return QList({iconItem, textItem}); + return QList({textItem}); } diff --git a/src/modules/im/src/chatlog/chatmessageitem.h b/src/modules/im/src/chatlog/chatmessageitem.h index 2af71367..7f52bd89 100644 --- a/src/modules/im/src/chatlog/chatmessageitem.h +++ b/src/modules/im/src/chatlog/chatmessageitem.h @@ -2,7 +2,7 @@ #define CHATMESSAGEITEM_H #include "chatline.h" - + class ContactAvatar; class Text; class SimpleText; @@ -10,11 +10,11 @@ class NotificationIcon; class ChatMessageBox : public IChatItem { public: - ChatMessageBox(const QPixmap &avatar, const QString &contactName, - const QString &message, bool isSelf = false); + ChatMessageBox(const QPixmap& avatar, const QString& contactName, const QString& message, + bool isSelf = false); - ChatMessageBox(const QPixmap &avatar, const QString &contactName, - ChatLineContent *messageItem, bool isSelf = false); + ChatMessageBox(const QPixmap& avatar, const QString& contactName, ChatLineContent* messageItem, + bool isSelf = false); void setMessageState(MessageState state); @@ -22,44 +22,39 @@ class ChatMessageBox : public IChatItem { QRectF sceneBoundingRect() const override; void setVisible(bool visible) override; - void markAsDelivered(const QDateTime &time) override; + void markAsDelivered(const QDateTime& time) override; - ChatLineContent *contentAtPos(QPointF scenePos) const override; - ChatLineContent *centerContent() const override; + ChatLineContent* contentAtPos(QPointF scenePos) const override; + ChatLineContent* centerContent() const override; // set before add to scene void setLayoutDirection(Qt::LayoutDirection direction); void setShowNickname(bool show); - bool selectable() const override { - return true; - } - ContactAvatar *getAvatarItem(){ - return avatarItem; - } + bool selectable() const override { return true; } + ContactAvatar* getAvatarItem() { return avatarItem; } + + SimpleText* nickname() { return nicknameItem; } - SimpleText *nickname(){ - return nicknameItem; - } protected: - QList contents() override; + QList contents() override; void reloadTheme() override; private: - inline QPointF mapToLayout(const QPointF &pos, qreal width, qreal offset) { + inline QPointF mapToLayout(const QPointF& pos, qreal width, qreal offset) { if (layoutDirection == Qt::RightToLeft) { return QPointF(width - pos.x() - offset, pos.y()); } return pos; } - QFont nicknameFont(const QFont &baseFont); + QFont nicknameFont(const QFont& baseFont); void updateTextTheme(); int itemType() override; private: - ContactAvatar *avatarItem = nullptr; - SimpleText *nicknameItem = nullptr; - ChatLineContent *messageItem = nullptr; - ChatLineContent *stateItem = nullptr; + ContactAvatar* avatarItem = nullptr; + SimpleText* nicknameItem = nullptr; + ChatLineContent* messageItem = nullptr; + ChatLineContent* stateItem = nullptr; MessageState msgState = MessageState::complete; QPointF scenePos; Qt::LayoutDirection layoutDirection = Qt::LeftToRight; @@ -70,28 +65,25 @@ class ChatMessageBox : public IChatItem { class ChatNotificationBox : public IChatItem { public: - ChatNotificationBox(const QString &message, const QFont &font); + ChatNotificationBox(const QString& message, const QFont& font); - void setIcon(ChatLineContent *item); + void setIcon(ChatLineContent* item); void layout(qreal width, QPointF scenePos) override; QRectF sceneBoundingRect() const override; - ChatLineContent *contentAtPos(QPointF scenePos) const override; - ChatLineContent *centerContent() const override; + ChatLineContent* contentAtPos(QPointF scenePos) const override; + ChatLineContent* centerContent() const override; int itemType() override; - bool selectable() const override { - return false; - } + bool selectable() const override { return false; } protected: - QList contents() override; + QList contents() override; private: - ChatLineContent *iconItem = nullptr; - Text *textItem = nullptr; + ChatLineContent* iconItem = nullptr; + Text* textItem = nullptr; }; -#endif // !CHATMESSAGEITEM_H - +#endif // !CHATMESSAGEITEM_H diff --git a/src/modules/im/src/chatlog/content/broken.cpp b/src/modules/im/src/chatlog/content/broken.cpp index 0959839a..3fe0271a 100644 --- a/src/modules/im/src/chatlog/content/broken.cpp +++ b/src/modules/im/src/chatlog/content/broken.cpp @@ -11,45 +11,29 @@ */ #include "broken.h" -#include "src/chatlog/pixmapcache.h" #include +#include "src/chatlog/pixmapcache.h" class QStyleOptionGraphicsItem; Broken::Broken(const QString& img, QSize size) - : pmap{PixmapCache::getInstance().get(img, size)} - , size{size} -{ -} + : pmap{PixmapCache::getInstance().get(img, size)}, size{size} {} -QRectF Broken::boundingRect() const -{ +QRectF Broken::boundingRect() const { return QRectF(QPointF(-size.width() / 2.0, -size.height() / 2.0), size); } -void Broken::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, - QWidget* widget) -{ +void Broken::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { painter->setRenderHint(QPainter::SmoothPixmapTransform); painter->translate(QPointF(-size.width() / 2.0, -size.height() / 2.0)); painter->drawPixmap(0, 0, pmap); Q_UNUSED(option) Q_UNUSED(widget) - } -void Broken::setWidth(qreal width) -{ - Q_UNUSED(width); -} +void Broken::setWidth(qreal width) { Q_UNUSED(width); } -void Broken::visibilityChanged(bool visible) -{ - Q_UNUSED(visible); -} +void Broken::visibilityChanged(bool visible) { Q_UNUSED(visible); } -qreal Broken::getAscent() const -{ - return 0.0; -} +qreal Broken::getAscent() const { return 0.0; } diff --git a/src/modules/im/src/chatlog/content/broken.h b/src/modules/im/src/chatlog/content/broken.h index ce5ac9a0..db7d3b5c 100644 --- a/src/modules/im/src/chatlog/content/broken.h +++ b/src/modules/im/src/chatlog/content/broken.h @@ -18,14 +18,12 @@ #include #include -class Broken : public ChatLineContent -{ +class Broken : public ChatLineContent { Q_OBJECT public: Broken(const QString& img, QSize size); QRectF boundingRect() const override; - void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, - QWidget* widget) override; + void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override; void setWidth(qreal width) override; void visibilityChanged(bool visible) override; qreal getAscent() const override; @@ -35,4 +33,4 @@ class Broken : public ChatLineContent QPixmap pmap; }; -#endif // BROKEN_H +#endif // BROKEN_H diff --git a/src/modules/im/src/chatlog/content/contactavatar.cpp b/src/modules/im/src/chatlog/content/contactavatar.cpp index d8477f8e..df805292 100644 --- a/src/modules/im/src/chatlog/content/contactavatar.cpp +++ b/src/modules/im/src/chatlog/content/contactavatar.cpp @@ -15,48 +15,34 @@ #include - static constexpr float avatar_size = 40; -ContactAvatar::ContactAvatar(const QPixmap &avatar) - : avatar(avatar) -{ -} +ContactAvatar::ContactAvatar(const QPixmap& avatar) : avatar(avatar) {} -QRectF ContactAvatar::boundingRect() const -{ - return QRectF(0, 0, avatar_size, avatar_size); -} +QRectF ContactAvatar::boundingRect() const { return QRectF(0, 0, avatar_size, avatar_size); } -qreal ContactAvatar::getAscent() const -{ - return 0.0; -} +qreal ContactAvatar::getAscent() const { return 0.0; } -void ContactAvatar::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) -{ +void ContactAvatar::paint(QPainter* painter, + const QStyleOptionGraphicsItem* option, + QWidget* widget) { QRectF r = boundingRect(); QPainterPath path; path.addRoundedRect(r.adjusted(0, 0, -1, -1), 4.0, 4.0); - painter->setRenderHints(QPainter::SmoothPixmapTransform | - QPainter::Antialiasing); - - if (!avatar.isNull()) - { + painter->setRenderHints(QPainter::SmoothPixmapTransform | QPainter::Antialiasing); + + if (!avatar.isNull()) { qreal factor = painter->device()->devicePixelRatioF(); QPixmap temp(avatar_size * factor, avatar_size * factor); temp.fill(QColor(0, 0, 0, 0)); temp.setDevicePixelRatio(factor); QPainter p(&temp); - p.setRenderHints(QPainter::SmoothPixmapTransform | - QPainter::Antialiasing); + p.setRenderHints(QPainter::SmoothPixmapTransform | QPainter::Antialiasing); p.fillPath(path, QColor(0xffffff)); p.setCompositionMode(QPainter::CompositionMode_SourceIn); p.drawPixmap(r.toRect(), avatar); p.end(); painter->drawPixmap(0, 0, temp); - } - else - { + } else { painter->translate(0.5, 0.5); painter->fillPath(path, QColor(0x4D90FE)); } @@ -65,9 +51,4 @@ void ContactAvatar::paint(QPainter* painter, const QStyleOptionGraphicsItem* opt Q_UNUSED(widget) } -void ContactAvatar::setWidth(qreal width) -{ - Q_UNUSED(width) -} - - +void ContactAvatar::setWidth(qreal width) { Q_UNUSED(width) } diff --git a/src/modules/im/src/chatlog/content/contactavatar.h b/src/modules/im/src/chatlog/content/contactavatar.h index a35cce10..a5aa5e15 100644 --- a/src/modules/im/src/chatlog/content/contactavatar.h +++ b/src/modules/im/src/chatlog/content/contactavatar.h @@ -17,10 +17,9 @@ #include -class ContactAvatar : public ChatLineContent -{ +class ContactAvatar : public ChatLineContent { public: - ContactAvatar(const QPixmap & avatar); + ContactAvatar(const QPixmap& avatar); virtual QRectF boundingRect() const override; virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, @@ -32,4 +31,4 @@ class ContactAvatar : public ChatLineContent QPixmap avatar; }; -#endif // CONTACTAVATAR_H +#endif // CONTACTAVATAR_H diff --git a/src/modules/im/src/chatlog/content/filetransferwidget.cpp b/src/modules/im/src/chatlog/content/filetransferwidget.cpp index 8b1e122a..93e337ed 100644 --- a/src/modules/im/src/chatlog/content/filetransferwidget.cpp +++ b/src/modules/im/src/chatlog/content/filetransferwidget.cpp @@ -33,9 +33,8 @@ #include #include -#include #include - +#include // The leftButton is used to accept, pause, or resume a file transfer, as well as to open a // received file. @@ -43,14 +42,13 @@ // downloaded to. FileTransferWidget::FileTransferWidget(QWidget* parent, ToxFile file) - : QWidget(parent) - , ui(new Ui::FileTransferWidget) - , fileInfo(file) - , backgroundColor(Style::getColor(Style::TransferMiddle)) - , buttonColor(Style::getColor(Style::TransferWait)) - , buttonBackgroundColor(Style::getColor(Style::GroundBase)) - , active(true) -{ + : QWidget(parent) + , ui(new Ui::FileTransferWidget) + , fileInfo(file) + , backgroundColor(Style::getColor(Style::TransferMiddle)) + , buttonColor(Style::getColor(Style::TransferWait)) + , buttonBackgroundColor(Style::getColor(Style::GroundBase)) + , active(true) { ui->setupUi(this); // hide the QWidget background (background-color: transparent doesn't seem to work) @@ -74,34 +72,34 @@ FileTransferWidget::FileTransferWidget(QWidget* parent, ToxFile file) buttonColorAnimation = new QVariantAnimation(this); buttonColorAnimation->setDuration(500); buttonColorAnimation->setEasingCurve(QEasingCurve::OutCubic); - connect(buttonColorAnimation, &QVariantAnimation::valueChanged, this, [this](const QVariant& val) { - buttonColor = val.value(); - update(); - }); + connect(buttonColorAnimation, &QVariantAnimation::valueChanged, this, + [this](const QVariant& val) { + buttonColor = val.value(); + update(); + }); CoreFile* coreFile = Core::getInstance()->getCoreFile(); connect(ui->leftButton, &QPushButton::clicked, this, &FileTransferWidget::onLeftButtonClicked); - connect(ui->rightButton, &QPushButton::clicked, this, &FileTransferWidget::onRightButtonClicked); + connect(ui->rightButton, &QPushButton::clicked, this, + &FileTransferWidget::onRightButtonClicked); connect(ui->previewButton, &QPushButton::clicked, this, &FileTransferWidget::onPreviewButtonClicked); // Set lastStatus to anything but the file's current value, this forces an update - lastStatus = file.status == FileStatus::FINISHED ? FileStatus::INITIALIZING : FileStatus::FINISHED; + lastStatus = + file.status == FileStatus::FINISHED ? FileStatus::INITIALIZING : FileStatus::FINISHED; updateWidget(file); setFixedHeight(64); connect(&GUI::getInstance(), &GUI::themeApplyRequest, this, [this]() { backgroundColorAnimation->stop(); - setBackgroundColor(lastStatus, true); + setBackgroundColor(lastStatus, true); }); } -FileTransferWidget::~FileTransferWidget() -{ - delete ui; -} +FileTransferWidget::~FileTransferWidget() { delete ui; } // TODO(sudden6): remove file IO from the UI /** @@ -109,26 +107,18 @@ FileTransferWidget::~FileTransferWidget() * @param filepath Path to file which should be deleted. * @return True, if file writeable, false otherwise. */ -bool FileTransferWidget::tryRemoveFile(const QString& filepath) -{ +bool FileTransferWidget::tryRemoveFile(const QString& filepath) { QFile tmp(filepath); bool writable = tmp.open(QIODevice::WriteOnly); tmp.remove(); return writable; } -void FileTransferWidget::onFileTransferUpdate(ToxFile file) -{ - updateWidget(file); -} +void FileTransferWidget::onFileTransferUpdate(ToxFile file) { updateWidget(file); } -bool FileTransferWidget::isActive() const -{ - return active; -} +bool FileTransferWidget::isActive() const { return active; } -void FileTransferWidget::acceptTransfer(const QString& filepath) -{ +void FileTransferWidget::acceptTransfer(const QString& filepath) { if (filepath.isEmpty()) { return; } @@ -148,39 +138,35 @@ void FileTransferWidget::acceptTransfer(const QString& filepath) } void FileTransferWidget::setBackgroundColor(FileStatus status, bool useAnima) { - QColor color; bool whiteFont; switch (status) { - case FileStatus::INITIALIZING: - case FileStatus::PAUSED: - case FileStatus::TRANSMITTING: - color = Style::getColor(Style::TransferMiddle); - whiteFont = false; - break; - case FileStatus::BROKEN: - case FileStatus::CANCELED: - color = Style::getColor(Style::TransferBad); - whiteFont = true; - break; - case FileStatus::FINISHED: - color = Style::getColor(Style::TransferGood); - whiteFont = true; - break; - default: - return; - break; + case FileStatus::INITIALIZING: + case FileStatus::PAUSED: + case FileStatus::TRANSMITTING: + color = Style::getColor(Style::TransferMiddle); + whiteFont = false; + break; + case FileStatus::BROKEN: + case FileStatus::CANCELED: + color = Style::getColor(Style::TransferBad); + whiteFont = true; + break; + case FileStatus::FINISHED: + color = Style::getColor(Style::TransferGood); + whiteFont = true; + break; + default: + return; + break; } - if (color != backgroundColor) - { + if (color != backgroundColor) { if (useAnima) { backgroundColorAnimation->setStartValue(backgroundColor); backgroundColorAnimation->setEndValue(color); backgroundColorAnimation->start(); - } - else - { + } else { backgroundColor = color; } } @@ -190,8 +176,7 @@ void FileTransferWidget::setBackgroundColor(FileStatus status, bool useAnima) { setStyleSheet(Style::getStylesheet("fileTransferInstance/filetransferWidget.css")); } -void FileTransferWidget::setButtonColor(const QColor& c) -{ +void FileTransferWidget::setButtonColor(const QColor& c) { if (c != buttonColor) { buttonColorAnimation->setStartValue(buttonColor); buttonColorAnimation->setEndValue(c); @@ -199,14 +184,12 @@ void FileTransferWidget::setButtonColor(const QColor& c) } } -bool FileTransferWidget::drawButtonAreaNeeded() const -{ - return (ui->rightButton->isVisible() || ui->leftButton->isVisible()) - && !(ui->leftButton->isVisible() && ui->leftButton->objectName() == "ok"); +bool FileTransferWidget::drawButtonAreaNeeded() const { + return (ui->rightButton->isVisible() || ui->leftButton->isVisible()) && + !(ui->leftButton->isVisible() && ui->leftButton->objectName() == "ok"); } -void FileTransferWidget::paintEvent(QPaintEvent*) -{ +void FileTransferWidget::paintEvent(QPaintEvent*) { // required by Hi-DPI support as border-image doesn't work. QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); @@ -226,8 +209,8 @@ void FileTransferWidget::paintEvent(QPaintEvent*) // Draw the button background: QPainterPath buttonBackground; buttonBackground.addRoundedRect(width() - 2 * buttonFieldWidth - lineWidth * 2, 0, - buttonFieldWidth, buttonFieldWidth + lineWidth, 50, 50, - Qt::RelativeSize); + buttonFieldWidth, buttonFieldWidth + lineWidth, 50, 50, + Qt::RelativeSize); buttonBackground.addRect(width() - 2 * buttonFieldWidth - lineWidth * 2, 0, buttonFieldWidth * 2, buttonFieldWidth / 2); buttonBackground.addRect(width() - 1.5 * buttonFieldWidth - lineWidth * 2, 0, @@ -239,8 +222,8 @@ void FileTransferWidget::paintEvent(QPaintEvent*) // Draw the left button: QPainterPath leftButton; leftButton.addRoundedRect(QRect(width() - 2 * buttonFieldWidth - lineWidth, 0, - buttonFieldWidth, buttonFieldWidth), - 50, 50, Qt::RelativeSize); + buttonFieldWidth, buttonFieldWidth), + 50, 50, Qt::RelativeSize); leftButton.addRect(QRect(width() - 2 * buttonFieldWidth - lineWidth, 0, buttonFieldWidth / 2, buttonFieldWidth / 2)); leftButton.addRect(QRect(width() - 1.5 * buttonFieldWidth - lineWidth, 0, @@ -251,13 +234,13 @@ void FileTransferWidget::paintEvent(QPaintEvent*) // Draw the right button: painter.setBrush(QBrush(buttonColor)); - painter.setClipRect(QRect(width() - buttonFieldWidth, 0, buttonFieldWidth, buttonFieldWidth)); + painter.setClipRect( + QRect(width() - buttonFieldWidth, 0, buttonFieldWidth, buttonFieldWidth)); painter.drawRoundedRect(geometry(), r * ratio, r, Qt::RelativeSize); } } -QString FileTransferWidget::getHumanReadableSize(qint64 size) -{ +QString FileTransferWidget::getHumanReadableSize(qint64 size) { static const char* suffix[] = {"B", "kiB", "MiB", "GiB", "TiB"}; int exp = 0; @@ -268,238 +251,233 @@ QString FileTransferWidget::getHumanReadableSize(qint64 size) return QString().setNum(size / pow(1024, exp), 'f', exp > 1 ? 2 : 0).append(suffix[exp]); } -void FileTransferWidget::updateWidgetColor(ToxFile const& file) -{ +void FileTransferWidget::updateWidgetColor(ToxFile const& file) { if (lastStatus == file.status) { return; } switch (file.status) { - case FileStatus::INITIALIZING: - case FileStatus::PAUSED: - case FileStatus::TRANSMITTING: - case FileStatus::BROKEN: - case FileStatus::CANCELED: - case FileStatus::FINISHED: - setBackgroundColor(file.status); - break; - default: - qWarning() << "Invalid file status" << file.fileId; - break; + case FileStatus::INITIALIZING: + case FileStatus::PAUSED: + case FileStatus::TRANSMITTING: + case FileStatus::BROKEN: + case FileStatus::CANCELED: + case FileStatus::FINISHED: + setBackgroundColor(file.status); + break; + default: + qWarning() << "Invalid file status" << file.fileId; + break; } } -void FileTransferWidget::updateWidgetText(ToxFile const& file) -{ +void FileTransferWidget::updateWidgetText(ToxFile const& file) { if (lastStatus == file.status && file.status != FileStatus::PAUSED) { return; } switch (file.status) { - case FileStatus::INITIALIZING: - if (file.direction == FileDirection::SENDING) { - ui->progressLabel->setText(tr("Waiting to send...", "file transfer widget")); - } else { - ui->progressLabel->setText(tr("Accept to receive this file", "file transfer widget")); - } - break; - case FileStatus::PAUSED: -// ui->etaLabel->setText(""); -// if (file.pauseStatus.localPaused()) { -// ui->progressLabel->setText(tr("Paused", "file transfer widget")); -// } else { -// ui->progressLabel->setText(tr("Remote Paused", "file transfer widget")); -// } - break; - case FileStatus::TRANSMITTING: - ui->etaLabel->setText(""); - ui->progressLabel->setText(tr("Resuming...", "file transfer widget")); - break; - case FileStatus::BROKEN: - case FileStatus::CANCELED: - break; - case FileStatus::FINISHED: - break; - default: - qWarning() << "Invalid file status" << file.fileId; - break; + case FileStatus::INITIALIZING: + if (file.direction == FileDirection::SENDING) { + ui->progressLabel->setText(tr("Waiting to send...", "file transfer widget")); + } else { + ui->progressLabel->setText( + tr("Accept to receive this file", "file transfer widget")); + } + break; + case FileStatus::PAUSED: + // ui->etaLabel->setText(""); + // if (file.pauseStatus.localPaused()) { + // ui->progressLabel->setText(tr("Paused", "file transfer widget")); + // } else { + // ui->progressLabel->setText(tr("Remote Paused", "file transfer widget")); + // } + break; + case FileStatus::TRANSMITTING: + ui->etaLabel->setText(""); + ui->progressLabel->setText(tr("Resuming...", "file transfer widget")); + break; + case FileStatus::BROKEN: + case FileStatus::CANCELED: + break; + case FileStatus::FINISHED: + break; + default: + qWarning() << "Invalid file status" << file.fileId; + break; } } -void FileTransferWidget::updatePreview(ToxFile const& file) -{ +void FileTransferWidget::updatePreview(ToxFile const& file) { if (lastStatus == file.status) { return; } switch (file.status) { - case FileStatus::INITIALIZING: - case FileStatus::PAUSED: - case FileStatus::TRANSMITTING: - case FileStatus::BROKEN: - case FileStatus::CANCELED: - if (file.direction == FileDirection::SENDING) { + case FileStatus::INITIALIZING: + case FileStatus::PAUSED: + case FileStatus::TRANSMITTING: + case FileStatus::BROKEN: + case FileStatus::CANCELED: + if (file.direction == FileDirection::SENDING) { + showPreview(file.filePath); + } + break; + case FileStatus::FINISHED: showPreview(file.filePath); - } - break; - case FileStatus::FINISHED: - showPreview(file.filePath); - break; - default: - qWarning() << "Invalid file status" << file.fileId; -// assert(false); + break; + default: + qWarning() << "Invalid file status" << file.fileId; + // assert(false); } } -void FileTransferWidget::updateFileProgress(ToxFile const& file) -{ +void FileTransferWidget::updateFileProgress(ToxFile const& file) { switch (file.status) { - case FileStatus::INITIALIZING: - break; - case FileStatus::PAUSED: - fileProgress.resetSpeed(); - break; - case FileStatus::TRANSMITTING: { - if (!fileProgress.needsUpdate()) { + case FileStatus::INITIALIZING: break; - } + case FileStatus::PAUSED: + fileProgress.resetSpeed(); + break; + case FileStatus::TRANSMITTING: { + if (!fileProgress.needsUpdate()) { + break; + } - fileProgress.addSample(file); - auto speed = fileProgress.getSpeed(); - auto progress = fileProgress.getProgress(); - auto remainingTime = fileProgress.getTimeLeftSeconds(); + fileProgress.addSample(file); + auto speed = fileProgress.getSpeed(); + auto progress = fileProgress.getProgress(); + auto remainingTime = fileProgress.getTimeLeftSeconds(); - ui->progressBar->setValue(static_cast(progress * 100.0)); + ui->progressBar->setValue(static_cast(progress * 100.0)); - // update UI - if (speed > 0) { - // ETA - QTime toGo = QTime(0, 0).addSecs(remainingTime); - QString format = toGo.hour() > 0 ? "hh:mm:ss" : "mm:ss"; - ui->etaLabel->setText(toGo.toString(format)); - } else { - ui->etaLabel->setText(""); - } + // update UI + if (speed > 0) { + // ETA + QTime toGo = QTime(0, 0).addSecs(remainingTime); + QString format = toGo.hour() > 0 ? "hh:mm:ss" : "mm:ss"; + ui->etaLabel->setText(toGo.toString(format)); + } else { + ui->etaLabel->setText(""); + } - ui->progressLabel->setText(getHumanReadableSize(speed) + "/s"); - break; - } - case FileStatus::BROKEN: - case FileStatus::CANCELED: - case FileStatus::FINISHED: { - ui->progressBar->hide(); - ui->progressLabel->hide(); - ui->etaLabel->hide(); - break; - } - default: - qWarning() << "Invalid file status" << file.fileId; -// assert(false); + ui->progressLabel->setText(getHumanReadableSize(speed) + "/s"); + break; + } + case FileStatus::BROKEN: + case FileStatus::CANCELED: + case FileStatus::FINISHED: { + ui->progressBar->hide(); + ui->progressLabel->hide(); + ui->etaLabel->hide(); + break; + } + default: + qWarning() << "Invalid file status" << file.fileId; + // assert(false); } } -void FileTransferWidget::updateSignals(ToxFile const& file) -{ +void FileTransferWidget::updateSignals(ToxFile const& file) { if (lastStatus == file.status) { return; } switch (file.status) { - case FileStatus::CANCELED: - case FileStatus::BROKEN: - case FileStatus::FINISHED: - active = false; - disconnect(Core::getInstance()->getCoreFile(), nullptr, this, nullptr); - break; - case FileStatus::INITIALIZING: - case FileStatus::PAUSED: - case FileStatus::TRANSMITTING: - break; - default: - qWarning() << "Invalid file status" << file.fileId; - break; + case FileStatus::CANCELED: + case FileStatus::BROKEN: + case FileStatus::FINISHED: + active = false; + disconnect(Core::getInstance()->getCoreFile(), nullptr, this, nullptr); + break; + case FileStatus::INITIALIZING: + case FileStatus::PAUSED: + case FileStatus::TRANSMITTING: + break; + default: + qWarning() << "Invalid file status" << file.fileId; + break; } } -void FileTransferWidget::setupButtons(ToxFile const& file) -{ +void FileTransferWidget::setupButtons(ToxFile const& file) { if (lastStatus == file.status && file.status != FileStatus::PAUSED) { return; } switch (file.status) { - case FileStatus::TRANSMITTING: - ui->leftButton->setIcon(QIcon(Style::getImagePath("fileTransferInstance/pause.svg"))); - ui->leftButton->setObjectName("pause"); - ui->leftButton->setToolTip(tr("Pause transfer")); - - ui->rightButton->setIcon(QIcon(Style::getImagePath("fileTransferInstance/no.svg"))); - ui->rightButton->setObjectName("cancel"); - ui->rightButton->setToolTip(tr("Cancel transfer")); - - setButtonColor(Style::getColor(Style::TransferGood)); - break; - - case FileStatus::PAUSED: -// if (file.pauseStatus.localPaused()) { -// ui->leftButton->setIcon(QIcon(Style::getImagePath("fileTransferInstance/arrow_white.svg"))); -// ui->leftButton->setObjectName("resume"); -// ui->leftButton->setToolTip(tr("Resume transfer")); -// } else { -// ui->leftButton->setIcon(QIcon(Style::getImagePath("fileTransferInstance/pause.svg"))); -// ui->leftButton->setObjectName("pause"); -// ui->leftButton->setToolTip(tr("Pause transfer")); -// } - - ui->rightButton->setIcon(QIcon(Style::getImagePath("fileTransferInstance/no.svg"))); - ui->rightButton->setObjectName("cancel"); - ui->rightButton->setToolTip(tr("Cancel transfer")); - - setButtonColor(Style::getColor(Style::TransferMiddle)); - break; - - case FileStatus::INITIALIZING: - ui->rightButton->setIcon(QIcon(Style::getImagePath("fileTransferInstance/no.svg"))); - ui->rightButton->setObjectName("cancel"); - ui->rightButton->setToolTip(tr("Cancel transfer")); - - if (file.direction == FileDirection::SENDING) { + case FileStatus::TRANSMITTING: ui->leftButton->setIcon(QIcon(Style::getImagePath("fileTransferInstance/pause.svg"))); ui->leftButton->setObjectName("pause"); ui->leftButton->setToolTip(tr("Pause transfer")); - } else { + + ui->rightButton->setIcon(QIcon(Style::getImagePath("fileTransferInstance/no.svg"))); + ui->rightButton->setObjectName("cancel"); + ui->rightButton->setToolTip(tr("Cancel transfer")); + + setButtonColor(Style::getColor(Style::TransferGood)); + break; + + case FileStatus::PAUSED: + // if (file.pauseStatus.localPaused()) { + // ui->leftButton->setIcon(QIcon(Style::getImagePath("fileTransferInstance/arrow_white.svg"))); + // ui->leftButton->setObjectName("resume"); + // ui->leftButton->setToolTip(tr("Resume transfer")); + // } else { + // ui->leftButton->setIcon(QIcon(Style::getImagePath("fileTransferInstance/pause.svg"))); + // ui->leftButton->setObjectName("pause"); + // ui->leftButton->setToolTip(tr("Pause transfer")); + // } + + ui->rightButton->setIcon(QIcon(Style::getImagePath("fileTransferInstance/no.svg"))); + ui->rightButton->setObjectName("cancel"); + ui->rightButton->setToolTip(tr("Cancel transfer")); + + setButtonColor(Style::getColor(Style::TransferMiddle)); + break; + + case FileStatus::INITIALIZING: + ui->rightButton->setIcon(QIcon(Style::getImagePath("fileTransferInstance/no.svg"))); + ui->rightButton->setObjectName("cancel"); + ui->rightButton->setToolTip(tr("Cancel transfer")); + + if (file.direction == FileDirection::SENDING) { + ui->leftButton->setIcon( + QIcon(Style::getImagePath("fileTransferInstance/pause.svg"))); + ui->leftButton->setObjectName("pause"); + ui->leftButton->setToolTip(tr("Pause transfer")); + } else { + ui->leftButton->setIcon(QIcon(Style::getImagePath("fileTransferInstance/yes.svg"))); + ui->leftButton->setObjectName("accept"); + ui->leftButton->setToolTip(tr("Accept transfer")); + } + break; + case FileStatus::CANCELED: + case FileStatus::BROKEN: + ui->leftButton->hide(); + ui->rightButton->hide(); + break; + case FileStatus::FINISHED: ui->leftButton->setIcon(QIcon(Style::getImagePath("fileTransferInstance/yes.svg"))); - ui->leftButton->setObjectName("accept"); - ui->leftButton->setToolTip(tr("Accept transfer")); - } - break; - case FileStatus::CANCELED: - case FileStatus::BROKEN: - ui->leftButton->hide(); - ui->rightButton->hide(); - break; - case FileStatus::FINISHED: - ui->leftButton->setIcon(QIcon(Style::getImagePath("fileTransferInstance/yes.svg"))); - ui->leftButton->setObjectName("ok"); - ui->leftButton->setToolTip(tr("Open file")); - ui->leftButton->show(); - - ui->rightButton->setIcon(QIcon(Style::getImagePath("fileTransferInstance/dir.svg"))); - ui->rightButton->setObjectName("dir"); - ui->rightButton->setToolTip(tr("Open file directory")); - ui->rightButton->show(); - - break; - default: - qWarning() << "Invalid file status" << file.fileId; - break; + ui->leftButton->setObjectName("ok"); + ui->leftButton->setToolTip(tr("Open file")); + ui->leftButton->show(); + + ui->rightButton->setIcon(QIcon(Style::getImagePath("fileTransferInstance/dir.svg"))); + ui->rightButton->setObjectName("dir"); + ui->rightButton->setToolTip(tr("Open file directory")); + ui->rightButton->show(); + + break; + default: + qWarning() << "Invalid file status" << file.fileId; + break; } } -void FileTransferWidget::handleButton(QPushButton* btn) -{ +void FileTransferWidget::handleButton(QPushButton* btn) { CoreFile* coreFile = Core::getInstance()->getCoreFile(); - qDebug() <<"handle button for file:" << fileInfo.fileName; + qDebug() << "handle button for file:" << fileInfo.fileName; if (fileInfo.direction == FileDirection::SENDING) { if (btn->objectName() == "cancel") { coreFile->cancelFileSend(fileInfo.receiver, fileInfo.fileId); @@ -508,7 +486,7 @@ void FileTransferWidget::handleButton(QPushButton* btn) } else if (btn->objectName() == "resume") { coreFile->pauseResumeFile(fileInfo.receiver, fileInfo.fileId); } - } else // receiving or paused + } else // receiving or paused { if (btn->objectName() == "cancel") { coreFile->cancelFileRecv(fileInfo.receiver, fileInfo.fileId); @@ -517,12 +495,11 @@ void FileTransferWidget::handleButton(QPushButton* btn) } else if (btn->objectName() == "resume") { coreFile->pauseResumeFile(fileInfo.receiver, fileInfo.fileId); } else if (btn->objectName() == "accept") { - QString path = Settings::getInstance().getGlobalAutoAcceptDir() - + "/" + fileInfo.fileName; - if(path.isEmpty()) - return; + QString path = + Settings::getInstance().getGlobalAutoAcceptDir() + "/" + fileInfo.fileName; + if (path.isEmpty()) return; - qDebug() <<"accept file save to path:" << path; + qDebug() << "accept file save to path:" << path; acceptTransfer(path); } } @@ -535,8 +512,7 @@ void FileTransferWidget::handleButton(QPushButton* btn) } } -void FileTransferWidget::showPreview(const QString& filename) -{ +void FileTransferWidget::showPreview(const QString& filename) { qDebug() << __func__ << filename; static const QStringList previewExtensions = {"png", "jpeg", "jpg", "gif", "svg", @@ -553,12 +529,13 @@ void FileTransferWidget::showPreview(const QString& filename) auto imageFileData = imageFile.readAll(); auto image = QImage::fromData(imageFileData); - if(image.isNull()){ - qWarning() <<"Unable to read the image data!"; + if (image.isNull()) { + qWarning() << "Unable to read the image data!"; return; } - const int exifOrientation = getExifOrientation(imageFileData.constData(), imageFileData.size()); + const int exifOrientation = + getExifOrientation(imageFileData.constData(), imageFileData.size()); if (exifOrientation) { applyTransformation(exifOrientation, image); } @@ -588,27 +565,18 @@ void FileTransferWidget::showPreview(const QString& filename) buffer.open(QIODevice::WriteOnly); previewImage.save(&buffer, "PNG"); buffer.close(); - ui->previewButton->setToolTip(""); + ui->previewButton->setToolTip(""); } } -void FileTransferWidget::onLeftButtonClicked() -{ - handleButton(ui->leftButton); -} +void FileTransferWidget::onLeftButtonClicked() { handleButton(ui->leftButton); } -void FileTransferWidget::onRightButtonClicked() -{ - handleButton(ui->rightButton); -} +void FileTransferWidget::onRightButtonClicked() { handleButton(ui->rightButton); } -void FileTransferWidget::onPreviewButtonClicked() -{ - handleButton(ui->previewButton); -} +void FileTransferWidget::onPreviewButtonClicked() { handleButton(ui->previewButton); } -QPixmap FileTransferWidget::scaleCropIntoSquare(const QPixmap& source, const int targetSize) -{ +QPixmap FileTransferWidget::scaleCropIntoSquare(const QPixmap& source, const int targetSize) { QPixmap result; // Make sure smaller-than-icon images (at least one dimension is smaller) will not be @@ -632,9 +600,9 @@ QPixmap FileTransferWidget::scaleCropIntoSquare(const QPixmap& source, const int return result; } -int FileTransferWidget::getExifOrientation(const char* data, const int size) -{ - ExifData* exifData = exif_data_new_from_data(reinterpret_cast(data), size); +int FileTransferWidget::getExifOrientation(const char* data, const int size) { + ExifData* exifData = + exif_data_new_from_data(reinterpret_cast(data), size); if (!exifData) { return 0; @@ -650,43 +618,41 @@ int FileTransferWidget::getExifOrientation(const char* data, const int size) return orientation; } -void FileTransferWidget::applyTransformation(const int orientation, QImage& image) -{ +void FileTransferWidget::applyTransformation(const int orientation, QImage& image) { QTransform exifTransform; switch (static_cast(orientation)) { - case ExifOrientation::TopLeft: - break; - case ExifOrientation::TopRight: - image = image.mirrored(1, 0); - break; - case ExifOrientation::BottomRight: - exifTransform.rotate(180); - break; - case ExifOrientation::BottomLeft: - image = image.mirrored(0, 1); - break; - case ExifOrientation::LeftTop: - exifTransform.rotate(90); - image = image.mirrored(0, 1); - break; - case ExifOrientation::RightTop: - exifTransform.rotate(-90); - break; - case ExifOrientation::RightBottom: - exifTransform.rotate(-90); - image = image.mirrored(0, 1); - break; - case ExifOrientation::LeftBottom: - exifTransform.rotate(90); - break; - default: - qWarning() << "Invalid exif orientation passed to applyTransformation!"; + case ExifOrientation::TopLeft: + break; + case ExifOrientation::TopRight: + image = image.mirrored(1, 0); + break; + case ExifOrientation::BottomRight: + exifTransform.rotate(180); + break; + case ExifOrientation::BottomLeft: + image = image.mirrored(0, 1); + break; + case ExifOrientation::LeftTop: + exifTransform.rotate(90); + image = image.mirrored(0, 1); + break; + case ExifOrientation::RightTop: + exifTransform.rotate(-90); + break; + case ExifOrientation::RightBottom: + exifTransform.rotate(-90); + image = image.mirrored(0, 1); + break; + case ExifOrientation::LeftBottom: + exifTransform.rotate(90); + break; + default: + qWarning() << "Invalid exif orientation passed to applyTransformation!"; } image = image.transformed(exifTransform); } -void FileTransferWidget::updateWidget(ToxFile const& file) -{ +void FileTransferWidget::updateWidget(ToxFile const& file) { assert(file == fileInfo); fileInfo = file; @@ -705,13 +671,12 @@ void FileTransferWidget::updateWidget(ToxFile const& file) // trigger repaint switch (file.status) { - case FileStatus::TRANSMITTING: - if (!bTransmitNeedsUpdate) { - break; - } - // fallthrough - default: - update(); + case FileStatus::TRANSMITTING: + if (!bTransmitNeedsUpdate) { + break; + } + // fallthrough + default: + update(); } } - diff --git a/src/modules/im/src/chatlog/content/filetransferwidget.h b/src/modules/im/src/chatlog/content/filetransferwidget.h index f2a81f43..1b289754 100644 --- a/src/modules/im/src/chatlog/content/filetransferwidget.h +++ b/src/modules/im/src/chatlog/content/filetransferwidget.h @@ -20,7 +20,6 @@ #include "src/chatlog/toxfileprogress.h" #include "src/core/toxfile.h" - namespace Ui { class FileTransferWidget; } @@ -28,8 +27,7 @@ class FileTransferWidget; class QVariantAnimation; class QPushButton; -class FileTransferWidget : public QWidget -{ +class FileTransferWidget : public QWidget { Q_OBJECT public: @@ -66,7 +64,7 @@ private slots: static QPixmap scaleCropIntoSquare(const QPixmap& source, int targetSize); static int getExifOrientation(const char* data, const int size); static void applyTransformation(const int oritentation, QImage& image); - static bool tryRemoveFile(const QString &filepath); + static bool tryRemoveFile(const QString& filepath); void updateWidget(ToxFile const& file); @@ -83,8 +81,7 @@ private slots: bool active; FileStatus lastStatus; - enum class ExifOrientation - { + enum class ExifOrientation { /* do not change values, this is exif spec * * name corresponds to where the 0 row and 0 column is in form row-column @@ -103,4 +100,4 @@ private slots: }; }; -#endif // FILETRANSFERWIDGET_H +#endif // FILETRANSFERWIDGET_H diff --git a/src/modules/im/src/chatlog/content/image.cpp b/src/modules/im/src/chatlog/content/image.cpp index cb85a1a7..9b27cf9a 100644 --- a/src/modules/im/src/chatlog/content/image.cpp +++ b/src/modules/im/src/chatlog/content/image.cpp @@ -15,24 +15,17 @@ #include -Image::Image(QSize Size, const QString& filename) - : size(Size) -{ +Image::Image(QSize Size, const QString& filename) : size(Size) { pmap = PixmapCache::getInstance().get(filename, size); } -QRectF Image::boundingRect() const -{ +QRectF Image::boundingRect() const { return QRectF(QPointF(-size.width() / 2.0, -size.height() / 2.0), size); } -qreal Image::getAscent() const -{ - return 0.0; -} +qreal Image::getAscent() const { return 0.0; } -void Image::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) -{ +void Image::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { painter->setClipRect(boundingRect()); painter->setRenderHint(QPainter::SmoothPixmapTransform); @@ -43,7 +36,4 @@ void Image::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWi Q_UNUSED(widget) } -void Image::setWidth(qreal width) -{ - Q_UNUSED(width) -} +void Image::setWidth(qreal width) { Q_UNUSED(width) } diff --git a/src/modules/im/src/chatlog/content/image.h b/src/modules/im/src/chatlog/content/image.h index 7f6bdaaa..eff55f62 100644 --- a/src/modules/im/src/chatlog/content/image.h +++ b/src/modules/im/src/chatlog/content/image.h @@ -17,8 +17,7 @@ #include -class Image : public ChatLineContent -{ +class Image : public ChatLineContent { public: Image(QSize size, const QString& filename); @@ -33,4 +32,4 @@ class Image : public ChatLineContent QPixmap pmap; }; -#endif // IMAGE_H +#endif // IMAGE_H diff --git a/src/modules/im/src/chatlog/content/notificationicon.cpp b/src/modules/im/src/chatlog/content/notificationicon.cpp index fa4ff37c..c08f5975 100644 --- a/src/modules/im/src/chatlog/content/notificationicon.cpp +++ b/src/modules/im/src/chatlog/content/notificationicon.cpp @@ -18,9 +18,7 @@ #include #include -NotificationIcon::NotificationIcon(QSize Size) - : size(Size) -{ +NotificationIcon::NotificationIcon(QSize Size) : size(Size) { pmap = PixmapCache::getInstance().get(Style::getImagePath("chatArea/typing.svg"), size); updateTimer = new QTimer(this); @@ -32,13 +30,12 @@ NotificationIcon::NotificationIcon(QSize Size) connect(updateTimer, &QTimer::timeout, this, &NotificationIcon::updateGradient); } -QRectF NotificationIcon::boundingRect() const -{ +QRectF NotificationIcon::boundingRect() const { return QRectF(QPointF(-size.width() / 2.0, -size.height() / 2.0), size); } -void NotificationIcon::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) -{ +void NotificationIcon::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, + QWidget* widget) { painter->setClipRect(boundingRect()); painter->setRenderHint(QPainter::SmoothPixmapTransform); @@ -51,22 +48,14 @@ void NotificationIcon::paint(QPainter* painter, const QStyleOptionGraphicsItem* Q_UNUSED(widget) } -void NotificationIcon::setWidth(qreal width) -{ - Q_UNUSED(width) -} +void NotificationIcon::setWidth(qreal width) { Q_UNUSED(width) } -qreal NotificationIcon::getAscent() const -{ - return 3.0; -} +qreal NotificationIcon::getAscent() const { return 3.0; } -void NotificationIcon::updateGradient() -{ +void NotificationIcon::updateGradient() { alpha += 0.01; - if (alpha + dotWidth >= 1.0) - alpha = 0.0; + if (alpha + dotWidth >= 1.0) alpha = 0.0; grad = QLinearGradient(QPointF(-0.5 * size.width(), 0), QPointF(3.0 / 2.0 * size.width(), 0)); grad.setColorAt(0, Qt::lightGray); @@ -75,6 +64,5 @@ void NotificationIcon::updateGradient() grad.setColorAt(qMin(1.0, alpha + dotWidth), Qt::lightGray); grad.setColorAt(1, Qt::lightGray); - if (scene() && isVisible()) - scene()->invalidate(sceneBoundingRect()); + if (scene() && isVisible()) scene()->invalidate(sceneBoundingRect()); } diff --git a/src/modules/im/src/chatlog/content/notificationicon.h b/src/modules/im/src/chatlog/content/notificationicon.h index bf98cf69..ad2b07c4 100644 --- a/src/modules/im/src/chatlog/content/notificationicon.h +++ b/src/modules/im/src/chatlog/content/notificationicon.h @@ -20,8 +20,7 @@ class QTimer; -class NotificationIcon : public ChatLineContent -{ +class NotificationIcon : public ChatLineContent { Q_OBJECT public: explicit NotificationIcon(QSize size); @@ -45,4 +44,4 @@ private slots: qreal alpha = 0.0; }; -#endif // NOTIFICATIONICON_H +#endif // NOTIFICATIONICON_H diff --git a/src/modules/im/src/chatlog/content/simpletext.cpp b/src/modules/im/src/chatlog/content/simpletext.cpp index 2b1d8a64..85f71b07 100644 --- a/src/modules/im/src/chatlog/content/simpletext.cpp +++ b/src/modules/im/src/chatlog/content/simpletext.cpp @@ -1,32 +1,26 @@ #include "simpletext.h" #include -SimpleText::SimpleText(const QString &txt, const QFont &font) - : text(txt), defFont(font) { +SimpleText::SimpleText(const QString& txt, const QFont& font) : text(txt), defFont(font) { color = Style::getColor(colorRole); updateBoundingRect(); } -void SimpleText::setText(const QString &txt) { +void SimpleText::setText(const QString& txt) { if (text != txt) { text = txt; updateBoundingRect(); } } -QRectF SimpleText::boundingRect() const { - return QRectF(QPointF(0, 0), boundSize); -} +QRectF SimpleText::boundingRect() const { return QRectF(QPointF(0, 0), boundSize); } -void SimpleText::paint(QPainter *painter, - const QStyleOptionGraphicsItem *option, - QWidget *widget) { +void SimpleText::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { if (!text.isEmpty()) { painter->setFont(defFont); painter->setPen(QPen(color)); int y_offset = QFontMetricsF(defFont).leading() / 2.0; - painter->drawText(QRectF(QPointF(0, y_offset), boundSize), - Qt::AlignCenter, text); + painter->drawText(QRectF(QPointF(0, y_offset), boundSize), Qt::AlignCenter, text); } } @@ -40,15 +34,13 @@ void SimpleText::setWidth(qreal width) { } } -void SimpleText::setColor(Style::ColorPalette role) -{ +void SimpleText::setColor(Style::ColorPalette role) { customColor = false; colorRole = role; color = Style::getColor(colorRole); } -void SimpleText::setColor(const QColor &color) -{ +void SimpleText::setColor(const QColor& color) { customColor = true; this->color = color; } @@ -59,11 +51,9 @@ void SimpleText::updateBoundingRect() { boundSize = fm.boundingRect(text).size(); else boundSize = QSizeF(fm.height(), fm.height()); - if (forceWidth > 0) - boundSize.rwidth() = forceWidth; + if (forceWidth > 0) boundSize.rwidth() = forceWidth; } void SimpleText::reloadTheme() { - if (!customColor) - color = Style::getColor(colorRole); + if (!customColor) color = Style::getColor(colorRole); } diff --git a/src/modules/im/src/chatlog/content/simpletext.h b/src/modules/im/src/chatlog/content/simpletext.h index acf97602..62948f10 100644 --- a/src/modules/im/src/chatlog/content/simpletext.h +++ b/src/modules/im/src/chatlog/content/simpletext.h @@ -10,19 +10,17 @@ class SimpleText : public ChatLineContent { Q_OBJECT public: - SimpleText(const QString &txt = "", const QFont &font = QFont()); - ~SimpleText() { - } + SimpleText(const QString& txt = "", const QFont& font = QFont()); + ~SimpleText() {} - void setText(const QString &txt); + void setText(const QString& txt); QRectF boundingRect() const override; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, - QWidget *widget) override; + void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override; void setWidth(qreal width) override; void setColor(Style::ColorPalette role); - void setColor(const QColor &color); + void setColor(const QColor& color); private: void updateBoundingRect(); @@ -38,5 +36,4 @@ class SimpleText : public ChatLineContent { qreal forceWidth = -1; }; -#endif // !SIMPLETEXT_H - +#endif // !SIMPLETEXT_H diff --git a/src/modules/im/src/chatlog/content/spinner.cpp b/src/modules/im/src/chatlog/content/spinner.cpp index 8ce24f2c..7e3e0134 100644 --- a/src/modules/im/src/chatlog/content/spinner.cpp +++ b/src/modules/im/src/chatlog/content/spinner.cpp @@ -19,13 +19,10 @@ #include #include -Spinner::Spinner(const QString& img, QSize Size, qreal speed) - : size(Size) - , rotSpeed(speed) -{ +Spinner::Spinner(const QString& img, QSize Size, qreal speed) : size(Size), rotSpeed(speed) { pmap = PixmapCache::getInstance().get(img, size); - timer.setInterval(1000 / 30); // 30Hz + timer.setInterval(1000 / 30); // 30Hz timer.setSingleShot(false); blendAnimation = new QVariantAnimation(this); @@ -40,18 +37,17 @@ Spinner::Spinner(const QString& img, QSize Size, qreal speed) QObject::connect(&timer, &QTimer::timeout, this, &Spinner::timeout); } -QRectF Spinner::boundingRect() const -{ +QRectF Spinner::boundingRect() const { return QRectF(QPointF(-size.width() / 2.0, -size.height() / 2.0), size); } -void Spinner::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) -{ +void Spinner::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { painter->setClipRect(boundingRect()); - QTransform trans = QTransform() - .rotate(QTime::currentTime().msecsSinceStartOfDay() / 1000.0 * rotSpeed) - .translate(-size.width() / 2.0, -size.height() / 2.0); + QTransform trans = + QTransform() + .rotate(QTime::currentTime().msecsSinceStartOfDay() / 1000.0 * rotSpeed) + .translate(-size.width() / 2.0, -size.height() / 2.0); painter->setOpacity(alpha); painter->setTransform(trans, true); painter->setRenderHint(QPainter::SmoothPixmapTransform); @@ -61,26 +57,17 @@ void Spinner::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, Q Q_UNUSED(widget) } -void Spinner::setWidth(qreal width) -{ - Q_UNUSED(width) -} +void Spinner::setWidth(qreal width) { Q_UNUSED(width) } -void Spinner::visibilityChanged(bool visible) -{ +void Spinner::visibilityChanged(bool visible) { if (visible) timer.start(); else timer.stop(); } -qreal Spinner::getAscent() const -{ - return 0.0; -} +qreal Spinner::getAscent() const { return 0.0; } -void Spinner::timeout() -{ - if (scene()) - scene()->invalidate(sceneBoundingRect()); +void Spinner::timeout() { + if (scene()) scene()->invalidate(sceneBoundingRect()); } diff --git a/src/modules/im/src/chatlog/content/spinner.h b/src/modules/im/src/chatlog/content/spinner.h index 7a09de89..e2bf6e92 100644 --- a/src/modules/im/src/chatlog/content/spinner.h +++ b/src/modules/im/src/chatlog/content/spinner.h @@ -21,8 +21,7 @@ class QVariantAnimation; -class Spinner : public ChatLineContent -{ +class Spinner : public ChatLineContent { Q_OBJECT public: Spinner(const QString& img, QSize size, qreal speed); @@ -46,4 +45,4 @@ private slots: QVariantAnimation* blendAnimation; }; -#endif // SPINNER_H +#endif // SPINNER_H diff --git a/src/modules/im/src/chatlog/content/text.cpp b/src/modules/im/src/chatlog/content/text.cpp index c4ffb80c..291941f2 100644 --- a/src/modules/im/src/chatlog/content/text.cpp +++ b/src/modules/im/src/chatlog/content/text.cpp @@ -25,35 +25,28 @@ #include Text::Text(const QString& txt, const QFont& font, bool enableElide, const QString& rwText) - : rawText(rwText) - , elide(enableElide) - , defFont(font) - , defStyleSheet(Style::getStylesheet(QStringLiteral("chatArea/innerStyle.css"), font)) -{ + : rawText(rwText) + , elide(enableElide) + , defFont(font) + , defStyleSheet(Style::getStylesheet(QStringLiteral("chatArea/innerStyle.css"), font)) { color = textColor(); setText(txt); setAcceptedMouseButtons(Qt::LeftButton); setAcceptHoverEvents(true); } -Text::~Text() -{ - if (doc) - DocumentCache::getInstance().push(doc); +Text::~Text() { + if (doc) DocumentCache::getInstance().push(doc); } -void Text::setTextSelectable(bool selectable) -{ - this->selectable = selectable; -} +void Text::setTextSelectable(bool selectable) { this->selectable = selectable; } -void Text::setText(const QString &txt) { +void Text::setText(const QString& txt) { text = txt; dirty = true; } -void Text::selectText(const QString& txt, const std::pair& point) -{ +void Text::selectText(const QString& txt, const std::pair& point) { regenerate(); if (!doc || !selectable) { @@ -65,8 +58,7 @@ void Text::selectText(const QString& txt, const std::pair& point) selectText(cursor, point); } -void Text::selectText(const QRegularExpression &exp, const std::pair& point) -{ +void Text::selectText(const QRegularExpression& exp, const std::pair& point) { regenerate(); if (!doc || !selectable) { @@ -78,25 +70,21 @@ void Text::selectText(const QRegularExpression &exp, const std::pair& selectText(cursor, point); } -void Text::deselectText() -{ +void Text::deselectText() { dirty = true; regenerate(); update(); } -void Text::setWidth(qreal w) -{ +void Text::setWidth(qreal w) { width = w; dirty = true; regenerate(); } -void Text::selectionMouseMove(QPointF scenePos) -{ - if (!doc || !selectable) - return; +void Text::selectionMouseMove(QPointF scenePos) { + if (!doc || !selectable) return; int cur = cursorFromPos(scenePos); if (cur >= 0) { @@ -107,8 +95,7 @@ void Text::selectionMouseMove(QPointF scenePos) update(); } -void Text::selectionStarted(QPointF scenePos) -{ +void Text::selectionStarted(QPointF scenePos) { int cur = cursorFromPos(scenePos); if (cur >= 0) { selectionEnd = cur; @@ -116,8 +103,7 @@ void Text::selectionStarted(QPointF scenePos) } } -void Text::selectionCleared() -{ +void Text::selectionCleared() { selectedText.clear(); selectedText.squeeze(); @@ -127,10 +113,8 @@ void Text::selectionCleared() update(); } -void Text::selectionDoubleClick(QPointF scenePos) -{ - if (!doc) - return; +void Text::selectionDoubleClick(QPointF scenePos) { + if (!doc) return; int cur = cursorFromPos(scenePos); @@ -148,10 +132,8 @@ void Text::selectionDoubleClick(QPointF scenePos) update(); } -void Text::selectionTripleClick(QPointF scenePos) -{ - if (!doc) - return; +void Text::selectionTripleClick(QPointF scenePos) { + if (!doc) return; int cur = cursorFromPos(scenePos); @@ -163,8 +145,7 @@ void Text::selectionTripleClick(QPointF scenePos) selectionAnchor = cursor.selectionStart(); selectionEnd = cursor.selectionEnd(); - if (cursor.block().isValid() && cursor.block().blockNumber() != 0) - selectionAnchor++; + if (cursor.block().isValid() && cursor.block().blockNumber() != 0) selectionAnchor++; selectedText = extractSanitizedText(getSelectionStart(), getSelectionEnd()); } @@ -172,16 +153,13 @@ void Text::selectionTripleClick(QPointF scenePos) update(); } -void Text::selectionFocusChanged(bool focusIn) -{ +void Text::selectionFocusChanged(bool focusIn) { selectionHasFocus = focusIn; update(); } -void Text::selectAll() -{ - if (!doc) - return; +void Text::selectAll() { + if (!doc) return; QTextCursor cursor(doc); cursor.setPosition(0); @@ -192,52 +170,37 @@ void Text::selectAll() update(); } -bool Text::isOverSelection(QPointF scenePos) const -{ +bool Text::isOverSelection(QPointF scenePos) const { int cur = cursorFromPos(scenePos); - if (getSelectionStart() < cur && getSelectionEnd() >= cur) - return true; + if (getSelectionStart() < cur && getSelectionEnd() >= cur) return true; return false; } -QString Text::getSelectedText() const -{ - return selectedText; -} +QString Text::getSelectedText() const { return selectedText; } -void Text::fontChanged(const QFont& font) -{ - defFont = font; -} +void Text::fontChanged(const QFont& font) { defFont = font; } -QRectF Text::boundingRect() const -{ - return QRectF(QPointF(0, 0), size + QSize(margins.left() + margins.right(), - margins.top() + margins.bottom())); +QRectF Text::boundingRect() const { + return QRectF(QPointF(0, 0), + size + QSize(margins.left() + margins.right(), margins.top() + margins.bottom())); } -void Text::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) -{ +void Text::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { Q_UNUSED(option); Q_UNUSED(widget); - if (!doc) - return; + if (!doc) return; painter->setRenderHint(QPainter::Antialiasing); - if (backgroundColor.isValid()) - { + if (backgroundColor.isValid()) { painter->save(); painter->translate(0.5, 0.5); - if (boundRadius > 0) - { + if (boundRadius > 0) { QPainterPath path; path.addRoundedRect(boundingRect(), boundRadius, boundRadius); painter->fillPath(path, backgroundColor); - } - else - { + } else { painter->fillRect(boundingRect(), backgroundColor); } painter->restore(); @@ -268,16 +231,14 @@ void Text::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWid painter->restore(); } -void Text::visibilityChanged(bool visible) -{ +void Text::visibilityChanged(bool visible) { keepInMemory = visible; regenerate(); update(); } -void Text::reloadTheme() -{ +void Text::reloadTheme() { defStyleSheet = Style::getStylesheet(QStringLiteral("chatArea/innerStyle.css"), defFont); color = textColor(); dirty = true; @@ -285,33 +246,23 @@ void Text::reloadTheme() update(); } -qreal Text::getAscent() const -{ - return ascent; -} +qreal Text::getAscent() const { return ascent; } -void Text::mousePressEvent(QGraphicsSceneMouseEvent* event) -{ - if (event->button() == Qt::LeftButton) - event->accept(); // grabber +void Text::mousePressEvent(QGraphicsSceneMouseEvent* event) { + if (event->button() == Qt::LeftButton) event->accept(); // grabber } -void Text::mouseReleaseEvent(QGraphicsSceneMouseEvent* event) -{ - if (!doc) - return; +void Text::mouseReleaseEvent(QGraphicsSceneMouseEvent* event) { + if (!doc) return; QString anchor = doc->documentLayout()->anchorAt(event->pos()); // open anchor in browser - if (!anchor.isEmpty()) - QDesktopServices::openUrl(anchor); + if (!anchor.isEmpty()) QDesktopServices::openUrl(anchor); } -void Text::hoverMoveEvent(QGraphicsSceneHoverEvent* event) -{ - if (!doc) - return; +void Text::hoverMoveEvent(QGraphicsSceneHoverEvent* event) { + if (!doc) return; QString anchor = doc->documentLayout()->anchorAt(event->pos()); @@ -324,50 +275,37 @@ void Text::hoverMoveEvent(QGraphicsSceneHoverEvent* event) setToolTip(extractImgTooltip(cursorFromPos(event->scenePos(), false))); } -QString Text::getText() const -{ - return rawText; -} +QString Text::getText() const { return rawText; } /** * @brief Extracts the target of a link from the text at a given coordinate * @param scenePos Position in scene coordinates * @return The link target URL, or an empty string if there is no link there */ -QString Text::getLinkAt(QPointF scenePos) const -{ +QString Text::getLinkAt(QPointF scenePos) const { QTextCursor cursor(doc); cursor.setPosition(cursorFromPos(scenePos)); return cursor.charFormat().anchorHref(); } -void Text::setContentsMargins(QMarginsF margins) -{ - this->margins = margins; -} +void Text::setContentsMargins(QMarginsF margins) { this->margins = margins; } -void Text::setBoundingRadius(qreal radius) -{ - if (boundRadius != radius) - { +void Text::setBoundingRadius(qreal radius) { + if (boundRadius != radius) { boundRadius = radius; update(); } } -void Text::setBackgroundColor(const QColor &color) -{ - if (backgroundColor != color) - { +void Text::setBackgroundColor(const QColor& color) { + if (backgroundColor != color) { backgroundColor = color; update(); } } -void Text::setColor(Style::ColorPalette role) -{ - if (isCustomColor || colorRole != role) - { +void Text::setColor(Style::ColorPalette role) { + if (isCustomColor || colorRole != role) { isCustomColor = false; colorRole = role; color = textColor(); @@ -375,18 +313,15 @@ void Text::setColor(Style::ColorPalette role) } } -void Text::setColor(const QColor &color) -{ - if (!isCustomColor || this->color != color) - { +void Text::setColor(const QColor& color) { + if (!isCustomColor || this->color != color) { isCustomColor = true; this->color = color; update(); } } -void Text::regenerate() -{ +void Text::regenerate() { if (!doc) { doc = DocumentCache::getInstance().pop(); dirty = true; @@ -419,8 +354,7 @@ void Text::regenerate() ascent = doc->firstBlock().layout()->lineAt(0).ascent(); // let the scene know about our change in size - if (size != idealSize()) - prepareGeometryChange(); + if (size != idealSize()) prepareGeometryChange(); // get the new width and height size = idealSize(); @@ -429,58 +363,41 @@ void Text::regenerate() } // if we are not visible -> free mem - if (!keepInMemory) - freeResources(); + if (!keepInMemory) freeResources(); } -void Text::freeResources() -{ +void Text::freeResources() { DocumentCache::getInstance().push(doc); doc = nullptr; } -QSizeF Text::idealSize() -{ - if (doc) - return doc->size(); +QSizeF Text::idealSize() { + if (doc) return doc->size(); return size; } -int Text::cursorFromPos(QPointF scenePos, bool fuzzy) const -{ - if (doc) - { +int Text::cursorFromPos(QPointF scenePos, bool fuzzy) const { + if (doc) { QPointF pos = mapFromScene(scenePos); QRectF rect = this->boundingRect(); - if (rect.contains(pos)) - { - pos.ry() = qBound(rect.top() + margins.top() + 1, pos.y(), rect.bottom() - margins.bottom() - 1); + if (rect.contains(pos)) { + pos.ry() = qBound( + rect.top() + margins.top() + 1, pos.y(), rect.bottom() - margins.bottom() - 1); } return doc->documentLayout()->hitTest(pos, fuzzy ? Qt::FuzzyHit : Qt::ExactHit); } return -1; } -int Text::getSelectionEnd() const -{ - return qMax(selectionAnchor, selectionEnd); -} +int Text::getSelectionEnd() const { return qMax(selectionAnchor, selectionEnd); } -int Text::getSelectionStart() const -{ - return qMin(selectionAnchor, selectionEnd); -} +int Text::getSelectionStart() const { return qMin(selectionAnchor, selectionEnd); } -bool Text::hasSelection() const -{ - return selectionEnd >= 0; -} +bool Text::hasSelection() const { return selectionEnd >= 0; } -QString Text::extractSanitizedText(int from, int to) const -{ - if (!doc) - return ""; +QString Text::extractSanitizedText(int from, int to) const { + if (!doc) return ""; QString txt; @@ -488,12 +405,12 @@ QString Text::extractSanitizedText(int from, int to) const QTextBlock end = doc->findBlock(to); for (QTextBlock block = begin; block != end.next() && block.isValid(); block = block.next()) { for (QTextBlock::Iterator itr = block.begin(); itr != block.end(); ++itr) { - int pos = itr.fragment().position(); // fragment position -> position of the first - // character in the fragment + int pos = itr.fragment().position(); // fragment position -> position of the first + // character in the fragment if (itr.fragment().charFormat().isImageFormat()) { QTextImageFormat imgFmt = itr.fragment().charFormat().toImageFormat(); - QString key = imgFmt.name(); // img key (eg. key::D for :D) + QString key = imgFmt.name(); // img key (eg. key::D for :D) QString rune = key.mid(4); if (pos >= from && pos < to) { @@ -502,8 +419,7 @@ QString Text::extractSanitizedText(int from, int to) const } } else { for (QChar c : itr.fragment().text()) { - if (pos >= from && pos < to) - txt += c; + if (pos >= from && pos < to) txt += c; ++pos; } @@ -518,9 +434,9 @@ QString Text::extractSanitizedText(int from, int to) const return txt; } -QString Text::extractImgTooltip(int pos) const -{ - for (QTextBlock::Iterator itr = doc->firstBlock().begin(); itr != doc->firstBlock().end(); ++itr) { +QString Text::extractImgTooltip(int pos) const { + for (QTextBlock::Iterator itr = doc->firstBlock().begin(); itr != doc->firstBlock().end(); + ++itr) { if (itr.fragment().contains(pos) && itr.fragment().charFormat().isImageFormat()) { QTextImageFormat imgFmt = itr.fragment().charFormat().toImageFormat(); return imgFmt.toolTip(); @@ -530,8 +446,7 @@ QString Text::extractImgTooltip(int pos) const return QString(); } -void Text::selectText(QTextCursor& cursor, const std::pair& point) -{ +void Text::selectText(QTextCursor& cursor, const std::pair& point) { if (!cursor.isNull()) { cursor.beginEditBlock(); cursor.setPosition(point.first); @@ -547,7 +462,4 @@ void Text::selectText(QTextCursor& cursor, const std::pair& point) } } -QColor Text::textColor() const -{ - return isCustomColor ? color : Style::getColor(colorRole); -} \ No newline at end of file +QColor Text::textColor() const { return isCustomColor ? color : Style::getColor(colorRole); } \ No newline at end of file diff --git a/src/modules/im/src/chatlog/content/text.h b/src/modules/im/src/chatlog/content/text.h index c721979a..dd12b5f5 100644 --- a/src/modules/im/src/chatlog/content/text.h +++ b/src/modules/im/src/chatlog/content/text.h @@ -20,12 +20,10 @@ class QTextDocument; -class Text : public ChatLineContent -{ +class Text : public ChatLineContent { Q_OBJECT public: - Text(const QString& txt = "", const QFont& font = QFont(), bool enableElide = false, const QString& rawText = QString()); virtual ~Text(); @@ -50,7 +48,8 @@ class Text : public ChatLineContent virtual void fontChanged(const QFont& font) final; virtual QRectF boundingRect() const final; - virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) final; + virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, + QWidget* widget) final; virtual void visibilityChanged(bool keepInMemory) final; virtual void reloadTheme() final override; @@ -58,7 +57,7 @@ class Text : public ChatLineContent virtual qreal getAscent() const final; virtual void mousePressEvent(QGraphicsSceneMouseEvent* event) final override; virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent* event) final override; - void hoverMoveEvent(QGraphicsSceneHoverEvent* event) final override; + void hoverMoveEvent(QGraphicsSceneHoverEvent* event) final override; virtual QString getText() const final; QString getLinkAt(QPointF scenePos) const; @@ -66,9 +65,9 @@ class Text : public ChatLineContent void setContentsMargins(QMarginsF margins); void setBoundingRadius(qreal radius); - void setBackgroundColor(const QColor &color); + void setBackgroundColor(const QColor& color); void setColor(Style::ColorPalette role); - void setColor(const QColor &color); + void setColor(const QColor& color); protected: // dynamic resource management @@ -103,7 +102,7 @@ class Text : public ChatLineContent qreal ascent = 0.0; QFont defFont; QString defStyleSheet; - + QColor backgroundColor; bool isCustomColor = false; Style::ColorPalette colorRole = Style::MainText; @@ -114,4 +113,4 @@ class Text : public ChatLineContent bool selectable = true; }; -#endif // TEXT_H +#endif // TEXT_H diff --git a/src/modules/im/src/chatlog/content/timestamp.cpp b/src/modules/im/src/chatlog/content/timestamp.cpp index 4abb50d1..eab62d8b 100644 --- a/src/modules/im/src/chatlog/content/timestamp.cpp +++ b/src/modules/im/src/chatlog/content/timestamp.cpp @@ -13,18 +13,13 @@ #include "timestamp.h" Timestamp::Timestamp(const QDateTime& time, const QString& format, const QFont& font) - : Text(time.toString(format), font, false, time.toString(format)) -{ - this->time = time; + : Text(time.toString(format), font, false, time.toString(format)) { + this->time = time; } -QDateTime Timestamp::getTime() -{ - return time; -} +QDateTime Timestamp::getTime() { return time; } -QSizeF Timestamp::idealSize() -{ +QSizeF Timestamp::idealSize() { if (doc) { return QSizeF(qMin(doc->idealWidth(), width), doc->size().height()); } diff --git a/src/modules/im/src/chatlog/content/timestamp.h b/src/modules/im/src/chatlog/content/timestamp.h index d0183687..14130c9e 100644 --- a/src/modules/im/src/chatlog/content/timestamp.h +++ b/src/modules/im/src/chatlog/content/timestamp.h @@ -13,14 +13,13 @@ #ifndef TIMESTAMP_H #define TIMESTAMP_H -#include "text.h" #include #include +#include "text.h" class QTextDocument; -class Timestamp : public Text -{ +class Timestamp : public Text { Q_OBJECT public: Timestamp(const QDateTime& time, const QString& format, const QFont& font); @@ -33,4 +32,4 @@ class Timestamp : public Text QDateTime time; }; -#endif // TIMESTAMP_H +#endif // TIMESTAMP_H diff --git a/src/modules/im/src/chatlog/customtextdocument.cpp b/src/modules/im/src/chatlog/customtextdocument.cpp index fe5cfe0f..b23e372f 100644 --- a/src/modules/im/src/chatlog/customtextdocument.cpp +++ b/src/modules/im/src/chatlog/customtextdocument.cpp @@ -19,15 +19,12 @@ #include #include -CustomTextDocument::CustomTextDocument(QObject* parent) - : QTextDocument(parent) -{ +CustomTextDocument::CustomTextDocument(QObject* parent) : QTextDocument(parent) { setUndoRedoEnabled(false); setUseDesignMetrics(false); } -QVariant CustomTextDocument::loadResource(int type, const QUrl& name) -{ +QVariant CustomTextDocument::loadResource(int type, const QUrl& name) { if (type == QTextDocument::ImageResource && name.scheme() == "key") { QSize size = QSize(Settings::getInstance().getEmojiFontPointSize(), Settings::getInstance().getEmojiFontPointSize()); diff --git a/src/modules/im/src/chatlog/customtextdocument.h b/src/modules/im/src/chatlog/customtextdocument.h index 6acf2a57..7f7390cb 100644 --- a/src/modules/im/src/chatlog/customtextdocument.h +++ b/src/modules/im/src/chatlog/customtextdocument.h @@ -13,15 +13,14 @@ #ifndef CUSTOMTEXTDOCUMENT_H #define CUSTOMTEXTDOCUMENT_H -#include #include +#include #include class QIcon; -class CustomTextDocument : public QTextDocument -{ +class CustomTextDocument : public QTextDocument { Q_OBJECT public: explicit CustomTextDocument(QObject* parent = nullptr); @@ -33,4 +32,4 @@ class CustomTextDocument : public QTextDocument QList> emoticonIcons; }; -#endif // CUSTOMTEXTDOCUMENT_H +#endif // CUSTOMTEXTDOCUMENT_H diff --git a/src/modules/im/src/chatlog/documentcache.cpp b/src/modules/im/src/chatlog/documentcache.cpp index 041d15e6..15b57d1f 100644 --- a/src/modules/im/src/chatlog/documentcache.cpp +++ b/src/modules/im/src/chatlog/documentcache.cpp @@ -13,22 +13,17 @@ #include "documentcache.h" #include "customtextdocument.h" -DocumentCache::~DocumentCache() -{ - while (!documents.isEmpty()) - delete documents.pop(); +DocumentCache::~DocumentCache() { + while (!documents.isEmpty()) delete documents.pop(); } -QTextDocument* DocumentCache::pop() -{ - if (documents.empty()) - documents.push(new CustomTextDocument); +QTextDocument* DocumentCache::pop() { + if (documents.empty()) documents.push(new CustomTextDocument); return documents.pop(); } -void DocumentCache::push(QTextDocument* doc) -{ +void DocumentCache::push(QTextDocument* doc) { if (doc) { doc->clear(); documents.push(doc); @@ -38,8 +33,7 @@ void DocumentCache::push(QTextDocument* doc) /** * @brief Returns the singleton instance. */ -DocumentCache& DocumentCache::getInstance() -{ +DocumentCache& DocumentCache::getInstance() { static DocumentCache instance; return instance; } diff --git a/src/modules/im/src/chatlog/documentcache.h b/src/modules/im/src/chatlog/documentcache.h index a9188ea1..a96ef7fb 100644 --- a/src/modules/im/src/chatlog/documentcache.h +++ b/src/modules/im/src/chatlog/documentcache.h @@ -17,8 +17,7 @@ class QTextDocument; -class DocumentCache -{ +class DocumentCache { public: static DocumentCache& getInstance(); @@ -35,4 +34,4 @@ class DocumentCache QStack documents; }; -#endif // DOCUMENTCACHE_H +#endif // DOCUMENTCACHE_H diff --git a/src/modules/im/src/chatlog/pixmapcache.cpp b/src/modules/im/src/chatlog/pixmapcache.cpp index 68dda3bd..819f958b 100644 --- a/src/modules/im/src/chatlog/pixmapcache.cpp +++ b/src/modules/im/src/chatlog/pixmapcache.cpp @@ -12,8 +12,7 @@ #include "pixmapcache.h" -QPixmap PixmapCache::get(const QString& filename, QSize size) -{ +QPixmap PixmapCache::get(const QString& filename, QSize size) { auto itr = cache.find(filename); if (itr == cache.end()) { @@ -30,8 +29,7 @@ QPixmap PixmapCache::get(const QString& filename, QSize size) /** * @brief Returns the singleton instance. */ -PixmapCache& PixmapCache::getInstance() -{ +PixmapCache& PixmapCache::getInstance() { static PixmapCache instance; return instance; } diff --git a/src/modules/im/src/chatlog/pixmapcache.h b/src/modules/im/src/chatlog/pixmapcache.h index 96b57f7e..ef86b0da 100644 --- a/src/modules/im/src/chatlog/pixmapcache.h +++ b/src/modules/im/src/chatlog/pixmapcache.h @@ -17,16 +17,13 @@ #include #include -class PixmapCache -{ +class PixmapCache { public: QPixmap get(const QString& filename, QSize size); static PixmapCache& getInstance(); protected: - PixmapCache() - { - } + PixmapCache() {} PixmapCache(PixmapCache&) = delete; PixmapCache& operator=(const PixmapCache&) = delete; @@ -34,4 +31,4 @@ class PixmapCache QHash cache; }; -#endif // ICONCACHE_H +#endif // ICONCACHE_H diff --git a/src/modules/im/src/chatlog/textformatter.cpp b/src/modules/im/src/chatlog/textformatter.cpp index 881eaf51..2ba2f9ea 100644 --- a/src/modules/im/src/chatlog/textformatter.cpp +++ b/src/modules/im/src/chatlog/textformatter.cpp @@ -85,7 +85,6 @@ static const QVector URI_WORD_PATTERNS = { QRegularExpression(QStringLiteral(R"((?<=^|\s)\S*(magnet:[?]((xt(.\d)?=urn:)|(mt=)|(kt=)|(tr=)|(dn=)|(xl=)|(xs=)|(as=)|(x.))[\S| ]+))")), }; - // clang-format on struct MatchingUri { @@ -94,40 +93,33 @@ struct MatchingUri { }; // pairs of characters that are ignored when surrounding a URI -static const QPair URI_WRAPPING_CHARS[] = { - {QString("("), QString(")")}, - {QString("["), QString("]")}, - {QString("""), QString(""")}, - {QString("'"), QString("'")} -}; +static const QPair URI_WRAPPING_CHARS[] = {{QString("("), QString(")")}, + {QString("["), QString("]")}, + {QString("""), QString(""")}, + {QString("'"), QString("'")}}; // characters which are ignored from the end of URI -static const QChar URI_ENDING_CHARS[] = { - QChar::fromLatin1('?'), - QChar::fromLatin1('.'), - QChar::fromLatin1('!'), - QChar::fromLatin1(':'), - QChar::fromLatin1(',') -}; +static const QChar URI_ENDING_CHARS[] = {QChar::fromLatin1('?'), QChar::fromLatin1('.'), + QChar::fromLatin1('!'), QChar::fromLatin1(':'), + QChar::fromLatin1(',')}; /** * @brief Strips wrapping characters and ending punctuation from URI * @param QRegularExpressionMatch of a word containing a URI * @return MatchingUri containing info on the stripped URI */ -MatchingUri stripSurroundingChars(const QStringRef wrappedUri, const int startOfBareUri) -{ +MatchingUri stripSurroundingChars(const QStringRef wrappedUri, const int startOfBareUri) { bool matchFound; int curValidationStartPos = 0; int curValidationEndPos = wrappedUri.length(); do { matchFound = false; - for (auto const& surroundChars : URI_WRAPPING_CHARS) - { + for (auto const& surroundChars : URI_WRAPPING_CHARS) { const int openingCharLength = surroundChars.first.length(); const int closingCharLength = surroundChars.second.length(); if (surroundChars.first == wrappedUri.mid(curValidationStartPos, openingCharLength) && - surroundChars.second == wrappedUri.mid(curValidationEndPos - closingCharLength, closingCharLength)) { + surroundChars.second == wrappedUri.mid(curValidationEndPos - closingCharLength, + closingCharLength)) { curValidationStartPos += openingCharLength; curValidationEndPos -= closingCharLength; matchFound = true; @@ -161,8 +153,9 @@ MatchingUri stripSurroundingChars(const QStringRef wrappedUri, const int startOf * @note done separately from URI since the link must have a scheme added to be valid * @return Copy of message with highlighted URLs */ -QString highlight(const QString& message, const QVector& patterns, const QString& wrapper) -{ +QString highlight(const QString& message, + const QVector& patterns, + const QString& wrapper) { QString result = message; for (const QRegularExpression& exp : patterns) { const int startLength = result.length(); @@ -172,13 +165,17 @@ QString highlight(const QString& message, const QVector& pat const QRegularExpressionMatch match = iter.next(); const int uriWithWrapMatch{0}; const int uriWithoutWrapMatch{1}; - MatchingUri matchUri = stripSurroundingChars(match.capturedRef(uriWithWrapMatch), - match.capturedStart(uriWithoutWrapMatch) - match.capturedStart(uriWithWrapMatch)); + MatchingUri matchUri = + stripSurroundingChars(match.capturedRef(uriWithWrapMatch), + match.capturedStart(uriWithoutWrapMatch) - + match.capturedStart(uriWithWrapMatch)); if (!matchUri.valid) { continue; } - const QString wrappedURL = wrapper.arg(match.captured(uriWithoutWrapMatch).left(matchUri.length)); - result.replace(match.capturedStart(uriWithoutWrapMatch) + offset, matchUri.length, wrappedURL); + const QString wrappedURL = + wrapper.arg(match.captured(uriWithoutWrapMatch).left(matchUri.length)); + result.replace( + match.capturedStart(uriWithoutWrapMatch) + offset, matchUri.length, wrappedURL); offset = result.length() - startLength; } } @@ -190,8 +187,7 @@ QString highlight(const QString& message, const QVector& pat * @param message Where search for URLs * @return Copy of message with highlighted URLs */ -QString highlightURI(const QString& message) -{ +QString highlightURI(const QString& message) { QString result = highlight(message, URI_WORD_PATTERNS, HREF_WRAPPER); result = highlight(result, WWW_WORD_PATTERN, WWW_WRAPPER); return result; @@ -202,8 +198,7 @@ QString highlightURI(const QString& message) * @param str Checking string * @return True, if tag intersection detected */ -static bool isTagIntersection(const QString& str) -{ +static bool isTagIntersection(const QString& str) { const QRegularExpression TAG_PATTERN("(?<=<)/?[a-zA-Z0-9]+(?=>)"); int openingTagCount = 0; @@ -223,8 +218,7 @@ static bool isTagIntersection(const QString& str) * string * @return Copy of message with markdown applied */ -QString applyMarkdown(const QString& message, bool showFormattingSymbols) -{ +QString applyMarkdown(const QString& message, bool showFormattingSymbols) { QString result = message; for (const QPair& pair : REGEX_TO_WRAPPER) { QRegularExpressionMatchIterator iter = pair.first.globalMatch(result); diff --git a/src/modules/im/src/chatlog/textformatter.h b/src/modules/im/src/chatlog/textformatter.h index 20d56841..954e3e29 100644 --- a/src/modules/im/src/chatlog/textformatter.h +++ b/src/modules/im/src/chatlog/textformatter.h @@ -19,4 +19,4 @@ QString highlightURI(const QString& message); QString applyMarkdown(const QString& message, bool showFormattingSymbols); -#endif // TEXTFORMATTER_H +#endif // TEXTFORMATTER_H diff --git a/src/modules/im/src/chatlog/toxfileprogress.cpp b/src/modules/im/src/chatlog/toxfileprogress.cpp index affb1439..dabc06a5 100644 --- a/src/modules/im/src/chatlog/toxfileprogress.cpp +++ b/src/modules/im/src/chatlog/toxfileprogress.cpp @@ -14,10 +14,9 @@ #include "src/core/toxfile.h" -bool ToxFileProgress::needsUpdate() const -{ +bool ToxFileProgress::needsUpdate() const { QTime now = QTime::currentTime(); - qint64 dt = lastTick.msecsTo(now); // ms + qint64 dt = lastTick.msecsTo(now); // ms if (dt < 1000) { return false; @@ -26,10 +25,9 @@ bool ToxFileProgress::needsUpdate() const return true; } -void ToxFileProgress::addSample(ToxFile const& file) -{ +void ToxFileProgress::addSample(ToxFile const& file) { QTime now = QTime::currentTime(); - qint64 dt = lastTick.msecsTo(now); // ms + qint64 dt = lastTick.msecsTo(now); // ms if (dt < 1000) { return; @@ -62,25 +60,15 @@ void ToxFileProgress::addSample(ToxFile const& file) lastBytesSent = file.bytesSent; } -void ToxFileProgress::resetSpeed() -{ +void ToxFileProgress::resetSpeed() { meanIndex = 0; for (auto& item : meanData) { item = 0; } } -double ToxFileProgress::getProgress() const -{ - return progress; -} +double ToxFileProgress::getProgress() const { return progress; } -double ToxFileProgress::getSpeed() const -{ - return speedBytesPerSecond; -} +double ToxFileProgress::getSpeed() const { return speedBytesPerSecond; } -double ToxFileProgress::getTimeLeftSeconds() const -{ - return timeLeftSeconds; -} +double ToxFileProgress::getTimeLeftSeconds() const { return timeLeftSeconds; } diff --git a/src/modules/im/src/chatlog/toxfileprogress.h b/src/modules/im/src/chatlog/toxfileprogress.h index 4b272a1b..4d8b7b8c 100644 --- a/src/modules/im/src/chatlog/toxfileprogress.h +++ b/src/modules/im/src/chatlog/toxfileprogress.h @@ -17,8 +17,7 @@ struct ToxFile; -class ToxFileProgress -{ +class ToxFileProgress { public: bool needsUpdate() const; void addSample(ToxFile const& file); @@ -42,5 +41,4 @@ class ToxFileProgress double progress; }; - -#endif // TOXFILEPROGRESS_H +#endif // TOXFILEPROGRESS_H diff --git a/src/modules/im/src/core/FriendId.cpp b/src/modules/im/src/core/FriendId.cpp index 80786f02..1a384114 100644 --- a/src/modules/im/src/core/FriendId.cpp +++ b/src/modules/im/src/core/FriendId.cpp @@ -13,9 +13,9 @@ #include "FriendId.h" #include -#include #include #include +#include #include /** @@ -26,46 +26,36 @@ /** * @brief The default constructor. Creates an empty Tox key. */ -FriendId::FriendId() : ContactId() -{ -} +FriendId::FriendId() : ContactId() {} /** * @brief The copy constructor. * @param other ToxPk to copy */ -FriendId::FriendId(const FriendId& other) - : ContactId(other) -{ -} +FriendId::FriendId(const FriendId& other) : ContactId(other) {} /** * @brief Constructs a ToxPk from bytes. * @param rawId The bytes to construct the ToxPk from. The lenght must be exactly * TOX_PUBLIC_KEY_SIZE, else the ToxPk will be empty. */ -FriendId::FriendId(const QByteArray& rawId): - ContactId(rawId) -{ -} +FriendId::FriendId(const QByteArray& rawId) : ContactId(rawId) {} -FriendId::FriendId(const QString &strId): - ContactId(strId) -{ +FriendId::FriendId(const QString& strId) : ContactId(strId) { // 正则表达式模式,这里假设username不包含@,server不包含/ -// QRegularExpression re("([^@]+)@([^/]+)(/[^/]+)?"); -// // 匹配输入字符串 -// QRegularExpressionMatch match = re.match(strId); -// // 检查是否匹配成功 -// if (!match.hasMatch()) { -// qWarning() << "Unable to parse contactId:"< #include +#include "src/core/contactid.h" -namespace lib::messenger{ +namespace lib::messenger { class IMContactId; class IMPeerId; -} +} // namespace lib::messenger /** * 朋友ID * 格式:user@server * 比如:jidlpdyibulw@meet.chuanshaninfo.com */ -class FriendId : public ContactId -{ +class FriendId : public ContactId { public: FriendId(); FriendId(const FriendId& other); explicit FriendId(const QByteArray& rawId); explicit FriendId(const QString& rawId); explicit FriendId(const ContactId& rawId); - explicit FriendId(const lib::messenger::IMContactId & fId); + explicit FriendId(const lib::messenger::IMContactId& fId); bool operator==(const FriendId& other) const; bool operator<(const FriendId& other) const; - int getSize() const; QByteArray getByteArray() const; QString toString() const override; - }; - -inline uint qHash(const FriendId& id) -{ - return qHash(id.getByteArray()); -} +inline uint qHash(const FriendId& id) { return qHash(id.getByteArray()); } class ToxPeer : public FriendId { public: - explicit ToxPeer() = default; + explicit ToxPeer() = default; - explicit ToxPeer(const lib::messenger::IMPeerId& peerId); + explicit ToxPeer(const lib::messenger::IMPeerId& peerId); - explicit ToxPeer(const QString& rawId); + explicit ToxPeer(const QString& rawId); - bool isValid() const override; + bool isValid() const override; - QString toString() const override; + QString toString() const override; - QString getResource() const { - return resource; - } + QString getResource() const { return resource; } - const FriendId toFriendId() const { - return FriendId{username+"@"+server}; - } + const FriendId toFriendId() const { return FriendId{username + "@" + server}; } - QString resource; + QString resource; }; -#endif // TOXPK_H +#endif // TOXPK_H diff --git a/src/modules/im/src/core/contactid.cpp b/src/modules/im/src/core/contactid.cpp index 5831c6da..3450eedb 100644 --- a/src/modules/im/src/core/contactid.cpp +++ b/src/modules/im/src/core/contactid.cpp @@ -12,51 +12,43 @@ #include "src/core/contactid.h" #include +#include #include -#include #include +#include #include -#include #include "base/StringUtils.h" #include "lib/messenger/IMMessage.h" - /** * @brief The default constructor. Creates an empty id. */ -ContactId::ContactId() {} - - -ContactId::ContactId(const QByteArray &rawId) - : ContactId(QString::fromUtf8(rawId)) { +ContactId::ContactId() {} + +ContactId::ContactId(const QByteArray& rawId) : ContactId(QString::fromUtf8(rawId)) {} + +ContactId::ContactId(const QString& strId) { + // 检查是否匹配成功 + auto match = JidMatch(strId); + if (!match.hasMatch()) { + qWarning() << "Unable to parse contactId:" << strId; + return; + } + // 提取各个部分 + username = match.captured(1); + server = match.captured(2); } -ContactId::ContactId(const QString &strId) { - // 检查是否匹配成功 - auto match = JidMatch(strId); - if (!match.hasMatch()) { - qWarning() << "Unable to parse contactId:"< -#include -#include #include -#include #include #include +#include +#include +#include #include "lib/messenger/messenger.h" -inline QRegularExpressionMatch JidMatch(const QString& strId){ - // 正则表达式模式,这里假设username不包含@,server不包含/ - QRegularExpression re("([^@]+)@([^/]+)(/[^/]+)?"); - // 匹配输入字符串 - return re.match(strId); +inline QRegularExpressionMatch JidMatch(const QString& strId) { + // 正则表达式模式,这里假设username不包含@,server不包含/ + QRegularExpression re("([^@]+)@([^/]+)(/[^/]+)?"); + // 匹配输入字符串 + return re.match(strId); } /** - * 联系人ID + * 联系人ID(群聊ID和个人ID的父类) + * @see FriendId + * @see GroupId */ -class ContactId -{ +class ContactId { public: explicit ContactId(); - explicit ContactId(const ContactId &contactId); - explicit ContactId(const QByteArray &rawId); - explicit ContactId(const QString &strId); - explicit ContactId(const QString &username, const QString &server); + explicit ContactId(const ContactId& contactId); + explicit ContactId(const QByteArray& rawId); + explicit ContactId(const QString& strId); + explicit ContactId(const QString& username, const QString& server); virtual ~ContactId() = default; ContactId& operator=(const ContactId& other) = default; @@ -53,26 +54,20 @@ class ContactId virtual bool isValid() const; bool isGroup() const; + virtual QString toString() const { return username + "@" + server; }; - virtual QString toString() const { - return username+"@"+server; - }; + inline QString getId() const { return toString(); } - inline QString getId() const {return toString();} - - //用户名 + // 用户名 QString username; - //服务器地址 + // 服务器地址 QString server; - friend QDebug& operator<<(QDebug& debug, const ContactId &f); + friend QDebug& operator<<(QDebug& debug, const ContactId& f); }; -inline uint qHash(const ContactId& id) -{ - return qHash(id.getByteArray()); -} +inline uint qHash(const ContactId& id) { return qHash(id.getByteArray()); } using ContactIdPtr = std::shared_ptr; -#endif // CONTACTID_H +#endif // CONTACTID_H diff --git a/src/modules/im/src/core/core.cpp b/src/modules/im/src/core/core.cpp index 4d0591a1..9735eaea 100644 --- a/src/modules/im/src/core/core.cpp +++ b/src/modules/im/src/core/core.cpp @@ -4,10 +4,10 @@ * You can use this software according to the terms and conditions of the Mulan * PubL v2. You may obtain a copy of Mulan PubL v2 at: * http://license.coscl.org.cn/MulanPubL-2.0 - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, - * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, - * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * See the Mulan PubL v2 for more details. + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY + * KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO + * NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the + * Mulan PubL v2 for more details. */ #include "core.h" @@ -55,63 +55,64 @@ const QString Core::TOX_EXT = ".tox"; #define ASSERT_CORE_THREAD assert(QThread::currentThread() == coreThread.get()) -Core::Core(QThread *coreThread) - : tox(nullptr), toxTimer{new QTimer{this}}, - coreThread(coreThread) { +Core::Core(QThread* coreThread) + : tox(nullptr), toxTimer{new QTimer{this}}, coreThread(coreThread) { + assert(toxTimer); - assert(toxTimer); + qRegisterMetaType("ToxPeer"); - qRegisterMetaType("ToxPeer"); - - toxTimer->setSingleShot(true); - connect(toxTimer, &QTimer::timeout, this, &Core::process); - connect(coreThread, &QThread::finished, toxTimer, &QTimer::stop); + toxTimer->setSingleShot(true); + connect(toxTimer, &QTimer::timeout, this, &Core::process); + connect(coreThread, &QThread::finished, toxTimer, &QTimer::stop); } Core::~Core() { - /* - * First stop the thread to stop the timer and avoid Core emitting callbacks - * into an already destructed CoreAV. - */ - coreThread->exit(0); - coreThread->wait(); - -// av.reset(); - tox.reset(); -} - -Status::Status Core::fromToxStatus(const lib::messenger::IMStatus &status_) const { - Status::Status status; - switch (status_) { - case lib::messenger::IMStatus::Available: - case lib::messenger::IMStatus::Chat: - status = Status::Status::Online; - break; - case lib::messenger::IMStatus::Away: - status = Status::Status::Away; - break; - case lib::messenger::IMStatus::DND: - status = Status::Status::Busy; - break; - default: - status = Status::Status::Offline; - break; - } - return status; + /* + * First stop the thread to stop the timer and avoid Core emitting callbacks + * into an already destructed CoreAV. + */ + coreThread->exit(0); + coreThread->wait(); + + // av.reset(); + tox.reset(); +} + +Status::Status Core::fromToxStatus( + const lib::messenger::IMStatus& status_) const { + Status::Status status; + switch (status_) { + case lib::messenger::IMStatus::Available: + case lib::messenger::IMStatus::Chat: + status = Status::Status::Online; + break; + case lib::messenger::IMStatus::Away: + status = Status::Status::Away; + break; + case lib::messenger::IMStatus::DND: + status = Status::Status::Busy; + break; + default: + status = Status::Status::Offline; + break; + } + return status; } /** * @brief Registers all toxcore callbacks - * @param tox Tox instance to register the callbacks on + * @param messenger Tox instance to register the callbacks on */ -void Core::registerCallbacks(Tox *tox) { - tox->addFriendHandler(this); - tox->addGroupHandler(this); - tox->addSelfHandler(this); +void Core::registerCallbacks(lib::messenger::Messenger* messenger) { + messenger->addFriendHandler(this); + messenger->addGroupHandler(this); + messenger->addSelfHandler(this); - connect(tox, &lib::messenger::Messenger::connected, [this](){ - emit connected(); - }); + connect(messenger, &lib::messenger::Messenger::started, + [this, messenger]() { + messenger->requestBookmarks(); + emit started(); + }); } /** @@ -120,208 +121,111 @@ void Core::registerCallbacks(Tox *tox) { * @param settings Settings specific to Core * @return nullptr or a Core object ready to start */ -ToxCorePtr Core::makeToxCore(const QByteArray &savedata, - const ICoreSettings *const settings, - ToxCoreErrors *err) { - - QThread *thread = new QThread(); - if (!thread) { - qCritical() << "could not allocate Core thread"; - return {}; - } - thread->setObjectName("Core"); - - auto toxOptions = ToxOptions::makeToxOptions(savedata, settings); - if (toxOptions == nullptr) { - qCritical() << "could not allocate Tox Options data structure"; - if (err) { - *err = ToxCoreErrors::ERROR_ALLOC; +ToxCorePtr Core::makeToxCore(const QString& host, const QString& name, + const QString& password, + const QByteArray& savedata, + const ICoreSettings* const settings, + ToxCoreErrors* err) { + QThread* thread = new QThread(); + if (!thread) { + qCritical() << "could not allocate Core thread"; + return {}; } - return {}; - } + thread->setObjectName("Core"); - ToxCorePtr core(new Core(thread)); - if (core == nullptr) { - if (err) { - *err = ToxCoreErrors::ERROR_ALLOC; + auto toxOptions = ToxOptions::makeToxOptions(savedata, settings); + if (toxOptions == nullptr) { + qCritical() << "could not allocate Tox Options data structure"; + if (err) { + *err = ToxCoreErrors::ERROR_ALLOC; + } + return {}; } - return {}; - } - - // Tox_Err_New tox_err; -// core->tox = ToxPtr(tox_new(*toxOptions, &tox_err)); - core->tox =ToxPtr(new lib::messenger::Messenger()); - - // switch (tox_err) { - // case TOX_ERR_NEW_OK: - // break; - // - // case TOX_ERR_NEW_LOAD_BAD_FORMAT: - // qCritical() << "failed to parse Tox save data"; - // if (err) { - // *err = ToxCoreErrors::BAD_PROXY; - // } - // return {}; - // - // case TOX_ERR_NEW_PORT_ALLOC: - // if (toxOptions->getIPv6Enabled()) { - // toxOptions->setIPv6Enabled(false); - // core->tox = ToxPtr(tox_new(*toxOptions, &tox_err)); - // if (tox_err == TOX_ERR_NEW_OK) { - // qWarning() << "Core failed to start with IPv6, falling back to IPv4. - // " - // "LAN discovery " - // "may not work properly."; - // break; - // } - // } - // - // qCritical() << "can't to bind the port"; - // if (err) { - // *err = ToxCoreErrors::FAILED_TO_START; - // } - // return {}; - // - // case TOX_ERR_NEW_PROXY_BAD_HOST: - // case TOX_ERR_NEW_PROXY_BAD_PORT: - // case TOX_ERR_NEW_PROXY_BAD_TYPE: - // qCritical() << "bad proxy, error code:" << tox_err; - // if (err) { - // *err = ToxCoreErrors::BAD_PROXY; - // } - // return {}; - // - // case TOX_ERR_NEW_PROXY_NOT_FOUND: - // qCritical() << "proxy not found"; - // if (err) { - // *err = ToxCoreErrors::BAD_PROXY; - // } - // return {}; - // - // case TOX_ERR_NEW_LOAD_ENCRYPTED: - // qCritical() << "attempted to load encrypted Tox save data"; - // if (err) { - // *err = ToxCoreErrors::INVALID_SAVE; - // } - // return {}; - // - // case TOX_ERR_NEW_MALLOC: - // qCritical() << "memory allocation failed"; - // if (err) { - // *err = ToxCoreErrors::ERROR_ALLOC; - // } - // return {}; - // - // case TOX_ERR_NEW_NULL: - // qCritical() << "a parameter was null"; - // if (err) { - // *err = ToxCoreErrors::FAILED_TO_START; - // } - // return {}; - // - // default: - // qCritical() << "Tox core failed to start, unknown error code:" << - // tox_err; if (err) { - // *err = ToxCoreErrors::FAILED_TO_START; - // } - // return {}; - // } - - // tox should be valid by now - assert(core->tox != nullptr); - - // toxcore is successfully created, create toxav - // TODO(sudden6): don't create CoreAv here, Core should be usable without - // CoreAV -// core->av = CoreAV::makeCoreAV(core->tox.get(), core->coreLoopLock); -// if (!core->av) { -// qCritical() << "Toxav failed to start"; -// if (err) { -// *err = ToxCoreErrors::FAILED_TO_START; -// } -// return {}; -// } - // create CoreFile - core->file = - CoreFile::makeCoreFile(core.get(), core->tox.get(), core->coreLoopLock); - if (!core->file) { - qCritical() << "CoreFile failed to start"; - if (err) { - *err = ToxCoreErrors::FAILED_TO_START; + ToxCorePtr core(new Core(thread)); + if (core == nullptr) { + if (err) { + *err = ToxCoreErrors::ERROR_ALLOC; + } + return {}; } - return {}; - } - - core->registerCallbacks(core->tox.get()); - - // connect the thread with the Core - connect(thread, &QThread::started, core.get(), &Core::onStarted); - core->moveToThread(thread); - - // when leaving this function 'core' should be ready for it's start() action - // or a nullptr - return core; -} -void Core::onStarted() { - qDebug() << "connected..."; - ASSERT_CORE_THREAD; + core->tox = + std::make_unique(host, name, password); - // One time initialization stuff - QString name = getUsername(); - qDebug() << "username:" << name; - if (!name.isEmpty()) { - emit usernameSet(name); - } + // CoreAV + core->av = CoreAV::makeCoreAV(core.get()); + // CoreFile + core->file = CoreFile::makeCoreFile(core.get(), core->coreLoopLock); - auto status = getStatus(); - emit statusSet(status); + core->registerCallbacks(core->tox.get()); - QString msg = getStatusMessage(); - if (!msg.isEmpty()) { - emit statusMessageSet(msg); - } + // connect the thread with the Core + connect(thread, &QThread::started, core.get(), &Core::onStarted); + core->moveToThread(thread); - // ToxId id = getSelfId(); - // // Id comes from toxcore, must be valid - // assert(id.isValid()); - // emit idSet(id); - // std::this_thread::sleep_for(std::chrono::seconds(4)); // sleep 5秒 + // when leaving this function 'core' should be ready for it's start() action + // or a nullptr + return core; +} - // loadFriends(); - // loadGroups(); - tox->start(); -// av->start(); - process(); // starts its own timer - emit avReady(); - qDebug() << "connected completed."; +void Core::onStarted() { + qDebug() << "connected..."; + ASSERT_CORE_THREAD; + + // One time initialization stuff + // QString name = getUsername(); + // qDebug() << "username:" << name; + // if (!name.isEmpty()) { + // emit usernameSet(name); + // } + // + // auto status = getStatus(); + // emit statusSet(status); + // + // QString msg = getStatusMessage(); + // if (!msg.isEmpty()) { + // emit statusMessageSet(msg); + // } + + // ToxId id = getSelfId(); + // // Id comes from toxcore, must be valid + // assert(id.isValid()); + // emit idSet(id); + // std::this_thread::sleep_for(std::chrono::seconds(4)); // sleep 5秒 + + // loadFriends(); + // loadGroups(); + tox->start(); + // av->start(); + process(); // starts its own timer + // emit avReady(); + // qDebug() << "connected completed."; } /** * @brief Starts toxcore and it's event loop, can be called from any thread */ void Core::start() { - qDebug() << __func__ << "..."; - coreThread->start(); - coreThread->quit(); + qDebug() << __func__ << "..."; + coreThread->start(); } void Core::stop() { - qDebug() << __func__ << "..."; - coreThread->quit(); + qDebug() << __func__ << "..."; + coreThread->quit(); } /** * @brief Returns the global widget's Core instance */ -Core *Core::getInstance() { return Nexus::getCore(); } +Core* Core::getInstance() { return Nexus::getCore(); } -//const CoreAV *Core::getAv() const { return av.get(); } +// const CoreAV *Core::getAv() const { return av.get(); } -//CoreAV *Core::getAv() { return av.get(); } +// CoreAV *Core::getAv() { return av.get(); } -CoreFile *Core::getCoreFile() const { return file.get(); } +CoreFile* Core::getCoreFile() const { return file.get(); } /* Using the now commented out statements in checkConnection(), I watched how * many ticks disconnects-after-initial-connect lasted. Out of roughly 15 @@ -337,183 +241,178 @@ CoreFile *Core::getCoreFile() const { return file.get(); } * own timer */ void Core::process() { - QMutexLocker ml{&coreLoopLock}; + QMutexLocker ml{&coreLoopLock}; - ASSERT_CORE_THREAD; + ASSERT_CORE_THREAD; - static int tolerance = CORE_DISCONNECT_TOLERANCE; - // tox_iterate(tox.get(), this); + static int tolerance = CORE_DISCONNECT_TOLERANCE; + // tox_iterate(tox.get(), this); #ifdef DEBUG - // we want to see the debug messages immediately - fflush(stdout); + // we want to see the debug messages immediately + fflush(stdout); #endif - // TODO(sudden6): recheck if this is still necessary - // if (checkConnection()) { - // tolerance = CORE_DISCONNECT_TOLERANCE; - // } else if (!(--tolerance)) { - // bootstrapDht(); - // tolerance = 3 * CORE_DISCONNECT_TOLERANCE; - // } + // TODO(sudden6): recheck if this is still necessary + // if (checkConnection()) { + // tolerance = CORE_DISCONNECT_TOLERANCE; + // } else if (!(--tolerance)) { + // bootstrapDht(); + // tolerance = 3 * CORE_DISCONNECT_TOLERANCE; + // } - // unsigned sleeptime = qMin(tox_iteration_interval(tox.get()), - // getCoreFile()->corefileIterationInterval()); - // toxTimer->start(sleeptime); + // unsigned sleeptime = qMin(tox_iteration_interval(tox.get()), + // getCoreFile()->corefileIterationInterval()); + // toxTimer->start(sleeptime); } bool Core::checkConnection() { - ASSERT_CORE_THREAD; - static bool isConnected = false; - // bool toxConnected =tox_self_get_connection_status(tox.get()) != - // TOX_CONNECTION_NONE; if (toxConnected && !isConnected) { - // qDebug() << "Connected to the DHT"; - // emit connected(); - // } else if (!toxConnected && isConnected) { - // qDebug() << "Disconnected from the DHT"; - // emit disconnected(); - // } - // - // isConnected = toxConnected; - // return toxConnected; - return true; + ASSERT_CORE_THREAD; + static bool isConnected = false; + // bool toxConnected =tox_self_get_connection_status(tox.get()) != + // TOX_CONNECTION_NONE; if (toxConnected && !isConnected) { + // qDebug() << "Connected to the DHT"; + // emit connected(); + // } else if (!toxConnected && isConnected) { + // qDebug() << "Disconnected from the DHT"; + // emit disconnected(); + // } + // + // isConnected = toxConnected; + // return toxConnected; + return true; } /** * @brief Connects us to the Tox network */ void Core::bootstrapDht() { - // ASSERT_CORE_THREAD; - - // QList bootstrapNodes = - // BootstrapNodeUpdater::loadDefaultBootstrapNodes(); - // - // int listSize = bootstrapNodes.size(); - // if (!listSize) { - // qWarning() << "no bootstrap list?!?"; - // return; - // } - - // int i = 0; - // #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) - // static int j = QRandomGenerator::global()->generate() % listSize; - // #else - // static int j = qrand() % listSize; - // #endif - // i think the more we bootstrap, the more we jitter because the more we - // overwrite nodes - // while (i < 2) { - // const DhtServer &dhtServer = bootstrapNodes[j % listSize]; - // QString dhtServerAddress = dhtServer.address.toLatin1(); - // QString port = QString::number(dhtServer.port); - // QString name = dhtServer.name; - // qDebug() << QString("Connecting to a bootstrap node..."); - // QByteArray address = dhtServer.address.toLatin1(); - // // TODO: constucting the pk via ToxId is a workaround - // ToxPk pk = ToxId{dhtServer.userId}.getPublicKey(); - - // const uint8_t *pkPtr = pk.getData(); - // - // Tox_Err_Bootstrap error; - // tox_bootstrap(tox.get(), address.constData(), dhtServer.port, pkPtr, - // &error); - // parseToxErrBootstrap(error); - // - // tox_add_tcp_relay(tox.get(), address.constData(), dhtServer.port, - // pkPtr, - // &error); - // parseToxErrBootstrap(error); - - // ++j; - // ++i; - // } -} - -void Core::onFriend(const lib::messenger::IMFriend & frnd) { - qDebug() << __func__ << frnd; - emit friendAdded(FriendInfo{frnd}); -} - -void Core::onFriendRequest(const QString friendId, - QString msg) { - qDebug() << "onFriendRequest" << friendId; - emit friendRequestReceived(FriendId(friendId), msg); + // ASSERT_CORE_THREAD; + + // QList bootstrapNodes = + // BootstrapNodeUpdater::loadDefaultBootstrapNodes(); + // + // int listSize = bootstrapNodes.size(); + // if (!listSize) { + // qWarning() << "no bootstrap list?!?"; + // return; + // } + + // int i = 0; + // #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) + // static int j = QRandomGenerator::global()->generate() % listSize; + // #else + // static int j = qrand() % listSize; + // #endif + // i think the more we bootstrap, the more we jitter because the more we + // overwrite nodes + // while (i < 2) { + // const DhtServer &dhtServer = bootstrapNodes[j % listSize]; + // QString dhtServerAddress = dhtServer.address.toLatin1(); + // QString port = QString::number(dhtServer.port); + // QString name = dhtServer.name; + // qDebug() << QString("Connecting to a bootstrap node..."); + // QByteArray address = dhtServer.address.toLatin1(); + // // TODO: constucting the pk via ToxId is a workaround + // ToxPk pk = ToxId{dhtServer.userId}.getPublicKey(); + + // const uint8_t *pkPtr = pk.getData(); + // + // Tox_Err_Bootstrap error; + // tox_bootstrap(tox.get(), address.constData(), dhtServer.port, pkPtr, + // &error); + // parseToxErrBootstrap(error); + // + // tox_add_tcp_relay(tox.get(), address.constData(), dhtServer.port, + // pkPtr, + // &error); + // parseToxErrBootstrap(error); + + // ++j; + // ++i; + // } +} + +void Core::onFriend(const lib::messenger::IMFriend& frnd) { + qDebug() << __func__ << frnd; + emit friendAdded(FriendInfo{frnd}); +} + +void Core::onFriendRequest(const QString friendId, QString msg) { + qDebug() << "onFriendRequest" << friendId; + emit friendRequestReceived(FriendId(friendId), msg); } void Core::onFriendRemoved(QString friendId) { - qDebug() << "removed" << friendId; - emit friendRemoved(friendId); + qDebug() << "removed" << friendId; + emit friendRemoved(friendId); } void Core::onFriendStatus(QString friendId, lib::messenger::IMStatus status) { - qDebug() << __func__ << friendId << (int)status; - Status::Status status0 = fromToxStatus(status); - emit friendStatusChanged(getFriendPublicKey(friendId), status0); + qDebug() << __func__ << friendId << (int)status; + Status::Status status0 = fromToxStatus(status); + emit friendStatusChanged(getFriendPublicKey(friendId), status0); } - void Core::onMessageSession(QString cId, QString sid) { - qDebug() <<__func__<< "contact:" << cId << "sid:" << sid; - + qDebug() << __func__ << "contact:" << cId << "sid:" << sid; auto contactId = ContactId(cId); emit messageSessionReceived(contactId, sid); } - void Core::onFriendMessage(QString friendId, lib::messenger::IMMessage message) { - qDebug() <<__func__<< "friend:" << friendId; - qDebug() <<"content:" << message.body; + qDebug() << __func__ << "friend:" << friendId; + qDebug() << "content:" << message.body; - sendReceiptReceived(friendId, message.id); + sendReceiptReceived(friendId, message.id); - FriendMessage msg; - msg.isAction=false; - msg.id= message.id; - msg.from= message.from; - msg.to = message.to; - msg.content=message.body; - msg.timestamp=message.timestamp; - msg.displayName=ContactId(message.from).username; - emit friendMessageReceived(FriendId(friendId), msg, false); + FriendMessage msg; + msg.isAction = false; + msg.id = message.id; + msg.from = message.from; + msg.to = message.to; + msg.content = message.body; + msg.timestamp = message.timestamp; + msg.displayName = ContactId(message.from).username; + emit friendMessageReceived(FriendId(friendId), msg, false); } /** * 实现ChatState */ void Core::onFriendChatState(QString friendId, int state) { - qDebug() << "onFriendChatState:" << friendId << "state:" << state; - emit friendTypingChanged(getFriendPublicKey(friendId), state == 2); + qDebug() << "onFriendChatState:" << friendId << "state:" << state; + emit friendTypingChanged(getFriendPublicKey(friendId), state == 2); } -void Core::onFriendNameChanged(QString friendId, QString name) { - qDebug() << __func__ << friendId << name; - emit friendUsernameChanged(getFriendPublicKey(friendId), name); +void Core::onFriendNickChanged(QString friendId, QString nick) { + qDebug() << __func__ << friendId << nick; + emit friendUsernameChanged(getFriendPublicKey(friendId), nick); } void Core::onFriendAvatarChanged(const QString friendId, const std::string avatar) { - qDebug() << __func__ << friendId <<"avatar size"<< avatar.size(); - if (avatar.empty()) - return; + qDebug() << __func__ << friendId << "avatar size" << avatar.size(); + if (avatar.empty()) return; - emit friendAvatarChanged(getFriendPublicKey(friendId), QByteArray::fromStdString(avatar)); + emit friendAvatarChanged(getFriendPublicKey(friendId), + QByteArray::fromStdString(avatar)); } -void Core::onFriendAliasChanged(const lib::messenger::IMContactId &fId, const QString &alias) -{ +void Core::onFriendAliasChanged(const lib::messenger::IMContactId& fId, + const QString& alias) { emit friendAliasChanged(FriendId{fId}, alias); } - void Core::onGroup(const QString groupId, const QString name) { - qDebug() << __func__ << "groupId:" << groupId << name; - emit groupAdded( GroupId (groupId), name); + qDebug() << __func__ << "groupId:" << groupId << name; + emit groupAdded(GroupId(groupId), name); } - // -//void Core::onGroupInvite(Tox *tox, QString receiver, Tox_Conference_Type type, +// void Core::onGroupInvite(Tox *tox, QString receiver, Tox_Conference_Type +// type, // const uint8_t *cookie, size_t length, void *vCore) { // Core *core = static_cast(vCore); // const QByteArray data(reinterpret_cast(cookie), length); @@ -534,15 +433,16 @@ void Core::onGroup(const QString groupId, const QString name) { // } //} // -//void Core::onGroupPeerListChange(Tox *, QString groupId, void *vCore) { +// void Core::onGroupPeerListChange(Tox *, QString groupId, void *vCore) { // const auto core = static_cast(vCore); // qDebug() << QString("Group %1 peerlist changed").arg(groupId); -// // no saveRequest, this callback is called on every connection to group peer, +// // no saveRequest, this callback is called on every connection to group +// peer, // // not just on brand new peers // emit core->groupPeerlistChanged(groupId); //} // -//void Core::onGroupPeerNameChange(Tox *, QString groupId, QString peerId, +// void Core::onGroupPeerNameChange(Tox *, QString groupId, QString peerId, // const uint8_t *name, size_t length, // void *vCore) { // const auto newName = ToxString(name, length).getQString(); @@ -555,7 +455,7 @@ void Core::onGroup(const QString groupId, const QString name) { // emit core->groupPeerNameChanged(groupId, peerPk, newName); //} // -//void Core::onGroupTitleChange(Tox *, QString groupId, QString peerId, +// void Core::onGroupTitleChange(Tox *, QString groupId, QString peerId, // const uint8_t *cTitle, size_t length, // void *vCore) { // Core *core = static_cast(vCore); @@ -565,23 +465,17 @@ void Core::onGroup(const QString groupId, const QString name) { // ToxString(cTitle, length).getQString()); //} -void Core::onGroupInvite(const QString groupId, - const QString peerId, +void Core::onGroupInvite(const QString groupId, const QString peerId, const QString message) { + qDebug() << __func__ << "groupId:" << groupId << " receiver:" << peerId + << " msg:" << message; - qDebug() << __func__ << "groupId:" << groupId - << " receiver:" << peerId - << " msg:" << message; - - GroupInvite invite(groupId, peerId, - ConferenceType::TEXT, - message.toUtf8()); - emit groupInviteReceived(invite); + GroupInvite invite(groupId, peerId, ConferenceType::TEXT, message.toUtf8()); + emit groupInviteReceived(invite); } -void Core::onGroupSubjectChanged(const QString &groupId, - const QString &subject) -{ +void Core::onGroupSubjectChanged(const QString& groupId, + const QString& subject) { qDebug() << __func__ << "groupId:" << groupId << " subject:" << subject; emit groupSubjectChanged(GroupId(groupId), subject); } @@ -589,71 +483,69 @@ void Core::onGroupSubjectChanged(const QString &groupId, void Core::onGroupMessage(const QString groupId, const lib::messenger::IMPeerId peerId, const lib::messenger::IMMessage message) { + qDebug() << __func__ << "groupId:" << groupId + << "peer:" << peerId.toString(); + qDebug() << "body:" << message.body; - qDebug() << __func__ << "groupId:" << groupId << "peer:" << peerId.toString(); - qDebug() << "body:" << message.body; + bool isAction = false; + GroupMessage msg; + msg.isAction = isAction; + msg.id = message.id; + msg.from = message.from; + msg.to = message.to; + msg.content = message.body; + msg.timestamp = message.timestamp; + msg.resource = peerId.resource; + msg.nick = peerId.resource; - bool isAction = false; - GroupMessage msg; - msg.isAction= isAction; - msg.id=message.id; - msg.from = message.from; - msg.to = message.to; - msg.content=message.body; - msg.timestamp=message.timestamp; - msg.resource=peerId.resource; - msg.nick=peerId.resource; - - emit groupMessageReceived(GroupId(groupId), msg); + emit groupMessageReceived(GroupId(groupId), msg); } void Core::onGroupOccupants(const QString groupId, const uint size) { - qDebug() << __func__ <<"groupId" << groupId <<"size"<< size; - emit groupPeerSizeChanged(groupId, size); + qDebug() << __func__ << "groupId" << groupId << "size" << size; + emit groupPeerSizeChanged(groupId, size); } -void Core::onGroupOccupantStatus(const QString groupId, // +void Core::onGroupOccupantStatus(const QString groupId, // const lib::messenger::IMGroupOccupant occ) { - GroupOccupant go = {.jid = occ.jid, - .nick=occ.nick, - .affiliation=occ.affiliation, - .role=occ.role, + .nick = occ.nick, + .affiliation = occ.affiliation, + .role = occ.role, .status = occ.status, - .codes=occ.codes}; + .codes = occ.codes}; emit groupPeerStatusChanged(groupId, go); } -void Core::onGroupInfo( QString groupId, lib::messenger::IMGroup groupInfo) { +void Core::onGroupInfo(QString groupId, lib::messenger::IMGroup groupInfo) { GroupInfo info = { - .name = groupInfo.name, - .description = groupInfo.description, - .subject = groupInfo.subject, - .creationdate = groupInfo.creationdate, - .occupants = groupInfo.occupants, - }; - emit groupInfoReceipt(GroupId(groupId), info); + .name = groupInfo.name, + .description = groupInfo.description, + .subject = groupInfo.subject, + .creationdate = groupInfo.creationdate, + .occupants = groupInfo.occupants, + }; + emit groupInfoReceipt(GroupId(groupId), info); } void Core::onMessageReceipt(QString friendId, MsgId receipt) { - qDebug()<<__func__<acceptFriendRequest(friendId); + QMutexLocker ml{&coreLoopLock}; - emit saveRequest(); + QString friendId = friendPk.toString(); + tox->acceptFriendRequest(friendId); + emit saveRequest(); } -void Core::rejectFriendRequest(const FriendId &friendPk) { - tox->rejectFriendRequest(friendPk.toString()); +void Core::rejectFriendRequest(const FriendId& friendPk) { + tox->rejectFriendRequest(friendPk.toString()); } /** @@ -664,229 +556,225 @@ void Core::rejectFriendRequest(const FriendId &friendPk) { * @return Returns empty string if sending request is correct, according error * message otherwise */ -QString Core::getFriendRequestErrorMessage(const ToxId &friendId, - const QString &message) const { - QMutexLocker ml{&coreLoopLock}; +QString Core::getFriendRequestErrorMessage(const ToxId& friendId, + const QString& message) const { + QMutexLocker ml{&coreLoopLock}; - if (!friendId.isValid()) { - return tr("Invalid Ok ID", "Error while sending friendship request"); - } + if (!friendId.isValid()) { + return tr("Invalid Ok ID", "Error while sending friendship request"); + } - if (message.isEmpty()) { - return tr("You need to write a message with your request", - "Error while sending friendship request"); - } + if (message.isEmpty()) { + return tr("You need to write a message with your request", + "Error while sending friendship request"); + } - // if (message.length() > static_cast(tox_max_friend_request_length())) - // { - // return tr("Your message is too long!", - // "Error while sending friendship request"); - // } + // if (message.length() > + // static_cast(tox_max_friend_request_length())) + // { + // return tr("Your message is too long!", + // "Error while sending friendship request"); + // } - // if (hasFriendWithPublicKey(receiver.getPublicKey())) { - return tr("IMFriend is already added", - "Error while sending friendship request"); - // } + // if (hasFriendWithPublicKey(receiver.getPublicKey())) { + return tr("IMFriend is already added", + "Error while sending friendship request"); + // } - return QString{}; + return QString{}; } -void Core::requestFriendship(const FriendId &friendId,const QString &nick, const QString &message) { - qDebug() << __func__<< friendId.toString() << nick << message; +void Core::requestFriendship(const FriendId& friendId, const QString& nick, + const QString& message) { + qDebug() << __func__ << friendId.toString() << nick << message; QMutexLocker ml{&coreLoopLock}; - // ToxPk friendPk = receiver.getPublicKey(); - // QString errorMessage = getFriendRequestErrorMessage(receiver, message); - // if (!errorMessage.isNull()) { - // emit failedToAddFriend(friendPk, errorMessage); - // emit saveRequest(); - // return; - // } - - // ToxString cMessage(message); -// QString fId = receiver.getToxIdAsStr(); - - tox->sendFriendRequest(friendId.toString(), nick, message); - - // uint32_t friendNumber = tox_friend_add(tox.get(), receiver.getBytes(), - // cMessage.data(), cMessage.size(), nullptr); - // if (friendNumber == std::numeric_limits::max()) { - // qDebug() << "Failed to request friendship"; - // emit failedToAddFriend(friendPk); - // } else { - // qDebug() << "Requested friendship of " << friendNumber; - // emit friendAdded(friendNumber, friendPk); - // emit requestSent(friendPk, message); - // } - - emit saveRequest(); -} - -bool Core::sendMessageWithType(QString friendId, - const QString &message, - const MsgId &id, - bool encrypt) { - - qDebug() << __func__ <<"receiver"<< friendId <<"message:"<< message; - if(friendId.isEmpty()) - { - qWarning() <<"receiver is empty."; - return false; - } + // ToxPk friendPk = receiver.getPublicKey(); + // QString errorMessage = getFriendRequestErrorMessage(receiver, message); + // if (!errorMessage.isNull()) { + // emit failedToAddFriend(friendPk, errorMessage); + // emit saveRequest(); + // return; + // } + + // ToxString cMessage(message); + // QString fId = receiver.getToxIdAsStr(); + + tox->sendFriendRequest(friendId.toString(), nick, message); + + // uint32_t friendNumber = tox_friend_add(tox.get(), receiver.getBytes(), + // cMessage.data(), cMessage.size(), nullptr); + // if (friendNumber == std::numeric_limits::max()) { + // qDebug() << "Failed to request friendship"; + // emit failedToAddFriend(friendPk); + // } else { + // qDebug() << "Requested friendship of " << friendNumber; + // emit friendAdded(friendNumber, friendPk); + // emit requestSent(friendPk, message); + // } + emit saveRequest(); +} - bool yes = tox->sendToFriend(friendId, message, id, encrypt); +bool Core::sendMessageWithType(QString friendId, const QString& message, + const MsgId& id, bool encrypt) { + qDebug() << __func__ << "receiver" << friendId << "message:" << message; + if (friendId.isEmpty()) { + qWarning() << "receiver is empty."; + return false; + } + + bool yes = tox->sendToFriend(friendId, message, id, encrypt); - // int size = message.toUtf8().size(); - // auto maxSize = tox_max_message_length(); - // if (size > maxSize) { - // qCritical() << "Core::sendMessageWithType called with message of size:" - // << size << "when max is:" << maxSize << ". Ignoring."; - // return false; - // } - // - // ToxString cMessage(message); - // Tox_Err_Friend_Send_Message error; -// receipt = MsgId{receipts}; - // if (parseFriendSendMessageError(error)) { - // return true; - // } - return yes; + // int size = message.toUtf8().size(); + // auto maxSize = tox_max_message_length(); + // if (size > maxSize) { + // qCritical() << "Core::sendMessageWithType called with message of + // size:" + // << size << "when max is:" << maxSize << ". Ignoring."; + // return false; + // } + // + // ToxString cMessage(message); + // Tox_Err_Friend_Send_Message error; + // receipt = MsgId{receipts}; + // if (parseFriendSendMessageError(error)) { + // return true; + // } + return yes; } -bool Core::sendMessage(QString friendId, const QString &message, - const MsgId &msgId, bool encrypt) { - QMutexLocker ml(&coreLoopLock); - return sendMessageWithType(friendId, message,msgId, encrypt); +bool Core::sendMessage(QString friendId, const QString& message, + const MsgId& msgId, bool encrypt) { + QMutexLocker ml(&coreLoopLock); + return sendMessageWithType(friendId, message, msgId, encrypt); } -bool Core::sendAction(QString friendId, const QString &action, - const MsgId &msgId, bool encrypt) { - QMutexLocker ml(&coreLoopLock); - return sendMessageWithType(friendId, action, msgId,encrypt); +bool Core::sendAction(QString friendId, const QString& action, + const MsgId& msgId, bool encrypt) { + QMutexLocker ml(&coreLoopLock); + return sendMessageWithType(friendId, action, msgId, encrypt); } void Core::sendTyping(QString friendId, bool typing) { - QMutexLocker ml{&coreLoopLock}; - tox->sendChatState(friendId, typing ? 2 : 4); - emit failedToSetTyping(typing); + QMutexLocker ml{&coreLoopLock}; + tox->sendChatState(friendId, typing ? 2 : 4); + emit failedToSetTyping(typing); } -bool Core::sendGroupMessageWithType(QString groupId,const QString &message, const MsgId &id) { - QMutexLocker ml{&coreLoopLock}; - return tox->sendToGroup(groupId, message, id); +bool Core::sendGroupMessageWithType(QString groupId, const QString& message, + const MsgId& id) { + QMutexLocker ml{&coreLoopLock}; + return tox->sendToGroup(groupId, message, id); } -bool Core::sendGroupMessage(QString groupId, const QString &message, const MsgId &id) { - QMutexLocker ml{&coreLoopLock}; +bool Core::sendGroupMessage(QString groupId, const QString& message, + const MsgId& id) { + QMutexLocker ml{&coreLoopLock}; return sendGroupMessageWithType(groupId, message, id); } -bool Core::sendGroupAction(QString groupId, const QString &message, const MsgId &id) { - QMutexLocker ml{&coreLoopLock}; - return sendGroupMessageWithType(groupId, message, id); +bool Core::sendGroupAction(QString groupId, const QString& message, + const MsgId& id) { + QMutexLocker ml{&coreLoopLock}; + return sendGroupMessageWithType(groupId, message, id); } -void Core::setGroupName(const QString &groupId, const QString &name) { - qDebug() << __func__ << groupId << name; - QMutexLocker ml{&coreLoopLock}; - tox->setRoomName(groupId, name); +void Core::setGroupName(const QString& groupId, const QString& name) { + qDebug() << __func__ << groupId << name; + QMutexLocker ml{&coreLoopLock}; + tox->setRoomName(groupId, name); } -void Core::setGroupSubject(const QString &groupId, const QString &subject) -{ +void Core::setGroupSubject(const QString& groupId, const QString& subject) { qDebug() << __func__ << groupId << subject; QMutexLocker ml{&coreLoopLock}; tox->setRoomSubject(groupId, subject); } -void Core::setGroupDesc(const QString &groupId, const QString &desc) -{ +void Core::setGroupDesc(const QString& groupId, const QString& desc) { qDebug() << __func__ << groupId << desc; QMutexLocker ml{&coreLoopLock}; tox->setRoomDesc(groupId, desc); } -void Core::setGroupAlias(const QString &groupId, const QString &alias) -{ +void Core::setGroupAlias(const QString& groupId, const QString& alias) { qDebug() << __func__ << groupId << alias; QMutexLocker ml{&coreLoopLock}; tox->setRoomAlias(groupId, alias); } void Core::removeFriend(QString friendId) { - qDebug() << "removeFriend" << friendId; - QMutexLocker ml{&coreLoopLock}; - bool success = tox->removeFriend(friendId); - if (success) { - emit saveRequest(); - emit friendRemoved(friendId); - return; - } + qDebug() << "removeFriend" << friendId; + QMutexLocker ml{&coreLoopLock}; + bool success = tox->removeFriend(friendId); + if (success) { + emit saveRequest(); + emit friendRemoved(friendId); + return; + } } void Core::leaveGroup(QString groupId) { - bool success = tox->leaveGroup(groupId); - if (success) { - emit saveRequest(); -// av->leaveGroupCall(groupId); - } + bool success = tox->leaveGroup(groupId); + if (success) { + emit saveRequest(); + // av->leaveGroupCall(groupId); + } } void Core::destroyGroup(QString groupId) { - bool success = tox->destroyGroup(groupId); - if (success) { - emit saveRequest(); -// av->leaveGroupCall(groupId); - } + bool success = tox->destroyGroup(groupId); + if (success) { + emit saveRequest(); + // av->leaveGroupCall(groupId); + } } - /** * @brief Returns our username, or an empty string on failure */ QString Core::getUsername() const { - QMutexLocker ml{&coreLoopLock}; - QString sname = tox->getSelfUsername(); - return sname; + QMutexLocker ml{&coreLoopLock}; + return tox->getSelfUsername(); } -void Core::setUsername(const QString &username) { - QMutexLocker ml{&coreLoopLock}; +void Core::setNick(const QString& nick) { + QMutexLocker ml{&coreLoopLock}; - if (username == getUsername()) { - return; - } + if (nick == getNick()) { + return; + } - tox->setSelfNickname(username); + tox->setSelfNickname(nick); - emit usernameSet(username); - emit saveRequest(); + emit usernameSet(nick); + emit saveRequest(); } QString Core::getNick() const { - QMutexLocker ml{&coreLoopLock}; - return tox->getSelfNick(); + QMutexLocker ml{&coreLoopLock}; + return tox->getSelfNick(); } -void Core::setPassword(const QString &password) { - QMutexLocker ml{&coreLoopLock}; +void Core::setPassword(const QString& password) { + QMutexLocker ml{&coreLoopLock}; - if (password.isEmpty()) { - return; - } + if (password.isEmpty()) { + return; + } - tox->changePassword(password); + tox->changePassword(password); } /** * @brief Returns our Ok ID */ ToxId Core::getSelfPeerId() const { - QMutexLocker ml{&coreLoopLock}; - auto selfId = tox->getSelfId(); - return ToxId(selfId.toString().toUtf8()); + QMutexLocker ml{&coreLoopLock}; + auto selfId = tox->getSelfId(); + return ToxId(selfId.toString().toUtf8()); } /** @@ -894,235 +782,235 @@ ToxId Core::getSelfPeerId() const { * @return Self PK */ FriendId Core::getSelfId() const { - QMutexLocker ml{&coreLoopLock}; - auto friendId = tox->getSelfId(); - return FriendId(friendId.toString()); + QMutexLocker ml{&coreLoopLock}; + auto friendId = tox->getSelfId(); + return FriendId(friendId.toString()); } /** * @brief Returns our public and private keys */ QPair Core::getKeypair() const { - QMutexLocker ml{&coreLoopLock}; + QMutexLocker ml{&coreLoopLock}; - QPair keypair; - // assert(tox != nullptr); - // - // QByteArray pk(TOX_PUBLIC_KEY_SIZE, 0x00); - // QByteArray sk(TOX_SECRET_KEY_SIZE, 0x00); - // tox_self_get_public_key(tox.get(), reinterpret_cast(pk.data())); tox_self_get_secret_key(tox.get(), - // reinterpret_cast(sk.data())); keypair.first = pk; - // keypair.second = sk; - return keypair; + QPair keypair; + // assert(tox != nullptr); + // + // QByteArray pk(TOX_PUBLIC_KEY_SIZE, 0x00); + // QByteArray sk(TOX_SECRET_KEY_SIZE, 0x00); + // tox_self_get_public_key(tox.get(), reinterpret_cast(pk.data())); tox_self_get_secret_key(tox.get(), + // reinterpret_cast(sk.data())); keypair.first = pk; + // keypair.second = sk; + return keypair; } /** * @brief Returns our status message, or an empty string on failure */ QString Core::getStatusMessage() const { - QMutexLocker ml{&coreLoopLock}; - auto status = getStatus(); - return Status::getAssetSuffix(status); + QMutexLocker ml{&coreLoopLock}; + auto status = getStatus(); + return Status::getAssetSuffix(status); } /** * @brief Returns our user status */ Status::Status Core::getStatus() const { - assert(tox != nullptr); - QMutexLocker ml{&coreLoopLock}; - switch (tox->getSelfStatus()) { - case lib::messenger::IMStatus::Available: - case lib::messenger::IMStatus::Chat: - return Status::Status::Online; - case lib::messenger::IMStatus::Away: - case lib::messenger::IMStatus::XA: - return Status::Status::Away; - case lib::messenger::IMStatus::DND: - return Status::Status::Busy; - default: - return Status::Status::Offline; - } -} - -void Core::setStatusMessage(const QString &message) { - QMutexLocker ml{&coreLoopLock}; - - if (message == getStatusMessage()) { - return; - } - - // ToxString cMessage(message); - // if (!tox_self_set_status_message(tox.get(), cMessage.data(), - // cMessage.size(), nullptr)) { - // emit failedToSetStatusMessage(message); - // return; - // } - - emit saveRequest(); - emit statusMessageSet(message); + assert(tox != nullptr); + QMutexLocker ml{&coreLoopLock}; + switch (tox->getSelfStatus()) { + case lib::messenger::IMStatus::Available: + case lib::messenger::IMStatus::Chat: + return Status::Status::Online; + case lib::messenger::IMStatus::Away: + case lib::messenger::IMStatus::XA: + return Status::Status::Away; + case lib::messenger::IMStatus::DND: + return Status::Status::Busy; + default: + return Status::Status::Offline; + } } -void Core::setStatus(Status::Status status_) { - QMutexLocker ml{&coreLoopLock}; +void Core::setStatusMessage(const QString& message) { + QMutexLocker ml{&coreLoopLock}; - lib::messenger::IMStatus userstatus; - switch (status_) { - case Status::Status::Online: - userstatus = lib::messenger::IMStatus::Available; - break; + if (message == getStatusMessage()) { + return; + } - case Status::Status::Away: - userstatus = lib::messenger::IMStatus::Away; - break; + // ToxString cMessage(message); + // if (!tox_self_set_status_message(tox.get(), cMessage.data(), + // cMessage.size(), nullptr)) { + // emit failedToSetStatusMessage(message); + // return; + // } - case Status::Status::Busy: - userstatus = lib::messenger::IMStatus::DND; - break; - default: - break; - } + emit saveRequest(); + emit statusMessageSet(message); +} + +void Core::setStatus(Status::Status status_) { + QMutexLocker ml{&coreLoopLock}; - emit saveRequest(); - emit statusSet(status_); + lib::messenger::IMStatus userstatus; + switch (status_) { + case Status::Status::Online: + userstatus = lib::messenger::IMStatus::Available; + break; + + case Status::Status::Away: + userstatus = lib::messenger::IMStatus::Away; + break; + + case Status::Status::Busy: + userstatus = lib::messenger::IMStatus::DND; + break; + default: + break; + } + + emit saveRequest(); + emit statusSet(status_); } -void Core::setAvatar(const QByteArray &avatar) { tox->setSelfAvatar(avatar); } +void Core::setAvatar(const QByteArray& avatar) { tox->setSelfAvatar(avatar); } /** * @brief Returns the unencrypted tox save data */ QByteArray Core::getToxSaveData() { - QMutexLocker ml{&coreLoopLock}; + QMutexLocker ml{&coreLoopLock}; - QByteArray data; - // uint32_t fileSize = tox_get_savedata_size(tox.get()); - // data.resize(fileSize); - // tox_get_savedata(tox.get(), (uint8_t *)data.data()); - return data; + QByteArray data; + // uint32_t fileSize = tox_get_savedata_size(tox.get()); + // data.resize(fileSize); + // tox_get_savedata(tox.get(), (uint8_t *)data.data()); + return data; } // Declared to avoid code duplication #define GET_FRIEND_PROPERTY(property, function, checkSize) \ - const size_t property##Size = function##_size(tox.get(), ids[i], nullptr); \ - if ((!checkSize || property##Size) && property##Size != SIZE_MAX) { \ - uint8_t *prop = new uint8_t[property##Size]; \ - if (function(tox.get(), ids[i], prop, nullptr)) { \ - QString propStr = ToxString(prop, property##Size).getQString(); \ - emit friend##property##Changed(ids[i], propStr); \ - } \ + const size_t property##Size = function##_size(tox.get(), ids[i], nullptr); \ + if ((!checkSize || property##Size) && property##Size != SIZE_MAX) { \ + uint8_t* prop = new uint8_t[property##Size]; \ + if (function(tox.get(), ids[i], prop, nullptr)) { \ + QString propStr = ToxString(prop, property##Size).getQString(); \ + emit friend##property##Changed(ids[i], propStr); \ + } \ \ - delete[] prop; \ - } + delete[] prop; \ + } void Core::loadFriends() { - QMutexLocker ml{&coreLoopLock}; - const size_t friendCount = tox->getFriendCount(); - qDebug() << "friendCount" << friendCount; - if (friendCount == 0) { - return; - } - - // std::list peers = messenger->loadFriendList(); - // for (auto itr : peers) { - // qDebug() << "id=" << qstring(itr.getJid()) - // << " name=" << qstring(itr.getUsername()); - // } - - // uint32_t *ids = new uint32_t[friendCount]; - // tox_self_get_friend_list(tox.get(), ids); - // uint8_t friendPk[TOX_PUBLIC_KEY_SIZE] = {0x00}; - // for (size_t i = 0; i < friendCount; ++i) { - // if (!tox_friend_get_public_key(tox.get(), ids[i], friendPk, nullptr)) { - // continue; - // } - - // emit friendAdded(ids[i], ToxPk(friendPk)); - // GET_FRIEND_PROPERTY(Username, tox_friend_get_name, true); - // GET_FRIEND_PROPERTY(StatusMessage, tox_friend_get_status_message, false); - // checkLastOnline(ids[i]); - // } - // delete[] ids; + QMutexLocker ml{&coreLoopLock}; + const size_t friendCount = tox->getFriendCount(); + qDebug() << "friendCount" << friendCount; + if (friendCount == 0) { + return; + } + + // std::list peers = messenger->loadFriendList(); + // for (auto itr : peers) { + // qDebug() << "id=" << qstring(itr.getJid()) + // << " name=" << qstring(itr.getUsername()); + // } + + // uint32_t *ids = new uint32_t[friendCount]; + // tox_self_get_friend_list(tox.get(), ids); + // uint8_t friendPk[TOX_PUBLIC_KEY_SIZE] = {0x00}; + // for (size_t i = 0; i < friendCount; ++i) { + // if (!tox_friend_get_public_key(tox.get(), ids[i], friendPk, nullptr)) { + // continue; + // } + + // emit friendAdded(ids[i], ToxPk(friendPk)); + // GET_FRIEND_PROPERTY(Username, tox_friend_get_name, true); + // GET_FRIEND_PROPERTY(StatusMessage, tox_friend_get_status_message, + // false); checkLastOnline(ids[i]); + // } + // delete[] ids; } void Core::loadGroups() { - QMutexLocker ml{&coreLoopLock}; - - // const size_t groupCount = tox_conference_get_chatlist_size(tox.get()); - // if (groupCount == 0) { - // return; - // } - // - // auto groupNumbers = new uint32_t[groupCount]; - // tox_conference_get_chatlist(tox.get(), groupNumbers); - // - // for (size_t i = 0; i < groupCount; ++i) { - // TOX_ERR_CONFERENCE_TITLE error; - // QString name; - // const auto groupNumber = groupNumbers[i]; - // size_t titleSize = - // tox_conference_get_title_size(tox.get(), groupNumber, &error); - // const GroupId persistentId = getGroupPersistentId(groupNumber); - // const QString defaultName = - // tr("Groupchat %1").arg(persistentId.toString().left(8)); - // if (LogConferenceTitleError(error)) { - // name = defaultName; - // } else { - // QByteArray nameByteArray = - // QByteArray(static_cast(titleSize), Qt::Uninitialized); - // tox_conference_get_title( - // tox.get(), groupNumber, - // reinterpret_cast(nameByteArray.data()), &error); - // if (LogConferenceTitleError(error)) { - // name = defaultName; - // } else { - // name = ToxString(nameByteArray).getQString(); - // } - // } - // if (getGroupAvEnabled(groupNumber)) { - // if (toxav_groupchat_enable_av(tox.get(), groupNumber, - // CoreAV::groupCallCallback, this)) { - // qCritical() << "Failed to enable audio on loaded group" << - // groupNumber; - // } - // } - // emit emptyGroupCreated(groupNumber, persistentId, name); - // } - - // delete[] groupNumbers; + QMutexLocker ml{&coreLoopLock}; + + // const size_t groupCount = tox_conference_get_chatlist_size(tox.get()); + // if (groupCount == 0) { + // return; + // } + // + // auto groupNumbers = new uint32_t[groupCount]; + // tox_conference_get_chatlist(tox.get(), groupNumbers); + // + // for (size_t i = 0; i < groupCount; ++i) { + // TOX_ERR_CONFERENCE_TITLE error; + // QString name; + // const auto groupNumber = groupNumbers[i]; + // size_t titleSize = + // tox_conference_get_title_size(tox.get(), groupNumber, &error); + // const GroupId persistentId = getGroupPersistentId(groupNumber); + // const QString defaultName = + // tr("Groupchat %1").arg(persistentId.toString().left(8)); + // if (LogConferenceTitleError(error)) { + // name = defaultName; + // } else { + // QByteArray nameByteArray = + // QByteArray(static_cast(titleSize), Qt::Uninitialized); + // tox_conference_get_title( + // tox.get(), groupNumber, + // reinterpret_cast(nameByteArray.data()), &error); + // if (LogConferenceTitleError(error)) { + // name = defaultName; + // } else { + // name = ToxString(nameByteArray).getQString(); + // } + // } + // if (getGroupAvEnabled(groupNumber)) { + // if (toxav_groupchat_enable_av(tox.get(), groupNumber, + // CoreAV::groupCallCallback, this)) { + // qCritical() << "Failed to enable audio on loaded group" << + // groupNumber; + // } + // } + // emit emptyGroupCreated(groupNumber, persistentId, name); + // } + + // delete[] groupNumbers; } void Core::checkLastOnline(QString friendId) { - QMutexLocker ml{&coreLoopLock}; + QMutexLocker ml{&coreLoopLock}; - // const uint64_t lastOnline = - // tox_friend_get_last_online(tox.get(), receiver, nullptr); - // if (lastOnline != std::numeric_limits::max()) { - // emit friendLastSeenChanged(receiver, QDateTime::fromTime_t(lastOnline)); - // } + // const uint64_t lastOnline = + // tox_friend_get_last_online(tox.get(), receiver, nullptr); + // if (lastOnline != std::numeric_limits::max()) { + // emit friendLastSeenChanged(receiver, + // QDateTime::fromTime_t(lastOnline)); + // } } /** * @brief Returns the list of friendIds in our friendlist, an empty list on * error */ -void Core::loadFriendList(std::list &friends) const { - QMutexLocker ml{&coreLoopLock}; - - std::list fs; - tox->getFriendList(fs); +void Core::loadFriendList(std::list& friends) const { + QMutexLocker ml{&coreLoopLock}; - for (auto &f :fs) { - auto x= FriendInfo{f}; - friends.push_back(x); - } + std::list fs; + tox->getFriendList(fs); + for (auto& f : fs) { + auto x = FriendInfo{f}; + friends.push_back(x); + } } GroupId Core::getGroupPersistentId(QString groupId) const { - QMutexLocker ml{&coreLoopLock}; - return GroupId{groupId.toUtf8()}; + QMutexLocker ml{&coreLoopLock}; + return GroupId{groupId.toUtf8()}; } /** @@ -1130,112 +1018,113 @@ GroupId Core::getGroupPersistentId(QString groupId) const { * @return The number of peers in the conference. UINT32_MAX on failure. */ uint32_t Core::getGroupNumberPeers(QString groupId) const { - QMutexLocker ml{&coreLoopLock}; - qDebug() << "getGroupNumberPeers:" << groupId; + QMutexLocker ml{&coreLoopLock}; + qDebug() << "getGroupNumberPeers:" << groupId; - // Tox_Err_Conference_Peer_Query error; - // uint32_t count = tox_conference_peer_count(tox.get(), groupId, &error); - // if (!parsePeerQueryError(error)) { - // return std::numeric_limits::max(); - // } + // Tox_Err_Conference_Peer_Query error; + // uint32_t count = tox_conference_peer_count(tox.get(), groupId, &error); + // if (!parsePeerQueryError(error)) { + // return std::numeric_limits::max(); + // } - // return count; - return 0; + // return count; + return 0; } /** * @brief Get the name of a peer of a group */ QString Core::getGroupPeerName(QString groupId, QString peerId) const { - QMutexLocker ml{&coreLoopLock}; + QMutexLocker ml{&coreLoopLock}; - // from tox.h: "If peer_number == UINT32_MAX, then author is unknown (e.g. - // initial joining the conference)." - if (peerId == std::numeric_limits::max()) { - return {}; - } - - // Tox_Err_Conference_Peer_Query error; - // size_t length = - // tox_conference_peer_get_name_size(tox.get(), groupId, peerId, &error); - // if (!parsePeerQueryError(error)) { - // return QString{}; - // } - // - // QByteArray name(length, Qt::Uninitialized); - // uint8_t *namePtr = reinterpret_cast(name.data()); - // bool success = - // tox_conference_peer_get_name(tox.get(), groupId, peerId, namePtr, - // &error); - // if (!parsePeerQueryError(error)) { - // return QString{}; - // } - // assert(success); - - // return ToxString(name).getQString(); - return QString{}; + // from tox.h: "If peer_number == UINT32_MAX, then author is unknown (e.g. + // initial joining the conference)." + if (peerId == std::numeric_limits::max()) { + return {}; + } + + // Tox_Err_Conference_Peer_Query error; + // size_t length = + // tox_conference_peer_get_name_size(tox.get(), groupId, peerId, + // &error); + // if (!parsePeerQueryError(error)) { + // return QString{}; + // } + // + // QByteArray name(length, Qt::Uninitialized); + // uint8_t *namePtr = reinterpret_cast(name.data()); + // bool success = + // tox_conference_peer_get_name(tox.get(), groupId, peerId, namePtr, + // &error); + // if (!parsePeerQueryError(error)) { + // return QString{}; + // } + // assert(success); + + // return ToxString(name).getQString(); + return QString{}; } /** * @brief Get the public key of a peer of a group */ ToxPeer Core::getGroupPeerPk(QString groupId, QString peerId) const { - QMutexLocker ml{&coreLoopLock}; + QMutexLocker ml{&coreLoopLock}; - // uint8_t friendPk[TOX_PUBLIC_KEY_SIZE] = {0x00}; - // Tox_Err_Conference_Peer_Query error; - // bool success = tox_conference_peer_get_public_key(tox.get(), groupId, - // peerId, - // friendPk, &error); - // if (!parsePeerQueryError(error)) { - // return ToxPk{}; - // } - // assert(success); + // uint8_t friendPk[TOX_PUBLIC_KEY_SIZE] = {0x00}; + // Tox_Err_Conference_Peer_Query error; + // bool success = tox_conference_peer_get_public_key(tox.get(), groupId, + // peerId, + // friendPk, &error); + // if (!parsePeerQueryError(error)) { + // return ToxPk{}; + // } + // assert(success); - auto toxPk = ToxPeer{peerId}; - return toxPk; + auto toxPk = ToxPeer{peerId}; + return toxPk; } /** * @brief Get the names of the peers of a group */ QStringList Core::getGroupPeerNames(QString groupId) const { - QMutexLocker ml{&coreLoopLock}; + QMutexLocker ml{&coreLoopLock}; - assert(tox != nullptr); + assert(tox != nullptr); - uint32_t nPeers = getGroupNumberPeers(groupId); - if (nPeers == std::numeric_limits::max()) { - qWarning() << "getGroupPeerNames: Unable to get number of peers"; - return {}; - } - - QStringList names; - // for (uint32_t i = 0; i < nPeers; ++i) { - // TOX_ERR_CONFERENCE_PEER_QUERY error; - // size_t length = - // tox_conference_peer_get_name_size(tox.get(), groupId, i, &error); - // if (!parsePeerQueryError(error)) { - // names.append(QString()); - // continue; - // } - // - // QByteArray name(length, Qt::Uninitialized); - // uint8_t *namePtr = reinterpret_cast(name.data()); - // bool ok = - // tox_conference_peer_get_name(tox.get(), groupId, i, namePtr, - // &error); - // if (ok && parsePeerQueryError(error)) { - // names.append(ToxString(name).getQString()); - // } else { - // names.append(QString()); - // } - // } - - // names.append("user1"); - // names.append("user2"); - // assert(names.size() == nPeers); - return names; + uint32_t nPeers = getGroupNumberPeers(groupId); + if (nPeers == std::numeric_limits::max()) { + qWarning() << "getGroupPeerNames: Unable to get number of peers"; + return {}; + } + + QStringList names; + // for (uint32_t i = 0; i < nPeers; ++i) { + // TOX_ERR_CONFERENCE_PEER_QUERY error; + // size_t length = + // tox_conference_peer_get_name_size(tox.get(), groupId, i, &error); + // if (!parsePeerQueryError(error)) { + // names.append(QString()); + // continue; + // } + // + // QByteArray name(length, Qt::Uninitialized); + // uint8_t *namePtr = reinterpret_cast(name.data()); + // bool ok = + // tox_conference_peer_get_name(tox.get(), groupId, i, namePtr, + // &error); + // if (ok && parsePeerQueryError(error)) { + // names.append(ToxString(name).getQString()); + // } else { + // names.append(QString()); + // } + // } + + // names.append("user1"); + // names.append("user2"); + // assert(names.size() == nPeers); + return names; } /** @@ -1244,135 +1133,135 @@ QStringList Core::getGroupPeerNames(QString groupId) const { * @return True for AV groups, false for text-only groups */ bool Core::getGroupAvEnabled(QString groupId) const { - QMutexLocker ml{&coreLoopLock}; - // TOX_ERR_CONFERENCE_GET_TYPE error; - // TOX_CONFERENCE_TYPE type = - // tox_conference_get_type(tox.get(), groupId, &error); - // switch (error) { - // case TOX_ERR_CONFERENCE_GET_TYPE_OK: - // break; - // case TOX_ERR_CONFERENCE_GET_TYPE_CONFERENCE_NOT_FOUND: - // qWarning() << "Conference not found"; - // break; - // default: - // qWarning() << "Unknown error code:" << QString::number(error); - // break; - // } - - // return type == TOX_CONFERENCE_TYPE_AV; - return true; + QMutexLocker ml{&coreLoopLock}; + // TOX_ERR_CONFERENCE_GET_TYPE error; + // TOX_CONFERENCE_TYPE type = + // tox_conference_get_type(tox.get(), groupId, &error); + // switch (error) { + // case TOX_ERR_CONFERENCE_GET_TYPE_OK: + // break; + // case TOX_ERR_CONFERENCE_GET_TYPE_CONFERENCE_NOT_FOUND: + // qWarning() << "Conference not found"; + // break; + // default: + // qWarning() << "Unknown error code:" << QString::number(error); + // break; + // } + + // return type == TOX_CONFERENCE_TYPE_AV; + return true; } - /** * @brief Accept a groupchat invite. * @param inviteInfo Object which contains info about group invitation * * @return Conference number on success, UINT32_MAX on failure. */ -QString Core::joinGroupchat(const GroupInvite &inviteInfo) { - QMutexLocker ml{&coreLoopLock}; - - tox->joinGroup(inviteInfo.getGroupId()); - - // const QString receiver = inviteInfo.getFriendId(); - // const uint8_t confType = inviteInfo.getType(); - // const QByteArray invite = inviteInfo.getInvite(); - // const uint8_t *const cookie = reinterpret_cast(invite.data()); const size_t cookieLength = invite.length(); QString - // groupNum{std::numeric_limits::max()}; - - // switch (confType) { - // case TOX_CONFERENCE_TYPE_TEXT: { - // qDebug() << QString( - // "Trying to join text groupchat invite sent by friend - // %1") .arg(receiver); - // Tox_Err_Conference_Join error; - // groupNum = tox_conference_join(tox.get(), receiver, cookie, - // cookieLength, &error); if (!parseConferenceJoinError(error)) { - // groupNum = std::numeric_limits::max(); - // } - // break; - // } - // case TOX_CONFERENCE_TYPE_AV: { - // qDebug() << QString("Trying to join AV groupchat invite sent by friend - // %1") - // .arg(receiver); - // groupNum = toxav_join_av_groupchat(tox.get(), receiver, cookie, - // cookieLength, - // CoreAV::groupCallCallback, - // const_cast(this)); - // break; - // } - // default: - // qWarning() << "joinGroupchat: Unknown groupchat type " << confType; - // } - // if (groupNum != std::numeric_limits::max()) { - // emit saveRequest(); - // emit groupJoined(groupNum, getGroupPersistentId(groupNum)); - // } - // return groupNum; - return {}; -} - -void Core::joinRoom(const QString &groupId) { - tox->joinGroup(groupId); -} - -void Core::inviteToGroup(const ContactId &friendId, const GroupId& groupId) { - QMutexLocker ml{&coreLoopLock}; - tox->inviteGroup(lib::messenger::IMContactId{groupId.toString()}, lib::messenger::IMContactId{friendId.toString()}); +QString Core::joinGroupchat(const GroupInvite& inviteInfo) { + QMutexLocker ml{&coreLoopLock}; + + tox->joinGroup(inviteInfo.getGroupId()); + + // const QString receiver = inviteInfo.getFriendId(); + // const uint8_t confType = inviteInfo.getType(); + // const QByteArray invite = inviteInfo.getInvite(); + // const uint8_t *const cookie = reinterpret_cast(invite.data()); const size_t cookieLength = invite.length(); QString + // groupNum{std::numeric_limits::max()}; + + // switch (confType) { + // case TOX_CONFERENCE_TYPE_TEXT: { + // qDebug() << QString( + // "Trying to join text groupchat invite sent by friend + // %1") .arg(receiver); + // Tox_Err_Conference_Join error; + // groupNum = tox_conference_join(tox.get(), receiver, cookie, + // cookieLength, &error); if (!parseConferenceJoinError(error)) { + // groupNum = std::numeric_limits::max(); + // } + // break; + // } + // case TOX_CONFERENCE_TYPE_AV: { + // qDebug() << QString("Trying to join AV groupchat invite sent by friend + // %1") + // .arg(receiver); + // groupNum = toxav_join_av_groupchat(tox.get(), receiver, cookie, + // cookieLength, + // CoreAV::groupCallCallback, + // const_cast(this)); + // break; + // } + // default: + // qWarning() << "joinGroupchat: Unknown groupchat type " << confType; + // } + // if (groupNum != std::numeric_limits::max()) { + // emit saveRequest(); + // emit groupJoined(groupNum, getGroupPersistentId(groupNum)); + // } + // return groupNum; + return {}; +} + +void Core::joinRoom(const QString& groupId) { tox->joinGroup(groupId); } + +void Core::inviteToGroup(const ContactId& friendId, const GroupId& groupId) { + QMutexLocker ml{&coreLoopLock}; + tox->inviteGroup(lib::messenger::IMContactId{groupId.toString()}, + lib::messenger::IMContactId{friendId.toString()}); } GroupId Core::createGroup(const QString& name) { - qDebug() << __func__ << name; + qDebug() << __func__ << name; - QMutexLocker ml{&coreLoopLock}; - QString id = QUuid::createUuid().toString(QUuid::StringFormat::WithoutBraces); + QMutexLocker ml{&coreLoopLock}; + QString id = + QUuid::createUuid().toString(QUuid::StringFormat::WithoutBraces); - return GroupId{ tox->createGroup(id.split("-").at(0), name)}; + return GroupId{tox->createGroup(id.split("-").at(0), name)}; } /** * @brief Checks if a friend is online. Unknown friends are considered offline. */ bool Core::isFriendOnline(QString friendId) const { - QMutexLocker ml{&coreLoopLock}; - // - // Tox_Connection connection = - // tox_friend_get_connection_status(tox.get(), receiver, nullptr); - // return connection != TOX_CONNECTION_NONE; - return false; + QMutexLocker ml{&coreLoopLock}; + // + // Tox_Connection connection = + // tox_friend_get_connection_status(tox.get(), receiver, nullptr); + // return connection != TOX_CONNECTION_NONE; + return false; } /** * @brief Checks if we have a friend by public key */ -bool Core::hasFriendWithPublicKey(const FriendId &publicKey) const { - // QMutexLocker ml{&coreLoopLock}; - // - // if (publicKey.isEmpty()) { - // return false; - // } - // - // QString receiver = tox_friend_by_public_key(tox.get(), - // publicKey.getData(), nullptr); return receiver != - // std::numeric_limits::max(); - return false; +bool Core::hasFriendWithPublicKey(const FriendId& publicKey) const { + // QMutexLocker ml{&coreLoopLock}; + // + // if (publicKey.isEmpty()) { + // return false; + // } + // + // QString receiver = tox_friend_by_public_key(tox.get(), + // publicKey.getData(), nullptr); return receiver != + // std::numeric_limits::max(); + return false; } /** * @brief Get the public key part of the ToxID only */ inline FriendId Core::getFriendPublicKey(QString friendNumber) const { - //qDebug() << "getFriendPublicKey" << friendNumber; - // QMutexLocker ml{&coreLoopLock}; - // uint8_t rawid[TOX_PUBLIC_KEY_SIZE]; - // if (!tox_friend_get_public_key(tox.get(), friendNumber, rawid, nullptr)) { - // qWarning() << "getFriendPublicKey: Getting public key failed"; - // return ToxPk(); - // } - return FriendId(friendNumber.toUtf8()); + // qDebug() << "getFriendPublicKey" << friendNumber; + // QMutexLocker ml{&coreLoopLock}; + // uint8_t rawid[TOX_PUBLIC_KEY_SIZE]; + // if (!tox_friend_get_public_key(tox.get(), friendNumber, rawid, + // nullptr)) { + // qWarning() << "getFriendPublicKey: Getting public key failed"; + // return ToxPk(); + // } + return FriendId(friendNumber.toUtf8()); } QString Core::getFriendUsername(QString friendnumber) const { @@ -1380,150 +1269,147 @@ QString Core::getFriendUsername(QString friendnumber) const { return {}; } -void Core::setFriendAlias(const QString &friendId, const QString &alias) -{ +void Core::setFriendAlias(const QString& friendId, const QString& alias) { tox->setFriendAlias(friendId, alias); } void Core::getFriendInfo(const QString& friendnumber) const { - tox->getFriendVCard(friendnumber); -} - -Status::Status Core::getFriendStatus(const QString &friendNumber) const { - auto status= tox->getFriendStatus(friendNumber); - return status == lib::messenger::IMStatus::Available - ? Status::Status::Online : Status::Status::Offline; -} - -QStringList Core::splitMessage(const QString &message) { - QStringList splittedMsgs; - QByteArray ba_message{message.toUtf8()}; - - /* - * TODO: Remove this hack; the reported max message length we receive from - * c-toxcore as of 08-02-2019 is inaccurate, causing us to generate too large - * messages when splitting them up. - * - * The inconsistency lies in c-toxcore group.c:2480 using - * MAX_GROUP_MESSAGE_DATA_LEN to verify message size is within limit, but - * tox_max_message_length giving a different size limit to us. - * - * (uint32_t tox_max_message_length(void); declared in tox.h, unable to see - * explicit definition) - */ - const auto maxLen = 1024; - - while (ba_message.size() > maxLen) { - int splitPos = ba_message.lastIndexOf('\n', maxLen - 1); - - if (splitPos <= 0) { - splitPos = ba_message.lastIndexOf(' ', maxLen - 1); - } + tox->getFriendVCard(friendnumber); +} + +Status::Status Core::getFriendStatus(const QString& friendNumber) const { + auto status = tox->getFriendStatus(friendNumber); + return status == lib::messenger::IMStatus::Available + ? Status::Status::Online + : Status::Status::Offline; +} + +QStringList Core::splitMessage(const QString& message) { + QStringList splittedMsgs; + QByteArray ba_message{message.toUtf8()}; + + /* + * TODO: Remove this hack; the reported max message length we receive from + * c-toxcore as of 08-02-2019 is inaccurate, causing us to generate too + * large messages when splitting them up. + * + * The inconsistency lies in c-toxcore group.c:2480 using + * MAX_GROUP_MESSAGE_DATA_LEN to verify message size is within limit, but + * tox_max_message_length giving a different size limit to us. + * + * (uint32_t tox_max_message_length(void); declared in tox.h, unable to see + * explicit definition) + */ + const auto maxLen = 1024; + + while (ba_message.size() > maxLen) { + int splitPos = ba_message.lastIndexOf('\n', maxLen - 1); + + if (splitPos <= 0) { + splitPos = ba_message.lastIndexOf(' ', maxLen - 1); + } - if (splitPos <= 0) { - constexpr uint8_t firstOfMultiByteMask = 0xC0; - constexpr uint8_t multiByteMask = 0x80; - splitPos = maxLen; - // don't split a utf8 character - if ((ba_message[splitPos] & multiByteMask) == multiByteMask) { - while ((ba_message[splitPos] & firstOfMultiByteMask) != - firstOfMultiByteMask) { - --splitPos; + if (splitPos <= 0) { + constexpr uint8_t firstOfMultiByteMask = 0xC0; + constexpr uint8_t multiByteMask = 0x80; + splitPos = maxLen; + // don't split a utf8 character + if ((ba_message[splitPos] & multiByteMask) == multiByteMask) { + while ((ba_message[splitPos] & firstOfMultiByteMask) != + firstOfMultiByteMask) { + --splitPos; + } + } + --splitPos; } - } - --splitPos; + splittedMsgs.append(QString{ba_message.left(splitPos + 1)}); + ba_message = ba_message.mid(splitPos + 1); } - splittedMsgs.append(QString{ba_message.left(splitPos + 1)}); - ba_message = ba_message.mid(splitPos + 1); - } - - splittedMsgs.append(QString{ba_message}); - return splittedMsgs; -} - -QString Core::getPeerName(const FriendId &id) const { - QMutexLocker ml{&coreLoopLock}; - - QString name; - // QString receiver = tox_friend_by_public_key(tox.get(), id.getData(), - // nullptr); if (receiver == std::numeric_limits::max()) { - // qWarning() << "getPeerName: No such peer"; - // return name; - // } - // - // const size_t nameSize = - // tox_friend_get_name_size(tox.get(), receiver, nullptr); - // if (nameSize == SIZE_MAX) { - // return name; - // } - // - // uint8_t *cname = - // new uint8_t[nameSize < tox_max_name_length() ? tox_max_name_length() - // : nameSize]; - // if (!tox_friend_get_name(tox.get(), receiver, cname, nullptr)) { - // qWarning() << "getPeerName: Can't get name of friend " + - // QString().setNum(receiver); - // delete[] cname; - // return name; - // } - // - // name = ToxString(cname, nameSize).getQString(); - // delete[] cname; - return name; + + splittedMsgs.append(QString{ba_message}); + return splittedMsgs; +} + +QString Core::getPeerName(const FriendId& id) const { + QMutexLocker ml{&coreLoopLock}; + + QString name; + // QString receiver = tox_friend_by_public_key(tox.get(), id.getData(), + // nullptr); if (receiver == std::numeric_limits::max()) { + // qWarning() << "getPeerName: No such peer"; + // return name; + // } + // + // const size_t nameSize = + // tox_friend_get_name_size(tox.get(), receiver, nullptr); + // if (nameSize == SIZE_MAX) { + // return name; + // } + // + // uint8_t *cname = + // new uint8_t[nameSize < tox_max_name_length() ? tox_max_name_length() + // : nameSize]; + // if (!tox_friend_get_name(tox.get(), receiver, cname, nullptr)) { + // qWarning() << "getPeerName: Can't get name of friend " + + // QString().setNum(receiver); + // delete[] cname; + // return name; + // } + // + // name = ToxString(cname, nameSize).getQString(); + // delete[] cname; + return name; } void Core::logout() { tox->stop(); } void Core::onSelfNameChanged(QString name) { - QMutexLocker ml{&coreLoopLock}; -// qDebug()<<"onSelfNameChanged:"<setNick(name, false); + emit usernameSet(name); } void Core::onSelfAvatarChanged(const std::string avatar) { - QMutexLocker ml{&coreLoopLock}; - - auto a = QByteArray::fromStdString(avatar); + QMutexLocker ml{&coreLoopLock}; -// emit avatarSet(a); - auto p = Nexus::getProfile(); - if (!p) { - qWarning() << "Can not get profile!"; - return; - } - p->setAvatar(a); + auto a = QByteArray::fromStdString(avatar); + // emit avatarSet(a); + auto p = Nexus::getProfile(); + if (!p) { + qWarning() << "Can not get profile!"; + return; + } + p->setAvatar(a, false); } void Core::onSelfStatusChanged(lib::messenger::IMStatus userStatus, - const std::string &msg) { - QMutexLocker ml{&coreLoopLock}; - auto st = fromToxStatus(userStatus); - emit statusSet(st); - auto t = getTitle(st); - if (!msg.empty()) { - t.append(": ").append(msg.data()); - } - emit statusMessageSet(t); + const std::string& msg) { + QMutexLocker ml{&coreLoopLock}; + auto st = fromToxStatus(userStatus); + emit statusSet(st); + auto t = getTitle(st); + if (!msg.empty()) { + t.append(": ").append(msg.data()); + } + emit statusMessageSet(t); } void Core::onSelfIdChanged(QString id) { - QMutexLocker ml{&coreLoopLock}; - emit idSet(ToxId(id)); + QMutexLocker ml{&coreLoopLock}; + emit idSet(ToxId(id)); } -void Core::sendReceiptReceived(const QString &friendId, QString receipt) { - qDebug() << "receiver" << friendId << "receipt" << receipt; - tox->receiptReceived(friendId, receipt); +void Core::sendReceiptReceived(const QString& friendId, QString receipt) { + qDebug() << "receiver" << friendId << "receipt" << receipt; + tox->receiptReceived(friendId, receipt); } -void Core::requestBookmarks() { - tox->requestBookmarks(); -} +void Core::requestBookmarks() { tox->requestBookmarks(); } -void Core::setUIStarted() { - tox->setUIStarted(); -} -void Core::loadGroupList() const { - tox->loadGroupList(); -} +void Core::loadGroupList() const { tox->loadGroupList(); } diff --git a/src/modules/im/src/core/core.h b/src/modules/im/src/core/core.h index b9cb89fc..b84b9d9e 100644 --- a/src/modules/im/src/core/core.h +++ b/src/modules/im/src/core/core.h @@ -50,6 +50,10 @@ class Core; using ToxCorePtr = std::unique_ptr; +/** + * IM Core 聊天核心 + * 维护av(音视频)、file(文件传输) + */ class Core : public QObject, public ICoreIdHandler, public ICoreFriendMessageSender, @@ -58,275 +62,284 @@ class Core : public QObject, public lib::messenger::FriendHandler, public lib::messenger::GroupHandler, public lib::messenger::SelfHandler { - Q_OBJECT - + Q_OBJECT public: - enum class ToxCoreErrors { BAD_PROXY, INVALID_SAVE, FAILED_TO_START, ERROR_ALLOC }; - - static ToxCorePtr makeToxCore(const QByteArray &savedata, const ICoreSettings *const settings, ToxCoreErrors *err = nullptr); - static Core *getInstance(); -// const CoreAV *getAv() const; -// CoreAV *getAv(); - CoreFile *getCoreFile() const; - ~Core(); - - static const QString TOX_EXT; - static QStringList splitMessage(const QString &message); - QString getPeerName(const FriendId &id) const; - void loadFriendList(std::list &) const; - - void loadGroupList() const; - GroupId getGroupPersistentId(QString groupId) const override; - uint32_t getGroupNumberPeers(QString groupId) const override; - QString getGroupPeerName(QString groupId, QString peerId) const override; - ToxPeer getGroupPeerPk(QString groupId, QString peerId) const override; - QStringList getGroupPeerNames(QString groupId) const override; - bool getGroupAvEnabled(QString groupId) const override; - FriendId getFriendPublicKey(QString friendNumber) const; - - QString getFriendUsername(QString friendNumber) const; - void setFriendAlias(const QString &friendId, const QString &alias); - - void getFriendInfo(const QString &friendNumber) const; - Status::Status getFriendStatus(const QString &friendNumber) const; - - bool isFriendOnline(QString friendId) const; - bool hasFriendWithPublicKey(const FriendId &publicKey) const; - QString joinGroupchat(const GroupInvite &inviteInfo); - void joinRoom(const QString &groupId); - void quitGroupChat(const QString &groupId) const; - - QString getUsername() const override; - QString getNick() const override; - Status::Status getStatus() const; - QString getStatusMessage() const; - ToxId getSelfPeerId() const override; - FriendId getSelfId() const override; - QPair getKeypair() const; - - void sendFile(QString friendId, QString filename, QString filePath, long long filesize); - - void requestBookmarks(); - void setUIStarted(); - - void start(); - void stop(); - - QByteArray getToxSaveData(); - - void acceptFriendRequest(const FriendId &friendPk); - void rejectFriendRequest(const FriendId &friendPk); - void removeFriend(QString friendId); - void requestFriendship(const FriendId &friendAddress, const QString &nick, const QString &message); - // FriendSender - bool sendMessage(QString friendId, const QString &message, const MsgId &msgId, bool encrypt = false) override; - bool sendAction(QString friendId, const QString &action, const MsgId &msgId, bool encrypt = false) override; - void sendTyping(QString friendId, bool typing); - - GroupId createGroup(const QString &name=""); - void inviteToGroup(const ContactId &friendId, const GroupId& groupId); - void leaveGroup(QString groupId); - void destroyGroup(QString groupId); - - void setStatus(Status::Status status); - void setUsername(const QString &username); - void setPassword(const QString &password); - void setStatusMessage(const QString &message); - void setAvatar(const QByteArray &avatar); - - // GroupSender - bool sendGroupMessage(QString groupId, const QString &message, const MsgId& id) override; - bool sendGroupAction(QString groupId, const QString &message, const MsgId& id) override; - - void setGroupName(const QString &groupId, const QString &name); - void setGroupSubject(const QString &groupId, const QString &subject); - void setGroupDesc(const QString &groupId, const QString &desc); - void setGroupAlias(const QString &groupId, const QString &alias); - - - - void logout(); + enum class ToxCoreErrors { BAD_PROXY, INVALID_SAVE, FAILED_TO_START, ERROR_ALLOC }; + + static ToxCorePtr makeToxCore(const QString& host, + const QString& name, + const QString& password, + const QByteArray& savedata, + const ICoreSettings* const settings, + ToxCoreErrors* err = nullptr); + static Core* getInstance(); + // const CoreAV *getAv() const; + // CoreAV *getAv(); + CoreFile* getCoreFile() const; + ~Core(); + lib::messenger::Messenger* getMessenger() { return tox.get(); } + static const QString TOX_EXT; + static QStringList splitMessage(const QString& message); + QString getPeerName(const FriendId& id) const; + void loadFriendList(std::list&) const; + + void loadGroupList() const; + GroupId getGroupPersistentId(QString groupId) const override; + uint32_t getGroupNumberPeers(QString groupId) const override; + QString getGroupPeerName(QString groupId, QString peerId) const override; + ToxPeer getGroupPeerPk(QString groupId, QString peerId) const override; + QStringList getGroupPeerNames(QString groupId) const override; + bool getGroupAvEnabled(QString groupId) const override; + FriendId getFriendPublicKey(QString friendNumber) const; + + QString getFriendUsername(QString friendNumber) const; + void setFriendAlias(const QString& friendId, const QString& alias); + + void getFriendInfo(const QString& friendNumber) const; + Status::Status getFriendStatus(const QString& friendNumber) const; + + bool isFriendOnline(QString friendId) const; + bool hasFriendWithPublicKey(const FriendId& publicKey) const; + QString joinGroupchat(const GroupInvite& inviteInfo); + void joinRoom(const QString& groupId); + void quitGroupChat(const QString& groupId) const; + + QString getUsername() const override; + QString getNick() const override; + Status::Status getStatus() const; + QString getStatusMessage() const; + ToxId getSelfPeerId() const override; + FriendId getSelfId() const override; + QPair getKeypair() const; + + void sendFile(QString friendId, QString filename, QString filePath, long long filesize); + + void requestBookmarks(); + + void start(); + void stop(); + + QByteArray getToxSaveData(); + + void acceptFriendRequest(const FriendId& friendPk); + void rejectFriendRequest(const FriendId& friendPk); + void removeFriend(QString friendId); + void requestFriendship(const FriendId& friendAddress, const QString& nick, + const QString& message); + // FriendSender + bool sendMessage(QString friendId, const QString& message, const MsgId& msgId, + bool encrypt = false) override; + bool sendAction(QString friendId, const QString& action, const MsgId& msgId, + bool encrypt = false) override; + void sendTyping(QString friendId, bool typing); + + GroupId createGroup(const QString& name = ""); + void inviteToGroup(const ContactId& friendId, const GroupId& groupId); + void leaveGroup(QString groupId); + void destroyGroup(QString groupId); + + void setStatus(Status::Status status); + void setNick(const QString& nick); + void setPassword(const QString& password); + void setStatusMessage(const QString& message); + void setAvatar(const QByteArray& avatar); + + // GroupSender + bool sendGroupMessage(QString groupId, const QString& message, const MsgId& id) override; + bool sendGroupAction(QString groupId, const QString& message, const MsgId& id) override; + + void setGroupName(const QString& groupId, const QString& name); + void setGroupSubject(const QString& groupId, const QString& subject); + void setGroupDesc(const QString& groupId, const QString& desc); + void setGroupAlias(const QString& groupId, const QString& alias); + + void logout(); signals: - void connected(); - void disconnected(); + void started(); + void connected(); + void disconnected(); - void friendRequestReceived(const FriendId &friendPk, const QString &message); - void friendAvatarChanged(const FriendId &friendPk, const QByteArray &avatar); - void friendAliasChanged(const FriendId &fId, const QString &alias); - void friendAvatarRemoved(const FriendId &friendPk); + void friendRequestReceived(const FriendId& friendPk, const QString& message); + void friendAvatarChanged(const FriendId& friendPk, const QByteArray& avatar); + void friendAliasChanged(const FriendId& fId, const QString& alias); + void friendAvatarRemoved(const FriendId& friendPk); - void requestSent(const FriendId &friendPk, const QString &message); - void failedToAddFriend(const FriendId &friendPk, const QString &errorInfo = QString()); + void requestSent(const FriendId& friendPk, const QString& message); + void failedToAddFriend(const FriendId& friendPk, const QString& errorInfo = QString()); - void usernameSet(const QString &username); - void avatarSet(QByteArray avatar); - void statusMessageSet(const QString &message); - void statusSet(Status::Status status); - void idSet(const ToxId &id); + void usernameSet(const QString& username); + void avatarSet(QByteArray avatar); + void statusMessageSet(const QString& message); + void statusSet(Status::Status status); + void idSet(const ToxId& id); - void failedToSetUsername(const QString &username); - void failedToSetStatusMessage(const QString &message); - void failedToSetStatus(Status::Status status); - void failedToSetTyping(bool typing); + void failedToSetUsername(const QString& username); + void failedToSetStatusMessage(const QString& message); + void failedToSetStatus(Status::Status status); + void failedToSetTyping(bool typing); - void avReady(); + void avReady(); - void saveRequest(); + void saveRequest(); - void fileAvatarOfferReceived(QString friendId, // - QString fileId, // - const QByteArray &avatarHash); + void fileAvatarOfferReceived(QString friendId, // + QString fileId, // + const QByteArray& avatarHash); - void messageSessionReceived(const ContactId &cId, const QString &sid); + void messageSessionReceived(const ContactId& cId, const QString& sid); - void friendMessageReceived(const FriendId &friendId, // - const FriendMessage &message, // - bool isAction); + void friendMessageReceived(const FriendId& friendId, // + const FriendMessage& message, // + bool isAction); - void friendAdded(const FriendInfo frnd); + void friendAdded(const FriendInfo frnd); - void friendStatusChanged(const FriendId &friendId, Status::Status status); - void friendStatusMessageChanged(const FriendId &friendId, const QString &message); - void friendUsernameChanged(const FriendId &friendPk, const QString &username); - void friendTypingChanged(const FriendId &friendId, bool isTyping); + void friendStatusChanged(const FriendId& friendId, Status::Status status); + void friendStatusMessageChanged(const FriendId& friendId, const QString& message); + void friendUsernameChanged(const FriendId& friendPk, const QString& username); + void friendTypingChanged(const FriendId& friendId, bool isTyping); - void friendRemoved(QString friendId); - void friendLastSeenChanged(QString friendId, const QDateTime &dateTime); + void friendRemoved(QString friendId); + void friendLastSeenChanged(QString friendId, const QDateTime& dateTime); - void emptyGroupCreated(QString groupnumber, const GroupId groupId, const QString &title = QString()); - void groupInviteReceived(const GroupInvite &inviteInfo); + void emptyGroupCreated(QString groupnumber, const GroupId groupId, + const QString& title = QString()); + void groupInviteReceived(const GroupInvite& inviteInfo); - void groupSubjectChanged(GroupId groupId, QString subject); + void groupSubjectChanged(GroupId groupId, QString subject); - void groupMessageReceived(GroupId groupId, GroupMessage msg); + void groupMessageReceived(GroupId groupId, GroupMessage msg); - void groupNamelistChanged(QString groupnumber, QString peerId, uint8_t change); + void groupNamelistChanged(QString groupnumber, QString peerId, uint8_t change); - void groupPeerlistChanged(QString groupnumber); + void groupPeerlistChanged(QString groupnumber); - void groupPeerSizeChanged(QString groupnumber, const uint size); + void groupPeerSizeChanged(QString groupnumber, const uint size); - void groupPeerStatusChanged(QString groupnumber, GroupOccupant go); + void groupPeerStatusChanged(QString groupnumber, GroupOccupant go); - void groupPeerNameChanged(QString groupnumber, const FriendId &peerPk, const QString &newName); + void groupPeerNameChanged(QString groupnumber, const FriendId& peerPk, const QString& newName); - void groupInfoReceipt(const GroupId &groupId, const GroupInfo &info); + void groupInfoReceipt(const GroupId& groupId, const GroupInfo& info); - void groupPeerAudioPlaying(QString groupnumber, FriendId peerPk); + void groupPeerAudioPlaying(QString groupnumber, FriendId peerPk); - void groupSentFailed(QString groupId); + void groupSentFailed(QString groupId); - void groupAdded(const GroupId &groupId, const QString &name); + void groupAdded(const GroupId& groupId, const QString& name); - void actionSentResult(QString friendId, const QString &action, int success); + void actionSentResult(QString friendId, const QString& action, int success); - void receiptRecieved(const FriendId &friedId, MsgId receipt); + void receiptRecieved(const FriendId& friedId, MsgId receipt); - void failedToRemoveFriend(QString friendId); + void failedToRemoveFriend(QString friendId); private: - Core(QThread *coreThread); + Core(QThread* coreThread); - /** - * SelfHandler - */ - virtual void onSelfIdChanged(QString id) override; - virtual void onSelfNameChanged(QString name) override; - virtual void onSelfAvatarChanged(const std::string avatar) override; - virtual void onSelfStatusChanged(lib::messenger::IMStatus status, const std::string &msg) override; + /** + * SelfHandler + */ + virtual void onSelfIdChanged(QString id) override; + virtual void onSelfNameChanged(QString name) override; + virtual void onSelfAvatarChanged(const std::string avatar) override; + virtual void onSelfStatusChanged(lib::messenger::IMStatus status, + const std::string& msg) override; - bool sendGroupMessageWithType(QString groupId, const QString &message,const MsgId &msgId); + bool sendGroupMessageWithType(QString groupId, const QString& message, const MsgId& msgId); - bool sendMessageWithType(QString friendId, const QString &message, - const MsgId &msgId, bool encrypt = false); + bool sendMessageWithType(QString friendId, const QString& message, const MsgId& msgId, + bool encrypt = false); - void sendReceiptReceived(const QString &friendId, QString receipt); + void sendReceiptReceived(const QString& friendId, QString receipt); - bool checkConnection(); + bool checkConnection(); - void makeTox(QByteArray savedata, ICoreSettings *s); - void loadFriends(); - void loadGroups(); - void bootstrapDht(); + void makeTox(QByteArray savedata, ICoreSettings* s); + void loadFriends(); + void loadGroups(); + void bootstrapDht(); - void checkLastOnline(QString friendId); + void checkLastOnline(QString friendId); - QString getFriendRequestErrorMessage(const ToxId &friendId, const QString &message) const; - void registerCallbacks(Tox *tox); + QString getFriendRequestErrorMessage(const ToxId& friendId, const QString& message) const; + void registerCallbacks(lib::messenger::Messenger* messenger); - /** - * FriendHandler - * @param list - */ + /** + * FriendHandler + * @param list + */ - virtual void onFriend(const lib::messenger::IMFriend &frnd) override; + virtual void onFriend(const lib::messenger::IMFriend& frnd) override; - virtual void onFriendRequest(const QString friendId, QString name) override; + virtual void onFriendRequest(const QString friendId, QString name) override; - virtual void onFriendRemoved(QString friendId) override; + virtual void onFriendRemoved(QString friendId) override; - virtual void onFriendStatus(QString friendId, lib::messenger::IMStatus status) override; + virtual void onFriendStatus(QString friendId, lib::messenger::IMStatus status) override; - virtual void onFriendMessage(QString friendId, lib::messenger::IMMessage message) override; + virtual void onFriendMessage(QString friendId, lib::messenger::IMMessage message) override; - virtual void onMessageSession(QString cId, QString sid) override; + virtual void onMessageSession(QString cId, QString sid) override; - virtual void onFriendChatState(QString friendId, int state) override; + virtual void onFriendChatState(QString friendId, int state) override; - virtual void onFriendNameChanged(QString friendId, QString name) override; + virtual void onFriendNickChanged(QString friendId, QString nick) override; - virtual void onFriendAvatarChanged(const QString friendId, const std::string avatar) override; + virtual void onFriendAvatarChanged(const QString friendId, const std::string avatar) override; - virtual void onFriendAliasChanged(const lib::messenger::IMContactId &fId, const QString &alias) override; - virtual void onMessageReceipt(QString friendId, MsgId receipt) override; + virtual void onFriendAliasChanged(const lib::messenger::IMContactId& fId, + const QString& alias) override; + virtual void onMessageReceipt(QString friendId, MsgId receipt) override; - /** - * GroupHandler - */ - virtual void onGroup(const QString groupId, const QString name) override; + /** + * GroupHandler + */ + virtual void onGroup(const QString groupId, const QString name) override; - virtual void onGroupInvite(const QString groupId, // - const QString peerId, // - const QString message) override; - virtual void onGroupSubjectChanged(const QString &groupId, const QString &subject) override; + virtual void onGroupInvite(const QString groupId, // + const QString peerId, // + const QString message) override; + virtual void onGroupSubjectChanged(const QString& groupId, const QString& subject) override; - virtual void onGroupMessage(const QString groupId, // - const lib::messenger::IMPeerId peerId, // - const lib::messenger::IMMessage message) override; + virtual void onGroupMessage(const QString groupId, // + const lib::messenger::IMPeerId peerId, // + const lib::messenger::IMMessage message) override; - virtual void onGroupInfo(QString groupId, lib::messenger::IMGroup groupInfo) override; + virtual void onGroupInfo(QString groupId, lib::messenger::IMGroup groupInfo) override; - virtual void onGroupOccupants(const QString groupId, uint size) override; + virtual void onGroupOccupants(const QString groupId, uint size) override; - virtual void onGroupOccupantStatus(const QString groupId, lib::messenger::IMGroupOccupant) override; + virtual void onGroupOccupantStatus(const QString groupId, + lib::messenger::IMGroupOccupant) override; private slots: - void process(); - void onStarted(); + void process(); + void onStarted(); private: - struct ToxDeleter { - void operator()(Tox *tox) { - if (tox) { - tox->stop(); - } - } - }; - - using ToxPtr = std::unique_ptr; - ToxPtr tox; - - std::unique_ptr file; -// std::unique_ptr av; - MsgId m_receipt; - QTimer *toxTimer = nullptr; - // recursive, since we might call our own functions - mutable CompatibleRecursiveMutex coreLoopLock; - - std::unique_ptr coreThread = nullptr; - - Status::Status fromToxStatus(const lib::messenger::IMStatus &status) const; + // struct ToxDeleter { + // void operator()(lib::messenger::Messenger *tox) { + // if (tox) { + // tox->stop(); + // } + // } + // }; + + std::unique_ptr tox; + std::unique_ptr file; + std::unique_ptr av; + + MsgId m_receipt; + QTimer* toxTimer = nullptr; + + // recursive, since we might call our own functions + mutable CompatibleRecursiveMutex coreLoopLock; + + std::unique_ptr coreThread = nullptr; + + Status::Status fromToxStatus(const lib::messenger::IMStatus& status) const; }; -#endif // CORE_HPP +#endif // CORE_HPP diff --git a/src/modules/im/src/core/coreav.cpp b/src/modules/im/src/core/coreav.cpp index 095b4770..6ba2f62c 100644 --- a/src/modules/im/src/core/coreav.cpp +++ b/src/modules/im/src/core/coreav.cpp @@ -11,6 +11,12 @@ */ #include "coreav.h" +#include +#include +#include +#include +#include +#include #include "base/compatiblerecursivemutex.h" #include "core.h" #include "src/audio/audio.h" @@ -19,38 +25,55 @@ #include "src/persistence/settings.h" #include "src/video/corevideosource.h" #include "src/video/videoframe.h" -#include -#include -#include -#include -#include -#include /** * 音视频 * @brief CoreAV::CoreAV */ -CoreAV::CoreAV() : audioCtrl{Nexus::getInstance().audio()}, coreavThread{new QThread{this}}, selfVideoSource{std::make_unique()}, iterateTimer{new QTimer{this}} { - assert(coreavThread); - assert(iterateTimer); +static CoreAV* instance = nullptr; - qDebug() << __func__; +CoreAV::CoreAV(Core* core) + : core{core} + , audioCtrl{Nexus::getInstance().audio()} + , coreavThread{new QThread{this}} + , selfVideoSource{std::make_unique()} + , iterateTimer{new QTimer{this}} { + assert(coreavThread); + assert(iterateTimer); - qRegisterMetaType("FriendId"); - qRegisterMetaType("vpx_image"); + qDebug() << __func__; - connect(this, &CoreAV::createCallToPeerId, this, &CoreAV::doCreateCallToPeerId); + qRegisterMetaType("FriendId"); + qRegisterMetaType("vpx_image"); - iterateTimer->setSingleShot(true); - connect(iterateTimer, &QTimer::timeout, this, &CoreAV::process); + connect(this, &CoreAV::createCallToPeerId, this, &CoreAV::doCreateCallToPeerId); - coreavThread->setObjectName("CoreAV"); - connect(coreavThread.get(), &QThread::finished, iterateTimer, &QTimer::stop); - connect(coreavThread.get(), &QThread::started, this, &CoreAV::process); - moveToThread(coreavThread.get()); + iterateTimer->setSingleShot(true); + connect(iterateTimer, &QTimer::timeout, this, &CoreAV::process); - qDebug() << __func__ << "done."; + coreavThread->setObjectName("CoreAV"); + connect(coreavThread.get(), &QThread::finished, iterateTimer, &QTimer::stop); + connect(coreavThread.get(), &QThread::started, this, &CoreAV::process); + moveToThread(coreavThread.get()); + + qDebug() << __func__ << "done."; +} + +CoreAV::~CoreAV() { + /* Gracefully leave calls and group calls to avoid deadlocks in destructor */ + for (const auto& call : calls) { + cancelCall(call.first); + } + for (const auto& call : groupCalls) { + leaveGroupCall(call.first); + } + + assert(calls.empty()); + assert(groupCalls.empty()); + + coreavThread->exit(0); + coreavThread->wait(); } /** @@ -58,15 +81,16 @@ CoreAV::CoreAV() : audioCtrl{Nexus::getInstance().audio()}, coreavThread{new QTh * @param core pointer to the Tox instance * @return CoreAV instance on success, {} on failure */ -CoreAV::CoreAVPtr CoreAV::makeCoreAV() { return CoreAVPtr{new CoreAV}; } +CoreAV::CoreAVPtr CoreAV::makeCoreAV(Core* core) { + if (!instance) { + instance = new CoreAV(core); + } + return CoreAVPtr{instance}; +} -CoreAV *CoreAV::getInstance() { - static CoreAV *instance = nullptr; - if (!instance) { - instance = new CoreAV; - instance->start(); - } - return instance; +CoreAV* CoreAV::getInstance() { + assert(instance); + return instance; } /** @@ -75,7 +99,7 @@ CoreAV *CoreAV::getInstance() { * @note This must be called before starting CoreAV and audio must outlive * CoreAV */ -void CoreAV::setAudio(IAudioControl &newAudio) { audioCtrl.exchange(&newAudio); } +void CoreAV::setAudio(IAudioControl& newAudio) { audioCtrl.exchange(&newAudio); } /** * @brief Get the audio backend used @@ -84,188 +108,178 @@ void CoreAV::setAudio(IAudioControl &newAudio) { audioCtrl.exchange(&newAudio); * restarting class doesn't have access to the audio backend and wants to keep * it the same. */ -IAudioControl *CoreAV::getAudio() { return audioCtrl; } - -CoreAV::~CoreAV() { - /* Gracefully leave calls and group calls to avoid deadlocks in destructor */ - for (const auto &call : calls) { - cancelCall(call.first); - } - for (const auto &call : groupCalls) { - leaveGroupCall(call.first); - } - - assert(calls.empty()); - assert(groupCalls.empty()); - - coreavThread->exit(0); - coreavThread->wait(); -} +IAudioControl* CoreAV::getAudio() { return audioCtrl; } /** * @brief Starts the CoreAV main loop that calls toxav's main loop */ void CoreAV::start() { - qDebug() << __func__; - coreavThread->start(); + qDebug() << __func__; + coreavThread->start(); } void CoreAV::process() { - qDebug() << __func__; - - assert(QThread::currentThread() == coreavThread.get()); + qDebug() << __func__; - imCall = std::make_unique(); - imCall->addCallHandler(this); + assert(QThread::currentThread() == coreavThread.get()); - connect(imCall.get(), &ToxAV::receiveFriendVideoFrame, this, &CoreAV::onFriendVideoFrame); + imCall = std::make_unique(core->getMessenger()); + imCall->addCallHandler(this); - connect(imCall.get(), &ToxAV::receiveSelfVideoFrame, this, &CoreAV::onSelfVideoFrame); + connect(imCall.get(), &lib::messenger::MessengerCall::receiveFriendVideoFrame, this, + &CoreAV::onFriendVideoFrame); + connect(imCall.get(), &lib::messenger::MessengerCall::receiveSelfVideoFrame, this, + &CoreAV::onSelfVideoFrame); } -bool CoreAV::isCallStarted(const ContactId *f) const { - QReadLocker locker{&callsLock}; - return f && (calls.find(f->toString()) != calls.end()); +bool CoreAV::isCallStarted(const ContactId* f) const { + QReadLocker locker{&callsLock}; + return f && (calls.find(f->toString()) != calls.end()); } -bool CoreAV::isCallActive(const ContactId *f) const { - QReadLocker locker{&callsLock}; - auto it = calls.find(f->toString()); - if (it == calls.end()) { - return false; - } - return isCallStarted(f) && it->second->isActive(); +bool CoreAV::isCallActive(const ContactId* f) const { + QReadLocker locker{&callsLock}; + auto it = calls.find(f->toString()); + if (it == calls.end()) { + return false; + } + return isCallStarted(f) && it->second->isActive(); } -bool CoreAV::isCallVideoEnabled(const ContactId *f) const { - QReadLocker locker{&callsLock}; - auto it = calls.find(f->toString()); - return isCallStarted(f) && it->second->getVideoEnabled(); +bool CoreAV::isCallVideoEnabled(const ContactId* f) const { + QReadLocker locker{&callsLock}; + auto it = calls.find(f->toString()); + return isCallStarted(f) && it->second->getVideoEnabled(); } bool CoreAV::answerCall(ToxPeer peerId, bool video) { - qDebug() << __func__ << "peer:" << peerId << "isVideo?" << video; - QWriteLocker locker{&callsLock}; - - auto friendId = peerId.toFriendId(); //.toString(); - - qDebug() << QString("Answering call to %1").arg(friendId.toString()); - auto it = calls.find(friendId.toString()); - assert(it != calls.end()); - - QString callId = it->second->getCallId(); - qDebug() << QString("callId: %1").arg(callId); - - auto answer = imCall->callAnswerToFriend(lib::messenger::IMPeerId(peerId.toString()), callId, video); - - locker.unlock(); + qDebug() << __func__ << "peer:" << peerId << "isVideo?" << video; + QWriteLocker locker{&callsLock}; + + auto friendId = peerId.toFriendId(); //.toString(); + + qDebug() << QString("Answering call to %1").arg(friendId.toString()); + auto it = calls.find(friendId.toString()); + assert(it != calls.end()); + + QString callId = it->second->getCallId(); + qDebug() << QString("callId: %1").arg(callId); + + auto answer = + imCall->callAnswerToFriend(lib::messenger::IMPeerId(peerId.toString()), callId, video); + + locker.unlock(); + + if (answer) { + // + emit avStart(friendId, isCallVideoEnabled(&friendId)); + it->second->setActive(true); + return true; + } else { + qWarning() << "Failed to answer call with error"; + // toxav_call_control(toxav.get(), friendNum, TOXAV_CALL_CONTROL_CANCEL, + // nullptr); + calls.erase(it); + return false; + } - if (answer) { + // TOXAV_ERR_ANSWER err; // - emit avStart(friendId, isCallVideoEnabled(&friendId)); - it->second->setActive(true); - return true; - } else { - qWarning() << "Failed to answer call with error"; + // const uint32_t videoBitrate = video ? VIDEO_DEFAULT_BITRATE : 0; + // if (toxav_answer(toxav.get(), friendNum, + // Settings::getInstance().getAudioBitrate(), videoBitrate, + // &err)) { + // it->second->setActive(true); + // return true; + // } else { + // qWarning() << "Failed to answer call with error" << err; // toxav_call_control(toxav.get(), friendNum, TOXAV_CALL_CONTROL_CANCEL, - // nullptr); - calls.erase(it); - return false; - } - - // TOXAV_ERR_ANSWER err; - // - // const uint32_t videoBitrate = video ? VIDEO_DEFAULT_BITRATE : 0; - // if (toxav_answer(toxav.get(), friendNum, - // Settings::getInstance().getAudioBitrate(), videoBitrate, - // &err)) { - // it->second->setActive(true); - // return true; - // } else { - // qWarning() << "Failed to answer call with error" << err; - // toxav_call_control(toxav.get(), friendNum, TOXAV_CALL_CONTROL_CANCEL, - // nullptr); - // calls.erase(it); - // return false; - //// } + // nullptr); + // calls.erase(it); + // return false; + //// } } // bool CoreAV::startCall(QString friendNum, bool video) { - qDebug() << __func__ << "=>" << friendNum << "video?" << video; + qDebug() << __func__ << "=>" << friendNum << "video?" << video; - QWriteLocker locker{&callsLock}; + QWriteLocker locker{&callsLock}; - auto it = calls.find(friendNum); - if (it != calls.end()) { - qWarning() << QString("Can't start call with %1, we're already in this call!").arg(friendNum); - return false; - } + auto it = calls.find(friendNum); + if (it != calls.end()) { + qWarning() + << QString("Can't start call with %1, we're already in this call!").arg(friendNum); + return false; + } - QString sId = QString::number(QDateTime::currentDateTime().toMSecsSinceEpoch()); - if (!imCall->callToFriend(friendNum, sId, video)) { - qWarning() << "Failed call to friend" << friendNum; - return false; - } + QString sId = QString::number(QDateTime::currentDateTime().toMSecsSinceEpoch()); + if (!imCall->callToFriend(friendNum, sId, video)) { + qWarning() << "Failed call to friend" << friendNum; + return false; + } - // Audio backend must be set before making a call + // Audio backend must be set before making a call - ToxFriendCallPtr call = ToxFriendCallPtr(new ToxFriendCall(friendNum, video, *this, *audioCtrl)); - assert(call != nullptr); - call->setCallId(sId); - // Call object must be owned by this thread or there will be locking problems - // with Audio - call->moveToThread(this->thread()); - calls.emplace(friendNum, std::move(call)); - return true; + ToxFriendCallPtr call = + ToxFriendCallPtr(new ToxFriendCall(friendNum, video, *this, *audioCtrl)); + assert(call != nullptr); + call->setCallId(sId); + // Call object must be owned by this thread or there will be locking problems + // with Audio + call->moveToThread(this->thread()); + calls.emplace(friendNum, std::move(call)); + return true; } bool CoreAV::cancelCall(QString friendNum) { - // QWriteLocker locker{&callsLock}; - // QMutexLocker coreLocker{&coreLock}; - qDebug() << QString("Canceling call with %1").arg(friendNum); - - auto it = calls.find(friendNum); - if (it == calls.end()) { - qWarning() << QString("Can't cancel call with %1, we're already not in this call!").arg(friendNum); - return true; - } + // QWriteLocker locker{&callsLock}; + // QMutexLocker coreLocker{&coreLock}; + qDebug() << QString("Canceling call with %1").arg(friendNum); + + auto it = calls.find(friendNum); + if (it == calls.end()) { + qWarning() << QString("Can't cancel call with %1, we're already not in this call!") + .arg(friendNum); + return true; + } - QString callId = it->second->getCallId(); - imCall->callRetract(lib::messenger::IMContactId{friendNum}, callId); - qDebug() << QString("Canceling call=>%1").arg(callId); - calls.erase(friendNum); + QString callId = it->second->getCallId(); + imCall->callRetract(lib::messenger::IMContactId{friendNum}, callId); + qDebug() << QString("Canceling call=>%1").arg(callId); + calls.erase(friendNum); - // locker.unlock(); - // coreLocker.unlock(); + // locker.unlock(); + // coreLocker.unlock(); - emit avEnd(FriendId{friendNum}); - return true; + emit avEnd(FriendId{friendNum}); + return true; } -void CoreAV::rejectCall(const ToxPeer &peerId) { - qDebug() << "peer:" << peerId; +void CoreAV::rejectCall(const ToxPeer& peerId) { + qDebug() << "peer:" << peerId; - auto fId = peerId.toFriendId().toString(); + auto fId = peerId.toFriendId().toString(); - auto it = calls.find(fId); - if (it == calls.end()) { - qWarning() << QString("Can't reject call with %1, we're already not in this call!").arg(peerId.toString()); - return; - } + auto it = calls.find(fId); + if (it == calls.end()) { + qWarning() << QString("Can't reject call with %1, we're already not in this call!") + .arg(peerId.toString()); + return; + } - auto &call = it->second; + auto& call = it->second; - imCall->callReject(lib::messenger::IMPeerId{peerId.toString()}, call->getCallId()); + imCall->callReject(lib::messenger::IMPeerId{peerId.toString()}, call->getCallId()); } void CoreAV::timeoutCall(QString friendNum) { - // QWriteLocker locker{&callsLock}; + // QWriteLocker locker{&callsLock}; - if (!cancelCall(friendNum)) { - qWarning() << QString("Failed to timeout call with %1").arg(friendNum); - return; - } - qDebug() << "Call with friend" << friendNum << "timed out"; + if (!cancelCall(friendNum)) { + qWarning() << QString("Failed to timeout call with %1").arg(friendNum); + return; + } + qDebug() << "Call with friend" << friendNum << "timed out"; } /** @@ -277,128 +291,130 @@ void CoreAV::timeoutCall(QString friendNum) { * @param rate Audio sampling rate used in this frame. * @return False only on error, but not if there's nothing to send. */ -bool CoreAV::sendCallAudio(QString callId, const int16_t *pcm, size_t samples, uint8_t chans, uint32_t rate) const { - QReadLocker locker{&callsLock}; +bool CoreAV::sendCallAudio(QString callId, const int16_t* pcm, size_t samples, uint8_t chans, + uint32_t rate) const { + QReadLocker locker{&callsLock}; - auto it = calls.find(callId); - if (it == calls.end()) { - return false; - } + auto it = calls.find(callId); + if (it == calls.end()) { + return false; + } - ToxFriendCall const &call = *it->second; + ToxFriendCall const& call = *it->second; + + if (call.getMuteMic() || !call.isActive() || !(call.getState() == lib::messenger::CallState::ACCEPTING_A)) { + return true; + } + + // TOXAV_ERR_SEND_FRAME_SYNC means toxav failed to lock, retry 5 times in this + // case + // TOXAV_ERR_SEND_FRAME err; + // int retries = 0; + // do { + // if (!toxav_audio_send_frame(toxav.get(), callId, pcm, samples, chans, + // rate, + // &err)) { + // if (err == TOXAV_ERR_SEND_FRAME_SYNC) { + // ++retries; + // QThread::usleep(500); + // } else { + // qDebug() << "toxav_audio_send_frame error: " << err; + // } + // } + // } while (err == TOXAV_ERR_SEND_FRAME_SYNC && retries < 5); + // if (err == TOXAV_ERR_SEND_FRAME_SYNC) { + // qDebug() << "toxav_audio_send_frame error: Lock busy, dropping frame"; + // } - if (call.getMuteMic() || !call.isActive() || !(call.getState() & TOXAV_FRIEND_CALL_STATE_ACCEPTING_A)) { return true; - } - - // TOXAV_ERR_SEND_FRAME_SYNC means toxav failed to lock, retry 5 times in this - // case - // TOXAV_ERR_SEND_FRAME err; - // int retries = 0; - // do { - // if (!toxav_audio_send_frame(toxav.get(), callId, pcm, samples, chans, - // rate, - // &err)) { - // if (err == TOXAV_ERR_SEND_FRAME_SYNC) { - // ++retries; - // QThread::usleep(500); - // } else { - // qDebug() << "toxav_audio_send_frame error: " << err; - // } - // } - // } while (err == TOXAV_ERR_SEND_FRAME_SYNC && retries < 5); - // if (err == TOXAV_ERR_SEND_FRAME_SYNC) { - // qDebug() << "toxav_audio_send_frame error: Lock busy, dropping frame"; - // } - - return true; } void CoreAV::sendCallVideo(QString callId, std::shared_ptr vframe) { - // QWriteLocker locker{&callsLock}; - - // We might be running in the FFmpeg thread and holding the CameraSource lock - // So be careful not to deadlock with anything while toxav locks in - // toxav_video_send_frame - auto it = calls.find(callId); - if (it == calls.end()) { - return; - } - - ToxFriendCall &call = *it->second; - - if (!call.getVideoEnabled() || !call.isActive() || !(call.getState() & TOXAV_FRIEND_CALL_STATE_ACCEPTING_V)) { - return; - } - - if (call.getNullVideoBitrate()) { - qDebug() << "Restarting video stream to friend" << callId; - // QMutexLocker coreLocker{&coreLock}; - // toxav_video_set_bit_rate(toxav.get(), callId, VIDEO_DEFAULT_BITRATE, - // nullptr); - call.setNullVideoBitrate(false); - } - - ToxYUVFrame frame = vframe->toToxYUVFrame(); - - if (!frame) { - return; - } - - // TOXAV_ERR_SEND_FRAME_SYNC means toxav failed to lock, retry 5 times in this - // case We don't want to be dropping iframes because of some lock held by - // toxav_iterate - // TOXAV_ERR_SEND_FRAME err; - // int retries = 0; - // do { - // if (!toxav_video_send_frame(toxav.get(), callId, frame.width, - // frame.height, - // frame.y, frame.u, frame.v, &err)) { - // if (err == TOXAV_ERR_SEND_FRAME_SYNC) { - // ++retries; - // QThread::usleep(500); - // } else { - // qDebug() << "toxav_video_send_frame error: " << err; - // } - // } - // } while (err == TOXAV_ERR_SEND_FRAME_SYNC && retries < 5); - // if (err == TOXAV_ERR_SEND_FRAME_SYNC) { - // qDebug() << "toxav_video_send_frame error: Lock busy, dropping frame"; - // } + // QWriteLocker locker{&callsLock}; + + // We might be running in the FFmpeg thread and holding the CameraSource lock + // So be careful not to deadlock with anything while toxav locks in + // toxav_video_send_frame + auto it = calls.find(callId); + if (it == calls.end()) { + return; + } + + ToxFriendCall& call = *it->second; + + if (!call.getVideoEnabled() || !call.isActive() || + !(call.getState() == lib::messenger::CallState::ACCEPTING_V)) { + return; + } + + if (call.getNullVideoBitrate()) { + qDebug() << "Restarting video stream to friend" << callId; + // QMutexLocker coreLocker{&coreLock}; + // toxav_video_set_bit_rate(toxav.get(), callId, VIDEO_DEFAULT_BITRATE, + // nullptr); + call.setNullVideoBitrate(false); + } + + ToxYUVFrame frame = vframe->toToxYUVFrame(); + + if (!frame) { + return; + } + + // TOXAV_ERR_SEND_FRAME_SYNC means toxav failed to lock, retry 5 times in this + // case We don't want to be dropping iframes because of some lock held by + // toxav_iterate + // TOXAV_ERR_SEND_FRAME err; + // int retries = 0; + // do { + // if (!toxav_video_send_frame(toxav.get(), callId, frame.width, + // frame.height, + // frame.y, frame.u, frame.v, &err)) { + // if (err == TOXAV_ERR_SEND_FRAME_SYNC) { + // ++retries; + // QThread::usleep(500); + // } else { + // qDebug() << "toxav_video_send_frame error: " << err; + // } + // } + // } while (err == TOXAV_ERR_SEND_FRAME_SYNC && retries < 5); + // if (err == TOXAV_ERR_SEND_FRAME_SYNC) { + // qDebug() << "toxav_video_send_frame error: Lock busy, dropping frame"; + // } } /** * @brief Toggles the mute state of the call's input (microphone). * @param f The friend assigned to the call */ -void CoreAV::toggleMuteCallInput(const ContactId *f) { - QWriteLocker locker{&callsLock}; - - auto it = calls.find(f->toString()); - if (f && (it != calls.end())) { - ToxCall &call = *it->second; - call.setMuteMic(!call.getMuteMic()); - imCall->setMute(call.getMuteMic()); - } +void CoreAV::toggleMuteCallInput(const ContactId* f) { + QWriteLocker locker{&callsLock}; + + auto it = calls.find(f->toString()); + if (f && (it != calls.end())) { + ToxCall& call = *it->second; + call.setMuteMic(!call.getMuteMic()); + imCall->setMute(call.getMuteMic()); + } } /** * @brief Toggles the mute state of the call's output (speaker). * @param f The friend assigned to the call */ -void CoreAV::toggleMuteCallOutput(const ContactId *f) { - QWriteLocker locker{&callsLock}; +void CoreAV::toggleMuteCallOutput(const ContactId* f) { + QWriteLocker locker{&callsLock}; - auto it = calls.find(f->toString()); - if (f && (it != calls.end())) { - ToxCall &call = *it->second; - call.setMuteVol(!call.getMuteVol()); - } - if (f && (it != calls.end())) { - ToxCall &call = *it->second; - call.setMuteMic(!call.getMuteMic()); - imCall->setRemoteMute(call.getMuteMic()); - } + auto it = calls.find(f->toString()); + if (f && (it != calls.end())) { + ToxCall& call = *it->second; + call.setMuteVol(!call.getMuteVol()); + } + if (f && (it != calls.end())) { + ToxCall& call = *it->second; + call.setMuteMic(!call.getMuteMic()); + imCall->setRemoteMute(call.getMuteMic()); + } } /** @@ -413,42 +429,44 @@ void CoreAV::toggleMuteCallOutput(const ContactId *f) { * @param[in] sample_rate the audio sample rate * @param[in] core the qTox Core class */ -void CoreAV::groupCallCallback(void *tox, QString group, QString peer, const int16_t *data, unsigned samples, uint8_t channels, uint32_t sample_rate, void *core) { - /* - * Currently group call audio decoding is handled in the Tox thread by - * c-toxcore, so we can be sure that this function is always called from the - * Core thread. To change this, an API change in c-toxcore is needed and this - * function probably must be changed. See - * https://github.com/TokTok/c-toxcore/issues/1364 for details. - */ - - Q_UNUSED(tox); - Core *c = static_cast(core); - - // CoreAV *cav = c->getAv(); - // QReadLocker locker{&cav->callsLock}; - - const FriendId peerPk = c->getGroupPeerPk(group, peer); - const Settings &s = Settings::getInstance(); - // don't play the audio if it comes from a muted peer - if (s.getBlackList().contains(peerPk.toString())) { - return; - } - - emit c->groupPeerAudioPlaying(group, peerPk); - - // auto it = cav->groupCalls.find(group); - // if (it == cav->groupCalls.end()) { - // return; - // } - // - // ToxGroupCall &call = *it->second; - // - // if (call.getMuteVol() || !call.isActive()) { - // return; - // } - // - // call.playAudioBuffer(peerPk, data, samples, channels, sample_rate); +void CoreAV::groupCallCallback(void* tox, QString group, QString peer, const int16_t* data, + unsigned samples, uint8_t channels, uint32_t sample_rate, + void* core) { + /* + * Currently group call audio decoding is handled in the Tox thread by + * c-toxcore, so we can be sure that this function is always called from the + * Core thread. To change this, an API change in c-toxcore is needed and this + * function probably must be changed. See + * https://github.com/TokTok/c-toxcore/issues/1364 for details. + */ + + Q_UNUSED(tox); + Core* c = static_cast(core); + + // CoreAV *cav = c->getAv(); + // QReadLocker locker{&cav->callsLock}; + + const FriendId peerPk = c->getGroupPeerPk(group, peer); + const Settings& s = Settings::getInstance(); + // don't play the audio if it comes from a muted peer + if (s.getBlackList().contains(peerPk.toString())) { + return; + } + + emit c->groupPeerAudioPlaying(group, peerPk); + + // auto it = cav->groupCalls.find(group); + // if (it == cav->groupCalls.end()) { + // return; + // } + // + // ToxGroupCall &call = *it->second; + // + // if (call.getMuteVol() || !call.isActive()) { + // return; + // } + // + // call.playAudioBuffer(peerPk, data, samples, channels, sample_rate); } /** @@ -458,13 +476,13 @@ void CoreAV::groupCallCallback(void *tox, QString group, QString peer, const int * @param peer Peer Index */ void CoreAV::invalidateGroupCallPeerSource(QString group, FriendId peerPk) { - // QWriteLocker locker{&callsLock}; + // QWriteLocker locker{&callsLock}; - auto it = groupCalls.find(group); - if (it == groupCalls.end()) { - return; - } - it->second->removePeer(peerPk); + auto it = groupCalls.find(group); + if (it == groupCalls.end()) { + return; + } + it->second->removePeer(peerPk); } /** @@ -472,18 +490,18 @@ void CoreAV::invalidateGroupCallPeerSource(QString group, FriendId peerPk) { * @param friendNum Id of friend in call list. * @return Video surface to show */ -VideoSource *CoreAV::getVideoSourceFromCall(QString friendNum) const { - QReadLocker locker{&callsLock}; - - auto it = calls.find(friendNum); - if (it == calls.end()) { - qWarning() << "CoreAV::getVideoSourceFromCall: No such call, did it die " - "before we finished " - "answering?"; - return nullptr; - } +VideoSource* CoreAV::getVideoSourceFromCall(QString friendNum) const { + QReadLocker locker{&callsLock}; + + auto it = calls.find(friendNum); + if (it == calls.end()) { + qWarning() << "CoreAV::getVideoSourceFromCall: No such call, did it die " + "before we finished " + "answering?"; + return nullptr; + } - return it->second->getVideoSource(); + return it->second->getVideoSource(); } /** @@ -491,28 +509,28 @@ VideoSource *CoreAV::getVideoSourceFromCall(QString friendNum) const { * @note Call from the GUI thread. * @param groupId Id of group to join */ -void CoreAV::joinGroupCall(const Group &group) { - QWriteLocker locker{&callsLock}; +void CoreAV::joinGroupCall(const Group& group) { + QWriteLocker locker{&callsLock}; - qDebug() << QString("Joining group call %1").arg(group.getId()); + qDebug() << QString("Joining group call %1").arg(group.getId()); - // Audio backend must be set before starting a call - assert(audioCtrl != nullptr); + // Audio backend must be set before starting a call + assert(audioCtrl != nullptr); - ToxGroupCallPtr groupcall = ToxGroupCallPtr(new ToxGroupCall{group, *this, *audioCtrl}); - // Call Objects must be owned by CoreAV or there will be locking problems with - // Audio - groupcall->moveToThread(this->thread()); + ToxGroupCallPtr groupcall = ToxGroupCallPtr(new ToxGroupCall{group, *this, *audioCtrl}); + // Call Objects must be owned by CoreAV or there will be locking problems with + // Audio + groupcall->moveToThread(this->thread()); - auto ret = groupCalls.emplace(group.getId(), std::move(groupcall)); - if (!ret.second) { - qWarning() << "This group call already exists, not joining!"; - return; - } - ret.first->second->setActive(true); + auto ret = groupCalls.emplace(group.getId(), std::move(groupcall)); + if (!ret.second) { + qWarning() << "This group call already exists, not joining!"; + return; + } + ret.first->second->setActive(true); - // TODO 发起群视频 - imCall->callToGroup(group.getId()); + // TODO 发起群视频 +// imCall->callToGroup(group.getId()); } /** @@ -521,31 +539,32 @@ void CoreAV::joinGroupCall(const Group &group) { * @param groupId Id of group to leave */ void CoreAV::leaveGroupCall(QString groupId) { - QWriteLocker locker{&callsLock}; + QWriteLocker locker{&callsLock}; - qDebug() << QString("Leaving group call %1").arg(groupId); + qDebug() << QString("Leaving group call %1").arg(groupId); - groupCalls.erase(groupId); + groupCalls.erase(groupId); } -bool CoreAV::sendGroupCallAudio(QString groupId, const int16_t *pcm, size_t samples, uint8_t chans, uint32_t rate) const { - QReadLocker locker{&callsLock}; +bool CoreAV::sendGroupCallAudio(QString groupId, const int16_t* pcm, size_t samples, uint8_t chans, + uint32_t rate) const { + QReadLocker locker{&callsLock}; - std::map::const_iterator it = groupCalls.find(groupId); - if (it == groupCalls.end()) { - return false; - } + std::map::const_iterator it = groupCalls.find(groupId); + if (it == groupCalls.end()) { + return false; + } - if (!it->second->isActive() || it->second->getMuteMic()) { - return true; - } + if (!it->second->isActive() || it->second->getMuteMic()) { + return true; + } - // if (toxav_group_send_audio(toxav_get_tox(toxav.get()), groupId, pcm, - // samples, - // chans, rate) != 0) - // qDebug() << "toxav_group_send_audio error"; - // return true; - return false; + // if (toxav_group_send_audio(toxav_get_tox(toxav.get()), groupId, pcm, + // samples, + // chans, rate) != 0) + // qDebug() << "toxav_group_send_audio error"; + // return true; + return false; } /** @@ -553,14 +572,14 @@ bool CoreAV::sendGroupCallAudio(QString groupId, const int16_t *pcm, size_t samp * @param g The group * @param mute True to mute, false to unmute */ -void CoreAV::muteCallInput(const ContactId *g, bool mute) { - QWriteLocker locker{&callsLock}; +void CoreAV::muteCallInput(const ContactId* g, bool mute) { + QWriteLocker locker{&callsLock}; - auto it = calls.find(g->getId()); - if (g && (it != calls.end())) { - it->second->setMuteMic(mute); - } - imCall->setRemoteMute(mute); + auto it = calls.find(g->getId()); + if (g && (it != calls.end())) { + it->second->setMuteMic(mute); + } + imCall->setRemoteMute(mute); } /** @@ -568,14 +587,14 @@ void CoreAV::muteCallInput(const ContactId *g, bool mute) { * @param g The group * @param mute True to mute, false to unmute */ -void CoreAV::muteCallOutput(const ContactId *g, bool mute) { - QWriteLocker locker{&callsLock}; +void CoreAV::muteCallOutput(const ContactId* g, bool mute) { + QWriteLocker locker{&callsLock}; - auto it = calls.find(g->getId()); - if (g && (it != calls.end())) { - it->second->setMuteVol(mute); - } - imCall->setMute(mute); + auto it = calls.find(g->getId()); + if (g && (it != calls.end())) { + it->second->setMuteVol(mute); + } + imCall->setMute(mute); } /** @@ -583,16 +602,16 @@ void CoreAV::muteCallOutput(const ContactId *g, bool mute) { * @param groupId The group id to check * @return true when muted, false otherwise */ -bool CoreAV::isGroupCallInputMuted(const Group *g) const { - QReadLocker locker{&callsLock}; +bool CoreAV::isGroupCallInputMuted(const Group* g) const { + QReadLocker locker{&callsLock}; - if (!g) { - return false; - } + if (!g) { + return false; + } - const QString groupId = g->getId(); - auto it = groupCalls.find(groupId); - return (it != groupCalls.end()) && it->second->getMuteMic(); + const QString groupId = g->getId(); + auto it = groupCalls.find(groupId); + return (it != groupCalls.end()) && it->second->getMuteMic(); } /** @@ -600,16 +619,16 @@ bool CoreAV::isGroupCallInputMuted(const Group *g) const { * @param groupId The group id to check * @return true when muted, false otherwise */ -bool CoreAV::isGroupCallOutputMuted(const Group *g) const { - QReadLocker locker{&callsLock}; +bool CoreAV::isGroupCallOutputMuted(const Group* g) const { + QReadLocker locker{&callsLock}; - if (!g) { - return false; - } + if (!g) { + return false; + } - const QString groupId = g->getId(); - auto it = groupCalls.find(groupId); - return (it != groupCalls.end()) && it->second->getMuteVol(); + const QString groupId = g->getId(); + auto it = groupCalls.find(groupId); + return (it != groupCalls.end()) && it->second->getMuteVol(); } /** @@ -617,15 +636,15 @@ bool CoreAV::isGroupCallOutputMuted(const Group *g) const { * @param f The friend to check * @return true when muted, false otherwise */ -bool CoreAV::isCallInputMuted(const ContactId *f) const { - QReadLocker locker{&callsLock}; +bool CoreAV::isCallInputMuted(const ContactId* f) const { + QReadLocker locker{&callsLock}; - if (!f) { - return false; - } - const QString friendId = f->toString(); - auto it = calls.find(friendId); - return (it != calls.end()) && it->second->getMuteMic(); + if (!f) { + return false; + } + const QString friendId = f->toString(); + auto it = calls.find(friendId); + return (it != calls.end()) && it->second->getMuteMic(); } /** @@ -633,15 +652,15 @@ bool CoreAV::isCallInputMuted(const ContactId *f) const { * @param friendId The friend to check * @return true when muted, false otherwise */ -bool CoreAV::isCallOutputMuted(const ContactId *f) const { - QReadLocker locker{&callsLock}; +bool CoreAV::isCallOutputMuted(const ContactId* f) const { + QReadLocker locker{&callsLock}; - if (!f) { - return false; - } - const QString friendId = f->getId(); - auto it = calls.find(friendId); - return (it != calls.end()) && it->second->getMuteVol(); + if (!f) { + return false; + } + const QString friendId = f->getId(); + auto it = calls.find(friendId); + return (it != calls.end()) && it->second->getMuteVol(); } /** @@ -649,261 +668,266 @@ bool CoreAV::isCallOutputMuted(const ContactId *f) const { * @note The next frame sent cancels this. */ void CoreAV::sendNoVideo() { - QWriteLocker locker{&callsLock}; - - // We don't change the audio bitrate, but we signal that we're not sending - // video anymore - qDebug() << "CoreAV: Signaling end of video sending"; - for (auto &kv : calls) { - ToxFriendCall &call = *kv.second; - call.setNullVideoBitrate(true); - } + QWriteLocker locker{&callsLock}; + + // We don't change the audio bitrate, but we signal that we're not sending + // video anymore + qDebug() << "CoreAV: Signaling end of video sending"; + for (auto& kv : calls) { + ToxFriendCall& call = *kv.second; + call.setNullVideoBitrate(true); + } } -void CoreAV::onCall(const lib::messenger::IMPeerId &peerId, const QString &callId, bool audio, bool video) { - qDebug() << __func__ << "peerId:" << peerId.toString() << "callId:" << callId; +void CoreAV::onCall(const lib::messenger::IMPeerId& peerId, const QString& callId, bool audio, + bool video) { + qDebug() << __func__ << "peerId:" << peerId.toString() << "callId:" << callId; - // CoreAV *self = static_cast(vSelf); - QWriteLocker locker{&callsLock}; + // CoreAV *self = static_cast(vSelf); + QWriteLocker locker{&callsLock}; - auto peer = ToxPeer(peerId); + auto peer = ToxPeer(peerId); - // Audio backend must be set before receiving a call + // Audio backend must be set before receiving a call - ToxFriendCallPtr call = ToxFriendCallPtr(new ToxFriendCall{peerId.toString(), video, *this, *audioCtrl}); - call->setCallId(callId); - // Call object must be owned by CoreAV thread or there will be locking - // problems with Audio - call->moveToThread(thread()); - assert(call != nullptr); + ToxFriendCallPtr call = + ToxFriendCallPtr(new ToxFriendCall{peerId.toString(), video, *this, *audioCtrl}); + call->setCallId(callId); + // Call object must be owned by CoreAV thread or there will be locking + // problems with Audio + call->moveToThread(thread()); + assert(call != nullptr); - auto it = calls.emplace(peer.toFriendId().toString(), std::move(call)); - if (it.second == false) { - qWarning() << QString("Rejecting call invite from %1, we're already in that call!").arg(peerId.toString()); - // toxav_call_control(toxav, friendNum, TOXAV_CALL_CONTROL_CANCEL, - // nullptr); - return; - } - qDebug() << QString("Received call invite from %1").arg(peerId.toString()); + auto it = calls.emplace(peer.toFriendId().toString(), std::move(call)); + if (it.second == false) { + qWarning() << QString("Rejecting call invite from %1, we're already in that call!") + .arg(peerId.toString()); + // toxav_call_control(toxav, friendNum, TOXAV_CALL_CONTROL_CANCEL, + // nullptr); + return; + } + qDebug() << QString("Received call invite from %1").arg(peerId.toString()); - // We don't get a state callback when answering, so fill the state ourselves - // in advance - int state = 0; - if (audioCtrl) - state |= TOXAV_FRIEND_CALL_STATE_SENDING_A | TOXAV_FRIEND_CALL_STATE_ACCEPTING_A; - if (video) - state |= TOXAV_FRIEND_CALL_STATE_SENDING_V | TOXAV_FRIEND_CALL_STATE_ACCEPTING_V; - it.first->second->setState(static_cast(state)); + // We don't get a state callback when answering, so fill the state ourselves + // in advance +// int state = 0; +// if (audioCtrl){ +// state |= lib::messenger::CallState::SENDING_A | lib::messenger::CallState::ACCEPTING_A; +// } +// if (video) +// state == lib::messenger::CallState::SENDING_V | lib::messenger::CallState::ACCEPTING_V; +// it.first->second->setState(static_cast(state)); - // Must explicitly unlock, because a deadlock can happen via ChatForm/Audio - // locker.unlock(); + // Must explicitly unlock, because a deadlock can happen via ChatForm/Audio + // locker.unlock(); - emit avInvite(ToxPeer(peerId), video); + emit avInvite(ToxPeer(peerId), video); } -void CoreAV::onCallRetract(const QString &friendNum, int state) { - qDebug() << __func__ << QString("Canceling call with %1").arg(friendNum); +void CoreAV::onCallRetract(const QString& friendNum, int state) { + qDebug() << __func__ << QString("Canceling call with %1").arg(friendNum); - auto it = calls.find(friendNum); - if (it == calls.end()) { - qWarning() << QString("Can't cancel call with %1, we're already not in this call!").arg(friendNum); - return; - } + auto it = calls.find(friendNum); + if (it == calls.end()) { + qWarning() << QString("Can't cancel call with %1, we're already not in this call!") + .arg(friendNum); + return; + } - calls.erase(friendNum); - emit avEnd(FriendId{friendNum}); + calls.erase(friendNum); + emit avEnd(FriendId{friendNum}); } -void CoreAV::onCallAcceptByOther(const QString &callId, const lib::messenger::IMPeerId &peerId) { - - qDebug() << __func__ << peerId.toString() << "callId" << callId; - QString friendNum; - for (auto &item : calls) { - if (item.second->getCallId() == callId) { - friendNum = item.second->getPeerId(); - break; +void CoreAV::onCallAcceptByOther(const QString& callId, const lib::messenger::IMPeerId& peerId) { + qDebug() << __func__ << peerId.toString() << "callId" << callId; + QString friendNum; + for (auto& item : calls) { + if (item.second->getCallId() == callId) { + friendNum = item.second->getPeerId(); + break; + } } - } - if (friendNum.isEmpty()) { - qWarning() << "Unable to find friend for call" << callId; - return; - } + if (friendNum.isEmpty()) { + qWarning() << "Unable to find friend for call" << callId; + return; + } - qDebug() << "avEnd" << friendNum; + qDebug() << "avEnd" << friendNum; - calls.erase(friendNum); + calls.erase(friendNum); - emit avEnd(FriendId{friendNum}); + emit avEnd(FriendId{friendNum}); } void CoreAV::receiveCallStateAccepted(lib::messenger::IMPeerId peerId, QString callId, bool video) { - qDebug() << __func__ << "peerId" << peerId.toString() << "callId:" << callId; + qDebug() << __func__ << "peerId" << peerId.toString() << "callId:" << callId; - stateCallback(peerId.toFriendId(), // - video ? TOXAV_FRIEND_CALL_STATE::TOXAV_FRIEND_CALL_STATE_ACCEPTING_V : TOXAV_FRIEND_CALL_STATE::TOXAV_FRIEND_CALL_STATE_ACCEPTING_A); + stateCallback(peerId.toFriendId(), // + video ? lib::messenger::CallState::ACCEPTING_V + : lib::messenger::CallState::ACCEPTING_A); - if (QThread::currentThread() != coreavThread.get()) { - emit createCallToPeerId(peerId, callId, video); - } else { - imCall->callToPeerId(peerId, callId, video); - } + if (QThread::currentThread() != coreavThread.get()) { + emit createCallToPeerId(peerId, callId, video); + } else { + imCall->callToPeerId(peerId, callId, video); + } } -void CoreAV::doCreateCallToPeerId(lib::messenger::IMPeerId friendId, QString callId, bool video) { imCall->callToPeerId(friendId, callId, video); } - -void CoreAV::receiveCallStateRejected(lib::messenger::IMPeerId friendId, QString callId, bool video) { - qDebug() << __func__ << "peerId:" << friendId.toString() << "callId:" << callId; - stateCallback(friendId.toFriendId(), TOXAV_FRIEND_CALL_STATE::TOXAV_FRIEND_CALL_STATE_FINISHED); +void CoreAV::doCreateCallToPeerId(lib::messenger::IMPeerId friendId, QString callId, bool video) { + imCall->callToPeerId(friendId, callId, video); } -void CoreAV::onHangup(const QString &friendId, TOXAV_FRIEND_CALL_STATE state) { - qDebug() << __func__ << "peerId:" << friendId; - stateCallback(friendId, state); +void CoreAV::receiveCallStateRejected(lib::messenger::IMPeerId friendId, QString callId, + bool video) { + qDebug() << __func__ << "peerId:" << friendId.toString() << "callId:" << callId; + stateCallback(friendId.toFriendId(), lib::messenger::CallState::FINISHED); } -void CoreAV::onFriendVideoFrame(const QString &friendId, uint16_t w, uint16_t h, const uint8_t *y, const uint8_t *u, const uint8_t *v, int32_t ystride, int32_t ustride, - int32_t vstride) { +void CoreAV::onHangup(const QString& friendId, lib::messenger::CallState state) { + qDebug() << __func__ << "peerId:" << friendId; + stateCallback(friendId, state); +} - // This callback should come from the CoreAV thread - // QReadLocker locker{&callsLock}; 为了提高性能暂时去掉 +void CoreAV::onFriendVideoFrame(const QString& friendId, uint16_t w, uint16_t h, const uint8_t* y, + const uint8_t* u, const uint8_t* v, int32_t ystride, + int32_t ustride, int32_t vstride) { + // This callback should come from the CoreAV thread + // QReadLocker locker{&callsLock}; 为了提高性能暂时去掉 - auto it = calls.find(friendId); - if (it == calls.end()) { - qWarning() << "Unable to find call!" << friendId; - return; - } + auto it = calls.find(friendId); + if (it == calls.end()) { + qWarning() << "Unable to find call!" << friendId; + return; + } - auto frame = makeVpxFrame(w, h, y, u, v, ystride, ustride, vstride); - it->second->getVideoSource()->pushFrame(&frame); + auto frame = makeVpxFrame(w, h, y, u, v, ystride, ustride, vstride); + it->second->getVideoSource()->pushFrame(&frame); } -void CoreAV::onSelfVideoFrame(uint16_t w, uint16_t h, const uint8_t *y, const uint8_t *u, const uint8_t *v, int32_t ystride, int32_t ustride, int32_t vstride) { - - auto frame = makeVpxFrame(w, h, y, u, v, ystride, ustride, vstride); - selfVideoSource->pushFrame(&frame); +void CoreAV::onSelfVideoFrame(uint16_t w, uint16_t h, const uint8_t* y, const uint8_t* u, + const uint8_t* v, int32_t ystride, int32_t ustride, int32_t vstride) { + auto frame = makeVpxFrame(w, h, y, u, v, ystride, ustride, vstride); + selfVideoSource->pushFrame(&frame); } -void CoreAV::stateCallback(QString friendNum, uint32_t state) { - qDebug() << "stateCallback friend:" << friendNum; +void CoreAV::stateCallback(QString friendNum, lib::messenger::CallState state) { + qDebug() << "stateCallback friend:" << friendNum; - auto friendId = FriendId{friendNum}; + auto friendId = FriendId{friendNum}; - auto it = calls.find(friendNum); - if (it == calls.end()) { - qWarning() << QString("stateCallback called, but call %1 is already dead").arg(friendNum); - return; - } + auto it = calls.find(friendNum); + if (it == calls.end()) { + qWarning() << QString("stateCallback called, but call %1 is already dead").arg(friendNum); + return; + } - // we must unlock this lock before emitting any signals - // QWriteLocker locker{&self->callsLock}; + // we must unlock this lock before emitting any signals + // QWriteLocker locker{&self->callsLock}; + + ToxFriendCall& call = *it->second; + if (state == lib::messenger::CallState::ERROR0) { + qWarning() << "Call with friend" << friendNum << "died of unnatural causes!"; + calls.erase(friendNum); + emit avEnd(friendId, true); + } else if (state == lib::messenger::CallState::FINISHED) { + qDebug() << "Call with friend" << friendNum << "finished quietly"; + calls.erase(friendNum); + emit avEnd(friendId); + } else { + // If our state was null, we started the call and were still ringing + if (call.getState() != state) { + call.setActive(true); + bool videoEnabled = call.getVideoEnabled(); + call.setState(static_cast(state)); + emit avStart(FriendId{friendNum}, videoEnabled); + } else if ((call.getState() == lib::messenger::CallState::SENDING_V) && + !(state == lib::messenger::CallState::SENDING_V)) { + qDebug() << "IMFriend" << friendNum << "stopped sending video"; + if (call.getVideoSource()) { + call.getVideoSource()->stopSource(); + } + + call.setState(static_cast(state)); + } else if (!(call.getState() == lib::messenger::CallState::SENDING_V) && + (state == lib::messenger::CallState::SENDING_V)) { + // Workaround toxav sometimes firing callbacks for "send last frame" -> + // "stop sending video" out of orders (even though they were sent in order + // by the other end). We simply stop the videoSource from emitting + // anything while the other end says it's not sending + if (call.getVideoSource()) { + call.getVideoSource()->restartSource(); + } + + call.setState(static_cast(state)); + } + } - ToxFriendCall &call = *it->second; - if (state & TOXAV_FRIEND_CALL_STATE_ERROR) { - qWarning() << "Call with friend" << friendNum << "died of unnatural causes!"; - calls.erase(friendNum); - emit avEnd(friendId, true); - } else if (state & TOXAV_FRIEND_CALL_STATE_FINISHED) { - qDebug() << "Call with friend" << friendNum << "finished quietly"; - calls.erase(friendNum); - emit avEnd(friendId); - } else { - // If our state was null, we started the call and were still ringing - if (!call.getState() && state) { - call.setActive(true); - bool videoEnabled = call.getVideoEnabled(); - call.setState(static_cast(state)); - emit avStart(FriendId{friendNum}, videoEnabled); - } else if ((call.getState() & TOXAV_FRIEND_CALL_STATE_SENDING_V) && !(state & TOXAV_FRIEND_CALL_STATE_SENDING_V)) { - qDebug() << "IMFriend" << friendNum << "stopped sending video"; - if (call.getVideoSource()) { - call.getVideoSource()->stopSource(); - } - - call.setState(static_cast(state)); - } else if (!(call.getState() & TOXAV_FRIEND_CALL_STATE_SENDING_V) && (state & TOXAV_FRIEND_CALL_STATE_SENDING_V)) { - // Workaround toxav sometimes firing callbacks for "send last frame" -> - // "stop sending video" out of orders (even though they were sent in order - // by the other end). We simply stop the videoSource from emitting - // anything while the other end says it's not sending - if (call.getVideoSource()) { - call.getVideoSource()->restartSource(); - } - - call.setState(static_cast(state)); - } - } - - // locker.unlock(); + // locker.unlock(); } // This is only a dummy implementation for now -void CoreAV::bitrateCallback(ToxAV *toxav, QString friendNum, uint32_t arate, uint32_t vrate, void *vSelf) { - CoreAV *self = static_cast(vSelf); - Q_UNUSED(self); - Q_UNUSED(toxav); - - qDebug() << "Recommended bitrate with" << friendNum << " is now " << arate << "/" << vrate << ", ignoring it"; +void CoreAV::bitrateCallback(QString friendNum, uint32_t arate, uint32_t vrate, void* vSelf) { + qDebug() << "Recommended bitrate with" << friendNum << " is now " << arate << "/" << vrate + << ", ignoring it"; } // This is only a dummy implementation for now -void CoreAV::audioBitrateCallback(ToxAV *toxav, QString friendNum, uint32_t rate, void *vSelf) { - CoreAV *self = static_cast(vSelf); - Q_UNUSED(self); - Q_UNUSED(toxav); - - qDebug() << "Recommended audio bitrate with" << friendNum << " is now " << rate << ", ignoring it"; +void CoreAV::audioBitrateCallback(QString friendNum, uint32_t rate, void* vSelf) { + qDebug() << "Recommended audio bitrate with" << friendNum << " is now " << rate + << ", ignoring it"; } // This is only a dummy implementation for now -void CoreAV::videoBitrateCallback(ToxAV *toxav, QString friendNum, uint32_t rate, void *vSelf) { - CoreAV *self = static_cast(vSelf); - Q_UNUSED(self); - Q_UNUSED(toxav); - - qDebug() << "Recommended video bitrate with" << friendNum << " is now " << rate << ", ignoring it"; -} - -void CoreAV::audioFrameCallback(ToxAV *, QString friendNum, const int16_t *pcm, size_t sampleCount, uint8_t channels, uint32_t samplingRate, void *vSelf) { - CoreAV *self = static_cast(vSelf); - // This callback should come from the CoreAV thread - assert(QThread::currentThread() == self->coreavThread.get()); - QReadLocker locker{&self->callsLock}; - - auto it = self->calls.find(friendNum); - if (it == self->calls.end()) { - return; - } +void CoreAV::videoBitrateCallback(QString friendNum, uint32_t rate, void* vSelf) { + CoreAV* self = static_cast(vSelf); + Q_UNUSED(self); + qDebug() << "Recommended video bitrate with" << friendNum << " is now " << rate + << ", ignoring it"; +} + +void CoreAV::audioFrameCallback(QString friendNum, const int16_t* pcm, size_t sampleCount, + uint8_t channels, uint32_t samplingRate, void* vSelf) { + CoreAV* self = static_cast(vSelf); + // This callback should come from the CoreAV thread + assert(QThread::currentThread() == self->coreavThread.get()); + QReadLocker locker{&self->callsLock}; + + auto it = self->calls.find(friendNum); + if (it == self->calls.end()) { + return; + } - ToxFriendCall &call = *it->second; + ToxFriendCall& call = *it->second; - if (call.getMuteVol()) { - return; - } + if (call.getMuteVol()) { + return; + } - call.playAudioBuffer(pcm, sampleCount, channels, samplingRate); + call.playAudioBuffer(pcm, sampleCount, channels, samplingRate); } -vpx_image CoreAV::makeVpxFrame(uint16_t w, uint16_t h, const uint8_t *y, const uint8_t *u, const uint8_t *v, int32_t ystride, int32_t ustride, int32_t vstride) { - vpx_image frame; - frame.d_h = h; - frame.d_w = w; - frame.planes[0] = const_cast(y); - frame.planes[1] = const_cast(u); - frame.planes[2] = const_cast(v); - frame.stride[0] = ystride; - frame.stride[1] = ustride; - frame.stride[2] = vstride; - return frame; +vpx_image CoreAV::makeVpxFrame(uint16_t w, uint16_t h, const uint8_t* y, const uint8_t* u, + const uint8_t* v, int32_t ystride, int32_t ustride, + int32_t vstride) { + vpx_image frame; + frame.d_h = h; + frame.d_w = w; + frame.planes[0] = const_cast(y); + frame.planes[1] = const_cast(u); + frame.planes[2] = const_cast(v); + frame.stride[0] = ystride; + frame.stride[1] = ustride; + frame.stride[2] = vstride; + return frame; } -void CoreAV::videoFramePush(CoreVideoSource *videoSource, // - const vpx_image &frame // +void CoreAV::videoFramePush(CoreVideoSource* videoSource, // + const vpx_image& frame // ) { + if (!videoSource) { + return; + } - if (!videoSource) { - return; - } - - videoSource->pushFrame(&frame); + videoSource->pushFrame(&frame); } diff --git a/src/modules/im/src/core/coreav.h b/src/modules/im/src/core/coreav.h index 25ce5f86..46565b02 100644 --- a/src/modules/im/src/core/coreav.h +++ b/src/modules/im/src/core/coreav.h @@ -19,9 +19,8 @@ #include #include -#include "src/core/toxcall.h" #include "base/compatiblerecursivemutex.h" -#include "lib/messenger/IMCall.h" +#include "src/core/toxcall.h" class Friend; class Group; @@ -35,168 +34,153 @@ class Core; struct vpx_image; class CoreAV : public QObject, public lib::messenger::CallHandler { - Q_OBJECT - + Q_OBJECT public: - using CoreAVPtr = std::unique_ptr; - - static CoreAVPtr makeCoreAV(); - static CoreAV* getInstance(); - - void setAudio(IAudioControl &newAudio); - IAudioControl *getAudio(); - - ~CoreAV(); - - bool isCallStarted(const ContactId *f) const; - bool isCallActive(const ContactId *f) const; - bool isCallVideoEnabled(const ContactId *f) const; - bool sendCallAudio(QString friendId, const int16_t *pcm, size_t samples, - uint8_t chans, uint32_t rate) const; - void sendCallVideo(QString friendId, std::shared_ptr frame); - bool sendGroupCallAudio(QString groupNum, const int16_t *pcm, size_t samples, - uint8_t chans, uint32_t rate) const; - - CoreVideoSource *getSelfVideoSource() { - return selfVideoSource.get(); - } - - VideoSource *getVideoSourceFromCall(QString callNumber) const; - void sendNoVideo(); - - void joinGroupCall(const Group &group); - void leaveGroupCall(QString groupNum); - void muteCallInput(const ContactId *g, bool mute); - void muteCallOutput(const ContactId *g, bool mute); - bool isGroupCallInputMuted(const Group *g) const; - bool isGroupCallOutputMuted(const Group *g) const; - - bool isCallInputMuted(const ContactId *f) const; - bool isCallOutputMuted(const ContactId *f) const; - void toggleMuteCallInput(const ContactId *f); - void toggleMuteCallOutput(const ContactId *f); - static void groupCallCallback(void *tox, QString group, QString peer, - const int16_t *data, unsigned samples, - uint8_t channels, uint32_t sample_rate, - void *core); - void invalidateGroupCallPeerSource(QString group, FriendId peerPk); + using CoreAVPtr = std::unique_ptr; + + static CoreAVPtr makeCoreAV(Core* core); + static CoreAV* getInstance(); + + void setAudio(IAudioControl& newAudio); + IAudioControl* getAudio(); + + ~CoreAV(); + + bool isCallStarted(const ContactId* f) const; + bool isCallActive(const ContactId* f) const; + bool isCallVideoEnabled(const ContactId* f) const; + bool sendCallAudio(QString friendId, const int16_t* pcm, size_t samples, uint8_t chans, + uint32_t rate) const; + void sendCallVideo(QString friendId, std::shared_ptr frame); + bool sendGroupCallAudio(QString groupNum, const int16_t* pcm, size_t samples, uint8_t chans, + uint32_t rate) const; + + CoreVideoSource* getSelfVideoSource() { return selfVideoSource.get(); } + + VideoSource* getVideoSourceFromCall(QString callNumber) const; + void sendNoVideo(); + + void joinGroupCall(const Group& group); + void leaveGroupCall(QString groupNum); + void muteCallInput(const ContactId* g, bool mute); + void muteCallOutput(const ContactId* g, bool mute); + bool isGroupCallInputMuted(const Group* g) const; + bool isGroupCallOutputMuted(const Group* g) const; + + bool isCallInputMuted(const ContactId* f) const; + bool isCallOutputMuted(const ContactId* f) const; + void toggleMuteCallInput(const ContactId* f); + void toggleMuteCallOutput(const ContactId* f); + static void groupCallCallback(void* tox, QString group, QString peer, const int16_t* data, + unsigned samples, uint8_t channels, uint32_t sample_rate, + void* core); + void invalidateGroupCallPeerSource(QString group, FriendId peerPk); public slots: - bool startCall(QString friendId, bool video); - bool answerCall(ToxPeer peerId, bool video); - bool cancelCall(QString friendId); - void rejectCall(const ToxPeer &peerId); - void timeoutCall(QString friendId); - void start(); + bool startCall(QString friendId, bool video); + bool answerCall(ToxPeer peerId, bool video); + bool cancelCall(QString friendId); + void rejectCall(const ToxPeer& peerId); + void timeoutCall(QString friendId); + void start(); signals: - void avInvite(ToxPeer peerId, bool video); - void avStart(FriendId friendId, bool video); - void avEnd(FriendId friendId, bool error = false); - void createCallToPeerId(lib::messenger::IMPeerId friendId, QString callId, bool video); + void avInvite(ToxPeer peerId, bool video); + void avStart(FriendId friendId, bool video); + void avEnd(FriendId friendId, bool error = false); + void createCallToPeerId(lib::messenger::IMPeerId friendId, QString callId, bool video); private slots: - void doCreateCallToPeerId(lib::messenger::IMPeerId friendId, QString callId, bool video); - - void stateCallback(QString friendId, uint32_t state); - - static void bitrateCallback(ToxAV *toxAV, QString friendId, uint32_t arate, - uint32_t vrate, void *self); - static void audioBitrateCallback(ToxAV *toxAV, QString friendId, - uint32_t rate, void *self); - static void videoBitrateCallback(ToxAV *toxAV, QString friendId, - uint32_t rate, void *self); - void onFriendVideoFrame(const QString &friendId, // - uint16_t w, uint16_t h, // - const uint8_t *y, // - const uint8_t *u, // - const uint8_t *v, // + void doCreateCallToPeerId(lib::messenger::IMPeerId friendId, QString callId, bool video); + + void stateCallback(QString friendId, lib::messenger::CallState state); + + void bitrateCallback(QString friendId, uint32_t arate, uint32_t vrate, void* self); + void audioBitrateCallback(QString friendId, uint32_t rate, void* self); + void videoBitrateCallback(QString friendId, uint32_t rate, void* self); + void onFriendVideoFrame(const QString& friendId, // + uint16_t w, uint16_t h, // + const uint8_t* y, // + const uint8_t* u, // + const uint8_t* v, // + int32_t ystride, // + int32_t ustride, // + int32_t vstride) override; + + void onSelfVideoFrame(uint16_t w, uint16_t h, // + const uint8_t* y, // + const uint8_t* u, // + const uint8_t* v, // int32_t ystride, // int32_t ustride, // int32_t vstride) override; - void onSelfVideoFrame(uint16_t w, uint16_t h, // - const uint8_t *y, // - const uint8_t *u, // - const uint8_t *v, // - int32_t ystride, // - int32_t ustride, // - int32_t vstride) override; - private: - struct ToxAVDeleter { - void operator()(ToxAV *tox) { /* toxav_kill(tox);*/ - } - }; + CoreAV(Core* core); - CoreAV(); + void process(); + void audioFrameCallback(QString friendId, const int16_t* pcm, size_t sampleCount, + uint8_t channels, uint32_t samplingRate, void* self); - void process(); + // void videoFrameCallback(ToxAV *toxAV, QString friendId, uint16_t w, + // uint16_t h, const uint8_t *y, const uint8_t *u, + // const uint8_t *v, int32_t ystride, int32_t ustride, + // int32_t vstride, void *self); - static void audioFrameCallback(ToxAV *toxAV, QString friendId, - const int16_t *pcm, size_t sampleCount, - uint8_t channels, uint32_t samplingRate, - void *self); + vpx_image makeVpxFrame(uint16_t w, uint16_t h, const uint8_t* y, const uint8_t* u, + const uint8_t* v, int32_t ystride, int32_t ustride, int32_t vstride); -// void videoFrameCallback(ToxAV *toxAV, QString friendId, uint16_t w, -// uint16_t h, const uint8_t *y, const uint8_t *u, -// const uint8_t *v, int32_t ystride, int32_t ustride, -// int32_t vstride, void *self); + void videoFramePush(CoreVideoSource* vs, const vpx_image& frame); - vpx_image makeVpxFrame( uint16_t w, uint16_t h, - const uint8_t *y, const uint8_t *u, const uint8_t *v, - int32_t ystride, int32_t ustride, int32_t vstride); + void onCall(const lib::messenger::IMPeerId& peerId, const QString& callId, bool audio, + bool video) override; - void videoFramePush(CoreVideoSource *vs, const vpx_image &frame); + void onCallRetract(const QString& friendId, int state) override; - void onCall(const lib::messenger::IMPeerId &peerId, const QString& callId, bool audio, bool video) override; + void onCallAcceptByOther(const QString& callId, + const lib::messenger::IMPeerId& peerId) override; - void onCallRetract(const QString &friendId, int state) override; + void receiveCallStateAccepted(lib::messenger::IMPeerId friendId, QString callId, + bool video) override; - void onCallAcceptByOther(const QString& callId, const lib::messenger::IMPeerId & peerId) override; + void receiveCallStateRejected(lib::messenger::IMPeerId friendId, QString callId, + bool video) override; - void receiveCallStateAccepted(lib::messenger::IMPeerId friendId, QString callId, bool video) override; - - void receiveCallStateRejected(lib::messenger::IMPeerId friendId, QString callId, bool video) override; - - void onHangup(const QString &friendId, - TOXAV_FRIEND_CALL_STATE state) override; + void onHangup(const QString& friendId, lib::messenger::CallState state) override; private: - static constexpr uint32_t VIDEO_DEFAULT_BITRATE = 2500; + static constexpr uint32_t VIDEO_DEFAULT_BITRATE = 2500; private: - // std::unique_ptr selfVideoSource; - // atomic because potentially accessed by different threads - - std::atomic audioCtrl; - std::unique_ptr imCall; - std::unique_ptr coreavThread; - QTimer *iterateTimer = nullptr; - - std::unique_ptr selfVideoSource; - - - /** - * @brief Maps friend IDs to ToxFriendCall. - * @note Need to use STL container here, because Qt containers need a copy - * constructor. - */ - using ToxFriendCallPtr = std::unique_ptr; - std::map calls; - - using ToxGroupCallPtr = std::unique_ptr; - /** - * @brief Maps group IDs to ToxGroupCalls. - * @note Need to use STL container here, because Qt containers need a copy - * constructor. - */ - std::map groupCalls; - - // protect 'calls' and 'groupCalls' - mutable QReadWriteLock callsLock{QReadWriteLock::Recursive}; - + // std::unique_ptr selfVideoSource; + // atomic because potentially accessed by different threads + Core* core; + std::atomic audioCtrl; + std::unique_ptr imCall; + std::unique_ptr coreavThread; + QTimer* iterateTimer = nullptr; + + std::unique_ptr selfVideoSource; + + /** + * @brief Maps friend IDs to ToxFriendCall. + * @note Need to use STL container here, because Qt containers need a copy + * constructor. + */ + using ToxFriendCallPtr = std::unique_ptr; + std::map calls; + + using ToxGroupCallPtr = std::unique_ptr; + /** + * @brief Maps group IDs to ToxGroupCalls. + * @note Need to use STL container here, because Qt containers need a copy + * constructor. + */ + std::map groupCalls; + + // protect 'calls' and 'groupCalls' + mutable QReadWriteLock callsLock{QReadWriteLock::Recursive}; }; -#endif // COREAV_H +#endif // COREAV_H diff --git a/src/modules/im/src/core/corefile.cpp b/src/modules/im/src/core/corefile.cpp index 04e80b9c..0bdc6d75 100644 --- a/src/modules/im/src/core/corefile.cpp +++ b/src/modules/im/src/core/corefile.cpp @@ -11,46 +11,46 @@ */ #include "corefile.h" -#include "lib/messenger/IMFile.h" -#include "core.h" -#include "src/model/status.h" -#include "src/model/toxclientstandards.h" -#include "src/persistence/settings.h" -#include "base/compatiblerecursivemutex.h" -#include "toxfile.h" -#include "toxstring.h" +#include #include #include #include #include #include +#include + #include #include -#include +#include "base/compatiblerecursivemutex.h" #include "base/uuid.h" +#include "core.h" + +#include "src/model/status.h" +#include "src/model/toxclientstandards.h" +#include "src/persistence/settings.h" +#include "toxfile.h" +#include "toxstring.h" /** * @class CoreFile * @brief Manages the file transfer service of toxcore */ -CoreFilePtr CoreFile::makeCoreFile(Core *core, Tox *tox, - CompatibleRecursiveMutex &coreLoopLock) { - assert(core != nullptr); - assert(tox != nullptr); - +CoreFilePtr CoreFile::makeCoreFile(Core* core, CompatibleRecursiveMutex& coreLoopLock) { + assert(core != nullptr); - CoreFilePtr result = CoreFilePtr{new CoreFile{}}; + CoreFilePtr result = CoreFilePtr{new CoreFile{core}}; - // connect(core, &Core::friendStatusChanged, result.get(), -// &CoreFile::onConnectionStatusChanged); + // connect(core, &Core::friendStatusChanged, result.get(), + // &CoreFile::onConnectionStatusChanged); - return result; + return result; } -CoreFile::CoreFile() { - tox = new lib::messenger::IMFile(this); - connectCallbacks(*tox); +CoreFile::CoreFile(Core* core) { + qDebug() << __func__; + // lib::messenger::IMFile *imFile = core->messenger()->imFile(); + // imFile->addFileHandler(this); } /** @@ -61,117 +61,105 @@ CoreFile::CoreFile() { * tox_iterate() calls. */ unsigned CoreFile::corefileIterationInterval() { - /* - Sleep at most 1000ms if we have no FT, 10 for user FTs - There is no real difference between 10ms sleep and 50ms sleep when it - comes to CPU usage – just keep the CPU usage low when there are no file - transfers, and speed things up when there is an ongoing file transfer. - */ - constexpr unsigned fileInterval = 10, idleInterval = 1000; - - for (ToxFile &file : fileMap) { - if (file.status == FileStatus::TRANSMITTING) { - return fileInterval; + /* + Sleep at most 1000ms if we have no FT, 10 for user FTs + There is no real difference between 10ms sleep and 50ms sleep when it + comes to CPU usage – just keep the CPU usage low when there are no file + transfers, and speed things up when there is an ongoing file transfer. + */ + constexpr unsigned fileInterval = 10, idleInterval = 1000; + + for (ToxFile& file : fileMap) { + if (file.status == FileStatus::TRANSMITTING) { + return fileInterval; + } } - } - return idleInterval; -} - -void CoreFile::connectCallbacks(ToxFile1 &tox) { - qDebug() << __func__ << &tox; - tox.addFileHandler(this); + return idleInterval; } -void CoreFile::sendFile(QString friendId, - QString filename, - QString filePath, - quint64 filesize, - quint64 sent) { - - qDebug()<< __func__ << friendId << filename; +void CoreFile::sendFile( + QString friendId, QString filename, QString filePath, quint64 filesize, quint64 sent) { + qDebug() << __func__ << friendId << filename; QMutexLocker{coreLoopLock}; - auto sender= tox0->getSelfId().toFriendId(); + auto sender = messenger->getSelfId().toFriendId(); auto fileId = base::UUID::make(); auto sId = base::UUID::make(); - auto file = ToxFile { - sender, - friendId, - fileId, - sId, - filename, - filePath, - filesize, - sent, - FileStatus::INITIALIZING, - FileDirection::SENDING - }; + auto file = ToxFile{sender, + friendId, + fileId, + sId, + filename, + filePath, + filesize, + sent, + FileStatus::INITIALIZING, + FileDirection::SENDING}; addFile(file); qDebug() << "The file info is:" << file.toString(); - - bool y = tox->fileSendToFriend(friendId, file.toIMFile()); + bool y = messengerFile->fileSendToFriend(friendId, file.toIMFile()); if (!y) { - qWarning() << "sendFile: Sending file is failed."; - emit fileSendFailed(friendId, filename); - return; + qWarning() << "sendFile: Sending file is failed."; + emit fileSendFailed(friendId, filename); + return; } emit fileSendStarted(file); } void CoreFile::pauseResumeFile(QString friendId, QString fileId) { -qDebug()<<"暂不支持"; - // QMutexLocker{coreLoopLock}; -// -// ToxFile *file = findFile(receiver, fileId); -// if (!file) { -// qWarning("pauseResumeFileSend: No such file in queue"); -// return; -// } -// -// if (file->status != FileStatus::TRANSMITTING && -// file->status != FileStatus::PAUSED) { -// qWarning() << "pauseResumeFileSend: File is stopped"; -// return; -// } -// -// file->pauseStatus.localPauseToggle(); -// -// if (file->pauseStatus.paused()) { -// file->status = FileStatus::PAUSED; -// emit fileTransferPaused(*file); -// } else { -// file->status = FileStatus::TRANSMITTING; -// emit fileTransferAccepted(*file); -// } - - // if (file->pauseStatus.localPaused()) { - // tox_file_control(tox, file->receiver, file->fileNum, - // TOX_FILE_CONTROL_PAUSE, - // nullptr); - // } else { - // tox_file_control(tox, file->receiver, file->fileNum, - // TOX_FILE_CONTROL_RESUME, nullptr); - // } + qDebug() << "暂不支持"; + // QMutexLocker{coreLoopLock}; + // + // ToxFile *file = findFile(receiver, fileId); + // if (!file) { + // qWarning("pauseResumeFileSend: No such file in queue"); + // return; + // } + // + // if (file->status != FileStatus::TRANSMITTING && + // file->status != FileStatus::PAUSED) { + // qWarning() << "pauseResumeFileSend: File is stopped"; + // return; + // } + // + // file->pauseStatus.localPauseToggle(); + // + // if (file->pauseStatus.paused()) { + // file->status = FileStatus::PAUSED; + // emit fileTransferPaused(*file); + // } else { + // file->status = FileStatus::TRANSMITTING; + // emit fileTransferAccepted(*file); + // } + + // if (file->pauseStatus.localPaused()) { + // tox_file_control(tox, file->receiver, file->fileNum, + // TOX_FILE_CONTROL_PAUSE, + // nullptr); + // } else { + // tox_file_control(tox, file->receiver, file->fileNum, + // TOX_FILE_CONTROL_RESUME, nullptr); + // } } void CoreFile::cancelFileSend(QString friendId, QString fileId) { - qDebug() << __func__ <<"file"<< fileId; + qDebug() << __func__ << "file" << fileId; QMutexLocker{coreLoopLock}; - ToxFile *file = findFile(fileId); + ToxFile* file = findFile(fileId); if (!file) { - qWarning("cancelFileSend: No such file in queue"); - emit fileTransferNoExisting(friendId, fileId); - return; + qWarning("cancelFileSend: No such file in queue"); + emit fileTransferNoExisting(friendId, fileId); + return; } file->status = FileStatus::CANCELED; - tox->fileCancel(file->fileId); + messengerFile->fileCancel(file->fileId); emit fileTransferCancelled(*file); removeFile(fileId); @@ -180,13 +168,13 @@ void CoreFile::cancelFileSend(QString friendId, QString fileId) { void CoreFile::cancelFileRecv(QString friendId, QString fileId) { QMutexLocker{coreLoopLock}; - ToxFile *file = findFile( fileId); + ToxFile* file = findFile(fileId); if (!file) { - qWarning("cancelFileRecv: No such file in queue"); - return; + qWarning("cancelFileRecv: No such file in queue"); + return; } file->status = FileStatus::CANCELED; - tox->fileRejectRequest(friendId, file->toIMFile()); + messengerFile->fileRejectRequest(friendId, file->toIMFile()); emit fileTransferCancelled(*file); removeFile(fileId); } @@ -194,311 +182,300 @@ void CoreFile::cancelFileRecv(QString friendId, QString fileId) { void CoreFile::rejectFileRecvRequest(QString friendId, QString fileId) { QMutexLocker{coreLoopLock}; - ToxFile *file = findFile( fileId); + ToxFile* file = findFile(fileId); if (!file) { - qWarning("cancelFileRecv: No such file in queue"); - return; + qWarning("cancelFileRecv: No such file in queue"); + return; } file->status = FileStatus::CANCELED; - tox->fileRejectRequest(friendId, file->toIMFile()); + messengerFile->fileRejectRequest(friendId, file->toIMFile()); emit fileTransferCancelled(*file); - removeFile( fileId); + removeFile(fileId); } -void CoreFile::acceptFileRecvRequest(QString friendId, - QString fileId, - QString path) { +void CoreFile::acceptFileRecvRequest(QString friendId, QString fileId, QString path) { QMutexLocker{coreLoopLock}; - qInfo() << __func__ <<"fileId:" << fileId <<"friendId:" << friendId << "path:" << path; + qInfo() << __func__ << "fileId:" << fileId << "friendId:" << friendId << "path:" << path; - ToxFile *file = findFile(fileId); + ToxFile* file = findFile(fileId); if (!file) { - qWarning("acceptFileRecvRequest: No such file in queue"); - return; + qWarning("acceptFileRecvRequest: No such file in queue"); + return; } file->setFilePath(path); if (!file->open(true)) { - qWarning() << "acceptFileRecvRequest: Unable to open file"; - return; + qWarning() << "acceptFileRecvRequest: Unable to open file"; + return; } file->status = FileStatus::TRANSMITTING; - tox->fileAcceptRequest(friendId, file->toIMFile()); + messengerFile->fileAcceptRequest(friendId, file->toIMFile()); emit fileTransferAccepted(*file); } -ToxFile *CoreFile::findFile( QString fileId) { -// qDebug() << __func__ << "fileId:" << fileId; - QMutexLocker{coreLoopLock}; - - if (fileMap.contains(fileId)) { - return &fileMap[fileId]; - } - - qWarning() << __func__ << "fileId" << fileId - << "doesn't exist"; - return nullptr; +ToxFile* CoreFile::findFile(QString fileId) { + // qDebug() << __func__ << "fileId:" << fileId; + QMutexLocker{coreLoopLock}; + + if (fileMap.contains(fileId)) { + return &fileMap[fileId]; + } + + qWarning() << __func__ << "fileId" << fileId << "doesn't exist"; + return nullptr; } -const QString& CoreFile::addFile(ToxFile &file) { - qDebug() << __func__ << "file:"<:"/\\|?])")}; - filename.replace(regex, "_"); + QRegularExpression regex{QStringLiteral(R"([<>:"/\\|?])")}; + filename.replace(regex, "_"); - return filename; + return filename; } -void CoreFile::onFileReceiveCallback(Tox *tox, QString friendId, - QString fileId, uint32_t kind, - uint64_t filesize, const uint8_t *fname, - size_t fnameLen, void *vCore) { - // Core *core = static_cast(vCore); - // CoreFile *coreFile = core->getCoreFile(); - // auto filename = ToxString(fname, fnameLen); - // const ToxPk friendPk = core->getFriendPublicKey(receiver); - // - // if (kind == TOX_FILE_KIND_AVATAR) { - // if (!filesize) { - // qDebug() << QString("Received empty avatar request %1:%2") - // .arg(receiver) - // .arg(fileId); - // // Avatars of size 0 means explicitely no avatar - // tox_file_control(tox, receiver, fileId, TOX_FILE_CONTROL_CANCEL, - // nullptr); emit - // core->friendAvatarRemoved(core->getFriendPublicKey(receiver)); return; - // } else { - // if (!ToxClientStandards::IsValidAvatarSize(filesize)) { - // qWarning() << QString("Received avatar request from %1 with size - // %2.") - // .arg(receiver) - // .arg(filesize) + - // QString(" The max size allowed for avatars is %3. - // " - // "Cancelling transfer.") - // .arg(ToxClientStandards::MaxAvatarSize); - // tox_file_control(tox, receiver, fileId, TOX_FILE_CONTROL_CANCEL, - // nullptr); - // return; - // } - // static_assert(TOX_HASH_LENGTH <= TOX_FILE_ID_LENGTH, - // "TOX_HASH_LENGTH > TOX_FILE_ID_LENGTH!"); - // uint8_t avatarHash[TOX_FILE_ID_LENGTH]; - // tox_file_get_file_id(tox, receiver, fileId, avatarHash, nullptr); - // QByteArray avatarBytes{ - // static_cast(static_cast(avatarHash)), - // TOX_HASH_LENGTH}; - // emit core->fileAvatarOfferReceived(receiver, fileId, avatarBytes); - // return; - // } - // } else { - // const auto cleanFileName = - // CoreFile::getCleanFileName(filename.getQString()); - // if (cleanFileName != filename.getQString()) { - // qDebug() << QStringLiteral("Cleaned filename"); - // filename = ToxString(cleanFileName); - // emit coreFile->fileNameChanged(friendPk); - // } else { - // qDebug() << QStringLiteral("filename already clean"); - // } - // qDebug() << QString("Received file request %1:%2 kind %3") - // .arg(receiver) - // .arg(fileId) - // .arg(kind); - // } - // - // ToxFile file{fileId, receiver, filename.getBytes(), "", - // FileStatus::RECEIVING}; file.fileSize = filesize; file.fileKind = kind; - // file.resumeFileId.resize(TOX_FILE_ID_LENGTH); - // tox_file_get_file_id(tox, receiver, fileId, - // (uint8_t *)file.resumeFileId.data(), nullptr); - // coreFile->addFile(receiver, fileId, file); - // if (kind != TOX_FILE_KIND_AVATAR) { - // emit coreFile->fileReceiveRequested(file); - // } +void CoreFile::onFileReceiveCallback(lib::messenger::Messenger* tox, QString friendId, + QString fileId, uint32_t kind, uint64_t filesize, + const uint8_t* fname, size_t fnameLen, void* vCore) { + // Core *core = static_cast(vCore); + // CoreFile *coreFile = core->getCoreFile(); + // auto filename = ToxString(fname, fnameLen); + // const ToxPk friendPk = core->getFriendPublicKey(receiver); + // + // if (kind == TOX_FILE_KIND_AVATAR) { + // if (!filesize) { + // qDebug() << QString("Received empty avatar request %1:%2") + // .arg(receiver) + // .arg(fileId); + // // Avatars of size 0 means explicitely no avatar + // tox_file_control(tox, receiver, fileId, TOX_FILE_CONTROL_CANCEL, + // nullptr); emit + // core->friendAvatarRemoved(core->getFriendPublicKey(receiver)); return; + // } else { + // if (!ToxClientStandards::IsValidAvatarSize(filesize)) { + // qWarning() << QString("Received avatar request from %1 with size + // %2.") + // .arg(receiver) + // .arg(filesize) + + // QString(" The max size allowed for avatars is %3. + // " + // "Cancelling transfer.") + // .arg(ToxClientStandards::MaxAvatarSize); + // tox_file_control(tox, receiver, fileId, TOX_FILE_CONTROL_CANCEL, + // nullptr); + // return; + // } + // static_assert(TOX_HASH_LENGTH <= TOX_FILE_ID_LENGTH, + // "TOX_HASH_LENGTH > TOX_FILE_ID_LENGTH!"); + // uint8_t avatarHash[TOX_FILE_ID_LENGTH]; + // tox_file_get_file_id(tox, receiver, fileId, avatarHash, nullptr); + // QByteArray avatarBytes{ + // static_cast(static_cast(avatarHash)), + // TOX_HASH_LENGTH}; + // emit core->fileAvatarOfferReceived(receiver, fileId, avatarBytes); + // return; + // } + // } else { + // const auto cleanFileName = + // CoreFile::getCleanFileName(filename.getQString()); + // if (cleanFileName != filename.getQString()) { + // qDebug() << QStringLiteral("Cleaned filename"); + // filename = ToxString(cleanFileName); + // emit coreFile->fileNameChanged(friendPk); + // } else { + // qDebug() << QStringLiteral("filename already clean"); + // } + // qDebug() << QString("Received file request %1:%2 kind %3") + // .arg(receiver) + // .arg(fileId) + // .arg(kind); + // } + // + // ToxFile file{fileId, receiver, filename.getBytes(), "", + // FileStatus::RECEIVING}; file.fileSize = filesize; file.fileKind = kind; + // file.resumeFileId.resize(TOX_FILE_ID_LENGTH); + // tox_file_get_file_id(tox, receiver, fileId, + // (uint8_t *)file.resumeFileId.data(), nullptr); + // coreFile->addFile(receiver, fileId, file); + // if (kind != TOX_FILE_KIND_AVATAR) { + // emit coreFile->fileReceiveRequested(file); + // } } // TODO(sudden6): This whole method is a mess but needed to get stuff working // for now -void CoreFile::handleAvatarOffer(QString friendId, QString fileId, - bool accept) { - // if (!accept) { - // // If it's an avatar but we already have it cached, cancel - // qDebug() << QString("Received avatar request %1:%2, reject, since we - // have " - // "it in cache.") - // .arg(receiver) - // .arg(fileId); - // tox_file_control(tox, receiver, fileId, TOX_FILE_CONTROL_CANCEL, - // nullptr); return; - // } - // - // // It's an avatar and we don't have it, autoaccept the transfer - // qDebug() - // << QString( - // "Received avatar request %1:%2, accept, since we don't have it - // " "in cache.") .arg(receiver) .arg(fileId); - // tox_file_control(tox, receiver, fileId, TOX_FILE_CONTROL_RESUME, nullptr); - // - // ToxFile file{fileId, receiver, "", "", FileStatus::RECEIVING}; - // file.fileSize = 0; - // file.fileKind = TOX_FILE_KIND_AVATAR; - // file.resumeFileId.resize(TOX_FILE_ID_LENGTH); - // tox_file_get_file_id(tox, receiver, fileId, - // (uint8_t *)file.resumeFileId.data(), nullptr); - // addFile(receiver, fileId, file); +void CoreFile::handleAvatarOffer(QString friendId, QString fileId, bool accept) { + // if (!accept) { + // // If it's an avatar but we already have it cached, cancel + // qDebug() << QString("Received avatar request %1:%2, reject, since we + // have " + // "it in cache.") + // .arg(receiver) + // .arg(fileId); + // tox_file_control(tox, receiver, fileId, TOX_FILE_CONTROL_CANCEL, + // nullptr); return; + // } + // + // // It's an avatar and we don't have it, autoaccept the transfer + // qDebug() + // << QString( + // "Received avatar request %1:%2, accept, since we don't have it + // " "in cache.") .arg(receiver) .arg(fileId); + // tox_file_control(tox, receiver, fileId, TOX_FILE_CONTROL_RESUME, nullptr); + // + // ToxFile file{fileId, receiver, "", "", FileStatus::RECEIVING}; + // file.fileSize = 0; + // file.fileKind = TOX_FILE_KIND_AVATAR; + // file.resumeFileId.resize(TOX_FILE_ID_LENGTH); + // tox_file_get_file_id(tox, receiver, fileId, + // (uint8_t *)file.resumeFileId.data(), nullptr); + // addFile(receiver, fileId, file); } -void CoreFile::onFileRequest(const QString &from, - const lib::messenger::File &file) { - qDebug() << __func__<< file.name << "from"<< from; +void CoreFile::onFileRequest(const QString& from, const lib::messenger::File& file) { + qDebug() << __func__ << file.name << "from" << from; - auto receiver = tox0->getSelfId().toFriendId(); - ToxFile toxFile(from, receiver, file); - addFile(toxFile); - qDebug() <<"file:" << toxFile.toString(); - emit fileReceiveRequested(toxFile); +// auto receiver = messenger->getSelfId().toFriendId(); +// ToxFile toxFile(from, receiver, file); +// addFile(toxFile); +// qDebug() << "file:" << toxFile.toString(); +// emit fileReceiveRequested(toxFile); } -void CoreFile::onFileControlCallback(Tox *, QString friendId, - QString fileId, - lib::messenger::FileControl control, - void *vCore) { - Core *core = static_cast(vCore); - CoreFile *coreFile = core->getCoreFile(); - ToxFile *file = coreFile->findFile( fileId); - if (!file) { - qWarning("onFileControlCallback: No such file in queue"); - return; - } - - if (control == lib::messenger::FileControl::CANCEL) { - file->status = FileStatus::CANCELED; - emit coreFile->fileTransferCancelled(*file); - coreFile->removeFile( fileId); - } else if (control == lib::messenger::FileControl::PAUSE) { - file->status = FileStatus::PAUSED; - emit coreFile->fileTransferRemotePausedUnpaused(*file, true); - } else if (control == lib::messenger::FileControl::RESUME) { - if (file->direction == FileDirection::SENDING) - { - file->status =FileStatus::TRANSMITTING; - emit coreFile->fileTransferRemotePausedUnpaused(*file, false); +void CoreFile::onFileControlCallback(lib::messenger::Messenger* tox, QString friendId, + QString fileId, lib::messenger::FileControl control, + void* vCore) { + Core* core = static_cast(vCore); + CoreFile* coreFile = core->getCoreFile(); + ToxFile* file = coreFile->findFile(fileId); + if (!file) { + qWarning("onFileControlCallback: No such file in queue"); + return; + } + + if (control == lib::messenger::FileControl::CANCEL) { + file->status = FileStatus::CANCELED; + emit coreFile->fileTransferCancelled(*file); + coreFile->removeFile(fileId); + } else if (control == lib::messenger::FileControl::PAUSE) { + file->status = FileStatus::PAUSED; + emit coreFile->fileTransferRemotePausedUnpaused(*file, true); + } else if (control == lib::messenger::FileControl::RESUME) { + if (file->direction == FileDirection::SENDING) { + file->status = FileStatus::TRANSMITTING; + emit coreFile->fileTransferRemotePausedUnpaused(*file, false); + } + } else { + qWarning() << "Unhandled file control " << (int)control << " for file " << friendId << ':' + << fileId; } - }else { - qWarning() << "Unhandled file control " << (int)control << " for file " - << friendId << ':' << fileId; - } } -void CoreFile::onFileDataCallback(Tox *tox, QString friendId, QString fileId, - uint64_t pos, size_t length, void *vCore) { - - // Core *core = static_cast(vCore); - // CoreFile *coreFile = core->getCoreFile(); - // ToxFile *file = coreFile->findFile(receiver, fileId); - // if (!file) { - // qWarning("onFileDataCallback: No such file in queue"); - // return; - // } - // - // // If we reached EOF, ack and cleanup the transfer - // if (!length) { - // file->status = FileStatus::FINISHED; - // if (file->fileKind != TOX_FILE_KIND_AVATAR) { - // emit coreFile->fileTransferFinished(*file); - // emit coreFile->fileUploadFinished(file->filePath); - // } - // coreFile->removeFile(receiver, fileId); - // return; - // } - // - // std::unique_ptr data(new uint8_t[length]); - // int64_t nread; - // - // if (file->fileKind == TOX_FILE_KIND_AVATAR) { - // QByteArray chunk = file->avatarData.mid(pos, length); - // nread = chunk.size(); - // memcpy(data.get(), chunk.data(), nread); - // } else { - // file->file->seek(pos); - // nread = file->file->read((char *)data.get(), length); - // if (nread <= 0) { - // qWarning("onFileDataCallback: Failed to read from file"); - // file->status = FileStatus::CANCELED; - // emit coreFile->fileTransferCancelled(*file); - // tox_file_send_chunk(tox, receiver, fileId, pos, nullptr, 0, nullptr); - // coreFile->removeFile(receiver, fileId); - // return; - // } - // file->bytesSent += length; - // file->hashGenerator->addData((const char *)data.get(), length); - // } - // - // if (!tox_file_send_chunk(tox, receiver, fileId, pos, data.get(), nread, - // nullptr)) { - // qWarning("onFileDataCallback: Failed to send data chunk"); - // return; - // } - // if (file->fileKind != TOX_FILE_KIND_AVATAR) { - // emit coreFile->fileTransferInfo(*file); - // } +void CoreFile::onFileDataCallback(lib::messenger::Messenger* tox, QString friendId, QString fileId, + uint64_t pos, size_t length, void* vCore) { + // Core *core = static_cast(vCore); + // CoreFile *coreFile = core->getCoreFile(); + // ToxFile *file = coreFile->findFile(receiver, fileId); + // if (!file) { + // qWarning("onFileDataCallback: No such file in queue"); + // return; + // } + // + // // If we reached EOF, ack and cleanup the transfer + // if (!length) { + // file->status = FileStatus::FINISHED; + // if (file->fileKind != TOX_FILE_KIND_AVATAR) { + // emit coreFile->fileTransferFinished(*file); + // emit coreFile->fileUploadFinished(file->filePath); + // } + // coreFile->removeFile(receiver, fileId); + // return; + // } + // + // std::unique_ptr data(new uint8_t[length]); + // int64_t nread; + // + // if (file->fileKind == TOX_FILE_KIND_AVATAR) { + // QByteArray chunk = file->avatarData.mid(pos, length); + // nread = chunk.size(); + // memcpy(data.get(), chunk.data(), nread); + // } else { + // file->file->seek(pos); + // nread = file->file->read((char *)data.get(), length); + // if (nread <= 0) { + // qWarning("onFileDataCallback: Failed to read from file"); + // file->status = FileStatus::CANCELED; + // emit coreFile->fileTransferCancelled(*file); + // tox_file_send_chunk(tox, receiver, fileId, pos, nullptr, 0, nullptr); + // coreFile->removeFile(receiver, fileId); + // return; + // } + // file->bytesSent += length; + // file->hashGenerator->addData((const char *)data.get(), length); + // } + // + // if (!tox_file_send_chunk(tox, receiver, fileId, pos, data.get(), nread, + // nullptr)) { + // qWarning("onFileDataCallback: Failed to send data chunk"); + // return; + // } + // if (file->fileKind != TOX_FILE_KIND_AVATAR) { + // emit coreFile->fileTransferInfo(*file); + // } } -void CoreFile::onFileSendInfo(const QString &friendId, // - const lib::messenger::File &file_, // +void CoreFile::onFileSendInfo(const QString& friendId, // + const lib::messenger::File& file_, // int m_seq, int m_sentBytes, bool end) { - qDebug() << __func__ << friendId - << "file"<< file_.id - << "isEnd"<bytesSent += m_sentBytes; if (!end) { - file->status = FileStatus::TRANSMITTING; - emit fileTransferInfo(*file); + file->status = FileStatus::TRANSMITTING; + emit fileTransferInfo(*file); } else { - file->status = FileStatus::FINISHED; - emit fileTransferFinished(*file); - emit fileUploadFinished(file->filePath); - removeFile( file->fileId); + file->status = FileStatus::FINISHED; + emit fileTransferFinished(*file); + emit fileUploadFinished(file->filePath); + removeFile(file->fileId); } } -void CoreFile::onFileSendAbort(const QString &friendId, const lib::messenger::File &file_, int m_sentBytes) { +void CoreFile::onFileSendAbort(const QString& friendId, const lib::messenger::File& file_, + int m_sentBytes) { qDebug() << __func__ << file_.id; - ToxFile *file = findFile( file_.id); + ToxFile* file = findFile(file_.id); if (!file) { - qWarning()<<__func__<<"No such file in queue"; - return; + qWarning() << __func__ << "No such file in queue"; + return; } file->bytesSent = m_sentBytes; file->status = FileStatus::CANCELED; @@ -506,14 +483,14 @@ void CoreFile::onFileSendAbort(const QString &friendId, const lib::messenger::Fi removeFile(file->fileId); } -void CoreFile::onFileSendError(const QString &friendId, - const lib::messenger::File &file_, +void CoreFile::onFileSendError(const QString& friendId, + const lib::messenger::File& file_, int m_sentBytes) { - qWarning()<<__func__; - ToxFile *file = findFile(file_.id); + qWarning() << __func__; + ToxFile* file = findFile(file_.id); if (!file) { - qWarning()<<__func__<<"No such file in queue"; - return; + qWarning() << __func__ << "No such file in queue"; + return; } file->bytesSent = m_sentBytes; file->status = FileStatus::CANCELED; @@ -521,125 +498,122 @@ void CoreFile::onFileSendError(const QString &friendId, emit fileSendFailed(friendId, file->fileName); } -void CoreFile::onFileRecvChunkCallback(Tox *tox, QString friendId, - QString fileId, uint64_t position, - const uint8_t *data, size_t length, - void *vCore) { - // Core *core = static_cast(vCore); - // CoreFile *coreFile = core->getCoreFile(); - // ToxFile *file = coreFile->findFile(receiver, fileId); - // if (!file) { - // qWarning("onFileRecvChunkCallback: No such file in queue"); - // tox_file_control(tox, receiver, fileId, TOX_FILE_CONTROL_CANCEL, - // nullptr); return; - // } - // - // if (file->bytesSent != position) { - // qWarning("onFileRecvChunkCallback: Received a chunk out-of-order, - // aborting " - // "transfer"); - // if (file->fileKind != TOX_FILE_KIND_AVATAR) { - // file->status = FileStatus::CANCELED; - // emit coreFile->fileTransferCancelled(*file); - // } - // tox_file_control(tox, receiver, fileId, TOX_FILE_CONTROL_CANCEL, - // nullptr); coreFile->removeFile(receiver, fileId); return; - // } - // - // if (!length) { - // file->status = FileStatus::FINISHED; - // if (file->fileKind == TOX_FILE_KIND_AVATAR) { - // QPixmap pic; - // pic.loadFromData(file->avatarData); - // if (!pic.isNull()) { - // qDebug() << "Got" << file->avatarData.size() - // << "bytes of avatar data from" << receiver; - // emit core->friendAvatarChanged(core->getFriendPublicKey(receiver), - // file->avatarData); - // } - // } else { - // emit coreFile->fileTransferFinished(*file); - // emit coreFile->fileDownloadFinished(file->filePath); - // } - // coreFile->removeFile(receiver, fileId); - // return; - // } - // - // if (file->fileKind == TOX_FILE_KIND_AVATAR) { - // file->avatarData.append((char *)data, length); - // } else { - // file->file->write((char *)data, length); - // } - // file->bytesSent += length; - // file->hashGenerator->addData((const char *)data, length); - // - // if (file->fileKind != TOX_FILE_KIND_AVATAR) { - // emit coreFile->fileTransferInfo(*file); - // } +void CoreFile::onFileRecvChunkCallback(lib::messenger::Messenger* tox, QString friendId, + QString fileId, uint64_t position, const uint8_t* data, + size_t length, void* vCore) { + // Core *core = static_cast(vCore); + // CoreFile *coreFile = core->getCoreFile(); + // ToxFile *file = coreFile->findFile(receiver, fileId); + // if (!file) { + // qWarning("onFileRecvChunkCallback: No such file in queue"); + // tox_file_control(tox, receiver, fileId, TOX_FILE_CONTROL_CANCEL, + // nullptr); return; + // } + // + // if (file->bytesSent != position) { + // qWarning("onFileRecvChunkCallback: Received a chunk out-of-order, + // aborting " + // "transfer"); + // if (file->fileKind != TOX_FILE_KIND_AVATAR) { + // file->status = FileStatus::CANCELED; + // emit coreFile->fileTransferCancelled(*file); + // } + // tox_file_control(tox, receiver, fileId, TOX_FILE_CONTROL_CANCEL, + // nullptr); coreFile->removeFile(receiver, fileId); return; + // } + // + // if (!length) { + // file->status = FileStatus::FINISHED; + // if (file->fileKind == TOX_FILE_KIND_AVATAR) { + // QPixmap pic; + // pic.loadFromData(file->avatarData); + // if (!pic.isNull()) { + // qDebug() << "Got" << file->avatarData.size() + // << "bytes of avatar data from" << receiver; + // emit core->friendAvatarChanged(core->getFriendPublicKey(receiver), + // file->avatarData); + // } + // } else { + // emit coreFile->fileTransferFinished(*file); + // emit coreFile->fileDownloadFinished(file->filePath); + // } + // coreFile->removeFile(receiver, fileId); + // return; + // } + // + // if (file->fileKind == TOX_FILE_KIND_AVATAR) { + // file->avatarData.append((char *)data, length); + // } else { + // file->file->write((char *)data, length); + // } + // file->bytesSent += length; + // file->hashGenerator->addData((const char *)data, length); + // + // if (file->fileKind != TOX_FILE_KIND_AVATAR) { + // emit coreFile->fileTransferInfo(*file); + // } } -void CoreFile::onFileRecvChunk(const QString &friendId, const QString &fileId, int seq, const std::string &chunk) { - ToxFile *file = findFile(fileId); - if (!file) { - qWarning()<<("No such file in queue"); - return; - } +void CoreFile::onFileRecvChunk(const QString& friendId, const QString& fileId, int seq, + const std::string& chunk) { + ToxFile* file = findFile(fileId); + if (!file) { + qWarning() << ("No such file in queue"); + return; + } if (file->bytesSent > file->fileSize) { - qWarning()<<("Received a chunk out-of-order, aborting transfer"); + qWarning() << ("Received a chunk out-of-order, aborting transfer"); - file->status = FileStatus::CANCELED; - emit fileTransferCancelled(*file); + file->status = FileStatus::CANCELED; + emit fileTransferCancelled(*file); -// 取消传输 - tox->fileCancel(fileId); - removeFile(fileId); - return; + // 取消传输 + messengerFile->fileCancel(fileId); + removeFile(fileId); + return; } QByteArray buf = QByteArray::fromStdString(chunk); file->file->write(buf); -// file->hashGenerator->addData(buf); + // file->hashGenerator->addData(buf); file->bytesSent += buf.size(); - qDebug() << "Received bytes" << buf.size() << "/"<fileSize; + qDebug() << "Received bytes" << buf.size() << "/" << file->fileSize; emit fileTransferInfo(*file); } -void CoreFile::onFileRecvFinished(const QString &friendId, const QString &fileId) { - ToxFile *file = findFile(fileId); +void CoreFile::onFileRecvFinished(const QString& friendId, const QString& fileId) { + ToxFile* file = findFile(fileId); if (!file) { - qWarning() << __func__ << "No such file in queue"; - return; + qWarning() << __func__ << "No such file in queue"; + return; } file->status = FileStatus::FINISHED; - tox->fileFinishTransfer(friendId, file->sId); + messengerFile->fileFinishTransfer(friendId, file->sId); emit fileTransferFinished(*file); emit fileDownloadFinished(file->filePath); removeFile(fileId); - } -void CoreFile::onConnectionStatusChanged(QString friendId, - Status::Status state) { - // bool isOffline = state == Status::Status::Offline; - // // TODO: Actually resume broken file transfers - // // We need to: - // // - Start a new file transfer with the same 32byte file ID with toxcore - // // - Seek to the correct position again - // // - Update the fileNum in our ToxFile - // // - Update the users of our signals to check the 32byte tox file ID, not - // the - // // uint32_t file_num (fileId) - // FileStatus::FileStatus status = - // !isOffline ? FileStatus::TRANSMITTING : FileStatus::BROKEN; - // for (QString key : fileMap.keys()) { - // if (key >> 32 != receiver) - // continue; - // fileMap[key].status = status; - // emit fileTransferBrokenUnbroken(fileMap[key], isOffline); - // } +void CoreFile::onConnectionStatusChanged(QString friendId, Status::Status state) { + // bool isOffline = state == Status::Status::Offline; + // // TODO: Actually resume broken file transfers + // // We need to: + // // - Start a new file transfer with the same 32byte file ID with toxcore + // // - Seek to the correct position again + // // - Update the fileNum in our ToxFile + // // - Update the users of our signals to check the 32byte tox file ID, not + // the + // // uint32_t file_num (fileId) + // FileStatus::FileStatus status = + // !isOffline ? FileStatus::TRANSMITTING : FileStatus::BROKEN; + // for (QString key : fileMap.keys()) { + // if (key >> 32 != receiver) + // continue; + // fileMap[key].status = status; + // emit fileTransferBrokenUnbroken(fileMap[key], isOffline); + // } } - diff --git a/src/modules/im/src/core/corefile.h b/src/modules/im/src/core/corefile.h index d9165c81..e15e657a 100644 --- a/src/modules/im/src/core/corefile.h +++ b/src/modules/im/src/core/corefile.h @@ -30,105 +30,100 @@ #include #include "lib/messenger/messenger.h" -#include "lib/messenger/IMFile.h" class CoreFile; using CoreFilePtr = std::unique_ptr; class CoreFile : public QObject, public lib::messenger::FileHandler { - Q_OBJECT + Q_OBJECT public: + static CoreFilePtr makeCoreFile(Core* core, CompatibleRecursiveMutex& coreLoopLock); - static CoreFilePtr makeCoreFile(Core *core, Tox *tox, - CompatibleRecursiveMutex &coreLoopLock); + void handleAvatarOffer(QString friendId, QString fileId, bool accept); - void handleAvatarOffer(QString friendId, QString fileId, bool accept); + void sendFile(QString friendId, + QString filename, + QString filePath, + quint64 filesize, + quint64 sent = 0); - void sendFile( - QString friendId, - QString filename, - QString filePath, - quint64 filesize, - quint64 sent=0); + void pauseResumeFile(QString friendId, QString fileId); + void cancelFileSend(QString friendId, QString fileId); - void pauseResumeFile(QString friendId, QString fileId); - void cancelFileSend(QString friendId, QString fileId); + void cancelFileRecv(QString friendId, QString fileId); + void rejectFileRecvRequest(QString friendId, QString fileId); + void acceptFileRecvRequest(QString friendId, QString fileId, QString path); - void cancelFileRecv(QString friendId, QString fileId); - void rejectFileRecvRequest(QString friendId, QString fileId); - void acceptFileRecvRequest(QString friendId, QString fileId, QString path); + unsigned corefileIterationInterval(); - unsigned corefileIterationInterval(); + /** + * File handlers + */ - /** - * File handlers - */ + void onFileRequest(const QString& friendId, const lib::messenger::File& file) override; + void onFileRecvChunk(const QString& friendId, const QString& fileId, int seq, + const std::string& chunk) override; + void onFileRecvFinished(const QString& friendId, const QString& fileId) override; + void onFileSendInfo(const QString& friendId, const lib::messenger::File& file, int m_seq, + int m_sentBytes, bool end) override; - void onFileRequest(const QString &friendId, const lib::messenger::File& file) override; - void onFileRecvChunk(const QString &friendId, const QString& fileId, int seq, const std::string &chunk) override; - void onFileRecvFinished(const QString &friendId, const QString& fileId) override; - void onFileSendInfo(const QString &friendId, const lib::messenger::File &file, int m_seq, - int m_sentBytes, bool end) override; - - void onFileSendAbort(const QString &friendId, const lib::messenger::File &file, - int m_sentBytes) override; - void onFileSendError(const QString &friendId, const lib::messenger::File &file, - int m_sentBytes) override; + void onFileSendAbort(const QString& friendId, const lib::messenger::File& file, + int m_sentBytes) override; + void onFileSendError(const QString& friendId, const lib::messenger::File& file, + int m_sentBytes) override; signals: - void fileSendStarted(ToxFile file); - void fileReceiveRequested(ToxFile file); - void fileTransferAccepted(ToxFile file); - void fileTransferCancelled(ToxFile file); - void fileTransferFinished(ToxFile file); - void fileTransferNoExisting(const QString &friendId, const QString &fileId); - void fileUploadFinished(const QString &path); - void fileDownloadFinished(const QString &path); - void fileTransferPaused(ToxFile file); - void fileTransferInfo(ToxFile file); - void fileTransferRemotePausedUnpaused(ToxFile file, bool paused); - void fileTransferBrokenUnbroken(ToxFile file, bool broken); - void fileNameChanged(const FriendId &friendPk); - void fileSendFailed(QString friendId, const QString &fname); + void fileSendStarted(ToxFile file); + void fileReceiveRequested(ToxFile file); + void fileTransferAccepted(ToxFile file); + void fileTransferCancelled(ToxFile file); + void fileTransferFinished(ToxFile file); + void fileTransferNoExisting(const QString& friendId, const QString& fileId); + void fileUploadFinished(const QString& path); + void fileDownloadFinished(const QString& path); + void fileTransferPaused(ToxFile file); + void fileTransferInfo(ToxFile file); + void fileTransferRemotePausedUnpaused(ToxFile file, bool paused); + void fileTransferBrokenUnbroken(ToxFile file, bool broken); + void fileNameChanged(const FriendId& friendPk); + void fileSendFailed(QString friendId, const QString& fname); private: - CoreFile(); - - ToxFile *findFile(QString fileId); - const QString& addFile(ToxFile &file); - void removeFile(QString fileId); - - static QString getFriendKey(const QString& friendId, QString fileId) { - return friendId + "-"+ fileId; - } - - lib::messenger::File buildHandlerFile(const ToxFile* toxFile); - - void connectCallbacks(ToxFile1 &tox); - static void onFileReceiveCallback(Tox *tox, QString friendId, QString fileId, - uint32_t kind, uint64_t filesize, - const uint8_t *fname, size_t fnameLen, - void *vCore); - static void onFileControlCallback(Tox *tox, QString friendId, QString fileId, - lib::messenger::FileControl control, void *vCore); - static void onFileDataCallback(Tox *tox, QString friendId, QString fileId, - uint64_t pos, size_t length, void *vCore); - static void onFileRecvChunkCallback(Tox *tox, QString friendId, - QString fileId, uint64_t position, - const uint8_t *data, size_t length, - void *vCore); - - static QString getCleanFileName(QString filename); + CoreFile(Core*); + + ToxFile* findFile(QString fileId); + const QString& addFile(ToxFile& file); + void removeFile(QString fileId); + + static QString getFriendKey(const QString& friendId, QString fileId) { + return friendId + "-" + fileId; + } + + lib::messenger::File buildHandlerFile(const ToxFile* toxFile); + + static void onFileReceiveCallback(lib::messenger::Messenger* tox, QString friendId, + QString fileId, uint32_t kind, uint64_t filesize, + const uint8_t* fname, size_t fnameLen, void* vCore); + static void onFileControlCallback(lib::messenger::Messenger* tox, QString friendId, + QString fileId, lib::messenger::FileControl control, + void* vCore); + static void onFileDataCallback(lib::messenger::Messenger* tox, QString friendId, QString fileId, + uint64_t pos, size_t length, void* vCore); + static void onFileRecvChunkCallback(lib::messenger::Messenger* tox, QString friendId, + QString fileId, uint64_t position, const uint8_t* data, + size_t length, void* vCore); + + static QString getCleanFileName(QString filename); private slots: - void onConnectionStatusChanged(QString friendId, Status::Status state); + void onConnectionStatusChanged(QString friendId, Status::Status state); private: - QHash fileMap; - ToxFile1 *tox; - Tox *tox0; - CompatibleRecursiveMutex *coreLoopLock = nullptr; + QHash fileMap; + lib::messenger::Messenger* messenger; + lib::messenger::MessengerFile* messengerFile; + CompatibleRecursiveMutex* coreLoopLock = nullptr; }; -#endif // COREFILE_H +#endif // COREFILE_H diff --git a/src/modules/im/src/core/dhtserver.cpp b/src/modules/im/src/core/dhtserver.cpp index 0265bbfe..0a434899 100644 --- a/src/modules/im/src/core/dhtserver.cpp +++ b/src/modules/im/src/core/dhtserver.cpp @@ -17,10 +17,9 @@ * @param other the compared instance * @return true, if equal; false otherwise */ -bool DhtServer::operator==(const DhtServer& other) const -{ - return this == &other || (port == other.port && address == other.address - && userId == other.userId && name == other.name); +bool DhtServer::operator==(const DhtServer& other) const { + return this == &other || (port == other.port && address == other.address && + userId == other.userId && name == other.name); } /** @@ -28,7 +27,4 @@ bool DhtServer::operator==(const DhtServer& other) const * @param other the compared instance * @return true, if not equal; false otherwise */ -bool DhtServer::operator!=(const DhtServer& other) const -{ - return !(*this == other); -} +bool DhtServer::operator!=(const DhtServer& other) const { return !(*this == other); } diff --git a/src/modules/im/src/core/dhtserver.h b/src/modules/im/src/core/dhtserver.h index 990b4402..bc36ea97 100644 --- a/src/modules/im/src/core/dhtserver.h +++ b/src/modules/im/src/core/dhtserver.h @@ -15,8 +15,7 @@ #include -struct DhtServer -{ +struct DhtServer { QString name; QString userId; QString address; @@ -26,4 +25,4 @@ struct DhtServer bool operator!=(const DhtServer& other) const; }; -#endif // DHT_SERVER_H +#endif // DHT_SERVER_H diff --git a/src/modules/im/src/core/groupid.cpp b/src/modules/im/src/core/groupid.cpp index 62c0171c..afcb6c97 100644 --- a/src/modules/im/src/core/groupid.cpp +++ b/src/modules/im/src/core/groupid.cpp @@ -25,56 +25,30 @@ /** * @brief The default constructor. Creates an empty Tox group ID. */ -GroupId::GroupId() : ContactId() -{ -} +GroupId::GroupId() : ContactId() {} /** * @brief The copy constructor. * @param other GroupId to copy */ -GroupId::GroupId(const GroupId& other) - : ContactId(other.toString().toUtf8()) -{ -} +GroupId::GroupId(const GroupId& other) : ContactId(other.toString().toUtf8()) {} -GroupId::GroupId(const QByteArray &rawId) - : ContactId(rawId) -{ +GroupId::GroupId(const QByteArray& rawId) : ContactId(rawId) {} -} - -GroupId::GroupId(const QString &rawId):ContactId(rawId) -{ - -} +GroupId::GroupId(const QString& rawId) : ContactId(rawId) {} /** * @brief Constructs a GroupId from bytes. * @param rawId The bytes to construct the GroupId from. The lenght must be exactly * TOX_CONFERENCE_UID_SIZE, else the GroupId will be empty. */ -GroupId::GroupId(const ContactId& contactId) - : ContactId(contactId) -{ - -} +GroupId::GroupId(const ContactId& contactId) : ContactId(contactId) {} /** * @brief Get size of public id in bytes. * @return Size of public id in bytes. */ -int GroupId::getSize() const -{ - return toString().size(); -} - -bool GroupId::operator==(const GroupId& other) const -{ - return ContactId::operator==(other); -} +int GroupId::getSize() const { return toString().size(); } -bool GroupId::operator<(const GroupId& other) const -{ - return toString() < other.toString(); -} +bool GroupId::operator==(const GroupId& other) const { return ContactId::operator==(other); } +bool GroupId::operator<(const GroupId& other) const { return toString() < other.toString(); } diff --git a/src/modules/im/src/core/groupid.h b/src/modules/im/src/core/groupid.h index 27521fc4..b13f8a09 100644 --- a/src/modules/im/src/core/groupid.h +++ b/src/modules/im/src/core/groupid.h @@ -15,8 +15,7 @@ #include "src/core/contactid.h" - -class GroupId : public ContactId{ +class GroupId : public ContactId { public: GroupId(); GroupId(const GroupId& other); @@ -25,11 +24,11 @@ class GroupId : public ContactId{ explicit GroupId(const ContactId& contactId); int getSize() const; - bool operator==(const GroupId &other) const; - bool operator<(const GroupId &other) const; + bool operator==(const GroupId& other) const; + bool operator<(const GroupId& other) const; QString name; QString nick; }; -#endif // GROUPID_H +#endif // GROUPID_H diff --git a/src/modules/im/src/core/icorefriendmessagesender.h b/src/modules/im/src/core/icorefriendmessagesender.h index ac2cd618..a8b1eb21 100644 --- a/src/modules/im/src/core/icorefriendmessagesender.h +++ b/src/modules/im/src/core/icorefriendmessagesender.h @@ -20,11 +20,11 @@ class ICoreFriendMessageSender { public: - virtual ~ICoreFriendMessageSender() = default; - virtual bool sendAction(QString friendId, const QString &action, - const MsgId &msgId, bool encrypt = false) = 0; - virtual bool sendMessage(QString friendId, const QString &message, - const MsgId &msgId, bool encrypt = false) = 0; + virtual ~ICoreFriendMessageSender() = default; + virtual bool sendAction(QString friendId, const QString& action, const MsgId& msgId, + bool encrypt = false) = 0; + virtual bool sendMessage(QString friendId, const QString& message, const MsgId& msgId, + bool encrypt = false) = 0; }; #endif /* ICORE_FRIEND_MESSAGE_SENDER_H */ diff --git a/src/modules/im/src/core/icoregroupmessagesender.h b/src/modules/im/src/core/icoregroupmessagesender.h index da64ccbb..95a07863 100644 --- a/src/modules/im/src/core/icoregroupmessagesender.h +++ b/src/modules/im/src/core/icoregroupmessagesender.h @@ -17,13 +17,11 @@ #include "../model/MsgId.h" - -class ICoreGroupMessageSender -{ +class ICoreGroupMessageSender { public: virtual ~ICoreGroupMessageSender() = default; - virtual bool sendGroupAction(QString groupId, const QString& message, const MsgId &id) = 0; - virtual bool sendGroupMessage(QString groupId, const QString& message, const MsgId &id) = 0; + virtual bool sendGroupAction(QString groupId, const QString& message, const MsgId& id) = 0; + virtual bool sendGroupMessage(QString groupId, const QString& message, const MsgId& id) = 0; }; #endif /*ICORE_GROUP_MESSAGE_SENDER_H*/ diff --git a/src/modules/im/src/core/icoregroupquery.h b/src/modules/im/src/core/icoregroupquery.h index 0485487d..8175d4f0 100644 --- a/src/modules/im/src/core/icoregroupquery.h +++ b/src/modules/im/src/core/icoregroupquery.h @@ -21,8 +21,7 @@ #include -class ICoreGroupQuery -{ +class ICoreGroupQuery { public: virtual ~ICoreGroupQuery() = default; virtual GroupId getGroupPersistentId(QString groupId) const = 0; diff --git a/src/modules/im/src/core/icoreidhandler.h b/src/modules/im/src/core/icoreidhandler.h index 8dc71589..5824e1c5 100644 --- a/src/modules/im/src/core/icoreidhandler.h +++ b/src/modules/im/src/core/icoreidhandler.h @@ -16,9 +16,7 @@ #include "FriendId.h" #include "toxid.h" -class ICoreIdHandler -{ - +class ICoreIdHandler { public: virtual ~ICoreIdHandler() = default; virtual ToxId getSelfPeerId() const = 0; @@ -27,5 +25,4 @@ class ICoreIdHandler virtual QString getNick() const = 0; }; - #endif /*ICORE_ID_HANDLER_H*/ diff --git a/src/modules/im/src/core/icoresettings.h b/src/modules/im/src/core/icoresettings.h index 33381a07..7b1daa5d 100644 --- a/src/modules/im/src/core/icoresettings.h +++ b/src/modules/im/src/core/icoresettings.h @@ -22,8 +22,7 @@ class QNetworkProxy; class ICoreSettings { public: - enum class ProxyType - { + enum class ProxyType { // If changed, don't forget to update Settings::fixInvalidProxyType ptNone = 0, ptSOCKS5 = 1, @@ -59,4 +58,4 @@ class ICoreSettings { DECLARE_SIGNAL(proxyPortChanged, quint16 port); }; -#endif // I_CORE_SETTINGS_H +#endif // I_CORE_SETTINGS_H diff --git a/src/modules/im/src/core/toxcall.cpp b/src/modules/im/src/core/toxcall.cpp index 68118d36..1bcce0cd 100644 --- a/src/modules/im/src/core/toxcall.cpp +++ b/src/modules/im/src/core/toxcall.cpp @@ -11,14 +11,14 @@ */ #include "src/core/toxcall.h" +#include #include "src/audio/audio.h" #include "src/core/coreav.h" #include "src/model/group.h" #include "src/persistence/settings.h" #include "src/video/camerasource.h" #include "src/video/corevideosource.h" -#include -//#include +// #include /** * @var uint32_t ToxCall::callId @@ -36,25 +36,23 @@ * @var bool ToxFriendCall::nullVideoBitrate * @brief True if our video bitrate is zero, i.e. if the device is closed. * - * @var TOXAV_FRIEND_CALL_STATE ToxFriendCall::state + * @var CallState ToxFriendCall::state * @brief State of the peer (not ours!) * * @var QMap ToxGroupCall::peers * @brief Keeps sources for users in group calls. */ -ToxCall::ToxCall(bool VideoEnabled, CoreAV &av, IAudioControl &audio) - : av{&av}, - audio(audio), - videoEnabled{VideoEnabled} { - audioSource = audio.makeSource(); +ToxCall::ToxCall(bool VideoEnabled, CoreAV& av, IAudioControl& audio) + : av{&av}, audio(audio), videoEnabled{VideoEnabled} { + audioSource = audio.makeSource(); } ToxCall::~ToxCall() { - if (videoEnabled) { - QObject::disconnect(videoInConn); -// CameraSource::getInstance().unsubscribe(); - } + if (videoEnabled) { + QObject::disconnect(videoInConn); + // CameraSource::getInstance().unsubscribe(); + } } bool ToxCall::isActive() const { return active; } @@ -77,192 +75,180 @@ bool ToxCall::getNullVideoBitrate() const { return nullVideoBitrate; } void ToxCall::setNullVideoBitrate(bool value) { nullVideoBitrate = value; } -CoreVideoSource *ToxCall::getVideoSource() const { return videoSource; } +CoreVideoSource* ToxCall::getVideoSource() const { return videoSource; } -QString ToxCall::getCallId() const { return callId; } +QString ToxCall::getCallId() const { return callId; } void ToxCall::setCallId(QString value) { callId = value; } -ToxFriendCall::ToxFriendCall(QString peerId, bool VideoEnabled, CoreAV &av, - IAudioControl &audio) - : ToxCall(VideoEnabled, av, audio), - sink(audio.makeSink()), peerId{peerId} -{ - - connect( - audioSource.get(), &IAudioSource::frameAvailable, this, - [this](const int16_t *pcm, size_t samples, uint8_t chans, uint32_t rate) { - this->av->sendCallAudio(this->peerId, pcm, samples, chans, rate); - }); - - connect(audioSource.get(), &IAudioSource::invalidated, this, - &ToxFriendCall::onAudioSourceInvalidated); - - if (sink) { - audioSinkInvalid = sink->connectTo_invalidated( - this, [this]() { this->onAudioSinkInvalidated(); }); - } - - // register video - if (videoEnabled) { - videoSource = new CoreVideoSource(); - // CameraSource& source = CameraSource::getInstance(); - - // if (source.isNone()) { - // source.setupDefault(); - // } - // source.subscribe(); - // videoInConn = QObject::connect(&source, &VideoSource::frameAvailable, - // [&av, - // receiver](std::shared_ptr - // frame) { - // av.sendCallVideo(receiver, frame); - // }); - // if (!videoInConn) { - // qDebug() << "Video connection not working"; - // } - } +ToxFriendCall::ToxFriendCall(QString peerId, bool VideoEnabled, CoreAV& av, IAudioControl& audio) + : ToxCall(VideoEnabled, av, audio), sink(audio.makeSink()), peerId{peerId} { + connect(audioSource.get(), &IAudioSource::frameAvailable, this, + [this](const int16_t* pcm, size_t samples, uint8_t chans, uint32_t rate) { + this->av->sendCallAudio(this->peerId, pcm, samples, chans, rate); + }); + + connect(audioSource.get(), &IAudioSource::invalidated, this, + &ToxFriendCall::onAudioSourceInvalidated); + + if (sink) { + audioSinkInvalid = + sink->connectTo_invalidated(this, [this]() { this->onAudioSinkInvalidated(); }); + } + + // register video + if (videoEnabled) { + videoSource = new CoreVideoSource(); + // CameraSource& source = CameraSource::getInstance(); + + // if (source.isNone()) { + // source.setupDefault(); + // } + // source.subscribe(); + // videoInConn = QObject::connect(&source, &VideoSource::frameAvailable, + // [&av, + // receiver](std::shared_ptr + // frame) { + // av.sendCallVideo(receiver, frame); + // }); + // if (!videoInConn) { + // qDebug() << "Video connection not working"; + // } + } } ToxFriendCall::~ToxFriendCall() { QObject::disconnect(audioSinkInvalid); } void ToxFriendCall::onAudioSourceInvalidated() { -// auto newSrc = audio.makeSource(); -// connect( -// newSrc.get(), &IAudioSource::frameAvailable, this, -// [this](const int16_t *pcm, size_t samples, uint8_t chans, uint32_t rate) { -// this->av->sendCallAudio(this->friendId, pcm, samples, chans, rate); -// }); -// audioSource = std::move(newSrc); - -// connect(audioSource.get(), &IAudioSource::invalidated, this, -// &ToxFriendCall::onAudioSourceInvalidated); + // auto newSrc = audio.makeSource(); + // connect( + // newSrc.get(), &IAudioSource::frameAvailable, this, + // [this](const int16_t *pcm, size_t samples, uint8_t chans, uint32_t rate) { + // this->av->sendCallAudio(this->friendId, pcm, samples, chans, rate); + // }); + // audioSource = std::move(newSrc); + + // connect(audioSource.get(), &IAudioSource::invalidated, this, + // &ToxFriendCall::onAudioSourceInvalidated); } void ToxFriendCall::onAudioSinkInvalidated() { - auto newSink = audio.makeSink(); + auto newSink = audio.makeSink(); - if (newSink) { - audioSinkInvalid = newSink->connectTo_invalidated( - this, [this]() { this->onAudioSinkInvalidated(); }); - } + if (newSink) { + audioSinkInvalid = + newSink->connectTo_invalidated(this, [this]() { this->onAudioSinkInvalidated(); }); + } - sink = std::move(newSink); + sink = std::move(newSink); } -TOXAV_FRIEND_CALL_STATE ToxFriendCall::getState() const { return state; } +lib::messenger::CallState ToxFriendCall::getState() const { return state; } -void ToxFriendCall::setState(const TOXAV_FRIEND_CALL_STATE &value) { - state = value; -} +void ToxFriendCall::setState(const lib::messenger::CallState& value) { state = value; } -void ToxFriendCall::playAudioBuffer(const int16_t *data, int samples, - unsigned channels, int sampleRate) const { - if (sink) { - sink->playAudioBuffer(data, samples, channels, sampleRate); - } +void ToxFriendCall::playAudioBuffer(const int16_t* data, int samples, unsigned channels, + int sampleRate) const { + if (sink) { + sink->playAudioBuffer(data, samples, channels, sampleRate); + } } -ToxGroupCall::ToxGroupCall(const Group &group, CoreAV &av, IAudioControl &audio) - : ToxCall(false, av, audio), // - group{group} { - // register audio - connect( - audioSource.get(), // - &IAudioSource::frameAvailable, // - this, // - [this](const int16_t *pcm, size_t samples, uint8_t chans, uint32_t rate) { - if (this->group.getPeersCount() <= 1) { - return; - } - this->av->sendGroupCallAudio(this->group.getId(), pcm, samples, chans, - rate); - }); - - connect(audioSource.get(), // - &IAudioSource::invalidated, // - this, // - &ToxGroupCall::onAudioSourceInvalidated); +ToxGroupCall::ToxGroupCall(const Group& group, CoreAV& av, IAudioControl& audio) + : ToxCall(false, av, audio) + , // + group{group} { + // register audio + connect(audioSource.get(), // + &IAudioSource::frameAvailable, // + this, // + [this](const int16_t* pcm, size_t samples, uint8_t chans, uint32_t rate) { + if (this->group.getPeersCount() <= 1) { + return; + } + this->av->sendGroupCallAudio(this->group.getId(), pcm, samples, chans, rate); + }); + + connect(audioSource.get(), // + &IAudioSource::invalidated, // + this, // + &ToxGroupCall::onAudioSourceInvalidated); } ToxGroupCall::~ToxGroupCall() { - // disconnect all Qt connections - clearPeers(); + // disconnect all Qt connections + clearPeers(); } void ToxGroupCall::onAudioSourceInvalidated() { - auto newSrc = audio.makeSource(); - connect( - audioSource.get(), &IAudioSource::frameAvailable, - [this](const int16_t *pcm, size_t samples, uint8_t chans, uint32_t rate) { - if (this->group.getPeersCount() <= 1) { - return; - } - - this->av->sendGroupCallAudio(this->group.getId(), pcm, samples, chans, - rate); - }); - - audioSource = std::move(newSrc); - - connect(audioSource.get(), &IAudioSource::invalidated, this, - &ToxGroupCall::onAudioSourceInvalidated); + auto newSrc = audio.makeSource(); + connect(audioSource.get(), &IAudioSource::frameAvailable, + [this](const int16_t* pcm, size_t samples, uint8_t chans, uint32_t rate) { + if (this->group.getPeersCount() <= 1) { + return; + } + + this->av->sendGroupCallAudio(this->group.getId(), pcm, samples, chans, rate); + }); + + audioSource = std::move(newSrc); + + connect(audioSource.get(), &IAudioSource::invalidated, this, + &ToxGroupCall::onAudioSourceInvalidated); } void ToxGroupCall::onAudioSinkInvalidated(FriendId peerId) { - removePeer(peerId); - addPeer(peerId); + removePeer(peerId); + addPeer(peerId); } void ToxGroupCall::removePeer(FriendId peerId) { - const auto &source = peers.find(peerId); - if (source == peers.cend()) { - qDebug() << "Peer:" << peerId.toString() - << "does not have a source, can't remove"; - return; - } - - peers.erase(source); - QObject::disconnect(sinkInvalid[peerId]); - sinkInvalid.erase(peerId); + const auto& source = peers.find(peerId); + if (source == peers.cend()) { + qDebug() << "Peer:" << peerId.toString() << "does not have a source, can't remove"; + return; + } + + peers.erase(source); + QObject::disconnect(sinkInvalid[peerId]); + sinkInvalid.erase(peerId); } void ToxGroupCall::addPeer(FriendId peerId) { - std::unique_ptr newSink = audio.makeSink(); + std::unique_ptr newSink = audio.makeSink(); - QMetaObject::Connection con; + QMetaObject::Connection con; - if (newSink) { - con = newSink->connectTo_invalidated( - this, [this, peerId]() { this->onAudioSinkInvalidated(peerId); }); - } + if (newSink) { + con = newSink->connectTo_invalidated( + this, [this, peerId]() { this->onAudioSinkInvalidated(peerId); }); + } - peers.emplace(peerId, std::move(newSink)); - sinkInvalid.insert({peerId, con}); + peers.emplace(peerId, std::move(newSink)); + sinkInvalid.insert({peerId, con}); } bool ToxGroupCall::havePeer(FriendId peerId) { - const auto &source = peers.find(peerId); - return source != peers.cend(); + const auto& source = peers.find(peerId); + return source != peers.cend(); } void ToxGroupCall::clearPeers() { - peers.clear(); - for (auto con : sinkInvalid) { - QObject::disconnect(con.second); - } - - sinkInvalid.clear(); -} - -void ToxGroupCall::playAudioBuffer(const FriendId &peer, const int16_t *data, - int samples, unsigned channels, - int sampleRate) { - if (!havePeer(peer)) { - addPeer(peer); - } - const auto &source = peers.find(peer); - if (source->second) { - source->second->playAudioBuffer(data, samples, channels, sampleRate); - } + peers.clear(); + for (auto con : sinkInvalid) { + QObject::disconnect(con.second); + } + + sinkInvalid.clear(); +} + +void ToxGroupCall::playAudioBuffer(const FriendId& peer, const int16_t* data, int samples, + unsigned channels, int sampleRate) { + if (!havePeer(peer)) { + addPeer(peer); + } + const auto& source = peers.find(peer); + if (source->second) { + source->second->playAudioBuffer(data, samples, channels, sampleRate); + } } diff --git a/src/modules/im/src/core/toxcall.h b/src/modules/im/src/core/toxcall.h index e449cc00..3a7f7fdf 100644 --- a/src/modules/im/src/core/toxcall.h +++ b/src/modules/im/src/core/toxcall.h @@ -13,17 +13,18 @@ #ifndef TOXCALL_H #define TOXCALL_H -#include "lib/messenger/IMCall.h" -#include "src/audio/iaudiocontrol.h" -#include "src/audio/iaudiosink.h" -#include "src/audio/iaudiosource.h" -#include "src/core/FriendId.h" + +#include +#include + #include #include #include -#include -#include +#include "src/audio/iaudiocontrol.h" +#include "src/audio/iaudiosink.h" +#include "src/audio/iaudiosource.h" +#include "src/core/FriendId.h" class QTimer; class AudioFilterer; @@ -31,129 +32,128 @@ class CoreVideoSource; class CoreAV; class Group; - /**\brief Image Descriptor */ typedef struct vpx_image { + /* Image storage dimensions */ + unsigned int w; /**< Stored image width */ + unsigned int h; /**< Stored image height */ + unsigned int bit_depth; /**< Stored image bit-depth */ - /* Image storage dimensions */ - unsigned int w; /**< Stored image width */ - unsigned int h; /**< Stored image height */ - unsigned int bit_depth; /**< Stored image bit-depth */ + /* Image display dimensions */ + unsigned int d_w; /**< Displayed image width */ + unsigned int d_h; /**< Displayed image height */ - /* Image display dimensions */ - unsigned int d_w; /**< Displayed image width */ - unsigned int d_h; /**< Displayed image height */ - - unsigned char *planes[4]; /**< pointer to the top left pixel for each plane */ - int stride[4]; /**< stride between rows for each plane */ -} vpx_image_t; /**< alias for struct vpx_image */ + unsigned char* planes[4]; /**< pointer to the top left pixel for each plane */ + int stride[4]; /**< stride between rows for each plane */ +} vpx_image_t; /**< alias for struct vpx_image */ class ToxCall : public QObject { - Q_OBJECT + Q_OBJECT protected: - ToxCall() = delete; - ToxCall(bool VideoEnabled, CoreAV &av, IAudioControl &audio); - ~ToxCall(); + ToxCall() = delete; + ToxCall(bool VideoEnabled, CoreAV& av, IAudioControl& audio); + ~ToxCall(); public: - ToxCall(const ToxCall &other) = delete; - ToxCall(ToxCall &&other) = delete; + ToxCall(const ToxCall& other) = delete; + ToxCall(ToxCall&& other) = delete; + + ToxCall& operator=(const ToxCall& other) = delete; + ToxCall& operator=(ToxCall&& other) = delete; - ToxCall &operator=(const ToxCall &other) = delete; - ToxCall &operator=(ToxCall &&other) = delete; + bool isActive() const; + void setActive(bool value); - bool isActive() const; - void setActive(bool value); + bool getMuteVol() const; + void setMuteVol(bool value); - bool getMuteVol() const; - void setMuteVol(bool value); + bool getMuteMic() const; + void setMuteMic(bool value); - bool getMuteMic() const; - void setMuteMic(bool value); + bool getVideoEnabled() const; + void setVideoEnabled(bool value); - bool getVideoEnabled() const; - void setVideoEnabled(bool value); + bool getNullVideoBitrate() const; + void setNullVideoBitrate(bool value); - bool getNullVideoBitrate() const; - void setNullVideoBitrate(bool value); + CoreVideoSource* getVideoSource() const; - CoreVideoSource *getVideoSource() const; + QString getCallId() const; + void setCallId(QString value); - QString getCallId() const; - void setCallId(QString value); protected: - bool active{false}; - CoreAV *av{nullptr}; - // audio - IAudioControl &audio; - bool muteMic{false}; - bool muteVol{false}; - // video - CoreVideoSource *videoSource{nullptr}; - QMetaObject::Connection videoInConn; - bool videoEnabled{false}; - bool nullVideoBitrate{false}; - std::unique_ptr audioSource = nullptr; - QString callId; + bool active{false}; + CoreAV* av{nullptr}; + // audio + IAudioControl& audio; + bool muteMic{false}; + bool muteVol{false}; + // video + CoreVideoSource* videoSource{nullptr}; + QMetaObject::Connection videoInConn; + bool videoEnabled{false}; + bool nullVideoBitrate{false}; + std::unique_ptr audioSource = nullptr; + QString callId; }; class ToxFriendCall : public ToxCall { - Q_OBJECT + Q_OBJECT public: - ToxFriendCall() = delete; - ToxFriendCall(QString peerId, bool VideoEnabled, CoreAV &av, IAudioControl &audio); - ToxFriendCall(ToxFriendCall &&other) = delete; + ToxFriendCall() = delete; + ToxFriendCall(QString peerId, bool VideoEnabled, CoreAV& av, IAudioControl& audio); + ToxFriendCall(ToxFriendCall&& other) = delete; - ~ToxFriendCall(); + ~ToxFriendCall(); - ToxFriendCall &operator=(ToxFriendCall &&other) = delete; + ToxFriendCall& operator=(ToxFriendCall&& other) = delete; - TOXAV_FRIEND_CALL_STATE getState() const; + lib::messenger::CallState getState() const; - void setState(const TOXAV_FRIEND_CALL_STATE &value); + void setState(const lib::messenger::CallState& value); - void playAudioBuffer(const int16_t *data, int samples, unsigned channels, int sampleRate) const; + void playAudioBuffer(const int16_t* data, int samples, unsigned channels, int sampleRate) const; - const QString& getPeerId(){return peerId;} + const QString& getPeerId() { return peerId; } private slots: - void onAudioSourceInvalidated(); - void onAudioSinkInvalidated(); + void onAudioSourceInvalidated(); + void onAudioSinkInvalidated(); private: - QMetaObject::Connection audioSinkInvalid; - TOXAV_FRIEND_CALL_STATE state{TOXAV_FRIEND_CALL_STATE_NONE}; - std::unique_ptr sink = nullptr; - QString peerId; + QMetaObject::Connection audioSinkInvalid; + lib::messenger::CallState state{lib::messenger::CallState::NONE}; + std::unique_ptr sink = nullptr; + QString peerId; }; class ToxGroupCall : public ToxCall { - Q_OBJECT + Q_OBJECT public: - ToxGroupCall() = delete; - ToxGroupCall(const Group &group, CoreAV &av, IAudioControl &audio); - ToxGroupCall(ToxGroupCall &&other) = delete; - ~ToxGroupCall(); + ToxGroupCall() = delete; + ToxGroupCall(const Group& group, CoreAV& av, IAudioControl& audio); + ToxGroupCall(ToxGroupCall&& other) = delete; + ~ToxGroupCall(); - ToxGroupCall &operator=(ToxGroupCall &&other) = delete; - void removePeer(FriendId peerId); + ToxGroupCall& operator=(ToxGroupCall&& other) = delete; + void removePeer(FriendId peerId); - void playAudioBuffer(const FriendId &peer, const int16_t *data, int samples, - unsigned channels, int sampleRate); + void playAudioBuffer(const FriendId& peer, const int16_t* data, int samples, unsigned channels, + int sampleRate); private: - void addPeer(FriendId peerId); - bool havePeer(FriendId peerId); - void clearPeers(); + void addPeer(FriendId peerId); + bool havePeer(FriendId peerId); + void clearPeers(); - std::map> peers; - std::map sinkInvalid; - const Group &group; + std::map> peers; + std::map sinkInvalid; + const Group& group; private slots: - void onAudioSourceInvalidated(); - void onAudioSinkInvalidated(FriendId peerId); + void onAudioSourceInvalidated(); + void onAudioSinkInvalidated(FriendId peerId); }; -#endif // TOXCALL_H +#endif // TOXCALL_H diff --git a/src/modules/im/src/core/toxencrypt.cpp b/src/modules/im/src/core/toxencrypt.cpp index a2a90707..4da41ef8 100644 --- a/src/modules/im/src/core/toxencrypt.cpp +++ b/src/modules/im/src/core/toxencrypt.cpp @@ -36,14 +36,14 @@ * @brief Frees the passKey before destruction. */ ToxEncrypt::~ToxEncrypt() { - // tox_pass_key_free(passKey); + // tox_pass_key_free(passKey); } /** * @brief Constructs a ToxEncrypt object from a Tox_Pass_Key. * @param key Derived key to use for encryption and decryption. */ -ToxEncrypt::ToxEncrypt(Tox_Pass_Key *key) : passKey{key} {} +ToxEncrypt::ToxEncrypt(Tox_Pass_Key* key) : passKey{key} {} /** * @brief Gets the minimum number of bytes needed for isEncrypted() @@ -51,8 +51,8 @@ ToxEncrypt::ToxEncrypt(Tox_Pass_Key *key) : passKey{key} {} * using this module. */ int ToxEncrypt::getMinBytes() { - // return TOX_PASS_ENCRYPTION_EXTRA_LENGTH; - return 0; + // return TOX_PASS_ENCRYPTION_EXTRA_LENGTH; + return 0; } /** @@ -60,14 +60,14 @@ int ToxEncrypt::getMinBytes() { * @param ciphertext The data to check. * @return True if the data was encrypted using this module, false otherwise. */ -bool ToxEncrypt::isEncrypted(const QByteArray &ciphertext) { - // if (ciphertext.length() < TOX_PASS_ENCRYPTION_EXTRA_LENGTH) { - // return false; - // } - // - // return tox_is_data_encrypted( - // reinterpret_cast(ciphertext.constData())); - return false; +bool ToxEncrypt::isEncrypted(const QByteArray& ciphertext) { + // if (ciphertext.length() < TOX_PASS_ENCRYPTION_EXTRA_LENGTH) { + // return false; + // } + // + // return tox_is_data_encrypted( + // reinterpret_cast(ciphertext.constData())); + return false; } /** @@ -76,31 +76,30 @@ bool ToxEncrypt::isEncrypted(const QByteArray &ciphertext) { * @param password Password to encrypt the data. * @param plaintext The data to encrypt. */ -QByteArray ToxEncrypt::encryptPass(const QString &password, - const QByteArray &plaintext) { - // if (password.length() == 0) { - // qWarning() << "Empty password supplied, probably not what you - // intended."; - // } - // - // QByteArray pass = password.toUtf8(); - // QByteArray ciphertext(plaintext.length() + - // TOX_PASS_ENCRYPTION_EXTRA_LENGTH, - // 0x00); - // TOX_ERR_ENCRYPTION error; - // tox_pass_encrypt(reinterpret_cast(plaintext.constData()), - // static_cast(plaintext.size()), - // reinterpret_cast(pass.constData()), - // static_cast(pass.size()), - // reinterpret_cast(ciphertext.data()), &error); - // - // if (error != TOX_ERR_ENCRYPTION_OK) { - // qCritical() << getEncryptionError(error); - // return QByteArray{}; - // } +QByteArray ToxEncrypt::encryptPass(const QString& password, const QByteArray& plaintext) { + // if (password.length() == 0) { + // qWarning() << "Empty password supplied, probably not what you + // intended."; + // } + // + // QByteArray pass = password.toUtf8(); + // QByteArray ciphertext(plaintext.length() + + // TOX_PASS_ENCRYPTION_EXTRA_LENGTH, + // 0x00); + // TOX_ERR_ENCRYPTION error; + // tox_pass_encrypt(reinterpret_cast(plaintext.constData()), + // static_cast(plaintext.size()), + // reinterpret_cast(pass.constData()), + // static_cast(pass.size()), + // reinterpret_cast(ciphertext.data()), &error); + // + // if (error != TOX_ERR_ENCRYPTION_OK) { + // qCritical() << getEncryptionError(error); + // return QByteArray{}; + // } - // return ciphertext; - return QByteArray{}; + // return ciphertext; + return QByteArray{}; } /** @@ -109,38 +108,37 @@ QByteArray ToxEncrypt::encryptPass(const QString &password, * @param password The password used to encrypt the data. * @param ciphertext The encrypted data. */ -QByteArray ToxEncrypt::decryptPass(const QString &password, - const QByteArray &ciphertext) { - // if (!isEncrypted(ciphertext)) { - // qWarning() - // << "The data was not encrypted using this module or it's - // corrupted."; - // return QByteArray{}; - // } - // - // if (password.length() == 0) { - // qDebug() << "Empty password supplied, probably not what you intended."; - // } - // - // QByteArray pass = password.toUtf8(); - // QByteArray plaintext(ciphertext.length() - - // TOX_PASS_ENCRYPTION_EXTRA_LENGTH, - // 0x00); - // TOX_ERR_DECRYPTION error; - // tox_pass_decrypt(reinterpret_cast(ciphertext.constData()), - // static_cast(ciphertext.size()), - // reinterpret_cast(pass.constData()), - // static_cast(pass.size()), - // reinterpret_cast(plaintext.data()), &error); - // - // if (error != TOX_ERR_DECRYPTION_OK) { - // qWarning() << getDecryptionError(error); - // return QByteArray{}; - // } +QByteArray ToxEncrypt::decryptPass(const QString& password, const QByteArray& ciphertext) { + // if (!isEncrypted(ciphertext)) { + // qWarning() + // << "The data was not encrypted using this module or it's + // corrupted."; + // return QByteArray{}; + // } + // + // if (password.length() == 0) { + // qDebug() << "Empty password supplied, probably not what you intended."; + // } + // + // QByteArray pass = password.toUtf8(); + // QByteArray plaintext(ciphertext.length() - + // TOX_PASS_ENCRYPTION_EXTRA_LENGTH, + // 0x00); + // TOX_ERR_DECRYPTION error; + // tox_pass_decrypt(reinterpret_cast(ciphertext.constData()), + // static_cast(ciphertext.size()), + // reinterpret_cast(pass.constData()), + // static_cast(pass.size()), + // reinterpret_cast(plaintext.data()), &error); + // + // if (error != TOX_ERR_DECRYPTION_OK) { + // qWarning() << getDecryptionError(error); + // return QByteArray{}; + // } - // return plaintext; - return QByteArray{}; + // return plaintext; + return QByteArray{}; } /** @@ -151,24 +149,23 @@ QByteArray ToxEncrypt::decryptPass(const QString &password, * * Derives a key from the password and a new random salt. */ -std::unique_ptr -ToxEncrypt::makeToxEncrypt(const QString &password) { - // const QByteArray pass = password.toUtf8(); - // TOX_ERR_KEY_DERIVATION error; - // Tox_Pass_Key *const passKey = - // tox_pass_key_derive(reinterpret_cast(pass.constData()), - // static_cast(pass.length()), &error); - // - // if (error != TOX_ERR_KEY_DERIVATION_OK) { - // tox_pass_key_free(passKey); - // qCritical() << getKeyDerivationError(error); - // return std::unique_ptr{}; - // } +std::unique_ptr ToxEncrypt::makeToxEncrypt(const QString& password) { + // const QByteArray pass = password.toUtf8(); + // TOX_ERR_KEY_DERIVATION error; + // Tox_Pass_Key *const passKey = + // tox_pass_key_derive(reinterpret_cast(pass.constData()), + // static_cast(pass.length()), &error); + // + // if (error != TOX_ERR_KEY_DERIVATION_OK) { + // tox_pass_key_free(passKey); + // qCritical() << getKeyDerivationError(error); + // return std::unique_ptr{}; + // } - return std::unique_ptr(new ToxEncrypt(nullptr)); + return std::unique_ptr(new ToxEncrypt(nullptr)); - // return std::unique_ptr(nullptr); + // return std::unique_ptr(nullptr); } /** @@ -180,38 +177,37 @@ ToxEncrypt::makeToxEncrypt(const QString &password) { * * Derives a key from the password and the salt read from toxSave. */ -std::unique_ptr -ToxEncrypt::makeToxEncrypt(const QString &password, const QByteArray &toxSave) { - if (!isEncrypted(toxSave)) { - qWarning() - << "The data was not encrypted using this module or it's corrupted."; - return std::unique_ptr{}; - } +std::unique_ptr ToxEncrypt::makeToxEncrypt(const QString& password, + const QByteArray& toxSave) { + if (!isEncrypted(toxSave)) { + qWarning() << "The data was not encrypted using this module or it's corrupted."; + return std::unique_ptr{}; + } - // TOX_ERR_GET_SALT saltError; - // uint8_t salt[TOX_PASS_SALT_LENGTH]; - // tox_get_salt(reinterpret_cast(toxSave.constData()), salt, - // &saltError); - // - // if (saltError != TOX_ERR_GET_SALT_OK) { - // qWarning() << getSaltError(saltError); - // return std::unique_ptr{}; - // } - // - // QByteArray pass = password.toUtf8(); - // TOX_ERR_KEY_DERIVATION keyError; - Tox_Pass_Key *const passKey = nullptr; - // tox_pass_key_derive_with_salt( - // reinterpret_cast(pass.constData()), - // static_cast(pass.length()), salt, &keyError); - // - // if (keyError != TOX_ERR_KEY_DERIVATION_OK) { - // tox_pass_key_free(passKey); - // qWarning() << getKeyDerivationError(keyError); - // return std::unique_ptr{}; - // } + // TOX_ERR_GET_SALT saltError; + // uint8_t salt[TOX_PASS_SALT_LENGTH]; + // tox_get_salt(reinterpret_cast(toxSave.constData()), salt, + // &saltError); + // + // if (saltError != TOX_ERR_GET_SALT_OK) { + // qWarning() << getSaltError(saltError); + // return std::unique_ptr{}; + // } + // + // QByteArray pass = password.toUtf8(); + // TOX_ERR_KEY_DERIVATION keyError; + Tox_Pass_Key* const passKey = nullptr; + // tox_pass_key_derive_with_salt( + // reinterpret_cast(pass.constData()), + // static_cast(pass.length()), salt, &keyError); + // + // if (keyError != TOX_ERR_KEY_DERIVATION_OK) { + // tox_pass_key_free(passKey); + // qWarning() << getKeyDerivationError(keyError); + // return std::unique_ptr{}; + // } - return std::unique_ptr(new ToxEncrypt(passKey)); + return std::unique_ptr(new ToxEncrypt(passKey)); } /** @@ -219,30 +215,30 @@ ToxEncrypt::makeToxEncrypt(const QString &password, const QByteArray &toxSave) { * @return Encrypted data or empty QByteArray on failure. * @param plaintext The data to encrypt. */ -QByteArray ToxEncrypt::encrypt(const QByteArray &plaintext) const { - if (!passKey) { -// qCritical() << "The passKey is invalid."; +QByteArray ToxEncrypt::encrypt(const QByteArray& plaintext) const { + if (!passKey) { + // qCritical() << "The passKey is invalid."; + return QByteArray{}; + } return QByteArray{}; - } - return QByteArray{}; - // QByteArray ciphertext(plaintext.length() + - // TOX_PASS_ENCRYPTION_EXTRA_LENGTH, - // 0x00); - // TOX_ERR_ENCRYPTION error; - // tox_pass_key_encrypt(passKey, - // reinterpret_cast(plaintext.constData()), - // static_cast(plaintext.size()), - // reinterpret_cast(ciphertext.data()), - // &error); - // - // if (error != TOX_ERR_ENCRYPTION_OK) { - // qCritical() << getEncryptionError(error); - // return QByteArray{}; - // } - // - // return ciphertext; + // QByteArray ciphertext(plaintext.length() + + // TOX_PASS_ENCRYPTION_EXTRA_LENGTH, + // 0x00); + // TOX_ERR_ENCRYPTION error; + // tox_pass_key_encrypt(passKey, + // reinterpret_cast(plaintext.constData()), + // static_cast(plaintext.size()), + // reinterpret_cast(ciphertext.data()), + // &error); + // + // if (error != TOX_ERR_ENCRYPTION_OK) { + // qCritical() << getEncryptionError(error); + // return QByteArray{}; + // } + // + // return ciphertext; } /** @@ -250,9 +246,7 @@ QByteArray ToxEncrypt::encrypt(const QByteArray &plaintext) const { * @return The plaintext or an empty QByteArray on failure. * @param ciphertext The encrypted data. */ -QByteArray ToxEncrypt::decrypt(const QByteArray &ciphertext) const { - return ciphertext; -} +QByteArray ToxEncrypt::decrypt(const QByteArray& ciphertext) const { return ciphertext; } /** * @brief Gets the error string for TOX_ERR_KEY_DERIVATION errors. diff --git a/src/modules/im/src/core/toxencrypt.h b/src/modules/im/src/core/toxencrypt.h index 82b3af5b..230d4439 100644 --- a/src/modules/im/src/core/toxencrypt.h +++ b/src/modules/im/src/core/toxencrypt.h @@ -18,11 +18,9 @@ #include - struct Tox_Pass_Key; -class ToxEncrypt -{ +class ToxEncrypt { public: ~ToxEncrypt(); ToxEncrypt() = delete; @@ -46,4 +44,4 @@ class ToxEncrypt Tox_Pass_Key* passKey = nullptr; }; -#endif // TOXENCRYPT_H +#endif // TOXENCRYPT_H diff --git a/src/modules/im/src/core/toxfile.cpp b/src/modules/im/src/core/toxfile.cpp index e0e076aa..637a0a7e 100644 --- a/src/modules/im/src/core/toxfile.cpp +++ b/src/modules/im/src/core/toxfile.cpp @@ -11,42 +11,45 @@ */ #include "src/core/toxfile.h" -#include "FriendId.h" -#include "lib/messenger/IMFile.h" -#include -#include #include #include +#include +#include +#include "FriendId.h" -FileInfo::FileInfo( - const QString &sId, - const QString &id, - const QString &fileName, - const QString &filePath, + +FileInfo::FileInfo(const QString& sId, + const QString& id, + const QString& fileName, + const QString& filePath, quint64 fileSize, quint64 bytesSent, FileStatus status, FileDirection direction) - : sId{sId}, fileId(id), fileName(fileName), filePath(filePath) - , fileSize(fileSize), bytesSent(bytesSent), status(status), direction(direction) -{ - -} - -QString FileInfo::json() const -{ + : sId{sId} + , fileId(id) + , fileName(fileName) + , filePath(filePath) + , fileSize(fileSize) + , bytesSent(bytesSent) + , status(status) + , direction(direction) {} + +QString FileInfo::json() const { return QString("{\"id\":\"%1\", \"name\":\"%2\", " "\"path\":\"%3\", \"size\":%4, " "\"status\":%5, \"direction\":%6, " "\"sId\":\"%7\"}") - .arg(fileId).arg(fileName) - .arg(filePath).arg(fileSize) - .arg((int)status).arg((int)direction).arg(sId); + .arg(fileId) + .arg(fileName) + .arg(filePath) + .arg(fileSize) + .arg((int)status) + .arg((int)direction) + .arg(sId); } - -void FileInfo::parse(const QString &json) -{ +void FileInfo::parse(const QString& json) { auto doc = Jsons::toJSON(json.toUtf8()); auto obj = doc.object(); fileId = obj.value("id").toString(); @@ -58,9 +61,8 @@ void FileInfo::parse(const QString &json) direction = (FileDirection)obj.value("direction").toInt(); } - -ToxFile::ToxFile(const QString &sender, - const QString &friendId, +ToxFile::ToxFile(const QString& sender, + const QString& friendId, QString sId_, QString fileId_, QString filename_, @@ -69,60 +71,39 @@ ToxFile::ToxFile(const QString &sender, quint64 bytesSent, FileStatus status, FileDirection direction) - : FileInfo(sId_, fileId_, filename_, - filePath_, fileSize_, - bytesSent, status, direction) - ,file(new QFile(filePath_)), sender{sender}, receiver{friendId} -{ -} - -ToxFile::ToxFile(const QString &sender, const QString &friendId, const lib::messenger::File &file) - :FileInfo(file.sId, file.id, file.name, file.path, file.size, 0, - (FileStatus)file.status, - (FileDirection)file.direction) - ,file(new QFile(file.path)), sender{sender}, - receiver{friendId} -{ - -} - -ToxFile::ToxFile(const FileInfo &fi): FileInfo(fi) -{ + : FileInfo(sId_, fileId_, filename_, filePath_, fileSize_, bytesSent, status, direction) + , file(new QFile(filePath_)) + , sender{sender} + , receiver{friendId} {} -} +ToxFile::ToxFile(const QString& sender, const QString& friendId, const lib::messenger::File& file) + : FileInfo(file.sId, file.id, file.name, file.path, file.size, 0, (FileStatus)file.status, + (FileDirection)file.direction) + , file(new QFile(file.path)) + , sender{sender} + , receiver{friendId} {} -ToxFile::~ToxFile() -{ +ToxFile::ToxFile(const FileInfo& fi) : FileInfo(fi) {} -} +ToxFile::~ToxFile() {} -bool ToxFile::operator==(const ToxFile &other) const { - return (fileId == other.fileId); -} +bool ToxFile::operator==(const ToxFile& other) const { return (fileId == other.fileId); } -bool ToxFile::operator!=(const ToxFile &other) const { - return !(*this == other); -} +bool ToxFile::operator!=(const ToxFile& other) const { return !(*this == other); } void ToxFile::setFilePath(QString path) { - filePath = path; - file->setFileName(path); + filePath = path; + file->setFileName(path); } bool ToxFile::open(bool write) { - return write ? file->open(QIODevice::ReadWrite) - : file->open(QIODevice::ReadOnly); + return write ? file->open(QIODevice::ReadWrite) : file->open(QIODevice::ReadOnly); } -lib::messenger::File ToxFile::toIMFile() -{ - return lib::messenger::File{fileId, sId, fileName, filePath, fileSize}; +lib::messenger::File ToxFile::toIMFile() { + return lib::messenger::File{fileId, sId, fileName, filePath, fileSize}; } -const QString& ToxFile::getFriendId() const -{ +const QString& ToxFile::getFriendId() const { return direction == FileDirection::RECEIVING ? sender : receiver; } - - - diff --git a/src/modules/im/src/core/toxfile.h b/src/modules/im/src/core/toxfile.h index 982617b0..ab55c1d8 100644 --- a/src/modules/im/src/core/toxfile.h +++ b/src/modules/im/src/core/toxfile.h @@ -25,32 +25,44 @@ class QFile; class QTimer; class FriendId; + +// 不要修改顺序和值 +enum class FileStatus { + INITIALIZING = 0, + PAUSED = 1, + TRANSMITTING = 2, + BROKEN = 3, + CANCELED = 4, + FINISHED = 5, +}; + +// 不要修改顺序和值 +enum class FileDirection { + SENDING = 0, + RECEIVING = 1, +}; + namespace lib::messenger { class File; enum class FileStatus; enum class FileDirection; -} - -using FileStatus = lib::messenger::FileStatus; -using FileDirection = lib::messenger::FileDirection; +} // namespace lib::messenger struct FileInfo { public: - FileInfo()=default; - FileInfo( - const QString &sId, + FileInfo() = default; + FileInfo(const QString& sId, const QString& id, - const QString &fileName, - const QString & filePath, + const QString& fileName, + const QString& filePath, quint64 fileSize, quint64 bytesSent, FileStatus status, - FileDirection direction - ); + FileDirection direction); - //sessionId + // sessionId QString sId; - //uuid + // uuid QString fileId; QString fileName; QString filePath; @@ -59,56 +71,56 @@ struct FileInfo { FileStatus status; FileDirection direction; QString sha256; + public: [[nodiscard]] QString json() const; - void parse(const QString &json); - void setFilePath(const QString & path) { - this->filePath = path; - } + void parse(const QString& json); + void setFilePath(const QString& path) { this->filePath = path; } }; Q_DECLARE_METATYPE(FileInfo); - struct ToxFile : public FileInfo { - ToxFile() = default; - ToxFile(const QString &sender, - const QString &friendId, - QString sId, - QString FileId, - QString FileName, - QString filePath, - quint64 fileSize_, - quint64 bytesSent, - FileStatus status, - FileDirection Direction); - - ToxFile(const QString &sender, const QString &friendId, const lib::messenger::File &file); - ToxFile(const FileInfo& fi); - ~ToxFile(); - - bool operator==(const ToxFile &other) const; - bool operator!=(const ToxFile &other) const; - - void setFilePath(QString path); - bool open(bool write); - - lib::messenger::File toIMFile(); - - const QString& getFriendId() const; - - inline QString toString() const - { - return QString("{id:%1, sId:%2, name:%3, path:%4, size:%5}") - .arg(fileId).arg(sId).arg(fileName).arg(filePath).arg(fileSize); - } - - QString sender; - QString receiver; - - std::shared_ptr file; -// std::shared_ptr hashGenerator = std::make_shared(QCryptographicHash::Sha256); -}; + explicit ToxFile() = default; + explicit ToxFile(const QString& sender, + const QString& friendId, + QString sId, + QString FileId, + QString FileName, + QString filePath, + quint64 fileSize_, + quint64 bytesSent, + FileStatus status, + FileDirection Direction); + + explicit ToxFile(const QString& sender, const QString& friendId, const lib::messenger::File& file); + explicit ToxFile(const FileInfo& fi); + ~ToxFile(); + + bool operator==(const ToxFile& other) const; + bool operator!=(const ToxFile& other) const; + + void setFilePath(QString path); + bool open(bool write); + + lib::messenger::File toIMFile(); + + const QString& getFriendId() const; + + inline QString toString() const { + return QString("{id:%1, sId:%2, name:%3, path:%4, size:%5}") + .arg(fileId) + .arg(sId) + .arg(fileName) + .arg(filePath) + .arg(fileSize); + } + + QString sender; + QString receiver; -Q_DECLARE_METATYPE(ToxFile); + std::shared_ptr file; + // std::shared_ptr hashGenerator = + // std::make_shared(QCryptographicHash::Sha256); +}; -#endif // CORESTRUCTS_H +#endif // CORESTRUCTS_H diff --git a/src/modules/im/src/core/toxfilepause.h b/src/modules/im/src/core/toxfilepause.h index 9a69c056..e8841873 100644 --- a/src/modules/im/src/core/toxfilepause.h +++ b/src/modules/im/src/core/toxfilepause.h @@ -13,57 +13,29 @@ #ifndef TOX_FILE_PAUSE_H #define TOX_FILE_PAUSE_H -class ToxFilePause -{ +class ToxFilePause { public: - void localPause() - { - localPauseState = true; - } + void localPause() { localPauseState = true; } - void localResume() - { - localPauseState = false; - } + void localResume() { localPauseState = false; } - void localPauseToggle() - { - localPauseState = !localPauseState; - } + void localPauseToggle() { localPauseState = !localPauseState; } - void remotePause() - { - remotePauseState = true; - } + void remotePause() { remotePauseState = true; } - void remoteResume() - { - remotePauseState = false; - } + void remoteResume() { remotePauseState = false; } - void remotePauseToggle() - { - remotePauseState = !remotePauseState; - } + void remotePauseToggle() { remotePauseState = !remotePauseState; } - bool localPaused() const - { - return localPauseState; - } + bool localPaused() const { return localPauseState; } - bool remotePaused() const - { - return remotePauseState; - } + bool remotePaused() const { return remotePauseState; } - bool paused() const - { - return localPauseState || remotePauseState; - } + bool paused() const { return localPauseState || remotePauseState; } private: bool localPauseState = false; bool remotePauseState = false; }; -#endif // TOX_FILE_PAUSE_H +#endif // TOX_FILE_PAUSE_H diff --git a/src/modules/im/src/core/toxid.cpp b/src/modules/im/src/core/toxid.cpp index 5eea3a3d..0a03ce34 100644 --- a/src/modules/im/src/core/toxid.cpp +++ b/src/modules/im/src/core/toxid.cpp @@ -26,8 +26,8 @@ #define CHECKSUM_HEX_CHARS (2 * CHECKSUM_BYTES) #define TOXID_HEX_CHARS (2 * TOX_ADDRESS_SIZE) -//const QRegularExpression ToxId::ToxIdRegEx( -// QString("(^|\\s)[A-Fa-f0-9]{%1}($|\\s)").arg(TOXID_HEX_CHARS)); +// const QRegularExpression ToxId::ToxIdRegEx( +// QString("(^|\\s)[A-Fa-f0-9]{%1}($|\\s)").arg(TOXID_HEX_CHARS)); /** * @class ToxId @@ -45,7 +45,7 @@ ToxId::ToxId() : toxId() {} * @brief The copy constructor. * @param other ToxId to copy */ -ToxId::ToxId(const ToxId &other) : toxId(other.toxId) {} +ToxId::ToxId(const ToxId& other) : toxId(other.toxId) {} /** * @brief Create a Tox ID from a QString. @@ -57,19 +57,19 @@ ToxId::ToxId(const ToxId &other) : toxId(other.toxId) {} * * @param id Ok ID string to convert to ToxId object */ -ToxId::ToxId(const QString &id) { -// qDebug() << "ToxId::ToxId (id)" << id; - // TODO: remove construction from PK only - // if (isToxId(id)) { - // toxId = QByteArray::fromHex(id.toLatin1()); - // } else if (id.length() >= PUBLIC_KEY_HEX_CHARS) { - // toxId = QByteArray::fromHex(id.left(PUBLIC_KEY_HEX_CHARS).toLatin1()); - // } else { - // toxId = QByteArray(); // invalid id string - // } - if (isToxId(id)) { - toxId = (id.toUtf8()); - } +ToxId::ToxId(const QString& id) { + // qDebug() << "ToxId::ToxId (id)" << id; + // TODO: remove construction from PK only + // if (isToxId(id)) { + // toxId = QByteArray::fromHex(id.toLatin1()); + // } else if (id.length() >= PUBLIC_KEY_HEX_CHARS) { + // toxId = QByteArray::fromHex(id.left(PUBLIC_KEY_HEX_CHARS).toLatin1()); + // } else { + // toxId = QByteArray(); // invalid id string + // } + if (isToxId(id)) { + toxId = (id.toUtf8()); + } } /** @@ -82,7 +82,7 @@ ToxId::ToxId(const QString &id) { * * @param rawId Ok ID bytes to convert to ToxId object */ -ToxId::ToxId(const QByteArray &rawId) { constructToxId(rawId); } +ToxId::ToxId(const QByteArray& rawId) { constructToxId(rawId); } /** * @brief Create a Ok ID from uint8_t bytes and lenght, convenience function @@ -97,22 +97,22 @@ ToxId::ToxId(const QByteArray &rawId) { constructToxId(rawId); } * @param len Number of bytes to read. Must be TOX_SECRET_KEY_SIZE for a Public * Key or TOX_ADDRESS_SIZE for a Ok ID. */ -ToxId::ToxId(const uint8_t *rawId, int len) { - QByteArray tmpId(reinterpret_cast(rawId), len); - constructToxId(tmpId); +ToxId::ToxId(const uint8_t* rawId, int len) { + QByteArray tmpId(reinterpret_cast(rawId), len); + constructToxId(tmpId); } -void ToxId::constructToxId(const QByteArray &rawId) { - // TODO: remove construction from PK only - // if (rawId.length() == TOX_SECRET_KEY_SIZE) { - // toxId = QByteArray(rawId); // construct from PK only - // } else if (rawId.length() == TOX_ADDRESS_SIZE && - // isToxId(rawId.toHex().toUpper())) { - // toxId = QByteArray(rawId); // construct from full toxid - // } else { - // toxId = QByteArray(); // invalid id - // } - toxId = QByteArray(rawId); +void ToxId::constructToxId(const QByteArray& rawId) { + // TODO: remove construction from PK only + // if (rawId.length() == TOX_SECRET_KEY_SIZE) { + // toxId = QByteArray(rawId); // construct from PK only + // } else if (rawId.length() == TOX_ADDRESS_SIZE && + // isToxId(rawId.toHex().toUpper())) { + // toxId = QByteArray(rawId); // construct from full toxid + // } else { + // toxId = QByteArray(); // invalid id + // } + toxId = QByteArray(rawId); } /** @@ -120,18 +120,14 @@ void ToxId::constructToxId(const QByteArray &rawId) { * @param other Ok ID to compare. * @return True if both Tox IDs have the same public keys, false otherwise. */ -bool ToxId::operator==(const ToxId &other) const { - return toxId.compare(other.toxId) == 0; -} +bool ToxId::operator==(const ToxId& other) const { return toxId.compare(other.toxId) == 0; } /** * @brief Compares the inequality of the Public Key. * @param other Ok ID to compare. * @return True if both Tox IDs have different public keys, false otherwise. */ -bool ToxId::operator!=(const ToxId &other) const { - return getPublicKey() != other.getPublicKey(); -} +bool ToxId::operator!=(const ToxId& other) const { return getPublicKey() != other.getPublicKey(); } /** * @brief Returns the Ok ID converted to QString. @@ -150,12 +146,12 @@ void ToxId::clear() { toxId.clear(); } * @brief Gets the ToxID as bytes, convenience function for toxcore interface. * @return The ToxID as uint8_t* if isValid() is true, else a nullptr. */ -const uint8_t *ToxId::getBytes() const { - if (isValid()) { - return reinterpret_cast(toxId.constData()); - } +const uint8_t* ToxId::getBytes() const { + if (isValid()) { + return reinterpret_cast(toxId.constData()); + } - return nullptr; + return nullptr; } /** @@ -163,12 +159,12 @@ const uint8_t *ToxId::getBytes() const { * @return Public Key of the ToxID */ FriendId ToxId::getPublicKey() const { -// auto const pkBytes = toxId.left(TOX_PUBLIC_KEY_SIZE); -// if (pkBytes.isEmpty()) { -// return ToxPk{}; -// } else { -// return ToxPk{pkBytes}; -// } + // auto const pkBytes = toxId.left(TOX_PUBLIC_KEY_SIZE); + // if (pkBytes.isEmpty()) { + // return ToxPk{}; + // } else { + // return ToxPk{pkBytes}; + // } return FriendId{toxId}; } @@ -177,10 +173,7 @@ FriendId ToxId::getPublicKey() const { * @return The NoSpam value as QString or "" if the ToxId was constructed from a * Public Key. */ -QString ToxId::getNoSpamString() const { - - return {}; -} +QString ToxId::getNoSpamString() const { return {}; } /** * @brief Check, that id is a valid Ok ID. @@ -188,9 +181,7 @@ QString ToxId::getNoSpamString() const { * @return True if id is a valid Ok ID, false otherwise. * @note Validates the checksum. */ -bool ToxId::isValidToxId(const QString &id) { - return isToxId(id) && ToxId(id).isValid(); -} +bool ToxId::isValidToxId(const QString& id) { return isToxId(id) && ToxId(id).isValid(); } /** * @brief Check, that id is probably a valid Ok ID. @@ -198,9 +189,9 @@ bool ToxId::isValidToxId(const QString &id) { * @return True if the string can be a ToxID, false otherwise. * @note Doesn't validate checksum. */ -bool ToxId::isToxId(const QString &id) { - // return id.length() == TOXID_HEX_CHARS && id.contains(ToxIdRegEx); - return id.length() > 0; +bool ToxId::isToxId(const QString& id) { + // return id.length() == TOXID_HEX_CHARS && id.contains(ToxIdRegEx); + return id.length() > 0; } /** @@ -208,12 +199,10 @@ bool ToxId::isToxId(const QString &id) { * @return True if it is a valid Ok ID, false otherwise. */ bool ToxId::isValid() const { - if (toxId.length() > 0) { - return true; - } - return false; + if (toxId.length() > 0) { + return true; + } + return false; } -QString ToxId::getToxIdAsStr() const { - return QString::fromUtf8(toxId); -} +QString ToxId::getToxIdAsStr() const { return QString::fromUtf8(toxId); } diff --git a/src/modules/im/src/core/toxid.h b/src/modules/im/src/core/toxid.h index cc526c87..6c64d214 100644 --- a/src/modules/im/src/core/toxid.h +++ b/src/modules/im/src/core/toxid.h @@ -21,37 +21,37 @@ class ToxId { public: - ToxId(); - ToxId(const ToxId &other); - explicit ToxId(const QString &id); - explicit ToxId(const QByteArray &rawId); - explicit ToxId(const uint8_t *rawId, int len); - ToxId &operator=(const ToxId &other) = default; - ToxId &operator=(ToxId &&other) = default; - - bool operator==(const ToxId &other) const; - bool operator!=(const ToxId &other) const; - QString toString() const; - void clear(); - bool isValid() const; - - static bool isValidToxId(const QString &id); - static bool isToxId(const QString &id); - const uint8_t *getBytes() const; - QByteArray getToxId() const; - FriendId getPublicKey() const; - QString getNoSpamString() const; - - QString getToxIdAsStr() const; + ToxId(); + ToxId(const ToxId& other); + explicit ToxId(const QString& id); + explicit ToxId(const QByteArray& rawId); + explicit ToxId(const uint8_t* rawId, int len); + ToxId& operator=(const ToxId& other) = default; + ToxId& operator=(ToxId&& other) = default; + + bool operator==(const ToxId& other) const; + bool operator!=(const ToxId& other) const; + QString toString() const; + void clear(); + bool isValid() const; + + static bool isValidToxId(const QString& id); + static bool isToxId(const QString& id); + const uint8_t* getBytes() const; + QByteArray getToxId() const; + FriendId getPublicKey() const; + QString getNoSpamString() const; + + QString getToxIdAsStr() const; private: - void constructToxId(const QByteArray &rawId); + void constructToxId(const QByteArray& rawId); public: - static const QRegularExpression ToxIdRegEx; + static const QRegularExpression ToxIdRegEx; private: - QByteArray toxId; + QByteArray toxId; }; -#endif // TOXID_H +#endif // TOXID_H diff --git a/src/modules/im/src/core/toxoptions.cpp b/src/modules/im/src/core/toxoptions.cpp index 0bc65207..1e3a59e7 100644 --- a/src/modules/im/src/core/toxoptions.cpp +++ b/src/modules/im/src/core/toxoptions.cpp @@ -22,130 +22,126 @@ * and are correctly deleted. */ -ToxOptions::ToxOptions(Tox_Options *options, const QByteArray &proxyAddrData) - : options(options), proxyAddrData(proxyAddrData) {} +ToxOptions::ToxOptions(Tox_Options* options, const QByteArray& proxyAddrData) + : options(options), proxyAddrData(proxyAddrData) {} ToxOptions::~ToxOptions() { - // tox_options_free(options); + // tox_options_free(options); } -ToxOptions::ToxOptions(ToxOptions &&from) { - options = from.options; - proxyAddrData.swap(from.proxyAddrData); - from.options = nullptr; - from.proxyAddrData.clear(); +ToxOptions::ToxOptions(ToxOptions&& from) { + options = from.options; + proxyAddrData.swap(from.proxyAddrData); + from.options = nullptr; + from.proxyAddrData.clear(); } -const char *ToxOptions::getProxyAddrData() const { - return proxyAddrData.constData(); -} +const char* ToxOptions::getProxyAddrData() const { return proxyAddrData.constData(); } -ToxOptions::operator Tox_Options *() { return options; } +ToxOptions::operator Tox_Options*() { return options; } /** * @brief Initializes a ToxOptions instance * @param savedata Previously saved Tox data * @return ToxOptions instance initialized to create Tox instance */ -std::unique_ptr -ToxOptions::makeToxOptions(const QByteArray &savedata, const ICoreSettings *s) { - Tox_Options* tox_opts = { - };//tox_options_new(nullptr); -// -// if (!tox_opts) { -// qWarning() << "failed to create Tox_Options"; -// return {}; -// } +std::unique_ptr ToxOptions::makeToxOptions(const QByteArray& savedata, + const ICoreSettings* s) { + Tox_Options* tox_opts = {}; // tox_options_new(nullptr); + // + // if (!tox_opts) { + // qWarning() << "failed to create Tox_Options"; + // return {}; + // } - // need to init proxyAddr here, because we need it to construct ToxOptions - const QString proxyAddr = s == nullptr ? QString{} : s->getProxyAddr(); - // - auto toxOptions = std::unique_ptr(new ToxOptions(tox_opts, - proxyAddr.toUtf8())); - // // register log first, to get messages as early as possible - // tox_options_set_log_callback(*toxOptions, ToxLogger::onLogMessage); - // - // // savedata - // tox_options_set_savedata_type(*toxOptions, savedata.isNull() ? - // TOX_SAVEDATA_TYPE_NONE - // : - // TOX_SAVEDATA_TYPE_TOX_SAVE); - // tox_options_set_savedata_data(*toxOptions, reinterpret_cast(savedata.data()), - // savedata.size()); - // - // if(s == nullptr) { - // qDebug() << "Using Tox default settings"; - // return toxOptions; - // } - // - // // IPv6 needed for LAN discovery, but can crash some weird routers. On - // by default, can be - // // disabled in options. - // const bool enableIPv6 = s->getEnableIPv6(); - // bool forceTCP = s->getForceTCP(); - // // LAN requiring UDP is a toxcore limitation, ideally wouldn't be - // related const bool enableLanDiscovery = s->getEnableLanDiscovery() && - // !forceTCP; ICoreSettings::ProxyType proxyType = s->getProxyType(); - // quint16 proxyPort = s->getProxyPort(); - // - // if (!enableLanDiscovery) { - // qWarning() << "Core starting without LAN discovery. Peers can only - // be found through DHT."; - // } - // if (enableIPv6) { - // qDebug() << "Core starting with IPv6 enabled"; - // } else if (enableLanDiscovery) { - // qWarning() << "Core starting with IPv6 disabled. LAN discovery may - // not work properly."; - // } - // - // // No proxy by default - // tox_options_set_proxy_type(*toxOptions, TOX_PROXY_TYPE_NONE); - // tox_options_set_proxy_host(*toxOptions, nullptr); - // tox_options_set_proxy_port(*toxOptions, 0); - // - // if (proxyType != ICoreSettings::ProxyType::ptNone) { - // if (static_cast(proxyAddr.length()) > - // tox_max_hostname_length()) { - // qWarning() << "proxy address" << proxyAddr << "is too long"; - // } else if (!proxyAddr.isEmpty() && proxyPort > 0) { - // qDebug() << "using proxy" << proxyAddr << ":" << proxyPort; - // // protection against changings in Tox_Proxy_Type enum - // if (proxyType == ICoreSettings::ProxyType::ptSOCKS5) { - // tox_options_set_proxy_type(*toxOptions, - // TOX_PROXY_TYPE_SOCKS5); - // } else if (proxyType == ICoreSettings::ProxyType::ptHTTP) { - // tox_options_set_proxy_type(*toxOptions, - // TOX_PROXY_TYPE_HTTP); - // } - // - // tox_options_set_proxy_host(*toxOptions, - // toxOptions->getProxyAddrData()); - // tox_options_set_proxy_port(*toxOptions, proxyPort); - // - // if (!forceTCP) { - // qDebug() << "Proxy and UDP enabled, this is a security risk, - // forcing TCP only"; forceTCP = true; - // } - // } - // } - // - // // network options - // tox_options_set_udp_enabled(*toxOptions, !forceTCP); - // tox_options_set_ipv6_enabled(*toxOptions, enableIPv6); - // tox_options_set_local_discovery_enabled(*toxOptions, - // enableLanDiscovery); tox_options_set_start_port(*toxOptions, 0); - // tox_options_set_end_port(*toxOptions, 0); + // need to init proxyAddr here, because we need it to construct ToxOptions + const QString proxyAddr = s == nullptr ? QString{} : s->getProxyAddr(); + // + auto toxOptions = std::unique_ptr(new ToxOptions(tox_opts, proxyAddr.toUtf8())); + // // register log first, to get messages as early as possible + // tox_options_set_log_callback(*toxOptions, ToxLogger::onLogMessage); + // + // // savedata + // tox_options_set_savedata_type(*toxOptions, savedata.isNull() ? + // TOX_SAVEDATA_TYPE_NONE + // : + // TOX_SAVEDATA_TYPE_TOX_SAVE); + // tox_options_set_savedata_data(*toxOptions, reinterpret_cast(savedata.data()), + // savedata.size()); + // + // if(s == nullptr) { + // qDebug() << "Using Tox default settings"; + // return toxOptions; + // } + // + // // IPv6 needed for LAN discovery, but can crash some weird routers. On + // by default, can be + // // disabled in options. + // const bool enableIPv6 = s->getEnableIPv6(); + // bool forceTCP = s->getForceTCP(); + // // LAN requiring UDP is a toxcore limitation, ideally wouldn't be + // related const bool enableLanDiscovery = s->getEnableLanDiscovery() && + // !forceTCP; ICoreSettings::ProxyType proxyType = s->getProxyType(); + // quint16 proxyPort = s->getProxyPort(); + // + // if (!enableLanDiscovery) { + // qWarning() << "Core starting without LAN discovery. Peers can only + // be found through DHT."; + // } + // if (enableIPv6) { + // qDebug() << "Core starting with IPv6 enabled"; + // } else if (enableLanDiscovery) { + // qWarning() << "Core starting with IPv6 disabled. LAN discovery may + // not work properly."; + // } + // + // // No proxy by default + // tox_options_set_proxy_type(*toxOptions, TOX_PROXY_TYPE_NONE); + // tox_options_set_proxy_host(*toxOptions, nullptr); + // tox_options_set_proxy_port(*toxOptions, 0); + // + // if (proxyType != ICoreSettings::ProxyType::ptNone) { + // if (static_cast(proxyAddr.length()) > + // tox_max_hostname_length()) { + // qWarning() << "proxy address" << proxyAddr << "is too long"; + // } else if (!proxyAddr.isEmpty() && proxyPort > 0) { + // qDebug() << "using proxy" << proxyAddr << ":" << proxyPort; + // // protection against changings in Tox_Proxy_Type enum + // if (proxyType == ICoreSettings::ProxyType::ptSOCKS5) { + // tox_options_set_proxy_type(*toxOptions, + // TOX_PROXY_TYPE_SOCKS5); + // } else if (proxyType == ICoreSettings::ProxyType::ptHTTP) { + // tox_options_set_proxy_type(*toxOptions, + // TOX_PROXY_TYPE_HTTP); + // } + // + // tox_options_set_proxy_host(*toxOptions, + // toxOptions->getProxyAddrData()); + // tox_options_set_proxy_port(*toxOptions, proxyPort); + // + // if (!forceTCP) { + // qDebug() << "Proxy and UDP enabled, this is a security risk, + // forcing TCP only"; forceTCP = true; + // } + // } + // } + // + // // network options + // tox_options_set_udp_enabled(*toxOptions, !forceTCP); + // tox_options_set_ipv6_enabled(*toxOptions, enableIPv6); + // tox_options_set_local_discovery_enabled(*toxOptions, + // enableLanDiscovery); tox_options_set_start_port(*toxOptions, 0); + // tox_options_set_end_port(*toxOptions, 0); - return toxOptions; + return toxOptions; } bool ToxOptions::getIPv6Enabled() const { - return false; - // return tox_options_get_ipv6_enabled(options); + return false; + // return tox_options_get_ipv6_enabled(options); } void ToxOptions::setIPv6Enabled(bool enabled) { - // tox_options_set_ipv6_enabled(options, enabled); + // tox_options_set_ipv6_enabled(options, enabled); } diff --git a/src/modules/im/src/core/toxoptions.h b/src/modules/im/src/core/toxoptions.h index c348dd34..a7f9702d 100644 --- a/src/modules/im/src/core/toxoptions.h +++ b/src/modules/im/src/core/toxoptions.h @@ -20,12 +20,11 @@ class ICoreSettings; struct Tox_Options; -class ToxOptions -{ +class ToxOptions { public: ~ToxOptions(); ToxOptions(ToxOptions&& from); - operator Tox_Options * (); + operator Tox_Options*(); const char* getProxyAddrData() const; static std::unique_ptr makeToxOptions(const QByteArray& savedata, const ICoreSettings* s); @@ -40,4 +39,4 @@ class ToxOptions QByteArray proxyAddrData; }; -#endif // TOXOPTIONS_H +#endif // TOXOPTIONS_H diff --git a/src/modules/im/src/core/toxstring.cpp b/src/modules/im/src/core/toxstring.cpp index bfe06a24..7e80b768 100644 --- a/src/modules/im/src/core/toxstring.cpp +++ b/src/modules/im/src/core/toxstring.cpp @@ -27,27 +27,20 @@ * @brief Creates a ToxString from a QString. * @param string Input text. */ -ToxString::ToxString(const QString& text) - : ToxString(text.toUtf8()) -{ -} +ToxString::ToxString(const QString& text) : ToxString(text.toUtf8()) {} /** * @brief Creates a ToxString from bytes in a QByteArray. * @param text Input text. */ -ToxString::ToxString(const QByteArray& text) - : string(text) -{ -} +ToxString::ToxString(const QByteArray& text) : string(text) {} /** * @brief Creates a ToxString from the representation used by c-toxcore. * @param text Pointer to the beginning of the text. * @param length Number of bytes to read from the beginning. */ -ToxString::ToxString(const uint8_t* text, size_t length) -{ +ToxString::ToxString(const uint8_t* text, size_t length) { assert(length <= INT_MAX); string = QByteArray(reinterpret_cast(text), length); } @@ -56,8 +49,7 @@ ToxString::ToxString(const uint8_t* text, size_t length) * @brief Returns a pointer to the beginning of the string data. * @return Pointer to the beginning of the string data. */ -const uint8_t* ToxString::data() const -{ +const uint8_t* ToxString::data() const { return reinterpret_cast(string.constData()); } @@ -65,25 +57,16 @@ const uint8_t* ToxString::data() const * @brief Get the number of bytes in the string. * @return Number of bytes in the string. */ -size_t ToxString::size() const -{ - return string.size(); -} +size_t ToxString::size() const { return string.size(); } /** * @brief Gets the string as QString. * @return QString representation of the string. */ -QString ToxString::getQString() const -{ - return QString::fromUtf8(string); -} +QString ToxString::getQString() const { return QString::fromUtf8(string); } /** * @brief getBytes Gets the bytes of the string. * @return Bytes of the string as QByteArray. */ -QByteArray ToxString::getBytes() const -{ - return QByteArray(string); -} +QByteArray ToxString::getBytes() const { return QByteArray(string); } diff --git a/src/modules/im/src/core/toxstring.h b/src/modules/im/src/core/toxstring.h index 26e3bc77..f29c9f98 100644 --- a/src/modules/im/src/core/toxstring.h +++ b/src/modules/im/src/core/toxstring.h @@ -18,8 +18,7 @@ #include -class ToxString -{ +class ToxString { public: explicit ToxString(const QString& text); explicit ToxString(const QByteArray& text); @@ -33,4 +32,4 @@ class ToxString private: QByteArray string; }; -#endif // TOXSTRING_H +#endif // TOXSTRING_H diff --git a/src/modules/im/src/friendlist.cpp b/src/modules/im/src/friendlist.cpp index 485ca488..52aff689 100644 --- a/src/modules/im/src/friendlist.cpp +++ b/src/modules/im/src/friendlist.cpp @@ -11,65 +11,56 @@ */ #include "friendlist.h" +#include +#include #include "src/core/FriendId.h" #include "src/model/friend.h" #include "src/persistence/settings.h" -#include -#include - FriendMap FriendList::friendMap; -Friend *FriendList::addFriend(const FriendInfo &friendInfo) { - qDebug() << __func__ << "friendInfo:" << friendInfo.toString(); +Friend* FriendList::addFriend(const FriendInfo& friendInfo) { + qDebug() << __func__ << "friendInfo:" << friendInfo.toString(); - auto frnd = findFriend(friendInfo.id); - if(frnd){ - qWarning() <<"friend:" << friendInfo.toString() <<"is existing"; - return frnd; - } + auto frnd = findFriend(friendInfo.id); + if (frnd) { + qWarning() << "friend:" << friendInfo.toString() << "is existing"; + return frnd; + } - Friend *newfriend = new Friend(friendInfo.id, - friendInfo.isFriend(), - friendInfo.getAlias(), - {}); - friendMap[((ContactId&)friendInfo).toString()] = newfriend; + Friend* newfriend = new Friend(friendInfo.id, friendInfo.isFriend(), friendInfo.getAlias(), {}); + friendMap[((ContactId&)friendInfo).toString()] = newfriend; -// if(friendInfo.resource.isEmpty()){ -// newfriend->addEnd(friendInfo.resource); -// } - return newfriend; + // if(friendInfo.resource.isEmpty()){ + // newfriend->addEnd(friendInfo.resource); + // } + return newfriend; } -Friend *FriendList::findFriend(const ContactId &cId) { - return friendMap.value(cId.toString()); -} +Friend* FriendList::findFriend(const ContactId& cId) { return friendMap.value(cId.toString()); } -void FriendList::removeFriend(const FriendId &friendPk, bool fake) { +void FriendList::removeFriend(const FriendId& friendPk, bool fake) { auto f = findFriend(friendPk); - if(f){ + if (f) { friendMap.remove(((ContactId&)friendPk).toString()); f->deleteLater(); } } - void FriendList::clear() { - for (auto friendptr : friendMap) - delete friendptr; - friendMap.clear(); + for (auto friendptr : friendMap) delete friendptr; + friendMap.clear(); } -QList FriendList::getAllFriends() { return friendMap.values(); } +QList FriendList::getAllFriends() { return friendMap.values(); } -QString FriendList::decideNickname(const FriendId &friendPk, - const QString &origName) { - Friend *f = FriendList::findFriend(friendPk); - if (f != nullptr) { - return f->getDisplayedName(); - } else if (!origName.isEmpty()) { - return origName; - } else { - return friendPk.toString(); - } +QString FriendList::decideNickname(const FriendId& friendPk, const QString& origName) { + Friend* f = FriendList::findFriend(friendPk); + if (f != nullptr) { + return f->getDisplayedName(); + } else if (!origName.isEmpty()) { + return origName; + } else { + return friendPk.toString(); + } } diff --git a/src/modules/im/src/friendlist.h b/src/modules/im/src/friendlist.h index 2a0fb25f..32412c1f 100644 --- a/src/modules/im/src/friendlist.h +++ b/src/modules/im/src/friendlist.h @@ -13,12 +13,12 @@ #ifndef FRIENDLIST_H #define FRIENDLIST_H -#include #include +#include -#include "src/model/message.h" #include #include +#include "src/model/message.h" template class QList; template class QHash; @@ -27,19 +27,19 @@ class QByteArray; class QString; class FriendId; -using FriendMap = QMap; +using FriendMap = QMap; class FriendList { public: - static Friend *addFriend(const FriendInfo &friendInfo); - static Friend *findFriend(const ContactId &cId); - static QList getAllFriends(); - static void removeFriend(const FriendId &friendPk, bool fake = false); - static void clear(); - static QString decideNickname(const FriendId &friendPk, const QString &origName); + static Friend* addFriend(const FriendInfo& friendInfo); + static Friend* findFriend(const ContactId& cId); + static QList getAllFriends(); + static void removeFriend(const FriendId& friendPk, bool fake = false); + static void clear(); + static QString decideNickname(const FriendId& friendPk, const QString& origName); private: - static FriendMap friendMap; + static FriendMap friendMap; }; -#endif // FRIENDLIST_H +#endif // FRIENDLIST_H diff --git a/src/modules/im/src/grouplist.cpp b/src/modules/im/src/grouplist.cpp index 7ad9ca8b..42561c98 100644 --- a/src/modules/im/src/grouplist.cpp +++ b/src/modules/im/src/grouplist.cpp @@ -11,22 +11,21 @@ */ #include "grouplist.h" -#include "src/core/core.h" -#include "src/model/group.h" #include #include +#include "src/core/core.h" +#include "src/model/group.h" GroupMap GroupList::groupMap; Group* GroupList::addGroup(const GroupId& groupId, const QString& name, bool isAvGroupchat, - const QString& selfName) -{ - qDebug()<<"addGroup"<< "groupId" << groupId.toString(); + const QString& selfName) { + qDebug() << "addGroup" << "groupId" << groupId.toString(); auto checker = groupMap.value(groupId.toString()); - if (checker ){ + if (checker) { qWarning() << "addGroup: groupId already taken"; return checker; } @@ -38,17 +37,9 @@ Group* GroupList::addGroup(const GroupId& groupId, return newGroup; } -Group* GroupList::findGroup(const GroupId& groupId) -{ - - return groupMap.value(groupId.toString()); - -} - - +Group* GroupList::findGroup(const GroupId& groupId) { return groupMap.value(groupId.toString()); } -void GroupList::removeGroup(const GroupId& groupId, bool /*fake*/) -{ +void GroupList::removeGroup(const GroupId& groupId, bool /*fake*/) { auto g_it = groupMap.find(groupId.toString()); if (g_it != groupMap.end()) { delete *g_it; @@ -56,19 +47,15 @@ void GroupList::removeGroup(const GroupId& groupId, bool /*fake*/) } } -QList GroupList::getAllGroups() -{ +QList GroupList::getAllGroups() { QList res; - for (auto it : groupMap) - res.append(it); + for (auto it : groupMap) res.append(it); return res; } -void GroupList::clear() -{ - for (auto groupptr : groupMap) - delete groupptr; +void GroupList::clear() { + for (auto groupptr : groupMap) delete groupptr; groupMap.clear(); } diff --git a/src/modules/im/src/grouplist.h b/src/modules/im/src/grouplist.h index 9bea7876..935f3bae 100644 --- a/src/modules/im/src/grouplist.h +++ b/src/modules/im/src/grouplist.h @@ -15,19 +15,17 @@ #include "src/core/groupid.h" -template -class QHash; -template -class QList; +template class QHash; +template class QList; class Group; class QString; using GroupMap = QHash; -class GroupList -{ +class GroupList { public: - static Group* addGroup(const GroupId& groupId, const QString& name="", bool isAvGroupchat=true, const QString& selfName=""); + static Group* addGroup(const GroupId& groupId, const QString& name = "", + bool isAvGroupchat = true, const QString& selfName = ""); static Group* findGroup(const GroupId& groupId); static const GroupId& id2Key(QString groupNum); static void removeGroup(const GroupId& groupId, bool fake = false); @@ -38,4 +36,4 @@ class GroupList static GroupMap groupMap; }; -#endif // GROUPLIST_H +#endif // GROUPLIST_H diff --git a/src/modules/im/src/ipc.cpp b/src/modules/im/src/ipc.cpp index 01447745..8dc7da30 100644 --- a/src/modules/im/src/ipc.cpp +++ b/src/modules/im/src/ipc.cpp @@ -36,10 +36,7 @@ * @brief Inter-process communication */ -IPC::IPC(uint32_t profileId) - : profileId{profileId} - , globalMemory{"qtox-" IPC_PROTOCOL_VERSION} -{ +IPC::IPC(uint32_t profileId) : profileId{profileId}, globalMemory{"qtox-" IPC_PROTOCOL_VERSION} { qRegisterMetaType("IPCEventHandler"); timer.setInterval(EVENT_TIMER_MS); @@ -72,14 +69,13 @@ IPC::IPC(uint32_t profileId) } else { qDebug() << "Failed to attach to the global shared memory, giving up. Error:" << globalMemory.error(); - return; // We won't be able to do any IPC without being attached, let's get outta here + return; // We won't be able to do any IPC without being attached, let's get outta here } processEvents(); } -IPC::~IPC() -{ +IPC::~IPC() { if (!globalMemory.lock()) { qWarning() << "Failed to lock in ~IPC"; return; @@ -98,8 +94,7 @@ IPC::~IPC() * @param dest Settings::getCurrentProfileId() or 0 (main instance, default). * @return Time the event finished or 0 on error. */ -time_t IPC::postEvent(const QString& name, const QByteArray& data, uint32_t dest) -{ +time_t IPC::postEvent(const QString& name, const QByteArray& data, uint32_t dest) { QByteArray binName = name.toUtf8(); if (binName.length() > (int32_t)sizeof(IPCEvent::name)) { return 0; @@ -138,8 +133,7 @@ time_t IPC::postEvent(const QString& name, const QByteArray& data, uint32_t dest return result; } -bool IPC::isCurrentOwner() -{ +bool IPC::isCurrentOwner() { if (globalMemory.lock()) { const bool isOwner = isCurrentOwnerNoLock(); globalMemory.unlock(); @@ -154,13 +148,11 @@ bool IPC::isCurrentOwner() * @brief Register a handler for an IPC event * @param handler The handler callback. Should not block for more than a second, at worst */ -void IPC::registerEventHandler(const QString& name, IPCEventHandler handler) -{ +void IPC::registerEventHandler(const QString& name, IPCEventHandler handler) { eventHandlers[name] = handler; } -bool IPC::isEventAccepted(time_t time) -{ +bool IPC::isEventAccepted(time_t time) { bool result = false; if (!globalMemory.lock()) { return result; @@ -180,12 +172,10 @@ bool IPC::isEventAccepted(time_t time) return result; } -bool IPC::waitUntilAccepted(time_t postTime, int32_t timeout /*=-1*/) -{ +bool IPC::waitUntilAccepted(time_t postTime, int32_t timeout /*=-1*/) { bool result = false; time_t start = time(nullptr); - forever - { + forever { result = isEventAccepted(postTime); if (result || (timeout > 0 && difftime(time(nullptr), start) >= timeout)) { break; @@ -197,22 +187,15 @@ bool IPC::waitUntilAccepted(time_t postTime, int32_t timeout /*=-1*/) return result; } -bool IPC::isAttached() const -{ - return globalMemory.isAttached(); -} +bool IPC::isAttached() const { return globalMemory.isAttached(); } -void IPC::setProfileId(uint32_t profileId) -{ - this->profileId = profileId; -} +void IPC::setProfileId(uint32_t profileId) { this->profileId = profileId; } /** * @brief Only called when global memory IS LOCKED. * @return nullptr if no evnts present, IPC event otherwise */ -IPC::IPCEvent* IPC::fetchEvent() -{ +IPC::IPCEvent* IPC::fetchEvent() { IPCMemory* mem = global(); for (uint32_t i = 0; i < EVENT_QUEUE_SIZE; ++i) { IPCEvent* evt = &mem->events[i]; @@ -220,13 +203,13 @@ IPC::IPCEvent* IPC::fetchEvent() // Garbage-collect events that were not processed in EVENT_GC_TIMEOUT // and events that were processed and EVENT_GC_TIMEOUT passed after // so sending instance has time to react to those events. - if ((evt->processed && difftime(time(nullptr), evt->processed) > EVENT_GC_TIMEOUT) - || (!evt->processed && difftime(time(nullptr), evt->posted) > EVENT_GC_TIMEOUT)) { + if ((evt->processed && difftime(time(nullptr), evt->processed) > EVENT_GC_TIMEOUT) || + (!evt->processed && difftime(time(nullptr), evt->posted) > EVENT_GC_TIMEOUT)) { memset(evt, 0, sizeof(IPCEvent)); } - if (evt->posted && !evt->processed && evt->sender != getpid() - && (evt->dest == profileId || (evt->dest == 0 && isCurrentOwnerNoLock()))) { + if (evt->posted && !evt->processed && evt->sender != getpid() && + (evt->dest == profileId || (evt->dest == 0 && isCurrentOwnerNoLock()))) { return evt; } } @@ -234,8 +217,7 @@ IPC::IPCEvent* IPC::fetchEvent() return nullptr; } -bool IPC::runEventHandler(IPCEventHandler handler, const QByteArray& arg) -{ +bool IPC::runEventHandler(IPCEventHandler handler, const QByteArray& arg) { bool result = false; if (QThread::currentThread() == qApp->thread()) { result = handler(arg); @@ -248,8 +230,7 @@ bool IPC::runEventHandler(IPCEventHandler handler, const QByteArray& arg) return result; } -void IPC::processEvents() -{ +void IPC::processEvents() { if (!globalMemory.lock()) { timer.start(); return; @@ -305,8 +286,7 @@ void IPC::processEvents() * @brief Only called when global memory IS LOCKED. * @return true if owner, false if not owner or if error */ -bool IPC::isCurrentOwnerNoLock() -{ +bool IPC::isCurrentOwnerNoLock() { const void* const data = globalMemory.data(); if (!data) { qWarning() << "isCurrentOwnerNoLock failed to access the memory, returning false"; @@ -315,7 +295,4 @@ bool IPC::isCurrentOwnerNoLock() return (*static_cast(data) == globalId); } -IPC::IPCMemory* IPC::global() -{ - return static_cast(globalMemory.data()); -} +IPC::IPCMemory* IPC::global() { return static_cast(globalMemory.data()); } diff --git a/src/modules/im/src/ipc.h b/src/modules/im/src/ipc.h index 02158465..310c350a 100644 --- a/src/modules/im/src/ipc.h +++ b/src/modules/im/src/ipc.h @@ -10,7 +10,6 @@ * See the Mulan PubL v2 for more details. */ - #ifndef IPC_H #define IPC_H @@ -25,8 +24,7 @@ using IPCEventHandler = std::function; #define IPC_PROTOCOL_VERSION "2" -class IPC : public QObject -{ +class IPC : public QObject { Q_OBJECT protected: @@ -39,8 +37,7 @@ class IPC : public QObject IPC(uint32_t profileId); ~IPC(); - struct IPCEvent - { + struct IPCEvent { uint32_t dest; int32_t sender; char name[16]; @@ -52,8 +49,7 @@ class IPC : public QObject bool global; }; - struct IPCMemory - { + struct IPCMemory { uint64_t globalId; time_t lastEvent; time_t lastProcessed; @@ -85,4 +81,4 @@ public slots: QMap eventHandlers; }; -#endif // IPC_H +#endif // IPC_H diff --git a/src/modules/im/src/model/MsgId.h b/src/modules/im/src/model/MsgId.h index 56ff0b75..4bacdf73 100644 --- a/src/modules/im/src/model/MsgId.h +++ b/src/modules/im/src/model/MsgId.h @@ -20,7 +20,7 @@ using MsgId = QString; -//NamedType; -//Q_DECLARE_METATYPE(MsgId); +// NamedType; +// Q_DECLARE_METATYPE(MsgId); #endif /* RECEIPT_NUM_H */ diff --git a/src/modules/im/src/model/aboutfriend.cpp b/src/modules/im/src/model/aboutfriend.cpp index 38149459..6d9db22b 100644 --- a/src/modules/im/src/model/aboutfriend.cpp +++ b/src/modules/im/src/model/aboutfriend.cpp @@ -14,107 +14,78 @@ #include "src/model/friend.h" #include "src/nexus.h" -#include "src/persistence/profile.h" #include "src/persistence/ifriendsettings.h" +#include "src/persistence/profile.h" -AboutFriend::AboutFriend(const Friend* f, IFriendSettings* const s) - : f{f} - , settings{s} -{ - s->connectTo_contactNoteChanged(this, [this](const FriendId& pk, const QString& note) { - emit noteChanged(note); - }); - s->connectTo_autoAcceptCallChanged(this, - [this](const FriendId& pk, IFriendSettings::AutoAcceptCallFlags flag) { - emit autoAcceptCallChanged(flag); - }); +AboutFriend::AboutFriend(const Friend* f, IFriendSettings* const s) : f{f}, settings{s} { + s->connectTo_contactNoteChanged( + this, [this](const FriendId& pk, const QString& note) { emit noteChanged(note); }); + s->connectTo_autoAcceptCallChanged( + this, [this](const FriendId& pk, IFriendSettings::AutoAcceptCallFlags flag) { + emit autoAcceptCallChanged(flag); + }); s->connectTo_autoAcceptDirChanged(this, [this](const FriendId& pk, const QString& dir) { emit autoAcceptDirChanged(dir); }); - s->connectTo_autoGroupInviteChanged(this, [this](const FriendId& pk, bool enable) { - emit autoGroupInviteChanged(enable); - }); + s->connectTo_autoGroupInviteChanged( + this, [this](const FriendId& pk, bool enable) { emit autoGroupInviteChanged(enable); }); } -QString AboutFriend::getName() const -{ - return f->getName(); -} +QString AboutFriend::getName() const { return f->getName(); } -const QString &AboutFriend::getAlias() const -{ - return f->getAlias(); -} +const QString& AboutFriend::getAlias() const { return f->getAlias(); } -QString AboutFriend::getStatusMessage() const -{ - return f->getStatusMessage(); -} +QString AboutFriend::getStatusMessage() const { return f->getStatusMessage(); } -FriendId AboutFriend::getPublicKey() const -{ - return f->getPublicKey(); -} +FriendId AboutFriend::getPublicKey() const { return f->getPublicKey(); } -QPixmap AboutFriend::getAvatar() const -{ - return f->getAvatar(); -} +QPixmap AboutFriend::getAvatar() const { return f->getAvatar(); } -QString AboutFriend::getNote() const -{ +QString AboutFriend::getNote() const { const FriendId pk = f->getPublicKey(); return settings->getContactNote(pk); } -void AboutFriend::setNote(const QString& note) -{ +void AboutFriend::setNote(const QString& note) { const FriendId pk = f->getPublicKey(); settings->setContactNote(pk, note); settings->saveFriendSettings(pk); } -QString AboutFriend::getAutoAcceptDir() const -{ +QString AboutFriend::getAutoAcceptDir() const { const FriendId pk = f->getPublicKey(); return settings->getAutoAcceptDir(pk); } -void AboutFriend::setAutoAcceptDir(const QString& path) -{ +void AboutFriend::setAutoAcceptDir(const QString& path) { const FriendId pk = f->getPublicKey(); settings->setAutoAcceptDir(pk, path); settings->saveFriendSettings(pk); } -IFriendSettings::AutoAcceptCallFlags AboutFriend::getAutoAcceptCall() const -{ +IFriendSettings::AutoAcceptCallFlags AboutFriend::getAutoAcceptCall() const { const FriendId pk = f->getPublicKey(); return settings->getAutoAcceptCall(pk); } -void AboutFriend::setAutoAcceptCall(IFriendSettings::AutoAcceptCallFlags flag) -{ +void AboutFriend::setAutoAcceptCall(IFriendSettings::AutoAcceptCallFlags flag) { const FriendId pk = f->getPublicKey(); settings->setAutoAcceptCall(pk, flag); settings->saveFriendSettings(pk); } -bool AboutFriend::getAutoGroupInvite() const -{ +bool AboutFriend::getAutoGroupInvite() const { const FriendId pk = f->getPublicKey(); return settings->getAutoGroupInvite(pk); } -void AboutFriend::setAutoGroupInvite(bool enabled) -{ +void AboutFriend::setAutoGroupInvite(bool enabled) { const FriendId pk = f->getPublicKey(); settings->setAutoGroupInvite(pk, enabled); settings->saveFriendSettings(pk); } -bool AboutFriend::clearHistory() -{ +bool AboutFriend::clearHistory() { const FriendId pk = f->getPublicKey(); History* const history = Nexus::getProfile()->getHistory(); if (history) { @@ -125,8 +96,7 @@ bool AboutFriend::clearHistory() return false; } -bool AboutFriend::isHistoryExistence() -{ +bool AboutFriend::isHistoryExistence() { auto profile = Nexus::getProfile(); auto core = profile->getCore(); diff --git a/src/modules/im/src/model/aboutfriend.h b/src/modules/im/src/model/aboutfriend.h index 2b5aa037..0ea7e71d 100644 --- a/src/modules/im/src/model/aboutfriend.h +++ b/src/modules/im/src/model/aboutfriend.h @@ -22,15 +22,14 @@ class Friend; class IFriendSettings; -class AboutFriend : public QObject, public IAboutFriend -{ +class AboutFriend : public QObject, public IAboutFriend { Q_OBJECT public: AboutFriend(const Friend* f, IFriendSettings* const settings); - const Friend* getFriend()const override {return f;} + const Friend* getFriend() const override { return f; } QString getName() const override; - const QString & getAlias() const override; + const QString& getAlias() const override; QString getStatusMessage() const override; FriendId getPublicKey() const override; @@ -68,4 +67,4 @@ class AboutFriend : public QObject, public IAboutFriend IFriendSettings* const settings; }; -#endif // ABOUT_FRIEND_H +#endif // ABOUT_FRIEND_H diff --git a/src/modules/im/src/model/chathistory.cpp b/src/modules/im/src/model/chathistory.cpp index e3c747d7..b61f4723 100644 --- a/src/modules/im/src/model/chathistory.cpp +++ b/src/modules/im/src/model/chathistory.cpp @@ -21,8 +21,7 @@ namespace { * @param[in] sessionChatLog SessionChatLog containing currently loaded items * @return True if load is needed */ -bool needsLoadFromHistory(ChatLogIdx idx, const SessionChatLog& sessionChatLog) -{ +bool needsLoadFromHistory(ChatLogIdx idx, const SessionChatLog& sessionChatLog) { return idx < sessionChatLog.getFirstIdx(); } @@ -31,8 +30,7 @@ bool needsLoadFromHistory(ChatLogIdx idx, const SessionChatLog& sessionChatLog) * @param[in] sessionChatLog * @return index of first message */ -ChatLogIdx findFirstMessage(const SessionChatLog& sessionChatLog) -{ +ChatLogIdx findFirstMessage(const SessionChatLog& sessionChatLog) { auto it = sessionChatLog.getFirstIdx(); while (it < sessionChatLog.getNextIdx()) { auto item = sessionChatLog.at(it); @@ -49,8 +47,7 @@ ChatLogIdx findFirstMessage(const SessionChatLog& sessionChatLog) * @param[in/out] content * @return True if was an action */ -bool handleActionPrefix(QString& content) -{ +bool handleActionPrefix(QString& content) { // Unfortunately due to legacy reasons we have to continue // inserting and parsing for ACTION_PREFIX in our messages even // though we have the ability to something more intelligent now @@ -62,27 +59,26 @@ bool handleActionPrefix(QString& content) return isAction; } -} // namespace +} // namespace -ChatHistory::ChatHistory(const ContactId& f_, // - History* history_, // - const ICoreIdHandler& coreIdHandler, // - const Settings& settings_, // +ChatHistory::ChatHistory(const ContactId& f_, // + History* history_, // + const ICoreIdHandler& coreIdHandler, // + const Settings& settings_, // IMessageDispatcher& messageDispatcher) - : f(f_) - , history(history_) - , settings(settings_) - , coreIdHandler(coreIdHandler) - , sessionChatLog(getInitialChatLogIdx(), coreIdHandler) -{ - //消息发送成功 + : f(f_) + , history(history_) + , settings(settings_) + , coreIdHandler(coreIdHandler) + , sessionChatLog(getInitialChatLogIdx(), coreIdHandler) { + // 消息发送成功 connect(&messageDispatcher, &IMessageDispatcher::messageComplete, this, &ChatHistory::onMessageComplete); - //送达 + // 送达 connect(&messageDispatcher, &IMessageDispatcher::messageReceipt, this, &ChatHistory::onMessageReceipt); - //消息接受 + // 消息接受 connect(&messageDispatcher, &IMessageDispatcher::messageReceived, this, &ChatHistory::onMessageReceived); @@ -93,21 +89,24 @@ ChatHistory::ChatHistory(const ContactId& f_, // } // Now that we've fired off our unsent messages we can connect the message - connect(&messageDispatcher, &IMessageDispatcher::messageSent, this, &ChatHistory::onMessageSent); - - connect(&messageDispatcher, &IMessageDispatcher::fileReceived, this, &ChatHistory::onFileUpdated); - connect(&messageDispatcher, &IMessageDispatcher::fileReceived, &sessionChatLog, &SessionChatLog::onFileUpdated); - connect(&messageDispatcher, &IMessageDispatcher::fileCancelled, this, &ChatHistory::onFileCanceled); - connect(&messageDispatcher, &IMessageDispatcher::fileCancelled, &sessionChatLog, &SessionChatLog::onFileCanceled); - - + connect(&messageDispatcher, &IMessageDispatcher::messageSent, this, + &ChatHistory::onMessageSent); + + connect(&messageDispatcher, &IMessageDispatcher::fileReceived, this, + &ChatHistory::onFileUpdated); + connect(&messageDispatcher, &IMessageDispatcher::fileReceived, &sessionChatLog, + &SessionChatLog::onFileUpdated); + connect(&messageDispatcher, &IMessageDispatcher::fileCancelled, this, + &ChatHistory::onFileCanceled); + connect(&messageDispatcher, &IMessageDispatcher::fileCancelled, &sessionChatLog, + &SessionChatLog::onFileCanceled); // NOTE: this has to be done _after_ sending all sent messages since initial // state of the message has to be marked according to our dispatch state constexpr auto defaultNumMessagesToLoad = 100; auto firstChatLogIdx = sessionChatLog.getFirstIdx().get() < defaultNumMessagesToLoad - ? ChatLogIdx(0) - : sessionChatLog.getFirstIdx() - defaultNumMessagesToLoad; + ? ChatLogIdx(0) + : sessionChatLog.getFirstIdx() - defaultNumMessagesToLoad; if (canUseHistory()) { loadHistoryIntoSessionChatLog(firstChatLogIdx); @@ -116,17 +115,11 @@ ChatHistory::ChatHistory(const ContactId& f_, // // We don't manage any of the item updates ourselves, we just forward along // the underlying sessionChatLog's updates connect(&sessionChatLog, &IChatLog::itemUpdated, this, &IChatLog::itemUpdated); - - } -ChatHistory::~ChatHistory() -{ - qDebug()<<__func__; -} +ChatHistory::~ChatHistory() { qDebug() << __func__; } -const ChatLogItem* ChatHistory::at(ChatLogIdx idx) const -{ +const ChatLogItem* ChatHistory::at(ChatLogIdx idx) const { if (canUseHistory()) { ensureIdxInSessionChatLog(idx); } @@ -134,30 +127,26 @@ const ChatLogItem* ChatHistory::at(ChatLogIdx idx) const return sessionChatLog.at(idx); } -QList ChatHistory::getLastTextMessage(uint size) -{ - +QList ChatHistory::getLastTextMessage(uint size) { QList list; auto selfPk = coreIdHandler.getSelfId(); - auto messages = history->getLastMessageForFriend(selfPk, FriendId{f}, size, HistMessageContentType::message); - for(auto& i: messages){ - Message msg={.isAction=false, - .id = QString::number(i.id.get()), - .from = i.sender, - .to = i.receiver, - .content = i.asMessage(), - .timestamp = i.timestamp - }; - list.append(msg); + auto messages = history->getLastMessageForFriend(selfPk, FriendId{f}, size, + HistMessageContentType::message); + for (auto& i : messages) { + Message msg = {.isAction = false, + .id = QString::number(i.id.get()), + .from = i.sender, + .to = i.receiver, + .content = i.asMessage(), + .timestamp = i.timestamp}; + list.append(msg); } return list; - } SearchResult ChatHistory::searchForward(SearchPos startIdx, const QString& phrase, - const ParameterSearch& parameter) const -{ + const ParameterSearch& parameter) const { if (startIdx.logIdx >= getNextIdx()) { SearchResult res; res.found = false; @@ -172,8 +161,7 @@ SearchResult ChatHistory::searchForward(SearchPos startIdx, const QString& phras } SearchResult ChatHistory::searchBackward(SearchPos startIdx, const QString& phrase, - const ParameterSearch& parameter) const -{ + const ParameterSearch& parameter) const { auto res = sessionChatLog.searchBackward(startIdx, phrase, parameter); if (res.found || !canUseHistory()) { @@ -184,8 +172,8 @@ SearchResult ChatHistory::searchBackward(SearchPos startIdx, const QString& phra auto earliestMsg = sessionChatLog.at(earliestMessage); auto earliestMessageDate = (earliestMessage == ChatLogIdx(-1) || !earliestMsg) - ? QDateTime::currentDateTime() - : earliestMsg->getContentAsMessage().message.timestamp; + ? QDateTime::currentDateTime() + : earliestMsg->getContentAsMessage().message.timestamp; // Roundabout way of getting the first idx but I don't want to have to // deal with re-implementing so we'll just piece what we want together... @@ -193,10 +181,10 @@ SearchResult ChatHistory::searchBackward(SearchPos startIdx, const QString& phra // If the double disk access is real bad we can optimize this by adding // another function to history auto dateWherePhraseFound = - history->getDateWhereFindPhrase(f.toString(), earliestMessageDate, phrase, - parameter); + history->getDateWhereFindPhrase(f.toString(), earliestMessageDate, phrase, parameter); - auto loadIdx = history->getNumMessagesForFriendBeforeDate(coreIdHandler.getSelfId(), FriendId{f}, dateWherePhraseFound); + auto loadIdx = history->getNumMessagesForFriendBeforeDate(coreIdHandler.getSelfId(), + FriendId{f}, dateWherePhraseFound); loadHistoryIntoSessionChatLog(ChatLogIdx(loadIdx)); // Reset search pos to the message we just loaded to avoid a double search @@ -205,8 +193,7 @@ SearchResult ChatHistory::searchBackward(SearchPos startIdx, const QString& phra return sessionChatLog.searchBackward(startIdx, phrase, parameter); } -ChatLogIdx ChatHistory::getFirstIdx() const -{ +ChatLogIdx ChatHistory::getFirstIdx() const { if (canUseHistory()) { return ChatLogIdx(0); } else { @@ -214,17 +201,13 @@ ChatLogIdx ChatHistory::getFirstIdx() const } } -ChatLogIdx ChatHistory::getNextIdx() const -{ - return sessionChatLog.getNextIdx(); -} +ChatLogIdx ChatHistory::getNextIdx() const { return sessionChatLog.getNextIdx(); } -std::vector // - ChatHistory::getDateIdxs(const QDate& startDate, size_t maxDates) const -{ +std::vector // +ChatHistory::getDateIdxs(const QDate& startDate, size_t maxDates) const { if (canUseHistory()) { - auto counts = history->getNumMessagesForFriendBeforeDateBoundaries(FriendId(f), - startDate, maxDates); + auto counts = history->getNumMessagesForFriendBeforeDateBoundaries(FriendId(f), startDate, + maxDates); std::vector ret; std::transform(counts.begin(), counts.end(), std::back_inserter(ret), @@ -235,50 +218,45 @@ std::vector // return pair; }); - // Do not re-search in the session chat log. If we have history the query to the history should have been sufficient + // Do not re-search in the session chat log. If we have history the query to the history + // should have been sufficient return ret; } else { return sessionChatLog.getDateIdxs(startDate, maxDates); } } -void ChatHistory::onFileUpdated(const FriendId& sender, const ToxFile& file) -{ - qDebug() << __func__ <<"friendId:" << sender.toString() << file.fileName; +void ChatHistory::onFileUpdated(const FriendId& sender, const ToxFile& file) { + qDebug() << __func__ << "friendId:" << sender.toString() << file.fileName; if (canUseHistory()) { switch (file.status) { - case FileStatus::INITIALIZING: { - - history->addNewFileMessage(f.toString(), - file, - sender.toString(), - QDateTime::currentDateTime(), - {}); - break; - } - case FileStatus::CANCELED: - case FileStatus::FINISHED: - case FileStatus::BROKEN: { -// const bool isSuccess = file.status == FileStatus::FINISHED; - history->setFileMessage(file); - break; - } - case FileStatus::PAUSED: - case FileStatus::TRANSMITTING: - default: - break; + case FileStatus::INITIALIZING: { + history->addNewFileMessage(f.toString(), file, sender.toString(), + QDateTime::currentDateTime(), {}); + break; + } + case FileStatus::CANCELED: + case FileStatus::FINISHED: + case FileStatus::BROKEN: { + // const bool isSuccess = file.status == FileStatus::FINISHED; + history->setFileMessage(file); + break; + } + case FileStatus::PAUSED: + case FileStatus::TRANSMITTING: + default: + break; } } sessionChatLog.onFileUpdated(sender, file); } -void ChatHistory::onFileCanceled(const FriendId &sender, const QString &fileId) -{ - qDebug() << __func__ <<"fileId:" <getMessageByDataId(fileId); - for(auto f: files){ + for (auto f : files) { auto ff = f.asFile(); ff.status = FileStatus::CANCELED; history->setFileMessage(ToxFile(ff)); @@ -286,29 +264,27 @@ void ChatHistory::onFileCanceled(const FriendId &sender, const QString &fileId) } void ChatHistory::onFileTransferRemotePausedUnpaused(const FriendId& sender, const ToxFile& file, - bool paused) -{ + bool paused) { sessionChatLog.onFileTransferRemotePausedUnpaused(sender, file, paused); } -void ChatHistory::onFileTransferBrokenUnbroken(const FriendId& sender, const ToxFile& file, bool broken) -{ +void ChatHistory::onFileTransferBrokenUnbroken(const FriendId& sender, const ToxFile& file, + bool broken) { sessionChatLog.onFileTransferBrokenUnbroken(sender, file, broken); } -void ChatHistory::onMessageReceived(const FriendId& sender, const Message & message) -{ - qDebug()<<__func__<<"sender:"<addNewMessage(message, - HistMessageContentType::message, - false, - onInsertion); + history->addNewMessage(message, HistMessageContentType::message, false, onInsertion); } sessionChatLog.onMessageSent(id, message); } -void ChatHistory::onMessageComplete(DispatchedMessageId id) -{ +void ChatHistory::onMessageComplete(DispatchedMessageId id) { if (canUseHistory()) { completeMessage(id); } @@ -352,17 +323,14 @@ void ChatHistory::onMessageComplete(DispatchedMessageId id) sessionChatLog.onMessageComplete(id); } -void ChatHistory::onMessageReceipt(DispatchedMessageId id) -{ - qDebug() <<__func__<< id.get(); +void ChatHistory::onMessageReceipt(DispatchedMessageId id) { + qDebug() << __func__ << id.get(); if (canUseHistory()) { receiptMessage(id); } sessionChatLog.onMessageReceipt(id); } - - /** * @brief Forces the given index and all future indexes to be in the chatlog * @param[in] idx @@ -370,8 +338,7 @@ void ChatHistory::onMessageReceipt(DispatchedMessageId id) still have all the same items at all the same indexes, we've just stuckem in ram */ -void ChatHistory::ensureIdxInSessionChatLog(ChatLogIdx idx) const -{ +void ChatHistory::ensureIdxInSessionChatLog(ChatLogIdx idx) const { if (needsLoadFromHistory(idx, sessionChatLog)) { loadHistoryIntoSessionChatLog(idx); } @@ -386,8 +353,7 @@ void ChatHistory::ensureIdxInSessionChatLog(ChatLogIdx idx) const * @note no end idx as we always load from start -> latest. In the future we * could have a less contiguous history */ -void ChatHistory::loadHistoryIntoSessionChatLog(ChatLogIdx start) const -{ +void ChatHistory::loadHistoryIntoSessionChatLog(ChatLogIdx start) const { if (!needsLoadFromHistory(start, sessionChatLog)) { return; } @@ -400,10 +366,11 @@ void ChatHistory::loadHistoryIntoSessionChatLog(ChatLogIdx start) const // conversion should be safe assert(getFirstIdx() == ChatLogIdx(0)); - auto messages = history->getMessagesForFriend(core->getSelfId(), FriendId(f), start.get(), end.get()); - qDebug() <<"load message for:"<< f.toString() <<"messages:" << messages.size(); + auto messages = + history->getMessagesForFriend(core->getSelfId(), FriendId(f), start.get(), end.get()); + qDebug() << "load message for:" << f.toString() << "messages:" << messages.size(); -// assert(messages.size() == end.get() - start.get()); + // assert(messages.size() == end.get() - start.get()); ChatLogIdx nextIdx = start; for (const auto& message : messages) { @@ -412,74 +379,73 @@ void ChatHistory::loadHistoryIntoSessionChatLog(ChatLogIdx start) const auto currentIdx = nextIdx++; auto sender = ToxId(message.sender).getPublicKey(); -// auto frnd = FriendList::findFriend(ContactId{message.sender}); + // auto frnd = FriendList::findFriend(ContactId{message.sender}); auto dispName = sender.username; const auto date = message.timestamp; switch (message.type) { - case HistMessageContentType::file: { - auto file = message.asFile(); - auto tfile =ToxFile { file }; - tfile.receiver = message.receiver; - tfile.sender = message.sender; - auto chatLogFile = ChatLogFile{date, tfile}; - sessionChatLog.insertFileAtIdx(currentIdx, sender, dispName, chatLogFile); - break; - } - case HistMessageContentType::message: { - QString messageContent = message.asMessage(); - - auto isAction = handleActionPrefix(messageContent); - - auto processedMessage = Message{ - .isAction= isAction, - .from= message.sender, - .to = message.receiver, - .content=messageContent, - .timestamp= message.timestamp - }; - - auto dispatchedMessageIt = - std::find_if(dispatchedMessageRowIdMap.begin(), dispatchedMessageRowIdMap.end(), - [&](RowId dispatchedId) { return dispatchedId == message.id; }); - -// assert((message.state != MessageState::pending && dispatchedMessageIt == dispatchedMessageRowIdMap.end()) || -// (message.state == MessageState::pending && dispatchedMessageIt != dispatchedMessageRowIdMap.end())); - - auto chatLogMessage = ChatLogMessage{message.state, processedMessage}; - switch (message.state) { - case MessageState::complete: - sessionChatLog.insertCompleteMessageAtIdx(currentIdx, sender, dispName, - chatLogMessage); - break; - case MessageState::pending: - sessionChatLog.insertIncompleteMessageAtIdx(currentIdx, sender, dispName, - chatLogMessage, dispatchedMessageIt.key()); - break; - case MessageState::broken: - sessionChatLog.insertBrokenMessageAtIdx(currentIdx, sender, dispName, - chatLogMessage); - break; + case HistMessageContentType::file: { + auto file = message.asFile(); + auto tfile = ToxFile{file}; + tfile.receiver = message.receiver; + tfile.sender = message.sender; + auto chatLogFile = ChatLogFile{date, tfile}; + sessionChatLog.insertFileAtIdx(currentIdx, sender, dispName, chatLogFile); + break; + } + case HistMessageContentType::message: { + QString messageContent = message.asMessage(); + + auto isAction = handleActionPrefix(messageContent); + + auto processedMessage = Message{.isAction = isAction, + .from = message.sender, + .to = message.receiver, + .content = messageContent, + .timestamp = message.timestamp}; + + auto dispatchedMessageIt = std::find_if( + dispatchedMessageRowIdMap.begin(), dispatchedMessageRowIdMap.end(), + [&](RowId dispatchedId) { return dispatchedId == message.id; }); + + // assert((message.state != MessageState::pending && dispatchedMessageIt + // == dispatchedMessageRowIdMap.end()) || + // (message.state == MessageState::pending && dispatchedMessageIt + // != dispatchedMessageRowIdMap.end())); + + auto chatLogMessage = ChatLogMessage{message.state, processedMessage}; + switch (message.state) { + case MessageState::complete: + sessionChatLog.insertCompleteMessageAtIdx(currentIdx, sender, dispName, + chatLogMessage); + break; + case MessageState::pending: + sessionChatLog.insertIncompleteMessageAtIdx(currentIdx, sender, dispName, + chatLogMessage, + dispatchedMessageIt.key()); + break; + case MessageState::broken: + sessionChatLog.insertBrokenMessageAtIdx(currentIdx, sender, dispName, + chatLogMessage); + break; + } + break; } - break; - } } } -// assert(nextIdx == end); + // assert(nextIdx == end); } /** * @brief Sends any unsent messages in history to the underlying message dispatcher * @param[in] messageDispatcher */ -void ChatHistory::dispatchUnsentMessages(IMessageDispatcher& messageDispatcher) -{ +void ChatHistory::dispatchUnsentMessages(IMessageDispatcher& messageDispatcher) { auto core = Core::getInstance(); auto unsentMessages = history->getUndeliveredMessagesForFriend(core->getSelfId(), FriendId(f)); for (auto& message : unsentMessages) { - if(message.type != HistMessageContentType::message) - continue; + if (message.type != HistMessageContentType::message) continue; auto messageContent = message.asMessage(); auto isAction = handleActionPrefix(messageContent); @@ -503,10 +469,9 @@ void ChatHistory::dispatchUnsentMessages(IMessageDispatcher& messageDispatcher) } } -void ChatHistory::handleDispatchedMessage(DispatchedMessageId dispatchId, RowId historyId) -{ - qDebug() <<"handleDispatchedMessage dispatchId:" << dispatchId.get() - << "historyId" << historyId.get(); +void ChatHistory::handleDispatchedMessage(DispatchedMessageId dispatchId, RowId historyId) { + qDebug() << "handleDispatchedMessage dispatchId:" << dispatchId.get() << "historyId" + << historyId.get(); auto completedMessageIt = completedMessages.find(dispatchId); if (completedMessageIt == completedMessages.end()) { @@ -517,19 +482,17 @@ void ChatHistory::handleDispatchedMessage(DispatchedMessageId dispatchId, RowId } } -void ChatHistory::completeMessage(DispatchedMessageId id) -{ +void ChatHistory::completeMessage(DispatchedMessageId id) { auto dispatchedMessageIt = dispatchedMessageRowIdMap.find(id); if (dispatchedMessageIt == dispatchedMessageRowIdMap.end()) { completedMessages.insert(id); } else { history->markAsDelivered(*dispatchedMessageIt); -// dispatchedMessageRowIdMap.erase(dispatchedMessageIt); + // dispatchedMessageRowIdMap.erase(dispatchedMessageIt); } } -void ChatHistory::receiptMessage(DispatchedMessageId id) -{ +void ChatHistory::receiptMessage(DispatchedMessageId id) { auto dispatchedMessageIt = dispatchedMessageRowIdMap.find(id); if (dispatchedMessageIt != dispatchedMessageRowIdMap.end()) { history->markAsReceipt(*dispatchedMessageIt); @@ -537,10 +500,7 @@ void ChatHistory::receiptMessage(DispatchedMessageId id) } } -bool ChatHistory::canUseHistory() const -{ - return history && settings.getEnableLogging(); -} +bool ChatHistory::canUseHistory() const { return history && settings.getEnableLogging(); } /** * @brief Gets the initial chat log index for a sessionChatLog with 0 items loaded from history. @@ -549,8 +509,7 @@ bool ChatHistory::canUseHistory() const * @param[in] f * @return Initial chat log index */ -ChatLogIdx ChatHistory::getInitialChatLogIdx() const -{ +ChatLogIdx ChatHistory::getInitialChatLogIdx() const { if (canUseHistory()) { return ChatLogIdx(history->getNumMessagesForFriend(coreIdHandler.getSelfId(), FriendId(f))); } diff --git a/src/modules/im/src/model/chathistory.h b/src/modules/im/src/model/chathistory.h index 8a643a1a..0dbe0416 100644 --- a/src/modules/im/src/model/chathistory.h +++ b/src/modules/im/src/model/chathistory.h @@ -21,20 +21,19 @@ class Settings; -class ChatHistory : public IChatLog -{ +class ChatHistory : public IChatLog { Q_OBJECT public: ChatHistory(const ContactId& f_, - History* history_, - const ICoreIdHandler& coreIdHandler, - const Settings& settings, - IMessageDispatcher& messageDispatcher); + History* history_, + const ICoreIdHandler& coreIdHandler, + const Settings& settings, + IMessageDispatcher& messageDispatcher); ~ChatHistory(); const ChatLogItem* at(ChatLogIdx idx) const override; - //最后几条 + // 最后几条 QList getLastTextMessage(uint size); SearchResult searchForward(SearchPos startIdx, const QString& phrase, @@ -43,12 +42,14 @@ class ChatHistory : public IChatLog const ParameterSearch& parameter) const override; ChatLogIdx getFirstIdx() const override; ChatLogIdx getNextIdx() const override; - std::vector getDateIdxs(const QDate& startDate, size_t maxDates) const override; + std::vector getDateIdxs(const QDate& startDate, + size_t maxDates) const override; public slots: void onFileUpdated(const FriendId& sender, const ToxFile& file); void onFileCanceled(const FriendId& sender, const QString& fileId); - void onFileTransferRemotePausedUnpaused(const FriendId& sender, const ToxFile& file, bool paused); + void onFileTransferRemotePausedUnpaused(const FriendId& sender, const ToxFile& file, + bool paused); void onFileTransferBrokenUnbroken(const FriendId& sender, const ToxFile& file, bool broken); private slots: @@ -56,6 +57,7 @@ private slots: void onMessageSent(DispatchedMessageId id, const Message& message); void onMessageComplete(DispatchedMessageId id); void onMessageReceipt(DispatchedMessageId id); + private: void ensureIdxInSessionChatLog(ChatLogIdx idx) const; void loadHistoryIntoSessionChatLog(ChatLogIdx start) const; diff --git a/src/modules/im/src/model/chatlogitem.cpp b/src/modules/im/src/model/chatlogitem.cpp index 4e0d6e08..669ae558 100644 --- a/src/modules/im/src/model/chatlogitem.cpp +++ b/src/modules/im/src/model/chatlogitem.cpp @@ -17,100 +17,76 @@ #include "src/model/friend.h" #include "src/model/group.h" -#include #include +#include namespace { /** * Helper template to get the correct deleter function for our type erased unique_ptr */ -template -struct ChatLogItemDeleter -{ - static void doDelete(void* ptr) - { - delete static_cast(ptr); - } +template struct ChatLogItemDeleter { + static void doDelete(void* ptr) { delete static_cast(ptr); } }; -} // namespace +} // namespace ChatLogItem::ChatLogItem(FriendId sender_, QString displayName, ChatLogFile file_) - : ChatLogItem(sender_, displayName, ContentType::fileTransfer, - ContentPtr(new ChatLogFile(std::move(file_)), - ChatLogItemDeleter::doDelete)) -{} + : ChatLogItem(sender_, displayName, ContentType::fileTransfer, + ContentPtr(new ChatLogFile(std::move(file_)), + ChatLogItemDeleter::doDelete)) {} ChatLogItem::ChatLogItem(FriendId sender_, QString displayName, ChatLogMessage message_) - : ChatLogItem(sender_, displayName, ContentType::message, - ContentPtr(new ChatLogMessage(std::move(message_)), - ChatLogItemDeleter::doDelete)) -{} - -ChatLogItem::ChatLogItem(FriendId sender_, QString displayName, ContentType contentType_, ContentPtr content_) - : sender(std::move(sender_)) - , displayName(displayName) - , contentType(contentType_) - , content(std::move(content_)) -{} - -const FriendId& ChatLogItem::getSender() const -{ - return sender; -} + : ChatLogItem(sender_, displayName, ContentType::message, + ContentPtr(new ChatLogMessage(std::move(message_)), + ChatLogItemDeleter::doDelete)) {} -ChatLogItem::ContentType ChatLogItem::getContentType() const -{ - return contentType; -} +ChatLogItem::ChatLogItem(FriendId sender_, QString displayName, ContentType contentType_, + ContentPtr content_) + : sender(std::move(sender_)) + , displayName(displayName) + , contentType(contentType_) + , content(std::move(content_)) {} + +const FriendId& ChatLogItem::getSender() const { return sender; } -ChatLogFile& ChatLogItem::getContentAsFile() -{ +ChatLogItem::ContentType ChatLogItem::getContentType() const { return contentType; } + +ChatLogFile& ChatLogItem::getContentAsFile() { assert(contentType == ContentType::fileTransfer); return *static_cast(content.get()); } -const ChatLogFile& ChatLogItem::getContentAsFile() const -{ +const ChatLogFile& ChatLogItem::getContentAsFile() const { assert(contentType == ContentType::fileTransfer); return *static_cast(content.get()); } -ChatLogMessage& ChatLogItem::getContentAsMessage() -{ +ChatLogMessage& ChatLogItem::getContentAsMessage() { assert(contentType == ContentType::message); return *static_cast(content.get()); } -const ChatLogMessage& ChatLogItem::getContentAsMessage() const -{ +const ChatLogMessage& ChatLogItem::getContentAsMessage() const { assert(contentType == ContentType::message); return *static_cast(content.get()); } -QDateTime ChatLogItem::getTimestamp() const -{ +QDateTime ChatLogItem::getTimestamp() const { switch (contentType) { - case ChatLogItem::ContentType::message: { - const auto& message = getContentAsMessage(); - return message.message.timestamp; - } - case ChatLogItem::ContentType::fileTransfer: { - const auto& file = getContentAsFile(); - return file.timestamp; - } + case ChatLogItem::ContentType::message: { + const auto& message = getContentAsMessage(); + return message.message.timestamp; + } + case ChatLogItem::ContentType::fileTransfer: { + const auto& file = getContentAsFile(); + return file.timestamp; + } } assert(false); return QDateTime(); } -void ChatLogItem::setDisplayName(QString name) -{ - displayName = name; -} +void ChatLogItem::setDisplayName(QString name) { displayName = name; } -const QString& ChatLogItem::getDisplayName() const -{ - return displayName; -} +const QString& ChatLogItem::getDisplayName() const { return displayName; } diff --git a/src/modules/im/src/model/chatlogitem.h b/src/modules/im/src/model/chatlogitem.h index f0651299..73d7f534 100644 --- a/src/modules/im/src/model/chatlogitem.h +++ b/src/modules/im/src/model/chatlogitem.h @@ -20,32 +20,28 @@ #include -struct ChatLogMessage -{ +struct ChatLogMessage { MessageState state; Message message; }; -struct ChatLogFile -{ +struct ChatLogFile { QDateTime timestamp; ToxFile file; }; -class ChatLogItem -{ +class ChatLogItem { private: using ContentPtr = std::unique_ptr; public: - enum class ContentType - { + enum class ContentType { message, fileTransfer, }; - ChatLogItem(FriendId sender,QString displayName, ChatLogFile file); - ChatLogItem(FriendId sender,QString displayName, ChatLogMessage message); + ChatLogItem(FriendId sender, QString displayName, ChatLogFile file); + ChatLogItem(FriendId sender, QString displayName, ChatLogMessage message); const FriendId& getSender() const; ContentType getContentType() const; ChatLogFile& getContentAsFile(); diff --git a/src/modules/im/src/model/chatroom/chatroom.cpp b/src/modules/im/src/model/chatroom/chatroom.cpp index 7854dcf9..93b07ccb 100644 --- a/src/modules/im/src/model/chatroom/chatroom.cpp +++ b/src/modules/im/src/model/chatroom/chatroom.cpp @@ -15,18 +15,11 @@ // #include "chatroom.h" -Chatroom::Chatroom() -{ +Chatroom::Chatroom() {} -} - -Chatroom::~Chatroom() -{ - -} +Chatroom::~Chatroom() {} -void Chatroom::setActive(bool _active) -{ +void Chatroom::setActive(bool _active) { if (active != _active) { active = _active; emit activeChanged(active); diff --git a/src/modules/im/src/model/chatroom/chatroom.h b/src/modules/im/src/model/chatroom/chatroom.h index c80c97fe..b3dcbe51 100644 --- a/src/modules/im/src/model/chatroom/chatroom.h +++ b/src/modules/im/src/model/chatroom/chatroom.h @@ -13,23 +13,21 @@ #ifndef MODEL_CHATROOM_H #define MODEL_CHATROOM_H - #include "src/model/contact.h" -class Chatroom : public QObject -{ +class Chatroom : public QObject { Q_OBJECT public: virtual const ContactId& getContactId() = 0; - Chatroom(); - ~Chatroom(); + Chatroom(); + ~Chatroom(); void setActive(bool _active); signals: void activeChanged(bool activated); private: - bool active; + bool active; }; #endif /* MODEL_CHATROOM_H */ diff --git a/src/modules/im/src/model/chatroom/friendchatroom.cpp b/src/modules/im/src/model/chatroom/friendchatroom.cpp index 53dbc029..2377c464 100644 --- a/src/modules/im/src/model/chatroom/friendchatroom.cpp +++ b/src/modules/im/src/model/chatroom/friendchatroom.cpp @@ -10,8 +10,8 @@ * See the Mulan PubL v2 for more details. */ -#include "src/grouplist.h" #include "src/model/chatroom/friendchatroom.h" +#include "src/grouplist.h" #include "src/model/dialogs/idialogsmanager.h" #include "src/model/friend.h" #include "src/model/group.h" @@ -23,93 +23,63 @@ namespace { -QString getShortName(const QString& name) -{ +QString getShortName(const QString& name) { constexpr auto MAX_NAME_LENGTH = 30; if (name.length() <= MAX_NAME_LENGTH) { return name; } - return name.left(MAX_NAME_LENGTH).trimmed() + ( "..." ); -} - + return name.left(MAX_NAME_LENGTH).trimmed() + ("..."); } -FriendChatroom::FriendChatroom(const FriendId* frnd, - IDialogsManager* dialogsManager) - : frnd{frnd} - , dialogsManager{dialogsManager} -{ - qDebug()<<__func__ <<"friend"<< frnd->getId(); -} +} // namespace -FriendChatroom::~FriendChatroom() -{ - qDebug()<<__func__; +FriendChatroom::FriendChatroom(const FriendId* frnd, IDialogsManager* dialogsManager) + : frnd{frnd}, dialogsManager{dialogsManager} { + qDebug() << __func__ << "friend" << frnd->getId(); } -const FriendId* FriendChatroom::getFriend() -{ - return frnd; -} +FriendChatroom::~FriendChatroom() { qDebug() << __func__; } -const ContactId& FriendChatroom::getContactId() -{ - return *frnd; -} +const FriendId* FriendChatroom::getFriend() { return frnd; } +const ContactId& FriendChatroom::getContactId() { return *frnd; } -bool FriendChatroom::canBeInvited() const -{ +bool FriendChatroom::canBeInvited() const { return false; -// return Status::isOnline(frnd->getStatus()); + // return Status::isOnline(frnd->getStatus()); } -int FriendChatroom::getCircleId() const -{ - return 0; -} +int FriendChatroom::getCircleId() const { return 0; } -QString FriendChatroom::getCircleName() const -{ +QString FriendChatroom::getCircleName() const { const auto circleId = getCircleId(); return Settings::getInstance().getCircleName(circleId); } - -QString FriendChatroom::getAutoAcceptDir() const -{ +QString FriendChatroom::getAutoAcceptDir() const { return Settings::getInstance().getAutoAcceptDir(*frnd); } -void FriendChatroom::setAutoAcceptDir(const QString& dir) -{ +void FriendChatroom::setAutoAcceptDir(const QString& dir) { Settings::getInstance().setAutoAcceptDir(*frnd, dir); } -void FriendChatroom::disableAutoAccept() -{ - setAutoAcceptDir(QString{}); -} +void FriendChatroom::disableAutoAccept() { setAutoAcceptDir(QString{}); } -bool FriendChatroom::autoAcceptEnabled() const -{ - return getAutoAcceptDir().isEmpty(); -} +bool FriendChatroom::autoAcceptEnabled() const { return getAutoAcceptDir().isEmpty(); } -void FriendChatroom::inviteFriend(const Group* group) -{ +void FriendChatroom::inviteFriend(const Group* group) { const auto friendId = frnd->getId(); const auto groupId = group->getId(); -// Core::getInstance()->groupInviteFriend(friendId, groupId); + // Core::getInstance()->groupInviteFriend(friendId, groupId); } -QVector FriendChatroom::getGroups() const -{ +QVector FriendChatroom::getGroups() const { QVector groups; for (const auto group : GroupList::getAllGroups()) { const auto name = getShortName(group->getName()); - const GroupToDisplay groupToDisplay = { name, group }; + const GroupToDisplay groupToDisplay = {name, group}; groups.push_back(groupToDisplay); } @@ -119,8 +89,7 @@ QVector FriendChatroom::getGroups() const /** * @brief Return sorted list of circles exclude current circle. */ -QVector FriendChatroom::getOtherCircles() const -{ +QVector FriendChatroom::getOtherCircles() const { QVector circles; const auto currentCircleId = getCircleId(); const auto& s = Settings::getInstance(); @@ -130,7 +99,7 @@ QVector FriendChatroom::getOtherCircles() const } const auto name = getShortName(s.getCircleName(i)); - const CircleToDisplay circle = { name, i }; + const CircleToDisplay circle = {name, i}; circles.push_back(circle); } @@ -144,34 +113,28 @@ QVector FriendChatroom::getOtherCircles() const return circles; } -void FriendChatroom::resetEventFlags() -{ -// frnd->setEventFlag(false); +void FriendChatroom::resetEventFlags() { + // frnd->setEventFlag(false); } -bool FriendChatroom::possibleToOpenInNewWindow() const -{ -// const auto friendPk = frnd->getId(); +bool FriendChatroom::possibleToOpenInNewWindow() const { + // const auto friendPk = frnd->getId(); const auto dialogs = dialogsManager->getFriendDialogs(*frnd); return !dialogs || dialogs->chatroomCount() > 1; } -bool FriendChatroom::canBeRemovedFromWindow() const -{ +bool FriendChatroom::canBeRemovedFromWindow() const { const auto friendPk = frnd; const auto dialogs = dialogsManager->getFriendDialogs(*friendPk); return dialogs && dialogs->hasContact(ContactId(frnd->toString())); } -bool FriendChatroom::friendCanBeRemoved() const -{ - +bool FriendChatroom::friendCanBeRemoved() const { const auto dialogs = dialogsManager->getFriendDialogs(*frnd); return !dialogs || !dialogs->hasContact(ContactId(frnd->toString())); } -void FriendChatroom::removeFriendFromDialogs() -{ +void FriendChatroom::removeFriendFromDialogs() { auto dialogs = dialogsManager->getFriendDialogs(*frnd); dialogs->removeFriend(*frnd); } diff --git a/src/modules/im/src/model/chatroom/friendchatroom.h b/src/modules/im/src/model/chatroom/friendchatroom.h index 94186e4a..d78b536d 100644 --- a/src/modules/im/src/model/chatroom/friendchatroom.h +++ b/src/modules/im/src/model/chatroom/friendchatroom.h @@ -15,30 +15,27 @@ #include "chatroom.h" -#include "src/core/FriendId.h" #include #include #include #include +#include "src/core/FriendId.h" class IDialogsManager; class Friend; class Group; -struct GroupToDisplay -{ +struct GroupToDisplay { QString name; Group* group; }; -struct CircleToDisplay -{ +struct CircleToDisplay { QString name; int circleId; }; -class FriendChatroom : public Chatroom -{ +class FriendChatroom : public Chatroom { Q_OBJECT public: FriendChatroom(const FriendId* frnd, IDialogsManager* dialogsManager); @@ -48,16 +45,13 @@ class FriendChatroom : public Chatroom public slots: - const FriendId* getFriend(); - - + const FriendId* getFriend(); bool canBeInvited() const; int getCircleId() const; QString getCircleName() const; - void inviteFriend(const Group* group); bool autoAcceptEnabled() const; @@ -75,12 +69,10 @@ public slots: bool friendCanBeRemoved() const; void removeFriendFromDialogs(); - private: bool active{false}; const FriendId* frnd{nullptr}; IDialogsManager* dialogsManager{nullptr}; - }; -#endif // FRIEND_H +#endif // FRIEND_H diff --git a/src/modules/im/src/model/chatroom/groupchatroom.cpp b/src/modules/im/src/model/chatroom/groupchatroom.cpp index 5471ec23..b052ec2d 100644 --- a/src/modules/im/src/model/chatroom/groupchatroom.cpp +++ b/src/modules/im/src/model/chatroom/groupchatroom.cpp @@ -22,49 +22,30 @@ #include "src/persistence/settings.h" GroupChatroom::GroupChatroom(const GroupId* groupId_, IDialogsManager* dialogsManager) - : groupId{groupId_} - , dialogsManager{dialogsManager} -{ -} - -GroupChatroom::~GroupChatroom() -{ - qDebug() << __func__; -} + : groupId{groupId_}, dialogsManager{dialogsManager} {} -const ContactId &GroupChatroom::getContactId() -{ - return *groupId; -} +GroupChatroom::~GroupChatroom() { qDebug() << __func__; } +const ContactId& GroupChatroom::getContactId() { return *groupId; } -bool GroupChatroom::hasNewMessage() const -{ - return false; -} +bool GroupChatroom::hasNewMessage() const { return false; } -void GroupChatroom::resetEventFlags() -{ -// group->setEventFlag(false); -// group->setMentionedFlag(false); +void GroupChatroom::resetEventFlags() { + // group->setEventFlag(false); + // group->setMentionedFlag(false); } -bool GroupChatroom::friendExists(const FriendId& pk) -{ +bool GroupChatroom::friendExists(const FriendId& pk) { return FriendList::findFriend(pk) != nullptr; } -void GroupChatroom::inviteFriend(const FriendId& pk) -{ +void GroupChatroom::inviteFriend(const FriendId& pk) { const Friend* frnd = FriendList::findFriend(pk); const auto friendId = frnd->getId(); const auto canInvite = Status::isOnline(frnd->getStatus()); if (canInvite) { -// Core::getInstance()->groupInviteFriend(friendId.toString(), groupId->getId()); + // Core::getInstance()->groupInviteFriend(friendId.toString(), groupId->getId()); } } - - - diff --git a/src/modules/im/src/model/chatroom/groupchatroom.h b/src/modules/im/src/model/chatroom/groupchatroom.h index 1aea0417..ef2ce4e3 100644 --- a/src/modules/im/src/model/chatroom/groupchatroom.h +++ b/src/modules/im/src/model/chatroom/groupchatroom.h @@ -23,8 +23,7 @@ class IDialogsManager; class Group; class FriendId; -class GroupChatroom : public Chatroom -{ +class GroupChatroom : public Chatroom { Q_OBJECT public: GroupChatroom(const GroupId* groupId, IDialogsManager* dialogsManager); @@ -38,13 +37,10 @@ class GroupChatroom : public Chatroom bool friendExists(const FriendId& pk); void inviteFriend(const FriendId& pk); - - - private: - const GroupId* groupId{nullptr}; + const GroupId* groupId{nullptr}; - IDialogsManager* dialogsManager{nullptr}; + IDialogsManager* dialogsManager{nullptr}; }; #endif /* GROUP_CHATROOM_H */ diff --git a/src/modules/im/src/model/contact.cpp b/src/modules/im/src/model/contact.cpp index eb8d7c0e..386c6757 100644 --- a/src/modules/im/src/model/contact.cpp +++ b/src/modules/im/src/model/contact.cpp @@ -10,132 +10,110 @@ * See the Mulan PubL v2 for more details. */ - #include "contact.h" -#include #include +#include #include "src/persistence/profile.h" -Contact:: Contact(){ - -} - -Contact:: Contact(const ContactId& id_, const QString& name_, - const QString& alias_, bool isGroup_) - : id(id_),name{name_},alias{alias_}, - group(isGroup_), - avatarSetStatus{ Status::AvatarSet::None}{ +Contact::Contact() {} +Contact::Contact(const ContactId& id_, const QString& name_, const QString& alias_, bool isGroup_) + : id(id_) + , name{name_} + , alias{alias_} + , group(isGroup_) + , avatarSetStatus{Status::AvatarSet::None} { auto profile = Nexus::getProfile(); uint dbId = profile->addContact(id); - qDebug() <<__func__ <<"Add contact"<< id.toString() << " saved to db dbId=>"<" << dbId; -// auto alias0 = profile->getFriendAlias(id.toString()); -// if(!alias0.isEmpty()){ -// alias = alias0; -// } + // auto alias0 = profile->getFriendAlias(id.toString()); + // if(!alias0.isEmpty()){ + // alias = alias0; + // } auto avt = profile->loadAvatarData(FriendId{id}); - if(!avt.isNull()){ + if (!avt.isNull()) { avatar.loadFromData(avt); avatarSetStatus = Status::AvatarSet::UserSet; - }else{ - setDefaultAvatar(); + } else { + setDefaultAvatar(); } } -Contact::~Contact() -= default; +Contact::~Contact() = default; QString Contact::getDisplayedName() const { - if (!alias.isEmpty()) { - return alias; - } - if(!name.isEmpty()){ - return name; - } - return id.username; + if (!alias.isEmpty()) { + return alias; + } + if (!name.isEmpty()) { + return name; + } + return id.username; } -const QPixmap& Contact::setDefaultAvatar() -{ +const QPixmap& Contact::setDefaultAvatar() { auto name = !group ? "contact" : "group"; auto uri = QString(":img/%1_dark.svg").arg(name); avatar = QPixmap(uri); - avatarSetStatus=Status::AvatarSet::DefaultSet; + avatarSetStatus = Status::AvatarSet::DefaultSet; return avatar; } -void Contact::setAvatar(const QPixmap &pix) -{ - if(pix.isNull()){ +void Contact::setAvatar(const QPixmap& pix) { + if (pix.isNull()) { return; } avatar = pix; - avatarSetStatus=Status::AvatarSet::UserSet; + avatarSetStatus = Status::AvatarSet::UserSet; - //save to profile + // save to profile auto profile = Nexus::getProfile(); QByteArray buf; avatar.save(buf); - profile->saveAvatar(FriendId{id}, buf); + profile->saveFriendAvatar(FriendId{id}, buf); emit avatarChanged(avatar); } -void Contact::clearAvatar() -{ +void Contact::clearAvatar() { avatar = QPixmap{}; emit avatarChanged(avatar); } -const QPixmap &Contact::getAvatar() const -{ - return avatar; -} - - -void Contact::setName(const QString &_name) { +const QPixmap& Contact::getAvatar() const { return avatar; } - if (_name == name) { - return; - } +void Contact::setName(const QString& _name) { + if (_name == name) { + return; + } - name = _name; - emit nameChanged(name); + name = _name; + emit nameChanged(name); - if(alias.isEmpty()){ - emit displayedNameChanged(name); - } + if (alias.isEmpty()) { + emit displayedNameChanged(name); + } } +void Contact::setAlias(const QString& alias_) { + qDebug() << __func__ << alias_; -void Contact::setAlias(const QString &alias_) { - qDebug() <<__func__< #include #include +#include "src/core/contactid.h" +#include "src/model/status.h" /** * 联系人(朋友和群的基类) */ -class Contact : public QObject -{ +class Contact : public QObject { Q_OBJECT public: Contact(); - Contact(const ContactId& id, const QString& name, const QString& alias="", bool isGroup = false); + Contact(const ContactId& id, const QString& name, const QString& alias = "", + bool isGroup = false); ~Contact() override; - bool isGroup()const{return group;} + bool isGroup() const { return group; } void setName(const QString& name); - const QString& getName() const{return name;}; + const QString& getName() const { return name; }; - void setAlias(const QString &name); - const QString& getAlias() const{return alias;}; + void setAlias(const QString& name); + const QString& getAlias() const { return alias; }; bool hasAlias() const { return !alias.isEmpty(); } + QString getDisplayedName() const; - QString getDisplayedName() const ; - - const ContactId& getPersistentId() const {return id;}; - QString getId() const {return id.toString(); }; + const ContactId& getPersistentId() const { return id; }; + QString getId() const { return id.toString(); }; const QPixmap& setDefaultAvatar(); void setAvatar(const QPixmap& pix); void clearAvatar(); const QPixmap& getAvatar() const; - virtual void setEventFlag(bool flag) ; - virtual bool getEventFlag() const ; + virtual void setEventFlag(bool flag); + virtual bool getEventFlag() const; - signals: +signals: // 用户名称 - void nameChanged(const QString &name); + void nameChanged(const QString& name); // 备注名称 void aliasChanged(QString alias); // 显示名称(备注名》用户姓名》用户名) - void displayedNameChanged(const QString &newName); + void displayedNameChanged(const QString& newName); // 头像 - void avatarChanged(const QPixmap &avatar); + void avatarChanged(const QPixmap& avatar); - protected: - //是否群聊 +protected: + // 是否群聊 bool group; - //联系人Id + // 联系人Id ContactId id; - //名称(nick): https://xmpp.org/extensions/xep-0172.html + // 名称(nick): https://xmpp.org/extensions/xep-0172.html QString name; - //别名(自己备注,即书签名称)https://xmpp.org/extensions/xep-0048.html + // 别名(自己备注,即书签名称)https://xmpp.org/extensions/xep-0048.html QString alias; - //头像 + // 头像 QPixmap avatar; Status::AvatarSet avatarSetStatus; }; -#endif // CONTACT_H +#endif // CONTACT_H diff --git a/src/modules/im/src/model/dialogs/idialogs.h b/src/modules/im/src/model/dialogs/idialogs.h index cbfaa847..19f7b789 100644 --- a/src/modules/im/src/model/dialogs/idialogs.h +++ b/src/modules/im/src/model/dialogs/idialogs.h @@ -17,8 +17,7 @@ class ContactId; class GroupId; class FriendId; -class IDialogs -{ +class IDialogs { public: virtual ~IDialogs() = default; virtual bool hasContact(const ContactId& contactId) const = 0; @@ -30,4 +29,4 @@ class IDialogs virtual int chatroomCount() const = 0; }; -#endif // I_DIALOGS_H +#endif // I_DIALOGS_H diff --git a/src/modules/im/src/model/dialogs/idialogsmanager.h b/src/modules/im/src/model/dialogs/idialogsmanager.h index bb9120ff..b154ffe9 100644 --- a/src/modules/im/src/model/dialogs/idialogsmanager.h +++ b/src/modules/im/src/model/dialogs/idialogsmanager.h @@ -18,12 +18,11 @@ class GroupId; class FriendId; -class IDialogsManager -{ +class IDialogsManager { public: virtual ~IDialogsManager() = default; virtual IDialogs* getFriendDialogs(const FriendId& friendId) const = 0; virtual IDialogs* getGroupDialogs(const GroupId& groupId) const = 0; }; -#endif // I_DIALOGS_MANAGER +#endif // I_DIALOGS_MANAGER diff --git a/src/modules/im/src/model/friend.cpp b/src/modules/im/src/model/friend.cpp index 497c539c..498bb89b 100644 --- a/src/modules/im/src/model/friend.cpp +++ b/src/modules/im/src/model/friend.cpp @@ -15,32 +15,32 @@ #include "src/persistence/profile.h" #include "src/widget/form/chatform.h" -Friend::Friend(const FriendId &friendPk, // - bool isFriend, // - const QString &userAlias, // - const QString &userName)// - : Contact(friendPk, userName, userAlias, false),// - id{friendPk}, // - hasNewEvents{false}, // - friendStatus{Status::Status::Offline},// - isFriend_{isFriend} { - auto core = Core::getInstance(); - friendStatus = core->getFriendStatus(friendPk.toString()); +Friend::Friend(const FriendId& friendPk, // + bool isFriend, // + const QString& userAlias, // + const QString& userName) // + : Contact(friendPk, userName, userAlias, false) + , // + id{friendPk} + , // + hasNewEvents{false} + , // + friendStatus{Status::Status::Offline} + , // + isFriend_{isFriend} { + auto core = Core::getInstance(); + friendStatus = core->getFriendStatus(friendPk.toString()); } - Friend::~Friend() { qDebug() << __func__; } -QString Friend::toString() const -{ - return getId().toString(); -} +QString Friend::toString() const { return getId().toString(); } -void Friend::setStatusMessage(const QString &message) { - if (statusMessage != message) { - statusMessage = message; - emit statusMessageChanged(message); - } +void Friend::setStatusMessage(const QString& message) { + if (statusMessage != message) { + statusMessage = message; + emit statusMessageChanged(message); + } } QString Friend::getStatusMessage() const { return statusMessage; } @@ -50,17 +50,16 @@ void Friend::setEventFlag(bool flag) { hasNewEvents = flag; } bool Friend::getEventFlag() const { return hasNewEvents; } void Friend::setStatus(Status::Status s) { - if (friendStatus != s) { - auto oldStatus = friendStatus; - friendStatus = s; - emit statusChanged(friendStatus, hasNewEvents); - if (!Status::isOnline(oldStatus) && Status::isOnline(friendStatus)) { - emit onlineOfflineChanged(true); - } else if (Status::isOnline(oldStatus) && !Status::isOnline(friendStatus)) { - emit onlineOfflineChanged(false); + if (friendStatus != s) { + auto oldStatus = friendStatus; + friendStatus = s; + emit statusChanged(friendStatus, hasNewEvents); + if (!Status::isOnline(oldStatus) && Status::isOnline(friendStatus)) { + emit onlineOfflineChanged(true); + } else if (Status::isOnline(oldStatus) && !Status::isOnline(friendStatus)) { + emit onlineOfflineChanged(false); + } } - } } Status::Status Friend::getStatus() const { return friendStatus; } - diff --git a/src/modules/im/src/model/friend.h b/src/modules/im/src/model/friend.h index 13fca552..8d213db4 100644 --- a/src/modules/im/src/model/friend.h +++ b/src/modules/im/src/model/friend.h @@ -13,66 +13,64 @@ #ifndef FRIEND_H #define FRIEND_H +#include +#include #include "contact.h" #include "src/core/contactid.h" #include "src/core/core.h" #include "src/core/toxid.h" #include "src/model/status.h" -#include -#include -namespace lib::messenger{ +namespace lib::messenger { class IMFriend; } class Friend : public Contact { - Q_OBJECT + Q_OBJECT public: + Friend(const FriendId& friendPk, + bool isFriend, + const QString& userAlias = {}, + const QString& userName = {}); - Friend(const FriendId &friendPk, - bool isFriend, - const QString &userAlias = {}, - const QString &userName = {}); - - ~Friend(); - - const FriendId& getId() const {return id; }; + ~Friend(); - QString toString() const; + const FriendId& getId() const { return id; }; - bool hasAlias() const; + QString toString() const; - void setStatusMessage(const QString &message); - QString getStatusMessage() const; + bool hasAlias() const; - void setEventFlag(bool f) override; - bool getEventFlag() const override; + void setStatusMessage(const QString& message); + QString getStatusMessage() const; - const FriendId getPublicKey() const{return FriendId{ Contact::getId()};}; + void setEventFlag(bool f) override; + bool getEventFlag() const override; + const FriendId getPublicKey() const { return FriendId{Contact::getId()}; }; - void setStatus(Status::Status s); - Status::Status getStatus() const; + void setStatus(Status::Status s); + Status::Status getStatus() const; - bool isFriend()const {return isFriend_;} - void addEnd(const QString& end){ends.append(end);} + bool isFriend() const { return isFriend_; } + void addEnd(const QString& end) { ends.append(end); } signals: -// void nameChanged(const QString &name); -// void aliasChanged(const ToxPk &receiver, QString alias); - void statusChanged(Status::Status status, bool event); - void onlineOfflineChanged( bool isOnline); - void statusMessageChanged( const QString &message); - void loadChatHistory(); + // void nameChanged(const QString &name); + // void aliasChanged(const ToxPk &receiver, QString alias); + void statusChanged(Status::Status status, bool event); + void onlineOfflineChanged(bool isOnline); + void statusMessageChanged(const QString& message); + void loadChatHistory(); public slots: private: - FriendId id; - bool hasNewEvents{}; - bool isFriend_; - QString statusMessage; - Status::Status friendStatus; - QList ends;//终端列表 + FriendId id; + bool hasNewEvents{}; + bool isFriend_; + QString statusMessage; + Status::Status friendStatus; + QList ends; // 终端列表 }; -#endif // FRIEND_H +#endif // FRIEND_H diff --git a/src/modules/im/src/model/friendmessagedispatcher.cpp b/src/modules/im/src/model/friendmessagedispatcher.cpp index 8b6e5f7f..c74e3b17 100644 --- a/src/modules/im/src/model/friendmessagedispatcher.cpp +++ b/src/modules/im/src/model/friendmessagedispatcher.cpp @@ -11,8 +11,8 @@ */ #include "friendmessagedispatcher.h" -#include "src/model/status.h" #include "src/model/message.h" +#include "src/model/status.h" #include "src/persistence/settings.h" namespace { @@ -24,82 +24,70 @@ namespace { * @param[in] message * @param[out] receipt */ -bool sendMessageToCore(ICoreFriendMessageSender &messageSender, - const FriendId &f, - const Message &message, - const MsgId &msgId, +bool sendMessageToCore(ICoreFriendMessageSender& messageSender, + const FriendId& f, + const Message& message, + const MsgId& msgId, bool encrypt) { - QString friendId = f.getId(); + QString friendId = f.getId(); - auto sendFn = message.isAction - ? std::mem_fn(&ICoreFriendMessageSender::sendAction) - : std::mem_fn(&ICoreFriendMessageSender::sendMessage); + auto sendFn = message.isAction ? std::mem_fn(&ICoreFriendMessageSender::sendAction) + : std::mem_fn(&ICoreFriendMessageSender::sendMessage); - return sendFn(messageSender, friendId, message.content, msgId, encrypt); + return sendFn(messageSender, friendId, message.content, msgId, encrypt); } -} // namespace - -FriendMessageDispatcher::FriendMessageDispatcher( - const FriendId &f_, - const MessageProcessor::SharedParams& p, - ICoreIdHandler &idHandler_, - ICoreFriendMessageSender &messageSender_) - : f(f_), - messageSender(messageSender_), - offlineMsgEngine(&f_, &messageSender_), - processor(MessageProcessor(idHandler_, f_, p )) -{ -// connect(&f, &IMFriend::onlineOfflineChanged, -// this, &FriendMessageDispatcher::onFriendOnlineOfflineChanged); +} // namespace + +FriendMessageDispatcher::FriendMessageDispatcher(const FriendId& f_, + const MessageProcessor::SharedParams& p, + ICoreIdHandler& idHandler_, + ICoreFriendMessageSender& messageSender_) + : f(f_) + , messageSender(messageSender_) + , offlineMsgEngine(&f_, &messageSender_) + , processor(MessageProcessor(idHandler_, f_, p)) { + // connect(&f, &IMFriend::onlineOfflineChanged, + // this, &FriendMessageDispatcher::onFriendOnlineOfflineChanged); } -FriendMessageDispatcher::~FriendMessageDispatcher() -{ - qDebug()<<__func__; -} +FriendMessageDispatcher::~FriendMessageDispatcher() { qDebug() << __func__; } /** * @see IMessageSender::sendMessage */ -std::pair -FriendMessageDispatcher::sendMessage(bool isAction, const QString &content, bool encrypt) { - qDebug() << __func__ << content; +std::pair FriendMessageDispatcher::sendMessage(bool isAction, + const QString& content, + bool encrypt) { + qDebug() << __func__ << content; - const auto firstId = nextMessageId; - auto lastId = nextMessageId; + const auto firstId = nextMessageId; + auto lastId = nextMessageId; - for (const auto &message : processor.processOutgoingMessage(isAction, content)) { - qDebug() << "Preparing to send a message:" << message.id; + for (const auto& message : processor.processOutgoingMessage(isAction, content)) { + qDebug() << "Preparing to send a message:" << message.id; - auto dispatcherId = nextMessageId++; - qDebug() <<"dispatcherId:" << dispatcherId.get(); + auto dispatcherId = nextMessageId++; + qDebug() << "dispatcherId:" << dispatcherId.get(); - lastId = dispatcherId; + lastId = dispatcherId; - auto onOfflineMsgComplete = [this, dispatcherId] { - emit messageComplete(dispatcherId); - }; + auto onOfflineMsgComplete = [this, dispatcherId] { emit messageComplete(dispatcherId); }; - auto onMsgRead = [this, dispatcherId]{ - emit messageReceipt(dispatcherId); - }; + auto onMsgRead = [this, dispatcherId] { emit messageReceipt(dispatcherId); }; - emit messageSent(dispatcherId, message); + emit messageSent(dispatcherId, message); + bool messageSent = sendMessageToCore(messageSender, f, message, message.id, encrypt); + qDebug() << "sendMessage=>" << messageSent + << QString("{msgId:%1, dispatcherId:%2}").arg(message.id).arg(dispatcherId.get()); - bool messageSent = sendMessageToCore(messageSender, f, message, message.id, encrypt); - qDebug() << "sendMessage=>"< -class FriendMessageDispatcher : public IMessageDispatcher -{ +class FriendMessageDispatcher : public IMessageDispatcher { Q_OBJECT public: FriendMessageDispatcher(const FriendId& f, - const MessageProcessor::SharedParams &sharedParams, - ICoreIdHandler &idHandler_, + const MessageProcessor::SharedParams& sharedParams, + ICoreIdHandler& idHandler_, ICoreFriendMessageSender& messageSender); ~FriendMessageDispatcher(); - std::pair sendMessage( - bool isAction, - const QString& content, - bool encrypt = false) override; + std::pair sendMessage(bool isAction, + const QString& content, + bool encrypt = false) override; - void onMessageReceived(FriendMessage &msg); + void onMessageReceived(FriendMessage& msg); void onReceiptReceived(MsgId receipt); void clearOutgoingMessages() override; - void onFileReceived(const ToxFile &file); - void onFileCancelled(const QString &fileId); + void onFileReceived(const ToxFile& file); + void onFileCancelled(const QString& fileId); private slots: - void onFriendOnlineOfflineChanged( bool isOnline); + void onFriendOnlineOfflineChanged(bool isOnline); private: const FriendId& f; @@ -58,5 +56,4 @@ private slots: MessageProcessor processor; }; - #endif /* IMESSAGE_DISPATCHER_H */ diff --git a/src/modules/im/src/model/group.cpp b/src/modules/im/src/model/group.cpp index 7803f2cc..7be3527c 100644 --- a/src/modules/im/src/model/group.cpp +++ b/src/modules/im/src/model/group.cpp @@ -11,6 +11,7 @@ */ #include "group.h" +#include #include "friend.h" #include "src/core/FriendId.h" #include "src/core/contactid.h" @@ -21,86 +22,80 @@ #include "src/persistence/settings.h" #include "src/widget/form/groupchatform.h" #include "src/widget/groupwidget.h" -#include static const int MAX_GROUP_TITLE_LENGTH = 128; -namespace { +namespace { -Group::Role parseRole(const QString &role){ - if(role=="moderator"){ - return Group::Role::Moderator; - }else if(role=="participant"){ +Group::Role parseRole(const QString& role) { + if (role == "moderator") { + return Group::Role::Moderator; + } else if (role == "participant") { return Group::Role::Participant; - }else if(role == "visitor"){ + } else if (role == "visitor") { return Group::Role::Visitor; } return Group::Role::None; } -Group::Affiliation parseAffiliation(const QString & affiliation){ - if(affiliation == "admin"){ +Group::Affiliation parseAffiliation(const QString& affiliation) { + if (affiliation == "admin") { return Group::Affiliation::Admin; - }else if(affiliation=="owner"){ + } else if (affiliation == "owner") { return Group::Affiliation::Owner; - }else if(affiliation=="member"){ - return Group::Affiliation::Member; - }else if(affiliation=="outcast"){ + } else if (affiliation == "member") { + return Group::Affiliation::Member; + } else if (affiliation == "outcast") { return Group::Affiliation::Outcast; } return Group::Affiliation::None; } +} // namespace + +Group::Group(const GroupId groupId_, const QString& name, bool isAvGroupchat, + const QString& selfName, ICoreGroupQuery& groupQuery, ICoreIdHandler& idHandler) + : Contact(groupId_, name, name, true) + , groupId{groupId_} + , avGroupchat{isAvGroupchat} + , groupQuery(groupQuery) + , idHandler(idHandler) + , role{Role::None} + , affiliation{Affiliation::None} { + // in groupchats, we only notify on messages containing your name <-- dumb + // sound notifications should be on all messages, but system popup + // notification on naming is appropriate + hasNewMessages = 0; + userWasMentioned = 0; } - -Group::Group(const GroupId groupId_, - const QString &name, bool isAvGroupchat, const QString &selfName, - ICoreGroupQuery &groupQuery, ICoreIdHandler &idHandler) - :Contact(groupId_, name, name, true), - groupId{groupId_}, - avGroupchat{isAvGroupchat}, - groupQuery(groupQuery), - idHandler(idHandler), - role{Role::None}, affiliation{Affiliation::None} -{ - // in groupchats, we only notify on messages containing your name <-- dumb - // sound notifications should be on all messages, but system popup - // notification on naming is appropriate - hasNewMessages = 0; - userWasMentioned = 0; - -} - -void Group::setSubject(const QString &author, const QString &newTitle) { - const QString shortTitle = newTitle.left(MAX_GROUP_TITLE_LENGTH); - if (!shortTitle.isEmpty() && subject != shortTitle) { - subject = shortTitle; - emit subjectChanged(author, subject); - } +void Group::setSubject(const QString& author, const QString& newTitle) { + const QString shortTitle = newTitle.left(MAX_GROUP_TITLE_LENGTH); + if (!shortTitle.isEmpty() && subject != shortTitle) { + subject = shortTitle; + emit subjectChanged(author, subject); + } } - void Group::updateUsername(const QString oldName, const QString newName) { -// const QString displayName = FriendList::decideNickname(pk, newName); -// qDebug() <<"updateUsername=>" << displayName; + // const QString displayName = FriendList::decideNickname(pk, newName); + // qDebug() <<"updateUsername=>" << displayName; - if(!peerDisplayNames.contains(oldName)){ - return; - } + if (!peerDisplayNames.contains(oldName)) { + return; + } - if (peerDisplayNames[oldName] != newName) { - peerDisplayNames[newName] = newName; - emit peerNameChanged(oldName, newName); - } + if (peerDisplayNames[oldName] != newName) { + peerDisplayNames[newName] = newName; + emit peerNameChanged(oldName, newName); + } } bool Group::isAvGroupchat() const { return avGroupchat; } int Group::getPeersCount() const { return peerCount; } -void Group::setPeerCount(uint32_t count) -{ +void Group::setPeerCount(uint32_t count) { peerCount = count; emit peerCountChanged(peerCount); } @@ -109,29 +104,26 @@ void Group::setPeerCount(uint32_t count) * @brief Gets the PKs and names of all peers * @return PKs and names of all peers, including our own PK and name */ -const QMap &Group::getPeerList() const { - return peerDisplayNames; -} +const QMap& Group::getPeerList() const { return peerDisplayNames; } -QString Group::getPeerDisplayName(const QString &resource) -{ - return peerDisplayNames.value(resource, resource); +QString Group::getPeerDisplayName(const QString& resource) { + return peerDisplayNames.value(resource, resource); } -void Group::addPeer(const GroupOccupant &occ) { - qDebug() << __func__ << occ.jid << occ.nick ; +void Group::addPeer(const GroupOccupant& occ) { + qDebug() << __func__ << occ.jid << occ.nick; - peerDisplayNames[ToxPeer(occ.jid).resource] = occ.nick; + peerDisplayNames[ToxPeer(occ.jid).resource] = occ.nick; - //判断成员是否为自己 - auto core = Core::getInstance(); - auto selfId = core->getSelfId(); - if(selfId.toString() == ContactId(occ.jid).toString()){ - role = parseRole(occ.role); - affiliation=parseAffiliation(occ.affiliation); - statusCodes = occ.codes; - emit privilegesChanged(role, affiliation, statusCodes); - } + // 判断成员是否为自己 + auto core = Core::getInstance(); + auto selfId = core->getSelfId(); + if (selfId.toString() == ContactId(occ.jid).toString()) { + role = parseRole(occ.role); + affiliation = parseAffiliation(occ.affiliation); + statusCodes = occ.codes; + emit privilegesChanged(role, affiliation, statusCodes); + } } void Group::setEventFlag(bool f) { hasNewMessages = f; } @@ -142,26 +134,21 @@ void Group::setMentionedFlag(bool f) { userWasMentioned = f; } bool Group::getMentionedFlag() const { return userWasMentioned; } - -void Group::setDesc(const QString &desc_) -{ +void Group::setDesc(const QString& desc_) { desc = desc_; emit descChanged(desc); } -const QString& Group::getDesc() const -{ - return desc; -} +const QString& Group::getDesc() const { return desc; } -void Group::setName(const QString &name) -{ +void Group::setName(const QString& name) { qDebug() << __func__ << name; Contact::setName(name); } -void Group::stopAudioOfDepartedPeers(const FriendId &peerPk) { - if (avGroupchat) { -// Core::getInstance()->getAv()->invalidateGroupCallPeerSource(peerPk.toString(), peerPk); - } +void Group::stopAudioOfDepartedPeers(const FriendId& peerPk) { + if (avGroupchat) { + // Core::getInstance()->getAv()->invalidateGroupCallPeerSource(peerPk.toString(), + // peerPk); + } } diff --git a/src/modules/im/src/model/group.h b/src/modules/im/src/model/group.h index 2e3e34b1..b4194d59 100644 --- a/src/modules/im/src/model/group.h +++ b/src/modules/im/src/model/group.h @@ -15,22 +15,21 @@ #include "contact.h" +#include +#include +#include #include "src/core/FriendId.h" #include "src/core/contactid.h" #include "src/core/groupid.h" #include "src/core/icoregroupquery.h" #include "src/core/icoreidhandler.h" #include "src/model/message.h" -#include -#include -#include -class Group : public Contact -{ +class Group : public Contact { Q_OBJECT public: enum class Role { - //https://xmpp.org/extensions/xep-0045.html#roles + // https://xmpp.org/extensions/xep-0045.html#roles None, Visitor, Participant, @@ -39,15 +38,14 @@ class Group : public Contact }; enum class Affiliation { - //https://xmpp.org/extensions/xep-0045.html#affil - Outcast,//被驱逐 + // https://xmpp.org/extensions/xep-0045.html#affil + Outcast, // 被驱逐 None, Owner, Admin, Member, }; - Group(const GroupId persistentGroupId, const QString& name, bool isAvGroupchat, @@ -57,7 +55,7 @@ class Group : public Contact bool isAvGroupchat() const; - void addPeer(const GroupOccupant &go); + void addPeer(const GroupOccupant& go); int getPeersCount() const; void setPeerCount(uint32_t count); const QMap& getPeerList() const; @@ -74,21 +72,19 @@ class Group : public Contact void updateUsername(const QString oldName, const QString newName); void setSubject(const QString& author, const QString& subject); - const QString &getSubject()const{return subject;}; + const QString& getSubject() const { return subject; }; void setSelfName(const QString& name); QString getSelfName() const; void setDesc(const QString& desc_); - const QString & getDesc() const; + const QString& getDesc() const; - const Role& getRole()const{return role;} + const Role& getRole() const { return role; } - const Affiliation& getAffiliation() const { - return affiliation; - } + const Affiliation& getAffiliation() const { return affiliation; } - const GroupId& getPersistentId() const {return groupId;}; + const GroupId& getPersistentId() const { return groupId; }; void setName(const QString& name); @@ -100,9 +96,7 @@ class Group : public Contact void peerCountChanged(uint32_t numPeers); void peerNameChanged(const QString& oldName, const QString& newName); void descChanged(const QString&); - void privilegesChanged(const Role &role, - const Affiliation &aff, - const QList codes); + void privilegesChanged(const Role& role, const Affiliation& aff, const QList codes); private: void stopAudioOfDepartedPeers(const FriendId& peerPk); @@ -123,4 +117,4 @@ class Group : public Contact QList statusCodes; }; -#endif // GROUP_H +#endif // GROUP_H diff --git a/src/modules/im/src/model/groupinvite.cpp b/src/modules/im/src/model/groupinvite.cpp index 38577dcb..0969d311 100644 --- a/src/modules/im/src/model/groupinvite.cpp +++ b/src/modules/im/src/model/groupinvite.cpp @@ -18,15 +18,17 @@ * @brief This class contains information needed to create a group invite */ -GroupInvite::GroupInvite(QString groupId, QString friendId, - ConferenceType inviteType, - const QByteArray &data) - : groupId{groupId}, friendId{friendId}, type{inviteType}, invite{data}, - date{QDateTime::currentDateTime()} {} - -bool GroupInvite::operator==(const GroupInvite &other) const { - return friendId == other.friendId && type == other.type && - invite == other.invite && date == other.date; +GroupInvite::GroupInvite(QString groupId, QString friendId, ConferenceType inviteType, + const QByteArray& data) + : groupId{groupId} + , friendId{friendId} + , type{inviteType} + , invite{data} + , date{QDateTime::currentDateTime()} {} + +bool GroupInvite::operator==(const GroupInvite& other) const { + return friendId == other.friendId && type == other.type && invite == other.invite && + date == other.date; } const QString& GroupInvite::getGroupId() const { return groupId; } diff --git a/src/modules/im/src/model/groupinvite.h b/src/modules/im/src/model/groupinvite.h index 86ab8f1a..82dd4e9b 100644 --- a/src/modules/im/src/model/groupinvite.h +++ b/src/modules/im/src/model/groupinvite.h @@ -13,29 +13,29 @@ #ifndef GROUPINVITE_H #define GROUPINVITE_H -#include "message.h" #include #include - +#include "message.h" class GroupInvite { public: - GroupInvite() = default; - GroupInvite(QString groupId, QString friendId, ConferenceType inviteType, const QByteArray &data); - bool operator==(const GroupInvite &other) const; + GroupInvite() = default; + GroupInvite(QString groupId, QString friendId, ConferenceType inviteType, + const QByteArray& data); + bool operator==(const GroupInvite& other) const; - const QString &getGroupId() const; - const QString &getFriendId() const; - ConferenceType getType() const; - QByteArray getInvite() const; - QDateTime getInviteDate() const; + const QString& getGroupId() const; + const QString& getFriendId() const; + ConferenceType getType() const; + QByteArray getInvite() const; + QDateTime getInviteDate() const; private: - QString groupId; - QString friendId; - ConferenceType type{ConferenceType::TEXT}; - QByteArray invite; - QDateTime date; + QString groupId; + QString friendId; + ConferenceType type{ConferenceType::TEXT}; + QByteArray invite; + QDateTime date; }; -#endif // GROUPINVITE_H +#endif // GROUPINVITE_H diff --git a/src/modules/im/src/model/groupmessagedispatcher.cpp b/src/modules/im/src/model/groupmessagedispatcher.cpp index 4b78583c..74d4f8da 100644 --- a/src/modules/im/src/model/groupmessagedispatcher.cpp +++ b/src/modules/im/src/model/groupmessagedispatcher.cpp @@ -15,42 +15,51 @@ #include -GroupMessageDispatcher::GroupMessageDispatcher(const GroupId &g_, MessageProcessor::SharedParams p, ICoreIdHandler &idHandler_, ICoreGroupMessageSender &messageSender_, - const IGroupSettings &groupSettings_) - : groupId(g_), processor(MessageProcessor(idHandler_, g_, p)), idHandler(idHandler_), messageSender(messageSender_), groupSettings(groupSettings_) { - // processor.enableMentions(); +GroupMessageDispatcher::GroupMessageDispatcher(const GroupId& g_, MessageProcessor::SharedParams p, + ICoreIdHandler& idHandler_, + ICoreGroupMessageSender& messageSender_, + const IGroupSettings& groupSettings_) + : groupId(g_) + , processor(MessageProcessor(idHandler_, g_, p)) + , idHandler(idHandler_) + , messageSender(messageSender_) + , groupSettings(groupSettings_) { + // processor.enableMentions(); } GroupMessageDispatcher::~GroupMessageDispatcher() { qDebug() << __func__; } -std::pair GroupMessageDispatcher::sendMessage(bool isAction, QString const &content, bool encrypt) { - Q_UNUSED(encrypt); +std::pair GroupMessageDispatcher::sendMessage(bool isAction, + QString const& content, + bool encrypt) { + Q_UNUSED(encrypt); - // const auto firstMessageId = nextMessageId; - // auto lastMessageId = firstMessageId; + // const auto firstMessageId = nextMessageId; + // auto lastMessageId = firstMessageId; - for (auto &message : processor.processOutgoingMessage(isAction, content)) { - qDebug() << "Preparing to send a message:" << message.id; - auto dispatchedId = nextMessageId++; - // lastMessageId = dispatchedId; + for (auto& message : processor.processOutgoingMessage(isAction, content)) { + qDebug() << "Preparing to send a message:" << message.id; + auto dispatchedId = nextMessageId++; + // lastMessageId = dispatchedId; - emit messageSent(dispatchedId, message); - emit messageComplete(dispatchedId); + emit messageSent(dispatchedId, message); + emit messageComplete(dispatchedId); - bool sent; - if (message.isAction) { - sent = messageSender.sendGroupAction(groupId.getId(), message.content, message.id); - } else { - sent = messageSender.sendGroupMessage(groupId.getId(), message.content, message.id); - } - qDebug() << "sendMessage=>" << sent << QString("{msgId:%1, dispatcherId:%2}").arg(message.id).arg(dispatchedId.get()); + bool sent; + if (message.isAction) { + sent = messageSender.sendGroupAction(groupId.getId(), message.content, message.id); + } else { + sent = messageSender.sendGroupMessage(groupId.getId(), message.content, message.id); + } + qDebug() << "sendMessage=>" << sent + << QString("{msgId:%1, dispatcherId:%2}").arg(message.id).arg(dispatchedId.get()); - sentMsgIdMap.insert(message.id, dispatchedId); + sentMsgIdMap.insert(message.id, dispatchedId); - return std::make_pair(dispatchedId, message.id); - } + return std::make_pair(dispatchedId, message.id); + } - return {}; + return {}; } /** @@ -59,37 +68,36 @@ std::pair GroupMessageDispatcher::sendMessage(bool i * @param[in] isAction True if is action * @param[in] content Message content */ -void GroupMessageDispatcher::onMessageReceived(GroupMessage &msg) { - - qDebug() << __func__ << "id:" << msg.id << "nick:" << msg.nick << "msg:" << msg.content; - if (sentMsgIdMap.contains(msg.id)) { - qWarning() << "Is a sent message!"; - return; - } - - auto self = idHandler.getSelfPeerId().toString(); - if (self == msg.from) { - qWarning() << "Is self message (from is mine)."; - return; - } - - // auto myNick= idHandler.getNick(); - // qDebug()<< "Self nick:"< - sendMessage(bool isAction, QString const &content, - bool encrypt = false) override; + std::pair sendMessage(bool isAction, QString const& content, + bool encrypt = false) override; - void onMessageReceived(GroupMessage &msg); + void onMessageReceived(GroupMessage& msg); - void clearOutgoingMessages() override; + void clearOutgoingMessages() override; private: - const GroupId &groupId; - MessageProcessor processor; - ICoreIdHandler &idHandler; - ICoreGroupMessageSender &messageSender; - const IGroupSettings &groupSettings; - DispatchedMessageId nextMessageId{0}; - QMap sentMsgIdMap; + const GroupId& groupId; + MessageProcessor processor; + ICoreIdHandler& idHandler; + ICoreGroupMessageSender& messageSender; + const IGroupSettings& groupSettings; + DispatchedMessageId nextMessageId{0}; + QMap sentMsgIdMap; }; #endif /* IMESSAGE_DISPATCHER_H */ diff --git a/src/modules/im/src/model/iaboutfriend.h b/src/modules/im/src/model/iaboutfriend.h index 733623ff..5035ce82 100644 --- a/src/modules/im/src/model/iaboutfriend.h +++ b/src/modules/im/src/model/iaboutfriend.h @@ -20,15 +20,14 @@ class Friend; -class IAboutFriend -{ +class IAboutFriend { public: virtual ~IAboutFriend() = default; virtual const Friend* getFriend() const = 0; virtual QString getName() const = 0; - virtual const QString & getAlias() const =0; + virtual const QString& getAlias() const = 0; virtual QString getStatusMessage() const = 0; virtual FriendId getPublicKey() const = 0; @@ -63,4 +62,4 @@ class IAboutFriend DECLARE_SIGNAL(autoGroupInviteChanged, bool); }; -#endif // I_ABOUT_FRIEND_H +#endif // I_ABOUT_FRIEND_H diff --git a/src/modules/im/src/model/ichatlog.h b/src/modules/im/src/model/ichatlog.h index 517646e0..f840ac33 100644 --- a/src/modules/im/src/model/ichatlog.h +++ b/src/modules/im/src/model/ichatlog.h @@ -28,41 +28,27 @@ #include -using ChatLogIdx = - NamedType; +using ChatLogIdx = NamedType; Q_DECLARE_METATYPE(ChatLogIdx); -struct SearchPos -{ +struct SearchPos { // Index to the chat log item we want ChatLogIdx logIdx; // Number of matches we've had. This is always number of matches from the // start even if we're searching backwards. size_t numMatches; - bool operator==(const SearchPos& other) const - { - return tie() == other.tie(); - } - - bool operator!=(const SearchPos& other) const - { - return tie() != other.tie(); - } - - bool operator<(const SearchPos& other) const - { - return tie() < other.tie(); - } - - std::tuple tie() const - { - return std::tie(logIdx, numMatches); - } + bool operator==(const SearchPos& other) const { return tie() == other.tie(); } + + bool operator!=(const SearchPos& other) const { return tie() != other.tie(); } + + bool operator<(const SearchPos& other) const { return tie() < other.tie(); } + + std::tuple tie() const { return std::tie(logIdx, numMatches); } }; -struct SearchResult -{ +struct SearchResult { bool found; SearchPos pos; size_t start; @@ -74,8 +60,7 @@ struct SearchResult QRegularExpression exp; }; -class IChatLog : public QObject -{ +class IChatLog : public QObject { Q_OBJECT public: virtual ~IChatLog() = default; @@ -117,8 +102,7 @@ class IChatLog : public QObject */ virtual ChatLogIdx getNextIdx() const = 0; - struct DateChatLogIdxPair - { + struct DateChatLogIdxPair { QDate date; ChatLogIdx idx; }; diff --git a/src/modules/im/src/model/imessagedispatcher.h b/src/modules/im/src/model/imessagedispatcher.h index afc207b0..50c23362 100644 --- a/src/modules/im/src/model/imessagedispatcher.h +++ b/src/modules/im/src/model/imessagedispatcher.h @@ -22,19 +22,16 @@ #include - - using DispatchedMessageId = NamedType; Q_DECLARE_METATYPE(DispatchedMessageId); -class IMessageDispatcher : public QObject -{ +class IMessageDispatcher : public QObject { Q_OBJECT public: virtual ~IMessageDispatcher() = default; - virtual std::pair - sendMessage(bool isAction, const QString& content, bool encrypt = false) = 0; + virtual std::pair sendMessage(bool isAction, const QString& content, + bool encrypt = false) = 0; virtual void clearOutgoingMessages() = 0; @@ -42,14 +39,14 @@ class IMessageDispatcher : public QObject /** * @brief Emitted when a message is received and processed */ - void messageReceived(const FriendId& sender, const Message & message); + void messageReceived(const FriendId& sender, const Message& message); /** * @brief Emitted when a message is processed and sent * @param id message id for completion * @param message sent message */ - void messageSent(DispatchedMessageId id, const Message & message); + void messageSent(DispatchedMessageId id, const Message& message); /** * @brief Emitted when a receiver report is received from the associated chat @@ -63,9 +60,9 @@ class IMessageDispatcher : public QObject */ void messageReceipt(DispatchedMessageId id); - void fileReceived(const FriendId& f, const ToxFile & file); + void fileReceived(const FriendId& f, const ToxFile& file); - void fileCancelled(const FriendId& f, const QString & fileId); + void fileCancelled(const FriendId& f, const QString& fileId); }; #endif /* IMESSAGE_DISPATCHER_H */ diff --git a/src/modules/im/src/model/message.cpp b/src/modules/im/src/model/message.cpp index 8563fc2e..73c09b16 100644 --- a/src/modules/im/src/model/message.cpp +++ b/src/modules/im/src/model/message.cpp @@ -11,94 +11,100 @@ */ #include "message.h" +#include "base/uuid.h" #include "friend.h" #include "src/core/core.h" -#include "base/uuid.h" -void MessageProcessor::SharedParams::onUserNameSet(const QString &username) { - QString sanename = username; - sanename.remove(QRegularExpression("[\\t\\n\\v\\f\\r\\x0000]")); - nameMention = QRegularExpression("\\b" + QRegularExpression::escape(username) + "\\b", QRegularExpression::CaseInsensitiveOption); - sanitizedNameMention = QRegularExpression("\\b" + QRegularExpression::escape(sanename) + "\\b", QRegularExpression::CaseInsensitiveOption); +void MessageProcessor::SharedParams::onUserNameSet(const QString& username) { + QString sanename = username; + sanename.remove(QRegularExpression("[\\t\\n\\v\\f\\r\\x0000]")); + nameMention = QRegularExpression("\\b" + QRegularExpression::escape(username) + "\\b", + QRegularExpression::CaseInsensitiveOption); + sanitizedNameMention = QRegularExpression("\\b" + QRegularExpression::escape(sanename) + "\\b", + QRegularExpression::CaseInsensitiveOption); } /** * @brief Set the public key on which a message should be highlighted * @param pk ToxPk in its hex string form */ -void MessageProcessor::SharedParams::setPublicKey(const QString &pk) { - // no sanitization needed, we expect a ToxPk in its string form - pubKeyMention = QRegularExpression("\\b" + pk + "\\b", QRegularExpression::CaseInsensitiveOption); +void MessageProcessor::SharedParams::setPublicKey(const QString& pk) { + // no sanitization needed, we expect a ToxPk in its string form + pubKeyMention = + QRegularExpression("\\b" + pk + "\\b", QRegularExpression::CaseInsensitiveOption); } -MessageProcessor::MessageProcessor(ICoreIdHandler &idHandler_, const ContactId &f_, const MessageProcessor::SharedParams &sharedParams_) - : idHandler{idHandler_}, f{f_}, sharedParams(sharedParams_) {} +MessageProcessor::MessageProcessor(ICoreIdHandler& idHandler_, const ContactId& f_, + const MessageProcessor::SharedParams& sharedParams_) + : idHandler{idHandler_}, f{f_}, sharedParams(sharedParams_) {} /** * @brief Converts an outgoing message into one (or many) sanitized Message(s) */ -std::vector MessageProcessor::processOutgoingMessage(bool isAction, QString const &content) { - std::vector ret; - - QStringList splitMsgs(content); - - QDateTime timestamp = QDateTime::currentDateTime(); - std::transform(splitMsgs.begin(), splitMsgs.end(), std::back_inserter(ret), [&](const QString &part) { - Message message; - message.id = base::UUID::make(); - message.isAction = isAction; - message.to = f.getId(); - message.from = idHandler.getSelfPeerId().toString(); - message.content = part; - message.timestamp = timestamp; - qDebug() << "Generated a new message:" << message.id; - return message; - }); - return ret; +std::vector MessageProcessor::processOutgoingMessage(bool isAction, + QString const& content) { + std::vector ret; + + QStringList splitMsgs(content); + + QDateTime timestamp = QDateTime::currentDateTime(); + std::transform(splitMsgs.begin(), splitMsgs.end(), std::back_inserter(ret), + [&](const QString& part) { + Message message; + message.id = base::UUID::make(); + message.isAction = isAction; + message.to = f.getId(); + message.from = idHandler.getSelfPeerId().toString(); + message.content = part; + message.timestamp = timestamp; + qDebug() << "Generated a new message:" << message.id; + return message; + }); + return ret; } /** * @brief Converts an incoming message into a sanitized Message */ -Message MessageProcessor::processIncomingMessage(Message &ret) { - - if (detectingMentions) { - auto nameMention = sharedParams.GetNameMention(); - auto sanitizedNameMention = sharedParams.GetSanitizedNameMention(); - auto pubKeyMention = sharedParams.GetPublicKeyMention(); - - for (auto const &mention : {nameMention, sanitizedNameMention, pubKeyMention}) { - auto matchIt = mention.globalMatch(ret.content); - if (!matchIt.hasNext()) { - continue; - } - - auto match = matchIt.next(); - - auto pos = static_cast(match.capturedStart()); - auto length = static_cast(match.capturedLength()); - - // skip matches on empty usernames - if (length == 0) { - continue; - } - - ret.metadata.push_back({MessageMetadataType::selfMention, pos, pos + length}); - break; +Message MessageProcessor::processIncomingMessage(Message& ret) { + if (detectingMentions) { + auto nameMention = sharedParams.GetNameMention(); + auto sanitizedNameMention = sharedParams.GetSanitizedNameMention(); + auto pubKeyMention = sharedParams.GetPublicKeyMention(); + + for (auto const& mention : {nameMention, sanitizedNameMention, pubKeyMention}) { + auto matchIt = mention.globalMatch(ret.content); + if (!matchIt.hasNext()) { + continue; + } + + auto match = matchIt.next(); + + auto pos = static_cast(match.capturedStart()); + auto length = static_cast(match.capturedLength()); + + // skip matches on empty usernames + if (length == 0) { + continue; + } + + ret.metadata.push_back({MessageMetadataType::selfMention, pos, pos + length}); + break; + } } - } - - return ret; -} -FriendInfo::FriendInfo(const lib::messenger::IMFriend &aFriend) - : id{ContactId{aFriend.id.toString()}}, - alias{aFriend.alias}, is_friend{aFriend.isFriend()}, - online(aFriend.online), groups(aFriend.groups) { + return ret; } -QDebug &operator<<(QDebug &debug, const FriendInfo &f) { - QDebugStateSaver saver(debug); - debug.nospace() << f.toString(); - return debug; +FriendInfo::FriendInfo(const lib::messenger::IMFriend& aFriend) + : id{ContactId{aFriend.id.toString()}} + , alias{aFriend.alias} + , is_friend{aFriend.isFriend()} + , online(aFriend.online) + , groups(aFriend.groups) {} + +QDebug& operator<<(QDebug& debug, const FriendInfo& f) { + QDebugStateSaver saver(debug); + debug.nospace() << f.toString(); + return debug; } diff --git a/src/modules/im/src/model/message.h b/src/modules/im/src/model/message.h index bb7f9c1c..7eadd9e2 100644 --- a/src/modules/im/src/model/message.h +++ b/src/modules/im/src/model/message.h @@ -19,162 +19,174 @@ #include -#include "lib/messenger/IMFile.h" -#include "lib/messenger/IMMessage.h" -#include "src/core/icoreidhandler.h" #include #include +#include "lib/messenger/IMMessage.h" +#include "src/core/icoreidhandler.h" + #include "MsgId.h" #include "contact.h" // NOTE: This could be extended in the future to handle all text processing (see // ChatMessage::createChatMessage) enum class MessageMetadataType { - selfMention, + selfMention, }; // May need to be extended in the future to have a more varianty type (imagine // if we wanted to add message replies and shoved a reply id in here) struct MessageMetadata { - MessageMetadataType type; - // Indicates start position within a Message::content - size_t start; - // Indicates end position within a Message::content - size_t end; + MessageMetadataType type; + // Indicates start position within a Message::content + size_t start; + // Indicates end position within a Message::content + size_t end; }; struct Message { public: - bool isGroup{false}; - bool isAction; - MsgId id; - QString from; - QString to; - QString displayName; - QString content; - QString dataId; - QDateTime timestamp; - std::vector metadata; - QString toString() const { - return QString("{id:%1, from:%2, to:%3, " - "time:%4, content:%5, sId:%6}") - .arg(id).arg(from).arg(to) - .arg(timestamp.toString()).arg(content).arg(dataId); - } + bool isGroup{false}; + bool isAction; + MsgId id; + QString from; + QString to; + QString displayName; + QString content; + QString dataId; + QDateTime timestamp; + std::vector metadata; + QString toString() const { + return QString("{id:%1, from:%2, to:%3, " + "time:%4, content:%5, sId:%6}") + .arg(id) + .arg(from) + .arg(to) + .arg(timestamp.toString()) + .arg(content) + .arg(dataId); + } }; struct FriendMessage : Message { - // ToxPk to; + // ToxPk to; }; struct GroupMessage : public Message { public: - GroupMessage() { isGroup = true; } - QString nick; - QString resource; - - QString toString() const { - return QString("{id:%1, from:%2, to:%3, time:%4, content:%5, nick:%6, resource:%7}").arg(id).arg(from).arg(to).arg(timestamp.toString()).arg(content).arg(nick).arg(resource); - } + GroupMessage() { isGroup = true; } + QString nick; + QString resource; + + QString toString() const { + return QString("{id:%1, from:%2, to:%3, time:%4, content:%5, nick:%6, resource:%7}") + .arg(id) + .arg(from) + .arg(to) + .arg(timestamp.toString()) + .arg(content) + .arg(nick) + .arg(resource); + } }; struct FriendInfo { - FriendId id; - QString alias; - bool is_friend; - bool online; - QStringList groups; + FriendId id; + QString alias; + bool is_friend; + bool online; + QStringList groups; - explicit FriendInfo(const lib::messenger::IMFriend &aFriend); + explicit FriendInfo(const lib::messenger::IMFriend& aFriend); - [[nodiscard]] inline const FriendId &getId() const { return id; } + [[nodiscard]] inline const FriendId& getId() const { return id; } - [[nodiscard]] inline const QString &getAlias() const { return alias; } + [[nodiscard]] inline const QString& getAlias() const { return alias; } - [[nodiscard]] inline bool isFriend() const { return is_friend; }; + [[nodiscard]] inline bool isFriend() const { return is_friend; }; - [[nodiscard]] inline QString toString() const { - return QString("{id: %1, alias: %2, is_friend:%3, online:%4, groups:[%5]}") // - .arg(id.toString()).arg(alias).arg(is_friend).arg(online).arg(groups.join(",")); - } + [[nodiscard]] inline QString toString() const { + return QString("{id: %1, alias: %2, is_friend:%3, online:%4, groups:[%5]}") // + .arg(id.toString()) + .arg(alias) + .arg(is_friend) + .arg(online) + .arg(groups.join(",")); + } - friend QDebug &operator<<(QDebug &debug, const FriendInfo &f); + friend QDebug& operator<<(QDebug& debug, const FriendInfo& f); }; struct GroupInfo { - QString name; - QString description; - QString subject; - QString creationdate; - uint64_t occupants = 0; + QString name; + QString description; + QString subject; + QString creationdate; + uint64_t occupants = 0; }; struct GroupOccupant { - QString jid; - QString nick; - QString affiliation; - QString role; - int status; - QList codes; + QString jid; + QString nick; + QString affiliation; + QString role; + int status; + QList codes; }; enum class ChatType { - Chat, // 单聊 - GroupChat // 群聊 + Chat, // 单聊 + GroupChat // 群聊 }; -enum class ConferenceType { - TEXT, - AV -}; +enum class ConferenceType { TEXT, AV }; class MessageProcessor { - public: - /** - * Parameters needed by all message processors. Used to reduce duplication - * of expensive data looked at by all message processors - */ - class SharedParams { - - public: - // 模式匹配 - const QRegularExpression &GetNameMention() const { return nameMention; } + /** + * Parameters needed by all message processors. Used to reduce duplication + * of expensive data looked at by all message processors + */ + class SharedParams { + public: + // 模式匹配 + const QRegularExpression& GetNameMention() const { return nameMention; } - const QRegularExpression &GetSanitizedNameMention() const { return sanitizedNameMention; } - const QRegularExpression &GetPublicKeyMention() const { return pubKeyMention; } + const QRegularExpression& GetSanitizedNameMention() const { return sanitizedNameMention; } + const QRegularExpression& GetPublicKeyMention() const { return pubKeyMention; } - void onUserNameSet(const QString &username); - void setPublicKey(const QString &pk); + void onUserNameSet(const QString& username); + void setPublicKey(const QString& pk); - private: - QRegularExpression nameMention; - QRegularExpression sanitizedNameMention; - QRegularExpression pubKeyMention; - }; + private: + QRegularExpression nameMention; + QRegularExpression sanitizedNameMention; + QRegularExpression pubKeyMention; + }; - MessageProcessor(ICoreIdHandler &idHandler, const ContactId &f, const SharedParams &sharedParams); + MessageProcessor(ICoreIdHandler& idHandler, + const ContactId& f, + const SharedParams& sharedParams); - std::vector processOutgoingMessage(bool isAction, QString const &content); + std::vector processOutgoingMessage(bool isAction, QString const& content); - Message processIncomingMessage(Message &message); + Message processIncomingMessage(Message& message); - /** - * @brief Enables mention detection in the processor - */ - inline void enableMentions() { detectingMentions = true; } + /** + * @brief Enables mention detection in the processor + */ + inline void enableMentions() { detectingMentions = true; } - /** - * @brief Disables mention detection in the processor - */ - inline void disableMentions() { detectingMentions = false; }; + /** + * @brief Disables mention detection in the processor + */ + inline void disableMentions() { detectingMentions = false; }; private: - bool detectingMentions = false; - ICoreIdHandler &idHandler; - const ContactId &f; - const SharedParams &sharedParams; + bool detectingMentions = false; + ICoreIdHandler& idHandler; + const ContactId& f; + const SharedParams& sharedParams; }; #endif /*MESSAGE_H*/ diff --git a/src/modules/im/src/model/profile/iprofileinfo.h b/src/modules/im/src/model/profile/iprofileinfo.h index 5bb08a88..ad5b86ab 100644 --- a/src/modules/im/src/model/profile/iprofileinfo.h +++ b/src/modules/im/src/model/profile/iprofileinfo.h @@ -16,20 +16,13 @@ class ToxId; -class IProfileInfo -{ +class IProfileInfo { public: - enum class RenameResult { - OK, EmptyName, ProfileAlreadyExists, Error - }; + enum class RenameResult { OK, EmptyName, ProfileAlreadyExists, Error }; - enum class SaveResult { - OK, EmptyPath, NoWritePermission, Error - }; + enum class SaveResult { OK, EmptyPath, NoWritePermission, Error }; - enum class SetAvatarResult { - OK, EmptyPath, CanNotOpen, CanNotRead, TooLarge - }; + enum class SetAvatarResult { OK, EmptyPath, CanNotOpen, CanNotRead, TooLarge }; virtual ~IProfileInfo() = default; virtual bool setPassword(const QString& password) = 0; @@ -40,7 +33,7 @@ class IProfileInfo virtual void setUsername(const QString& name) = 0; virtual QString getUsername() const = 0; - virtual const QString &getDisplayName() const = 0; + virtual const QString& getDisplayName() const = 0; virtual void setAvatar(const QPixmap& avatar) = 0; virtual const QPixmap& getAvatar() = 0; diff --git a/src/modules/im/src/model/profile/profileinfo.cpp b/src/modules/im/src/model/profile/profileinfo.cpp index 75950de2..f1caf449 100644 --- a/src/modules/im/src/model/profile/profileinfo.cpp +++ b/src/modules/im/src/model/profile/profileinfo.cpp @@ -12,10 +12,10 @@ #include "profileinfo.h" #include "src/core/core.h" +#include "src/model/toxclientstandards.h" #include "src/nexus.h" #include "src/persistence/profile.h" #include "src/persistence/settings.h" -#include "src/model/toxclientstandards.h" #include #include @@ -36,31 +36,24 @@ * @param profile Pointer to Profile. * @note All pointers parameters shouldn't be null. */ -ProfileInfo::ProfileInfo(Core* core, Profile* profile) - : profile{profile} - , core{core} -{ +ProfileInfo::ProfileInfo(Core* core, Profile* profile) : profile{profile}, core{core} { connect(core, &Core::idSet, this, &ProfileInfo::idChanged); connect(core, &Core::usernameSet, this, &ProfileInfo::usernameChanged); connect(core, &Core::avatarSet, this, &ProfileInfo::avatarChanged); connect(core, &Core::statusMessageSet, this, &ProfileInfo::statusMessageChanged); -// connectTo_usernameChanged(this, -// [this](const QString& val) { -// profile->rename(val); -// }); - - + // connectTo_usernameChanged(this, + // [this](const QString& val) { + // profile->rename(val); + // }); } - /** * @brief Set a user password for profile. * @param password New password. * @return True on success, false otherwise. */ -bool ProfileInfo::setPassword(const QString& password) -{ +bool ProfileInfo::setPassword(const QString& password) { QString errorMsg = profile->setPassword(password); return errorMsg.isEmpty(); } @@ -69,8 +62,7 @@ bool ProfileInfo::setPassword(const QString& password) * @brief Delete a user password for profile. * @return True on success, false otherwise. */ -bool ProfileInfo::deletePassword() -{ +bool ProfileInfo::deletePassword() { QString errorMsg = profile->setPassword(""); return errorMsg.isEmpty(); } @@ -79,16 +71,12 @@ bool ProfileInfo::deletePassword() * @brief Check if current profile is encrypted. * @return True if encrypted, false otherwise. */ -bool ProfileInfo::isEncrypted() const -{ - return profile->isEncrypted(); -} +bool ProfileInfo::isEncrypted() const { return profile->isEncrypted(); } /** * @brief Copy self ToxId to clipboard. */ -void ProfileInfo::copyId() const -{ +void ProfileInfo::copyId() const { ToxId selfId = core->getSelfPeerId(); QString txt = selfId.toString(); QClipboard* clip = QApplication::clipboard(); @@ -102,51 +90,32 @@ void ProfileInfo::copyId() const * @brief Set self user name. * @param name New name. */ -void ProfileInfo::setUsername(const QString& name) -{ - core->setUsername(name); -} +void ProfileInfo::setUsername(const QString& name) { profile->setNick(name, true); } -void ProfileInfo::setAvatar(const QPixmap &avatar) { - // set avatar. - profile->setAvatarOnly(avatar); -} +void ProfileInfo::setAvatar(const QPixmap& avatar) { profile->setAvatarOnly(avatar); } -const QPixmap &ProfileInfo::getAvatar() -{ - return profile->loadAvatar(); -} +const QPixmap& ProfileInfo::getAvatar() { return profile->loadAvatar(); } /** * @brief Set self status message. * @param status New status message. */ -void ProfileInfo::setStatusMessage(const QString& status) -{ - core->setStatusMessage(status); -} +void ProfileInfo::setStatusMessage(const QString& status) { core->setStatusMessage(status); } /** * @brief Get name of tox profile file. * @return Profile name. */ -QString ProfileInfo::getUsername() const -{ - return profile->getName(); -} +QString ProfileInfo::getUsername() const { return profile->getName(); } -const QString &ProfileInfo::getDisplayName() const -{ - return profile->getDisplayName(); -} +const QString& ProfileInfo::getDisplayName() const { return profile->getDisplayName(); } /** * @brief Remove characters not supported for profile name from string. * @param src Source string. * @return Sanitized string. */ -static QString sanitize(const QString& src) -{ +static QString sanitize(const QString& src) { QString name = src; // these are pretty much Windows banned filename characters QList banned{'/', '\\', ':', '<', '>', '"', '|', '?', '*'}; @@ -171,8 +140,7 @@ static QString sanitize(const QString& src) * @param name New profile name. * @return Result code of rename operation. */ -IProfileInfo::RenameResult ProfileInfo::renameProfile(const QString& name) -{ +IProfileInfo::RenameResult ProfileInfo::renameProfile(const QString& name) { QString cur = profile->getName(); if (name.isEmpty()) { return RenameResult::EmptyName; @@ -197,8 +165,7 @@ IProfileInfo::RenameResult ProfileInfo::renameProfile(const QString& name) * @param filepath Path to file which should be deleted. * @return True, if file writeable, false otherwise. */ -static bool tryRemoveFile(const QString& filepath) -{ +static bool tryRemoveFile(const QString& filepath) { QFile tmp(filepath); bool writable = tmp.open(QIODevice::WriteOnly); tmp.remove(); @@ -210,8 +177,7 @@ static bool tryRemoveFile(const QString& filepath) * @param path Path to save profile. * @return Result code of save operation. */ -IProfileInfo::SaveResult ProfileInfo::exportProfile(const QString& path) const -{ +IProfileInfo::SaveResult ProfileInfo::exportProfile(const QString& path) const { QString current = profile->getName() + Core::TOX_EXT; if (path.isEmpty()) { return SaveResult::EmptyPath; @@ -232,8 +198,7 @@ IProfileInfo::SaveResult ProfileInfo::exportProfile(const QString& path) const * @brief Remove profile. * @return List of files, which couldn't be removed automaticaly. */ -QStringList ProfileInfo::removeProfile() -{ +QStringList ProfileInfo::removeProfile() { QStringList manualDeleteFiles = profile->remove(); QMetaObject::invokeMethod(&Nexus::getInstance(), "showLogin"); return manualDeleteFiles; @@ -242,27 +207,23 @@ QStringList ProfileInfo::removeProfile() /** * @brief Log out from current profile. */ -void ProfileInfo::logout() -{ - qDebug()<<__func__; - emit Nexus::getInstance().destroyProfile(getUsername()); +void ProfileInfo::logout() { + auto username = getUsername(); + qDebug() << __func__ << username; + emit Nexus::getInstance().destroyProfile(username); } -void ProfileInfo::exit() -{ - qDebug()<<__func__; - emit Nexus::getInstance().exit(getUsername()); +void ProfileInfo::exit() { + auto username = getUsername(); + qDebug() << __func__ << username; + emit Nexus::getInstance().exit(username); } - /** * @brief Copy image to clipboard. * @param image Image to copy. */ -void ProfileInfo::copyQr(const QImage& image) const -{ - QApplication::clipboard()->setImage(image); -} +void ProfileInfo::copyQr(const QImage& image) const { QApplication::clipboard()->setImage(image); } /** * @brief Save image to file. @@ -270,8 +231,7 @@ void ProfileInfo::copyQr(const QImage& image) const * @param path Path to save. * @return Result code of save operation. */ -IProfileInfo::SaveResult ProfileInfo::saveQr(const QImage& image, const QString& path) const -{ +IProfileInfo::SaveResult ProfileInfo::saveQr(const QImage& image, const QString& path) const { QString current = profile->getName() + ".png"; if (path.isEmpty()) { return SaveResult::EmptyPath; @@ -295,8 +255,7 @@ IProfileInfo::SaveResult ProfileInfo::saveQr(const QImage& image, const QString& * @param pic Picture to convert. * @return Byte array with png image. */ -QByteArray picToPng(const QImage& pic) -{ +QByteArray picToPng(const QImage& pic) { QByteArray bytes; QBuffer buffer(&bytes); buffer.open(QIODevice::WriteOnly); @@ -310,8 +269,7 @@ QByteArray picToPng(const QImage& pic) * @param path Path to image, which should be the new avatar. * @return Code of set avatar operation. */ -IProfileInfo::SetAvatarResult ProfileInfo::setAvatar(const QString& path) -{ +IProfileInfo::SetAvatarResult ProfileInfo::setAvatar(const QString& path) { if (path.isEmpty()) { return SetAvatarResult::EmptyPath; } @@ -324,7 +282,7 @@ IProfileInfo::SetAvatarResult ProfileInfo::setAvatar(const QString& path) QByteArray avatar; const auto err = createAvatarFromFile(file, avatar); if (err == SetAvatarResult::OK) { - profile->setAvatar(avatar); + profile->setAvatar(avatar, true); } return err; } @@ -335,8 +293,7 @@ IProfileInfo::SetAvatarResult ProfileInfo::setAvatar(const QString& path) * @param avatar Output avatar of correct file type and size. * @return SetAvatarResult */ -IProfileInfo::SetAvatarResult ProfileInfo::createAvatarFromFile(QFile& file, QByteArray& avatar) -{ +IProfileInfo::SetAvatarResult ProfileInfo::createAvatarFromFile(QFile& file, QByteArray& avatar) { QByteArray fileContents{file.readAll()}; auto err = byteArrayToPng(fileContents, avatar); if (err != SetAvatarResult::OK) { @@ -353,8 +310,7 @@ IProfileInfo::SetAvatarResult ProfileInfo::createAvatarFromFile(QFile& file, QBy * @param outPng byte array which the png will be written to. * @return SetAvatarResult */ -IProfileInfo::SetAvatarResult ProfileInfo::byteArrayToPng(QByteArray inData, QByteArray& outPng) -{ +IProfileInfo::SetAvatarResult ProfileInfo::byteArrayToPng(QByteArray inData, QByteArray& outPng) { QBuffer inBuffer{&inData}; QImageReader reader{&inBuffer}; QImage image; @@ -379,14 +335,12 @@ IProfileInfo::SetAvatarResult ProfileInfo::byteArrayToPng(QByteArray inData, QBy * @param avatar byte array containing the avatar. * @return SetAvatarResult */ -IProfileInfo::SetAvatarResult ProfileInfo::scalePngToAvatar(QByteArray& avatar) -{ +IProfileInfo::SetAvatarResult ProfileInfo::scalePngToAvatar(QByteArray& avatar) { // We do a first rescale to 256x256 in case the image was huge, then keep tryng from here constexpr int scaleSizes[] = {256, 128, 64, 32}; for (auto scaleSize : scaleSizes) { - if (ToxClientStandards::IsValidAvatarSize(avatar.size())) - break; + if (ToxClientStandards::IsValidAvatarSize(avatar.size())) break; QImage image; image.loadFromData(avatar); image = image.scaled(scaleSize, scaleSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); @@ -399,11 +353,6 @@ IProfileInfo::SetAvatarResult ProfileInfo::scalePngToAvatar(QByteArray& avatar) } return SetAvatarResult::OK; } - -/** - * @brief Remove self avatar. - */ -void ProfileInfo::removeAvatar() -{ - profile->removeSelfAvatar(); +void ProfileInfo::removeAvatar() { + profile->removeAvatar(true); } diff --git a/src/modules/im/src/model/profile/profileinfo.h b/src/modules/im/src/model/profile/profileinfo.h index 052c1b9f..f5c85c9c 100644 --- a/src/modules/im/src/model/profile/profileinfo.h +++ b/src/modules/im/src/model/profile/profileinfo.h @@ -10,18 +10,17 @@ * See the Mulan PubL v2 for more details. */ +#include #include "iprofileinfo.h" #include "src/base/interface.h" #include "src/core/FriendId.h" -#include class Core; class QFile; class QPoint; class Profile; -class ProfileInfo : public QObject, public IProfileInfo -{ +class ProfileInfo : public QObject, public IProfileInfo { Q_OBJECT public: ProfileInfo(Core* core, Profile* profile); @@ -67,5 +66,4 @@ class ProfileInfo : public QObject, public IProfileInfo signals: void logouted(); - }; diff --git a/src/modules/im/src/model/sessionchatlog.cpp b/src/modules/im/src/model/sessionchatlog.cpp index 22f944bf..c1c41d88 100644 --- a/src/modules/im/src/model/sessionchatlog.cpp +++ b/src/modules/im/src/model/sessionchatlog.cpp @@ -24,16 +24,15 @@ namespace { * between a Message and QDateTime in both directions */ struct MessageDateAdaptor { - static const QDateTime invalidDateTime; - MessageDateAdaptor(const std::pair &item) - : timestamp(item.second.getContentType() == - ChatLogItem::ContentType::message - ? item.second.getContentAsMessage().message.timestamp - : invalidDateTime) {} + static const QDateTime invalidDateTime; + MessageDateAdaptor(const std::pair& item) + : timestamp(item.second.getContentType() == ChatLogItem::ContentType::message + ? item.second.getContentAsMessage().message.timestamp + : invalidDateTime) {} - MessageDateAdaptor(const QDateTime ×tamp) : timestamp(timestamp) {} + MessageDateAdaptor(const QDateTime& timestamp) : timestamp(timestamp) {} - const QDateTime ×tamp; + const QDateTime& timestamp; }; const QDateTime MessageDateAdaptor::invalidDateTime; @@ -44,285 +43,267 @@ const QDateTime MessageDateAdaptor::invalidDateTime; * regular expression * @return Regular expression which finds the input */ -QRegularExpression getRegexpForPhrase(const QString &phrase, - FilterSearch filter) { - constexpr auto regexFlags = QRegularExpression::UseUnicodePropertiesOption; - constexpr auto caseInsensitiveFlags = - QRegularExpression::CaseInsensitiveOption; - - switch (filter) { - case FilterSearch::Register: - return QRegularExpression(QRegularExpression::escape(phrase), regexFlags); - case FilterSearch::WordsOnly: - return QRegularExpression( - SearchExtraFunctions::generateFilterWordsOnly(phrase), - caseInsensitiveFlags); - case FilterSearch::RegisterAndWordsOnly: - return QRegularExpression( - SearchExtraFunctions::generateFilterWordsOnly(phrase), regexFlags); - case FilterSearch::RegisterAndRegular: - return QRegularExpression(phrase, regexFlags); - case FilterSearch::Regular: - return QRegularExpression(phrase, caseInsensitiveFlags); - default: - return QRegularExpression(QRegularExpression::escape(phrase), - caseInsensitiveFlags); - } +QRegularExpression getRegexpForPhrase(const QString& phrase, FilterSearch filter) { + constexpr auto regexFlags = QRegularExpression::UseUnicodePropertiesOption; + constexpr auto caseInsensitiveFlags = QRegularExpression::CaseInsensitiveOption; + + switch (filter) { + case FilterSearch::Register: + return QRegularExpression(QRegularExpression::escape(phrase), regexFlags); + case FilterSearch::WordsOnly: + return QRegularExpression(SearchExtraFunctions::generateFilterWordsOnly(phrase), + caseInsensitiveFlags); + case FilterSearch::RegisterAndWordsOnly: + return QRegularExpression(SearchExtraFunctions::generateFilterWordsOnly(phrase), + regexFlags); + case FilterSearch::RegisterAndRegular: + return QRegularExpression(phrase, regexFlags); + case FilterSearch::Regular: + return QRegularExpression(phrase, caseInsensitiveFlags); + default: + return QRegularExpression(QRegularExpression::escape(phrase), caseInsensitiveFlags); + } } /** * @return True if the given status indicates no future updates will come in */ bool toxFileIsComplete(FileStatus status) { - switch (status) { - case FileStatus::INITIALIZING: - case FileStatus::PAUSED: - case FileStatus::TRANSMITTING: - return false; - case FileStatus::BROKEN: - case FileStatus::CANCELED: - case FileStatus::FINISHED: - default: - return true; - } + switch (status) { + case FileStatus::INITIALIZING: + case FileStatus::PAUSED: + case FileStatus::TRANSMITTING: + return false; + case FileStatus::BROKEN: + case FileStatus::CANCELED: + case FileStatus::FINISHED: + default: + return true; + } } -std::map::const_iterator -firstItemAfterDate(QDate date, const std::map &items) { +std::map::const_iterator firstItemAfterDate( + QDate date, const std::map& items) { #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) - return std::lower_bound( - items.begin(), items.end(), QDateTime(date.startOfDay()), + return std::lower_bound(items.begin(), items.end(), QDateTime(date.startOfDay()), #else - return std::lower_bound( - items.begin(), items.end(), QDateTime(date), + return std::lower_bound(items.begin(), items.end(), QDateTime(date), #endif - [](const MessageDateAdaptor &a, MessageDateAdaptor const &b) { - return a.timestamp.date() < b.timestamp.date(); - }); + [](const MessageDateAdaptor& a, MessageDateAdaptor const& b) { + return a.timestamp.date() < b.timestamp.date(); + }); } -} // namespace +} // namespace -SessionChatLog::SessionChatLog(const ICoreIdHandler &coreIdHandler) - : coreIdHandler(coreIdHandler) { - -} +SessionChatLog::SessionChatLog(const ICoreIdHandler& coreIdHandler) + : coreIdHandler(coreIdHandler) {} /** * @brief Alternate constructor that allows for an initial index to be set */ -SessionChatLog::SessionChatLog(ChatLogIdx initialIdx, - const ICoreIdHandler &coreIdHandler) - : coreIdHandler(coreIdHandler), nextIdx(initialIdx) {} +SessionChatLog::SessionChatLog(ChatLogIdx initialIdx, const ICoreIdHandler& coreIdHandler) + : coreIdHandler(coreIdHandler), nextIdx(initialIdx) {} -SessionChatLog::~SessionChatLog(){ - qDebug() << __func__; -} +SessionChatLog::~SessionChatLog() { qDebug() << __func__; } const ChatLogItem* SessionChatLog::at(ChatLogIdx idx) const { - auto it = items.find(idx); - if (it == items.end()) { - qWarning()<<"Unable to find ChatLogItem:" << idx.get(); - return nullptr; - } - return &(it->second); + auto it = items.find(idx); + if (it == items.end()) { + qWarning() << "Unable to find ChatLogItem:" << idx.get(); + return nullptr; + } + return &(it->second); } -SearchResult -SessionChatLog::searchForward(SearchPos startPos, const QString &phrase, - const ParameterSearch ¶meter) const { - if (startPos.logIdx >= getNextIdx()) { - SearchResult res; - res.found = false; - return res; - } +SearchResult SessionChatLog::searchForward(SearchPos startPos, const QString& phrase, + const ParameterSearch& parameter) const { + if (startPos.logIdx >= getNextIdx()) { + SearchResult res; + res.found = false; + return res; + } - auto currentPos = startPos; + auto currentPos = startPos; - auto regexp = getRegexpForPhrase(phrase, parameter.filter); + auto regexp = getRegexpForPhrase(phrase, parameter.filter); - for (auto it = items.find(currentPos.logIdx); it != items.end(); ++it) { - const auto &key = it->first; - const auto &item = it->second; + for (auto it = items.find(currentPos.logIdx); it != items.end(); ++it) { + const auto& key = it->first; + const auto& item = it->second; - if (item.getContentType() != ChatLogItem::ContentType::message) { - continue; - } + if (item.getContentType() != ChatLogItem::ContentType::message) { + continue; + } - const auto &content = item.getContentAsMessage(); + const auto& content = item.getContentAsMessage(); - auto match = regexp.globalMatch(content.message.content, 0); + auto match = regexp.globalMatch(content.message.content, 0); - auto numMatches = 0; - QRegularExpressionMatch lastMatch; - while (match.isValid() && numMatches <= currentPos.numMatches && - match.hasNext()) { - lastMatch = match.next(); - numMatches++; - } + auto numMatches = 0; + QRegularExpressionMatch lastMatch; + while (match.isValid() && numMatches <= currentPos.numMatches && match.hasNext()) { + lastMatch = match.next(); + numMatches++; + } - if (numMatches > currentPos.numMatches) { - SearchResult res; - res.found = true; - res.pos.logIdx = key; - res.pos.numMatches = numMatches; - res.start = lastMatch.capturedStart(); - res.len = lastMatch.capturedLength(); - return res; - } + if (numMatches > currentPos.numMatches) { + SearchResult res; + res.found = true; + res.pos.logIdx = key; + res.pos.numMatches = numMatches; + res.start = lastMatch.capturedStart(); + res.len = lastMatch.capturedLength(); + return res; + } - // After the first iteration we force this to 0 to search the whole - // message - currentPos.numMatches = 0; - } + // After the first iteration we force this to 0 to search the whole + // message + currentPos.numMatches = 0; + } - // We should have returned from the above loop if we had found anything - SearchResult ret; - ret.found = false; - return ret; + // We should have returned from the above loop if we had found anything + SearchResult ret; + ret.found = false; + return ret; } -SearchResult -SessionChatLog::searchBackward(SearchPos startPos, const QString &phrase, - const ParameterSearch ¶meter) const { - auto currentPos = startPos; - auto regexp = getRegexpForPhrase(phrase, parameter.filter); - auto startIt = items.find(currentPos.logIdx); - - // If we don't have it we'll start at the end - if (startIt == items.end()) { - if (items.empty()) { - SearchResult ret; - ret.found = false; - return ret; +SearchResult SessionChatLog::searchBackward(SearchPos startPos, const QString& phrase, + const ParameterSearch& parameter) const { + auto currentPos = startPos; + auto regexp = getRegexpForPhrase(phrase, parameter.filter); + auto startIt = items.find(currentPos.logIdx); + + // If we don't have it we'll start at the end + if (startIt == items.end()) { + if (items.empty()) { + SearchResult ret; + ret.found = false; + return ret; + } + startIt = std::prev(items.end()); + startPos.numMatches = 0; } - startIt = std::prev(items.end()); - startPos.numMatches = 0; - } - // Off by 1 due to reverse_iterator api - auto rStartIt = std::reverse_iterator(std::next(startIt)); - auto rEnd = std::reverse_iterator(items.begin()); + // Off by 1 due to reverse_iterator api + auto rStartIt = std::reverse_iterator(std::next(startIt)); + auto rEnd = std::reverse_iterator(items.begin()); - for (auto it = rStartIt; it != rEnd; ++it) { - const auto &key = it->first; - const auto &item = it->second; + for (auto it = rStartIt; it != rEnd; ++it) { + const auto& key = it->first; + const auto& item = it->second; - if (item.getContentType() != ChatLogItem::ContentType::message) { - continue; - } + if (item.getContentType() != ChatLogItem::ContentType::message) { + continue; + } - const auto &content = item.getContentAsMessage(); - auto match = regexp.globalMatch(content.message.content, 0); - - auto totalMatches = 0; - auto numMatchesBeforePos = 0; - QRegularExpressionMatch lastMatch; - while (match.isValid() && match.hasNext()) { - auto currentMatch = match.next(); - totalMatches++; - if (currentPos.numMatches == 0 || - currentPos.numMatches > numMatchesBeforePos) { - lastMatch = currentMatch; - numMatchesBeforePos++; - } - } + const auto& content = item.getContentAsMessage(); + auto match = regexp.globalMatch(content.message.content, 0); + + auto totalMatches = 0; + auto numMatchesBeforePos = 0; + QRegularExpressionMatch lastMatch; + while (match.isValid() && match.hasNext()) { + auto currentMatch = match.next(); + totalMatches++; + if (currentPos.numMatches == 0 || currentPos.numMatches > numMatchesBeforePos) { + lastMatch = currentMatch; + numMatchesBeforePos++; + } + } - if ((numMatchesBeforePos < currentPos.numMatches || - currentPos.numMatches == 0) && - numMatchesBeforePos > 0) { - SearchResult res; - res.found = true; - res.pos.logIdx = key; - res.pos.numMatches = numMatchesBeforePos; - res.start = lastMatch.capturedStart(); - res.len = lastMatch.capturedLength(); - return res; - } + if ((numMatchesBeforePos < currentPos.numMatches || currentPos.numMatches == 0) && + numMatchesBeforePos > 0) { + SearchResult res; + res.found = true; + res.pos.logIdx = key; + res.pos.numMatches = numMatchesBeforePos; + res.start = lastMatch.capturedStart(); + res.len = lastMatch.capturedLength(); + return res; + } - // After the first iteration we force this to 0 to search the whole - // message - currentPos.numMatches = 0; - } + // After the first iteration we force this to 0 to search the whole + // message + currentPos.numMatches = 0; + } - // We should have returned from the above loop if we had found anything - SearchResult ret; - ret.found = false; - return ret; + // We should have returned from the above loop if we had found anything + SearchResult ret; + ret.found = false; + return ret; } ChatLogIdx SessionChatLog::getFirstIdx() const { - if (items.empty()) { - return nextIdx; - } + if (items.empty()) { + return nextIdx; + } - return items.begin()->first; + return items.begin()->first; } ChatLogIdx SessionChatLog::getNextIdx() const { return nextIdx; } -std::vector -SessionChatLog::getDateIdxs(const QDate &startDate, size_t maxDates) const { - std::vector ret; - auto dateIt = startDate; +std::vector SessionChatLog::getDateIdxs(const QDate& startDate, + size_t maxDates) const { + std::vector ret; + auto dateIt = startDate; - while (true) { - auto it = firstItemAfterDate(dateIt, items); + while (true) { + auto it = firstItemAfterDate(dateIt, items); - if (it == items.end()) { - break; - } + if (it == items.end()) { + break; + } - DateChatLogIdxPair pair; - pair.date = dateIt; - pair.idx = it->first; + DateChatLogIdxPair pair; + pair.date = dateIt; + pair.idx = it->first; - ret.push_back(std::move(pair)); + ret.push_back(std::move(pair)); - dateIt = dateIt.addDays(1); - if (startDate.daysTo(dateIt) > maxDates && maxDates != 0) { - break; + dateIt = dateIt.addDays(1); + if (startDate.daysTo(dateIt) > maxDates && maxDates != 0) { + break; + } } - } - return ret; + return ret; } void SessionChatLog::insertCompleteMessageAtIdx(ChatLogIdx idx, - const FriendId &sender, - const QString &senderName, - const ChatLogMessage &message) { - auto item = ChatLogItem(sender, senderName, message); - assert(message.state == MessageState::complete); - items.emplace(idx, std::move(item)); + const FriendId& sender, + const QString& senderName, + const ChatLogMessage& message) { + auto item = ChatLogItem(sender, senderName, message); + assert(message.state == MessageState::complete); + items.emplace(idx, std::move(item)); } -void SessionChatLog::insertIncompleteMessageAtIdx( - ChatLogIdx idx, const FriendId &sender, const QString &senderName, - const ChatLogMessage &message, DispatchedMessageId dispatchId) { - - auto item = ChatLogItem(sender,senderName, message); - assert(message.state == MessageState::pending); +void SessionChatLog::insertIncompleteMessageAtIdx(ChatLogIdx idx, const FriendId& sender, + const QString& senderName, + const ChatLogMessage& message, + DispatchedMessageId dispatchId) { + auto item = ChatLogItem(sender, senderName, message); + assert(message.state == MessageState::pending); - items.emplace(idx, std::move(item)); - outgoingMessages.insert(dispatchId, idx); + items.emplace(idx, std::move(item)); + outgoingMessages.insert(dispatchId, idx); } void SessionChatLog::insertBrokenMessageAtIdx(ChatLogIdx idx, - const FriendId &sender, - const QString &senderName, - const ChatLogMessage &message) { - auto item = ChatLogItem(sender, senderName, message); - assert(message.state == MessageState::broken); + const FriendId& sender, + const QString& senderName, + const ChatLogMessage& message) { + auto item = ChatLogItem(sender, senderName, message); + assert(message.state == MessageState::broken); - items.emplace(idx, std::move(item)); + items.emplace(idx, std::move(item)); } -void SessionChatLog::insertFileAtIdx(ChatLogIdx idx, const FriendId &sender, - const QString &senderName, - const ChatLogFile &file) { - - auto item = ChatLogItem(sender, senderName, file); - items.emplace(idx, std::move(item)); +void SessionChatLog::insertFileAtIdx(ChatLogIdx idx, const FriendId& sender, + const QString& senderName, const ChatLogFile& file) { + auto item = ChatLogItem(sender, senderName, file); + items.emplace(idx, std::move(item)); } /** @@ -330,24 +311,23 @@ void SessionChatLog::insertFileAtIdx(ChatLogIdx idx, const FriendId &sender, * @note Owner of SessionChatLog is in charge of attaching this to the * appropriate IMessageDispatcher */ -void SessionChatLog::onMessageReceived(const FriendId &sender, - const Message &message) { - qDebug()<<__func__<< "msgId:"<second.getContentAsMessage().state = MessageState::complete; - emit this->itemUpdated(messageIt->first); + qDebug() << __func__ << "dispatchedMessageId:" << id.get(); + + auto chatLogIdxIt = outgoingMessages.find(id); + if (chatLogIdxIt == outgoingMessages.end()) { + qWarning() << "Failed to find outgoing message"; + return; + } + + const auto& chatLogIdx = *chatLogIdxIt; + auto messageIt = items.find(chatLogIdx); + if (messageIt == items.end()) { + qWarning() << "Failed to look up message in chat log"; + return; + } + + messageIt->second.getContentAsMessage().state = MessageState::complete; + emit this->itemUpdated(messageIt->first); } -void SessionChatLog::onMessageReceipt(DispatchedMessageId id) -{ - qDebug() <<__func__<< "dispatchedMessageId:" << id.get(); +void SessionChatLog::onMessageReceipt(DispatchedMessageId id) { + qDebug() << __func__ << "dispatchedMessageId:" << id.get(); auto chatLogIdxIt = outgoingMessages.find(id); if (chatLogIdxIt == outgoingMessages.end()) { - qWarning() << "Failed to find outgoing message"; - return; + qWarning() << "Failed to find outgoing message"; + return; } - const auto &chatLogIdx = *chatLogIdxIt; + const auto& chatLogIdx = *chatLogIdxIt; auto messageIt = items.find(chatLogIdx); if (messageIt == items.end()) { - qWarning() << "Failed to look up message in chat log"; - return; + qWarning() << "Failed to look up message in chat log"; + return; } messageIt->second.getContentAsMessage().state = MessageState::receipt; emit this->itemUpdated(messageIt->first); @@ -424,109 +403,103 @@ void SessionChatLog::onMessageReceipt(DispatchedMessageId id) * validation * @note This should be attached to any CoreFile signal that fits the signature */ -void SessionChatLog::onFileUpdated(const FriendId &friendId, const ToxFile &file) { - qDebug() <<__func__ <<"friendId:" <idx; + fileIt->file = file; + + items.at(messageIdx).getContentAsFile().file = file; } else { - senderName = FriendList::decideNickname(senderId, senderId.username); + // This may be a file unbroken message that we don't handle ATM + return; } - items.emplace(currentTransfer.idx, ChatLogItem(senderId, - senderName, - chatLogFile)); - messageIdx = currentTransfer.idx; - } else if (fileIt != currentFileTransfers.end()) { - messageIdx = fileIt->idx; - fileIt->file = file; - - items.at(messageIdx).getContentAsFile().file = file; - } else { - // This may be a file unbroken message that we don't handle ATM - return; - } - - if (toxFileIsComplete(file.status)) { - currentFileTransfers.erase(fileIt); - } - - qDebug() <<"file messageIdx"<< messageIdx.get(); - emit this->itemUpdated(messageIdx); + + if (toxFileIsComplete(file.status)) { + currentFileTransfers.erase(fileIt); + } + + qDebug() << "file messageIdx" << messageIdx.get(); + emit this->itemUpdated(messageIdx); } -void SessionChatLog::onFileCanceled(const FriendId &sender, const QString &fileId) -{ - qDebug() <<__func__<< fileId; +void SessionChatLog::onFileCanceled(const FriendId& sender, const QString& fileId) { + qDebug() << __func__ << fileId; ChatLogIdx messageIdx; - if(currentFileTransfers.empty()){ - //db - for(auto &item : items){ - if(item.second.getContentType() == ChatLogItem:: ContentType::fileTransfer){ - auto f = item.second.getContentAsFile(); - if(f.file.fileId == fileId){ - messageIdx = item.first; + if (currentFileTransfers.empty()) { + // db + for (auto& item : items) { + if (item.second.getContentType() == ChatLogItem::ContentType::fileTransfer) { + auto f = item.second.getContentAsFile(); + if (f.file.fileId == fileId) { + messageIdx = item.first; break; - } - } - } - }else{ - //cache + } + } + } + } else { + // cache auto fileIt = std::find_if(currentFileTransfers.begin(), currentFileTransfers.end(), - [&](const CurrentFileTransfer &transfer) { - return transfer.file.fileId == fileId; - }); + [&](const CurrentFileTransfer& transfer) { + return transfer.file.fileId == fileId; + }); if (fileIt != currentFileTransfers.end()) { - messageIdx = fileIt->idx; + messageIdx = fileIt->idx; } } - //Update status to canceled - qDebug() <<"messageIdx" << messageIdx.get(); + // Update status to canceled + qDebug() << "messageIdx" << messageIdx.get(); items.at(messageIdx).getContentAsFile().file.status = FileStatus::CANCELED; emit this->itemUpdated(messageIdx); } -void SessionChatLog::onFileTransferRemotePausedUnpaused(const FriendId &sender, - const ToxFile &file, +void SessionChatLog::onFileTransferRemotePausedUnpaused(const FriendId& sender, + const ToxFile& file, bool /*paused*/) { - onFileUpdated(sender, file); + onFileUpdated(sender, file); } -void SessionChatLog::onFileTransferBrokenUnbroken(const FriendId &sender, - const ToxFile &file, +void SessionChatLog::onFileTransferBrokenUnbroken(const FriendId& sender, + const ToxFile& file, bool /*broken*/) { onFileUpdated(sender, file); } -ChatLogIdx SessionChatLog::getNextIdx(MsgId msgId) -{ +ChatLogIdx SessionChatLog::getNextIdx(MsgId msgId) { assert(!msgId.isEmpty()); auto idx = id2IdxMap.value(msgId, ChatLogIdx(-1)); - if(idx.get() == -1){ + if (idx.get() == -1) { idx = nextIdx++; id2IdxMap.insert(msgId, idx); } - qDebug()<<"make next msgId:"<< msgId<< " idx:" << idx.get(); + qDebug() << "make next msgId:" << msgId << " idx:" << idx.get(); return idx; } diff --git a/src/modules/im/src/model/sessionchatlog.h b/src/modules/im/src/model/sessionchatlog.h index 4e30fb85..c6da3345 100644 --- a/src/modules/im/src/model/sessionchatlog.h +++ b/src/modules/im/src/model/sessionchatlog.h @@ -21,9 +21,7 @@ struct SessionChatLogMetadata; - -class SessionChatLog : public IChatLog -{ +class SessionChatLog : public IChatLog { Q_OBJECT public: SessionChatLog(const ICoreIdHandler& coreIdHandler); @@ -37,31 +35,35 @@ class SessionChatLog : public IChatLog const ParameterSearch& parameter) const override; ChatLogIdx getFirstIdx() const override; ChatLogIdx getNextIdx() const override; - std::vector getDateIdxs(const QDate& startDate, size_t maxDates) const override; - - void insertCompleteMessageAtIdx(ChatLogIdx idx, const FriendId& sender, const QString& senderName, - const ChatLogMessage& message); - void insertIncompleteMessageAtIdx(ChatLogIdx idx, const FriendId& sender, const QString& senderName, - const ChatLogMessage& message, DispatchedMessageId dispatchId); + std::vector getDateIdxs(const QDate& startDate, + size_t maxDates) const override; + + void insertCompleteMessageAtIdx(ChatLogIdx idx, const FriendId& sender, + const QString& senderName, const ChatLogMessage& message); + void insertIncompleteMessageAtIdx(ChatLogIdx idx, const FriendId& sender, + const QString& senderName, const ChatLogMessage& message, + DispatchedMessageId dispatchId); void insertBrokenMessageAtIdx(ChatLogIdx idx, const FriendId& sender, const QString& senderName, const ChatLogMessage& message); - void insertFileAtIdx(ChatLogIdx idx, const FriendId& sender, const QString& senderName, const ChatLogFile& file); + void insertFileAtIdx(ChatLogIdx idx, const FriendId& sender, const QString& senderName, + const ChatLogFile& file); public slots: void onMessageReceived(const FriendId& sender, const Message& message); - //消息发送 + // 消息发送 void onMessageSent(DispatchedMessageId id, const Message& message); - //消息发送成功 + // 消息发送成功 void onMessageComplete(DispatchedMessageId id); - //消息接收 + // 消息接收 void onMessageReceipt(DispatchedMessageId id); void onFileUpdated(const FriendId& sender, const ToxFile& file); void onFileCanceled(const FriendId& sender, const QString& fileId); - void onFileTransferRemotePausedUnpaused(const FriendId& sender, const ToxFile& file, bool paused); + void onFileTransferRemotePausedUnpaused(const FriendId& sender, const ToxFile& file, + bool paused); void onFileTransferBrokenUnbroken(const FriendId& sender, const ToxFile& file, bool broken); - inline ChatLogIdx getNextIdx(MsgId msgId); + ChatLogIdx getNextIdx(MsgId msgId); private: const ICoreIdHandler& coreIdHandler; @@ -72,8 +74,7 @@ public slots: QMap outgoingMessages; std::map items; - struct CurrentFileTransfer - { + struct CurrentFileTransfer { ChatLogIdx idx; ToxFile file; }; @@ -84,9 +85,6 @@ public slots: * in order to find our existing transfers */ std::vector currentFileTransfers; - - - }; #endif /*SESSION_CHAT_LOG_H*/ diff --git a/src/modules/im/src/model/status.cpp b/src/modules/im/src/model/status.cpp index 8c0dcd8c..db4b246f 100644 --- a/src/modules/im/src/model/status.cpp +++ b/src/modules/im/src/model/status.cpp @@ -12,18 +12,16 @@ #include -#include -#include #include #include +#include +#include #include -namespace Status -{ - QString getTitle(Status status) - { - switch (status) { +namespace Status { +QString getTitle(Status status) { + switch (status) { case Status::Online: return QObject::tr("online", "contact status"); case Status::Away: @@ -34,15 +32,14 @@ namespace Status return QObject::tr("offline", "contact status"); case Status::Blocked: return QObject::tr("blocked", "contact status"); - } - -// assert(false); - return QStringLiteral(""); } - QString getAssetSuffix(Status status) - { - switch (status) { + // assert(false); + return QStringLiteral(""); +} + +QString getAssetSuffix(Status status) { + switch (status) { case Status::Online: return "online"; case Status::Away: @@ -53,24 +50,20 @@ namespace Status return "offline"; case Status::Blocked: return "blocked"; - } - assert(false); - return QStringLiteral(""); } + assert(false); + return QStringLiteral(""); +} - QString getIconPath(Status status, bool event) - { - const QString eventSuffix = event ? QStringLiteral("_notification") : QString(); - const QString statusSuffix = getAssetSuffix(status); - if (status == Status::Blocked) { - return ":/img/status/" + statusSuffix + ".svg"; - } else { - return ":/img/status/" + statusSuffix + eventSuffix + ".svg"; - } +QString getIconPath(Status status, bool event) { + const QString eventSuffix = event ? QStringLiteral("_notification") : QString(); + const QString statusSuffix = getAssetSuffix(status); + if (status == Status::Blocked) { + return ":/img/status/" + statusSuffix + ".svg"; + } else { + return ":/img/status/" + statusSuffix + eventSuffix + ".svg"; } +} - bool isOnline(Status status) - { - return status != Status::Offline && status != Status::Blocked; - } -} // namespace Status +bool isOnline(Status status) { return status != Status::Offline && status != Status::Blocked; } +} // namespace Status diff --git a/src/modules/im/src/model/status.h b/src/modules/im/src/model/status.h index efa33bbf..7eee6da2 100644 --- a/src/modules/im/src/model/status.h +++ b/src/modules/im/src/model/status.h @@ -10,36 +10,23 @@ * See the Mulan PubL v2 for more details. */ -#include #include +#include #ifndef STATUS_H #define STATUS_H -namespace Status -{ +namespace Status { -enum class AvatarSet { - None, - DefaultSet, - UserSet -}; +enum class AvatarSet { None, DefaultSet, UserSet }; - // Status::Status is weird, but Status is a fitting name for both the namespace and enum class.. - enum class Status - { - None=-1, - Online = 0, - Away, - Busy, - Offline, - Blocked - }; +// Status::Status is weird, but Status is a fitting name for both the namespace and enum class.. +enum class Status { None = -1, Online = 0, Away, Busy, Offline, Blocked }; - QString getIconPath(Status status, bool event = false); - QString getTitle(Status status); - QString getAssetSuffix(Status status); - bool isOnline(Status status); -} +QString getIconPath(Status status, bool event = false); +QString getTitle(Status status); +QString getAssetSuffix(Status status); +bool isOnline(Status status); +} // namespace Status -#endif // STATUS_H +#endif // STATUS_H diff --git a/src/modules/im/src/model/toxclientstandards.h b/src/modules/im/src/model/toxclientstandards.h index bd1319a6..82d64e27 100644 --- a/src/modules/im/src/model/toxclientstandards.h +++ b/src/modules/im/src/model/toxclientstandards.h @@ -15,14 +15,10 @@ #include -namespace ToxClientStandards -{ - // From TCS 2.2.4, max valid avatar size is 64KiB - constexpr static uint64_t MaxAvatarSize = 64 * 1024; - constexpr bool IsValidAvatarSize(uint64_t fileSize) - { - return fileSize <= MaxAvatarSize; - } -} // ToxClientStandards +namespace ToxClientStandards { +// From TCS 2.2.4, max valid avatar size is 64KiB +constexpr static uint64_t MaxAvatarSize = 64 * 1024; +constexpr bool IsValidAvatarSize(uint64_t fileSize) { return fileSize <= MaxAvatarSize; } +} // namespace ToxClientStandards -#endif // TOXCLIENTSTANDARDS_H +#endif // TOXCLIENTSTANDARDS_H diff --git a/src/modules/im/src/nexus.cpp b/src/modules/im/src/nexus.cpp index 1e451aa3..e466ed34 100644 --- a/src/modules/im/src/nexus.cpp +++ b/src/modules/im/src/nexus.cpp @@ -11,6 +11,17 @@ */ #include "nexus.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Bus.h" +#include "application.h" #include "base/OkSettings.h" #include "lib/settings/translator.h" #include "persistence/settings.h" @@ -22,16 +33,6 @@ #include "src/widget/widget.h" #include "video/camerasource.h" #include "widget/gui.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - #ifdef Q_OS_MAC #include @@ -47,14 +48,9 @@ * and forwarding signals appropriately to the right objects, * it is in charge of starting the GUI and the Core. */ +static Nexus* nexus{nullptr}; -Q_DECLARE_OPAQUE_POINTER(ToxAV *) - -static Nexus *nexus{nullptr}; - -Nexus::Nexus(QObject *parent) - : stared(false), profile{nullptr}, m_widget{nullptr} { - +Nexus::Nexus(QObject* parent) : stared(false), profile{nullptr}, m_widget{nullptr} { qDebug() << __func__; Q_INIT_RESOURCE(res); @@ -62,103 +58,99 @@ Nexus::Nexus(QObject *parent) Q_INIT_RESOURCE(smileys); Q_INIT_RESOURCE(IM); - auto &settings = Settings::getInstance(); + auto& settings = Settings::getInstance(); audioControl = std::unique_ptr(Audio::makeAudio(settings)); + // Create GUI + m_widget = new Widget(*audioControl); - - -// connect(this, &Nexus::destroyProfile, this, &Nexus::do_logout); + // connect(this, &Nexus::destroyProfile, this, &Nexus::do_logout); } Nexus::~Nexus() { - qDebug() << __func__; - if (m_widget) - m_widget->deleteLater(); + qDebug() << __func__; + if (m_widget) m_widget->deleteLater(); - delete profile; - profile = nullptr; - emit saveGlobal(); + delete profile; + profile = nullptr; + emit saveGlobal(); #ifdef Q_OS_MAC - delete globalMenuBar; + delete globalMenuBar; #endif } -void Nexus::init(Profile *p) { - profile = p; - assert(profile); +void Nexus::init(Profile* p) { + profile = p; + assert(profile); } -void Nexus::onSave(SavedInfo &savedInfo) { - -// if (settings->getShowSystemTray() && settings->getCloseToTray()) { -// widget->close(); -// return; -// } -// if (autoAwayActive) { -// emit statusSet(Status::Status::Online); -// autoAwayActive = false; -// } +void Nexus::onSave(SavedInfo& savedInfo) { + // if (settings->getShowSystemTray() && settings->getCloseToTray()) { + // widget->close(); + // return; + // } + // if (autoAwayActive) { + // emit statusSet(Status::Status::Online); + // autoAwayActive = false; + // } settings->setWindowGeometry(savedInfo.windowGeometry); settings->saveGlobal(); m_widget->close(); - } - - /** - * @brief Sets up invariants and calls showLogin - * - * Hides the login screen and shows the GUI for the given profile. - * Will delete the current GUI, if it exists. - */ - void Nexus::start(ok::session::SignInInfo &signInInfo) { +} - qDebug() << __func__ <<"for user:" << signInInfo.username; +/** + * @brief Sets up invariants and calls showLogin + * + * Hides the login screen and shows the GUI for the given profile. + * Will delete the current GUI, if it exists. + */ +void Nexus::start(std::shared_ptr session) { + auto& signInInfo = session->getSignInInfo(); + qDebug() << __func__ << "for user:" << signInInfo.username; if (stared) { - qWarning("This module is already started."); - return; + qWarning("This module is already started."); + return; } QCommandLineParser parser; if (!Profile::exists(signInInfo.username)) { - profile = Profile::createProfile(signInInfo.username, &parser, signInInfo.password); + profile = Profile::createProfile(signInInfo.host, signInInfo.username, &parser, + signInInfo.password); } else { - profile = Profile::loadProfile(signInInfo.username, &parser, signInInfo.password); + profile = Profile::loadProfile(signInInfo.host, signInInfo.username, &parser, + signInInfo.password); } - assert(profile); if (!profile) { - qWarning() << tr("Can not create profile!"); - emit createProfileFailed(tr("Can not create profile!")); - return; + qWarning() << tr("Can not create profile!"); + emit createProfileFailed(tr("Can not create profile!")); + return; } qDebug() << "Starting up"; stared = true; - auto &s = ok::base::OkSettings::getInstance(); + auto& s = ok::base::OkSettings::getInstance(); QString locale = s.getTranslation(); qDebug() << "locale" << locale; // add_definitions(-D${PROJECT_NAME}_MODULE="${PROJECT_NAME}") settings::Translator::translate(OK_IM_MODULE, locale); - - // Setup the environment qRegisterMetaType("Status::Status"); - + qRegisterMetaType("uint8_t"); qRegisterMetaType("uint16_t"); qRegisterMetaType("uint32_t"); - qRegisterMetaType("const int16_t*"); + qRegisterMetaType("const int16_t*"); qRegisterMetaType("int32_t"); qRegisterMetaType("int64_t"); qRegisterMetaType("size_t"); qRegisterMetaType("QPixmap"); - qRegisterMetaType("Profile*"); - qRegisterMetaType("ToxAV*"); + qRegisterMetaType("Profile*"); qRegisterMetaType("ToxFile"); qRegisterMetaType("FileDirection"); qRegisterMetaType("FileStatus"); @@ -173,6 +165,17 @@ void Nexus::onSave(SavedInfo &savedInfo) { qApp->setQuitOnLastWindowClosed(false); + // Connections + connect(profile, &Profile::selfAvatarChanged, m_widget, &Widget::onSelfAvatarLoaded); + + connect(profile, &Profile::selfAvatarChanged, + [&](const QPixmap& pixmap) { emit updateAvatar(pixmap); }); + + connect(profile, &Profile::coreChanged, + [&](Core& core) { emit ok::Application::Instance() -> bus()->coreChanged(&core); }); + + profile->startCore(); + #ifdef Q_OS_MAC // TODO: still needed? globalMenuBar = new QMenuBar(0); @@ -185,38 +188,35 @@ void Nexus::onSave(SavedInfo &savedInfo) { fullscreenAction = viewMenu->addAction(QString()); fullscreenAction->setShortcut(QKeySequence::FullScreen); - connect(fullscreenAction, &QAction::triggered, this, - &Nexus::toggleFullscreen); + connect(fullscreenAction, &QAction::triggered, this, &Nexus::toggleFullscreen); minimizeAction = windowMenu->addAction(QString()); minimizeAction->setShortcut(Qt::CTRL + Qt::Key_M); connect(minimizeAction, &QAction::triggered, [this]() { - minimizeAction->setEnabled(false); - QApplication::focusWindow()->showMinimized(); + minimizeAction->setEnabled(false); + QApplication::focusWindow()->showMinimized(); }); windowMenu->addSeparator(); frontAction = windowMenu->addAction(QString()); connect(frontAction, &QAction::triggered, this, &Nexus::bringAllToFront); - QAction *quitAction = new QAction(globalMenuBar); + QAction* quitAction = new QAction(globalMenuBar); quitAction->setMenuRole(QAction::QuitRole); connect(quitAction, &QAction::triggered, qApp, &QApplication::quit); retranslateUi(); #endif - showMainGUI(); - } - - void Nexus::hide() { m_widget->hide(); } +} +void Nexus::hide() { m_widget->hide(); } - QString Nexus::name() { return Nexus::Name(); } +QString Nexus::name() { return Nexus::Name(); } - /** - * @brief Hides the main GUI, delete the profile, and shows the login screen - */ - int Nexus::showLogin(const QString &profileName) { +/** + * @brief Hides the main GUI, delete the profile, and shows the login screen + */ +int Nexus::showLogin(const QString& profileName) { // delete widget; // widget = nullptr; @@ -239,19 +239,17 @@ void Nexus::onSave(SavedInfo &savedInfo) { // } // disconnect(this, &Nexus::currentProfileChanged, this, // &Nexus::bootstrapWithProfile); return returnval; - return -1; - } - - void Nexus::do_logout(const QString &profileName) - { - Settings::getInstance().saveGlobal(); - profile->stopCore(); - delete profile; - profile = nullptr; + return -1; +} - } +void Nexus::do_logout(const QString& profileName) { + Settings::getInstance().saveGlobal(); + profile->stopCore(); + delete profile; + profile = nullptr; +} - void Nexus::bootstrapWithProfile(Profile * p) { +void Nexus::bootstrapWithProfile(Profile* p) { // kriby: This is a hack until a proper controller is written // // Q_INIT_RESOURCE(res); @@ -276,47 +274,44 @@ void Nexus::onSave(SavedInfo &savedInfo) { // profile->getCore()->getAv()->setAudio(*audioControl); // start(); // } - } +} - void Nexus::setSettings(Settings * settings) { +void Nexus::setSettings(Settings* settings) { if (this->settings) { - QObject::disconnect(this, &Nexus::saveGlobal, this->settings, - &Settings::saveGlobal); + QObject::disconnect(this, &Nexus::saveGlobal, this->settings, &Settings::saveGlobal); } this->settings = settings; if (this->settings) { - QObject::connect(this, &Nexus::saveGlobal, this->settings, - &Settings::saveGlobal); + QObject::connect(this, &Nexus::saveGlobal, this->settings, &Settings::saveGlobal); } - } +} // void Nexus::connectLoginScreen(const LoginScreen &loginScreen) { - // TODO(kriby): Move connect sequences to a controller class object instead - - // // Nexus -> LoginScreen - // QObject::connect(this, &Nexus::profileLoaded, &loginScreen, - // &LoginScreen::onProfileLoaded); QObject::connect(this, - // &Nexus::profileLoadFailed, &loginScreen, - // &LoginScreen::onProfileLoadFailed); - // // LoginScreen -> Nexus - // QObject::connect(&loginScreen, &LoginScreen::createNewProfile, this, - // &Nexus::onCreateNewProfile); QObject::connect(&loginScreen, - // &LoginScreen::loadProfile, this, &Nexus::onLoadProfile); - // // LoginScreen -> Settings - // QObject::connect(&loginScreen, &LoginScreen::autoLoginChanged, - // settings, &Settings::setAutoLogin); QObject::connect(&loginScreen, - // &LoginScreen::autoLoginChanged, settings, &Settings::saveGlobal); - // // Settings -> LoginScreen - // QObject::connect(settings, &Settings::autoLoginChanged, &loginScreen, - // &LoginScreen::onAutoLoginChanged); +// TODO(kriby): Move connect sequences to a controller class object instead + +// // Nexus -> LoginScreen +// QObject::connect(this, &Nexus::profileLoaded, &loginScreen, +// &LoginScreen::onProfileLoaded); QObject::connect(this, +// &Nexus::profileLoadFailed, &loginScreen, +// &LoginScreen::onProfileLoadFailed); +// // LoginScreen -> Nexus +// QObject::connect(&loginScreen, &LoginScreen::createNewProfile, this, +// &Nexus::onCreateNewProfile); QObject::connect(&loginScreen, +// &LoginScreen::loadProfile, this, &Nexus::onLoadProfile); +// // LoginScreen -> Settings +// QObject::connect(&loginScreen, &LoginScreen::autoLoginChanged, +// settings, &Settings::setAutoLogin); QObject::connect(&loginScreen, +// &LoginScreen::autoLoginChanged, settings, &Settings::saveGlobal); +// // Settings -> LoginScreen +// QObject::connect(settings, &Settings::autoLoginChanged, &loginScreen, +// &LoginScreen::onAutoLoginChanged); // } - void Nexus::showMainGUI() { +void Nexus::showMainGUI() { // TODO(kriby): Rewrite as view-model connect sequence only, add to a // controller class object assert(profile); - // Create GUI - m_widget = new Widget(*audioControl); + // Start GUI m_widget->init(); GUI::getInstance(); @@ -328,18 +323,17 @@ void Nexus::onSave(SavedInfo &savedInfo) { GUI::setEnabled(false); // Connections - connect(profile, &Profile::selfAvatarChanged, m_widget, - &Widget::onSelfAvatarLoaded); + connect(profile, &Profile::selfAvatarChanged, m_widget, &Widget::onSelfAvatarLoaded); connect(profile, &Profile::selfAvatarChanged, - [&](const QPixmap &pixmap) { - emit updateAvatar(pixmap); - }); + [&](const QPixmap& pixmap) { emit updateAvatar(pixmap); }); + + connect(profile, &Profile::coreChanged, [&](Core& core) { emit coreChanged(core); }); connect(profile, &Profile::coreChanged, m_widget, &Widget::onCoreChanged); - connect(profile, &Profile::failedToStart, m_widget, - &Widget::onFailedToStartCore, Qt::BlockingQueuedConnection); + connect(profile, &Profile::failedToStart, m_widget, &Widget::onFailedToStartCore, + Qt::BlockingQueuedConnection); connect(profile, &Profile::badProxy, m_widget, &Widget::onBadProxyCore, Qt::BlockingQueuedConnection); @@ -347,36 +341,34 @@ void Nexus::onSave(SavedInfo &savedInfo) { profile->startCore(); GUI::setEnabled(true); +} - } - - Module *Nexus::Create() { - Nexus &inst = getInstance(); - return (Module *)(&inst); - } +Module* Nexus::Create() { + Nexus& inst = getInstance(); + return (Module*)(&inst); +} - /** - * @brief Returns the singleton instance. - */ - Nexus &Nexus::getInstance() { - if (!nexus) - nexus = new Nexus; +/** + * @brief Returns the singleton instance. + */ +Nexus& Nexus::getInstance() { + if (!nexus) nexus = new Nexus; return *nexus; - } +} - void Nexus::destroy() { +void Nexus::destroy() { delete nexus; nexus = nullptr; - } +} - void Nexus::cleanup(){ - qDebug() <<__func__ << "..."; +void Nexus::cleanup() { + qDebug() << __func__ << "..."; // force save early even though destruction saves, because Windows OS will // close qTox before cleanup() is finished if logging out or shutting down, // once the top level window has exited, which occurs in ~Widget within // ~Nexus. Re-ordering Nexus destruction is not trivial. - auto &s = Settings::getInstance(); + auto& s = Settings::getInstance(); s.saveGlobal(); s.savePersonal(); s.sync(); @@ -385,201 +377,195 @@ void Nexus::onSave(SavedInfo &savedInfo) { CameraSource::destroyInstance(); Settings::destroyInstance(); - qDebug() <<__func__ << "."; - } + qDebug() << __func__ << "."; +} - /** - * @brief Get core instance. - * @return nullptr if not started, core instance otherwise. - */ - Core *Nexus::getCore() { - Nexus &nexus = getInstance(); - if (!nexus.profile) - return nullptr; +/** + * @brief Get core instance. + * @return nullptr if not started, core instance otherwise. + */ +Core* Nexus::getCore() { + Nexus& nexus = getInstance(); + if (!nexus.profile) return nullptr; return nexus.profile->getCore(); - } - - /** - * @brief Get current user profile. - * @return nullptr if not started, profile otherwise. - */ - Profile *Nexus::getProfile() { return getInstance().profile; } - - /** - * @brief Creates a new profile and replaces the current one. - * @param name New username - * @param pass New password - */ - void Nexus::onCreateNewProfile(const QString &name, const QString &pass) { - setProfile(Profile::createProfile(name, parser, pass)); - parser = nullptr; // only apply cmdline proxy settings once - } - - /** - * Loads an existing profile and replaces the current one. - */ - void Nexus::onLoadProfile(const QString &name, const QString &pass) { - setProfile(Profile::loadProfile(name, parser, pass)); - parser = nullptr; // only apply cmdline proxy settings once - } - /** - * Changes the loaded profile and notifies listeners. - * @param p - */ - void Nexus::setProfile(Profile * p) { +} + +/** + * @brief Get current user profile. + * @return nullptr if not started, profile otherwise. + */ +Profile* Nexus::getProfile() { return getInstance().profile; } + +/** + * @brief Creates a new profile and replaces the current one. + * @param name New username + * @param pass New password + */ +void Nexus::onCreateNewProfile(const QString& host, const QString& name, const QString& pass) { + setProfile(Profile::createProfile(host, name, parser, pass)); + parser = nullptr; // only apply cmdline proxy settings once +} + +/** + * Loads an existing profile and replaces the current one. + */ +void Nexus::onLoadProfile(const QString& host, const QString& name, const QString& pass) { + setProfile(Profile::loadProfile(host, name, parser, pass)); + parser = nullptr; // only apply cmdline proxy settings once +} +/** + * Changes the loaded profile and notifies listeners. + * @param p + */ +void Nexus::setProfile(Profile* p) { if (!p) { - emit profileLoadFailed(); - // Warnings are issued during respective createNew/load calls - return; + emit profileLoadFailed(); + // Warnings are issued during respective createNew/load calls + return; } else { - emit profileLoaded(); + emit profileLoaded(); } emit currentProfileChanged(p); - } +} - void Nexus::setParser(QCommandLineParser * parser) { this->parser = parser; } +void Nexus::setParser(QCommandLineParser* parser) { this->parser = parser; } - /** - * @brief Get desktop GUI widget. - * @return nullptr if not started, desktop widget otherwise. - */ - Widget *Nexus::getDesktopGUI() { return dynamic_cast(getInstance().widget()); } +/** + * @brief Get desktop GUI widget. + * @return nullptr if not started, desktop widget otherwise. + */ +Widget* Nexus::getDesktopGUI() { return dynamic_cast(getInstance().widget()); } - void Nexus::bootstrapWithProfileName(const QString &profileName) { +void Nexus::bootstrapWithProfileName(const QString& host, const QString& profileName) { qDebug() << "bootstrapWithProfileName" << profileName; - Profile *profile = nullptr; + Profile* profile = nullptr; - Settings &settings = Settings::getInstance(); + Settings& settings = Settings::getInstance(); setSettings(&settings); // QString profileName = settings.getCurrentProfile(); QCommandLineParser parser; if (Profile::exists(profileName)) { - profile = Profile::loadProfile(profileName, &parser); + profile = Profile::loadProfile(host, profileName, &parser); } if (profile) { - bootstrapWithProfile(profile); + bootstrapWithProfile(profile); } - } +} - QString Nexus::Name() { return OK_IM_MODULE; } - QWidget *Nexus::widget() { return m_widget->getInstance(); } +QString Nexus::Name() { return OK_IM_MODULE; } +QWidget* Nexus::widget() { return m_widget->getInstance(); } #ifdef Q_OS_MAC - void Nexus::retranslateUi() { +void Nexus::retranslateUi() { viewMenu->menuAction()->setText(tr("View", "OS X Menu bar")); windowMenu->menuAction()->setText(tr("Window", "OS X Menu bar")); minimizeAction->setText(tr("Minimize", "OS X Menu bar")); frontAction->setText((tr("Bring All to Front", "OS X Menu bar"))); - } +} - void Nexus::onWindowStateChanged(Qt::WindowStates state) { +void Nexus::onWindowStateChanged(Qt::WindowStates state) { minimizeAction->setEnabled(QApplication::activeWindow() != nullptr); - if (QApplication::activeWindow() != nullptr && - sender() == QApplication::activeWindow()) { - if (state & Qt::WindowFullScreen) - minimizeAction->setEnabled(false); + if (QApplication::activeWindow() != nullptr && sender() == QApplication::activeWindow()) { + if (state & Qt::WindowFullScreen) minimizeAction->setEnabled(false); - if (state & Qt::WindowFullScreen) - fullscreenAction->setText(tr("Exit Fullscreen")); - else - fullscreenAction->setText(tr("Enter Fullscreen")); + if (state & Qt::WindowFullScreen) + fullscreenAction->setText(tr("Exit Fullscreen")); + else + fullscreenAction->setText(tr("Enter Fullscreen")); - updateWindows(); + updateWindows(); } updateWindowsStates(); - } +} - void Nexus::updateWindows() { updateWindowsArg(nullptr); } +void Nexus::updateWindows() { updateWindowsArg(nullptr); } - void Nexus::updateWindowsArg(QWindow * closedWindow) { +void Nexus::updateWindowsArg(QWindow* closedWindow) { QWindowList windowList = QApplication::topLevelWindows(); delete windowActions; windowActions = new QActionGroup(this); windowMenu->addSeparator(); - QAction *dockLast; + QAction* dockLast; if (!dockMenu->actions().isEmpty()) - dockLast = dockMenu->actions().first(); + dockLast = dockMenu->actions().first(); else - dockLast = nullptr; + dockLast = nullptr; - QWindow *activeWindow; + QWindow* activeWindow; if (QApplication::activeWindow()) - activeWindow = QApplication::activeWindow()->windowHandle(); + activeWindow = QApplication::activeWindow()->windowHandle(); else - activeWindow = nullptr; + activeWindow = nullptr; for (int i = 0; i < windowList.size(); ++i) { - if (closedWindow == windowList[i]) - continue; - - QAction *action = windowActions->addAction(windowList[i]->title()); - action->setCheckable(true); - action->setChecked(windowList[i] == activeWindow); - connect(action, &QAction::triggered, - [&] { onOpenWindow(windowList[i]); }); - windowMenu->addAction(action); - dockMenu->insertAction(dockLast, action); + if (closedWindow == windowList[i]) continue; + + + QAction* action = windowActions->addAction(windowList[i]->title()); + action->setCheckable(true); + action->setChecked(windowList[i] == activeWindow); + connect(action, &QAction::triggered, [&] { onOpenWindow(windowList[i]); }); + windowMenu->addAction(action); + dockMenu->insertAction(dockLast, action); + } - if (dockLast && !dockLast->isSeparator()) - dockMenu->insertSeparator(dockLast); - } + if (dockLast && !dockLast->isSeparator()) dockMenu->insertSeparator(dockLast); +} - void Nexus::updateWindowsClosed() { - updateWindowsArg(static_cast(sender())->windowHandle()); - } +void Nexus::updateWindowsClosed() { + updateWindowsArg(static_cast(sender())->windowHandle()); +} - void Nexus::updateWindowsStates() { +void Nexus::updateWindowsStates() { bool exists = false; QWindowList windowList = QApplication::topLevelWindows(); - for (QWindow *window : windowList) { - if (!(window->windowState() & Qt::WindowMinimized)) { - exists = true; - break; - } + for (QWindow* window : windowList) { + if (!(window->windowState() & Qt::WindowMinimized)) { + exists = true; + break; + } } frontAction->setEnabled(exists); - } +} - void Nexus::onOpenWindow(QObject * object) { - QWindow *window = static_cast(object); +void Nexus::onOpenWindow(QObject* object) { + QWindow* window = static_cast(object); - if (window->windowState() & QWindow::Minimized) - window->showNormal(); + if (window->windowState() & QWindow::Minimized) window->showNormal(); window->raise(); window->requestActivate(); - } +} - void Nexus::toggleFullscreen() { - QWidget *window = QApplication::activeWindow(); +void Nexus::toggleFullscreen() { + QWidget* window = QApplication::activeWindow(); if (window->isFullScreen()) - window->showNormal(); + window->showNormal(); else - window->showFullScreen(); - } + window->showFullScreen(); +} - void Nexus::bringAllToFront() { +void Nexus::bringAllToFront() { QWindowList windowList = QApplication::topLevelWindows(); - QWindow *focused = QApplication::focusWindow(); + QWindow* focused = QApplication::focusWindow(); - for (QWindow *window : windowList) - window->raise(); + for (QWindow* window : windowList) window->raise(); focused->raise(); - } +} #endif diff --git a/src/modules/im/src/nexus.h b/src/modules/im/src/nexus.h index 3b31b521..efe3e302 100644 --- a/src/modules/im/src/nexus.h +++ b/src/modules/im/src/nexus.h @@ -21,14 +21,8 @@ class Widget; class Profile; class Settings; -// class LoginScreen; class Core; class QCommandLineParser; -// -//#include "UI/window/login/src/LoginWindow.h" -//#include "UI/window/main/MainWindow.h" - -//using LoginScreen = UI::LoginWindow; #ifdef Q_OS_MAC class QMenuBar; @@ -40,100 +34,96 @@ class QSignalMapper; #endif class Nexus : public QObject, public Module { - Q_OBJECT + Q_OBJECT public: - /** * Module */ static QString Name(); - static Module *Create(); - - - void showMainGUI(); - void setSettings(Settings *settings); - void setParser(QCommandLineParser *parser); + static Module* Create(); - static Nexus &getInstance(); - static Core *getCore(); - static Profile *getProfile(); - static Widget *getDesktopGUI(); + void showMainGUI(); + void setSettings(Settings* settings); + void setParser(QCommandLineParser* parser); + static Nexus& getInstance(); + static Core* getCore(); + static Profile* getProfile(); + static Widget* getDesktopGUI(); - virtual void destroy() override; + virtual void destroy() override; - QString name() override; - QWidget* widget() override; - void init(Profile *) override; - void start(ok::session::SignInInfo &signInInfo) override; - bool isStarted() override { return stared; } - void hide() override; - void onSave(SavedInfo& ) override; - void cleanup() override; + QString name() override; + QWidget* widget() override; + void init(Profile*) override; + void start(std::shared_ptr session) override; + bool isStarted() override { return stared; } + void hide() override; + void onSave(SavedInfo&) override; + void cleanup() override; - IAudioControl* audio()const { - return audioControl.get(); - } + IAudioControl* audio() const { return audioControl.get(); } #ifdef Q_OS_MAC public: - QMenuBar *globalMenuBar; - QMenu *viewMenu; - QMenu *windowMenu; - QAction *minimizeAction; - QAction *fullscreenAction; - QAction *frontAction; - QMenu *dockMenu; + QMenuBar* globalMenuBar; + QMenu* viewMenu; + QMenu* windowMenu; + QAction* minimizeAction; + QAction* fullscreenAction; + QAction* frontAction; + QMenu* dockMenu; public slots: - void retranslateUi(); - void onWindowStateChanged(Qt::WindowStates state); - void updateWindows(); - void updateWindowsClosed(); - void updateWindowsStates(); - void onOpenWindow(QObject *object); - void toggleFullscreen(); - void bringAllToFront(); + void retranslateUi(); + void onWindowStateChanged(Qt::WindowStates state); + void updateWindows(); + void updateWindowsClosed(); + void updateWindowsStates(); + void onOpenWindow(QObject* object); + void toggleFullscreen(); + void bringAllToFront(); private: - void updateWindowsArg(QWindow *closedWindow); + void updateWindowsArg(QWindow* closedWindow); - QActionGroup *windowActions = nullptr; + QActionGroup* windowActions = nullptr; #endif signals: - void currentProfileChanged(Profile *Profile); - void profileLoaded(); - void profileLoadFailed(); - void saveGlobal(); - void updateAvatar(const QPixmap &pixmap); - void createProfileFailed(QString msg); - void destroyProfile(const QString &profile); - void exit(const QString &profile); + void currentProfileChanged(Profile* Profile); + void profileLoaded(); + void profileLoadFailed(); + void coreChanged(Core&); + void saveGlobal(); + void updateAvatar(const QPixmap& pixmap); + void createProfileFailed(QString msg); + void destroyProfile(const QString& profile); + void exit(const QString& profile); public slots: - void onCreateNewProfile(const QString &name, const QString &pass); - void onLoadProfile(const QString &name, const QString &pass); - void bootstrapWithProfile(Profile *p); - void bootstrapWithProfileName(const QString &p); - int showLogin(const QString &profileName = QString()); - void do_logout(const QString & profile); + void onCreateNewProfile(const QString& host, const QString& name, const QString& pass); + void onLoadProfile(const QString& host, const QString& name, const QString& pass); + void bootstrapWithProfile(Profile* p); + void bootstrapWithProfileName(const QString& host, const QString& p); + int showLogin(const QString& profileName = QString()); + void do_logout(const QString& profile); private: - explicit Nexus(QObject *parent = nullptr); - ~Nexus(); -// void connectLoginScreen(const LoginScreen &loginScreen); - void setProfile(Profile *p); + explicit Nexus(QObject* parent = nullptr); + ~Nexus(); + // void connectLoginScreen(const LoginScreen &loginScreen); + void setProfile(Profile* p); private: - bool stared; + bool stared; - Profile *profile; + Profile* profile; - Settings *settings; - QPointer m_widget; //某些异常情况下widget会被提前释放 - std::unique_ptr audioControl; - QCommandLineParser *parser = nullptr; + Settings* settings; + QPointer m_widget; // 某些异常情况下widget会被提前释放 + std::unique_ptr audioControl; + QCommandLineParser* parser = nullptr; }; -#endif // NEXUS_H +#endif // NEXUS_H diff --git a/src/modules/im/src/persistence/db/rawdatabase.cpp b/src/modules/im/src/persistence/db/rawdatabase.cpp index 386c27e6..3e7b1a9c 100644 --- a/src/modules/im/src/persistence/db/rawdatabase.cpp +++ b/src/modules/im/src/persistence/db/rawdatabase.cpp @@ -12,13 +12,12 @@ #include "rawdatabase.h" -#include #include #include #include #include #include - +#include /** * @class RawDatabase @@ -76,21 +75,20 @@ * Otherwise we will use toxencryptsave to derive a key and encrypt the database. */ RawDatabase::RawDatabase(const QString& path, const QString& password, const QByteArray& salt) - : workerThread{new QThread} - , path{path} - , currentSalt{salt} // we need the salt later if a new password should be set - , currentHexKey{deriveKey(password, salt)} - , sqlite{nullptr} -{ - qDebug() <<__func__ <<"path:" << path; + : workerThread{new QThread} + , path{path} + , currentSalt{salt} // we need the salt later if a new password should be set + , currentHexKey{deriveKey(password, salt)} + , sqlite{nullptr} { + qDebug() << __func__ << "path:" << path; workerThread->setObjectName("Database"); moveToThread(workerThread.get()); workerThread->start(); // first try with the new salt if (open(path, currentHexKey)) { - qWarning() << "Opened the db path" << path; - return; + qWarning() << "Opened the db path" << path; + return; } // avoid opening the same db twice @@ -103,17 +101,15 @@ RawDatabase::RawDatabase(const QString& path, const QString& password, const QBy upgrade = false; } - if (!open(path)) { - qFatal( "Failed to open database"); - } + if (!open(path)) { + qFatal("Failed to open database"); + } } -RawDatabase::~RawDatabase() -{ +RawDatabase::~RawDatabase() { close(); workerThread->exit(0); - while (workerThread->isRunning()) - workerThread->wait(50); + while (workerThread->isRunning()) workerThread->wait(50); } /** @@ -122,16 +118,13 @@ RawDatabase::~RawDatabase() * @param hexKey Hex representation of the key in string. * @return True if success, false otherwise. */ -bool RawDatabase::open(const QString& path, const QString& hexKey) -{ +bool RawDatabase::open(const QString& path, const QString& hexKey) { qDebug() << "open" << path; if (QThread::currentThread() != workerThread.get()) { bool ret; - QMetaObject::invokeMethod(this, "open", - Qt::BlockingQueuedConnection, - Q_RETURN_ARG(bool, ret), - Q_ARG(const QString&, path), + QMetaObject::invokeMethod(this, "open", Qt::BlockingQueuedConnection, + Q_RETURN_ARG(bool, ret), Q_ARG(const QString&, path), Q_ARG(const QString&, hexKey)); return ret; } @@ -143,19 +136,21 @@ bool RawDatabase::open(const QString& path, const QString& hexKey) } if (sqlite3_open_v2(path.toUtf8().data(), &sqlite, - SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX, nullptr) - != SQLITE_OK) { + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX, + nullptr) != SQLITE_OK) { qWarning() << "Failed to open database" << path << "with error:" << sqlite3_errmsg(sqlite); return false; } - if (sqlite3_create_function(sqlite, "regexp", 2, SQLITE_UTF8, nullptr, &RawDatabase::regexpInsensitive, nullptr, nullptr)) { + if (sqlite3_create_function(sqlite, "regexp", 2, SQLITE_UTF8, nullptr, + &RawDatabase::regexpInsensitive, nullptr, nullptr)) { qWarning() << "Failed to create function regexp"; close(); return false; } - if (sqlite3_create_function(sqlite, "regexpsensitive", 2, SQLITE_UTF8, nullptr, &RawDatabase::regexpSensitive, nullptr, nullptr)) { + if (sqlite3_create_function(sqlite, "regexpsensitive", 2, SQLITE_UTF8, nullptr, + &RawDatabase::regexpSensitive, nullptr, nullptr)) { qWarning() << "Failed to create function regexpsensitive"; close(); return false; @@ -164,14 +159,12 @@ bool RawDatabase::open(const QString& path, const QString& hexKey) return true; } -bool RawDatabase::testUsable() -{ +bool RawDatabase::testUsable() { // this will unfortunately log a warning if it fails, even though we may expect failure return execNow("SELECT count(*) FROM sqlite_master;"); } -bool RawDatabase::setKey(const QString& hexKey) -{ +bool RawDatabase::setKey(const QString& hexKey) { // setKey again to clear old bad cipher settings if (!execNow("PRAGMA key = \"x'" + hexKey + "'\"")) { qWarning() << "Failed to set encryption key"; @@ -180,8 +173,7 @@ bool RawDatabase::setKey(const QString& hexKey) return true; } -int RawDatabase::getUserVersion() -{ +int RawDatabase::getUserVersion() { int user_version; if (!execNow(RawDatabase::Query("PRAGMA user_version", [&](const QVector& row) { user_version = row[0].toLongLong(); @@ -195,8 +187,7 @@ int RawDatabase::getUserVersion() /** * @brief Close the database and free its associated resources. */ -void RawDatabase::close() -{ +void RawDatabase::close() { if (QThread::currentThread() != workerThread.get()) return (void)QMetaObject::invokeMethod(this, "close", Qt::BlockingQueuedConnection); @@ -213,8 +204,7 @@ void RawDatabase::close() * @brief Checks, that the database is open. * @return True if the database was opened successfully. */ -bool RawDatabase::isOpen() -{ +bool RawDatabase::isOpen() { // We don't need thread safety since only the ctor/dtor can write this pointer return sqlite != nullptr; } @@ -224,18 +214,14 @@ bool RawDatabase::isOpen() * @param statement Statement to execute. * @return Whether the transaction was successful. */ -bool RawDatabase::execNow(const QString& statement) -{ - return execNow(Query{statement}); -} +bool RawDatabase::execNow(const QString& statement) { return execNow(Query{statement}); } /** * @brief Executes a SQL transaction synchronously. * @param statement Statement to execute. * @return Whether the transaction was successful. */ -bool RawDatabase::execNow(const RawDatabase::Query& statement) -{ +bool RawDatabase::execNow(const RawDatabase::Query& statement) { return execNow(QVector{statement}); } @@ -244,8 +230,7 @@ bool RawDatabase::execNow(const RawDatabase::Query& statement) * @param statements List of statements to execute. * @return Whether the transaction was successful. */ -bool RawDatabase::execNow(const QVector& statements) -{ +bool RawDatabase::execNow(const QVector& statements) { if (!sqlite) { qWarning() << "Trying to startup, but the database is not open"; return false; @@ -266,8 +251,7 @@ bool RawDatabase::execNow(const QVector& statements) // We can't use blocking queued here, otherwise we might process future transactions // before returning, but we only want to wait until this transaction is done. QMetaObject::invokeMethod(this, "process"); - while (!done.load(std::memory_order_acquire)) - QThread::msleep(10); + while (!done.load(std::memory_order_acquire)) QThread::msleep(10); return success.load(std::memory_order_acquire); } @@ -276,18 +260,13 @@ bool RawDatabase::execNow(const QVector& statements) * @brief Executes a SQL transaction asynchronously. * @param statement Statement to execute. */ -void RawDatabase::execLater(const QString& statement) -{ - execLater(Query{statement}); -} +void RawDatabase::execLater(const QString& statement) { execLater(Query{statement}); } -void RawDatabase::execLater(const RawDatabase::Query& statement) -{ +void RawDatabase::execLater(const RawDatabase::Query& statement) { execLater(QVector{statement}); } -void RawDatabase::execLater(const QVector& statements) -{ +void RawDatabase::execLater(const QVector& statements) { if (!sqlite) { qWarning() << "Trying to startup, but the database is not open"; return; @@ -306,13 +285,11 @@ void RawDatabase::execLater(const QVector& statements) /** * @brief Waits until all the pending transactions are executed. */ -void RawDatabase::sync() -{ +void RawDatabase::sync() { QMetaObject::invokeMethod(this, "process", Qt::BlockingQueuedConnection); } -bool RawDatabase::commitDbSwap(const QString& hexKey) -{ +bool RawDatabase::commitDbSwap(const QString& hexKey) { // This is racy as hell, but nobody will race with us since we hold the profile lock // If we crash or die here, the rename should be atomic, so we can recover no matter // what @@ -334,8 +311,7 @@ bool RawDatabase::commitDbSwap(const QString& hexKey) * * @note Will process all transactions before renaming */ -bool RawDatabase::rename(const QString& newPath) -{ +bool RawDatabase::rename(const QString& newPath) { if (!sqlite) { qWarning() << "Trying to change the password, but the database is not open"; return false; @@ -350,15 +326,12 @@ bool RawDatabase::rename(const QString& newPath) process(); - if (path == newPath) - return true; + if (path == newPath) return true; - if (QFile::exists(newPath)) - return false; + if (QFile::exists(newPath)) return false; close(); - if (!QFile::rename(path, newPath)) - return false; + if (!QFile::rename(path, newPath)) return false; path = newPath; return open(path, currentHexKey); } @@ -368,8 +341,7 @@ bool RawDatabase::rename(const QString& newPath) * @note Will process all transactions before deletings. * @return True if success, false otherwise. */ -bool RawDatabase::remove() -{ +bool RawDatabase::remove() { if (!sqlite) { qWarning() << "Trying to remove the database, but it is not open"; return false; @@ -393,8 +365,7 @@ bool RawDatabase::remove() * @param salt Salt to improve password strength, must be TOX_PASS_SALT_LENGTH bytes * @return String representation of key */ -QString RawDatabase::deriveKey(const QString& password, const QByteArray& salt) -{ +QString RawDatabase::deriveKey(const QString& password, const QByteArray& salt) { return QString{}; } @@ -404,39 +375,34 @@ QString RawDatabase::deriveKey(const QString& password, const QByteArray& salt) * * @warning MUST only be called from the worker thread */ -void RawDatabase::process() -{ +void RawDatabase::process() { assert(QThread::currentThread() == workerThread.get()); - if (!sqlite) - return; + if (!sqlite) return; - forever - { + forever { // Fetch the next transaction Transaction trans; { QMutexLocker locker{&transactionsMutex}; - if (pendingTransactions.isEmpty()) - return; + if (pendingTransactions.isEmpty()) return; trans = pendingTransactions.dequeue(); } // In case we exit early, prepare to signal errors - if (trans.success != nullptr) - trans.success->store(false, std::memory_order_release); + if (trans.success != nullptr) trans.success->store(false, std::memory_order_release); // Add transaction commands if necessary -// if (trans.queries.size() > 1) { -// trans.queries.prepend({"BEGIN TRANSACTION;"}); -// trans.queries.append({"COMMIT;"}); -// } + // if (trans.queries.size() > 1) { + // trans.queries.prepend({"BEGIN TRANSACTION;"}); + // trans.queries.append({"COMMIT;"}); + // } // Compile queries for (Query& query : trans.queries) { assert(query.statements.isEmpty()); - qDebug() <<"execute sql:" << query.query; + qDebug() << "execute sql:" << query.query; // sqlite3_prepare_v2 only compiles one statement at a time in the query, // we need to loop over them all @@ -446,13 +412,14 @@ void RawDatabase::process() // Compile the next statement sqlite3_stmt* stmt; int r; - if ((r = sqlite3_prepare_v2(sqlite, compileTail, - query.query.size() - - static_cast(compileTail - query.query.data()), - &stmt, &compileTail)) - != SQLITE_OK) { + if ((r = sqlite3_prepare_v2( + sqlite, compileTail, + query.query.size() - + static_cast(compileTail - query.query.data()), + &stmt, &compileTail)) != SQLITE_OK) { qWarning() << "Failed to prepare statement:" << anonymizeQuery(query.query); - qWarning("The error code is %d errmsg is %s", sqlite3_errcode(sqlite), sqlite3_errmsg(sqlite)); + qWarning("The error code is %d errmsg is %s", sqlite3_errcode(sqlite), + sqlite3_errmsg(sqlite)); goto cleanupStatements; } query.statements += stmt; @@ -466,8 +433,8 @@ void RawDatabase::process() } for (int i = 0; i < nParams; ++i) { const QByteArray& blob = query.blobs[curParam + i]; - if (sqlite3_bind_blob(stmt, i + 1, blob.data(), blob.size(), SQLITE_STATIC) - != SQLITE_OK) { + if (sqlite3_bind_blob(stmt, i + 1, blob.data(), blob.size(), SQLITE_STATIC) != + SQLITE_OK) { qWarning() << "Failed to bind param" << curParam + i << "to query" << anonymizeQuery(query.query); goto cleanupStatements; @@ -476,7 +443,6 @@ void RawDatabase::process() curParam += nParams; } while (compileTail != query.query.data() + query.query.size()); - // Execute each statement of each query of our transaction for (sqlite3_stmt* stmt : query.statements) { int column_count = sqlite3_column_count(stmt); @@ -487,33 +453,31 @@ void RawDatabase::process() // Execute our row callback if (result == SQLITE_ROW && query.rowCallback) { QVector row; - for (int i = 0; i < column_count; ++i) - row += extractData(stmt, i); + for (int i = 0; i < column_count; ++i) row += extractData(stmt, i); query.rowCallback(row); } } while (result == SQLITE_ROW); - if (result == SQLITE_DONE) - continue; + if (result == SQLITE_DONE) continue; QString anonQuery = anonymizeQuery(query.query); switch (result) { - case SQLITE_ERROR: - qWarning() << "Error executing query" << anonQuery; - goto cleanupStatements; - case SQLITE_MISUSE: - qWarning() << "Misuse executing query" << anonQuery; - goto cleanupStatements; - case SQLITE_CONSTRAINT: - qWarning() << "Constraint error executing query" << anonQuery; - goto cleanupStatements; - case SQLITE_BUSY: - qWarning() << "Is busying executing query" << anonQuery; - goto cleanupStatements; - default: - qWarning() << "Unknown error" << result << "executing query" << anonQuery; - goto cleanupStatements; + case SQLITE_ERROR: + qWarning() << "Error executing query" << anonQuery; + goto cleanupStatements; + case SQLITE_MISUSE: + qWarning() << "Misuse executing query" << anonQuery; + goto cleanupStatements; + case SQLITE_CONSTRAINT: + qWarning() << "Constraint error executing query" << anonQuery; + goto cleanupStatements; + case SQLITE_BUSY: + qWarning() << "Is busying executing query" << anonQuery; + goto cleanupStatements; + default: + qWarning() << "Unknown error" << result << "executing query" << anonQuery; + goto cleanupStatements; } } @@ -521,20 +485,17 @@ void RawDatabase::process() query.insertCallback(RowId{sqlite3_last_insert_rowid(sqlite)}); } - if (trans.success != nullptr) - trans.success->store(true, std::memory_order_release); + if (trans.success != nullptr) trans.success->store(true, std::memory_order_release); // Free our statements cleanupStatements: for (Query& query : trans.queries) { - for (sqlite3_stmt* stmt : query.statements) - sqlite3_finalize(stmt); + for (sqlite3_stmt* stmt : query.statements) sqlite3_finalize(stmt); query.statements.clear(); } // Signal transaction results - if (trans.done != nullptr) - trans.done->store(true, std::memory_order_release); + if (trans.done != nullptr) trans.done->store(true, std::memory_order_release); } } @@ -543,8 +504,7 @@ void RawDatabase::process() * @param query Source query, which should be anonymized. * @return Query without timestamps and public keys. */ -QString RawDatabase::anonymizeQuery(const QByteArray& query) -{ +QString RawDatabase::anonymizeQuery(const QByteArray& query) { QString queryString(query); queryString.replace(QRegularExpression("chat.public_key='[A-F0-9]{64}'"), "char.public_key=''"); @@ -560,8 +520,7 @@ QString RawDatabase::anonymizeQuery(const QByteArray& query) * @param col Number of column to extract. * @return Extracted data. */ -QVariant RawDatabase::extractData(sqlite3_stmt* stmt, int col) -{ +QVariant RawDatabase::extractData(sqlite3_stmt* stmt, int col) { int type = sqlite3_column_type(stmt, col); if (type == SQLITE_INTEGER) { return sqlite3_column_int64(stmt, col); @@ -579,29 +538,31 @@ QVariant RawDatabase::extractData(sqlite3_stmt* stmt, int col) } /** - * @brief Use for create function in db for search data use regular experessions without case sensitive + * @brief Use for create function in db for search data use regular experessions without case + * sensitive * @param ctx ctx the context in which an SQL function executes * @param argc number of arguments * @param argv arguments */ -void RawDatabase::regexpInsensitive(sqlite3_context* ctx, int argc, sqlite3_value** argv) -{ - regexp(ctx, argc, argv, QRegularExpression::CaseInsensitiveOption | QRegularExpression::UseUnicodePropertiesOption); +void RawDatabase::regexpInsensitive(sqlite3_context* ctx, int argc, sqlite3_value** argv) { + regexp(ctx, argc, argv, + QRegularExpression::CaseInsensitiveOption | + QRegularExpression::UseUnicodePropertiesOption); } /** - * @brief Use for create function in db for search data use regular experessions without case sensitive + * @brief Use for create function in db for search data use regular experessions without case + * sensitive * @param ctx the context in which an SQL function executes * @param argc number of arguments * @param argv arguments */ -void RawDatabase::regexpSensitive(sqlite3_context* ctx, int argc, sqlite3_value** argv) -{ +void RawDatabase::regexpSensitive(sqlite3_context* ctx, int argc, sqlite3_value** argv) { regexp(ctx, argc, argv, QRegularExpression::UseUnicodePropertiesOption); } -void RawDatabase::regexp(sqlite3_context* ctx, int argc, sqlite3_value** argv, const QRegularExpression::PatternOptions cs) -{ +void RawDatabase::regexp(sqlite3_context* ctx, int argc, sqlite3_value** argv, + const QRegularExpression::PatternOptions cs) { QRegularExpression regex; const QString str1(reinterpret_cast(sqlite3_value_text(argv[0]))); const QString str2(reinterpret_cast(sqlite3_value_text(argv[1]))); diff --git a/src/modules/im/src/persistence/db/rawdatabase.h b/src/modules/im/src/persistence/db/rawdatabase.h index 598c5367..565b5a91 100644 --- a/src/modules/im/src/persistence/db/rawdatabase.h +++ b/src/modules/im/src/persistence/db/rawdatabase.h @@ -19,11 +19,11 @@ #include #include #include +#include #include #include #include #include -#include #include #include @@ -40,31 +40,19 @@ using RowId = NamedType; Q_DECLARE_METATYPE(RowId); -class RawDatabase : QObject -{ +class RawDatabase : QObject { Q_OBJECT public: - class Query - { + class Query { public: Query(QString query, QVector blobs = {}, const std::function& insertCallback = {}) - : query{query.toUtf8()} - , blobs{blobs} - , insertCallback{insertCallback} - { - } + : query{query.toUtf8()}, blobs{blobs}, insertCallback{insertCallback} {} Query(QString query, const std::function& insertCallback) - : query{query.toUtf8()} - , insertCallback{insertCallback} - { - } + : query{query.toUtf8()}, insertCallback{insertCallback} {} Query(QString query, const std::function&)>& rowCallback) - : query{query.toUtf8()} - , rowCallback{rowCallback} - { - } + : query{query.toUtf8()}, rowCallback{rowCallback} {} Query() = default; private: @@ -78,10 +66,7 @@ class RawDatabase : QObject }; public: - - RawDatabase(const QString& path, - const QString& password, - const QByteArray& salt); + RawDatabase(const QString& path, const QString& password, const QByteArray& salt); ~RawDatabase(); bool isOpen(); @@ -122,10 +107,10 @@ protected slots: static void regexpSensitive(sqlite3_context* ctx, int argc, sqlite3_value** argv); private: - static void regexp(sqlite3_context* ctx, int argc, sqlite3_value** argv, const QRegularExpression::PatternOptions cs); + static void regexp(sqlite3_context* ctx, int argc, sqlite3_value** argv, + const QRegularExpression::PatternOptions cs); - struct Transaction - { + struct Transaction { QVector queries; std::atomic_bool* success = nullptr; std::atomic_bool* done = nullptr; @@ -141,4 +126,4 @@ protected slots: QString currentHexKey; }; -#endif // RAWDATABASE_H +#endif // RAWDATABASE_H diff --git a/src/modules/im/src/persistence/history.cpp b/src/modules/im/src/persistence/history.cpp index 9632f67e..8b4754cf 100644 --- a/src/modules/im/src/persistence/history.cpp +++ b/src/modules/im/src/persistence/history.cpp @@ -13,75 +13,73 @@ #include #include +#include "db/rawdatabase.h" #include "history.h" #include "profile.h" #include "settings.h" -#include "db/rawdatabase.h" namespace { static constexpr int SCHEMA_VERSION = 1; -bool createCurrentSchema(RawDatabase& db) -{ +bool createCurrentSchema(RawDatabase& db) { QVector queries; queries += RawDatabase::Query(QString( - //peers - "CREATE TABLE peers (" - "id INTEGER PRIMARY KEY AUTOINCREMENT, " - "public_key TEXT NOT NULL UNIQUE);" - - //aliases - "CREATE TABLE aliases (" - "id INTEGER PRIMARY KEY, " - "owner INTEGER UNIQUE, " - "display_name BLOB NOT NULL" - ");" - - //history - "CREATE TABLE history ( " - " id INTEGER PRIMARY KEY AUTOINCREMENT, " - " timestamp INTEGER NOT NULL, " - " receiver TEXT NOT NULL, " - " sender TEXT NOT NULL, " - " message BLOB NOT NULL, " - " data_id TEXT, " - " type INTEGER " - " ); " - - //file_transfers - "CREATE TABLE file_transfers " - "(id INTEGER PRIMARY KEY, " - "chat_id INTEGER NOT NULL, " - "file_restart_id BLOB NOT NULL, " - "file_name BLOB NOT NULL, " - "file_path BLOB NOT NULL, " - "file_hash BLOB NOT NULL, " - "file_size INTEGER NOT NULL, " - "direction INTEGER NOT NULL, " - "file_state INTEGER NOT NULL);" - - //faux_offline_pending - "CREATE TABLE faux_offline_pending (id INTEGER PRIMARY KEY);" - - //broken_messages - "CREATE TABLE broken_messages (id INTEGER PRIMARY KEY);")); - -// queries += RawDatabase::Query(QString("CREATE INDEX his_receiver_idx ON history (receiver); ")); -// queries += RawDatabase::Query(QString("CREATE INDEX his_sender_idx ON history (sender); ")); -// queries += RawDatabase::Query(QString("CREATE INDEX idx_data_id ON history(data_id); ")); + // peers + "CREATE TABLE peers (" + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + "public_key TEXT NOT NULL UNIQUE);" + + // aliases + "CREATE TABLE aliases (" + "id INTEGER PRIMARY KEY, " + "owner INTEGER UNIQUE, " + "display_name BLOB NOT NULL" + ");" + + // history + "CREATE TABLE history ( " + " id INTEGER PRIMARY KEY AUTOINCREMENT, " + " timestamp INTEGER NOT NULL, " + " receiver TEXT NOT NULL, " + " sender TEXT NOT NULL, " + " message BLOB NOT NULL, " + " data_id TEXT, " + " type INTEGER " + " ); " + + // file_transfers + "CREATE TABLE file_transfers " + "(id INTEGER PRIMARY KEY, " + "chat_id INTEGER NOT NULL, " + "file_restart_id BLOB NOT NULL, " + "file_name BLOB NOT NULL, " + "file_path BLOB NOT NULL, " + "file_hash BLOB NOT NULL, " + "file_size INTEGER NOT NULL, " + "direction INTEGER NOT NULL, " + "file_state INTEGER NOT NULL);" + + // faux_offline_pending + "CREATE TABLE faux_offline_pending (id INTEGER PRIMARY KEY);" + + // broken_messages + "CREATE TABLE broken_messages (id INTEGER PRIMARY KEY);")); + + // queries += RawDatabase::Query(QString("CREATE INDEX his_receiver_idx ON history + // (receiver); ")); queries += RawDatabase::Query(QString("CREATE INDEX his_sender_idx ON + // history (sender); ")); queries += RawDatabase::Query(QString("CREATE INDEX idx_data_id ON + // history(data_id); ")); queries += RawDatabase::Query(QString("PRAGMA user_version = %1;").arg(SCHEMA_VERSION)); return db.execNow(queries); } -bool isNewDb(std::shared_ptr& db, bool& success) -{ +bool isNewDb(std::shared_ptr& db, bool& success) { bool newDb; - if (!db->execNow(RawDatabase::Query("SELECT COUNT(*) FROM sqlite_master;", - [&](const QVector& row) { - newDb = row[0].toLongLong() == 0; - }))) { + if (!db->execNow(RawDatabase::Query( + "SELECT COUNT(*) FROM sqlite_master;", + [&](const QVector& row) { newDb = row[0].toLongLong() == 0; }))) { db.reset(); success = false; return false; @@ -96,24 +94,23 @@ bool isNewDb(std::shared_ptr& db, bool& success) * @param db * @return */ -bool dbSchema0to1(RawDatabase& db) -{ +bool dbSchema0to1(RawDatabase& db) { qDebug() << __func__; QVector queries; - queries += RawDatabase::Query(QStringLiteral("ALTER TABLE history ADD COLUMN is_receipt blob;")); + queries += + RawDatabase::Query(QStringLiteral("ALTER TABLE history ADD COLUMN is_receipt blob;")); queries += RawDatabase::Query(QStringLiteral("PRAGMA user_version = 1;")); return db.execNow(queries); } - /** -* @brief Upgrade the db schema -* @return True if the schema upgrade succeded, false otherwise -* @note On future alterations of the database all you have to do is bump the SCHEMA_VERSION -* variable and add another case to the switch statement below. Make sure to fall through on each case. -*/ -bool dbSchemaUpgrade(std::shared_ptr& db) -{ + * @brief Upgrade the db schema + * @return True if the schema upgrade succeded, false otherwise + * @note On future alterations of the database all you have to do is bump the SCHEMA_VERSION + * variable and add another case to the switch statement below. Make sure to fall through on each + * case. + */ +bool dbSchemaUpgrade(std::shared_ptr& db) { qDebug() << __func__; int64_t databaseSchemaVersion; @@ -123,60 +120,61 @@ bool dbSchemaUpgrade(std::shared_ptr& db) qCritical() << "History failed to read user_version"; return false; } - qDebug() <<"Current db schame version is"<< databaseSchemaVersion; + qDebug() << "Current db schame version is" << databaseSchemaVersion; if (databaseSchemaVersion > SCHEMA_VERSION) { - qWarning().nospace() << "Database version (" << databaseSchemaVersion << - ") is newer than we currently support (" << SCHEMA_VERSION << "). Please upgrade the program!"; + qWarning().nospace() << "Database version (" << databaseSchemaVersion + << ") is newer than we currently support (" << SCHEMA_VERSION + << "). Please upgrade the program!"; db->remove(); return false; } switch (databaseSchemaVersion) { - case 0: { - bool success = false; - const bool newDb = isNewDb(db, success); - if (!success) { - qCritical() << "Failed to determine the db is new"; - return false; - } - if (newDb) { - if (!createCurrentSchema(*db)) { - qCritical() << "Failed to create current db schema"; + case 0: { + bool success = false; + const bool newDb = isNewDb(db, success); + if (!success) { + qCritical() << "Failed to determine the db is new"; return false; } - qDebug() << "Database created at schema version" << SCHEMA_VERSION; - break; // new db is the only case where we don't incrementally upgrade through each version + if (newDb) { + if (!createCurrentSchema(*db)) { + qCritical() << "Failed to create current db schema"; + return false; + } + qDebug() << "Database created at schema version" << SCHEMA_VERSION; + break; // new db is the only case where we don't incrementally upgrade through each + // version + } } - } - case 1: { - dbSchema0to1(*db.get()); - break; - } - // etc. - default: - qInfo() << "Database upgrade finished (databaseSchemaVersion" << databaseSchemaVersion - << "->" << SCHEMA_VERSION << ")"; + case 1: { + dbSchema0to1(*db.get()); + break; + } + // etc. + default: + qInfo() << "Database upgrade finished (databaseSchemaVersion" << databaseSchemaVersion + << "->" << SCHEMA_VERSION << ")"; } return true; } -MessageState getMessageState(bool isPending, bool isBroken, bool isReceipt) -{ +MessageState getMessageState(bool isPending, bool isBroken, bool isReceipt) { MessageState messageState; if (isPending) { messageState = MessageState::pending; } else if (isBroken) { messageState = MessageState::broken; - } else if (isReceipt){ + } else if (isReceipt) { messageState = MessageState::receipt; } else { messageState = MessageState::complete; } return messageState; } -} // namespace +} // namespace /** * @class History @@ -188,21 +186,19 @@ MessageState getMessageState(bool isPending, bool isBroken, bool isReceipt) */ static constexpr int NUM_MESSAGES_DEFAULT = - 100; // arbitrary number of messages loaded when not loading by date + 100; // arbitrary number of messages loaded when not loading by date -//FileDbInsertionData::FileDbInsertionData() +// FileDbInsertionData::FileDbInsertionData() //{ -// static int id = qRegisterMetaType(); -// (void)id; -//} +// static int id = qRegisterMetaType(); +// (void)id; +// } /** * @brief Prepares the database to work with the history. * @param db This database will be prepared for use with the history. */ -History::History(std::shared_ptr db_) - : db(db_) -{ +History::History(std::shared_ptr db_) : db(db_) { if (!isValid()) { qWarning() << "Database not open, init failed"; return; @@ -216,17 +212,15 @@ History::History(std::shared_ptr db_) return; } -// connect(this, &History::fileInserted, this, &History::onFileInserted); + // connect(this, &History::fileInserted, this, &History::onFileInserted); // Cache our current peers - db->execLater(RawDatabase::Query{"SELECT public_key, id FROM peers;", - [this](const QVector& row) { - peers[row[0].toString()] = row[1].toInt(); - }}); + db->execLater(RawDatabase::Query{ + "SELECT public_key, id FROM peers;", + [this](const QVector& row) { peers[row[0].toString()] = row[1].toInt(); }}); } -History::~History() -{ +History::~History() { if (!isValid()) { return; } @@ -240,18 +234,14 @@ History::~History() * @brief Checks if the database was opened successfully * @return True if database if opened, false otherwise. */ -bool History::isValid() -{ - return db && db->isOpen(); -} +bool History::isValid() { return db && db->isOpen(); } /** * @brief Checks if a friend has chat history * @param friendPk * @return True if has, false otherwise. */ -bool History::historyExists(const FriendId& me, const FriendId& friendPk) -{ +bool History::historyExists(const FriendId& me, const FriendId& friendPk) { if (historyAccessBlocked()) { return false; } @@ -262,58 +252,52 @@ bool History::historyExists(const FriendId& me, const FriendId& friendPk) /** * @brief Erases all the chat history from the database. */ -void History::eraseHistory() -{ +void History::eraseHistory() { if (!isValid()) { return; } - db->execNow("DELETE FROM faux_offline_pending;" - "DELETE FROM history;" - "DELETE FROM aliases;" - "DELETE FROM peers;" - "DELETE FROM file_transfers;" - "DELETE FROM broken_messages;" - "VACUUM;"); + db->execNow( + "DELETE FROM faux_offline_pending;" + "DELETE FROM history;" + "DELETE FROM aliases;" + "DELETE FROM peers;" + "DELETE FROM file_transfers;" + "DELETE FROM broken_messages;" + "VACUUM;"); } /** * @brief Erases the chat history with one friend. * @param friendPk IMFriend public key to erase. */ -void History::removeFriendHistory(const QString& friendPk) -{ - qDebug()<<__func__<< friendPk; +void History::removeFriendHistory(const QString& friendPk) { + qDebug() << __func__ << friendPk; if (!isValid()) { return; } QString sql = QString("DELETE FROM history WHERE receiver='%1' or sender='%1'; " - "DELETE FROM peers WHERE public_key='%1'; " - "DELETE FROM aliases WHERE owner='%1'; " - "VACUUM;") - .arg(friendPk); + "DELETE FROM peers WHERE public_key='%1'; " + "DELETE FROM aliases WHERE owner='%1'; " + "VACUUM;") + .arg(friendPk); if (!db->execNow(sql)) { qWarning() << "Failed to remove friend's history"; return; } peers.remove(friendPk); - } -uint History::addNewContact(const QString &contactId) -{ - auto q = QString("INSERT OR IGNORE INTO peers (public_key) VALUES ('%1');" - ) - .arg(contactId); +uint History::addNewContact(const QString& contactId) { + auto q = QString("INSERT OR IGNORE INTO peers (public_key) VALUES ('%1');").arg(contactId); db->execNow(q); uint id = 0; - db->execNow({ "SELECT last_insert_rowid();", [&id](const QVector& row){ - id = row[0].toUInt(); - } }); + db->execNow({"SELECT last_insert_rowid();", + [&id](const QVector& row) { id = row[0].toUInt(); }}); return id; } @@ -327,74 +311,72 @@ uint History::addNewContact(const QString &contactId) * @param dispName Name, which should be displayed. * @param insertIdCallback Function, called after query execution. */ -QVector -History::generateNewMessageQueries(const Message& message, - HistMessageContentType type, - bool isDelivered, - std::function insertIdCallback) -{ +QVector History::generateNewMessageQueries(const Message& message, + HistMessageContentType type, + bool isDelivered, + std::function + insertIdCallback) { QVector queries; - queries += - RawDatabase::Query(QString("INSERT INTO history " - "(timestamp, receiver, sender, message, type, data_id, is_receipt) " - "values (%1, '%2', '%3', '%4', %5, '%6', %7)") - .arg(message.timestamp.toMSecsSinceEpoch()) //1 - .arg(message.to) //2 - .arg(message.from) //3 - .arg(message.content) //4 - .arg((int)type) //5 - .arg(message.dataId)//6 - .arg(false), //7 - insertIdCallback); + queries += RawDatabase::Query( + QString("INSERT INTO history " + "(timestamp, receiver, sender, message, type, data_id, is_receipt) " + "values (%1, '%2', '%3', '%4', %5, '%6', %7)") + .arg(message.timestamp.toMSecsSinceEpoch()) // 1 + .arg(message.to) // 2 + .arg(message.from) // 3 + .arg(message.content) // 4 + .arg((int)type) // 5 + .arg(message.dataId) // 6 + .arg(false), // 7 + insertIdCallback); if (!isDelivered) { - queries += RawDatabase::Query{"INSERT INTO faux_offline_pending (id) VALUES (" - " last_insert_rowid()" - ");"}; + queries += RawDatabase::Query{ + "INSERT INTO faux_offline_pending (id) VALUES (" + " last_insert_rowid()" + ");"}; } return queries; } -void History::onFileInserted(RowId dbId, QString fileId) -{ -// auto& fileInfo = fileCached[fileId]; -// if (fileInfo.finished) { -// db->execLater(generateFileFinished(dbId, fileInfo.success, fileInfo.filePath, fileInfo.fileHash)); -// fileInfos.remove(fileId); -// } else { -// fileInfo.finished = false; -// fileInfo.fileId = dbId; -// } +void History::onFileInserted(RowId dbId, QString fileId) { + // auto& fileInfo = fileCached[fileId]; + // if (fileInfo.finished) { + // db->execLater(generateFileFinished(dbId, fileInfo.success, fileInfo.filePath, + // fileInfo.fileHash)); fileInfos.remove(fileId); + // } else { + // fileInfo.finished = false; + // fileInfo.fileId = dbId; + // } } -//RawDatabase::Query History::generateFileFinished(RowId id, bool success, const QString& filePath, -// const QByteArray& fileHash) +// RawDatabase::Query History::generateFileFinished(RowId id, bool success, const QString& filePath, +// const QByteArray& fileHash) //{ -// auto file_state = success ? FileStatus::FINISHED : FileStatus::CANCELED; -// if (filePath.length()) { -// return RawDatabase::Query(QStringLiteral("UPDATE file_transfers " -// "SET file_state = %1, file_path = ?, file_hash = ?" -// "WHERE id = %2") -// .arg(file_state) -// .arg(id.get()), -// {filePath.toUtf8(), fileHash}); -// } else { -// return RawDatabase::Query(QStringLiteral("UPDATE file_transfers " -// "SET finished = %1 " -// "WHERE id = %2") -// .arg(file_state) -// .arg(id.get())); -// } -//} +// auto file_state = success ? FileStatus::FINISHED : FileStatus::CANCELED; +// if (filePath.length()) { +// return RawDatabase::Query(QStringLiteral("UPDATE file_transfers " +// "SET file_state = %1, file_path = ?, file_hash = +// ?" "WHERE id = %2") +// .arg(file_state) +// .arg(id.get()), +// {filePath.toUtf8(), fileHash}); +// } else { +// return RawDatabase::Query(QStringLiteral("UPDATE file_transfers " +// "SET finished = %1 " +// "WHERE id = %2") +// .arg(file_state) +// .arg(id.get())); +// } +// } void History::addNewFileMessage(const QString& friendPk, const ToxFile& file, const QString& sender, const QDateTime& time, - QString const& dispName) -{ + QString const& dispName) { if (historyAccessBlocked()) { return; } @@ -412,33 +394,32 @@ void History::addNewFileMessage(const QString& friendPk, // message in it, and get the id with the callbck. Once we have the id we can ammend // the data to have our newly inserted file_id as well -// FileStatus::FileDirection direction; -// if (sender == friendPk) { -// direction = FileStatus::RECEIVING; -// } else { -// direction = FileStatus::SENDING; -// } + // FileStatus::FileDirection direction; + // if (sender == friendPk) { + // direction = FileStatus::RECEIVING; + // } else { + // direction = FileStatus::SENDING; + // } - qDebug() <<"add new file:" << file.fileName; + qDebug() << "add new file:" << file.fileName; std::weak_ptr weakThis = shared_from_this(); FileInfo insertionData{file}; auto insertFileTransferFn = [&](RowId rowId) { - qDebug() <<"file has be cached as rowId" << rowId.get(); + qDebug() << "file has be cached as rowId" << rowId.get(); }; - Message msg = { - .isAction=false, - .from=sender, - .to = friendPk, - .content=insertionData.json(), - .dataId = file.fileId, - .timestamp=time + Message msg = {.isAction = false, + .from = sender, + .to = friendPk, + .content = insertionData.json(), + .dataId = file.fileId, + .timestamp = time }; - addNewMessage(msg, HistMessageContentType::file, true, insertFileTransferFn); + addNewMessage(msg, HistMessageContentType::file, true, insertFileTransferFn); } /** @@ -454,9 +435,8 @@ void History::addNewFileMessage(const QString& friendPk, void History::addNewMessage(const Message& message, HistMessageContentType type, bool isDelivered, - const std::function& insertIdCallback) -{ - qDebug() << __func__ << "from:"<& insertIdCallback) { + qDebug() << __func__ << "from:" << message.from << "message" << message.content; if (historyAccessBlocked()) { return; @@ -465,62 +445,53 @@ void History::addNewMessage(const Message& message, db->execLater(sql); } -void History::setFileMessage(const ToxFile& file) -{ - qDebug() <<__func__ <<"file:" <execNow(sql); - + auto message = file.json(); + auto sql = QString("UPDATE history SET message = '%1' WHERE data_id = '%2'; ") + .arg(message) + .arg(file.fileId); + db->execNow(sql); } - -QList History::getMessageByDataId(const QString &dataId) -{ - if(dataId.isEmpty()) - return {}; +QList History::getMessageByDataId(const QString& dataId) { + if (dataId.isEmpty()) return {}; if (historyAccessBlocked()) { return {}; } - - QString queryText = QString("SELECT " - "id, " //0 - "timestamp, " //1 - "receiver, " //2 - "sender, " //3 - "message, " //4 - "type, " //5 - "0, " //6 - "0, " //7 + "id, " // 0 + "timestamp, " // 1 + "receiver, " // 2 + "sender, " // 3 + "message, " // 4 + "type, " // 5 + "0, " // 6 + "0, " // 7 "data_id," - "is_receipt " //8 - "from history where data_id = '%1'").arg(dataId); + "is_receipt " // 8 + "from history where data_id = '%1'") + .arg(dataId); - qDebug()< messages; - db->execNow({queryText, [&](const QVector& row) { - messages.append(rowToMessage(row)); - }}); + db->execNow( + {queryText, [&](const QVector& row) { messages.append(rowToMessage(row)); }}); return messages; } -size_t History::getNumMessagesForFriend(const FriendId& me, const FriendId& friendPk) -{ +size_t History::getNumMessagesForFriend(const FriendId& me, const FriendId& friendPk) { if (historyAccessBlocked()) { return 0; } @@ -528,8 +499,8 @@ size_t History::getNumMessagesForFriend(const FriendId& me, const FriendId& frie return getNumMessagesForFriendBeforeDate(me, friendPk, QDateTime()); } -size_t History::getNumMessagesForFriendBeforeDate(const FriendId& me, const FriendId& friendPk, const QDateTime& date) -{ +size_t History::getNumMessagesForFriendBeforeDate(const FriendId& me, const FriendId& friendPk, + const QDateTime& date) { if (historyAccessBlocked()) { return 0; } @@ -538,14 +509,15 @@ size_t History::getNumMessagesForFriendBeforeDate(const FriendId& me, const Frie QString queryText = QString("SELECT COUNT(id) " "FROM history " "WHERE sender = '%1' %2 receiver = '%1'") - .arg(ContactId(friendPk).toString()).arg(link); + .arg(ContactId(friendPk).toString()) + .arg(link); if (date.isNull()) { queryText += ";"; } else { queryText += QString(" AND timestamp < %1;").arg(date.toMSecsSinceEpoch()); } -// qDebug() << queryText; + // qDebug() << queryText; size_t numMessages = 0; auto rowCallback = [&numMessages](const QVector& row) { numMessages = row[0].toLongLong(); @@ -556,50 +528,49 @@ size_t History::getNumMessagesForFriendBeforeDate(const FriendId& me, const Frie return numMessages; } -QString History::makeSqlForFriend(const FriendId& me, const FriendId& friendPk){ +QString History::makeSqlForFriend(const FriendId& me, const FriendId& friendPk) { QString link = me == friendPk ? "AND" : "OR"; - QString queryText = QString( - "SELECT history.id, " //0 - "timestamp, " //1 - "receiver, " //2 - "sender, " //3 - "message, " //4 - "type, " //5 - "broken_messages.id bro_id, " //6 - "faux_offline_pending.id off_id, " //7 - "data_id, " //8 - "is_receipt " //9 - "FROM history " - "LEFT JOIN faux_offline_pending ON history.id = faux_offline_pending.id " - "LEFT JOIN broken_messages ON history.id = broken_messages.id " - "WHERE (history.sender='%1' %2 history.receiver='%1') ") - .arg(friendPk.toString()).arg(link); + QString queryText = + QString("SELECT history.id, " // 0 + "timestamp, " // 1 + "receiver, " // 2 + "sender, " // 3 + "message, " // 4 + "type, " // 5 + "broken_messages.id bro_id, " // 6 + "faux_offline_pending.id off_id, " // 7 + "data_id, " // 8 + "is_receipt " // 9 + "FROM history " + "LEFT JOIN faux_offline_pending ON history.id = faux_offline_pending.id " + "LEFT JOIN broken_messages ON history.id = broken_messages.id " + "WHERE (history.sender='%1' %2 history.receiver='%1') ") + .arg(friendPk.toString()) + .arg(link); return queryText; } -History::HistMessage History::rowToMessage(const QVector& row){ - - auto id = RowId{row[0].toLongLong()}; - auto timestamp = QDateTime::fromMSecsSinceEpoch(row[1].toLongLong()); - auto receiver = row[2].toString(); +History::HistMessage History::rowToMessage(const QVector& row) { + auto id = RowId{row[0].toLongLong()}; + auto timestamp = QDateTime::fromMSecsSinceEpoch(row[1].toLongLong()); + auto receiver = row[2].toString(); auto sender_key = row[3].toString(); - auto message = row[4].toString(); - auto type = row[5].toInt(0); - auto isBroken = row[6].toInt(0); - auto isPending = row[7].toInt(0); + auto message = row[4].toString(); + auto type = row[5].toInt(0); + auto isBroken = row[6].toInt(0); + auto isPending = row[7].toInt(0); auto dataId = row[8].toString(); auto isReceipt = row[9].toBool(); auto ctype = static_cast(type); auto state = getMessageState(isPending, isBroken, isReceipt); - return History::HistMessage{ id, ctype, state,timestamp,sender_key,receiver, message, dataId }; + return History::HistMessage{id, ctype, state, timestamp, sender_key, receiver, message, dataId}; } QList History::getMessagesForFriend(const FriendId& me, const FriendId& friendPk, size_t firstIdx, - size_t lastIdx) -{ + size_t lastIdx) { if (historyAccessBlocked()) { return {}; } @@ -607,68 +578,62 @@ QList History::getMessagesForFriend(const FriendId& me, auto sqlPrefix = makeSqlForFriend(me, friendPk); QString queryText = QString("%1 " - "ORDER by history.timestamp " - "LIMIT %2 OFFSET %3; ") - .arg(sqlPrefix) - .arg(lastIdx - firstIdx) - .arg(firstIdx); + "ORDER by history.timestamp " + "LIMIT %2 OFFSET %3; ") + .arg(sqlPrefix) + .arg(lastIdx - firstIdx) + .arg(firstIdx); -// qDebug()< messages; - db->execNow({queryText, [&](const QVector& row) { - messages.append(rowToMessage(row)); - }}); + db->execNow( + {queryText, [&](const QVector& row) { messages.append(rowToMessage(row)); }}); return messages; } - QList History::getLastMessageForFriend(const FriendId &me, const FriendId &friendPk, - uint size, HistMessageContentType type) - { - - if (historyAccessBlocked()) { - return {}; - } - - auto sqlPrefix = makeSqlForFriend(me, friendPk); - - auto sql = QString("%1 " - "AND type = %3 " - "ORDER by history.timestamp DESC LIMIT %2;") - .arg(sqlPrefix) - .arg(size) - .arg((int)type); -// qDebug() <<"sql:"< messages; - auto rowCallback = [&](const QVector& row) { - messages += rowToMessage(row); - }; - db->execNow({sql, rowCallback}); - return messages; - } - -QList History::getUndeliveredMessagesForFriend(const FriendId& me, const FriendId& friendPk) -{ +QList History::getLastMessageForFriend(const FriendId& me, + const FriendId& friendPk, uint size, + HistMessageContentType type) { + if (historyAccessBlocked()) { + return {}; + } + + auto sqlPrefix = makeSqlForFriend(me, friendPk); + + auto sql = QString("%1 " + "AND type = %3 " + "ORDER by history.timestamp DESC LIMIT %2;") + .arg(sqlPrefix) + .arg(size) + .arg((int)type); + // qDebug() <<"sql:"< messages; + auto rowCallback = [&](const QVector& row) { messages += rowToMessage(row); }; + db->execNow({sql, rowCallback}); + return messages; +} + +QList History::getUndeliveredMessagesForFriend(const FriendId& me, + const FriendId& friendPk) { if (historyAccessBlocked()) { return {}; } auto sqlPrefix = makeSqlForFriend(me, friendPk); auto queryText = - QString("SELECT history.id, faux_offline_pending.id, timestamp, chat.public_key, " - "chat.public_key, message, broken_messages.id " - "FROM history " - "JOIN faux_offline_pending ON history.id = faux_offline_pending.id " - "JOIN peers chat on history.sender = chat.public_key " - "LEFT JOIN broken_messages ON history.id = broken_messages.id " - "WHERE chat.public_key='%1';") - .arg(friendPk.toString()); + QString("SELECT history.id, faux_offline_pending.id, timestamp, chat.public_key, " + "chat.public_key, message, broken_messages.id " + "FROM history " + "JOIN faux_offline_pending ON history.id = faux_offline_pending.id " + "JOIN peers chat on history.sender = chat.public_key " + "LEFT JOIN broken_messages ON history.id = broken_messages.id " + "WHERE chat.public_key='%1';") + .arg(friendPk.toString()); QList ret; - auto rowCallback = [&](const QVector& row) { - ret += rowToMessage(row); - }; + auto rowCallback = [&](const QVector& row) { ret += rowToMessage(row); }; db->execNow({queryText, rowCallback}); return ret; @@ -683,8 +648,7 @@ QList History::getUndeliveredMessagesForFriend(const Frien * @return date of the message where the phrase was found */ QDateTime History::getDateWhereFindPhrase(const QString& friendPk, const QDateTime& from, - QString phrase, const ParameterSearch& parameter) -{ + QString phrase, const ParameterSearch& parameter) { if (historyAccessBlocked()) { return QDateTime(); } @@ -699,26 +663,26 @@ QDateTime History::getDateWhereFindPhrase(const QString& friendPk, const QDateTi QString message; switch (parameter.filter) { - case FilterSearch::Register: - message = QStringLiteral("message LIKE '%%1%'").arg(phrase); - break; - case FilterSearch::WordsOnly: - message = QStringLiteral("message REGEXP '%1'") - .arg(SearchExtraFunctions::generateFilterWordsOnly(phrase).toLower()); - break; - case FilterSearch::RegisterAndWordsOnly: - message = QStringLiteral("REGEXPSENSITIVE(message, '%1')") - .arg(SearchExtraFunctions::generateFilterWordsOnly(phrase)); - break; - case FilterSearch::Regular: - message = QStringLiteral("message REGEXP '%1'").arg(phrase); - break; - case FilterSearch::RegisterAndRegular: - message = QStringLiteral("REGEXPSENSITIVE(message '%1')").arg(phrase); - break; - default: - message = QStringLiteral("LOWER(message) LIKE '%%1%'").arg(phrase.toLower()); - break; + case FilterSearch::Register: + message = QStringLiteral("message LIKE '%%1%'").arg(phrase); + break; + case FilterSearch::WordsOnly: + message = QStringLiteral("message REGEXP '%1'") + .arg(SearchExtraFunctions::generateFilterWordsOnly(phrase).toLower()); + break; + case FilterSearch::RegisterAndWordsOnly: + message = QStringLiteral("REGEXPSENSITIVE(message, '%1')") + .arg(SearchExtraFunctions::generateFilterWordsOnly(phrase)); + break; + case FilterSearch::Regular: + message = QStringLiteral("message REGEXP '%1'").arg(phrase); + break; + case FilterSearch::RegisterAndRegular: + message = QStringLiteral("REGEXPSENSITIVE(message '%1')").arg(phrase); + break; + default: + message = QStringLiteral("LOWER(message) LIKE '%%1%'").arg(phrase.toLower()); + break; } QDateTime date = from; @@ -727,7 +691,8 @@ QDateTime History::getDateWhereFindPhrase(const QString& friendPk, const QDateTi date = QDateTime::currentDateTime(); } - if (parameter.period == PeriodSearch::AfterDate || parameter.period == PeriodSearch::BeforeDate) { + if (parameter.period == PeriodSearch::AfterDate || + parameter.period == PeriodSearch::BeforeDate) { #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) date = parameter.date.startOfDay(); #else @@ -737,33 +702,34 @@ QDateTime History::getDateWhereFindPhrase(const QString& friendPk, const QDateTi QString period; switch (parameter.period) { - case PeriodSearch::WithTheFirst: - period = QStringLiteral("ORDER BY timestamp ASC LIMIT 1;"); - break; - case PeriodSearch::AfterDate: - period = QStringLiteral("AND timestamp > '%1' ORDER BY timestamp ASC LIMIT 1;") - .arg(date.toMSecsSinceEpoch()); - break; - case PeriodSearch::BeforeDate: - period = QStringLiteral("AND timestamp < '%1' ORDER BY timestamp DESC LIMIT 1;") - .arg(date.toMSecsSinceEpoch()); - break; - default: - period = QStringLiteral("AND timestamp < '%1' ORDER BY timestamp DESC LIMIT 1;") - .arg(date.toMSecsSinceEpoch()); - break; + case PeriodSearch::WithTheFirst: + period = QStringLiteral("ORDER BY timestamp ASC LIMIT 1;"); + break; + case PeriodSearch::AfterDate: + period = QStringLiteral("AND timestamp > '%1' ORDER BY timestamp ASC LIMIT 1;") + .arg(date.toMSecsSinceEpoch()); + break; + case PeriodSearch::BeforeDate: + period = QStringLiteral("AND timestamp < '%1' ORDER BY timestamp DESC LIMIT 1;") + .arg(date.toMSecsSinceEpoch()); + break; + default: + period = QStringLiteral("AND timestamp < '%1' ORDER BY timestamp DESC LIMIT 1;") + .arg(date.toMSecsSinceEpoch()); + break; } QString queryText = - QStringLiteral("SELECT timestamp " - "FROM history " - "LEFT JOIN faux_offline_pending ON history.id = faux_offline_pending.id " - "WHERE public_key='%1' " - "AND %2 " - "%3") - .arg(friendPk) - .arg(message) - .arg(period); + QStringLiteral( + "SELECT timestamp " + "FROM history " + "LEFT JOIN faux_offline_pending ON history.id = faux_offline_pending.id " + "WHERE public_key='%1' " + "AND %2 " + "%3") + .arg(friendPk) + .arg(message) + .arg(period); db->execNow({queryText, rowCallback}); @@ -771,9 +737,10 @@ QDateTime History::getDateWhereFindPhrase(const QString& friendPk, const QDateTi } /** - * @brief Gets date boundaries in conversation with friendPk. History doesn't model conversation indexes, - * but we can count messages between us and friendPk to effectively give us an index. This function - * returns how many messages have happened between us <-> friendPk each time the date changes + * @brief Gets date boundaries in conversation with friendPk. History doesn't model conversation + * indexes, but we can count messages between us and friendPk to effectively give us an index. This + * function returns how many messages have happened between us <-> friendPk each time the date + * changes * @param[in] friendPk ToxPk of conversation to retrieve * @param[in] from Start date to look from * @param[in] maxNum Maximum number of date boundaries to retrieve @@ -782,10 +749,8 @@ QDateTime History::getDateWhereFindPhrase(const QString& friendPk, const QDateTi * of date changes (for loadHistory). We could write two separate queries but the query is fairly * intricate compared to our other ones so reducing duplication of it is preferable. */ -QList History::getNumMessagesForFriendBeforeDateBoundaries(const FriendId& friendPk, - const QDate& from, - size_t maxNum) -{ +QList History::getNumMessagesForFriendBeforeDateBoundaries( + const FriendId& friendPk, const QDate& from, size_t maxNum) { if (historyAccessBlocked()) { return {}; } @@ -797,12 +762,10 @@ QList History::getNumMessagesForFriendBeforeDateBoundaries(con // certain date. We do this by re-joining our table a second time // but this time with the only filter being that our id is less than // the ID of the corresponding row in the table that is grouped by day - auto countMessagesForFriend = - QString("SELECT COUNT(*) " - "FROM history " - "WHERE public_key = '%1' " - ) - .arg(friendPkString); + auto countMessagesForFriend = QString("SELECT COUNT(*) " + "FROM history " + "WHERE public_key = '%1' ") + .arg(friendPkString); auto limitString = (maxNum) ? QString("LIMIT %1").arg(maxNum) : QString(""); @@ -812,21 +775,21 @@ QList History::getNumMessagesForFriendBeforeDateBoundaries(con "AND timestamp >= %3 " "GROUP by day " "%4;") - .arg(countMessagesForFriend) - .arg(friendPkString) + .arg(countMessagesForFriend) + .arg(friendPkString) #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) - .arg(QDateTime(from.startOfDay()).toMSecsSinceEpoch()) + .arg(QDateTime(from.startOfDay()).toMSecsSinceEpoch()) #else - .arg(QDateTime(from).toMSecsSinceEpoch()) + .arg(QDateTime(from).toMSecsSinceEpoch()) #endif - .arg(limitString); + .arg(limitString); QList dateIdxs; auto rowCallback = [&dateIdxs](const QVector& row) { DateIdx dateIdx; dateIdx.numMessagesIn = row[0].toLongLong(); dateIdx.date = - QDateTime::fromMSecsSinceEpoch(row[1].toLongLong() * 24 * 60 * 60 * 1000).date(); + QDateTime::fromMSecsSinceEpoch(row[1].toLongLong() * 24 * 60 * 60 * 1000).date(); dateIdxs.append(dateIdx); }; @@ -841,8 +804,7 @@ QList History::getNumMessagesForFriendBeforeDateBoundaries(con * * @param id Message ID. */ -void History::markAsDelivered(RowId messageId) -{ +void History::markAsDelivered(RowId messageId) { if (historyAccessBlocked()) { return; } @@ -850,23 +812,19 @@ void History::markAsDelivered(RowId messageId) db->execLater(QString("DELETE FROM faux_offline_pending WHERE id=%1;").arg(messageId.get())); } -void History::markAsReceipt(RowId messageId) -{ +void History::markAsReceipt(RowId messageId) { if (historyAccessBlocked()) { return; } db->execLater(QString("UPDATE history SET is_receipt = 1 WHERE id=%1;").arg(messageId.get())); } -void History::setFriendAlias(const QString &friendPk, const QString &alias) -{ +void History::setFriendAlias(const QString& friendPk, const QString& alias) { int owner = -1; db->execNow({QString("SELECT id FROM peers where public_key = '%1'").arg(friendPk), - [&owner](const QVector& row) { - owner = row[0].toLongLong(); - }}); - if(owner < 0){ - qWarning() <<"contactId"<& row) { owner = row[0].toLongLong(); }}); + if (owner < 0) { + qWarning() << "contactId" << friendPk << " is no existing"; return; } @@ -874,30 +832,26 @@ void History::setFriendAlias(const QString &friendPk, const QString &alias) "VALUES (%1, '%2') " "ON CONFLICT(owner) " "DO UPDATE SET display_name = excluded.display_name;") - .arg(owner) - .arg(alias); + .arg(owner) + .arg(alias); db->execNow((sql)); } -QString History::getFriendAlias(const QString &friendPk) -{ +QString History::getFriendAlias(const QString& friendPk) { QString name; db->execNow({QString("select display_name " - "from aliases a join peers p on a.owner = p.id " - "where p.public_key='%1'") - .arg(friendPk), - [&name](const QVector& row) { - name = row[0].toString(); - }}); + "from aliases a join peers p on a.owner = p.id " + "where p.public_key='%1'") + .arg(friendPk), + [&name](const QVector& row) { name = row[0].toString(); }}); return name; } /** -* @brief Determines if history access should be blocked -* @return True if history should not be accessed -*/ -bool History::historyAccessBlocked() -{ + * @brief Determines if history access should be blocked + * @return True if history should not be accessed + */ +bool History::historyAccessBlocked() { if (!Settings::getInstance().getEnableLogging()) { assert(false); qCritical() << "Blocked history access while history is disabled"; @@ -909,5 +863,4 @@ bool History::historyAccessBlocked() } return false; - } diff --git a/src/modules/im/src/persistence/history.h b/src/modules/im/src/persistence/history.h index a1f880c4..40bda99a 100644 --- a/src/modules/im/src/persistence/history.h +++ b/src/modules/im/src/persistence/history.h @@ -18,9 +18,9 @@ #include #include -#include #include #include +#include #include #include @@ -34,59 +34,51 @@ class Profile; class HistoryKeeper; -enum class HistMessageContentType -{ - message, - file -}; +enum class HistMessageContentType { message, file }; -//struct FileDbInsertionData +// struct FileDbInsertionData //{ -// FileDbInsertionData(); +// FileDbInsertionData(); // -// QString fileId; -// QString fileName; -// QString filePath; -// int64_t size; -// int direction; +// QString fileId; +// QString fileName; +// QString filePath; +// int64_t size; +// int direction; // -// QString json(){ -// return QString("{\"id:\":\"%1\", \"name\":\"%2\", \"path\":\"%3\", \"size\":%4, \"direction\":%5}") -// .arg(fileId).arg(fileName).arg(filePath).arg(size).arg(direction); -// } +// QString json(){ +// return QString("{\"id:\":\"%1\", \"name\":\"%2\", \"path\":\"%3\", \"size\":%4, +// \"direction\":%5}") +// .arg(fileId).arg(fileName).arg(filePath).arg(size).arg(direction); +// } // -// void parse(const QString &json){ -// auto doc = Jsons::toJSON(json.toUtf8()); -// auto obj = doc.object(); -// fileId = obj.value("id").toString(); -// fileName = obj.value("fileName").toString(); -// filePath = obj.value("path").toString(); -// size = obj.value("size").toInt(); -// direction = obj.value("direction").toInt(); -// } -//}; +// void parse(const QString &json){ +// auto doc = Jsons::toJSON(json.toUtf8()); +// auto obj = doc.object(); +// fileId = obj.value("id").toString(); +// fileName = obj.value("fileName").toString(); +// filePath = obj.value("path").toString(); +// size = obj.value("size").toInt(); +// direction = obj.value("direction").toInt(); +// } +// }; // // -//Q_DECLARE_METATYPE(FileDbInsertionData); +// Q_DECLARE_METATYPE(FileDbInsertionData); - -enum class MessageState -{ - complete, //消息发送成功 - pending, //消息发送中 - broken, //消息失败 - receipt, //消息接收 +enum class MessageState { + complete, // 消息发送成功 + pending, // 消息发送中 + broken, // 消息失败 + receipt, // 消息接收 }; -class History : public QObject, public std::enable_shared_from_this -{ +class History : public QObject, public std::enable_shared_from_this { Q_OBJECT public: - - struct HistMessage - { - HistMessage()=default; + struct HistMessage { + HistMessage() = default; HistMessage(RowId id, HistMessageContentType type, MessageState state, @@ -95,22 +87,21 @@ class History : public QObject, public std::enable_shared_from_this QString receiver, QString message, QString dataId) - : id{id}, - type{type}, - state(state), - timestamp{std::move(timestamp)}, - sender{std::move(sender)}, - receiver{std::move(receiver)}, - message(std::move(message)), - dataId{dataId} - { -// if(type==HistMessageContentType::message){ -// data = std::make_shared(std::move(message)); -// }else if(type==HistMessageContentType::file){ -// FileDbInsertionData dbFile; -// dbFile.parse(message); -// data= std::make_shared(std::move(dbFile)); -// } + : id{id} + , type{type} + , state(state) + , timestamp{std::move(timestamp)} + , sender{std::move(sender)} + , receiver{std::move(receiver)} + , message(std::move(message)) + , dataId{dataId} { + // if(type==HistMessageContentType::message){ + // data = std::make_shared(std::move(message)); + // }else if(type==HistMessageContentType::file){ + // FileDbInsertionData dbFile; + // dbFile.parse(message); + // data= std::make_shared(std::move(dbFile)); + // } } RowId id; @@ -122,32 +113,27 @@ class History : public QObject, public std::enable_shared_from_this QString message; QString dataId; - [[nodiscard]] QString asMessage() const - { - if(type == HistMessageContentType::message){ + [[nodiscard]] QString asMessage() const { + if (type == HistMessageContentType::message) { return message; } return {}; } - [[nodiscard]] FileInfo asFile() const - { - FileInfo file; - if(type == HistMessageContentType::file){ + [[nodiscard]] FileInfo asFile() const { + FileInfo file; + if (type == HistMessageContentType::file) { file.parse(message); } return file; } - }; - struct DateIdx - { + struct DateIdx { QDate date; size_t numMessagesIn; }; - explicit History(std::shared_ptr db); ~History(); @@ -171,17 +157,21 @@ class History : public QObject, public std::enable_shared_from_this const QDateTime& time, QString const& dispName); - void setFileMessage(const ToxFile& file ); + void setFileMessage(const ToxFile& file); - QList getMessageByDataId(const QString &dataId); + QList getMessageByDataId(const QString& dataId); size_t getNumMessagesForFriend(const FriendId& me, const FriendId& friendPk); - size_t getNumMessagesForFriendBeforeDate(const FriendId& me, const FriendId& friendPk, const QDateTime& date); + size_t getNumMessagesForFriendBeforeDate(const FriendId& me, const FriendId& friendPk, + const QDateTime& date); - QList getMessagesForFriend(const FriendId& me, const FriendId& friendPk, size_t firstIdx, size_t lastIdx); - QList getLastMessageForFriend(const FriendId &me, const FriendId& pk, uint size, HistMessageContentType type); + QList getMessagesForFriend(const FriendId& me, const FriendId& friendPk, + size_t firstIdx, size_t lastIdx); + QList getLastMessageForFriend(const FriendId& me, const FriendId& pk, uint size, + HistMessageContentType type); - QList getUndeliveredMessagesForFriend(const FriendId &me, const FriendId& friendPk); + QList getUndeliveredMessagesForFriend(const FriendId& me, + const FriendId& friendPk); QDateTime getDateWhereFindPhrase(const QString& friendPk, const QDateTime& from, QString phrase, @@ -192,21 +182,19 @@ class History : public QObject, public std::enable_shared_from_this void markAsDelivered(RowId messageId); void markAsReceipt(RowId messageId); - void setFriendAlias(const QString& friendPk, const QString& alias); QString getFriendAlias(const QString& friendPk); - protected: - QVector - generateNewMessageQueries(const Message& message, - HistMessageContentType type, - bool isDelivered, - std::function insertIdCallback = {}); + QVector generateNewMessageQueries( + const Message& message, + HistMessageContentType type, + bool isDelivered, + std::function insertIdCallback = {}); signals: -// void fileInserted(RowId dbId, QString fileId); + // void fileInserted(RowId dbId, QString fileId); private slots: @@ -214,30 +202,27 @@ private slots: private: bool historyAccessBlocked(); -// static RawDatabase::Query generateFileFinished(RowId fileId, -// bool success, -// const QString& filePath, -// const QByteArray& fileHash); - - + // static RawDatabase::Query generateFileFinished(RowId fileId, + // bool success, + // const QString& filePath, + // const QByteArray& fileHash); std::shared_ptr db; - QHash peers; -// struct FileInfo -// { -// bool finished = false; -// bool success = false; -// QString filePath; -// QByteArray fileHash; -// RowId fileId{-1}; -// }; + // struct FileInfo + // { + // bool finished = false; + // bool success = false; + // QString filePath; + // QByteArray fileHash; + // RowId fileId{-1}; + // }; // This needs to be a shared pointer to avoid callback lifetime issues -// QHash fileCached; - QString makeSqlForFriend(const FriendId &me, const FriendId &friendPk); - History::HistMessage rowToMessage(const QVector &row); + // QHash fileCached; + QString makeSqlForFriend(const FriendId& me, const FriendId& friendPk); + History::HistMessage rowToMessage(const QVector& row); }; -#endif // HISTORY_H +#endif // HISTORY_H diff --git a/src/modules/im/src/persistence/ifriendsettings.h b/src/modules/im/src/persistence/ifriendsettings.h index e70ac297..89f44d35 100644 --- a/src/modules/im/src/persistence/ifriendsettings.h +++ b/src/modules/im/src/persistence/ifriendsettings.h @@ -15,23 +15,16 @@ #include "src/base/interface.h" -#include #include +#include #include class FriendId; -class IFriendSettings -{ +class IFriendSettings { public: - enum class AutoAcceptCall - { - None = 0x00, - Audio = 0x01, - Video = 0x02, - AV = Audio | Video - }; + enum class AutoAcceptCall { None = 0x00, Audio = 0x01, Video = 0x02, AV = Audio | Video }; Q_DECLARE_FLAGS(AutoAcceptCallFlags, AutoAcceptCall) virtual ~IFriendSettings() = default; @@ -68,4 +61,4 @@ class IFriendSettings }; Q_DECLARE_OPERATORS_FOR_FLAGS(IFriendSettings::AutoAcceptCallFlags) -#endif // I_FRIEND_SETTINGS_H +#endif // I_FRIEND_SETTINGS_H diff --git a/src/modules/im/src/persistence/igroupsettings.h b/src/modules/im/src/persistence/igroupsettings.h index dce12778..25ed02fa 100644 --- a/src/modules/im/src/persistence/igroupsettings.h +++ b/src/modules/im/src/persistence/igroupsettings.h @@ -17,8 +17,7 @@ #include -class IGroupSettings -{ +class IGroupSettings { public: virtual ~IGroupSettings() = default; virtual QStringList getBlackList() const = 0; diff --git a/src/modules/im/src/persistence/offlinemsgengine.cpp b/src/modules/im/src/persistence/offlinemsgengine.cpp index 9c03bbf8..20ac4604 100644 --- a/src/modules/im/src/persistence/offlinemsgengine.cpp +++ b/src/modules/im/src/persistence/offlinemsgengine.cpp @@ -11,49 +11,46 @@ */ #include "offlinemsgengine.h" +#include +#include +#include +#include #include "src/core/core.h" #include "src/model/friend.h" #include "src/model/status.h" #include "src/nexus.h" #include "src/persistence/profile.h" #include "src/persistence/settings.h" -#include -#include -#include -#include -OfflineMsgEngine::OfflineMsgEngine(const FriendId *frnd, - ICoreFriendMessageSender *messageSender) - : f(frnd), messageSender(messageSender) {} +OfflineMsgEngine::OfflineMsgEngine(const FriendId* frnd, ICoreFriendMessageSender* messageSender) + : f(frnd), messageSender(messageSender) {} /** * @brief Notification that the message is now receipt by peer. * */ void OfflineMsgEngine::onReceiptReceived(MsgId receipt) { - - qDebug() << __func__ << receipt; + qDebug() << __func__ << receipt; QMutexLocker ml(&mutex); - if (receivedReceipts.contains(receipt)) { - qWarning() << "Receievd duplicate receipt" << receipt << "from friend" - << f->getId(); - return; - } - receivedReceipts.append(receipt); -// checkForCompleteMessages(receipt); - - if(receipt.isEmpty()){ - qWarning()<<"receipt is empty!"; - return; - } - - auto msgIt = sentMessages.find(receipt); - if (msgIt == sentMessages.end()) { - return; - } - - receiptMessage(msgIt); + if (receivedReceipts.contains(receipt)) { + qWarning() << "Receievd duplicate receipt" << receipt << "from friend" << f->getId(); + return; + } + receivedReceipts.append(receipt); + // checkForCompleteMessages(receipt); + + if (receipt.isEmpty()) { + qWarning() << "receipt is empty!"; + return; + } + + auto msgIt = sentMessages.find(receipt); + if (msgIt == sentMessages.end()) { + return; + } + + receiptMessage(msgIt); } /** @@ -68,13 +65,12 @@ void OfflineMsgEngine::onReceiptReceived(MsgId receipt) { * @param[in] msg chat message line in the chatlog, used to eventually * set the message's receieved timestamp */ -void OfflineMsgEngine::addUnsentMessage(Message const &message, - CompletionFn completionCallback) { - qDebug() << __func__ << message.content; +void OfflineMsgEngine::addUnsentMessage(Message const& message, CompletionFn completionCallback) { + qDebug() << __func__ << message.content; - QMutexLocker ml(&mutex); - unsentMessages.append(OfflineMessage{ - message, std::chrono::steady_clock::now(), completionCallback}); + QMutexLocker ml(&mutex); + unsentMessages.append( + OfflineMessage{message, std::chrono::steady_clock::now(), completionCallback}); } /** @@ -93,72 +89,67 @@ void OfflineMsgEngine::addUnsentMessage(Message const &message, * set the message's receieved timestamp */ void OfflineMsgEngine::addSentMessage(MsgId receipt, - Message const &message, + Message const& message, CompletionFn completionCallback, ReceiptFn readCallback) { + qDebug() << __func__ << "receipt:" << receipt << "content:" << message.content; - qDebug() << __func__ << "receipt:" <getStatus())) { -// return; -// } - - if (sentMessages.empty() && unsentMessages.empty()) { - return; - } - - QVector messages = - sentMessages.values().toVector() + unsentMessages; - // order messages by authorship time to resend in same order as they were - // written - std::sort(messages.begin(), messages.end(), - [](const OfflineMessage &lhs, const OfflineMessage &rhs) { - return lhs.authorshipTime < rhs.authorshipTime; - }); - removeAllMessages(); - - for (const auto &message : messages) { - QString messageText = message.message.content; - MsgId receipt; - bool messageSent{false}; - if (message.message.isAction) { - messageSent = messageSender->sendAction(f->getId(), messageText, receipt); - } else { - messageSent = messageSender->sendMessage(f->getId(), messageText, receipt); + QMutexLocker ml(&mutex); + + // if (!Status::isOnline(f->getStatus())) { + // return; + // } + + if (sentMessages.empty() && unsentMessages.empty()) { + return; } - if (messageSent) { - qDebug() <<"receipt:"< messages = sentMessages.values().toVector() + unsentMessages; + // order messages by authorship time to resend in same order as they were + // written + std::sort(messages.begin(), messages.end(), + [](const OfflineMessage& lhs, const OfflineMessage& rhs) { + return lhs.authorshipTime < rhs.authorshipTime; + }); + removeAllMessages(); + + for (const auto& message : messages) { + QString messageText = message.message.content; + MsgId receipt; + bool messageSent{false}; + if (message.message.isAction) { + messageSent = messageSender->sendAction(f->getId(), messageText, receipt); + } else { + messageSent = messageSender->sendMessage(f->getId(), messageText, receipt); + } + if (messageSent) { + qDebug() << "receipt:" << receipt; + addSentMessage(receipt, message.message, message.completionFn, message.receiptFn); + } else { + qCritical() << "deliverOfflineMsgs failed to send message"; + addUnsentMessage(message.message, message.completionFn); + } } - } } -bool OfflineMsgEngine::isFromThis(const Message &msg) -{ - if(sentMessages.contains(msg.id)){ +bool OfflineMsgEngine::isFromThis(const Message& msg) { + if (sentMessages.contains(msg.id)) { return true; } return false; @@ -168,19 +159,18 @@ bool OfflineMsgEngine::isFromThis(const Message &msg) * @brief Removes all messages which are being tracked. */ void OfflineMsgEngine::removeAllMessages() { - QMutexLocker ml(&mutex); - receivedReceipts.clear(); - sentMessages.clear(); - unsentMessages.clear(); + QMutexLocker ml(&mutex); + receivedReceipts.clear(); + sentMessages.clear(); + unsentMessages.clear(); } void OfflineMsgEngine::completeMessage(QMap::iterator msgIt) { - msgIt->completionFn(); -// sentMessages.erase(msgIt); + msgIt->completionFn(); + // sentMessages.erase(msgIt); } -void OfflineMsgEngine::receiptMessage(QMap::iterator msgIt) -{ +void OfflineMsgEngine::receiptMessage(QMap::iterator msgIt) { qDebug() << __func__ << msgIt.key(); msgIt->receiptFn(); receivedReceipts.removeOne(msgIt.key()); @@ -188,22 +178,22 @@ void OfflineMsgEngine::receiptMessage(QMap::iterator msgI } void OfflineMsgEngine::checkForCompleteMessages(MsgId receipt) { - qDebug() << __func__ << receipt; - if(receipt.isEmpty()){ - qWarning()<<"receipt is empty!"; - return; - } - - auto msgIt = sentMessages.find(receipt); - if (msgIt == sentMessages.end()) { - return; - } - -// const bool receiptReceived = receivedReceipts.contains(receipt); -// if (!receiptReceived) { -// return; -// } - - //发送消息即标识成功 + qDebug() << __func__ << receipt; + if (receipt.isEmpty()) { + qWarning() << "receipt is empty!"; + return; + } + + auto msgIt = sentMessages.find(receipt); + if (msgIt == sentMessages.end()) { + return; + } + + // const bool receiptReceived = receivedReceipts.contains(receipt); + // if (!receiptReceived) { + // return; + // } + + // 发送消息即标识成功 completeMessage(msgIt); } diff --git a/src/modules/im/src/persistence/offlinemsgengine.h b/src/modules/im/src/persistence/offlinemsgengine.h index b32b2c81..f51ac8bb 100644 --- a/src/modules/im/src/persistence/offlinemsgengine.h +++ b/src/modules/im/src/persistence/offlinemsgengine.h @@ -30,8 +30,7 @@ class Friend; class ICoreFriendMessageSender; -class OfflineMsgEngine : public QObject -{ +class OfflineMsgEngine : public QObject { Q_OBJECT public: using CompletionFn = std::function; @@ -39,20 +38,18 @@ class OfflineMsgEngine : public QObject explicit OfflineMsgEngine(const FriendId* f, ICoreFriendMessageSender* messageSender); void addUnsentMessage(Message const& message, CompletionFn completionCallback); - void addSentMessage(MsgId receipt, Message const& message, - CompletionFn completionCallback, + void addSentMessage(MsgId receipt, Message const& message, CompletionFn completionCallback, ReceiptFn receiptCallback); void deliverOfflineMsgs(); - bool isFromThis(const Message &msg); + bool isFromThis(const Message& msg); public slots: void removeAllMessages(); void onReceiptReceived(MsgId receipt); private: - struct OfflineMessage - { + struct OfflineMessage { Message message; std::chrono::time_point authorshipTime; CompletionFn completionFn; @@ -74,4 +71,4 @@ private slots: QVector unsentMessages; }; -#endif // OFFLINEMSGENGINE_H +#endif // OFFLINEMSGENGINE_H diff --git a/src/modules/im/src/persistence/paths.cpp b/src/modules/im/src/persistence/paths.cpp index 542ba556..3d362ca0 100644 --- a/src/modules/im/src/persistence/paths.cpp +++ b/src/modules/im/src/persistence/paths.cpp @@ -37,7 +37,7 @@ const QLatin1String TCSToxFileFolder{"~/Library/Application Support/Tox"}; #else const QLatin1String TCSToxFileFolder{"~/.config/tox/"}; #endif -} // namespace +} // namespace /** * @class Profile @@ -71,32 +71,32 @@ const QLatin1String TCSToxFileFolder{"~/.config/tox/"}; * @param mode * @return Pointer to Paths object on success, nullptr else */ -Paths* Paths::makePaths(Portable mode) -{ +Paths* Paths::makePaths(Portable mode) { bool portable = false; const QString basePortable = qApp->applicationDirPath(); - const QString baseNonPortable = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); + const QString baseNonPortable = + QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); const QString portableSettingsPath = basePortable % QDir::separator() % globalSettingsFile; switch (mode) { - case Portable::Portable: - qDebug() << "Forcing portable"; - portable = true; - break; - case Portable::NonPortable: - qDebug() << "Forcing non-portable"; - portable = false; - break; - case Portable::Auto: - // auto detect - if (QFile{portableSettingsPath}.exists()) { - qDebug() << "Automatic portable"; + case Portable::Portable: + qDebug() << "Forcing portable"; portable = true; - } else { - qDebug() << "Automatic non-portable"; + break; + case Portable::NonPortable: + qDebug() << "Forcing non-portable"; portable = false; - } - break; + break; + case Portable::Auto: + // auto detect + if (QFile{portableSettingsPath}.exists()) { + qDebug() << "Automatic portable"; + portable = true; + } else { + qDebug() << "Automatic non-portable"; + portable = false; + } + break; } QString basePath = portable ? basePortable : baseNonPortable; @@ -109,26 +109,19 @@ Paths* Paths::makePaths(Portable mode) return new Paths(basePath, portable); } -Paths::Paths(const QString& basePath, bool portable) - : basePath{basePath} - , portable{portable} -{} +Paths::Paths(const QString& basePath, bool portable) : basePath{basePath}, portable{portable} {} /** * @brief Check if qTox is running in portable mode. * @return True if running in portable mode, false else. */ -bool Paths::isPortable() const -{ - return portable; -} +bool Paths::isPortable() const { return portable; } /** * @brief Returns the path to the global settings file "qtox.ini" * @return The path to the folder. */ -QString Paths::getGlobalSettingsPath() const -{ +QString Paths::getGlobalSettingsPath() const { QString path; if (portable) { @@ -150,8 +143,7 @@ QString Paths::getGlobalSettingsPath() const * @brief Get the folder where profile specific information is stored, e.g. .ini * @return The path to the folder. */ -QString Paths::getProfilesDir() const -{ +QString Paths::getProfilesDir() const { return basePath % QDir::separator() % profileFolder % QDir::separator(); } @@ -160,34 +152,33 @@ QString Paths::getProfilesDir() const * @note Expect a change here, since TCS will probably be updated. * @return The path to the folder on success, empty string else. */ -QString Paths::getToxSaveDir() const -{ +QString Paths::getToxSaveDir() const { if (isPortable()) { return basePath % QDir::separator() % profileFolder % QDir::separator(); } - // GenericDataLocation would be a better solution, but we keep this code for backward - // compatibility + // GenericDataLocation would be a better solution, but we keep this code for backward + // compatibility // workaround for https://bugreports.qt-project.org/browse/QTBUG-38845 #ifdef Q_OS_WIN // TODO(sudden6): this doesn't really follow the Tox Client Standard and probably // breaks when %APPDATA% is changed - return QDir::cleanPath(QStandardPaths::writableLocation(QStandardPaths::HomeLocation) - + QDir::separator() + "AppData" + QDir::separator() + "Roaming" - + QDir::separator() + "tox") - + QDir::separator(); + return QDir::cleanPath(QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + + QDir::separator() + "AppData" + QDir::separator() + "Roaming" + + QDir::separator() + "tox") + + QDir::separator(); #elif defined(Q_OS_OSX) - return QDir::cleanPath(QStandardPaths::writableLocation(QStandardPaths::HomeLocation) - + QDir::separator() + "Library" + QDir::separator() - + "Application Support" + QDir::separator() + "Tox") - + QDir::separator(); + return QDir::cleanPath(QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + + QDir::separator() + "Library" + QDir::separator() + + "Application Support" + QDir::separator() + "Tox") + + QDir::separator(); #else // TODO(sudden6): This does not respect the XDG_* environment variables and also // stores user data in a config location - return QDir::cleanPath(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) - + QDir::separator() + "tox") - + QDir::separator(); + return QDir::cleanPath(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + + QDir::separator() + "tox") + + QDir::separator(); #endif } @@ -196,8 +187,7 @@ QString Paths::getToxSaveDir() const * @note Expect a change here, since TCS will probably be updated. * @return The path to the folder on success, empty string else. */ -QString Paths::getAvatarsDir() const -{ +QString Paths::getAvatarsDir() const { // follow the layout in // https://tox.gitbooks.io/tox-client-standard/content/data_storage/export_format.html QString path = getToxSaveDir(); @@ -213,8 +203,7 @@ QString Paths::getAvatarsDir() const * @brief Get the folder where screenshots are stored * @return The path to the folder. */ -QString Paths::getScreenshotsDir() const -{ +QString Paths::getScreenshotsDir() const { return basePath % QDir::separator() % screenshotsFolder % QDir::separator(); } @@ -222,8 +211,7 @@ QString Paths::getScreenshotsDir() const * @brief Get the folder where file transfer data is stored * @return The path to the folder. */ -QString Paths::getTransfersDir() const -{ +QString Paths::getTransfersDir() const { return basePath % QDir::separator() % transfersFolder % QDir::separator(); } @@ -232,8 +220,7 @@ QString Paths::getTransfersDir() const * @return A list of directories sorted from most important to least important. * @note Users of this function should use the theme from the folder that appears first in the list. */ -QStringList Paths::getThemeDirs() const -{ +QStringList Paths::getThemeDirs() const { QStringList themeFolders{}; if (!isPortable()) { diff --git a/src/modules/im/src/persistence/paths.h b/src/modules/im/src/persistence/paths.h index ff15a0ef..4b560816 100644 --- a/src/modules/im/src/persistence/paths.h +++ b/src/modules/im/src/persistence/paths.h @@ -16,13 +16,12 @@ #include #include -class Paths -{ +class Paths { public: enum class Portable { - Auto, /** Auto detect if portable or non-portable */ - Portable, /** Force portable mode */ - NonPortable /** Force non-portable mode */ + Auto, /** Auto detect if portable or non-portable */ + Portable, /** Force portable mode */ + NonPortable /** Force non-portable mode */ }; static Paths* makePaths(Portable mode = Portable::Auto); @@ -37,11 +36,11 @@ class Paths QString getScreenshotsDir() const; private: - Paths(const QString &basePath, bool portable); + Paths(const QString& basePath, bool portable); private: QString basePath{}; bool portable = false; }; -#endif // PATHS_H +#endif // PATHS_H diff --git a/src/modules/im/src/persistence/profile.cpp b/src/modules/im/src/persistence/profile.cpp index 95503620..38032e0e 100644 --- a/src/modules/im/src/persistence/profile.cpp +++ b/src/modules/im/src/persistence/profile.cpp @@ -19,6 +19,8 @@ #include #include +#include "base/OkSettings.h" +#include "base/images.h" #include "profile.h" #include "profilelocker.h" #include "settings.h" @@ -29,8 +31,6 @@ #include "src/widget/gui.h" #include "src/widget/tool/identicon.h" #include "src/widget/widget.h" -#include "base/images.h" -#include "base/OkSettings.h" /** * @class Profile @@ -45,64 +45,65 @@ QStringList Profile::profiles; -void Profile::initCore(const QByteArray &toxsave, ICoreSettings &s, - bool isNewProfile) { - if (toxsave.isEmpty() && !isNewProfile) { - qCritical() << "Existing toxsave is empty"; - emit failedToStart(); - } - - if (!toxsave.isEmpty() && isNewProfile) { - qCritical() << "New profile has toxsave data"; - emit failedToStart(); - } - - Core::ToxCoreErrors err; - core = Core::makeToxCore(toxsave, &s, &err); - if (!core) { - switch (err) { - case Core::ToxCoreErrors::BAD_PROXY: - emit badProxy(); - break; - case Core::ToxCoreErrors::ERROR_ALLOC: - case Core::ToxCoreErrors::FAILED_TO_START: - case Core::ToxCoreErrors::INVALID_SAVE: - default: - emit failedToStart(); - } - - qDebug() << "failed to start ToxCore"; - return; - } - - // save tox file when Core requests it - connect(core.get(), &Core::saveRequest, this, &Profile::onSaveToxSave); - // react to avatar changes - connect(core.get(), &Core::friendAvatarRemoved, this, &Profile::removeAvatar); - connect(core.get(), &Core::friendAvatarChanged, this, - &Profile::setFriendAvatar); - connect(core.get(), &Core::fileAvatarOfferReceived, this, - &Profile::onAvatarOfferReceived, - Qt::ConnectionType::QueuedConnection); -} - -Profile::Profile(QString name, const QString &password, bool isNewProfile, - const QByteArray &toxsave, std::unique_ptr passkey) - : name{name}, passkey{std::move(passkey)}, isRemoved{false}, - encrypted{this->passkey != nullptr} { - - qDebug() << "Initialize profile for" << name; - - Settings &s = Settings::getInstance(); - // Core settings are saved per profile, need to load them before starting Core - s.loadPersonal(name, this->passkey.get()); - - // TODO(kriby): Move/refactor core initialization to remove settings - // dependency - // note to self: use slots/signals for this? - initCore(toxsave, s, isNewProfile); - - loadDatabase(password); +void Profile::initCore(const QByteArray& toxsave, ICoreSettings& s, bool isNewProfile) { + if (toxsave.isEmpty() && !isNewProfile) { + qCritical() << "Existing toxsave is empty"; + emit failedToStart(); + } + + if (!toxsave.isEmpty() && isNewProfile) { + qCritical() << "New profile has toxsave data"; + emit failedToStart(); + } + + Core::ToxCoreErrors err; + core = Core::makeToxCore(host, name, password, toxsave, &s, &err); + if (!core) { + switch (err) { + case Core::ToxCoreErrors::BAD_PROXY: + emit badProxy(); + break; + case Core::ToxCoreErrors::ERROR_ALLOC: + case Core::ToxCoreErrors::FAILED_TO_START: + case Core::ToxCoreErrors::INVALID_SAVE: + default: + emit failedToStart(); + } + + qDebug() << "failed to start ToxCore"; + return; + } + + // save tox file when Core requests it + connect(core.get(), &Core::saveRequest, this, &Profile::onSaveToxSave); + // react to avatar changes + connect(core.get(), &Core::friendAvatarRemoved, this, &Profile::removeFriendAvatar); + connect(core.get(), &Core::friendAvatarChanged, this, &Profile::setFriendAvatar); +// connect(core.get(), &Core::fileAvatarOfferReceived, this, &Profile::onAvatarOfferReceived, +// Qt::ConnectionType::QueuedConnection); +} + +Profile::Profile(const QString& host, + const QString& name, + const QString& password, + bool isNewProfile) + : host{host} + , name{name} + , password{password} + , isRemoved{false} + , encrypted{this->passkey != nullptr} { + qDebug() << "Initialize profile for" << name; + + Settings& s = Settings::getInstance(); + // Core settings are saved per profile, need to load them before starting Core + s.loadPersonal(name, this->passkey.get()); + + // TODO(kriby): Move/refactor core initialization to remove settings + // dependency + // note to self: use slots/signals for this? + initCore(toxsave, s, isNewProfile); + + loadDatabase(password); } /** @@ -114,83 +115,84 @@ Profile::Profile(QString name, const QString &password, bool isNewProfile, * * @example If the profile is already in use return nullptr. */ -Profile *Profile::loadProfile(QString name, const QCommandLineParser *parser, - const QString &password) { - if (ProfileLocker::hasLock()) { - qCritical() << "Tried to load profile " << name - << ", but another profile is already locked!"; - return nullptr; - } +Profile* Profile::loadProfile(QString host, + QString name, + const QCommandLineParser* parser, + const QString& password) { + if (ProfileLocker::hasLock()) { + qCritical() << "Tried to load profile " << name + << ", but another profile is already locked!"; + return nullptr; + } - if (!ProfileLocker::lock(name)) { - qWarning() << "Failed to lock profile " << name; - return nullptr; - } - - std::unique_ptr tmpKey = nullptr; - QByteArray data = QByteArray(); - Profile *p = nullptr; - qint64 fileSize = 0; - - Settings &s = Settings::getInstance(); - QString path = s.getSettingsDirPath() + name + ".tox"; - QFile saveFile(path); - qDebug() << "Loading tox save " << path; - - if (!saveFile.exists()) { - qWarning() << "The tox save file " << path << " was not found"; - goto fail; - } - - if (!saveFile.open(QIODevice::ReadOnly)) { - qCritical() << "The tox save file " << path << " couldn't' be opened"; - goto fail; - } - - fileSize = saveFile.size(); - if (fileSize <= 0) { - qWarning() << "The tox save file" << path << " is empty!"; - goto fail; - } - - data = saveFile.readAll(); - // if (ToxEncrypt::isEncrypted(data)) { - // if (password.isEmpty()) { - // qCritical() - // << "The tox save file is encrypted, but we don't have a - // password!"; - // goto fail; - // } - // - // tmpKey = ToxEncrypt::makeToxEncrypt(password, data); - // if (!tmpKey) { - // qCritical() << "Failed to derive key of the tox save file"; - // goto fail; - // } - // - // data = tmpKey->decrypt(data); - // if (data.isEmpty()) { - // qCritical() << "Failed to decrypt the tox save file"; - // goto fail; - // } - // } else { - // if (!password.isEmpty()) { - // qWarning() - // << "We have a password, but the tox save file is not encrypted"; - // } - // } - - saveFile.close(); - p = new Profile(name, password, false, data, std::move(tmpKey)); - - s.updateProfileData(p, parser); - return p; + if (!ProfileLocker::lock(name)) { + qWarning() << "Failed to lock profile " << name; + return nullptr; + } + + std::unique_ptr tmpKey = nullptr; + QByteArray data = QByteArray(); + Profile* p = nullptr; + qint64 fileSize = 0; + + Settings& s = Settings::getInstance(); + QString path = s.getSettingsDirPath() + name + ".tox"; + QFile saveFile(path); + qDebug() << "Loading tox save " << path; + + if (!saveFile.exists()) { + qWarning() << "The tox save file " << path << " was not found"; + goto fail; + } + + if (!saveFile.open(QIODevice::ReadOnly)) { + qCritical() << "The tox save file " << path << " couldn't' be opened"; + goto fail; + } + + fileSize = saveFile.size(); + if (fileSize <= 0) { + qWarning() << "The tox save file" << path << " is empty!"; + goto fail; + } + + data = saveFile.readAll(); + // if (ToxEncrypt::isEncrypted(data)) { + // if (password.isEmpty()) { + // qCritical() + // << "The tox save file is encrypted, but we don't have a + // password!"; + // goto fail; + // } + // + // tmpKey = ToxEncrypt::makeToxEncrypt(password, data); + // if (!tmpKey) { + // qCritical() << "Failed to derive key of the tox save file"; + // goto fail; + // } + // + // data = tmpKey->decrypt(data); + // if (data.isEmpty()) { + // qCritical() << "Failed to decrypt the tox save file"; + // goto fail; + // } + // } else { + // if (!password.isEmpty()) { + // qWarning() + // << "We have a password, but the tox save file is not encrypted"; + // } + // } + + saveFile.close(); + p = new Profile(host, name, password, false); + s.updateProfileData(p, parser); + return p; // cleanup in case of error fail: - saveFile.close(); - ProfileLocker::unlock(); - return nullptr; + saveFile.close(); + ProfileLocker::unlock(); + return nullptr; } /** @@ -201,52 +203,51 @@ Profile *Profile::loadProfile(QString name, const QCommandLineParser *parser, * * @note If the profile is already in use return nullptr. */ -Profile *Profile::createProfile(QString name, const QCommandLineParser *parser, +Profile* Profile::createProfile(QString host, + QString name, + const QCommandLineParser* parser, QString password) { - - std::unique_ptr tmpKey; - if (!password.isEmpty()) { - tmpKey = ToxEncrypt::makeToxEncrypt(password); - if (!tmpKey) { - qCritical() << "Failed to derive key for the tox save"; - return nullptr; + std::unique_ptr tmpKey; + if (!password.isEmpty()) { + tmpKey = ToxEncrypt::makeToxEncrypt(password); + if (!tmpKey) { + qCritical() << "Failed to derive key for the tox save"; + return nullptr; + } } - } - if (ProfileLocker::hasLock()) { - qCritical() << "Tried to create profile " << name - << ", but another profile is already locked!"; - return nullptr; - } + if (ProfileLocker::hasLock()) { + qCritical() << "Tried to create profile " << name + << ", but another profile is already locked!"; + return nullptr; + } - if (exists(name)) { - qCritical() << "Tried to create profile " << name - << ", but it already exists!"; - return nullptr; - } + if (exists(name)) { + qCritical() << "Tried to create profile " << name << ", but it already exists!"; + return nullptr; + } - if (!ProfileLocker::lock(name)) { - qWarning() << "Failed to lock profile " << name; - return nullptr; - } +// if (!ProfileLocker::lock(name)) { +// qWarning() << "Failed to lock profile " << name; +// return nullptr; +// } - Settings::getInstance().createPersonal(name); - Profile *p = - new Profile(name, password, true, QByteArray(), std::move(tmpKey)); - return p; + Settings::getInstance().createPersonal(name); + Profile* p = new Profile(host, name, password, true); + return p; } Profile::~Profile() { - if (isRemoved) { - return; - } + if (isRemoved) { + return; + } - onSaveToxSave(); - Settings::getInstance().savePersonal(this); - Settings::getInstance().sync(); - ProfileLocker::assertLock(); - assert(ProfileLocker::getCurLockName() == name); - ProfileLocker::unlock(); + onSaveToxSave(); + Settings::getInstance().savePersonal(this); + Settings::getInstance().sync(); + ProfileLocker::assertLock(); + assert(ProfileLocker::getCurLockName() == name); + ProfileLocker::unlock(); } /** @@ -255,17 +256,17 @@ Profile::~Profile() { * @return Vector of filenames. */ QStringList Profile::getFilesByExt(QString extension) { - QDir dir(Settings::getInstance().getSettingsDirPath()); - QStringList out; - dir.setFilter(QDir::Files | QDir::NoDotAndDotDot); - dir.setNameFilters(QStringList("*." + extension)); - QFileInfoList list = dir.entryInfoList(); - out.reserve(list.size()); - for (QFileInfo file : list) { - out += file.completeBaseName(); - } + QDir dir(Settings::getInstance().getSettingsDirPath()); + QStringList out; + dir.setFilter(QDir::Files | QDir::NoDotAndDotDot); + dir.setNameFilters(QStringList("*." + extension)); + QFileInfoList list = dir.entryInfoList(); + out.reserve(list.size()); + for (QFileInfo file : list) { + out += file.completeBaseName(); + } - return out; + return out; } /** @@ -273,28 +274,25 @@ QStringList Profile::getFilesByExt(QString extension) { * @warning NOT thread-safe. */ const QStringList Profile::getAllProfileNames() { - profiles.clear(); - QStringList toxfiles = getFilesByExt("tox"), inifiles = getFilesByExt("ini"); - for (const QString &toxfile : toxfiles) { - if (!inifiles.contains(toxfile)) { - Settings::getInstance().createPersonal(toxfile); - } + profiles.clear(); + QStringList toxfiles = getFilesByExt("tox"), inifiles = getFilesByExt("ini"); + for (const QString& toxfile : toxfiles) { + if (!inifiles.contains(toxfile)) { + Settings::getInstance().createPersonal(toxfile); + } - profiles.append(toxfile); - } - return profiles; + profiles.append(toxfile); + } + return profiles; } -Core *Profile::getCore() { - return core.get(); -} +Core* Profile::getCore() { return core.get(); } const QString& Profile::getName() const { return name; } -const QString& Profile::getDisplayName() -{ +const QString& Profile::getDisplayName() { nick = core->getNick(); - if(!nick.isEmpty()){ + if (!nick.isEmpty()) { return nick; } return name; @@ -304,33 +302,31 @@ const QString& Profile::getDisplayName() * @brief Starts the Core thread */ void Profile::startCore() { - qDebug() <<__func__; + qDebug() << __func__; - connect(core.get(), &Core::requestSent, this, &Profile::onRequestSent); - core->start(); + connect(core.get(), &Core::requestSent, this, &Profile::onRequestSent); + core->start(); - emit coreChanged(*core); + emit coreChanged(*core); - // const ToxId &selfId = core->getSelfId(); - // const ToxPk &selfPk = selfId.getPublicKey(); - // const QByteArray data = loadAvatarData(selfPk); - // if (data.isEmpty()) { - // qDebug() << "Self avatar not found, will broadcast empty avatar to - // friends"; - // } - // // TODO(sudden6): moved here, because it crashes in the constructor - // // reason: Core::getInstance() returns nullptr, because it's not yet - // // initialized solution: kill Core::getInstance - // setAvatar(data); + // const ToxId &selfId = core->getSelfId(); + // const ToxPk &selfPk = selfId.getPublicKey(); + // const QByteArray data = loadAvatarData(selfPk); + // if (data.isEmpty()) { + // qDebug() << "Self avatar not found, will broadcast empty avatar to + // friends"; + // } + // // TODO(sudden6): moved here, because it crashes in the constructor + // // reason: Core::getInstance() returns nullptr, because it's not yet + // // initialized solution: kill Core::getInstance + // setAvatar(data); } -void Profile::stopCore() -{ - qDebug() <<__func__; +void Profile::stopCore() { + qDebug() << __func__; disconnect(core.get(), &Core::requestSent, this, &Profile::onRequestSent); core->stop(); - } /** @@ -338,20 +334,12 @@ void Profile::stopCore() * @warning Invalid on deleted profiles. */ void Profile::onSaveToxSave() { - QByteArray data = core->getToxSaveData(); - if (!data.size()) { - return; - } - // assert(data.size()); - saveToxSave(data); -} - -// TODO(sudden6): handle this better maybe? -void Profile::onAvatarOfferReceived(QString friendId, QString fileId, - const QByteArray &avatarHash) { - // accept if we don't have it already -// const bool accept = getAvatarHash(core->getFriendPublicKey(friendId)) != avatarHash; -// core->getCoreFile()->handleAvatarOffer(friendId, fileId, accept); + QByteArray data = core->getToxSaveData(); + if (!data.size()) { + return; + } + // assert(data.size()); + saveToxSave(data); } /** @@ -362,38 +350,38 @@ void Profile::onAvatarOfferReceived(QString friendId, QString fileId, * @warning Invalid on deleted profiles. */ bool Profile::saveToxSave(QByteArray data) { - assert(!isRemoved); - ProfileLocker::assertLock(); - assert(ProfileLocker::getCurLockName() == name); - - QString path = Settings::getInstance().getSettingsDirPath() + name + ".tox"; - qDebug() << "Saving tox save to " << path; - QSaveFile saveFile(path); - if (!saveFile.open(QIODevice::WriteOnly)) { - qCritical() << "Tox save file " << path << " couldn't be opened"; - return false; - } + assert(!isRemoved); + ProfileLocker::assertLock(); + assert(ProfileLocker::getCurLockName() == name); + + QString path = Settings::getInstance().getSettingsDirPath() + name + ".tox"; + qDebug() << "Saving tox save to " << path; + QSaveFile saveFile(path); + if (!saveFile.open(QIODevice::WriteOnly)) { + qCritical() << "Tox save file " << path << " couldn't be opened"; + return false; + } - if (encrypted) { - data = passkey->encrypt(data); - if (data.isEmpty()) { - qCritical() << "Failed to encrypt, can't save!"; - saveFile.cancelWriting(); - return false; + if (encrypted) { + data = passkey->encrypt(data); + if (data.isEmpty()) { + qCritical() << "Failed to encrypt, can't save!"; + saveFile.cancelWriting(); + return false; + } } - } - saveFile.write(data); + saveFile.write(data); - // check if everything got written - if (saveFile.flush()) { - saveFile.commit(); - } else { - saveFile.cancelWriting(); - qCritical() << "Failed to write, can't save!"; - return false; - } - return true; + // check if everything got written + if (saveFile.flush()) { + saveFile.commit(); + } else { + saveFile.cancelWriting(); + qCritical() << "Failed to write, can't save!"; + return false; + } + return true; } /** @@ -404,28 +392,28 @@ bool Profile::saveToxSave(QByteArray data) { * if this is an encrypted profile. * @return Path to the avatar. */ -QString Profile::avatarPath(const ContactId &owner, bool forceUnencrypted) { - auto ownerStr = owner.toString(); - auto base=Settings::getInstance().getSettingsDirPath(); - return base + "avatars/" + ownerStr + ".png"; +QString Profile::avatarPath(const ContactId& owner, bool forceUnencrypted) { + auto ownerStr = owner.toString(); + auto base = Settings::getInstance().getSettingsDirPath(); + return base + "avatars/" + ownerStr + ".png"; } /** * @brief Get our avatar from cache. * @return Avatar as QPixmap. */ -const QPixmap & Profile::loadAvatar() { - if(pixmap.isNull()) - { - //加载本地 - pixmap= loadAvatar(core->getSelfPeerId().getPublicKey()); +const QPixmap& Profile::loadAvatar() { + if (pixmap.isNull()) { + // 加载本地 + pixmap = loadAvatar(core->getSelfPeerId().getPublicKey()); } - if(pixmap.isNull()){ + if (pixmap.isNull()) { if (Settings::getInstance().getShowIdenticons()) { - pixmap = QPixmap::fromImage(Identicon(core->getSelfPeerId().getPublicKey().getByteArray()).toImage(16)); + pixmap = QPixmap::fromImage( + Identicon(core->getSelfPeerId().getPublicKey().getByteArray()).toImage(16)); } } - return pixmap; + return pixmap; } /** @@ -433,11 +421,11 @@ const QPixmap & Profile::loadAvatar() { * @param owner IMFriend PK to load avatar. * @return Avatar as QPixmap. */ -QPixmap Profile::loadAvatar(const ContactId &owner) { +QPixmap Profile::loadAvatar(const ContactId& owner) { QPixmap pixmap; const QByteArray avatarData = loadAvatarData(owner); - if(!avatarData.isEmpty()){ - pixmap.loadFromData(avatarData); + if (!avatarData.isEmpty()) { + pixmap.loadFromData(avatarData); } return pixmap; } @@ -447,51 +435,49 @@ QPixmap Profile::loadAvatar(const ContactId &owner) { * @param owner IMFriend PK to load avatar. * @return Avatar as QByteArray. */ -QByteArray Profile::loadAvatarData(const ContactId &owner) { +QByteArray Profile::loadAvatarData(const ContactId& owner) { qDebug() << __func__ << owner.toString(); - QString path = avatarPath(owner); - qDebug() << "read:"<(getDbPath(name), password, salt); - if (database && database->isOpen()) { - history.reset(new History(database)); - ok = history->isValid(); - } - if(!ok){ - qWarning() << "Failed to load database for profile" << name; - GUI::showError( - QObject::tr("Error"), - QObject::tr("Couldn't open your chat logs, they will be exit.")); - qApp->exit(1); - } + assert(core); + + if (isRemoved) { + qDebug() << "Can't load database of removed profile"; + return; + } + + QByteArray salt = password.toUtf8(); + qDebug() << "Create database for" << name; + + bool ok = false; + database = std::make_shared(getDbPath(name), password, salt); + if (database && database->isOpen()) { + history.reset(new History(database)); + ok = history->isValid(); + } + if (!ok) { + qWarning() << "Failed to load database for profile" << name; + GUI::showError(QObject::tr("Error"), + QObject::tr("Couldn't open your chat logs, they will be exit.")); + qApp->exit(1); + } } /** @@ -499,35 +485,38 @@ void Profile::loadDatabase(QString password) { * @param pic Picture to use as avatar, if empty an Identicon will be used * depending on settings */ -void Profile::setAvatar(QByteArray pic) { - bool loaded = false; - - QByteArray avatarData; - const FriendId &selfPk = core->getSelfId(); - if (!pic.isEmpty()) { - loaded = pixmap.loadFromData(pic); - avatarData = pic; - } else { - if (Settings::getInstance().getShowIdenticons()) { - const QImage identicon = Identicon(selfPk.getByteArray()).toImage(32); - pixmap = QPixmap::fromImage(identicon); +void Profile::setAvatar(QByteArray pic, bool saveToCore) { + bool loaded = false; + + QByteArray avatarData; + const FriendId& selfPk = core->getSelfId(); + if (!pic.isEmpty()) { + loaded = pixmap.loadFromData(pic); + avatarData = pic; } else { - loaded = pixmap.load(":/img/contact_dark.svg"); + if (Settings::getInstance().getShowIdenticons()) { + const QImage identicon = Identicon(selfPk.getByteArray()).toImage(32); + pixmap = QPixmap::fromImage(identicon); + } else { + loaded = pixmap.load(":/img/contact_dark.svg"); + } + } + qDebug() << "image loaded=>" << loaded; + if (!loaded) { + return; } - } - qDebug() << "image loaded=>" << loaded; - if (!loaded) { - return; - } - qDebug() << "pixmap" << pixmap.size(); - saveAvatar(selfPk, avatarData); + qDebug() << "pixmap" << pixmap.size(); + saveFriendAvatar(selfPk, avatarData); - emit selfAvatarChanged(pixmap); - core->setAvatar(avatarData); + emit selfAvatarChanged(pixmap); + if(saveToCore) core->setAvatar(avatarData); } -void Profile::setAvatarOnly(QPixmap pixmap) { emit selfAvatarChanged(pixmap); } +void Profile::setAvatarOnly(const QPixmap& pixmap_) { + pixmap = pixmap_; + emit selfAvatarChanged(pixmap); +} /** * @brief Sets a friends avatar @@ -535,41 +524,36 @@ void Profile::setAvatarOnly(QPixmap pixmap) { emit selfAvatarChanged(pixmap); } * depending on settings * @param owner pk of friend */ -void Profile::setFriendAvatar(const FriendId owner, const QByteArray & avatarData) { - qDebug() << __func__ << owner.toString() - << "size:" << avatarData.size(); - QPixmap pixmap; - if (!avatarData.isEmpty()) { - bool loaded = - base::Images::putToPixmap(avatarData, pixmap); - if (!loaded) { - return; - } - emit friendAvatarSet(owner, pixmap); - } else if (Settings::getInstance().getShowIdenticons()) { - pixmap =QPixmap::fromImage( Identicon(owner.getByteArray()).toImage(32)); - emit friendAvatarSet(owner, pixmap); - } else { - pixmap.load(":/img/contact_dark.svg"); - emit friendAvatarRemoved(owner); - } - friendAvatarChanged(owner, pixmap); - saveAvatar(owner, avatarData); -} - -void Profile::saveFriendAlias(const QString &friendPk, const QString &alias) -{ +void Profile::setFriendAvatar(const FriendId& owner, const QByteArray& avatarData) { + qDebug() << __func__ << owner.toString() << "size:" << avatarData.size(); + QPixmap pixmap; + if (!avatarData.isEmpty()) { + bool loaded = base::Images::putToPixmap(avatarData, pixmap); + if (!loaded) { + return; + } + emit friendAvatarSet(owner, pixmap); + } else if (Settings::getInstance().getShowIdenticons()) { + pixmap = QPixmap::fromImage(Identicon(owner.getByteArray()).toImage(32)); + emit friendAvatarSet(owner, pixmap); + } else { + pixmap.load(":/img/contact_dark.svg"); + emit friendAvatarRemoved(owner); + } + friendAvatarChanged(owner, pixmap); + saveFriendAvatar(owner, avatarData); +} + +void Profile::saveFriendAlias(const QString& friendPk, const QString& alias) { history->setFriendAlias(friendPk, alias); } -QString Profile::getFriendAlias(const QString &friendPk) -{ +QString Profile::getFriendAlias(const QString& friendPk) { return history->getFriendAlias(friendPk); } -uint Profile::addContact(const ContactId &cid) -{ - qDebug() << __func__<addNewContact(cid.toString()); } @@ -579,39 +563,38 @@ uint Profile::addContact(const ContactId &cid) * @param friendPk Pk of a friend which request is destined to * @param message Friendship request message */ -void Profile::onRequestSent(const FriendId &friendPk, const QString &message) { - if (!isHistoryEnabled()) { - return; - } +void Profile::onRequestSent(const FriendId& friendPk, const QString& message) { + if (!isHistoryEnabled()) { + return; + } - const QString pkStr = friendPk.toString(); - const QString inviteStr = - Core::tr("/me offers friendship, \"%1\"").arg(message); - const QString selfStr = core->getSelfId().toString(); - const QDateTime datetime = QDateTime::currentDateTime(); - const QString name = core->getUsername(); -// history->addNewMessage(pkStr, inviteStr, selfStr, datetime, true, name); + const QString pkStr = friendPk.toString(); + const QString inviteStr = Core::tr("/me offers friendship, \"%1\"").arg(message); + const QString selfStr = core->getSelfId().toString(); + const QDateTime datetime = QDateTime::currentDateTime(); + const QString name = core->getUsername(); + // history->addNewMessage(pkStr, inviteStr, selfStr, datetime, true, name); } /** * @brief Save an avatar to cache. - * @param pic Picture to save. + * @param avatar Picture to save. * @param owner PK of avatar owner. */ -void Profile::saveAvatar(const FriendId &owner, const QByteArray &pic) { - QString path = avatarPath(owner); - QDir(Settings::getInstance().getSettingsDirPath()).mkdir("avatars"); - if (pic.isEmpty()) { - QFile::remove(path); - } else { - QSaveFile file(path); - if (!file.open(QIODevice::WriteOnly)) { - qWarning() << "Tox avatar " << path << " couldn't be saved"; - return; - } - file.write(pic); - file.commit(); - } +void Profile::saveFriendAvatar(const FriendId& owner, const QByteArray& avatar) { + QString path = avatarPath(owner); + QDir(Settings::getInstance().getSettingsDirPath()).mkdir("avatars"); + if (avatar.isEmpty()) { + QFile::remove(path); + } else { + QSaveFile file(path); + if (!file.open(QIODevice::WriteOnly)) { + qWarning() << "Tox avatar " << path << " couldn't be saved"; + return; + } + file.write(avatar); + file.commit(); + } } /** @@ -619,57 +602,48 @@ void Profile::saveAvatar(const FriendId &owner, const QByteArray &pic) { * @param owner IMFriend PK to get hash. * @return Avatar tox hash. */ -QByteArray Profile::getAvatarHash(const FriendId &owner) { - // QByteArray pic = loadAvatarData(owner); - // QByteArray avatarHash(TOX_HASH_LENGTH, 0); - // tox_hash((uint8_t *)avatarHash.data(), (uint8_t *)pic.data(), pic.size()); - // return avatarHash; - return QByteArray{}; +QByteArray Profile::getFriendAvatarHash(const FriendId& owner) { + // QByteArray pic = loadAvatarData(owner); + // QByteArray avatarHash(TOX_HASH_LENGTH, 0); + // tox_hash((uint8_t *)avatarHash.data(), (uint8_t *)pic.data(), pic.size()); + // return avatarHash; + return QByteArray{}; } /** * @brief Removes our own avatar. */ -void Profile::removeSelfAvatar() { - removeAvatar(core->getSelfPeerId().getPublicKey()); +void Profile::removeAvatar(bool saveToCore) { + removeFriendAvatar(core->getSelfPeerId().getPublicKey()); + if(saveToCore){ + //TODO 用默认头像覆盖 + core->setAvatar({}); + } } /** * @brief Removes friend avatar. */ -void Profile::removeFriendAvatar(const FriendId &owner) { removeAvatar(owner); } +void Profile::removeFriendAvatar(const FriendId& owner) { + QFile::remove(avatarPath(owner)); +} /** * @brief Checks that the history is enabled in the settings, and loaded * successfully for this profile. * @return True if enabled, false otherwise. */ -bool Profile::isHistoryEnabled() { - return Settings::getInstance().getEnableLogging() && history; -} +bool Profile::isHistoryEnabled() { return Settings::getInstance().getEnableLogging() && history; } /** * @brief Get chat history. * @return May return a nullptr if the history failed to load. */ -History *Profile::getHistory() { return history.get(); } - -/** - * @brief Removes a cached avatar. - * @param owner IMFriend PK whose avater to delete. - */ -void Profile::removeAvatar(const FriendId &owner) { - QFile::remove(avatarPath(owner)); - if (owner == core->getSelfPeerId().getPublicKey()) { - setAvatar({}); - } else { - setFriendAvatar(owner, {}); - } -} +History* Profile::getHistory() { return history.get(); } bool Profile::exists(QString name) { - QString path = Settings::getInstance().getSettingsDirPath() + name; - return QFile::exists(path + ".tox"); + QString path = Settings::getInstance().getSettingsDirPath() + name; + return QFile::exists(path + ".tox"); } /** @@ -686,18 +660,18 @@ bool Profile::isEncrypted() const { return encrypted; } * @return True if profile is encrypted, false otherwise. */ bool Profile::isEncrypted(QString name) { - // uint8_t data[TOX_PASS_ENCRYPTION_EXTRA_LENGTH] = {0}; - // QString path = Settings::getInstance().getSettingsDirPath() + name + - // ".tox"; QFile saveFile(path); if (!saveFile.open(QIODevice::ReadOnly)) { - // qWarning() << "Couldn't open tox save " << path; - // return false; - // } - // - // saveFile.read((char *)data, TOX_PASS_ENCRYPTION_EXTRA_LENGTH); - // saveFile.close(); - // - // return tox_is_data_encrypted(data); - return false; + // uint8_t data[TOX_PASS_ENCRYPTION_EXTRA_LENGTH] = {0}; + // QString path = Settings::getInstance().getSettingsDirPath() + name + + // ".tox"; QFile saveFile(path); if (!saveFile.open(QIODevice::ReadOnly)) { + // qWarning() << "Couldn't open tox save " << path; + // return false; + // } + // + // saveFile.read((char *)data, TOX_PASS_ENCRYPTION_EXTRA_LENGTH); + // saveFile.close(); + // + // return tox_is_data_encrypted(data); + return false; } /** @@ -708,47 +682,46 @@ bool Profile::isEncrypted(QString name) { * profile. */ QStringList Profile::remove() { - if (isRemoved) { - qWarning() << "Profile " << name << " is already removed!"; - return {}; - } - isRemoved = true; + if (isRemoved) { + qWarning() << "Profile " << name << " is already removed!"; + return {}; + } + isRemoved = true; - qDebug() << "Removing profile" << name; - for (int i = 0; i < profiles.size(); ++i) { - if (profiles[i] == name) { - profiles.removeAt(i); - i--; + qDebug() << "Removing profile" << name; + for (int i = 0; i < profiles.size(); ++i) { + if (profiles[i] == name) { + profiles.removeAt(i); + i--; + } } - } - QString path = Settings::getInstance().getSettingsDirPath() + name; - ProfileLocker::unlock(); + QString path = Settings::getInstance().getSettingsDirPath() + name; + ProfileLocker::unlock(); - QFile profileMain{path + ".tox"}; - QFile profileConfig{path + ".ini"}; + QFile profileMain{path + ".tox"}; + QFile profileConfig{path + ".ini"}; - QStringList ret; + QStringList ret; - if (!profileMain.remove() && profileMain.exists()) { - ret.push_back(profileMain.fileName()); - qWarning() << "Could not remove file " << profileMain.fileName(); - } - if (!profileConfig.remove() && profileConfig.exists()) { - ret.push_back(profileConfig.fileName()); - qWarning() << "Could not remove file " << profileConfig.fileName(); - } + if (!profileMain.remove() && profileMain.exists()) { + ret.push_back(profileMain.fileName()); + qWarning() << "Could not remove file " << profileMain.fileName(); + } + if (!profileConfig.remove() && profileConfig.exists()) { + ret.push_back(profileConfig.fileName()); + qWarning() << "Could not remove file " << profileConfig.fileName(); + } - QString dbPath = getDbPath(name); - if (database && database->isOpen() && !database->remove() && - QFile::exists(dbPath)) { - ret.push_back(dbPath); - qWarning() << "Could not remove file " << dbPath; - } + QString dbPath = getDbPath(name); + if (database && database->isOpen() && !database->remove() && QFile::exists(dbPath)) { + ret.push_back(dbPath); + qWarning() << "Could not remove file " << dbPath; + } - history.reset(); - database.reset(); + history.reset(); + database.reset(); - return ret; + return ret; } /** @@ -757,32 +730,32 @@ QStringList Profile::remove() { * @return False on error, true otherwise. */ bool Profile::rename(QString newName) { - QString path = Settings::getInstance().getSettingsDirPath() + name, - newPath = Settings::getInstance().getSettingsDirPath() + newName; + QString path = Settings::getInstance().getSettingsDirPath() + name, + newPath = Settings::getInstance().getSettingsDirPath() + newName; - if (!ProfileLocker::lock(newName)) { - return false; - } + if (!ProfileLocker::lock(newName)) { + return false; + } - QFile::rename(path + ".tox", newPath + ".tox"); - QFile::rename(path + ".ini", newPath + ".ini"); - if (database) { - database->rename(newName); - } + QFile::rename(path + ".tox", newPath + ".tox"); + QFile::rename(path + ".ini", newPath + ".ini"); + if (database) { + database->rename(newName); + } - auto& qs = ok::base::OkSettings::getInstance(); - bool resetAutorun = qs.getAutorun(); - qs.setAutorun(false); - qs.setCurrentProfile(newName); - if (resetAutorun) { - qs.setAutorun(true); // fixes -p flag in autostart command line - } + auto& qs = ok::base::OkSettings::getInstance(); + bool resetAutorun = qs.getAutorun(); + qs.setAutorun(false); + qs.setCurrentProfile(newName); + if (resetAutorun) { + qs.setAutorun(true); // fixes -p flag in autostart command line + } - name = newName; - return true; + name = newName; + return true; } -const ToxEncrypt *Profile::getPasskey() const { return passkey.get(); } +const ToxEncrypt* Profile::getPasskey() const { return passkey.get(); } /** * @brief Changes the encryption password and re-saves everything with it @@ -792,34 +765,34 @@ const ToxEncrypt *Profile::getPasskey() const { return passkey.get(); } * QString if not yet encrypted. * @return Empty QString on success or error message on failure. */ -QString Profile::setPassword(const QString &newPassword) { - if (newPassword.isEmpty()) { - return {}; - } - // std::unique_ptr newpasskey = - // ToxEncrypt::makeToxEncrypt(newPassword); if (!newpasskey) { - // qCritical() << "Failed to derive key from password, the profile won't - // " - // "use the new password"; - // return tr("Failed to derive key from password, the profile won't use - // the " - // "new password."); - // } - // // apply change - // passkey = std::move(newpasskey); - // encrypted = true; +QString Profile::setPassword(const QString& newPassword) { + if (newPassword.isEmpty()) { + return {}; + } + // std::unique_ptr newpasskey = + // ToxEncrypt::makeToxEncrypt(newPassword); if (!newpasskey) { + // qCritical() << "Failed to derive key from password, the profile won't + // " + // "use the new password"; + // return tr("Failed to derive key from password, the profile won't use + // the " + // "new password."); + // } + // // apply change + // passkey = std::move(newpasskey); + // encrypted = true; - core->setPassword(newPassword); + core->setPassword(newPassword); - // apply new encryption - onSaveToxSave(); + // apply new encryption + onSaveToxSave(); - QString error{}; + QString error{}; - QByteArray avatar = loadAvatarData(core->getSelfPeerId().getPublicKey()); - saveAvatar(core->getSelfPeerId().getPublicKey(), avatar); + QByteArray avatar = loadAvatarData(core->getSelfPeerId().getPublicKey()); + saveFriendAvatar(core->getSelfPeerId().getPublicKey(), avatar); - return error; + return error; } /** @@ -827,6 +800,15 @@ QString Profile::setPassword(const QString &newPassword) { * @param profileName Profile name. * @return Path to database. */ -QString Profile::getDbPath(const QString &profileName) { - return Settings::getInstance().getSettingsDirPath() + profileName + ".db"; +QString Profile::getDbPath(const QString& profileName) { + return Settings::getInstance().getSettingsDirPath() + profileName + ".db"; +} + +void Profile::setNick(const QString& nick_, bool saveToCore) { + if (nick == nick_) return; + + nick = nick_; + emit nickChanged(nick); + + if (saveToCore) core->setNick(nick); } diff --git a/src/modules/im/src/persistence/profile.h b/src/modules/im/src/persistence/profile.h index 911cd36f..f20f15c1 100644 --- a/src/modules/im/src/persistence/profile.h +++ b/src/modules/im/src/persistence/profile.h @@ -29,112 +29,131 @@ class Settings; class QCommandLineParser; +/** + * 个人中心(包含Core) + * 1、对个人帐号的抽象,一个用户登录即产生一个Profile + * 2、包含基本帐号信息 + * 3、维护聊天核心Core + */ class Profile : public QObject { - Q_OBJECT - + Q_OBJECT public: - static Profile *loadProfile(QString name, // - const QCommandLineParser *parser,// - const QString &password = QString()); - static Profile *createProfile(QString name,// - const QCommandLineParser *parser,// - QString password); - ~Profile(); + static Profile* loadProfile(QString host, // + QString name, // + const QCommandLineParser* parser, // + const QString& password = QString()); + static Profile* createProfile(QString host, + QString name, // + const QCommandLineParser* parser, // + QString password); + ~Profile(); + + // 获取用户名 + const QString& getName() const; + // 获取显示名(优先nick,再用户名) + const QString& getDisplayName(); + + void startCore(); + void stopCore(); + Core* getCore(); + + bool isEncrypted() const; + QString setPassword(const QString& newPassword); + const ToxEncrypt* getPasskey() const; + const QPixmap& loadAvatar(); + void setAvatar(QByteArray pic, bool saveToCore); + void setAvatarOnly(const QPixmap& pic); - //获取用户名 - const QString& getName() const; - //获取显示名(优先nick,再用户名) - const QString& getDisplayName() ; + QPixmap loadAvatar(const ContactId& owner); + QByteArray loadAvatarData(const ContactId& owner); + void removeAvatar(bool saveToCore); - void startCore(); - void stopCore(); - Core *getCore(); + QByteArray getFriendAvatarHash(const FriendId& owner); - bool isEncrypted() const; - QString setPassword(const QString &newPassword); - const ToxEncrypt *getPasskey() const; + void saveFriendAvatar(const FriendId& owner, const QByteArray& avatar); + void saveFriendAlias(const QString& friendPk, const QString& alias); + QString getFriendAlias(const QString& friendPk); - const QPixmap& loadAvatar(); - void setAvatar(QByteArray pic); - void setAvatarOnly(QPixmap pic); - QPixmap loadAvatar(const ContactId &owner); - QByteArray loadAvatarData(const ContactId &owner); + bool isHistoryEnabled(); + History* getHistory(); + QStringList remove(); - QByteArray getAvatarHash(const FriendId &owner); - void removeSelfAvatar(); - void removeFriendAvatar(const FriendId &owner); - bool isHistoryEnabled(); - History *getHistory(); + bool rename(QString newName); - QStringList remove(); + static const QStringList getAllProfileNames(); - bool rename(QString newName); + static bool exists(QString name); + static bool isEncrypted(QString name); + static QString getDbPath(const QString& profileName); - static const QStringList getAllProfileNames(); - static bool exists(QString name); - static bool isEncrypted(QString name); - static QString getDbPath(const QString &profileName); + uint addContact(const ContactId& cid); - void saveAvatar(const FriendId &owner, const QByteArray &avatar); - void saveFriendAlias(const QString& friendPk, const QString& alias); - QString getFriendAlias(const QString& friendPk); + /** + * 保存昵称 + * @param nick + * @param saveToCore 是否存入聊天模块 + * + * 修改昵称后,同时发射信号 `nickChanged` + */ + void setNick(const QString& nick, bool saveToCore); +private: + Profile(const QString& host, const QString& name, const QString& password, bool newProfile); + static QStringList getFilesByExt(QString extension); + QString avatarPath(const ContactId& owner, bool forceUnencrypted = false); + bool saveToxSave(QByteArray data); + void initCore(const QByteArray& toxsave, ICoreSettings& s, bool isNewProfile); - uint addContact(const ContactId& cid); +private: + std::unique_ptr core = nullptr; + QString host; + // akka username + QString name; + QString password; + QString nick; + QByteArray toxsave; + std::unique_ptr passkey = nullptr; + std::shared_ptr database; + std::shared_ptr history; + bool isRemoved; + bool encrypted = false; + static QStringList profiles; + QPixmap pixmap; signals: - void selfAvatarChanged(const QPixmap &pixmap); - // emit on any change, including default avatar. Used by those that don't care - // about active on default avatar. - void friendAvatarChanged(const FriendId &friendPk, const QPixmap &pixmap); - // emit on a set of avatar, including identicon, used by those two care about - // active for default, so can't use friendAvatarChanged - void friendAvatarSet(const FriendId &friendPk, const QPixmap &pixmap); - // emit on set to default, used by those that modify on active - void friendAvatarRemoved(const FriendId &friendPk); - // TODO(sudden6): this doesn't seem to be the right place for Core errors - void failedToStart(); - void badProxy(); - void coreChanged(Core &core); + void selfAvatarChanged(const QPixmap& pixmap); + // emit on any change, including default avatar. Used by those that don't care + // about active on default avatar. + void friendAvatarChanged(const FriendId& friendPk, const QPixmap& pixmap); + // emit on a set of avatar, including identicon, used by those two care about + // active for default, so can't use friendAvatarChanged + void friendAvatarSet(const FriendId& friendPk, const QPixmap& pixmap); + // emit on set to default, used by those that modify on active + void friendAvatarRemoved(const FriendId& friendPk); + // TODO(sudden6): this doesn't seem to be the right place for Core errors + void failedToStart(); + void badProxy(); + void coreChanged(Core& core); + void nickChanged(const QString& nick); public slots: - void onRequestSent(const FriendId &friendPk, const QString &message); + void onRequestSent(const FriendId& friendPk, const QString& message); -private slots: - void loadDatabase(QString password); - void removeAvatar(const FriendId &owner); + void loadDatabase(QString password); - void onSaveToxSave(); - // TODO(sudden6): use ToxPk instead of receiver - void onAvatarOfferReceived(QString friendId, QString fileId, - const QByteArray &avatarHash); - void setFriendAvatar(const FriendId owner, const QByteArray &pic); + void removeFriendAvatar(const FriendId& owner); -private: - Profile(QString name, const QString &password, bool newProfile, - const QByteArray &toxsave, std::unique_ptr passKey); - static QStringList getFilesByExt(QString extension); - QString avatarPath(const ContactId &owner, bool forceUnencrypted = false); - bool saveToxSave(QByteArray data); - void initCore(const QByteArray &toxsave, ICoreSettings &s, bool isNewProfile); + void onSaveToxSave(); -private: - std::unique_ptr core = nullptr; - //is username - QString name; - QString nick; - - std::unique_ptr passkey = nullptr; - std::shared_ptr database; - std::shared_ptr history; - bool isRemoved; - bool encrypted = false; - static QStringList profiles; - QPixmap pixmap; +// void onAvatarOfferReceived(const QString& friendId, +// const QString &fileId, +// const QByteArray& avatarHash); + + void setFriendAvatar(const FriendId& owner, const QByteArray& pic); }; -#endif // PROFILE_H +#endif // PROFILE_H diff --git a/src/modules/im/src/persistence/profilelocker.cpp b/src/modules/im/src/persistence/profilelocker.cpp index b5a3d1d8..f4750f26 100644 --- a/src/modules/im/src/persistence/profilelocker.cpp +++ b/src/modules/im/src/persistence/profilelocker.cpp @@ -10,11 +10,10 @@ * See the Mulan PubL v2 for more details. */ - #include "profilelocker.h" -#include "src/persistence/settings.h" #include #include +#include "src/persistence/settings.h" /** * @class ProfileLocker @@ -29,8 +28,7 @@ using namespace std; unique_ptr ProfileLocker::lockfile; QString ProfileLocker::curLockName; -QString ProfileLocker::lockPathFromName(const QString& name) -{ +QString ProfileLocker::lockPathFromName(const QString& name) { return Settings::getInstance().getSettingsDirPath() + '/' + name + ".lock"; } @@ -42,11 +40,9 @@ QString ProfileLocker::lockPathFromName(const QString& name) * @param profile Profile name to check. * @return True, if profile locked, false otherwise. */ -bool ProfileLocker::isLockable(QString profile) -{ +bool ProfileLocker::isLockable(QString profile) { // If we already have the lock, it's definitely lockable - if (lockfile && curLockName == profile) - return true; + if (lockfile && curLockName == profile) return true; QLockFile newLock(lockPathFromName(profile)); return newLock.tryLock(); @@ -57,10 +53,8 @@ bool ProfileLocker::isLockable(QString profile) * @param profile Profile to lock. * @return Returns true if we already own the lock. */ -bool ProfileLocker::lock(QString profile) -{ - if (lockfile && curLockName == profile) - return true; +bool ProfileLocker::lock(QString profile) { + if (lockfile && curLockName == profile) return true; QLockFile* newLock = new QLockFile(lockPathFromName(profile)); newLock->setStaleLockTime(0); @@ -78,10 +72,8 @@ bool ProfileLocker::lock(QString profile) /** * @brief Releases the lock on the current profile. */ -void ProfileLocker::unlock() -{ - if (!lockfile) - return; +void ProfileLocker::unlock() { + if (!lockfile) return; lockfile->unlock(); lockfile.reset(); @@ -94,8 +86,7 @@ void ProfileLocker::unlock() * If we can't get a lock, exit qTox immediately. * If we never had a lock in the first place, exit immediately. */ -void ProfileLocker::assertLock() -{ +void ProfileLocker::assertLock() { if (!lockfile) { qCritical() << "assertLock: We don't seem to own any lock!"; deathByBrokenLock(); @@ -116,8 +107,7 @@ void ProfileLocker::assertLock() /** * @brief Print an error then exit immediately. */ -void ProfileLocker::deathByBrokenLock() -{ +void ProfileLocker::deathByBrokenLock() { qCritical() << "Lock is *BROKEN*, exiting immediately"; abort(); } @@ -126,17 +116,13 @@ void ProfileLocker::deathByBrokenLock() * @brief Chacks, that profile locked. * @return Returns true if we're currently holding a lock. */ -bool ProfileLocker::hasLock() -{ - return lockfile.operator bool(); -} +bool ProfileLocker::hasLock() { return lockfile.operator bool(); } /** * @brief Get current locked profile name. * @return Return the name of the currently loaded profile, a null string if there is none. */ -QString ProfileLocker::getCurLockName() -{ +QString ProfileLocker::getCurLockName() { if (lockfile) return curLockName; else diff --git a/src/modules/im/src/persistence/profilelocker.h b/src/modules/im/src/persistence/profilelocker.h index fe5d2305..dc053e5b 100644 --- a/src/modules/im/src/persistence/profilelocker.h +++ b/src/modules/im/src/persistence/profilelocker.h @@ -10,15 +10,13 @@ * See the Mulan PubL v2 for more details. */ - #ifndef PROFILELOCKER_H #define PROFILELOCKER_H #include #include -class ProfileLocker -{ +class ProfileLocker { private: ProfileLocker() = delete; @@ -39,4 +37,4 @@ class ProfileLocker static QString curLockName; }; -#endif // PROFILELOCKER_H +#endif // PROFILELOCKER_H diff --git a/src/modules/im/src/persistence/serialize.cpp b/src/modules/im/src/persistence/serialize.cpp index 78536759..267adab8 100644 --- a/src/modules/im/src/persistence/serialize.cpp +++ b/src/modules/im/src/persistence/serialize.cpp @@ -18,8 +18,7 @@ * @warning Do not use them on untrusted data (e.g. check a signature first). */ -QString dataToString(QByteArray data) -{ +QString dataToString(QByteArray data) { char num3; int strlen = 0; int num2 = 0; @@ -30,8 +29,7 @@ QString dataToString(QByteArray data) num2 += 7; } while ((num3 & 0x80) != 0); - if (strlen <= 0) - return QString(); + if (strlen <= 0) return QString(); // Remove the strlen data.remove(0, i); @@ -40,16 +38,14 @@ QString dataToString(QByteArray data) return QString(data); } -uint64_t dataToUint64(const QByteArray& data) -{ - return static_cast(data[0]) | (static_cast(data[1]) << 8) - | (static_cast(data[2]) << 16) | (static_cast(data[3]) << 24) - | (static_cast(data[4]) << 32) | (static_cast(data[5]) << 40) - | (static_cast(data[6]) << 48) | (static_cast(data[7]) << 56); +uint64_t dataToUint64(const QByteArray& data) { + return static_cast(data[0]) | (static_cast(data[1]) << 8) | + (static_cast(data[2]) << 16) | (static_cast(data[3]) << 24) | + (static_cast(data[4]) << 32) | (static_cast(data[5]) << 40) | + (static_cast(data[6]) << 48) | (static_cast(data[7]) << 56); } -int dataToVInt(const QByteArray& data) -{ +int dataToVInt(const QByteArray& data) { char num3; int num = 0; int num2 = 0; @@ -62,8 +58,7 @@ int dataToVInt(const QByteArray& data) return num; } -size_t dataToVUint(const QByteArray& data) -{ +size_t dataToVUint(const QByteArray& data) { char num3; size_t num = 0; int num2 = 0; @@ -76,8 +71,7 @@ size_t dataToVUint(const QByteArray& data) return num; } -unsigned getVUint32Size(QByteArray data) -{ +unsigned getVUint32Size(QByteArray data) { unsigned lensize = 0; char num3; @@ -89,8 +83,7 @@ unsigned getVUint32Size(QByteArray data) return lensize; } -QByteArray vintToData(int num) -{ +QByteArray vintToData(int num) { QByteArray data(sizeof(int), 0); // Write the size in a Uint of variable lenght (8-32 bits) int i = 0; @@ -104,8 +97,7 @@ QByteArray vintToData(int num) return data; } -QByteArray vuintToData(size_t num) -{ +QByteArray vuintToData(size_t num) { QByteArray data(sizeof(size_t), 0); // Write the size in a Uint of variable lenght (8-32 bits) int i = 0; diff --git a/src/modules/im/src/persistence/serialize.h b/src/modules/im/src/persistence/serialize.h index e29d5f21..e4042dbf 100644 --- a/src/modules/im/src/persistence/serialize.h +++ b/src/modules/im/src/persistence/serialize.h @@ -10,7 +10,6 @@ * See the Mulan PubL v2 for more details. */ - #ifndef SERIALIZE_H #define SERIALIZE_H @@ -26,4 +25,4 @@ unsigned getVUint32Size(QByteArray data); QByteArray vintToData(int num); QByteArray vuintToData(size_t num); -#endif // SERIALIZE_H +#endif // SERIALIZE_H diff --git a/src/modules/im/src/persistence/settings.cpp b/src/modules/im/src/persistence/settings.cpp index af7ba6b4..16bd3c82 100644 --- a/src/modules/im/src/persistence/settings.cpp +++ b/src/modules/im/src/persistence/settings.cpp @@ -23,8 +23,8 @@ #include "src/persistence/smileypack.h" #include "src/widget/gui.h" -#include "base/compatiblerecursivemutex.h" #include "base/OkSettings.h" +#include "base/compatiblerecursivemutex.h" #include #include @@ -48,41 +48,38 @@ * which have widget->saveX() and widget->loadX() methods. */ -const QString Settings::globalSettingsFile = - APPLICATION_ALIAS "-" OK_IM_MODULE ".ini"; +const QString Settings::globalSettingsFile = APPLICATION_ALIAS "-" OK_IM_MODULE ".ini"; CompatibleRecursiveMutex Settings::bigLock; -QThread *Settings::settingsThread{nullptr}; +QThread* Settings::settingsThread{nullptr}; -Settings::Settings() - : loaded(false), useCustomDhtList{false}, makeToxPortable{false} { - settingsThread = new QThread(); - settingsThread->setObjectName(globalSettingsFile); - settingsThread->start(QThread::LowPriority); - moveToThread(settingsThread); - loadGlobal(); +Settings::Settings() : loaded(false), useCustomDhtList{false}, makeToxPortable{false} { + settingsThread = new QThread(); + settingsThread->setObjectName(globalSettingsFile); + settingsThread->start(QThread::LowPriority); + moveToThread(settingsThread); + loadGlobal(); } Settings::~Settings() { - sync(); - settingsThread->exit(0); - settingsThread->wait(); - delete settingsThread; + sync(); + settingsThread->exit(0); + settingsThread->wait(); + delete settingsThread; } /** * @brief Returns the singleton instance. */ -Settings &Settings::getInstance() { - static Settings *settings = nullptr; - if (!settings) - settings = new Settings(); - return *settings; +Settings& Settings::getInstance() { + static Settings* settings = nullptr; + if (!settings) settings = new Settings(); + return *settings; } void Settings::destroyInstance() { - // delete settings; - // settings = nullptr; + // delete settings; + // settings = nullptr; } // 国际化下拉框 @@ -91,196 +88,182 @@ void Settings::destroyInstance() { // } void Settings::loadGlobal() { - QMutexLocker locker{&bigLock}; - - if (loaded) - return; - - createSettingsDir(); - - makeToxPortable = Settings::isToxPortable(); - - QDir dir(getSettingsDirPath()); - QString filePath = dir.filePath(globalSettingsFile); - - // If no settings file exist -- use the default one - if (!QFile(filePath).exists()) { - qDebug() << "No settings file found, using defaults"; - filePath = ":/conf/" + globalSettingsFile; - } - - qDebug() << "Loading settings from " + filePath; - - QSettings s(filePath, QSettings::IniFormat); - s.setIniCodec("UTF-8"); - - // 自动登录 - s.beginGroup("Login"); - { autoLogin = s.value("autoLogin", false).toBool(); } - s.endGroup(); - // 语言 - s.beginGroup("General"); - { - - autoAwayTime = s.value("autoAwayTime", 10).toInt(); - checkUpdates = s.value("checkUpdates", true).toBool(); - // note: notifySound and busySound UI elements are now under UI settings - // page, but kept under General in settings file to be backwards compatible - notifySound = s.value("notifySound", true).toBool(); - notifyHide = s.value("notifyHide", false).toBool(); - busySound = s.value("busySound", false).toBool(); - globalAutoAcceptDir = - s.value("globalAutoAcceptDir", - QStandardPaths::locate(QStandardPaths::HomeLocation, QString(), - QStandardPaths::LocateDirectory)) - .toString(); - autoAcceptMaxSize = static_cast( - s.value("autoAcceptMaxSize", 20 << 20 /*20 MB*/).toLongLong()); - stylePreference = - static_cast(s.value("stylePreference", 1).toInt()); - } - s.endGroup(); - - s.beginGroup("Advanced"); - { - makeToxPortable = s.value("makeToxPortable", false).toBool(); - enableIPv6 = s.value("enableIPv6", true).toBool(); - forceTCP = s.value("forceTCP", false).toBool(); - enableLanDiscovery = s.value("enableLanDiscovery", true).toBool(); - } - s.endGroup(); - - s.beginGroup("Widgets"); - { - QList objectNames = s.childKeys(); - for (const QString &name : objectNames) - widgetSettings[name] = s.value(name).toByteArray(); - } - s.endGroup(); - - s.beginGroup("GUI"); - { - showWindow = s.value("showWindow", true).toBool(); - notify = s.value("notify", true).toBool(); - desktopNotify = s.value("desktopNotify", true).toBool(); - groupAlwaysNotify = s.value("groupAlwaysNotify", true).toBool(); - groupchatPosition = s.value("groupchatPosition", true).toBool(); - separateWindow = s.value("separateWindow", false).toBool(); - dontGroupWindows = s.value("dontGroupWindows", false).toBool(); - showIdenticons = s.value("showIdenticons", true).toBool(); - - const QString DEFAULT_SMILEYS = ":/smileys/emojione/emoticons.xml"; - smileyPack = s.value("smileyPack", DEFAULT_SMILEYS).toString(); - if (!QFile::exists(smileyPack)) { - smileyPack = DEFAULT_SMILEYS; - } - - emojiFontPointSize = s.value("emojiFontPointSize", 24).toInt(); - firstColumnHandlePos = s.value("firstColumnHandlePos", 50).toInt(); - secondColumnHandlePosFromRight = - s.value("secondColumnHandlePosFromRight", 50).toInt(); - timestampFormat = s.value("timestampFormat", "hh:mm:ss").toString(); - dateFormat = s.value("dateFormat", "yyyy-MM-dd").toString(); - lightTrayIcon = s.value("lightTrayIcon", false).toBool(); - useEmoticons = s.value("useEmoticons", true).toBool(); - statusChangeNotificationEnabled = - s.value("statusChangeNotificationEnabled", false).toBool(); - showGroupJoinLeaveMessages = - s.value("showGroupJoinLeaveMessages", false).toBool(); - spellCheckingEnabled = s.value("spellCheckingEnabled", true).toBool(); - themeColor = s.value("themeColor", 0).toInt(); - style = s.value("style", "").toString(); - if (style == "") // Default to Fusion if available, otherwise no style + QMutexLocker locker{&bigLock}; + + if (loaded) return; + + createSettingsDir(); + + makeToxPortable = Settings::isToxPortable(); + + QDir dir(getSettingsDirPath()); + QString filePath = dir.filePath(globalSettingsFile); + + // If no settings file exist -- use the default one + if (!QFile(filePath).exists()) { + qDebug() << "No settings file found, using defaults"; + filePath = ":/conf/" + globalSettingsFile; + } + + qDebug() << "Loading settings from " + filePath; + + QSettings s(filePath, QSettings::IniFormat); + s.setIniCodec("UTF-8"); + + // 自动登录 + s.beginGroup("Login"); + { autoLogin = s.value("autoLogin", false).toBool(); } + s.endGroup(); + // 语言 + s.beginGroup("General"); + { + autoAwayTime = s.value("autoAwayTime", 10).toInt(); + checkUpdates = s.value("checkUpdates", true).toBool(); + // note: notifySound and busySound UI elements are now under UI settings + // page, but kept under General in settings file to be backwards compatible + notifySound = s.value("notifySound", true).toBool(); + notifyHide = s.value("notifyHide", false).toBool(); + busySound = s.value("busySound", false).toBool(); + globalAutoAcceptDir = + s.value("globalAutoAcceptDir", + QStandardPaths::locate(QStandardPaths::HomeLocation, QString(), + QStandardPaths::LocateDirectory)) + .toString(); + autoAcceptMaxSize = + static_cast(s.value("autoAcceptMaxSize", 20 << 20 /*20 MB*/).toLongLong()); + stylePreference = static_cast(s.value("stylePreference", 1).toInt()); + } + s.endGroup(); + + s.beginGroup("Advanced"); + { + makeToxPortable = s.value("makeToxPortable", false).toBool(); + enableIPv6 = s.value("enableIPv6", true).toBool(); + forceTCP = s.value("forceTCP", false).toBool(); + enableLanDiscovery = s.value("enableLanDiscovery", true).toBool(); + } + s.endGroup(); + + s.beginGroup("Widgets"); + { + QList objectNames = s.childKeys(); + for (const QString& name : objectNames) widgetSettings[name] = s.value(name).toByteArray(); + } + s.endGroup(); + + s.beginGroup("GUI"); + { + showWindow = s.value("showWindow", true).toBool(); + notify = s.value("notify", true).toBool(); + desktopNotify = s.value("desktopNotify", true).toBool(); + groupAlwaysNotify = s.value("groupAlwaysNotify", true).toBool(); + groupchatPosition = s.value("groupchatPosition", true).toBool(); + separateWindow = s.value("separateWindow", false).toBool(); + dontGroupWindows = s.value("dontGroupWindows", false).toBool(); + showIdenticons = s.value("showIdenticons", true).toBool(); + + const QString DEFAULT_SMILEYS = ":/smileys/emojione/emoticons.xml"; + smileyPack = s.value("smileyPack", DEFAULT_SMILEYS).toString(); + if (!QFile::exists(smileyPack)) { + smileyPack = DEFAULT_SMILEYS; + } + + emojiFontPointSize = s.value("emojiFontPointSize", 24).toInt(); + firstColumnHandlePos = s.value("firstColumnHandlePos", 50).toInt(); + secondColumnHandlePosFromRight = s.value("secondColumnHandlePosFromRight", 50).toInt(); + timestampFormat = s.value("timestampFormat", "hh:mm:ss").toString(); + dateFormat = s.value("dateFormat", "yyyy-MM-dd").toString(); + lightTrayIcon = s.value("lightTrayIcon", false).toBool(); + useEmoticons = s.value("useEmoticons", true).toBool(); + statusChangeNotificationEnabled = + s.value("statusChangeNotificationEnabled", false).toBool(); + showGroupJoinLeaveMessages = s.value("showGroupJoinLeaveMessages", false).toBool(); + spellCheckingEnabled = s.value("spellCheckingEnabled", true).toBool(); + themeColor = s.value("themeColor", 0).toInt(); + style = s.value("style", "").toString(); + if (style == "") // Default to Fusion if available, otherwise no style + { + if (QStyleFactory::keys().contains("Fusion")) + style = "Fusion"; + else + style = "None"; + } + nameColors = s.value("nameColors", false).toBool(); + } + s.endGroup(); + + s.beginGroup("Chat"); + { chatMessageFont = s.value("chatMessageFont", Style::getFont(Style::Big)).value(); } + s.endGroup(); + // 隐私 + s.beginGroup("State"); + { + windowGeometry = s.value("windowGeometry", QByteArray()).toByteArray(); + windowState = s.value("windowState", QByteArray()).toByteArray(); + splitterState = s.value("splitterState", QByteArray()).toByteArray(); + dialogGeometry = s.value("dialogGeometry", QByteArray()).toByteArray(); + dialogSplitterState = s.value("dialogSplitterState", QByteArray()).toByteArray(); + dialogSettingsGeometry = s.value("dialogSettingsGeometry", QByteArray()).toByteArray(); + } + s.endGroup(); + + s.beginGroup("Audio"); { - if (QStyleFactory::keys().contains("Fusion")) - style = "Fusion"; - else - style = "None"; - } - nameColors = s.value("nameColors", false).toBool(); - } - s.endGroup(); - - s.beginGroup("Chat"); - { - chatMessageFont = - s.value("chatMessageFont", Style::getFont(Style::Big)).value(); - } - s.endGroup(); - // 隐私 - s.beginGroup("State"); - { - windowGeometry = s.value("windowGeometry", QByteArray()).toByteArray(); - windowState = s.value("windowState", QByteArray()).toByteArray(); - splitterState = s.value("splitterState", QByteArray()).toByteArray(); - dialogGeometry = s.value("dialogGeometry", QByteArray()).toByteArray(); - dialogSplitterState = - s.value("dialogSplitterState", QByteArray()).toByteArray(); - dialogSettingsGeometry = - s.value("dialogSettingsGeometry", QByteArray()).toByteArray(); - } - s.endGroup(); - - s.beginGroup("Audio"); - { - inDev = s.value("inDev", "").toString(); - audioInDevEnabled = s.value("audioInDevEnabled", true).toBool(); - outDev = s.value("outDev", "").toString(); - audioOutDevEnabled = s.value("audioOutDevEnabled", true).toBool(); - audioInGainDecibel = s.value("inGain", 0).toReal(); - audioThreshold = s.value("audioThreshold", 0).toReal(); - outVolume = s.value("outVolume", 100).toInt(); - enableTestSound = s.value("enableTestSound", true).toBool(); - audioBitrate = s.value("audioBitrate", 64).toInt(); - } - s.endGroup(); - - s.beginGroup("Video"); - { - videoDev = s.value("videoDev", "").toString(); - camVideoRes = s.value("camVideoRes", QRect()).toRect(); - screenRegion = s.value("screenRegion", QRect()).toRect(); - screenGrabbed = s.value("screenGrabbed", false).toBool(); - camVideoFPS = static_cast(s.value("camVideoFPS", 0).toUInt()); - } - s.endGroup(); - - loaded = true; + inDev = s.value("inDev", "").toString(); + audioInDevEnabled = s.value("audioInDevEnabled", true).toBool(); + outDev = s.value("outDev", "").toString(); + audioOutDevEnabled = s.value("audioOutDevEnabled", true).toBool(); + audioInGainDecibel = s.value("inGain", 0).toReal(); + audioThreshold = s.value("audioThreshold", 0).toReal(); + outVolume = s.value("outVolume", 100).toInt(); + enableTestSound = s.value("enableTestSound", true).toBool(); + audioBitrate = s.value("audioBitrate", 64).toInt(); + } + s.endGroup(); + + s.beginGroup("Video"); + { + videoDev = s.value("videoDev", "").toString(); + camVideoRes = s.value("camVideoRes", QRect()).toRect(); + screenRegion = s.value("screenRegion", QRect()).toRect(); + screenGrabbed = s.value("screenGrabbed", false).toBool(); + camVideoFPS = static_cast(s.value("camVideoFPS", 0).toUInt()); + } + s.endGroup(); + + loaded = true; } bool Settings::isToxPortable() { - QString localSettingsPath = - qApp->applicationDirPath() + QDir::separator() + globalSettingsFile; - if (!QFile(localSettingsPath).exists()) { - return false; - } - QSettings ps(localSettingsPath, QSettings::IniFormat); - ps.setIniCodec("UTF-8"); - ps.beginGroup("Advanced"); - bool result = ps.value("makeToxPortable", false).toBool(); - ps.endGroup(); - return result; + QString localSettingsPath = qApp->applicationDirPath() + QDir::separator() + globalSettingsFile; + if (!QFile(localSettingsPath).exists()) { + return false; + } + QSettings ps(localSettingsPath, QSettings::IniFormat); + ps.setIniCodec("UTF-8"); + ps.beginGroup("Advanced"); + bool result = ps.value("makeToxPortable", false).toBool(); + ps.endGroup(); + return result; } -void Settings::updateProfileData(Profile *profile, - const QCommandLineParser *parser) { - QMutexLocker locker{&bigLock}; +void Settings::updateProfileData(Profile* profile, const QCommandLineParser* parser) { + QMutexLocker locker{&bigLock}; - if (profile == nullptr) { - qWarning() << QString( - "Could not load new settings (profile change to nullptr)"); - return; - } - auto &ok = ok::base::OkSettings::getInstance(); - ok.setCurrentProfile(profile->getName()); - ok.saveGlobal(); + if (profile == nullptr) { + qWarning() << QString("Could not load new settings (profile change to nullptr)"); + return; + } + auto& ok = ok::base::OkSettings::getInstance(); + ok.setCurrentProfile(profile->getName()); + ok.saveGlobal(); - saveGlobal(); + saveGlobal(); - loadPersonal(profile->getName(), profile->getPasskey()); - if (parser) { - applyCommandLineOptions(*parser); - } + loadPersonal(profile->getName(), profile->getPasskey()); + if (parser) { + applyCommandLineOptions(*parser); + } } /** @@ -290,88 +273,87 @@ void Settings::updateProfileData(Profile *profile, * removed in a future refactor. * @param parser QCommandLineParser instance */ -bool Settings::verifyProxySettings(const QCommandLineParser &parser) { - QString IPv6SettingString = parser.value("I").toLower(); - QString LANSettingString = parser.value("L").toLower(); - QString UDPSettingString = parser.value("U").toLower(); - QString proxySettingString = parser.value("proxy").toLower(); - QStringList proxySettingStrings = proxySettingString.split(":"); - - const QString SOCKS5 = QStringLiteral("socks5"); - const QString HTTP = QStringLiteral("http"); - const QString NONE = QStringLiteral("none"); - const QString ON = QStringLiteral("on"); - const QString OFF = QStringLiteral("off"); - - // Check for incompatible settings - bool activeProxyType = false; - - if (parser.isSet("P")) { - activeProxyType = - proxySettingStrings[0] == SOCKS5 || proxySettingStrings[0] == HTTP; - } - - if (parser.isSet("I")) { - if (!(IPv6SettingString == ON || IPv6SettingString == OFF)) { - qCritical() << "Unable to parse IPv6 setting."; - return false; - } - } - - if (parser.isSet("U")) { - if (!(UDPSettingString == ON || UDPSettingString == OFF)) { - qCritical() << "Unable to parse UDP setting."; - return false; - } - } - - if (parser.isSet("L")) { - if (!(LANSettingString == ON || LANSettingString == OFF)) { - qCritical() << "Unable to parse LAN setting."; - return false; - } - } - if (activeProxyType && UDPSettingString == ON) { - qCritical() << "Cannot set UDP on with proxy."; - return false; - } +bool Settings::verifyProxySettings(const QCommandLineParser& parser) { + QString IPv6SettingString = parser.value("I").toLower(); + QString LANSettingString = parser.value("L").toLower(); + QString UDPSettingString = parser.value("U").toLower(); + QString proxySettingString = parser.value("proxy").toLower(); + QStringList proxySettingStrings = proxySettingString.split(":"); + + const QString SOCKS5 = QStringLiteral("socks5"); + const QString HTTP = QStringLiteral("http"); + const QString NONE = QStringLiteral("none"); + const QString ON = QStringLiteral("on"); + const QString OFF = QStringLiteral("off"); + + // Check for incompatible settings + bool activeProxyType = false; + + if (parser.isSet("P")) { + activeProxyType = proxySettingStrings[0] == SOCKS5 || proxySettingStrings[0] == HTTP; + } - if (activeProxyType && LANSettingString == ON) { - qCritical() << "Cannot set LAN discovery on with proxy."; - return false; - } + if (parser.isSet("I")) { + if (!(IPv6SettingString == ON || IPv6SettingString == OFF)) { + qCritical() << "Unable to parse IPv6 setting."; + return false; + } + } - if (LANSettingString == ON && UDPSettingString == OFF) { - qCritical() << "Incompatible UDP/LAN settings."; - return false; - } + if (parser.isSet("U")) { + if (!(UDPSettingString == ON || UDPSettingString == OFF)) { + qCritical() << "Unable to parse UDP setting."; + return false; + } + } - if (parser.isSet("P")) { - if (proxySettingStrings[0] == NONE) { - // slightly lazy check here, accepting 'NONE[:.*]' is fine since no other - // arguments will be investigated when proxy settings are applied. - return true; + if (parser.isSet("L")) { + if (!(LANSettingString == ON || LANSettingString == OFF)) { + qCritical() << "Unable to parse LAN setting."; + return false; + } } - // Since the first argument isn't 'none', verify format of remaining - // arguments - if (proxySettingStrings.size() != 3) { - qCritical() << "Invalid number of proxy arguments."; - return false; + if (activeProxyType && UDPSettingString == ON) { + qCritical() << "Cannot set UDP on with proxy."; + return false; } - if (!(proxySettingStrings[0] == SOCKS5 || proxySettingStrings[0] == HTTP)) { - qCritical() << "Unable to parse proxy type."; - return false; + if (activeProxyType && LANSettingString == ON) { + qCritical() << "Cannot set LAN discovery on with proxy."; + return false; } - // TODO(Kriby): Sanity check IPv4/IPv6 addresses/hostnames? + if (LANSettingString == ON && UDPSettingString == OFF) { + qCritical() << "Incompatible UDP/LAN settings."; + return false; + } - int portNumber = proxySettingStrings[2].toInt(); - if (!(portNumber > 0 && portNumber < 65536)) { - qCritical() << "Invalid port number range."; + if (parser.isSet("P")) { + if (proxySettingStrings[0] == NONE) { + // slightly lazy check here, accepting 'NONE[:.*]' is fine since no other + // arguments will be investigated when proxy settings are applied. + return true; + } + // Since the first argument isn't 'none', verify format of remaining + // arguments + if (proxySettingStrings.size() != 3) { + qCritical() << "Invalid number of proxy arguments."; + return false; + } + + if (!(proxySettingStrings[0] == SOCKS5 || proxySettingStrings[0] == HTTP)) { + qCritical() << "Unable to parse proxy type."; + return false; + } + + // TODO(Kriby): Sanity check IPv4/IPv6 addresses/hostnames? + + int portNumber = proxySettingStrings[2].toInt(); + if (!(portNumber > 0 && portNumber < 65536)) { + qCritical() << "Invalid port number range."; + } } - } - return true; + return true; } /** @@ -380,230 +362,225 @@ bool Settings::verifyProxySettings(const QCommandLineParser &parser) { * @param parser QCommandLineParser instance * @return Success indicator (success = true) */ -bool Settings::applyCommandLineOptions(const QCommandLineParser &parser) { - if (!verifyProxySettings(parser)) { - return false; - }; - - QString IPv6Setting = parser.value("I").toUpper(); - QString LANSetting = parser.value("L").toUpper(); - QString UDPSetting = parser.value("U").toUpper(); - QString proxySettingString = parser.value("proxy").toUpper(); - QStringList proxySettings = proxySettingString.split(":"); - - const QString SOCKS5 = QStringLiteral("SOCKS5"); - const QString HTTP = QStringLiteral("HTTP"); - const QString NONE = QStringLiteral("NONE"); - const QString ON = QStringLiteral("ON"); - const QString OFF = QStringLiteral("OFF"); - - if (parser.isSet("I")) { - enableIPv6 = IPv6Setting == ON; - qDebug() << QString("Setting IPv6 %1.").arg(IPv6Setting); - } - - if (parser.isSet("P")) { - qDebug() << QString("Setting proxy type to %1.").arg(proxySettings[0]); - - quint16 portNumber = 0; - QString address = ""; - - if (proxySettings[0] == NONE) { - proxyType = ICoreSettings::ProxyType::ptNone; - } else { - if (proxySettings[0] == SOCKS5) { - proxyType = ICoreSettings::ProxyType::ptSOCKS5; - } else if (proxySettings[0] == HTTP) { - proxyType = ICoreSettings::ProxyType::ptHTTP; - } else { - qCritical() << "Failed to set valid proxy type"; - assert(false); // verifyProxySettings should've made this impossible - } - - forceTCP = true; - enableLanDiscovery = false; - - address = proxySettings[1]; - portNumber = static_cast(proxySettings[2].toInt()); - } - - proxyAddr = address; - qDebug() << QString("Setting proxy address to %1.").arg(address); - proxyPort = portNumber; - qDebug() << QString("Setting port number to %1.").arg(portNumber); - } - - if (parser.isSet("U")) { - bool shouldForceTCP = UDPSetting == OFF; - if (!shouldForceTCP && proxyType != ICoreSettings::ProxyType::ptNone) { - qDebug() << "Cannot use UDP with proxy; disable proxy explicitly with " - "'-P none'."; - } else { - forceTCP = shouldForceTCP; - qDebug() << QString("Setting UDP %1.").arg(UDPSetting); - } - - // LANSetting == ON is caught by verifyProxySettings, the OFF check removes - // needless debug - if (shouldForceTCP && !(LANSetting == OFF) && enableLanDiscovery) { - qDebug() << "Cannot perform LAN discovery without UDP; disabling LAN " - "discovery."; - enableLanDiscovery = false; - } - } - - if (parser.isSet("L")) { - bool shouldEnableLAN = LANSetting == ON; - - if (shouldEnableLAN && proxyType != ICoreSettings::ProxyType::ptNone) { - qDebug() << "Cannot use LAN discovery with proxy; disable proxy " - "explicitly with '-P none'."; - } else if (shouldEnableLAN && forceTCP) { - qDebug() << "Cannot use LAN discovery without UDP; enable UDP explicitly " - "with '-U on'."; - } else { - enableLanDiscovery = shouldEnableLAN; - qDebug() << QString("Setting LAN Discovery %1.").arg(LANSetting); - } - } - return true; +bool Settings::applyCommandLineOptions(const QCommandLineParser& parser) { + if (!verifyProxySettings(parser)) { + return false; + }; + + QString IPv6Setting = parser.value("I").toUpper(); + QString LANSetting = parser.value("L").toUpper(); + QString UDPSetting = parser.value("U").toUpper(); + QString proxySettingString = parser.value("proxy").toUpper(); + QStringList proxySettings = proxySettingString.split(":"); + + const QString SOCKS5 = QStringLiteral("SOCKS5"); + const QString HTTP = QStringLiteral("HTTP"); + const QString NONE = QStringLiteral("NONE"); + const QString ON = QStringLiteral("ON"); + const QString OFF = QStringLiteral("OFF"); + + if (parser.isSet("I")) { + enableIPv6 = IPv6Setting == ON; + qDebug() << QString("Setting IPv6 %1.").arg(IPv6Setting); + } + + if (parser.isSet("P")) { + qDebug() << QString("Setting proxy type to %1.").arg(proxySettings[0]); + + quint16 portNumber = 0; + QString address = ""; + + if (proxySettings[0] == NONE) { + proxyType = ICoreSettings::ProxyType::ptNone; + } else { + if (proxySettings[0] == SOCKS5) { + proxyType = ICoreSettings::ProxyType::ptSOCKS5; + } else if (proxySettings[0] == HTTP) { + proxyType = ICoreSettings::ProxyType::ptHTTP; + } else { + qCritical() << "Failed to set valid proxy type"; + assert(false); // verifyProxySettings should've made this impossible + } + + forceTCP = true; + enableLanDiscovery = false; + + address = proxySettings[1]; + portNumber = static_cast(proxySettings[2].toInt()); + } + + proxyAddr = address; + qDebug() << QString("Setting proxy address to %1.").arg(address); + proxyPort = portNumber; + qDebug() << QString("Setting port number to %1.").arg(portNumber); + } + + if (parser.isSet("U")) { + bool shouldForceTCP = UDPSetting == OFF; + if (!shouldForceTCP && proxyType != ICoreSettings::ProxyType::ptNone) { + qDebug() << "Cannot use UDP with proxy; disable proxy explicitly with " + "'-P none'."; + } else { + forceTCP = shouldForceTCP; + qDebug() << QString("Setting UDP %1.").arg(UDPSetting); + } + + // LANSetting == ON is caught by verifyProxySettings, the OFF check removes + // needless debug + if (shouldForceTCP && !(LANSetting == OFF) && enableLanDiscovery) { + qDebug() << "Cannot perform LAN discovery without UDP; disabling LAN " + "discovery."; + enableLanDiscovery = false; + } + } + + if (parser.isSet("L")) { + bool shouldEnableLAN = LANSetting == ON; + + if (shouldEnableLAN && proxyType != ICoreSettings::ProxyType::ptNone) { + qDebug() << "Cannot use LAN discovery with proxy; disable proxy " + "explicitly with '-P none'."; + } else if (shouldEnableLAN && forceTCP) { + qDebug() << "Cannot use LAN discovery without UDP; enable UDP explicitly " + "with '-U on'."; + } else { + enableLanDiscovery = shouldEnableLAN; + qDebug() << QString("Setting LAN Discovery %1.").arg(LANSetting); + } + } + return true; } void Settings::resetToDefault() { - // To stop saving - loaded = false; + // To stop saving + loaded = false; - // Remove file with profile settings - QDir dir(getSettingsDirPath()); - Profile *profile = Nexus::getProfile(); - QString localPath = dir.filePath(profile->getName() + ".ini"); - QFile local(localPath); - if (local.exists()) - local.remove(); + // Remove file with profile settings + QDir dir(getSettingsDirPath()); + Profile* profile = Nexus::getProfile(); + QString localPath = dir.filePath(profile->getName() + ".ini"); + QFile local(localPath); + if (local.exists()) local.remove(); } /** * @brief Asynchronous, saves the global settings. */ void Settings::saveGlobal() { - if (QThread::currentThread() != settingsThread) - return (void)QMetaObject::invokeMethod(&getInstance(), "saveGlobal"); - - QMutexLocker locker{&bigLock}; - if (!loaded) - return; - - QString path = getSettingsDirPath() + globalSettingsFile; - qDebug() << "Saving global settings at " + path; - - QSettings s(path, QSettings::IniFormat); - s.setIniCodec("UTF-8"); - - s.clear(); - - s.beginGroup("Login"); - { s.setValue("autoLogin", autoLogin); } - s.endGroup(); - - s.beginGroup("General"); - { - s.setValue("autoAwayTime", autoAwayTime); - s.setValue("checkUpdates", checkUpdates); - s.setValue("notifySound", notifySound); - s.setValue("notifyHide", notifyHide); - s.setValue("busySound", busySound); - s.setValue("autoAcceptMaxSize", static_cast(autoAcceptMaxSize)); - s.setValue("globalAutoAcceptDir", globalAutoAcceptDir); - s.setValue("stylePreference", static_cast(stylePreference)); - } - s.endGroup(); - - s.beginGroup("Advanced"); - { - s.setValue("makeToxPortable", makeToxPortable); - s.setValue("enableIPv6", enableIPv6); - s.setValue("forceTCP", forceTCP); - s.setValue("enableLanDiscovery", enableLanDiscovery); - s.setValue("dbSyncType", static_cast(dbSyncType)); - } - s.endGroup(); - - s.beginGroup("Widgets"); - { - const QList widgetNames = widgetSettings.keys(); - for (const QString &name : widgetNames) - s.setValue(name, widgetSettings.value(name)); - } - s.endGroup(); - - s.beginGroup("GUI"); - { - s.setValue("showWindow", showWindow); - s.setValue("notify", notify); - s.setValue("desktopNotify", desktopNotify); - s.setValue("groupAlwaysNotify", groupAlwaysNotify); - s.setValue("separateWindow", separateWindow); - s.setValue("dontGroupWindows", dontGroupWindows); - s.setValue("groupchatPosition", groupchatPosition); - s.setValue("showIdenticons", showIdenticons); - - s.setValue("smileyPack", smileyPack); - s.setValue("emojiFontPointSize", emojiFontPointSize); - s.setValue("firstColumnHandlePos", firstColumnHandlePos); - s.setValue("secondColumnHandlePosFromRight", - secondColumnHandlePosFromRight); - s.setValue("timestampFormat", timestampFormat); - s.setValue("dateFormat", dateFormat); - s.setValue("lightTrayIcon", lightTrayIcon); - s.setValue("useEmoticons", useEmoticons); - s.setValue("themeColor", themeColor); - s.setValue("style", style); - s.setValue("nameColors", nameColors); - s.setValue("statusChangeNotificationEnabled", - statusChangeNotificationEnabled); - s.setValue("showGroupJoinLeaveMessages", showGroupJoinLeaveMessages); - s.setValue("spellCheckingEnabled", spellCheckingEnabled); - } - s.endGroup(); - - s.beginGroup("Chat"); - { s.setValue("chatMessageFont", chatMessageFont); } - s.endGroup(); - - s.beginGroup("State"); - { - s.setValue("windowGeometry", windowGeometry); - s.setValue("windowState", windowState); - s.setValue("splitterState", splitterState); - s.setValue("dialogGeometry", dialogGeometry); - s.setValue("dialogSplitterState", dialogSplitterState); - s.setValue("dialogSettingsGeometry", dialogSettingsGeometry); - } - s.endGroup(); - // 音频 - s.beginGroup("Audio"); - { - s.setValue("inDev", inDev); - s.setValue("audioInDevEnabled", audioInDevEnabled); - s.setValue("outDev", outDev); - s.setValue("audioOutDevEnabled", audioOutDevEnabled); - s.setValue("inGain", audioInGainDecibel); - s.setValue("audioThreshold", audioThreshold); - s.setValue("outVolume", outVolume); - s.setValue("enableTestSound", enableTestSound); - s.setValue("audioBitrate", audioBitrate); - } - s.endGroup(); - - s.beginGroup("Video"); - { - s.setValue("videoDev", videoDev); - s.setValue("camVideoRes", camVideoRes); - s.setValue("camVideoFPS", camVideoFPS); - s.setValue("screenRegion", screenRegion); - s.setValue("screenGrabbed", screenGrabbed); - } - s.endGroup(); + if (QThread::currentThread() != settingsThread) + return (void)QMetaObject::invokeMethod(&getInstance(), "saveGlobal"); + + QMutexLocker locker{&bigLock}; + if (!loaded) return; + + QString path = getSettingsDirPath() + globalSettingsFile; + qDebug() << "Saving global settings at " + path; + + QSettings s(path, QSettings::IniFormat); + s.setIniCodec("UTF-8"); + + s.clear(); + + s.beginGroup("Login"); + { s.setValue("autoLogin", autoLogin); } + s.endGroup(); + + s.beginGroup("General"); + { + s.setValue("autoAwayTime", autoAwayTime); + s.setValue("checkUpdates", checkUpdates); + s.setValue("notifySound", notifySound); + s.setValue("notifyHide", notifyHide); + s.setValue("busySound", busySound); + s.setValue("autoAcceptMaxSize", static_cast(autoAcceptMaxSize)); + s.setValue("globalAutoAcceptDir", globalAutoAcceptDir); + s.setValue("stylePreference", static_cast(stylePreference)); + } + s.endGroup(); + + s.beginGroup("Advanced"); + { + s.setValue("makeToxPortable", makeToxPortable); + s.setValue("enableIPv6", enableIPv6); + s.setValue("forceTCP", forceTCP); + s.setValue("enableLanDiscovery", enableLanDiscovery); + s.setValue("dbSyncType", static_cast(dbSyncType)); + } + s.endGroup(); + + s.beginGroup("Widgets"); + { + const QList widgetNames = widgetSettings.keys(); + for (const QString& name : widgetNames) s.setValue(name, widgetSettings.value(name)); + } + s.endGroup(); + + s.beginGroup("GUI"); + { + s.setValue("showWindow", showWindow); + s.setValue("notify", notify); + s.setValue("desktopNotify", desktopNotify); + s.setValue("groupAlwaysNotify", groupAlwaysNotify); + s.setValue("separateWindow", separateWindow); + s.setValue("dontGroupWindows", dontGroupWindows); + s.setValue("groupchatPosition", groupchatPosition); + s.setValue("showIdenticons", showIdenticons); + + s.setValue("smileyPack", smileyPack); + s.setValue("emojiFontPointSize", emojiFontPointSize); + s.setValue("firstColumnHandlePos", firstColumnHandlePos); + s.setValue("secondColumnHandlePosFromRight", secondColumnHandlePosFromRight); + s.setValue("timestampFormat", timestampFormat); + s.setValue("dateFormat", dateFormat); + s.setValue("lightTrayIcon", lightTrayIcon); + s.setValue("useEmoticons", useEmoticons); + s.setValue("themeColor", themeColor); + s.setValue("style", style); + s.setValue("nameColors", nameColors); + s.setValue("statusChangeNotificationEnabled", statusChangeNotificationEnabled); + s.setValue("showGroupJoinLeaveMessages", showGroupJoinLeaveMessages); + s.setValue("spellCheckingEnabled", spellCheckingEnabled); + } + s.endGroup(); + + s.beginGroup("Chat"); + { s.setValue("chatMessageFont", chatMessageFont); } + s.endGroup(); + + s.beginGroup("State"); + { + s.setValue("windowGeometry", windowGeometry); + s.setValue("windowState", windowState); + s.setValue("splitterState", splitterState); + s.setValue("dialogGeometry", dialogGeometry); + s.setValue("dialogSplitterState", dialogSplitterState); + s.setValue("dialogSettingsGeometry", dialogSettingsGeometry); + } + s.endGroup(); + // 音频 + s.beginGroup("Audio"); + { + s.setValue("inDev", inDev); + s.setValue("audioInDevEnabled", audioInDevEnabled); + s.setValue("outDev", outDev); + s.setValue("audioOutDevEnabled", audioOutDevEnabled); + s.setValue("inGain", audioInGainDecibel); + s.setValue("audioThreshold", audioThreshold); + s.setValue("outVolume", outVolume); + s.setValue("enableTestSound", enableTestSound); + s.setValue("audioBitrate", audioBitrate); + } + s.endGroup(); + + s.beginGroup("Video"); + { + s.setValue("videoDev", videoDev); + s.setValue("camVideoRes", camVideoRes); + s.setValue("camVideoFPS", camVideoFPS); + s.setValue("screenRegion", screenRegion); + s.setValue("screenGrabbed", screenGrabbed); + } + s.endGroup(); } /** @@ -613,130 +590,123 @@ void Settings::saveGlobal() { * @note If basename is "profile", settings will be saved in profile.ini */ void Settings::createPersonal(QString basename) { + QMutexLocker locker{&bigLock}; - QMutexLocker locker{&bigLock}; + qDebug() << "Creating new profile for" << basename; + QString path = getSettingsDirPath() + QDir::separator() + basename + ".ini"; + qDebug() << "Creating new profile settings in " << path; - qDebug() << "Creating new profile for" << basename; - QString path = getSettingsDirPath() + QDir::separator() + basename + ".ini"; - qDebug() << "Creating new profile settings in " << path; + QSettings ps(path, QSettings::IniFormat); + ps.setIniCodec("UTF-8"); + ps.beginGroup("Friends"); + // ps.beginWriteArray("IMFriend", 0); + // ps.endArray(); + ps.endGroup(); - QSettings ps(path, QSettings::IniFormat); - ps.setIniCodec("UTF-8"); - ps.beginGroup("Friends"); - // ps.beginWriteArray("IMFriend", 0); - // ps.endArray(); - ps.endGroup(); + ps.beginGroup("Privacy"); + ps.endGroup(); +} - ps.beginGroup("Privacy"); - ps.endGroup(); +void Settings::loadPersonal(QString profileName, const ToxEncrypt* passKey) { + QMutexLocker locker{&bigLock}; -} + QDir dir(getSettingsDirPath()); + QString filePath = dir.filePath(globalSettingsFile); + // load from a profile specific friend data list if possible + QString tmp = dir.filePath(profileName + ".ini"); + if (QFile(tmp).exists()) // otherwise, filePath remains the global file + filePath = tmp; -void Settings::loadPersonal(QString profileName, const ToxEncrypt *passKey) { - QMutexLocker locker{&bigLock}; + qDebug() << "Loading personal settings from" << filePath; - QDir dir(getSettingsDirPath()); - QString filePath = dir.filePath(globalSettingsFile); + QSettings ps(filePath, QSettings::IniFormat); + friendLst.clear(); - // load from a profile specific friend data list if possible - QString tmp = dir.filePath(profileName + ".ini"); - if (QFile(tmp).exists()) // otherwise, filePath remains the global file - filePath = tmp; + ps.beginGroup("Privacy"); + { + typingNotification = ps.value("typingNotification", true).toBool(); + enableLogging = ps.value("enableLogging", true).toBool(); + blackList = ps.value("blackList").toString().split('\n'); + } + ps.endGroup(); - qDebug() << "Loading personal settings from" << filePath; + ps.beginGroup("Friends"); + { + int size = ps.beginReadArray("IMFriend"); + friendLst.reserve(size); + friendLst.clear(); + for (int i = 0; i < size; i++) { + ps.setArrayIndex(i); + friendProp fp{ps.value("addr").toString()}; + fp.alias = ps.value("alias").toString(); + fp.note = ps.value("note").toString(); + fp.autoAcceptDir = ps.value("autoAcceptDir").toString(); + + if (fp.autoAcceptDir == "") fp.autoAcceptDir = ps.value("autoAccept").toString(); + + fp.autoAcceptCall = + Settings::AutoAcceptCallFlags(QFlag(ps.value("autoAcceptCall", 0).toInt())); + fp.autoGroupInvite = ps.value("autoGroupInvite").toBool(); + fp.circleID = ps.value("circle", -1).toInt(); + + if (getEnableLogging()) fp.activity = ps.value("activity", QDateTime()).toDateTime(); + friendLst.insert(ToxId(fp.addr).getPublicKey().getByteArray(), fp); + } + ps.endArray(); + } + ps.endGroup(); - QSettings ps(filePath, QSettings::IniFormat); - friendLst.clear(); + ps.beginGroup("Requests"); + { + int size = ps.beginReadArray("Request"); + friendRequests.clear(); + friendRequests.reserve(size); + for (int i = 0; i < size; i++) { + ps.setArrayIndex(i); + Request request; + request.address = ps.value("addr").toString(); + request.message = ps.value("message").toString(); + request.read = ps.value("read").toBool(); + friendRequests.push_back(request); + } + ps.endArray(); + } + ps.endGroup(); + // 用戶 + ps.beginGroup("GUI"); + { + compactLayout = ps.value("compactLayout", true).toBool(); + sortingMode = static_cast( + ps.value("friendSortingMethod", static_cast(FriendListSortingMode::Name)) + .toInt()); + } + ps.endGroup(); - ps.beginGroup("Privacy"); - { - typingNotification = ps.value("typingNotification", true).toBool(); - enableLogging = ps.value("enableLogging", true).toBool(); - blackList = ps.value("blackList").toString().split('\n'); - } - ps.endGroup(); + ps.beginGroup("Proxy"); + { + proxyType = static_cast(ps.value("proxyType", 0 /* ProxyType::None */).toInt()); + proxyType = fixInvalidProxyType(proxyType); + proxyAddr = ps.value("proxyAddr", proxyAddr).toString(); + proxyPort = static_cast(ps.value("proxyPort", proxyPort).toUInt()); + } + ps.endGroup(); - ps.beginGroup("Friends"); - { - int size = ps.beginReadArray("IMFriend"); - friendLst.reserve(size); - friendLst.clear(); - for (int i = 0; i < size; i++) { - ps.setArrayIndex(i); - friendProp fp{ps.value("addr").toString()}; - fp.alias = ps.value("alias").toString(); - fp.note = ps.value("note").toString(); - fp.autoAcceptDir = ps.value("autoAcceptDir").toString(); - - if (fp.autoAcceptDir == "") - fp.autoAcceptDir = ps.value("autoAccept").toString(); - - fp.autoAcceptCall = Settings::AutoAcceptCallFlags( - QFlag(ps.value("autoAcceptCall", 0).toInt())); - fp.autoGroupInvite = ps.value("autoGroupInvite").toBool(); - fp.circleID = ps.value("circle", -1).toInt(); - - if (getEnableLogging()) - fp.activity = ps.value("activity", QDateTime()).toDateTime(); - friendLst.insert(ToxId(fp.addr).getPublicKey().getByteArray(), fp); - } - ps.endArray(); - } - ps.endGroup(); - - ps.beginGroup("Requests"); - { - int size = ps.beginReadArray("Request"); - friendRequests.clear(); - friendRequests.reserve(size); - for (int i = 0; i < size; i++) { - ps.setArrayIndex(i); - Request request; - request.address = ps.value("addr").toString(); - request.message = ps.value("message").toString(); - request.read = ps.value("read").toBool(); - friendRequests.push_back(request); - } - ps.endArray(); - } - ps.endGroup(); - // 用戶 - ps.beginGroup("GUI"); - { - compactLayout = ps.value("compactLayout", true).toBool(); - sortingMode = static_cast( - ps.value("friendSortingMethod", - static_cast(FriendListSortingMode::Name)) - .toInt()); - } - ps.endGroup(); - - ps.beginGroup("Proxy"); - { - proxyType = static_cast( - ps.value("proxyType", 0 /* ProxyType::None */).toInt()); - proxyType = fixInvalidProxyType(proxyType); - proxyAddr = ps.value("proxyAddr", proxyAddr).toString(); - proxyPort = static_cast(ps.value("proxyPort", proxyPort).toUInt()); - } - ps.endGroup(); - - ps.beginGroup("Circles"); - { - int size = ps.beginReadArray("Circle"); - circleLst.clear(); - circleLst.reserve(size); - for (int i = 0; i < size; i++) { - ps.setArrayIndex(i); - circleProp cp; - cp.name = ps.value("name").toString(); - cp.expanded = ps.value("expanded", true).toBool(); - circleLst.push_back(cp); - } - ps.endArray(); - } - ps.endGroup(); + ps.beginGroup("Circles"); + { + int size = ps.beginReadArray("Circle"); + circleLst.clear(); + circleLst.reserve(size); + for (int i = 0; i < size; i++) { + ps.setArrayIndex(i); + circleProp cp; + cp.name = ps.value("name").toString(); + cp.expanded = ps.value("expanded", true).toBool(); + circleLst.push_back(cp); + } + ps.endArray(); + } + ps.endGroup(); } /** @@ -748,104 +718,102 @@ void Settings::savePersonal() { savePersonal(Nexus::getProfile()); } * @brief Asynchronous, saves the profile. * @param profile Profile to save. */ -void Settings::savePersonal(Profile *profile) { - if (!profile) { - qDebug() << "Could not save personal settings because there is no active " - "profile"; - return; - } - if (QThread::currentThread() != settingsThread) - return (void)QMetaObject::invokeMethod(&getInstance(), "savePersonal", - Q_ARG(Profile *, profile)); - savePersonal(profile->getName(), profile->getPasskey()); -} - -void Settings::savePersonal(QString profileName, const ToxEncrypt *passkey) { - QMutexLocker locker{&bigLock}; - if (!loaded) - return; - - QString path = getSettingsDirPath() + profileName + ".ini"; - - qDebug() << "Saving personal settings at " << path; - - QSettings ps(path, QSettings::IniFormat); - ps.beginGroup("Friends"); - { - ps.beginWriteArray("IMFriend", friendLst.size()); - int index = 0; - for (auto &frnd : friendLst) { - ps.setArrayIndex(index); - ps.setValue("addr", frnd.addr); - ps.setValue("alias", frnd.alias); - ps.setValue("note", frnd.note); - ps.setValue("autoAcceptDir", frnd.autoAcceptDir); - ps.setValue("autoAcceptCall", static_cast(frnd.autoAcceptCall)); - ps.setValue("autoGroupInvite", frnd.autoGroupInvite); - ps.setValue("circle", frnd.circleID); - - if (getEnableLogging()) - ps.setValue("activity", frnd.activity); - - ++index; - } - ps.endArray(); - } - ps.endGroup(); - - ps.beginGroup("Requests"); - { - ps.beginWriteArray("Request", friendRequests.size()); - int index = 0; - for (auto &request : friendRequests) { - ps.setArrayIndex(index); - ps.setValue("addr", request.address); - ps.setValue("message", request.message); - ps.setValue("read", request.read); - - ++index; - } - ps.endArray(); - } - ps.endGroup(); - - ps.beginGroup("GUI"); - { - ps.setValue("compactLayout", compactLayout); - ps.setValue("friendSortingMethod", static_cast(sortingMode)); - } - ps.endGroup(); - - ps.beginGroup("Proxy"); - { - ps.setValue("proxyType", static_cast(proxyType)); - ps.setValue("proxyAddr", proxyAddr); - ps.setValue("proxyPort", proxyPort); - } - ps.endGroup(); - - ps.beginGroup("Circles"); - { - ps.beginWriteArray("Circle", circleLst.size()); - int index = 0; - for (auto &circle : circleLst) { - ps.setArrayIndex(index); - ps.setValue("name", circle.name); - ps.setValue("expanded", circle.expanded); - ++index; - } - ps.endArray(); - } - ps.endGroup(); - - ps.beginGroup("Privacy"); - { - ps.setValue("typingNotification", typingNotification); - ps.setValue("enableLogging", enableLogging); - ps.setValue("blackList", blackList.join('\n')); - } - ps.endGroup(); - // ps.save(); +void Settings::savePersonal(Profile* profile) { + if (!profile) { + qDebug() << "Could not save personal settings because there is no active " + "profile"; + return; + } + if (QThread::currentThread() != settingsThread) + return (void)QMetaObject::invokeMethod(&getInstance(), "savePersonal", + Q_ARG(Profile*, profile)); + savePersonal(profile->getName(), profile->getPasskey()); +} + +void Settings::savePersonal(QString profileName, const ToxEncrypt* passkey) { + QMutexLocker locker{&bigLock}; + if (!loaded) return; + + QString path = getSettingsDirPath() + profileName + ".ini"; + + qDebug() << "Saving personal settings at " << path; + + QSettings ps(path, QSettings::IniFormat); + ps.beginGroup("Friends"); + { + ps.beginWriteArray("IMFriend", friendLst.size()); + int index = 0; + for (auto& frnd : friendLst) { + ps.setArrayIndex(index); + ps.setValue("addr", frnd.addr); + ps.setValue("alias", frnd.alias); + ps.setValue("note", frnd.note); + ps.setValue("autoAcceptDir", frnd.autoAcceptDir); + ps.setValue("autoAcceptCall", static_cast(frnd.autoAcceptCall)); + ps.setValue("autoGroupInvite", frnd.autoGroupInvite); + ps.setValue("circle", frnd.circleID); + + if (getEnableLogging()) ps.setValue("activity", frnd.activity); + + ++index; + } + ps.endArray(); + } + ps.endGroup(); + + ps.beginGroup("Requests"); + { + ps.beginWriteArray("Request", friendRequests.size()); + int index = 0; + for (auto& request : friendRequests) { + ps.setArrayIndex(index); + ps.setValue("addr", request.address); + ps.setValue("message", request.message); + ps.setValue("read", request.read); + + ++index; + } + ps.endArray(); + } + ps.endGroup(); + + ps.beginGroup("GUI"); + { + ps.setValue("compactLayout", compactLayout); + ps.setValue("friendSortingMethod", static_cast(sortingMode)); + } + ps.endGroup(); + + ps.beginGroup("Proxy"); + { + ps.setValue("proxyType", static_cast(proxyType)); + ps.setValue("proxyAddr", proxyAddr); + ps.setValue("proxyPort", proxyPort); + } + ps.endGroup(); + + ps.beginGroup("Circles"); + { + ps.beginWriteArray("Circle", circleLst.size()); + int index = 0; + for (auto& circle : circleLst) { + ps.setArrayIndex(index); + ps.setValue("name", circle.name); + ps.setValue("expanded", circle.expanded); + ++index; + } + ps.endArray(); + } + ps.endGroup(); + + ps.beginGroup("Privacy"); + { + ps.setValue("typingNotification", typingNotification); + ps.setValue("enableLogging", enableLogging); + ps.setValue("blackList", blackList.join('\n')); + } + ps.endGroup(); + // ps.save(); } /** @@ -853,28 +821,24 @@ void Settings::savePersonal(QString profileName, const ToxEncrypt *passkey) { * @return Path to settings directory, ends with a directory separator. */ QString Settings::getSettingsDirPath() const { - QMutexLocker locker{&bigLock}; - if (makeToxPortable) - return qApp->applicationDirPath() + QDir::separator(); + QMutexLocker locker{&bigLock}; + if (makeToxPortable) return qApp->applicationDirPath() + QDir::separator(); // workaround for https://bugreports.qt-project.org/browse/QTBUG-38845 #ifdef Q_OS_WIN - return QDir::cleanPath( - QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + - QDir::separator() + "AppData" + QDir::separator() + "Roaming" + - QDir::separator() + APPLICATION_ID) + - QDir::separator(); + return QDir::cleanPath(QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + + QDir::separator() + "AppData" + QDir::separator() + "Roaming" + + QDir::separator() + APPLICATION_ID) + + QDir::separator(); #elif defined(Q_OS_OSX) - return QDir::cleanPath( - QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + - QDir::separator() + "Library" + QDir::separator() + - "Application Support" + QDir::separator() + APPLICATION_ID) + - QDir::separator(); + return QDir::cleanPath(QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + + QDir::separator() + "Library" + QDir::separator() + + "Application Support" + QDir::separator() + APPLICATION_ID) + + QDir::separator(); #else - return QDir::cleanPath( - QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + - QDir::separator() + APPLICATION_ID) + - QDir::separator(); + return QDir::cleanPath(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + + QDir::separator() + APPLICATION_ID) + + QDir::separator(); #endif } @@ -883,351 +847,344 @@ QString Settings::getSettingsDirPath() const { * @return Path to application data, ends with a directory separator. */ QString Settings::getAppDataDirPath() const { - QMutexLocker locker{&bigLock}; - if (makeToxPortable) - return qApp->applicationDirPath() + QDir::separator(); + QMutexLocker locker{&bigLock}; + if (makeToxPortable) return qApp->applicationDirPath() + QDir::separator(); // workaround for https://bugreports.qt-project.org/browse/QTBUG-38845 #ifdef Q_OS_WIN - return QDir::cleanPath( - QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + - QDir::separator() + "AppData" + QDir::separator() + "Roaming" + - QDir::separator() + "tox") + - QDir::separator(); + return QDir::cleanPath(QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + + QDir::separator() + "AppData" + QDir::separator() + "Roaming" + + QDir::separator() + "tox") + + QDir::separator(); #elif defined(Q_OS_OSX) - return QDir::cleanPath( - QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + - QDir::separator() + "Library" + QDir::separator() + - "Application Support" + QDir::separator() + "Tox") + - QDir::separator(); + return QDir::cleanPath(QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + + QDir::separator() + "Library" + QDir::separator() + + "Application Support" + QDir::separator() + "Tox") + + QDir::separator(); #else - /* - * TODO: Change QStandardPaths::DataLocation to AppDataLocation when upgrate - * Qt to 5.4+ For now we need support Qt 5.3, so we use deprecated - * DataLocation BTW, it's not a big deal since for linux AppDataLocation and - * DataLocation are equal - */ - return QDir::cleanPath( - QStandardPaths::writableLocation(QStandardPaths::DataLocation)) + - QDir::separator(); + /* + * TODO: Change QStandardPaths::DataLocation to AppDataLocation when upgrate + * Qt to 5.4+ For now we need support Qt 5.3, so we use deprecated + * DataLocation BTW, it's not a big deal since for linux AppDataLocation and + * DataLocation are equal + */ + return QDir::cleanPath(QStandardPaths::writableLocation(QStandardPaths::DataLocation)) + + QDir::separator(); #endif } - bool Settings::getEnableTestSound() const { - QMutexLocker locker{&bigLock}; - return enableTestSound; + QMutexLocker locker{&bigLock}; + return enableTestSound; } void Settings::setEnableTestSound(bool newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != enableTestSound) { - enableTestSound = newValue; - emit enableTestSoundChanged(enableTestSound); - } + if (newValue != enableTestSound) { + enableTestSound = newValue; + emit enableTestSoundChanged(enableTestSound); + } } bool Settings::getEnableIPv6() const { - QMutexLocker locker{&bigLock}; - return enableIPv6; + QMutexLocker locker{&bigLock}; + return enableIPv6; } void Settings::setEnableIPv6(bool enabled) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (enabled != enableIPv6) { - enableIPv6 = enabled; - emit enableIPv6Changed(enableIPv6); - } + if (enabled != enableIPv6) { + enableIPv6 = enabled; + emit enableIPv6Changed(enableIPv6); + } } bool Settings::getMakeToxPortable() const { - QMutexLocker locker{&bigLock}; - return makeToxPortable; + QMutexLocker locker{&bigLock}; + return makeToxPortable; } void Settings::setMakeToxPortable(bool newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != makeToxPortable) { - QFile(getSettingsDirPath() + globalSettingsFile).remove(); - makeToxPortable = newValue; - saveGlobal(); + if (newValue != makeToxPortable) { + QFile(getSettingsDirPath() + globalSettingsFile).remove(); + makeToxPortable = newValue; + saveGlobal(); - emit makeToxPortableChanged(makeToxPortable); - } + emit makeToxPortableChanged(makeToxPortable); + } } QString Settings::getStyle() const { - QMutexLocker locker{&bigLock}; - return style; + QMutexLocker locker{&bigLock}; + return style; } -void Settings::setStyle(const QString &newStyle) { - QMutexLocker locker{&bigLock}; +void Settings::setStyle(const QString& newStyle) { + QMutexLocker locker{&bigLock}; - if (newStyle != style) { - style = newStyle; - emit styleChanged(style); - } + if (newStyle != style) { + style = newStyle; + emit styleChanged(style); + } } void Settings::setUseEmoticons(bool newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != useEmoticons) { - useEmoticons = newValue; - emit useEmoticonsChanged(useEmoticons); - } + if (newValue != useEmoticons) { + useEmoticons = newValue; + emit useEmoticonsChanged(useEmoticons); + } } bool Settings::getUseEmoticons() const { - QMutexLocker locker{&bigLock}; - return useEmoticons; + QMutexLocker locker{&bigLock}; + return useEmoticons; } bool Settings::getLightTrayIcon() const { - QMutexLocker locker{&bigLock}; - return lightTrayIcon; + QMutexLocker locker{&bigLock}; + return lightTrayIcon; } void Settings::setLightTrayIcon(bool newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != lightTrayIcon) { - lightTrayIcon = newValue; - emit lightTrayIconChanged(lightTrayIcon); - } + if (newValue != lightTrayIcon) { + lightTrayIcon = newValue; + emit lightTrayIconChanged(lightTrayIcon); + } } bool Settings::getStatusChangeNotificationEnabled() const { - QMutexLocker locker{&bigLock}; - return statusChangeNotificationEnabled; + QMutexLocker locker{&bigLock}; + return statusChangeNotificationEnabled; } void Settings::setStatusChangeNotificationEnabled(bool newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != statusChangeNotificationEnabled) { - statusChangeNotificationEnabled = newValue; - emit statusChangeNotificationEnabledChanged( - statusChangeNotificationEnabled); - } + if (newValue != statusChangeNotificationEnabled) { + statusChangeNotificationEnabled = newValue; + emit statusChangeNotificationEnabledChanged(statusChangeNotificationEnabled); + } } bool Settings::getShowGroupJoinLeaveMessages() const { - QMutexLocker locker{&bigLock}; - return showGroupJoinLeaveMessages; + QMutexLocker locker{&bigLock}; + return showGroupJoinLeaveMessages; } void Settings::setShowGroupJoinLeaveMessages(bool newValue) { - QMutexLocker locker{&bigLock}; - if (newValue != showGroupJoinLeaveMessages) { - showGroupJoinLeaveMessages = newValue; - emit showGroupJoinLeaveMessagesChanged(showGroupJoinLeaveMessages); - } + QMutexLocker locker{&bigLock}; + if (newValue != showGroupJoinLeaveMessages) { + showGroupJoinLeaveMessages = newValue; + emit showGroupJoinLeaveMessagesChanged(showGroupJoinLeaveMessages); + } } bool Settings::getSpellCheckingEnabled() const { - const QMutexLocker locker{&bigLock}; - return spellCheckingEnabled; + const QMutexLocker locker{&bigLock}; + return spellCheckingEnabled; } void Settings::setSpellCheckingEnabled(bool newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != spellCheckingEnabled) { - spellCheckingEnabled = newValue; - emit statusChangeNotificationEnabledChanged( - statusChangeNotificationEnabled); - } + if (newValue != spellCheckingEnabled) { + spellCheckingEnabled = newValue; + emit statusChangeNotificationEnabledChanged(statusChangeNotificationEnabled); + } } bool Settings::getNotifySound() const { - QMutexLocker locker{&bigLock}; - return notifySound; + QMutexLocker locker{&bigLock}; + return notifySound; } void Settings::setNotifySound(bool newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != notifySound) { - notifySound = newValue; - emit notifySoundChanged(notifySound); - } + if (newValue != notifySound) { + notifySound = newValue; + emit notifySoundChanged(notifySound); + } } bool Settings::getNotifyHide() const { - QMutexLocker locker{&bigLock}; - return notifyHide; + QMutexLocker locker{&bigLock}; + return notifyHide; } void Settings::setNotifyHide(bool newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != notifyHide) { - notifyHide = newValue; - emit notifyHideChanged(notifyHide); - } + if (newValue != notifyHide) { + notifyHide = newValue; + emit notifyHideChanged(notifyHide); + } } bool Settings::getBusySound() const { - QMutexLocker locker{&bigLock}; - return busySound; + QMutexLocker locker{&bigLock}; + return busySound; } void Settings::setBusySound(bool newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != busySound) { - busySound = newValue; - emit busySoundChanged(busySound); - } + if (newValue != busySound) { + busySound = newValue; + emit busySoundChanged(busySound); + } } bool Settings::getGroupAlwaysNotify() const { - QMutexLocker locker{&bigLock}; - return groupAlwaysNotify; + QMutexLocker locker{&bigLock}; + return groupAlwaysNotify; } void Settings::setGroupAlwaysNotify(bool newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != groupAlwaysNotify) { - groupAlwaysNotify = newValue; - emit groupAlwaysNotifyChanged(groupAlwaysNotify); - } + if (newValue != groupAlwaysNotify) { + groupAlwaysNotify = newValue; + emit groupAlwaysNotifyChanged(groupAlwaysNotify); + } } QString Settings::getTranslation() const { - QMutexLocker locker{&bigLock}; - auto &s = ok::base::OkSettings::getInstance(); - return s.getTranslation(); -} - -void Settings::setTranslation(const QString &newValue) { - QMutexLocker locker{&bigLock}; - auto &s = ok::base::OkSettings::getInstance(); - auto translation = s.getTranslation(); - if (newValue != translation) { - translation = newValue; - s.translationChanged(translation); - } + QMutexLocker locker{&bigLock}; + auto& s = ok::base::OkSettings::getInstance(); + return s.getTranslation(); +} + +void Settings::setTranslation(const QString& newValue) { + QMutexLocker locker{&bigLock}; + auto& s = ok::base::OkSettings::getInstance(); + auto translation = s.getTranslation(); + if (newValue != translation) { + translation = newValue; + s.translationChanged(translation); + } } bool Settings::getForceTCP() const { - QMutexLocker locker{&bigLock}; - return forceTCP; + QMutexLocker locker{&bigLock}; + return forceTCP; } void Settings::setForceTCP(bool enabled) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (enabled != forceTCP) { - forceTCP = enabled; - emit forceTCPChanged(forceTCP); - } + if (enabled != forceTCP) { + forceTCP = enabled; + emit forceTCPChanged(forceTCP); + } } bool Settings::getEnableLanDiscovery() const { - QMutexLocker locker{&bigLock}; - return enableLanDiscovery; + QMutexLocker locker{&bigLock}; + return enableLanDiscovery; } void Settings::setEnableLanDiscovery(bool enabled) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (enabled != enableLanDiscovery) { - enableLanDiscovery = enabled; - emit enableLanDiscoveryChanged(enableLanDiscovery); - } + if (enabled != enableLanDiscovery) { + enableLanDiscovery = enabled; + emit enableLanDiscoveryChanged(enableLanDiscovery); + } } QNetworkProxy Settings::getProxy() const { - QMutexLocker locker{&bigLock}; - - QNetworkProxy proxy; - switch (Settings::getProxyType()) { - case ProxyType::ptNone: - proxy.setType(QNetworkProxy::NoProxy); - break; - case ProxyType::ptSOCKS5: - proxy.setType(QNetworkProxy::Socks5Proxy); - break; - case ProxyType::ptHTTP: - proxy.setType(QNetworkProxy::HttpProxy); - break; - default: - proxy.setType(QNetworkProxy::NoProxy); - qWarning() << "Invalid Proxy type, setting to NoProxy"; - break; - } - - proxy.setHostName(Settings::getProxyAddr()); - proxy.setPort(Settings::getProxyPort()); - return proxy; + QMutexLocker locker{&bigLock}; + + QNetworkProxy proxy; + switch (Settings::getProxyType()) { + case ProxyType::ptNone: + proxy.setType(QNetworkProxy::NoProxy); + break; + case ProxyType::ptSOCKS5: + proxy.setType(QNetworkProxy::Socks5Proxy); + break; + case ProxyType::ptHTTP: + proxy.setType(QNetworkProxy::HttpProxy); + break; + default: + proxy.setType(QNetworkProxy::NoProxy); + qWarning() << "Invalid Proxy type, setting to NoProxy"; + break; + } + + proxy.setHostName(Settings::getProxyAddr()); + proxy.setPort(Settings::getProxyPort()); + return proxy; } Settings::ProxyType Settings::getProxyType() const { - QMutexLocker locker{&bigLock}; - return proxyType; + QMutexLocker locker{&bigLock}; + return proxyType; } void Settings::setProxyType(ProxyType newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != proxyType) { - proxyType = newValue; - emit proxyTypeChanged(proxyType); - } + if (newValue != proxyType) { + proxyType = newValue; + emit proxyTypeChanged(proxyType); + } } QString Settings::getProxyAddr() const { - QMutexLocker locker{&bigLock}; - return proxyAddr; + QMutexLocker locker{&bigLock}; + return proxyAddr; } -void Settings::setProxyAddr(const QString &address) { - QMutexLocker locker{&bigLock}; +void Settings::setProxyAddr(const QString& address) { + QMutexLocker locker{&bigLock}; - if (address != proxyAddr) { - proxyAddr = address; - emit proxyAddressChanged(proxyAddr); - } + if (address != proxyAddr) { + proxyAddr = address; + emit proxyAddressChanged(proxyAddr); + } } quint16 Settings::getProxyPort() const { - QMutexLocker locker{&bigLock}; - return proxyPort; + QMutexLocker locker{&bigLock}; + return proxyPort; } void Settings::setProxyPort(quint16 port) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (port != proxyPort) { - proxyPort = port; - emit proxyPortChanged(proxyPort); - } + if (port != proxyPort) { + proxyPort = port; + emit proxyPortChanged(proxyPort); + } } bool Settings::getEnableLogging() const { - QMutexLocker locker{&bigLock}; - return enableLogging; + QMutexLocker locker{&bigLock}; + return enableLogging; } void Settings::setEnableLogging(bool newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != enableLogging) { - enableLogging = newValue; - emit enableLoggingChanged(enableLogging); - } + if (newValue != enableLogging) { + enableLogging = newValue; + emit enableLoggingChanged(enableLogging); + } } int Settings::getAutoAwayTime() const { - QMutexLocker locker{&bigLock}; - return autoAwayTime; + QMutexLocker locker{&bigLock}; + return autoAwayTime; } /** @@ -1237,883 +1194,868 @@ int Settings::getAutoAwayTime() const { * @note Values < 0 default to 10 minutes. */ void Settings::setAutoAwayTime(int newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue < 0) - newValue = 10; + if (newValue < 0) newValue = 10; - if (newValue != autoAwayTime) { - autoAwayTime = newValue; - emit autoAwayTimeChanged(autoAwayTime); - } + if (newValue != autoAwayTime) { + autoAwayTime = newValue; + emit autoAwayTimeChanged(autoAwayTime); + } } -QString Settings::getAutoAcceptDir(const FriendId &id) const { - QMutexLocker locker{&bigLock}; +QString Settings::getAutoAcceptDir(const FriendId& id) const { + QMutexLocker locker{&bigLock}; - auto it = friendLst.find(id.getByteArray()); - if (it != friendLst.end()) - return it->autoAcceptDir; + auto it = friendLst.find(id.getByteArray()); + if (it != friendLst.end()) return it->autoAcceptDir; - return QString(); + return QString(); } -void Settings::setAutoAcceptDir(const FriendId &id, const QString &dir) { - QMutexLocker locker{&bigLock}; +void Settings::setAutoAcceptDir(const FriendId& id, const QString& dir) { + QMutexLocker locker{&bigLock}; - auto &frnd = getOrInsertFriendPropRef(id); + auto& frnd = getOrInsertFriendPropRef(id); - if (frnd.autoAcceptDir != dir) { - frnd.autoAcceptDir = dir; - emit autoAcceptDirChanged(id, dir); - } + if (frnd.autoAcceptDir != dir) { + frnd.autoAcceptDir = dir; + emit autoAcceptDirChanged(id, dir); + } } -Settings::AutoAcceptCallFlags -Settings::getAutoAcceptCall(const FriendId &id) const { - QMutexLocker locker{&bigLock}; +Settings::AutoAcceptCallFlags Settings::getAutoAcceptCall(const FriendId& id) const { + QMutexLocker locker{&bigLock}; - auto it = friendLst.find(id.getByteArray()); - if (it != friendLst.end()) - return it->autoAcceptCall; + auto it = friendLst.find(id.getByteArray()); + if (it != friendLst.end()) return it->autoAcceptCall; - return Settings::AutoAcceptCallFlags(); + return Settings::AutoAcceptCallFlags(); } -void Settings::setAutoAcceptCall(const FriendId &id, AutoAcceptCallFlags accept) { - QMutexLocker locker{&bigLock}; +void Settings::setAutoAcceptCall(const FriendId& id, AutoAcceptCallFlags accept) { + QMutexLocker locker{&bigLock}; - auto &frnd = getOrInsertFriendPropRef(id); + auto& frnd = getOrInsertFriendPropRef(id); - if (frnd.autoAcceptCall != accept) { - frnd.autoAcceptCall = accept; - emit autoAcceptCallChanged(id, accept); - } + if (frnd.autoAcceptCall != accept) { + frnd.autoAcceptCall = accept; + emit autoAcceptCallChanged(id, accept); + } } -bool Settings::getAutoGroupInvite(const FriendId &id) const { - QMutexLocker locker{&bigLock}; +bool Settings::getAutoGroupInvite(const FriendId& id) const { + QMutexLocker locker{&bigLock}; - auto it = friendLst.find(id.getByteArray()); - if (it != friendLst.end()) { - return it->autoGroupInvite; - } + auto it = friendLst.find(id.getByteArray()); + if (it != friendLst.end()) { + return it->autoGroupInvite; + } - return false; + return false; } -void Settings::setAutoGroupInvite(const FriendId &id, bool accept) { - QMutexLocker locker{&bigLock}; +void Settings::setAutoGroupInvite(const FriendId& id, bool accept) { + QMutexLocker locker{&bigLock}; - auto &frnd = getOrInsertFriendPropRef(id); + auto& frnd = getOrInsertFriendPropRef(id); - if (frnd.autoGroupInvite != accept) { - frnd.autoGroupInvite = accept; - emit autoGroupInviteChanged(id, accept); - } + if (frnd.autoGroupInvite != accept) { + frnd.autoGroupInvite = accept; + emit autoGroupInviteChanged(id, accept); + } } -QString Settings::getContactNote(const FriendId &id) const { - QMutexLocker locker{&bigLock}; +QString Settings::getContactNote(const FriendId& id) const { + QMutexLocker locker{&bigLock}; - auto it = friendLst.find(id.getByteArray()); - if (it != friendLst.end()) - return it->note; + auto it = friendLst.find(id.getByteArray()); + if (it != friendLst.end()) return it->note; - return QString(); + return QString(); } -void Settings::setContactNote(const FriendId &id, const QString ¬e) { - QMutexLocker locker{&bigLock}; +void Settings::setContactNote(const FriendId& id, const QString& note) { + QMutexLocker locker{&bigLock}; - auto &frnd = getOrInsertFriendPropRef(id); + auto& frnd = getOrInsertFriendPropRef(id); - if (frnd.note != note) { - frnd.note = note; - emit contactNoteChanged(id, note); - } + if (frnd.note != note) { + frnd.note = note; + emit contactNoteChanged(id, note); + } } QString Settings::getGlobalAutoAcceptDir() const { - QMutexLocker locker{&bigLock}; - return globalAutoAcceptDir; + QMutexLocker locker{&bigLock}; + return globalAutoAcceptDir; } -void Settings::setGlobalAutoAcceptDir(const QString &newValue) { - QMutexLocker locker{&bigLock}; +void Settings::setGlobalAutoAcceptDir(const QString& newValue) { + QMutexLocker locker{&bigLock}; - if (newValue != globalAutoAcceptDir) { - globalAutoAcceptDir = newValue; - emit globalAutoAcceptDirChanged(globalAutoAcceptDir); - } + if (newValue != globalAutoAcceptDir) { + globalAutoAcceptDir = newValue; + emit globalAutoAcceptDirChanged(globalAutoAcceptDir); + } } size_t Settings::getMaxAutoAcceptSize() const { - QMutexLocker locker{&bigLock}; - return autoAcceptMaxSize; + QMutexLocker locker{&bigLock}; + return autoAcceptMaxSize; } void Settings::setMaxAutoAcceptSize(size_t size) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (size != autoAcceptMaxSize) { - autoAcceptMaxSize = size; - emit autoAcceptMaxSizeChanged(autoAcceptMaxSize); - } + if (size != autoAcceptMaxSize) { + autoAcceptMaxSize = size; + emit autoAcceptMaxSizeChanged(autoAcceptMaxSize); + } } -const QFont &Settings::getChatMessageFont() const { - QMutexLocker locker(&bigLock); - return chatMessageFont; +const QFont& Settings::getChatMessageFont() const { + QMutexLocker locker(&bigLock); + return chatMessageFont; } -void Settings::setChatMessageFont(const QFont &font) { - QMutexLocker locker(&bigLock); +void Settings::setChatMessageFont(const QFont& font) { + QMutexLocker locker(&bigLock); - if (font != chatMessageFont) { - chatMessageFont = font; - emit chatMessageFontChanged(chatMessageFont); - } + if (font != chatMessageFont) { + chatMessageFont = font; + emit chatMessageFontChanged(chatMessageFont); + } } -void Settings::setWidgetData(const QString &uniqueName, - const QByteArray &data) { - QMutexLocker locker{&bigLock}; +void Settings::setWidgetData(const QString& uniqueName, const QByteArray& data) { + QMutexLocker locker{&bigLock}; - if (!widgetSettings.contains(uniqueName) || - widgetSettings[uniqueName] != data) { - widgetSettings[uniqueName] = data; - emit widgetDataChanged(uniqueName); - } + if (!widgetSettings.contains(uniqueName) || widgetSettings[uniqueName] != data) { + widgetSettings[uniqueName] = data; + emit widgetDataChanged(uniqueName); + } } -QByteArray Settings::getWidgetData(const QString &uniqueName) const { - QMutexLocker locker{&bigLock}; - return widgetSettings.value(uniqueName); +QByteArray Settings::getWidgetData(const QString& uniqueName) const { + QMutexLocker locker{&bigLock}; + return widgetSettings.value(uniqueName); } QString Settings::getSmileyPack() const { - QMutexLocker locker{&bigLock}; - return smileyPack; + QMutexLocker locker{&bigLock}; + return smileyPack; } -void Settings::setSmileyPack(const QString &value) { - QMutexLocker locker{&bigLock}; +void Settings::setSmileyPack(const QString& value) { + QMutexLocker locker{&bigLock}; - if (value != smileyPack) { - smileyPack = value; - emit smileyPackChanged(smileyPack); - } + if (value != smileyPack) { + smileyPack = value; + emit smileyPackChanged(smileyPack); + } } int Settings::getEmojiFontPointSize() const { - QMutexLocker locker{&bigLock}; - return emojiFontPointSize; + QMutexLocker locker{&bigLock}; + return emojiFontPointSize; } void Settings::setEmojiFontPointSize(int value) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (value != emojiFontPointSize) { - emojiFontPointSize = value; - emit emojiFontPointSizeChanged(emojiFontPointSize); - } + if (value != emojiFontPointSize) { + emojiFontPointSize = value; + emit emojiFontPointSizeChanged(emojiFontPointSize); + } } -const QString &Settings::getTimestampFormat() const { - QMutexLocker locker{&bigLock}; - return timestampFormat; +const QString& Settings::getTimestampFormat() const { + QMutexLocker locker{&bigLock}; + return timestampFormat; } -void Settings::setTimestampFormat(const QString &format) { - QMutexLocker locker{&bigLock}; +void Settings::setTimestampFormat(const QString& format) { + QMutexLocker locker{&bigLock}; - if (format != timestampFormat) { - timestampFormat = format; - emit timestampFormatChanged(timestampFormat); - } + if (format != timestampFormat) { + timestampFormat = format; + emit timestampFormatChanged(timestampFormat); + } } -const QString &Settings::getDateFormat() const { - QMutexLocker locker{&bigLock}; - return dateFormat; +const QString& Settings::getDateFormat() const { + QMutexLocker locker{&bigLock}; + return dateFormat; } -void Settings::setDateFormat(const QString &format) { - QMutexLocker locker{&bigLock}; +void Settings::setDateFormat(const QString& format) { + QMutexLocker locker{&bigLock}; - if (format != dateFormat) { - dateFormat = format; - emit dateFormatChanged(dateFormat); - } + if (format != dateFormat) { + dateFormat = format; + emit dateFormatChanged(dateFormat); + } } Settings::StyleType Settings::getStylePreference() const { - QMutexLocker locker{&bigLock}; - return stylePreference; + QMutexLocker locker{&bigLock}; + return stylePreference; } void Settings::setStylePreference(StyleType newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != stylePreference) { - stylePreference = newValue; - emit stylePreferenceChanged(stylePreference); - } + if (newValue != stylePreference) { + stylePreference = newValue; + emit stylePreferenceChanged(stylePreference); + } } QByteArray Settings::getWindowGeometry() const { - QMutexLocker locker{&bigLock}; - return windowGeometry; + QMutexLocker locker{&bigLock}; + return windowGeometry; } -void Settings::setWindowGeometry(const QByteArray &value) { - QMutexLocker locker{&bigLock}; +void Settings::setWindowGeometry(const QByteArray& value) { + QMutexLocker locker{&bigLock}; - if (value != windowGeometry) { - windowGeometry = value; - emit windowGeometryChanged(windowGeometry); - } + if (value != windowGeometry) { + windowGeometry = value; + emit windowGeometryChanged(windowGeometry); + } } QByteArray Settings::getWindowState() const { - QMutexLocker locker{&bigLock}; - return windowState; + QMutexLocker locker{&bigLock}; + return windowState; } -void Settings::setWindowState(const QByteArray &value) { - QMutexLocker locker{&bigLock}; +void Settings::setWindowState(const QByteArray& value) { + QMutexLocker locker{&bigLock}; - if (value != windowState) { - windowState = value; - emit windowStateChanged(windowState); - } + if (value != windowState) { + windowState = value; + emit windowStateChanged(windowState); + } } bool Settings::getCheckUpdates() const { - QMutexLocker locker{&bigLock}; - return checkUpdates; + QMutexLocker locker{&bigLock}; + return checkUpdates; } void Settings::setCheckUpdates(bool newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != checkUpdates) { - checkUpdates = newValue; - emit checkUpdatesChanged(checkUpdates); - } + if (newValue != checkUpdates) { + checkUpdates = newValue; + emit checkUpdatesChanged(checkUpdates); + } } bool Settings::getNotify() const { - QMutexLocker locker{&bigLock}; - return notify; + QMutexLocker locker{&bigLock}; + return notify; } void Settings::setNotify(bool newValue) { - QMutexLocker locker{&bigLock}; - if (newValue != notify) { - notify = newValue; - emit notifyChanged(notify); - } + QMutexLocker locker{&bigLock}; + if (newValue != notify) { + notify = newValue; + emit notifyChanged(notify); + } } bool Settings::getShowWindow() const { - QMutexLocker locker{&bigLock}; - return showWindow; + QMutexLocker locker{&bigLock}; + return showWindow; } void Settings::setShowWindow(bool newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != showWindow) { - showWindow = newValue; - emit showWindowChanged(showWindow); - } + if (newValue != showWindow) { + showWindow = newValue; + emit showWindowChanged(showWindow); + } } bool Settings::getDesktopNotify() const { - QMutexLocker locker{&bigLock}; - return desktopNotify; + QMutexLocker locker{&bigLock}; + return desktopNotify; } void Settings::setDesktopNotify(bool enabled) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (enabled != desktopNotify) { - desktopNotify = enabled; - emit desktopNotifyChanged(desktopNotify); - } + if (enabled != desktopNotify) { + desktopNotify = enabled; + emit desktopNotifyChanged(desktopNotify); + } } QByteArray Settings::getSplitterState() const { - QMutexLocker locker{&bigLock}; - return splitterState; + QMutexLocker locker{&bigLock}; + return splitterState; } -void Settings::setSplitterState(const QByteArray &value) { - QMutexLocker locker{&bigLock}; +void Settings::setSplitterState(const QByteArray& value) { + QMutexLocker locker{&bigLock}; - if (value != splitterState) { - splitterState = value; - emit splitterStateChanged(splitterState); - } + if (value != splitterState) { + splitterState = value; + emit splitterStateChanged(splitterState); + } } QByteArray Settings::getDialogGeometry() const { - QMutexLocker locker{&bigLock}; - return dialogGeometry; + QMutexLocker locker{&bigLock}; + return dialogGeometry; } -void Settings::setDialogGeometry(const QByteArray &value) { - QMutexLocker locker{&bigLock}; +void Settings::setDialogGeometry(const QByteArray& value) { + QMutexLocker locker{&bigLock}; - if (value != dialogGeometry) { - dialogGeometry = value; - emit dialogGeometryChanged(dialogGeometry); - } + if (value != dialogGeometry) { + dialogGeometry = value; + emit dialogGeometryChanged(dialogGeometry); + } } QByteArray Settings::getDialogSplitterState() const { - QMutexLocker locker{&bigLock}; - return dialogSplitterState; + QMutexLocker locker{&bigLock}; + return dialogSplitterState; } -void Settings::setDialogSplitterState(const QByteArray &value) { - QMutexLocker locker{&bigLock}; +void Settings::setDialogSplitterState(const QByteArray& value) { + QMutexLocker locker{&bigLock}; - if (value != dialogSplitterState) { - dialogSplitterState = value; - emit dialogSplitterStateChanged(dialogSplitterState); - } + if (value != dialogSplitterState) { + dialogSplitterState = value; + emit dialogSplitterStateChanged(dialogSplitterState); + } } QByteArray Settings::getDialogSettingsGeometry() const { - QMutexLocker locker{&bigLock}; - return dialogSettingsGeometry; + QMutexLocker locker{&bigLock}; + return dialogSettingsGeometry; } -void Settings::setDialogSettingsGeometry(const QByteArray &value) { - QMutexLocker locker{&bigLock}; +void Settings::setDialogSettingsGeometry(const QByteArray& value) { + QMutexLocker locker{&bigLock}; - if (value != dialogSettingsGeometry) { - dialogSettingsGeometry = value; - emit dialogSettingsGeometryChanged(dialogSettingsGeometry); - } + if (value != dialogSettingsGeometry) { + dialogSettingsGeometry = value; + emit dialogSettingsGeometryChanged(dialogSettingsGeometry); + } } bool Settings::getTypingNotification() const { - QMutexLocker locker{&bigLock}; - return typingNotification; + QMutexLocker locker{&bigLock}; + return typingNotification; } void Settings::setTypingNotification(bool enabled) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (enabled != typingNotification) { - typingNotification = enabled; - emit typingNotificationChanged(typingNotification); - } + if (enabled != typingNotification) { + typingNotification = enabled; + emit typingNotificationChanged(typingNotification); + } } QStringList Settings::getBlackList() const { - QMutexLocker locker{&bigLock}; - return blackList; + QMutexLocker locker{&bigLock}; + return blackList; } -void Settings::setBlackList(const QStringList &blist) { - QMutexLocker locker{&bigLock}; +void Settings::setBlackList(const QStringList& blist) { + QMutexLocker locker{&bigLock}; - if (blist != blackList) { - blackList = blist; - emit blackListChanged(blackList); - } + if (blist != blackList) { + blackList = blist; + emit blackListChanged(blackList); + } } QString Settings::getInDev() const { - QMutexLocker locker{&bigLock}; - return inDev; + QMutexLocker locker{&bigLock}; + return inDev; } -void Settings::setInDev(const QString &deviceSpecifier) { - QMutexLocker locker{&bigLock}; +void Settings::setInDev(const QString& deviceSpecifier) { + QMutexLocker locker{&bigLock}; - if (deviceSpecifier != inDev) { - inDev = deviceSpecifier; - emit inDevChanged(inDev); - } + if (deviceSpecifier != inDev) { + inDev = deviceSpecifier; + emit inDevChanged(inDev); + } } bool Settings::getAudioInDevEnabled() const { - QMutexLocker locker(&bigLock); - return audioInDevEnabled; + QMutexLocker locker(&bigLock); + return audioInDevEnabled; } void Settings::setAudioInDevEnabled(bool enabled) { - QMutexLocker locker(&bigLock); + QMutexLocker locker(&bigLock); - if (enabled != audioInDevEnabled) { - audioInDevEnabled = enabled; - emit audioInDevEnabledChanged(enabled); - } + if (enabled != audioInDevEnabled) { + audioInDevEnabled = enabled; + emit audioInDevEnabledChanged(enabled); + } } qreal Settings::getAudioInGainDecibel() const { - QMutexLocker locker{&bigLock}; - return audioInGainDecibel; + QMutexLocker locker{&bigLock}; + return audioInGainDecibel; } void Settings::setAudioInGainDecibel(qreal dB) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (dB < audioInGainDecibel || dB > audioInGainDecibel) { - audioInGainDecibel = dB; - emit audioInGainDecibelChanged(audioInGainDecibel); - } + if (dB < audioInGainDecibel || dB > audioInGainDecibel) { + audioInGainDecibel = dB; + emit audioInGainDecibelChanged(audioInGainDecibel); + } } qreal Settings::getAudioThreshold() const { - QMutexLocker locker{&bigLock}; - return audioThreshold; + QMutexLocker locker{&bigLock}; + return audioThreshold; } void Settings::setAudioThreshold(qreal percent) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (percent < audioThreshold || percent > audioThreshold) { - audioThreshold = percent; - emit audioThresholdChanged(audioThreshold); - } + if (percent < audioThreshold || percent > audioThreshold) { + audioThreshold = percent; + emit audioThresholdChanged(audioThreshold); + } } QString Settings::getVideoDev() const { - QMutexLocker locker{&bigLock}; - return videoDev; + QMutexLocker locker{&bigLock}; + return videoDev; } -void Settings::setVideoDev(const QString &deviceSpecifier) { - QMutexLocker locker{&bigLock}; +void Settings::setVideoDev(const QString& deviceSpecifier) { + QMutexLocker locker{&bigLock}; - if (deviceSpecifier != videoDev) { - videoDev = deviceSpecifier; - emit videoDevChanged(videoDev); - } + if (deviceSpecifier != videoDev) { + videoDev = deviceSpecifier; + emit videoDevChanged(videoDev); + } } QString Settings::getOutDev() const { - QMutexLocker locker{&bigLock}; - return outDev; + QMutexLocker locker{&bigLock}; + return outDev; } -void Settings::setOutDev(const QString &deviceSpecifier) { - QMutexLocker locker{&bigLock}; +void Settings::setOutDev(const QString& deviceSpecifier) { + QMutexLocker locker{&bigLock}; - if (deviceSpecifier != outDev) { - outDev = deviceSpecifier; - emit outDevChanged(outDev); - } + if (deviceSpecifier != outDev) { + outDev = deviceSpecifier; + emit outDevChanged(outDev); + } } bool Settings::getAudioOutDevEnabled() const { - QMutexLocker locker(&bigLock); - return audioOutDevEnabled; + QMutexLocker locker(&bigLock); + return audioOutDevEnabled; } void Settings::setAudioOutDevEnabled(bool enabled) { - QMutexLocker locker(&bigLock); + QMutexLocker locker(&bigLock); - if (enabled != audioOutDevEnabled) { - audioOutDevEnabled = enabled; - emit audioOutDevEnabledChanged(audioOutDevEnabled); - } + if (enabled != audioOutDevEnabled) { + audioOutDevEnabled = enabled; + emit audioOutDevEnabledChanged(audioOutDevEnabled); + } } int Settings::getOutVolume() const { - QMutexLocker locker{&bigLock}; - return outVolume; + QMutexLocker locker{&bigLock}; + return outVolume; } void Settings::setOutVolume(int volume) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (volume != outVolume) { - outVolume = volume; - emit outVolumeChanged(outVolume); - } + if (volume != outVolume) { + outVolume = volume; + emit outVolumeChanged(outVolume); + } } int Settings::getAudioBitrate() const { - const QMutexLocker locker{&bigLock}; - return audioBitrate; + const QMutexLocker locker{&bigLock}; + return audioBitrate; } void Settings::setAudioBitrate(int bitrate) { - const QMutexLocker locker{&bigLock}; + const QMutexLocker locker{&bigLock}; - if (bitrate != audioBitrate) { - audioBitrate = bitrate; - emit audioBitrateChanged(audioBitrate); - } + if (bitrate != audioBitrate) { + audioBitrate = bitrate; + emit audioBitrateChanged(audioBitrate); + } } QRect Settings::getScreenRegion() const { - QMutexLocker locker(&bigLock); - return screenRegion; + QMutexLocker locker(&bigLock); + return screenRegion; } -void Settings::setScreenRegion(const QRect &value) { - QMutexLocker locker{&bigLock}; +void Settings::setScreenRegion(const QRect& value) { + QMutexLocker locker{&bigLock}; - if (value != screenRegion) { - screenRegion = value; - emit screenRegionChanged(screenRegion); - } + if (value != screenRegion) { + screenRegion = value; + emit screenRegionChanged(screenRegion); + } } bool Settings::getScreenGrabbed() const { - QMutexLocker locker(&bigLock); - return screenGrabbed; + QMutexLocker locker(&bigLock); + return screenGrabbed; } void Settings::setScreenGrabbed(bool value) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (value != screenGrabbed) { - screenGrabbed = value; - emit screenGrabbedChanged(screenGrabbed); - } + if (value != screenGrabbed) { + screenGrabbed = value; + emit screenGrabbedChanged(screenGrabbed); + } } QRect Settings::getCamVideoRes() const { - QMutexLocker locker{&bigLock}; - return camVideoRes; + QMutexLocker locker{&bigLock}; + return camVideoRes; } void Settings::setCamVideoRes(QRect newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != camVideoRes) { - camVideoRes = newValue; - emit camVideoResChanged(camVideoRes); - } + if (newValue != camVideoRes) { + camVideoRes = newValue; + emit camVideoResChanged(camVideoRes); + } } float Settings::getCamVideoFPS() const { - QMutexLocker locker{&bigLock}; - return camVideoFPS; + QMutexLocker locker{&bigLock}; + return camVideoFPS; } void Settings::setCamVideoFPS(float newValue) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (newValue != camVideoFPS) { - camVideoFPS = newValue; - emit camVideoFPSChanged(camVideoFPS); - } + if (newValue != camVideoFPS) { + camVideoFPS = newValue; + emit camVideoFPSChanged(camVideoFPS); + } } -QString Settings::getFriendAddress(const QString &publicKey) const { - QMutexLocker locker{&bigLock}; - // TODO: using ToxId here is a hack - QByteArray key = ToxId(publicKey).getPublicKey().getByteArray(); - auto it = friendLst.find(key); - if (it != friendLst.end()) - return it->addr; +QString Settings::getFriendAddress(const QString& publicKey) const { + QMutexLocker locker{&bigLock}; + // TODO: using ToxId here is a hack + QByteArray key = ToxId(publicKey).getPublicKey().getByteArray(); + auto it = friendLst.find(key); + if (it != friendLst.end()) return it->addr; - return QString(); + return QString(); } -void Settings::updateFriendAddress(const QString &newAddr) { - QMutexLocker locker{&bigLock}; - // TODO: using ToxId here is a hack - auto key = ToxId(newAddr).getPublicKey(); - auto &frnd = getOrInsertFriendPropRef(key); - frnd.addr = newAddr; +void Settings::updateFriendAddress(const QString& newAddr) { + QMutexLocker locker{&bigLock}; + // TODO: using ToxId here is a hack + auto key = ToxId(newAddr).getPublicKey(); + auto& frnd = getOrInsertFriendPropRef(key); + frnd.addr = newAddr; } -QString Settings::getFriendAlias(const ContactId &id) const { - QMutexLocker locker{&bigLock}; - if (friendLst.isEmpty()) - return {}; +QString Settings::getFriendAlias(const ContactId& id) const { + QMutexLocker locker{&bigLock}; + if (friendLst.isEmpty()) return {}; - auto it = friendLst.find(id.getByteArray()); - if (it != friendLst.end()) - return it->alias; + auto it = friendLst.find(id.getByteArray()); + if (it != friendLst.end()) return it->alias; - return {}; + return {}; } -void Settings::setFriendAlias(const FriendId &id, const QString &alias) { - QMutexLocker locker{&bigLock}; - auto &frnd = getOrInsertFriendPropRef(id); - frnd.alias = alias; +void Settings::setFriendAlias(const FriendId& id, const QString& alias) { + QMutexLocker locker{&bigLock}; + auto& frnd = getOrInsertFriendPropRef(id); + frnd.alias = alias; } -int Settings::getFriendCircleID(const FriendId &id) const { - QMutexLocker locker{&bigLock}; - auto it = friendLst.find(id.getByteArray()); - if (it != friendLst.end()) - return it->circleID; +int Settings::getFriendCircleID(const FriendId& id) const { + QMutexLocker locker{&bigLock}; + auto it = friendLst.find(id.getByteArray()); + if (it != friendLst.end()) return it->circleID; - return -1; + return -1; } -void Settings::setFriendCircleID(const FriendId &id, int circleID) { - QMutexLocker locker{&bigLock}; - auto &frnd = getOrInsertFriendPropRef(id); - frnd.circleID = circleID; +void Settings::setFriendCircleID(const FriendId& id, int circleID) { + QMutexLocker locker{&bigLock}; + auto& frnd = getOrInsertFriendPropRef(id); + frnd.circleID = circleID; } -QDateTime Settings::getFriendActivity(const FriendId &id) const { - QMutexLocker locker{&bigLock}; - auto it = friendLst.find(id.getByteArray()); - if (it != friendLst.end()) - return it->activity; +QDateTime Settings::getFriendActivity(const FriendId& id) const { + QMutexLocker locker{&bigLock}; + auto it = friendLst.find(id.getByteArray()); + if (it != friendLst.end()) return it->activity; - return QDateTime(); + return QDateTime(); } -void Settings::setFriendActivity(const FriendId &id, const QDateTime &activity) { - QMutexLocker locker{&bigLock}; - auto &frnd = getOrInsertFriendPropRef(id); - frnd.activity = activity; +void Settings::setFriendActivity(const FriendId& id, const QDateTime& activity) { + QMutexLocker locker{&bigLock}; + auto& frnd = getOrInsertFriendPropRef(id); + frnd.activity = activity; } -void Settings::saveFriendSettings(const FriendId &id) { - Q_UNUSED(id); - savePersonal(); +void Settings::saveFriendSettings(const FriendId& id) { + Q_UNUSED(id); + savePersonal(); } -void Settings::removeFriendSettings(const FriendId &id) { - QMutexLocker locker{&bigLock}; - friendLst.remove(id.getByteArray()); +void Settings::removeFriendSettings(const FriendId& id) { + QMutexLocker locker{&bigLock}; + friendLst.remove(id.getByteArray()); } bool Settings::getCompactLayout() const { - QMutexLocker locker{&bigLock}; - return compactLayout; + QMutexLocker locker{&bigLock}; + return compactLayout; } void Settings::setCompactLayout(bool value) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (value != compactLayout) { - compactLayout = value; - emit compactLayoutChanged(value); - } + if (value != compactLayout) { + compactLayout = value; + emit compactLayoutChanged(value); + } } Settings::FriendListSortingMode Settings::getFriendSortingMode() const { - QMutexLocker locker{&bigLock}; - return sortingMode; + QMutexLocker locker{&bigLock}; + return sortingMode; } void Settings::setFriendSortingMode(FriendListSortingMode mode) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (mode != sortingMode) { - sortingMode = mode; - emit sortingModeChanged(sortingMode); - } + if (mode != sortingMode) { + sortingMode = mode; + emit sortingModeChanged(sortingMode); + } } bool Settings::getSeparateWindow() const { - QMutexLocker locker{&bigLock}; - return separateWindow; + QMutexLocker locker{&bigLock}; + return separateWindow; } void Settings::setSeparateWindow(bool value) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (value != separateWindow) { - separateWindow = value; - emit separateWindowChanged(value); - } + if (value != separateWindow) { + separateWindow = value; + emit separateWindowChanged(value); + } } bool Settings::getDontGroupWindows() const { - QMutexLocker locker{&bigLock}; - return dontGroupWindows; + QMutexLocker locker{&bigLock}; + return dontGroupWindows; } void Settings::setDontGroupWindows(bool value) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (value != dontGroupWindows) { - dontGroupWindows = value; - emit dontGroupWindowsChanged(dontGroupWindows); - } + if (value != dontGroupWindows) { + dontGroupWindows = value; + emit dontGroupWindowsChanged(dontGroupWindows); + } } bool Settings::getGroupchatPosition() const { - QMutexLocker locker{&bigLock}; - return groupchatPosition; + QMutexLocker locker{&bigLock}; + return groupchatPosition; } void Settings::setGroupchatPosition(bool value) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (value != groupchatPosition) { - groupchatPosition = value; - emit groupchatPositionChanged(value); - } + if (value != groupchatPosition) { + groupchatPosition = value; + emit groupchatPositionChanged(value); + } } bool Settings::getShowIdenticons() const { - const QMutexLocker locker{&bigLock}; - return showIdenticons; + const QMutexLocker locker{&bigLock}; + return showIdenticons; } void Settings::setShowIdenticons(bool value) { - const QMutexLocker locker{&bigLock}; + const QMutexLocker locker{&bigLock}; - if (value != showIdenticons) { - showIdenticons = value; - emit showIdenticonsChanged(value); - } + if (value != showIdenticons) { + showIdenticons = value; + emit showIdenticonsChanged(value); + } } int Settings::getCircleCount() const { - QMutexLocker locker{&bigLock}; - return circleLst.size(); + QMutexLocker locker{&bigLock}; + return circleLst.size(); } QString Settings::getCircleName(int id) const { - QMutexLocker locker{&bigLock}; - return circleLst[id].name; + QMutexLocker locker{&bigLock}; + return circleLst[id].name; } -void Settings::setCircleName(int id, const QString &name) { - QMutexLocker locker{&bigLock}; - circleLst[id].name = name; - savePersonal(); +void Settings::setCircleName(int id, const QString& name) { + QMutexLocker locker{&bigLock}; + circleLst[id].name = name; + savePersonal(); } -int Settings::addCircle(const QString &name) { - QMutexLocker locker{&bigLock}; +int Settings::addCircle(const QString& name) { + QMutexLocker locker{&bigLock}; - circleProp cp; - cp.expanded = false; + circleProp cp; + cp.expanded = false; - if (name.isEmpty()) - cp.name = tr("Circle #%1").arg(circleLst.count() + 1); - else - cp.name = name; + if (name.isEmpty()) + cp.name = tr("Circle #%1").arg(circleLst.count() + 1); + else + cp.name = name; - circleLst.append(cp); - savePersonal(); - return circleLst.count() - 1; + circleLst.append(cp); + savePersonal(); + return circleLst.count() - 1; } bool Settings::getCircleExpanded(int id) const { - QMutexLocker locker{&bigLock}; - return circleLst[id].expanded; + QMutexLocker locker{&bigLock}; + return circleLst[id].expanded; } void Settings::setCircleExpanded(int id, bool expanded) { - QMutexLocker locker{&bigLock}; - circleLst[id].expanded = expanded; + QMutexLocker locker{&bigLock}; + circleLst[id].expanded = expanded; } -bool Settings::addFriendRequest(const QString &friendAddress, - const QString &message) { - QMutexLocker locker{&bigLock}; +bool Settings::addFriendRequest(const QString& friendAddress, const QString& message) { + QMutexLocker locker{&bigLock}; - for (auto queued : friendRequests) { - if (queued.address == friendAddress) { - queued.message = message; - queued.read = false; - return false; + for (auto queued : friendRequests) { + if (queued.address == friendAddress) { + queued.message = message; + queued.read = false; + return false; + } } - } - Request request; - request.address = friendAddress; - request.message = message; - request.read = false; - friendRequests.push_back(request); - return true; + Request request; + request.address = friendAddress; + request.message = message; + request.read = false; + friendRequests.push_back(request); + return true; } unsigned int Settings::getUnreadFriendRequests() const { - QMutexLocker locker{&bigLock}; - unsigned int unreadFriendRequests = 0; - for (auto request : friendRequests) - if (!request.read) - ++unreadFriendRequests; + QMutexLocker locker{&bigLock}; + unsigned int unreadFriendRequests = 0; + for (auto request : friendRequests) + if (!request.read) ++unreadFriendRequests; - return unreadFriendRequests; + return unreadFriendRequests; } Settings::Request Settings::getFriendRequest(int index) const { - QMutexLocker locker{&bigLock}; - return friendRequests.at(index); + QMutexLocker locker{&bigLock}; + return friendRequests.at(index); } int Settings::getFriendRequestSize() const { - QMutexLocker locker{&bigLock}; - return friendRequests.size(); + QMutexLocker locker{&bigLock}; + return friendRequests.size(); } void Settings::clearUnreadFriendRequests() { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - for (auto &request : friendRequests) - request.read = true; + for (auto& request : friendRequests) request.read = true; } void Settings::removeFriendRequest(int index) { - QMutexLocker locker{&bigLock}; - friendRequests.removeAt(index); + QMutexLocker locker{&bigLock}; + friendRequests.removeAt(index); } void Settings::readFriendRequest(int index) { - QMutexLocker locker{&bigLock}; - friendRequests[index].read = true; + QMutexLocker locker{&bigLock}; + friendRequests[index].read = true; } int Settings::removeCircle(int id) { - // Replace index with last one and remove last one instead. - // This gives you contiguous ids all the time. - circleLst[id] = circleLst.last(); - circleLst.pop_back(); - savePersonal(); - return circleLst.count(); + // Replace index with last one and remove last one instead. + // This gives you contiguous ids all the time. + circleLst[id] = circleLst.last(); + circleLst.pop_back(); + savePersonal(); + return circleLst.count(); } int Settings::getThemeColor() const { - QMutexLocker locker{&bigLock}; - return themeColor; + QMutexLocker locker{&bigLock}; + return themeColor; } void Settings::setThemeColor(int value) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (value != themeColor) { - themeColor = value; - emit themeColorChanged(themeColor); - } + if (value != themeColor) { + themeColor = value; + emit themeColorChanged(themeColor); + } } bool Settings::getAutoLogin() const { - QMutexLocker locker{&bigLock}; - return autoLogin; + QMutexLocker locker{&bigLock}; + return autoLogin; } void Settings::setAutoLogin(bool state) { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - if (state != autoLogin) { - autoLogin = state; - emit autoLoginChanged(autoLogin); - } + if (state != autoLogin) { + autoLogin = state; + emit autoLoginChanged(autoLogin); + } } void Settings::setEnableGroupChatsColor(bool state) { - QMutexLocker locker{&bigLock}; - if (state != nameColors) { - nameColors = state; - emit nameColorsChanged(nameColors); - } + QMutexLocker locker{&bigLock}; + if (state != nameColors) { + nameColors = state; + emit nameColorsChanged(nameColors); + } } bool Settings::getEnableGroupChatsColor() const { return nameColors; } @@ -2122,50 +2064,48 @@ bool Settings::getEnableGroupChatsColor() const { return nameColors; } * @brief Creates a path to the settings dir, if it doesn't already exist */ void Settings::createSettingsDir() { - QMutexLocker locker{&bigLock}; + QMutexLocker locker{&bigLock}; - QString dir = Settings::getSettingsDirPath(); - QDir directory(dir); - if (!directory.exists() && !directory.mkpath(directory.absolutePath())) - qCritical() << "Error while creating directory " << dir; + QString dir = Settings::getSettingsDirPath(); + QDir directory(dir); + if (!directory.exists() && !directory.mkpath(directory.absolutePath())) + qCritical() << "Error while creating directory " << dir; } /** * @brief Waits for all asynchronous operations to complete */ void Settings::sync() { - if (QThread::currentThread() != settingsThread) { - QMetaObject::invokeMethod(&getInstance(), "sync", - Qt::BlockingQueuedConnection); - return; - } - - QMutexLocker locker{&bigLock}; - qApp->processEvents(); -} - -Settings::friendProp &Settings::getOrInsertFriendPropRef(const FriendId &id) { - // No mutex lock, this is a private fn that should only be called by other - // public functions that already locked the mutex - auto it = friendLst.find(id.getByteArray()); - if (it == friendLst.end()) { - it = friendLst.insert(id.getByteArray(), friendProp{id.toString()}); - } - - return *it; -} - -ICoreSettings::ProxyType -Settings::fixInvalidProxyType(ICoreSettings::ProxyType proxyType) { - // Repair uninitialized enum that was saved to settings due to bug - // (https://github.com/qTox/qTox/issues/5311) - switch (proxyType) { - case ICoreSettings::ProxyType::ptNone: - case ICoreSettings::ProxyType::ptSOCKS5: - case ICoreSettings::ProxyType::ptHTTP: - return proxyType; - default: - qWarning() << "Repairing invalid ProxyType, UDP will be enabled"; - return ICoreSettings::ProxyType::ptNone; - } + if (QThread::currentThread() != settingsThread) { + QMetaObject::invokeMethod(&getInstance(), "sync", Qt::BlockingQueuedConnection); + return; + } + + QMutexLocker locker{&bigLock}; + qApp->processEvents(); +} + +Settings::friendProp& Settings::getOrInsertFriendPropRef(const FriendId& id) { + // No mutex lock, this is a private fn that should only be called by other + // public functions that already locked the mutex + auto it = friendLst.find(id.getByteArray()); + if (it == friendLst.end()) { + it = friendLst.insert(id.getByteArray(), friendProp{id.toString()}); + } + + return *it; +} + +ICoreSettings::ProxyType Settings::fixInvalidProxyType(ICoreSettings::ProxyType proxyType) { + // Repair uninitialized enum that was saved to settings due to bug + // (https://github.com/qTox/qTox/issues/5311) + switch (proxyType) { + case ICoreSettings::ProxyType::ptNone: + case ICoreSettings::ProxyType::ptSOCKS5: + case ICoreSettings::ProxyType::ptHTTP: + return proxyType; + default: + qWarning() << "Repairing invalid ProxyType, UDP will be enabled"; + return ICoreSettings::ProxyType::ptNone; + } } diff --git a/src/modules/im/src/persistence/settings.h b/src/modules/im/src/persistence/settings.h index 39a55a11..14488258 100644 --- a/src/modules/im/src/persistence/settings.h +++ b/src/modules/im/src/persistence/settings.h @@ -35,7 +35,6 @@ #include - class Profile; class QCommandLineParser; @@ -48,90 +47,93 @@ class Settings : public QObject, public IFriendSettings, public IGroupSettings, public IAudioSettings, - public IVideoSettings -{ + public IVideoSettings { Q_OBJECT Q_ENUMS(StyleType) - // general - Q_PROPERTY(bool compactLayout READ getCompactLayout WRITE setCompactLayout NOTIFY compactLayoutChanged FINAL) + Q_PROPERTY(bool compactLayout READ getCompactLayout WRITE setCompactLayout NOTIFY + compactLayoutChanged FINAL) // GUI Q_PROPERTY(bool separateWindow READ getSeparateWindow WRITE setSeparateWindow NOTIFY - separateWindowChanged FINAL) - Q_PROPERTY(QString smileyPack READ getSmileyPack WRITE setSmileyPack NOTIFY smileyPackChanged FINAL) + separateWindowChanged FINAL) + Q_PROPERTY(QString smileyPack READ getSmileyPack WRITE setSmileyPack NOTIFY smileyPackChanged + FINAL) Q_PROPERTY(int emojiFontPointSize READ getEmojiFontPointSize WRITE setEmojiFontPointSize NOTIFY - emojiFontPointSizeChanged FINAL) + emojiFontPointSizeChanged FINAL) Q_PROPERTY(QByteArray windowGeometry READ getWindowGeometry WRITE setWindowGeometry NOTIFY - windowGeometryChanged FINAL) - Q_PROPERTY(QByteArray windowState READ getWindowState WRITE setWindowState NOTIFY windowStateChanged FINAL) + windowGeometryChanged FINAL) + Q_PROPERTY(QByteArray windowState READ getWindowState WRITE setWindowState NOTIFY + windowStateChanged FINAL) Q_PROPERTY(QByteArray splitterState READ getSplitterState WRITE setSplitterState NOTIFY - splitterStateChanged FINAL) + splitterStateChanged FINAL) Q_PROPERTY(QByteArray dialogGeometry READ getDialogGeometry WRITE setDialogGeometry NOTIFY - dialogGeometryChanged FINAL) + dialogGeometryChanged FINAL) Q_PROPERTY(QByteArray dialogSplitterState READ getDialogSplitterState WRITE - setDialogSplitterState NOTIFY dialogSplitterStateChanged FINAL) + setDialogSplitterState NOTIFY dialogSplitterStateChanged FINAL) Q_PROPERTY(QByteArray dialogSettingsGeometry READ getDialogSettingsGeometry WRITE - setDialogSettingsGeometry NOTIFY dialogSettingsGeometryChanged FINAL) + setDialogSettingsGeometry NOTIFY dialogSettingsGeometryChanged FINAL) Q_PROPERTY(QString style READ getStyle WRITE setStyle NOTIFY styleChanged FINAL) Q_PROPERTY(bool showIdenticons READ getShowIdenticons WRITE setShowIdenticons NOTIFY - showIdenticonsChanged FINAL) + showIdenticonsChanged FINAL) // ChatView Q_PROPERTY(bool groupchatPosition READ getGroupchatPosition WRITE setGroupchatPosition NOTIFY - groupchatPositionChanged FINAL) + groupchatPositionChanged FINAL) Q_PROPERTY(QFont chatMessageFont READ getChatMessageFont WRITE setChatMessageFont NOTIFY - chatMessageFontChanged FINAL) + chatMessageFontChanged FINAL) Q_PROPERTY(StyleType stylePreference READ getStylePreference WRITE setStylePreference NOTIFY - stylePreferenceChanged FINAL) + stylePreferenceChanged FINAL) Q_PROPERTY(QString timestampFormat READ getTimestampFormat WRITE setTimestampFormat NOTIFY - timestampFormatChanged FINAL) - Q_PROPERTY(QString dateFormat READ getDateFormat WRITE setDateFormat NOTIFY dateFormatChanged FINAL) + timestampFormatChanged FINAL) + Q_PROPERTY(QString dateFormat READ getDateFormat WRITE setDateFormat NOTIFY dateFormatChanged + FINAL) Q_PROPERTY(bool statusChangeNotificationEnabled READ getStatusChangeNotificationEnabled WRITE - setStatusChangeNotificationEnabled NOTIFY statusChangeNotificationEnabledChanged FINAL) + setStatusChangeNotificationEnabled NOTIFY + statusChangeNotificationEnabledChanged FINAL) Q_PROPERTY(bool spellCheckingEnabled READ getSpellCheckingEnabled WRITE setSpellCheckingEnabled - NOTIFY spellCheckingEnabledChanged FINAL) + NOTIFY spellCheckingEnabledChanged FINAL) // Privacy Q_PROPERTY(bool typingNotification READ getTypingNotification WRITE setTypingNotification NOTIFY - typingNotificationChanged FINAL) - Q_PROPERTY(QStringList blackList READ getBlackList WRITE setBlackList NOTIFY blackListChanged FINAL) + typingNotificationChanged FINAL) + Q_PROPERTY(QStringList blackList READ getBlackList WRITE setBlackList NOTIFY blackListChanged + FINAL) // Audio Q_PROPERTY(QString inDev READ getInDev WRITE setInDev NOTIFY inDevChanged FINAL) Q_PROPERTY(bool audioInDevEnabled READ getAudioInDevEnabled WRITE setAudioInDevEnabled NOTIFY - audioInDevEnabledChanged FINAL) + audioInDevEnabledChanged FINAL) Q_PROPERTY(qreal audioInGainDecibel READ getAudioInGainDecibel WRITE setAudioInGainDecibel - NOTIFY audioInGainDecibelChanged FINAL) + NOTIFY audioInGainDecibelChanged FINAL) Q_PROPERTY(qreal audioThreshold READ getAudioThreshold WRITE setAudioThreshold NOTIFY - audioThresholdChanged FINAL) + audioThresholdChanged FINAL) Q_PROPERTY(QString outDev READ getOutDev WRITE setOutDev NOTIFY outDevChanged FINAL) Q_PROPERTY(bool audioOutDevEnabled READ getAudioOutDevEnabled WRITE setAudioOutDevEnabled NOTIFY - audioOutDevEnabledChanged FINAL) + audioOutDevEnabledChanged FINAL) Q_PROPERTY(int outVolume READ getOutVolume WRITE setOutVolume NOTIFY outVolumeChanged FINAL) - Q_PROPERTY(int audioBitrate READ getAudioBitrate WRITE setAudioBitrate NOTIFY audioBitrateChanged FINAL) + Q_PROPERTY(int audioBitrate READ getAudioBitrate WRITE setAudioBitrate NOTIFY + audioBitrateChanged FINAL) // Video Q_PROPERTY(QString videoDev READ getVideoDev WRITE setVideoDev NOTIFY videoDevChanged FINAL) - Q_PROPERTY(QRect camVideoRes READ getCamVideoRes WRITE setCamVideoRes NOTIFY camVideoResChanged FINAL) - Q_PROPERTY(QRect screenRegion READ getScreenRegion WRITE setScreenRegion NOTIFY screenRegionChanged FINAL) - Q_PROPERTY(bool screenGrabbed READ getScreenGrabbed WRITE setScreenGrabbed NOTIFY screenGrabbedChanged FINAL) - Q_PROPERTY(float camVideoFPS READ getCamVideoFPS WRITE setCamVideoFPS NOTIFY camVideoFPSChanged FINAL) + Q_PROPERTY(QRect camVideoRes READ getCamVideoRes WRITE setCamVideoRes NOTIFY camVideoResChanged + FINAL) + Q_PROPERTY(QRect screenRegion READ getScreenRegion WRITE setScreenRegion NOTIFY + screenRegionChanged FINAL) + Q_PROPERTY(bool screenGrabbed READ getScreenGrabbed WRITE setScreenGrabbed NOTIFY + screenGrabbedChanged FINAL) + Q_PROPERTY(float camVideoFPS READ getCamVideoFPS WRITE setCamVideoFPS NOTIFY camVideoFPSChanged + FINAL) public: - enum class StyleType - { - NONE = 0, - WITH_CHARS = 1, - WITHOUT_CHARS = 2 - }; + enum class StyleType { NONE = 0, WITH_CHARS = 1, WITHOUT_CHARS = 2 }; - enum class FriendListSortingMode - { + enum class FriendListSortingMode { Name, Activity, }; @@ -153,10 +155,9 @@ class Settings : public QObject, void resetToDefault(); -// QStringList getLocales(); + // QStringList getLocales(); - struct Request - { + struct Request { QString address; QString message; bool read; @@ -181,7 +182,6 @@ public slots: void notifyHideChanged(bool enabled); void groupAlwaysNotifyChanged(bool enabled); - void enableLoggingChanged(bool enabled); void autoAwayTimeChanged(int minutes); void globalAutoAcceptDirChanged(const QString& path); @@ -229,7 +229,6 @@ public slots: bool getMakeToxPortable() const; void setMakeToxPortable(bool newValue); - bool getLightTrayIcon() const; void setLightTrayIcon(bool newValue); @@ -239,7 +238,6 @@ public slots: bool getUseEmoticons() const; void setUseEmoticons(bool newValue); - QString getTranslation() const; void setTranslation(const QString& newValue); @@ -323,14 +321,8 @@ public slots: void setAudioThreshold(qreal percent) override; int getOutVolume() const override; - int getOutVolumeMin() const override - { - return 0; - } - int getOutVolumeMax() const override - { - return 100; - } + int getOutVolumeMin() const override { return 0; } + int getOutVolumeMax() const override { return 100; } void setOutVolume(int volume) override; int getAudioBitrate() const override; @@ -418,7 +410,6 @@ public slots: const QString& getDateFormat() const; void setDateFormat(const QString& format); - bool getStatusChangeNotificationEnabled() const; void setStatusChangeNotificationEnabled(bool newValue); @@ -520,20 +511,15 @@ public slots: // Wrappers around getWidgetData() and setWidgetData() // Assume widget has a unique objectName set - template - void restoreGeometryState(T* widget) const - { + template void restoreGeometryState(T* widget) const { widget->restoreGeometry(getWidgetData(widget->objectName() + "Geometry")); widget->restoreState(getWidgetData(widget->objectName() + "State")); } - template - void saveGeometryState(const T* widget) - { + template void saveGeometryState(const T* widget) { setWidgetData(widget->objectName() + "Geometry", widget->saveGeometry()); setWidgetData(widget->objectName() + "State", widget->saveState()); } - private: struct friendProp; @@ -563,7 +549,7 @@ public slots: bool dontGroupWindows; bool showIdenticons; bool enableIPv6; -// QString translation; + // QString translation; bool makeToxPortable; bool lightTrayIcon; @@ -585,8 +571,6 @@ public slots: QString proxyAddr; quint16 proxyPort; - - bool enableLogging; int autoAwayTime; @@ -643,12 +627,9 @@ public slots: bool screenGrabbed; float camVideoFPS; - struct friendProp - { + struct friendProp { friendProp() = delete; - friendProp(QString addr) - : addr(addr) - {} + friendProp(QString addr) : addr(addr) {} QString alias = ""; QString addr = ""; QString autoAcceptDir = ""; @@ -659,8 +640,7 @@ public slots: bool autoGroupInvite = false; }; - struct circleProp - { + struct circleProp { QString name; bool expanded; }; @@ -676,4 +656,4 @@ public slots: static QThread* settingsThread; }; -#endif // SETTINGS_HPP +#endif // SETTINGS_HPP diff --git a/src/modules/im/src/persistence/settingsserializer.cpp b/src/modules/im/src/persistence/settingsserializer.cpp index 9bcacb77..fa5690c3 100644 --- a/src/modules/im/src/persistence/settingsserializer.cpp +++ b/src/modules/im/src/persistence/settingsserializer.cpp @@ -13,13 +13,13 @@ #include "settingsserializer.h" #include "serialize.h" -#include "src/core/toxencrypt.h" -#include "src/persistence/profile.h" #include #include #include #include #include +#include "src/core/toxencrypt.h" +#include "src/persistence/profile.h" /** * @class SettingsSerializer @@ -42,8 +42,7 @@ * @var ArrayEnd * Not followed by any data */ -enum class RecordTag : uint8_t -{ +enum class RecordTag : uint8_t { }; /** @@ -52,32 +51,26 @@ enum class RecordTag : uint8_t */ const char SettingsSerializer::magic[] = {0x51, 0x54, 0x4F, 0x58}; -QDataStream& writeStream(QDataStream& dataStream, const SettingsSerializer::RecordTag& tag) -{ +QDataStream& writeStream(QDataStream& dataStream, const SettingsSerializer::RecordTag& tag) { return dataStream << static_cast(tag); } -QDataStream& writeStream(QDataStream& dataStream, const QByteArray& data) -{ +QDataStream& writeStream(QDataStream& dataStream, const QByteArray& data) { QByteArray size = vintToData(data.size()); dataStream.writeRawData(size.data(), size.size()); dataStream.writeRawData(data.data(), data.size()); return dataStream; } -QDataStream& writeStream(QDataStream& dataStream, const QString& str) -{ +QDataStream& writeStream(QDataStream& dataStream, const QString& str) { return writeStream(dataStream, str.toUtf8()); } -QDataStream& readStream(QDataStream& dataStream, SettingsSerializer::RecordTag& tag) -{ +QDataStream& readStream(QDataStream& dataStream, SettingsSerializer::RecordTag& tag) { return dataStream >> reinterpret_cast(tag); } - -QDataStream& readStream(QDataStream& dataStream, QByteArray& data) -{ +QDataStream& readStream(QDataStream& dataStream, QByteArray& data) { char num3; int num = 0; int num2 = 0; @@ -92,18 +85,10 @@ QDataStream& readStream(QDataStream& dataStream, QByteArray& data) } SettingsSerializer::SettingsSerializer(QString filePath, const ToxEncrypt* passKey) - : path{filePath} - , passKey{passKey} - , group{-1} - , array{-1} - , arrayIndex{-1} -{ -} + : path{filePath}, passKey{passKey}, group{-1}, array{-1}, arrayIndex{-1} {} -void SettingsSerializer::beginGroup(const QString& prefix) -{ - if (prefix.isEmpty()) - endGroup(); +void SettingsSerializer::beginGroup(const QString& prefix) { + if (prefix.isEmpty()) endGroup(); int index = groups.indexOf(prefix); if (index >= 0) { group = index; @@ -113,13 +98,9 @@ void SettingsSerializer::beginGroup(const QString& prefix) } } -void SettingsSerializer::endGroup() -{ - group = -1; -} +void SettingsSerializer::endGroup() { group = -1; } -int SettingsSerializer::beginReadArray(const QString& prefix) -{ +int SettingsSerializer::beginReadArray(const QString& prefix) { auto index = std::find_if(std::begin(arrays), std::end(arrays), [&](const Array& a) { return a.name == prefix; }); @@ -135,50 +116,38 @@ int SettingsSerializer::beginReadArray(const QString& prefix) } } -void SettingsSerializer::beginWriteArray(const QString& prefix, int size) -{ +void SettingsSerializer::beginWriteArray(const QString& prefix, int size) { auto index = std::find_if(std::begin(arrays), std::end(arrays), [&](const Array& a) { return a.name == prefix; }); if (index != std::end(arrays)) { array = static_cast(index - std::begin(arrays)); arrayIndex = -1; - if (size > 0) - index->size = std::max(index->size, size); + if (size > 0) index->size = std::max(index->size, size); } else { - if (size < 0) - size = 0; + if (size < 0) size = 0; array = arrays.size(); arrays.push_back({group, size, prefix, {}}); arrayIndex = -1; } } -void SettingsSerializer::endArray() -{ - array = -1; -} +void SettingsSerializer::endArray() { array = -1; } -void SettingsSerializer::setArrayIndex(int i) -{ - arrayIndex = i; -} +void SettingsSerializer::setArrayIndex(int i) { arrayIndex = i; } -void SettingsSerializer::setValue(const QString& key, const QVariant& value) -{ +void SettingsSerializer::setValue(const QString& key, const QVariant& value) { Value* v = findValue(key); if (v) { v->value = value; } else { Value nv{group, array, arrayIndex, key, value}; - if (array >= 0) - arrays[array].values.append(values.size()); + if (array >= 0) arrays[array].values.append(values.size()); values.append(nv); } } -QVariant SettingsSerializer::value(const QString& key, const QVariant& defaultValue) const -{ +QVariant SettingsSerializer::value(const QString& key, const QVariant& defaultValue) const { const Value* v = findValue(key); if (v) return v->value; @@ -186,29 +155,24 @@ QVariant SettingsSerializer::value(const QString& key, const QVariant& defaultVa return defaultValue; } -const SettingsSerializer::Value* SettingsSerializer::findValue(const QString& key) const -{ +const SettingsSerializer::Value* SettingsSerializer::findValue(const QString& key) const { if (array != -1) { for (const Array& a : arrays) { - if (a.group != group) - continue; + if (a.group != group) continue; for (int vi : a.values) { const Value& v = values[vi]; - if (v.arrayIndex == arrayIndex && v.key == key) - return &v; + if (v.arrayIndex == arrayIndex && v.key == key) return &v; } } } else { for (const Value& v : values) - if (v.group == group && v.array == -1 && v.key == key) - return &v; + if (v.group == group && v.array == -1 && v.key == key) return &v; } return nullptr; } -SettingsSerializer::Value* SettingsSerializer::findValue(const QString& key) -{ +SettingsSerializer::Value* SettingsSerializer::findValue(const QString& key) { return const_cast(const_cast(this)->findValue(key)); } @@ -217,22 +181,19 @@ SettingsSerializer::Value* SettingsSerializer::findValue(const QString& key) * @param filePath Path to file to check. * @return False on error, true otherwise. */ -bool SettingsSerializer::isSerializedFormat(QString filePath) -{ +bool SettingsSerializer::isSerializedFormat(QString filePath) { QFile f(filePath); - if (!f.open(QIODevice::ReadOnly)) - return false; + if (!f.open(QIODevice::ReadOnly)) return false; char fmagic[8]; - if (f.read(fmagic, sizeof(fmagic)) != sizeof(fmagic)) - return false; - return !memcmp(fmagic, magic, 4)/* || tox_is_data_encrypted(reinterpret_cast(fmagic))*/; + if (f.read(fmagic, sizeof(fmagic)) != sizeof(fmagic)) return false; + return !memcmp(fmagic, magic, + 4) /* || tox_is_data_encrypted(reinterpret_cast(fmagic))*/; } /** * @brief Loads the settings from file. */ -void SettingsSerializer::load() -{ +void SettingsSerializer::load() { if (isSerializedFormat(path)) readSerialized(); else @@ -242,8 +203,7 @@ void SettingsSerializer::load() /** * @brief Saves the current settings back to file */ -void SettingsSerializer::save() -{ +void SettingsSerializer::save() { QSaveFile f(path); if (!f.open(QIODevice::Truncate | QIODevice::WriteOnly)) { qWarning() << "Couldn't open file"; @@ -265,10 +225,8 @@ void SettingsSerializer::save() // Save all the arrays of this group for (const Array& a : arrays) { - if (a.group != g) - continue; - if (a.size <= 0) - continue; + if (a.group != g) continue; + if (a.size <= 0) continue; writeStream(stream, RecordTag::ArrayStart); writeStream(stream, a.name.toUtf8()); writeStream(stream, vintToData(a.size)); @@ -285,8 +243,7 @@ void SettingsSerializer::save() // Save all the values of this group that aren't in an array for (const Value& v : values) { - if (v.group != g || v.array != -1) - continue; + if (v.group != g || v.array != -1) continue; writeStream(stream, RecordTag::Value); writeStream(stream, v.key.toUtf8()); writePackedVariant(stream, v.value); @@ -309,8 +266,7 @@ void SettingsSerializer::save() } } -void SettingsSerializer::readSerialized() -{ +void SettingsSerializer::readSerialized() { QFile f(path); if (!f.open(QIODevice::ReadOnly)) { qWarning() << "Couldn't open file"; @@ -332,8 +288,7 @@ void SettingsSerializer::readSerialized() return; } } else { - if (passKey) - qWarning() << "We have a password, but the settings file is not encrypted"; + if (passKey) qWarning() << "We have a password, but the settings file is not encrypted"; } if (memcmp(data.data(), magic, 4)) { @@ -391,16 +346,14 @@ void SettingsSerializer::readSerialized() group = array = -1; } -void SettingsSerializer::readIni() -{ +void SettingsSerializer::readIni() { QSettings s(path, QSettings::IniFormat); // Read all keys of all groups, reading arrays as raw keys QList gstack; do { // Add all keys - if (!s.group().isEmpty()) - beginGroup(s.group()); + if (!s.group().isEmpty()) beginGroup(s.group()); for (QString k : s.childKeys()) { setValue(k, s.value(k)); @@ -408,8 +361,7 @@ void SettingsSerializer::readIni() // Add all groups gstack.push_back(QString()); - for (QString g : s.childGroups()) - gstack.push_back(g); + for (QString g : s.childGroups()) gstack.push_back(g); // Visit the next group, if any while (!gstack.isEmpty()) { @@ -434,8 +386,7 @@ void SettingsSerializer::readIni() std::unique_ptr groupSizes{new int[groups.size()]}; memset(groupSizes.get(), 0, static_cast(groups.size()) * sizeof(int)); for (const Value& v : values) { - if (v.group < 0 || v.group > groups.size()) - continue; + if (v.group < 0 || v.group > groups.size()) continue; groupSizes[static_cast(v.group)]++; } @@ -443,14 +394,10 @@ void SettingsSerializer::readIni() QVector groupsToKill; for (int i = values.size() - 1; i >= 0; i--) { const Value& v = values[i]; - if (v.group < 0 || v.group > groups.size()) - continue; - if (groupSizes[static_cast(v.group)] != 1) - continue; - if (v.key != "size") - continue; - if (!v.value.canConvert(QVariant::Int)) - continue; + if (v.group < 0 || v.group > groups.size()) continue; + if (groupSizes[static_cast(v.group)] != 1) continue; + if (v.key != "size") continue; + if (!v.value.canConvert(QVariant::Int)) continue; Array a; a.size = v.value.toInt(); @@ -462,8 +409,7 @@ void SettingsSerializer::readIni() } else { a.group = -1; for (int i = 0; i < groups.size(); ++i) - if (groups[i] == groups[static_cast(v.group)].left(slashIndex)) - a.group = i; + if (groups[i] == groups[static_cast(v.group)].left(slashIndex)) a.group = i; a.name = groups[static_cast(v.group)].mid(slashIndex + 1); } groupSizes[static_cast(v.group)]--; @@ -476,28 +422,23 @@ void SettingsSerializer::readIni() for (int ai = 0; ai < arrays.size(); ++ai) { Array& a = arrays[ai]; QString arrayPrefix; - if (a.group != -1) - arrayPrefix += groups[static_cast(a.group)] + '/'; + if (a.group != -1) arrayPrefix += groups[static_cast(a.group)] + '/'; arrayPrefix += a.name + '/'; // Find groups which represent each array index for (int g = 0; g < groups.size(); ++g) { - if (!groups[g].startsWith(arrayPrefix)) - continue; + if (!groups[g].startsWith(arrayPrefix)) continue; bool ok; int groupArrayIndex = groups[g].mid(arrayPrefix.size()).toInt(&ok); - if (!ok) - continue; + if (!ok) continue; groupsToKill.append(g); - if (groupArrayIndex > a.size) - a.size = groupArrayIndex; + if (groupArrayIndex > a.size) a.size = groupArrayIndex; // Associate the values for this array index for (int vi = values.size() - 1; vi >= 0; vi--) { Value& v = values[vi]; - if (v.group != g) - continue; + if (v.group != g) continue; groupSizes[static_cast(g)]--; v.group = a.group; v.array = ai; @@ -511,8 +452,7 @@ void SettingsSerializer::readIni() std::sort(std::begin(groupsToKill), std::end(groupsToKill), std::greater_equal()); for (int g : groupsToKill) { - if (groupSizes[static_cast(g)]) - continue; + if (groupSizes[static_cast(g)]) continue; removeGroup(g); } @@ -525,24 +465,20 @@ void SettingsSerializer::readIni() * @note The group must be empty. * @param group ID of group to remove. */ -void SettingsSerializer::removeGroup(int group) -{ +void SettingsSerializer::removeGroup(int group) { assert(group < groups.size()); for (Array& a : arrays) { assert(a.group != group); - if (a.group > group) - a.group--; + if (a.group > group) a.group--; } for (Value& v : values) { assert(v.group != group); - if (v.group > group) - v.group--; + if (v.group > group) v.group--; } groups.removeAt(group); } -void SettingsSerializer::writePackedVariant(QDataStream& stream, const QVariant& v) -{ +void SettingsSerializer::writePackedVariant(QDataStream& stream, const QVariant& v) { assert(v.canConvert(QVariant::String)); QString str = v.toString(); if (str == "true") diff --git a/src/modules/im/src/persistence/settingsserializer.h b/src/modules/im/src/persistence/settingsserializer.h index 613934fc..c027a5e7 100644 --- a/src/modules/im/src/persistence/settingsserializer.h +++ b/src/modules/im/src/persistence/settingsserializer.h @@ -20,8 +20,7 @@ #include #include -class SettingsSerializer -{ +class SettingsSerializer { public: SettingsSerializer(QString filePath, const ToxEncrypt* passKey = nullptr); @@ -42,35 +41,21 @@ class SettingsSerializer QVariant value(const QString& key, const QVariant& defaultValue = QVariant()) const; private: - enum class RecordTag : uint8_t - { + enum class RecordTag : uint8_t { Value = 0, GroupStart = 1, ArrayStart = 2, ArrayValue = 3, ArrayEnd = 4, }; - friend QDataStream& writeStream(QDataStream& dataStream, const SettingsSerializer::RecordTag& tag); + friend QDataStream& writeStream(QDataStream& dataStream, + const SettingsSerializer::RecordTag& tag); friend QDataStream& readStream(QDataStream& dataStream, SettingsSerializer::RecordTag& tag); - struct Value - { - Value() - : group{-2} - , array{-2} - , arrayIndex{-2} - , key{QString()} - , value{} - { - } + struct Value { + Value() : group{-2}, array{-2}, arrayIndex{-2}, key{QString()}, value{} {} Value(qint64 group, qint64 array, int arrayIndex, QString key, QVariant value) - : group{group} - , array{array} - , arrayIndex{arrayIndex} - , key{key} - , value{value} - { - } + : group{group}, array{array}, arrayIndex{arrayIndex}, key{key}, value{value} {} qint64 group; qint64 array; int arrayIndex; @@ -78,8 +63,7 @@ class SettingsSerializer QVariant value; }; - struct Array - { + struct Array { qint64 group; int size; QString name; @@ -105,4 +89,4 @@ class SettingsSerializer static const char magic[]; }; -#endif // SETTINGSSERIALIZER_H +#endif // SETTINGSSERIALIZER_H diff --git a/src/modules/im/src/persistence/smileypack.cpp b/src/modules/im/src/persistence/smileypack.cpp index 111e9359..24e48d2e 100644 --- a/src/modules/im/src/persistence/smileypack.cpp +++ b/src/modules/im/src/persistence/smileypack.cpp @@ -18,8 +18,8 @@ #include #include #include -#include #include +#include #if defined(Q_OS_FREEBSD) #include @@ -53,15 +53,14 @@ static const QString RICH_TEXT_PATTERN = QStringLiteral("start(CLEANUP_TIMEOUT); } -SmileyPack::~SmileyPack() -{ - if(cleanupTimer->isActive()){ - cleanupTimer->stop(); - } - cleanupTimer->deleteLater(); +SmileyPack::~SmileyPack() { + if (cleanupTimer->isActive()) { + cleanupTimer->stop(); + } + cleanupTimer->deleteLater(); } -void SmileyPack::cleanupIconsCache() -{ +void SmileyPack::cleanupIconsCache() { QMutexLocker locker(&loadingMutex); for (auto it = cachedIcon.begin(); it != cachedIcon.end();) { std::shared_ptr& icon = it->second; @@ -131,8 +125,7 @@ void SmileyPack::cleanupIconsCache() /** * @brief Returns the singleton instance. */ -SmileyPack& SmileyPack::getInstance() -{ +SmileyPack& SmileyPack::getInstance() { static SmileyPack smileyPack; return smileyPack; } @@ -140,8 +133,7 @@ SmileyPack& SmileyPack::getInstance() /** * @brief Does the same as listSmileyPaths, but with default paths */ -QList> SmileyPack::listSmileyPacks() -{ +QList> SmileyPack::listSmileyPacks() { return listSmileyPacks(DEFAULT_PATHS); } @@ -150,8 +142,7 @@ QList> SmileyPack::listSmileyPacks() * @param paths Paths where to search for file * @return Vector of pairs: {directoryName, absolutePathToFile} */ -QList> SmileyPack::listSmileyPacks(const QStringList& paths) -{ +QList> SmileyPack::listSmileyPacks(const QStringList& paths) { QList> smileyPacks; const QString homePath = QDir::homePath(); for (QString path : paths) { @@ -187,12 +178,11 @@ QList> SmileyPack::listSmileyPacks(const QStringList& pa * @param filename Filename of smile pack. * @return False if cannot open file, true otherwise. */ -bool SmileyPack::load(const QString& filename) -{ - qDebug()<<"SmileyPack::load"< SmileyPack::getEmoticons() const -{ -// QMutexLocker locker(&loadingMutex); +QList SmileyPack::getEmoticons() const { + // QMutexLocker locker(&loadingMutex); return emoticons; } @@ -311,8 +300,7 @@ QList SmileyPack::getEmoticons() const * @param emoticon Passed emoticon * @return Returns cached icon according to passed emoticon, null if no icon mapped to this emoticon */ -std::shared_ptr SmileyPack::getAsIcon(const QString& emoticon) const -{ +std::shared_ptr SmileyPack::getAsIcon(const QString& emoticon) const { QMutexLocker locker(&loadingMutex); if (cachedIcon.find(emoticon) != cachedIcon.end()) { return cachedIcon[emoticon]; @@ -329,7 +317,6 @@ std::shared_ptr SmileyPack::getAsIcon(const QString& emoticon) const return icon; } -void SmileyPack::onSmileyPackChanged() -{ +void SmileyPack::onSmileyPackChanged() { QtConcurrent::run(this, &SmileyPack::load, Settings::getInstance().getSmileyPack()); } diff --git a/src/modules/im/src/persistence/smileypack.h b/src/modules/im/src/persistence/smileypack.h index ff00e80d..4be33d73 100644 --- a/src/modules/im/src/persistence/smileypack.h +++ b/src/modules/im/src/persistence/smileypack.h @@ -22,8 +22,7 @@ class QTimer; -class SmileyPack : public QObject -{ +class SmileyPack : public QObject { Q_OBJECT public: @@ -57,4 +56,4 @@ private slots: mutable QMutex loadingMutex; }; -#endif // SMILEYPACK_H +#endif // SMILEYPACK_H diff --git a/src/modules/im/src/persistence/toxsave.cpp b/src/modules/im/src/persistence/toxsave.cpp index cc468015..e1c50f15 100644 --- a/src/modules/im/src/persistence/toxsave.cpp +++ b/src/modules/im/src/persistence/toxsave.cpp @@ -11,12 +11,11 @@ */ #include "toxsave.h" +#include #include "src/widget/gui.h" #include "src/widget/tool/profileimporter.h" -#include -bool toxSaveEventHandler(const QByteArray& eventData) -{ +bool toxSaveEventHandler(const QByteArray& eventData) { if (!eventData.endsWith(".tox")) { return false; } @@ -31,8 +30,7 @@ bool toxSaveEventHandler(const QByteArray& eventData) * @param path Path to .tox file. * @return True if import success, false, otherwise. */ -bool handleToxSave(const QString& path) -{ +bool handleToxSave(const QString& path) { ProfileImporter importer(GUI::getMainWidget()); return importer.importProfile(path); } diff --git a/src/modules/im/src/platform/camera/avfoundation.h b/src/modules/im/src/platform/camera/avfoundation.h index 4b8bfc27..1ad5f5a5 100644 --- a/src/modules/im/src/platform/camera/avfoundation.h +++ b/src/modules/im/src/platform/camera/avfoundation.h @@ -12,10 +12,10 @@ #ifndef AVFOUNDATION_H #define AVFOUNDATION_H -#include "src/video/videomode.h" #include #include #include +#include "src/video/videomode.h" #ifndef Q_OS_MACX #error "This file is only meant to be compiled for Mac OS X targets" @@ -26,6 +26,6 @@ const QString CAPTURE_SCREEN{"Capture screen"}; QVector getDeviceModes(QString devName); QVector> getDeviceList(); -} +} // namespace avfoundation -#endif // AVFOUNDATION_H +#endif // AVFOUNDATION_H diff --git a/src/modules/im/src/platform/camera/directshow.cpp b/src/modules/im/src/platform/camera/directshow.cpp index 41969313..0f6adb37 100644 --- a/src/modules/im/src/platform/camera/directshow.cpp +++ b/src/modules/im/src/platform/camera/directshow.cpp @@ -10,7 +10,6 @@ * See the Mulan PubL v2 for more details. */ - #include "directshow.h" // Because of replacing to incorrect order, which leads to building failing, @@ -32,29 +31,25 @@ * stdout and is not part of the public API for some reason. */ -static char* wcharToUtf8(wchar_t* w) -{ +static char* wcharToUtf8(wchar_t* w) { int l = WideCharToMultiByte(CP_UTF8, 0, w, -1, 0, 0, 0, 0); char* s = new char[l]; - if (s) - WideCharToMultiByte(CP_UTF8, 0, w, -1, s, l, 0, 0); + if (s) WideCharToMultiByte(CP_UTF8, 0, w, -1, s, l, 0, 0); return s; } -QVector> DirectShow::getDeviceList() -{ +QVector> DirectShow::getDeviceList() { IMoniker* m = nullptr; QVector> devices; ICreateDevEnum* devenum = nullptr; if (CoCreateInstance(CLSID_SystemDeviceEnum, nullptr, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, - (void**)&devenum) - != S_OK) + (void**)&devenum) != S_OK) return devices; IEnumMoniker* classenum = nullptr; - if (devenum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, (IEnumMoniker**)&classenum, 0) - != S_OK) + if (devenum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, (IEnumMoniker**)&classenum, + 0) != S_OK) return devices; while (classenum->Next(1, &m, nullptr) == S_OK) { @@ -65,41 +60,32 @@ QVector> DirectShow::getDeviceList() LPOLESTR olestr = nullptr; char *devIdString = nullptr, *devHumanName = nullptr; - if (CoGetMalloc(1, &coMalloc) != S_OK) - goto fail; - if (CreateBindCtx(0, &bindCtx) != S_OK) - goto fail; + if (CoGetMalloc(1, &coMalloc) != S_OK) goto fail; + if (CreateBindCtx(0, &bindCtx) != S_OK) goto fail; // Get an uuid for the device that we can pass to ffmpeg directly - if (m->GetDisplayName(bindCtx, nullptr, &olestr) != S_OK) - goto fail; + if (m->GetDisplayName(bindCtx, nullptr, &olestr) != S_OK) goto fail; devIdString = wcharToUtf8(olestr); // replace ':' with '_' since FFmpeg uses : to delimitate sources for (size_t i = 0; i < strlen(devIdString); ++i) - if (devIdString[i] == ':') - devIdString[i] = '_'; + if (devIdString[i] == ':') devIdString[i] = '_'; // Get a human friendly name/description - if (m->BindToStorage(nullptr, nullptr, IID_IPropertyBag, (void**)&bag) != S_OK) - goto fail; + if (m->BindToStorage(nullptr, nullptr, IID_IPropertyBag, (void**)&bag) != S_OK) goto fail; var.vt = VT_BSTR; - if (bag->Read(L"FriendlyName", &var, nullptr) != S_OK) - goto fail; + if (bag->Read(L"FriendlyName", &var, nullptr) != S_OK) goto fail; devHumanName = wcharToUtf8(var.bstrVal); devices += {QString("video=") + devIdString, devHumanName}; fail: - if (olestr && coMalloc) - coMalloc->Free(olestr); - if (bindCtx) - bindCtx->Release(); + if (olestr && coMalloc) coMalloc->Free(olestr); + if (bindCtx) bindCtx->Release(); delete[] devIdString; delete[] devHumanName; - if (bag) - bag->Release(); + if (bag) bag->Release(); m->Release(); } classenum->Release(); @@ -109,21 +95,19 @@ QVector> DirectShow::getDeviceList() // Used (by getDeviceModes) to select a device // so we can list its properties -static IBaseFilter* getDevFilter(QString devName) -{ +static IBaseFilter* getDevFilter(QString devName) { IBaseFilter* devFilter = nullptr; - devName = devName.mid(6); // Remove the "video=" + devName = devName.mid(6); // Remove the "video=" IMoniker* m = nullptr; ICreateDevEnum* devenum = nullptr; if (CoCreateInstance(CLSID_SystemDeviceEnum, nullptr, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, - (void**)&devenum) - != S_OK) + (void**)&devenum) != S_OK) return devFilter; IEnumMoniker* classenum = nullptr; - if (devenum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, (IEnumMoniker**)&classenum, 0) - != S_OK) + if (devenum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, (IEnumMoniker**)&classenum, + 0) != S_OK) return devFilter; while (classenum->Next(1, &m, nullptr) == S_OK) { @@ -132,57 +116,45 @@ static IBaseFilter* getDevFilter(QString devName) LPOLESTR olestr = nullptr; char* devIdString; - if (CoGetMalloc(1, &coMalloc) != S_OK) - goto fail; - if (CreateBindCtx(0, &bindCtx) != S_OK) - goto fail; + if (CoGetMalloc(1, &coMalloc) != S_OK) goto fail; + if (CreateBindCtx(0, &bindCtx) != S_OK) goto fail; - if (m->GetDisplayName(bindCtx, nullptr, &olestr) != S_OK) - goto fail; + if (m->GetDisplayName(bindCtx, nullptr, &olestr) != S_OK) goto fail; devIdString = wcharToUtf8(olestr); // replace ':' with '_' since FFmpeg uses : to delimitate sources for (size_t i = 0; i < strlen(devIdString); ++i) - if (devIdString[i] == ':') - devIdString[i] = '_'; + if (devIdString[i] == ':') devIdString[i] = '_'; - if (devName != devIdString) - goto fail; + if (devName != devIdString) goto fail; - if (m->BindToObject(0, 0, IID_IBaseFilter, (void**)&devFilter) != S_OK) - goto fail; + if (m->BindToObject(0, 0, IID_IBaseFilter, (void**)&devFilter) != S_OK) goto fail; fail: - if (olestr && coMalloc) - coMalloc->Free(olestr); - if (bindCtx) - bindCtx->Release(); + if (olestr && coMalloc) coMalloc->Free(olestr); + if (bindCtx) bindCtx->Release(); delete[] devIdString; m->Release(); } classenum->Release(); - if (!devFilter) - qWarning() << "Could't find the device " << devName; + if (!devFilter) qWarning() << "Could't find the device " << devName; return devFilter; } -QVector DirectShow::getDeviceModes(QString devName) -{ +QVector DirectShow::getDeviceModes(QString devName) { QVector modes; IBaseFilter* devFilter = getDevFilter(devName); - if (!devFilter) - return modes; + if (!devFilter) return modes; // The outter loop tries to find a valid output pin GUID category; DWORD r2; IEnumPins* pins = nullptr; IPin* pin; - if (devFilter->EnumPins(&pins) != S_OK) - return modes; + if (devFilter->EnumPins(&pins) != S_OK) return modes; while (pins->Next(1, &pin, nullptr) == S_OK) { IKsPropertySet* p = nullptr; @@ -190,15 +162,12 @@ QVector DirectShow::getDeviceModes(QString devName) pin->QueryPinInfo(&info); info.pFilter->Release(); - if (info.dir != PINDIR_OUTPUT) - goto next; - if (pin->QueryInterface(IID_IKsPropertySet, (void**)&p) != S_OK) - goto next; - if (p->Get(AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY, nullptr, 0, &category, sizeof(GUID), &r2) - != S_OK) - goto next; - if (!IsEqualGUID(category, PIN_CATEGORY_CAPTURE)) + if (info.dir != PINDIR_OUTPUT) goto next; + if (pin->QueryInterface(IID_IKsPropertySet, (void**)&p) != S_OK) goto next; + if (p->Get(AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY, nullptr, 0, &category, sizeof(GUID), + &r2) != S_OK) goto next; + if (!IsEqualGUID(category, PIN_CATEGORY_CAPTURE)) goto next; // Now we can list the video modes for the current pin // Prepare for another wall of spaghetti DIRECT SHOW QUALITY code @@ -206,10 +175,8 @@ QVector DirectShow::getDeviceModes(QString devName) IAMStreamConfig* config = nullptr; VIDEO_STREAM_CONFIG_CAPS* vcaps = nullptr; int size, n; - if (pin->QueryInterface(IID_IAMStreamConfig, (void**)&config) != S_OK) - goto next; - if (config->GetNumberOfCapabilities(&n, &size) != S_OK) - goto pinend; + if (pin->QueryInterface(IID_IAMStreamConfig, (void**)&config) != S_OK) goto next; + if (config->GetNumberOfCapabilities(&n, &size) != S_OK) goto pinend; assert(size == sizeof(VIDEO_STREAM_CONFIG_CAPS)); vcaps = new VIDEO_STREAM_CONFIG_CAPS; @@ -217,22 +184,19 @@ QVector DirectShow::getDeviceModes(QString devName) for (int i = 0; i < n; ++i) { AM_MEDIA_TYPE* type = nullptr; VideoMode mode; - if (config->GetStreamCaps(i, &type, (BYTE*)vcaps) != S_OK) - goto nextformat; + if (config->GetStreamCaps(i, &type, (BYTE*)vcaps) != S_OK) goto nextformat; - if (!IsEqualGUID(type->formattype, FORMAT_VideoInfo) - && !IsEqualGUID(type->formattype, FORMAT_VideoInfo2)) + if (!IsEqualGUID(type->formattype, FORMAT_VideoInfo) && + !IsEqualGUID(type->formattype, FORMAT_VideoInfo2)) goto nextformat; mode.width = vcaps->MaxOutputSize.cx; mode.height = vcaps->MaxOutputSize.cy; mode.FPS = 1e7 / vcaps->MinFrameInterval; - if (!modes.contains(mode)) - modes.append(std::move(mode)); + if (!modes.contains(mode)) modes.append(std::move(mode)); nextformat: - if (type->pbFormat) - CoTaskMemFree(type->pbFormat); + if (type->pbFormat) CoTaskMemFree(type->pbFormat); CoTaskMemFree(type); } pinend: @@ -240,8 +204,7 @@ QVector DirectShow::getDeviceModes(QString devName) delete vcaps; } next: - if (p) - p->Release(); + if (p) p->Release(); pin->Release(); } diff --git a/src/modules/im/src/platform/camera/directshow.h b/src/modules/im/src/platform/camera/directshow.h index e6459c80..b6f03b95 100644 --- a/src/modules/im/src/platform/camera/directshow.h +++ b/src/modules/im/src/platform/camera/directshow.h @@ -10,14 +10,13 @@ * See the Mulan PubL v2 for more details. */ - #ifndef DIRECTSHOW_H #define DIRECTSHOW_H -#include "src/video/videomode.h" #include #include #include +#include "src/video/videomode.h" #ifndef Q_OS_WIN #error "This file is only meant to be compiled for Windows targets" @@ -26,6 +25,6 @@ namespace DirectShow { QVector> getDeviceList(); QVector getDeviceModes(QString devName); -} +} // namespace DirectShow -#endif // DIRECTSHOW_H +#endif // DIRECTSHOW_H diff --git a/src/modules/im/src/platform/camera/v4l2.cpp b/src/modules/im/src/platform/camera/v4l2.cpp index 350b1e12..7827d90a 100644 --- a/src/modules/im/src/platform/camera/v4l2.cpp +++ b/src/modules/im/src/platform/camera/v4l2.cpp @@ -10,17 +10,16 @@ * See the Mulan PubL v2 for more details. */ - #include "v4l2.h" -#include #include #include #include #include -#include #include #include +#include +#include /** * Most of this file is adapted from libavdevice's v4l2.c, @@ -28,8 +27,7 @@ * stdout and is not part of the public API for some reason. */ -static std::map createPixFmtToQuality() -{ +static std::map createPixFmtToQuality() { std::map m; m[V4L2_PIX_FMT_H264] = 3; m[V4L2_PIX_FMT_MJPEG] = 2; @@ -39,8 +37,7 @@ static std::map createPixFmtToQuality() } const std::map pixFmtToQuality = createPixFmtToQuality(); -static std::map createPixFmtToName() -{ +static std::map createPixFmtToName() { std::map m; m[V4L2_PIX_FMT_H264] = QString("h264"); m[V4L2_PIX_FMT_MJPEG] = QString("mjpeg"); @@ -50,8 +47,7 @@ static std::map createPixFmtToName() } const std::map pixFmtToName = createPixFmtToName(); -static int deviceOpen(QString devName, int* error) -{ +static int deviceOpen(QString devName, int* error) { struct v4l2_capability cap; int fd; @@ -85,8 +81,7 @@ static int deviceOpen(QString devName, int* error) } static QVector getDeviceModeFramerates(int fd, unsigned w, unsigned h, - uint32_t pixelFormat) -{ + uint32_t pixelFormat) { QVector rates; v4l2_frmivalenum vfve{}; vfve.pixel_format = pixelFormat; @@ -96,16 +91,14 @@ static QVector getDeviceModeFramerates(int fd, unsigned w, unsigned h, while (!ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &vfve)) { float rate; switch (vfve.type) { - case V4L2_FRMSIZE_TYPE_DISCRETE: - rate = vfve.discrete.denominator / vfve.discrete.numerator; - if (!rates.contains(rate)) - rates.append(rate); - break; - case V4L2_FRMSIZE_TYPE_CONTINUOUS: - case V4L2_FRMSIZE_TYPE_STEPWISE: - rate = vfve.stepwise.min.denominator / vfve.stepwise.min.numerator; - if (!rates.contains(rate)) - rates.append(rate); + case V4L2_FRMSIZE_TYPE_DISCRETE: + rate = vfve.discrete.denominator / vfve.discrete.numerator; + if (!rates.contains(rate)) rates.append(rate); + break; + case V4L2_FRMSIZE_TYPE_CONTINUOUS: + case V4L2_FRMSIZE_TYPE_STEPWISE: + rate = vfve.stepwise.min.denominator / vfve.stepwise.min.numerator; + if (!rates.contains(rate)) rates.append(rate); } vfve.index++; } @@ -113,8 +106,7 @@ static QVector getDeviceModeFramerates(int fd, unsigned w, unsigned h, return rates; } -QVector v4l2::getDeviceModes(QString devName) -{ +QVector v4l2::getDeviceModes(QString devName) { QVector modes; int error = 0; @@ -136,21 +128,21 @@ QVector v4l2::getDeviceModes(QString devName) VideoMode mode; mode.pixel_format = vfse.pixel_format; switch (vfse.type) { - case V4L2_FRMSIZE_TYPE_DISCRETE: - mode.width = vfse.discrete.width; - mode.height = vfse.discrete.height; - break; - case V4L2_FRMSIZE_TYPE_CONTINUOUS: - case V4L2_FRMSIZE_TYPE_STEPWISE: - mode.width = vfse.stepwise.max_width; - mode.height = vfse.stepwise.max_height; - break; - default: - continue; + case V4L2_FRMSIZE_TYPE_DISCRETE: + mode.width = vfse.discrete.width; + mode.height = vfse.discrete.height; + break; + case V4L2_FRMSIZE_TYPE_CONTINUOUS: + case V4L2_FRMSIZE_TYPE_STEPWISE: + mode.width = vfse.stepwise.max_width; + mode.height = vfse.stepwise.max_height; + break; + default: + continue; } QVector rates = - getDeviceModeFramerates(fd, mode.width, mode.height, vfd.pixelformat); + getDeviceModeFramerates(fd, mode.width, mode.height, vfd.pixelformat); // insert dummy FPS value to have the mode in the list even if we don't know the FPS // this fixes support for some webcams, see #5082 @@ -171,14 +163,12 @@ QVector v4l2::getDeviceModes(QString devName) return modes; } -QVector> v4l2::getDeviceList() -{ +QVector> v4l2::getDeviceList() { QVector> devices; QStringList deviceFiles; DIR* dir = opendir("/dev"); - if (!dir) - return devices; + if (!dir) return devices; dirent* e; while ((e = readdir(dir))) @@ -194,23 +184,22 @@ QVector> v4l2::getDeviceList() } v4l2_capability caps; - if(ioctl(fd, VIDIOC_QUERYCAP, &caps) == 0){ - if(!(caps.device_caps & V4L2_CAP_VIDEO_CAPTURE)){ + if (ioctl(fd, VIDIOC_QUERYCAP, &caps) == 0) { + if (!(caps.device_caps & V4L2_CAP_VIDEO_CAPTURE)) { continue; } devices += {file, (const char*)caps.card}; - } + } close(fd); } - for(auto item : devices){ - qDebug()<<"v4l2 device:" <"<" << item.second; } return devices; } -QString v4l2::getPixelFormatString(uint32_t pixel_format) -{ +QString v4l2::getPixelFormatString(uint32_t pixel_format) { if (pixFmtToName.find(pixel_format) == pixFmtToName.end()) { qWarning() << "Pixel format not found"; return QString("invalid"); @@ -218,8 +207,7 @@ QString v4l2::getPixelFormatString(uint32_t pixel_format) return pixFmtToName.at(pixel_format); } -bool v4l2::betterPixelFormat(uint32_t a, uint32_t b) -{ +bool v4l2::betterPixelFormat(uint32_t a, uint32_t b) { if (pixFmtToQuality.find(a) == pixFmtToQuality.end()) { return false; } else if (pixFmtToQuality.find(b) == pixFmtToQuality.end()) { diff --git a/src/modules/im/src/platform/camera/v4l2.h b/src/modules/im/src/platform/camera/v4l2.h index c69fb826..76f247ee 100644 --- a/src/modules/im/src/platform/camera/v4l2.h +++ b/src/modules/im/src/platform/camera/v4l2.h @@ -12,10 +12,10 @@ #ifndef V4L2_H #define V4L2_H -#include "src/video/videomode.h" #include #include #include +#include "src/video/videomode.h" #if !(defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)) #error "This file is only meant to be compiled for Linux or FreeBSD targets" @@ -26,6 +26,6 @@ QVector getDeviceModes(QString devName); QVector> getDeviceList(); QString getPixelFormatString(uint32_t pixel_format); bool betterPixelFormat(uint32_t a, uint32_t b); -} +} // namespace v4l2 -#endif // V4L2_H +#endif // V4L2_H diff --git a/src/modules/im/src/platform/capslock.h b/src/modules/im/src/platform/capslock.h index 279d86f6..f9a09d4a 100644 --- a/src/modules/im/src/platform/capslock.h +++ b/src/modules/im/src/platform/capslock.h @@ -15,11 +15,10 @@ #ifndef PLATFORM_CAPSLOCK_H #define PLATFORM_CAPSLOCK_H - namespace Platform { bool capsLockEnabled(); } -#endif // PLATFORM_CAPSLOCK_H +#endif // PLATFORM_CAPSLOCK_H -#endif // QTOX_PLATFORM_EXT +#endif // QTOX_PLATFORM_EXT diff --git a/src/modules/im/src/platform/capslock_osx.cpp b/src/modules/im/src/platform/capslock_osx.cpp index c4a43334..0330c604 100644 --- a/src/modules/im/src/platform/capslock_osx.cpp +++ b/src/modules/im/src/platform/capslock_osx.cpp @@ -14,7 +14,4 @@ #include "src/platform/capslock.h" // TODO: Implement for osx -bool Platform::capsLockEnabled() -{ - return false; -} +bool Platform::capsLockEnabled() { return false; } diff --git a/src/modules/im/src/platform/capslock_win.cpp b/src/modules/im/src/platform/capslock_win.cpp index 7ce4b888..d7800a10 100644 --- a/src/modules/im/src/platform/capslock_win.cpp +++ b/src/modules/im/src/platform/capslock_win.cpp @@ -11,11 +11,8 @@ */ #include -#include "src/platform/capslock.h" #include +#include "src/platform/capslock.h" namespace Platform { -bool capsLockEnabled() -{ - return GetKeyState(VK_CAPITAL) == 1; -} -} \ No newline at end of file +bool capsLockEnabled() { return GetKeyState(VK_CAPITAL) == 1; } +} // namespace Platform \ No newline at end of file diff --git a/src/modules/im/src/platform/capslock_x11.cpp b/src/modules/im/src/platform/capslock_x11.cpp index 3e4412e6..1b050ddc 100644 --- a/src/modules/im/src/platform/capslock_x11.cpp +++ b/src/modules/im/src/platform/capslock_x11.cpp @@ -11,16 +11,15 @@ */ #include +#include #include "src/platform/capslock.h" #include "src/platform/x11_display.h" -#include #undef KeyPress #undef KeyRelease #undef FocusIn #undef FocusOut -bool Platform::capsLockEnabled() -{ +bool Platform::capsLockEnabled() { Display* d = X11Display::lock(); bool caps_state = false; if (d) { diff --git a/src/modules/im/src/platform/desktop_notifications/desktopnotify.cpp b/src/modules/im/src/platform/desktop_notifications/desktopnotify.cpp index 0ae173d3..2b438a08 100644 --- a/src/modules/im/src/platform/desktop_notifications/desktopnotify.cpp +++ b/src/modules/im/src/platform/desktop_notifications/desktopnotify.cpp @@ -19,10 +19,7 @@ #include DesktopNotify::DesktopNotify() - : notifyCore{Snore::SnoreCore::instance()} - , snoreIcon{":/img/icons/qtox.svg"} -{ - + : notifyCore{Snore::SnoreCore::instance()}, snoreIcon{":/img/icons/qtox.svg"} { notifyCore.loadPlugins(Snore::SnorePlugin::Backend); qDebug() << "primary notification backend:" << notifyCore.primaryNotificationBackend(); @@ -31,10 +28,10 @@ DesktopNotify::DesktopNotify() notifyCore.registerApplication(snoreApp); } -void DesktopNotify::createNotification(const QString& title, const QString& text, Snore::Icon& icon) -{ +void DesktopNotify::createNotification(const QString& title, const QString& text, + Snore::Icon& icon) { const Settings& s = Settings::getInstance(); - if(!(s.getNotify() && s.getDesktopNotify())) { + if (!(s.getNotify() && s.getDesktopNotify())) { return; } @@ -43,27 +40,36 @@ void DesktopNotify::createNotification(const QString& title, const QString& text notifyCore.broadcastNotification(notify); } -void DesktopNotify::notifyMessage(const QString& title, const QString& message) -{ +void DesktopNotify::notifyMessage(const QString& title, const QString& message) { createNotification(title, message, snoreIcon); } -void DesktopNotify::notifyMessagePixmap(const QString& title, const QString& message, QPixmap avatar) -{ +void DesktopNotify::notifyMessagePixmap(const QString& title, const QString& message, + QPixmap avatar) { Snore::Icon new_icon(avatar); createNotification(title, message, new_icon); } -void DesktopNotify::notifyMessageSimple(const MessageType type) -{ +void DesktopNotify::notifyMessageSimple(const MessageType type) { QString message; switch (type) { - case MessageType::FRIEND: message = tr("New message"); break; - case MessageType::FRIEND_FILE: message = tr("Incoming file transfer"); break; - case MessageType::FRIEND_REQUEST: message = tr("Friend request received"); break; - case MessageType::GROUP: message = tr("New group message"); break; - case MessageType::GROUP_INVITE: message = tr("Group invite received"); break; - default: break; + case MessageType::FRIEND: + message = tr("New message"); + break; + case MessageType::FRIEND_FILE: + message = tr("Incoming file transfer"); + break; + case MessageType::FRIEND_REQUEST: + message = tr("Friend request received"); + break; + case MessageType::GROUP: + message = tr("New group message"); + break; + case MessageType::GROUP_INVITE: + message = tr("Group invite received"); + break; + default: + break; } createNotification(message, {}, snoreIcon); diff --git a/src/modules/im/src/platform/desktop_notifications/desktopnotify.h b/src/modules/im/src/platform/desktop_notifications/desktopnotify.h index b51de976..dcf73d34 100644 --- a/src/modules/im/src/platform/desktop_notifications/desktopnotify.h +++ b/src/modules/im/src/platform/desktop_notifications/desktopnotify.h @@ -18,19 +18,12 @@ #include #include -class DesktopNotify : public QObject -{ +class DesktopNotify : public QObject { Q_OBJECT public: DesktopNotify(); - enum class MessageType { - FRIEND, - FRIEND_FILE, - FRIEND_REQUEST, - GROUP, - GROUP_INVITE - }; + enum class MessageType { FRIEND, FRIEND_FILE, FRIEND_REQUEST, GROUP, GROUP_INVITE }; public slots: void notifyMessage(const QString& title, const QString& message); @@ -46,4 +39,4 @@ public slots: Snore::Icon snoreIcon; }; -#endif // DESKTOPNOTIFY_H +#endif // DESKTOPNOTIFY_H diff --git a/src/modules/im/src/platform/install_osx.cpp b/src/modules/im/src/platform/install_osx.cpp index 17616ab1..d922fef7 100644 --- a/src/modules/im/src/platform/install_osx.cpp +++ b/src/modules/im/src/platform/install_osx.cpp @@ -10,7 +10,6 @@ * See the Mulan PubL v2 for more details. */ - #include "install_osx.h" #include #include @@ -22,8 +21,7 @@ #include -void osx::moveToAppFolder() -{ +void osx::moveToAppFolder() { if (qApp->applicationDirPath() != "/Applications/qtox.app/Contents/MacOS") { qDebug() << "OS X: Not in Applications folder"; @@ -31,12 +29,13 @@ void osx::moveToAppFolder() AskInstall.setIcon(QMessageBox::Question); AskInstall.setWindowModality(Qt::ApplicationModal); AskInstall.setText("Move to Applications folder?"); - AskInstall.setInformativeText("I can move myself to the Applications folder, keeping your " - "downloads folder less cluttered.\r\n"); + AskInstall.setInformativeText( + "I can move myself to the Applications folder, keeping your " + "downloads folder less cluttered.\r\n"); AskInstall.setStandardButtons(QMessageBox::Yes | QMessageBox::No); AskInstall.setDefaultButton(QMessageBox::Yes); - int AskInstallAttempt = AskInstall.exec(); // Actually ask the user + int AskInstallAttempt = AskInstall.exec(); // Actually ask the user if (AskInstallAttempt == QMessageBox::Yes) { QProcess* sudoprocess = new QProcess; @@ -49,7 +48,7 @@ void osx::moveToAppFolder() QString appdir_noqtox = appdir; appdir_noqtox.chop(8); - if ((appdir_noqtox + "qtox.app") != appdir) // quick safety check + if ((appdir_noqtox + "qtox.app") != appdir) // quick safety check { qDebug() << "OS X: Attmepted to delete non qTox directory!"; exit(EXIT_UPDATE_MACX_FAIL); @@ -59,37 +58,37 @@ void osx::moveToAppFolder() const QString sudoProgram = bindir + "/qtox_sudo"; const QStringList sudoArguments = {"rsync", "-avzhpltK", appdir, "/Applications"}; - sudoprocess->start(sudoProgram, sudoArguments); // Where the magic actually happens, safety checks ^ + sudoprocess->start(sudoProgram, + sudoArguments); // Where the magic actually happens, safety checks ^ sudoprocess->waitForFinished(); - if (old_app.removeRecursively()) // We've just deleted the running program + if (old_app.removeRecursively()) // We've just deleted the running program qDebug() << "OS X: Cleaned up old directory"; else qDebug() << "OS X: This should never happen, the directory failed to delete"; - if (fork() != 0) // Forking is required otherwise it won't actually cleanly launch + if (fork() != 0) // Forking is required otherwise it won't actually cleanly launch exit(EXIT_UPDATE_MACX); const QString qtoxProgram = "open"; const QStringList qtoxArguments = {"/Applications/qtox.app"}; qtoxprocess->start(qtoxProgram, qtoxArguments); - exit(0); // Actually kills it + exit(0); // Actually kills it } } } // migrateProfiles() is compatabilty code that can be removed down the line when the time seems // right. -void osx::migrateProfiles() -{ - QString oldPath = QDir::cleanPath(QStandardPaths::writableLocation(QStandardPaths::HomeLocation) - + QDir::separator() + "Library" + QDir::separator() - + "Preferences" + QDir::separator() + "tox"); +void osx::migrateProfiles() { + QString oldPath = QDir::cleanPath( + QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + QDir::separator() + + "Library" + QDir::separator() + "Preferences" + QDir::separator() + "tox"); QFileInfo checkDir(oldPath); - QString newPath = QDir::cleanPath(QStandardPaths::writableLocation(QStandardPaths::HomeLocation) - + QDir::separator() + "Library" + QDir::separator() - + "Application Support" + QDir::separator() + "Tox"); + QString newPath = QDir::cleanPath( + QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + QDir::separator() + + "Library" + QDir::separator() + "Application Support" + QDir::separator() + "Tox"); QDir dir; if (!checkDir.exists() || !checkDir.isDir()) { @@ -108,9 +107,10 @@ void osx::migrateProfiles() MigrateProfile.setWindowModality(Qt::ApplicationModal); MigrateProfile.setText("Alternate profile migration method used."); MigrateProfile.setInformativeText( - "It has been detected that your profiles \nwhere migrated to the new settings " - "directory; \nusing the alternate migration method. \n\nA backup can be found in your: " - "\n/Users/[USER]/.Tox-Backup[DATE-TIME] \n\nJust in case. \r\n"); + "It has been detected that your profiles \nwhere migrated to the new settings " + "directory; \nusing the alternate migration method. \n\nA backup can be found in " + "your: " + "\n/Users/[USER]/.Tox-Backup[DATE-TIME] \n\nJust in case. \r\n"); MigrateProfile.exec(); } } diff --git a/src/modules/im/src/platform/install_osx.h b/src/modules/im/src/platform/install_osx.h index d5a88b24..bf951e6b 100644 --- a/src/modules/im/src/platform/install_osx.h +++ b/src/modules/im/src/platform/install_osx.h @@ -20,11 +20,11 @@ namespace osx { static constexpr int EXIT_UPDATE_MACX = - 218; // We track our state using unique exit codes when debugging + 218; // We track our state using unique exit codes when debugging static constexpr int EXIT_UPDATE_MACX_FAIL = 216; void moveToAppFolder(); void migrateProfiles(); -} +} // namespace osx -#endif // INSTALLOSX_H +#endif // INSTALLOSX_H diff --git a/src/modules/im/src/platform/posixsignalnotifier.cpp b/src/modules/im/src/platform/posixsignalnotifier.cpp index 5f4041e3..7ae8d4c6 100644 --- a/src/modules/im/src/platform/posixsignalnotifier.cpp +++ b/src/modules/im/src/platform/posixsignalnotifier.cpp @@ -19,10 +19,10 @@ #include #include -#include // sigaction() -#include // socketpair() -#include // may be needed for BSD -#include // close() +#include // sigaction() +#include // socketpair() +#include // may be needed for BSD +#include // close() /** * @class PosixSignalNotifier @@ -34,19 +34,17 @@ namespace detail { static std::atomic_flag g_signalSocketUsageFlag = ATOMIC_FLAG_INIT; static std::array g_signalSocketPair; -static void signalHandler(int signum) -{ +static void signalHandler(int signum) { // DO NOT call any Qt functions directly, only limited amount of so-called async-signal-safe // functions can be called in signal handlers. // See https://doc.qt.io/qt-4.8/unix-signals.html - // If test_and_set() returns true, it means it was already in use (only by ~PosixSignalNotifier()), - // so we bail out. Our signal handler is blocking, only one will be called (no race between - // threads), hence simple implementation. - if (g_signalSocketUsageFlag.test_and_set()) - return; + // If test_and_set() returns true, it means it was already in use (only by + // ~PosixSignalNotifier()), so we bail out. Our signal handler is blocking, only one will be + // called (no race between threads), hence simple implementation. + if (g_signalSocketUsageFlag.test_and_set()) return; - if(::write(g_signalSocketPair[0], &signum, sizeof(signum)) == -1) { + if (::write(g_signalSocketPair[0], &signum, sizeof(signum)) == -1) { // We hardly can do anything more usefull in signal handler, and // any ways it's probably very unexpected error (out of memory?), // since we check socket existance with a flag beforehand. @@ -56,10 +54,9 @@ static void signalHandler(int signum) g_signalSocketUsageFlag.clear(); } -} // namespace detail +} // namespace detail -PosixSignalNotifier::~PosixSignalNotifier() -{ +PosixSignalNotifier::~PosixSignalNotifier() { while (detail::g_signalSocketUsageFlag.test_and_set()) { // spin-loop until we aquire flag (signal handler might be running and have flag in use) } @@ -71,41 +68,36 @@ PosixSignalNotifier::~PosixSignalNotifier() // do not clear the usage flag here, signal handler cannot use socket any more! } -void PosixSignalNotifier::watchSignal(int signum) -{ +void PosixSignalNotifier::watchSignal(int signum) { sigset_t blockMask; - sigemptyset(&blockMask); // do not prefix with ::, it's a macro on macOS - sigaddset(&blockMask, signum); // do not prefix with ::, it's a macro on macOS + sigemptyset(&blockMask); // do not prefix with ::, it's a macro on macOS + sigaddset(&blockMask, signum); // do not prefix with ::, it's a macro on macOS - struct sigaction action = {}; // all zeroes by default + struct sigaction action = {}; // all zeroes by default action.sa_handler = detail::signalHandler; - action.sa_mask = blockMask; // allow old signal to finish before new is raised + action.sa_mask = blockMask; // allow old signal to finish before new is raised if (::sigaction(signum, &action, nullptr)) { qFatal("Failed to setup signal %d, error = %d", signum, errno); } } -void PosixSignalNotifier::watchSignals(std::initializer_list signalSet) -{ - for (auto s: signalSet) { +void PosixSignalNotifier::watchSignals(std::initializer_list signalSet) { + for (auto s : signalSet) { watchSignal(s); } } -void PosixSignalNotifier::watchCommonTerminatingSignals() -{ +void PosixSignalNotifier::watchCommonTerminatingSignals() { watchSignals({SIGHUP, SIGINT, SIGQUIT, SIGTERM}); } -PosixSignalNotifier& PosixSignalNotifier::globalInstance() -{ +PosixSignalNotifier& PosixSignalNotifier::globalInstance() { static PosixSignalNotifier instance; return instance; } -void PosixSignalNotifier::onSignalReceived() -{ +void PosixSignalNotifier::onSignalReceived() { int signum{0}; if (::read(detail::g_signalSocketPair[1], &signum, sizeof(signum)) == -1) { qFatal("Failed to read from signal socket, error = %d", errno); @@ -115,10 +107,9 @@ void PosixSignalNotifier::onSignalReceived() emit activated(signum); } -PosixSignalNotifier::PosixSignalNotifier() -{ +PosixSignalNotifier::PosixSignalNotifier() { if (::socketpair(AF_UNIX, SOCK_STREAM, 0, detail::g_signalSocketPair.data())) { - qFatal("Failed to create socket pair, error = %d", errno); + qFatal("Failed to create socket pair, error = %d", errno); } notifier = new QSocketNotifier(detail::g_signalSocketPair[1], QSocketNotifier::Read, this); diff --git a/src/modules/im/src/platform/posixsignalnotifier.h b/src/modules/im/src/platform/posixsignalnotifier.h index 4d642c36..930d96c6 100644 --- a/src/modules/im/src/platform/posixsignalnotifier.h +++ b/src/modules/im/src/platform/posixsignalnotifier.h @@ -17,8 +17,7 @@ class QSocketNotifier; -class PosixSignalNotifier : public QObject -{ +class PosixSignalNotifier : public QObject { Q_OBJECT public: @@ -43,4 +42,4 @@ private slots: QSocketNotifier* notifier{nullptr}; }; -#endif // POSIXSIGNALNOTIFIER_H +#endif // POSIXSIGNALNOTIFIER_H diff --git a/src/modules/im/src/platform/statusnotifier/closures.h b/src/modules/im/src/platform/statusnotifier/closures.h index c5799860..6298cb96 100644 --- a/src/modules/im/src/platform/statusnotifier/closures.h +++ b/src/modules/im/src/platform/statusnotifier/closures.h @@ -19,8 +19,10 @@ G_BEGIN_DECLS /* BOOLEAN:INT,INT (closures.def:1) */ extern void g_cclosure_user_marshal_BOOLEAN__INT_INT(GClosure* closure, GValue* return_value, - guint n_param_values, const GValue* param_values, - gpointer invocation_hint, gpointer marshal_data); + guint n_param_values, + const GValue* param_values, + gpointer invocation_hint, + gpointer marshal_data); G_END_DECLS diff --git a/src/modules/im/src/platform/statusnotifier/enums.h b/src/modules/im/src/platform/statusnotifier/enums.h index a9f39ed0..f8d16aeb 100644 --- a/src/modules/im/src/platform/statusnotifier/enums.h +++ b/src/modules/im/src/platform/statusnotifier/enums.h @@ -14,7 +14,6 @@ #define __STATUS_NOTIFIER_ENUMS_H__ #include "statusnotifier.h" - GType status_notifier_error_get_type(void); #define TYPE_STATUS_NOTIFIER_ERROR (status_notifier_error_get_type()) GType status_notifier_state_get_type(void); diff --git a/src/modules/im/src/platform/statusnotifier/interfaces.h b/src/modules/im/src/platform/statusnotifier/interfaces.h index 899b3718..b00d0ff8 100644 --- a/src/modules/im/src/platform/statusnotifier/interfaces.h +++ b/src/modules/im/src/platform/statusnotifier/interfaces.h @@ -24,60 +24,59 @@ G_BEGIN_DECLS #define ITEM_INTERFACE "org.kde.StatusNotifierItem" static const gchar watcher_xml[] = - "" - " " - " " - " " - " " - " " - " " - " " - " " - ""; - + "" + " " + " " + " " + " " + " " + " " + " " + " " + ""; static const gchar item_xml[] = - "" - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - ""; + "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + ""; G_END_DECLS diff --git a/src/modules/im/src/platform/statusnotifier/statusnotifier.h b/src/modules/im/src/platform/statusnotifier/statusnotifier.h index f953541f..e2d7fb49 100644 --- a/src/modules/im/src/platform/statusnotifier/statusnotifier.h +++ b/src/modules/im/src/platform/statusnotifier/statusnotifier.h @@ -165,8 +165,7 @@ typedef enum { STATUS_NOTIFIER_SCROLL_ORIENTATION_VERTICAL } StatusNotifierScrollOrientation; -struct _StatusNotifier -{ +struct _StatusNotifier { /*< private >*/ GObject parent; StatusNotifierPrivate* priv; @@ -191,8 +190,7 @@ struct _StatusNotifier * @scroll: The user asked for a scroll action. This is caused from input such * as mouse wheel over the graphical representation of the item. */ -struct _StatusNotifierClass -{ +struct _StatusNotifierClass { GObjectClass parent_class; /* signals */ @@ -210,7 +208,8 @@ StatusNotifier* status_notifier_new_from_icon_name(const gchar* id, StatusNotifi const gchar* icon_name); const gchar* status_notifier_get_id(StatusNotifier* sn); StatusNotifierCategory status_notifier_get_category(StatusNotifier* sn); -void status_notifier_set_from_pixbuf(StatusNotifier* sn, StatusNotifierIcon icon, GdkPixbuf* pixbuf); +void status_notifier_set_from_pixbuf(StatusNotifier* sn, StatusNotifierIcon icon, + GdkPixbuf* pixbuf); void status_notifier_set_from_icon_name(StatusNotifier* sn, StatusNotifierIcon icon, const gchar* icon_name); gboolean status_notifier_has_pixbuf(StatusNotifier* sn, StatusNotifierIcon icon); diff --git a/src/modules/im/src/platform/timer.h b/src/modules/im/src/platform/timer.h index d54f052f..a5c7a422 100644 --- a/src/modules/im/src/platform/timer.h +++ b/src/modules/im/src/platform/timer.h @@ -17,11 +17,10 @@ #include - namespace Platform { uint32_t getIdleTime(); } -#endif // PLATFORM_TIMER_H +#endif // PLATFORM_TIMER_H -#endif // QTOX_PLATFORM_EXT +#endif // QTOX_PLATFORM_EXT diff --git a/src/modules/im/src/platform/timer_osx.cpp b/src/modules/im/src/platform/timer_osx.cpp index 7834d6ce..0c2de262 100644 --- a/src/modules/im/src/platform/timer_osx.cpp +++ b/src/modules/im/src/platform/timer_osx.cpp @@ -10,13 +10,12 @@ * See the Mulan PubL v2 for more details. */ -#include -#include "src/platform/timer.h" #include #include +#include +#include "src/platform/timer.h" -uint32_t Platform::getIdleTime() -{ +uint32_t Platform::getIdleTime() { // https://hg.pidgin.im/pidgin/main/file/13e4ae613a6a/pidgin/gtkidle.c // relevant code introduced to Pidgin in: // https://hg.pidgin.im/pidgin/main/diff/8ff1c408ef3e/src/gtkidle.c @@ -30,7 +29,8 @@ uint32_t Platform::getIdleTime() service = IOServiceGetMatchingService(master, IOServiceMatching("IOHIDSystem")); } - property = IORegistryEntryCreateCFProperty(service, CFSTR("HIDIdleTime"), kCFAllocatorDefault, 0); + property = + IORegistryEntryCreateCFProperty(service, CFSTR("HIDIdleTime"), kCFAllocatorDefault, 0); CFNumberGetValue((CFNumberRef)property, kCFNumberSInt64Type, &idleTime_ns); CFRelease(property); diff --git a/src/modules/im/src/platform/timer_win.cpp b/src/modules/im/src/platform/timer_win.cpp index 0b83b8d1..e0ec9cdb 100644 --- a/src/modules/im/src/platform/timer_win.cpp +++ b/src/modules/im/src/platform/timer_win.cpp @@ -11,18 +11,16 @@ */ #include -#include "src/platform/timer.h" #include +#include "src/platform/timer.h" namespace Platform { -uint32_t getIdleTime() -{ +uint32_t getIdleTime() { LASTINPUTINFO info = {0, 0}; info.cbSize = sizeof(info); - if (GetLastInputInfo(&info)) - return GetTickCount() - info.dwTime; + if (GetLastInputInfo(&info)) return GetTickCount() - info.dwTime; return 0; } -} \ No newline at end of file +} // namespace Platform \ No newline at end of file diff --git a/src/modules/im/src/platform/timer_x11.cpp b/src/modules/im/src/platform/timer_x11.cpp index 84ec7356..974abf5e 100644 --- a/src/modules/im/src/platform/timer_x11.cpp +++ b/src/modules/im/src/platform/timer_x11.cpp @@ -9,20 +9,19 @@ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * See the Mulan PubL v2 for more details. */ - -#include -#include "src/platform/timer.h" -#include "src/platform/x11_display.h" +// clang-format off #include #include +#include "src/platform/timer.h" +#include "src/platform/x11_display.h" +// clang-format on -uint32_t Platform::getIdleTime() -{ +uint32_t Platform::getIdleTime() { uint32_t idleTime = 0; Display* display = X11Display::lock(); if (!display) { - qDebug() << "XOpenDisplay failed"; + qWarning() << "XOpenDisplay failed"; X11Display::unlock(); return 0; } @@ -36,7 +35,7 @@ uint32_t Platform::getIdleTime() idleTime = info->idle; XFree(info); } else - qDebug() << "XScreenSaverAllocInfo() failed"; + qWarning() << "XScreenSaverAllocInfo() failed"; } X11Display::unlock(); return idleTime; diff --git a/src/modules/im/src/platform/x11_display.cpp b/src/modules/im/src/platform/x11_display.cpp index c6880762..f16b11cc 100644 --- a/src/modules/im/src/platform/x11_display.cpp +++ b/src/modules/im/src/platform/x11_display.cpp @@ -10,45 +10,35 @@ * See the Mulan PubL v2 for more details. */ -#include #include "src/platform/x11_display.h" -#include +#include #include +#include namespace Platform { -struct X11DisplayPrivate -{ +struct X11DisplayPrivate { Display* display; QMutex mutex; - X11DisplayPrivate() - : display(XOpenDisplay(nullptr)) - { - } - ~X11DisplayPrivate() - { + X11DisplayPrivate() : display(XOpenDisplay(nullptr)) {} + ~X11DisplayPrivate() { if (display) { XCloseDisplay(display); } } - static X11DisplayPrivate& getSingleInstance() - { + static X11DisplayPrivate& getSingleInstance() { // object created on-demand static X11DisplayPrivate singleInstance; return singleInstance; } }; -Display* X11Display::lock() -{ +Display* X11Display::lock() { X11DisplayPrivate& singleInstance = X11DisplayPrivate::getSingleInstance(); singleInstance.mutex.lock(); return singleInstance.display; } -void X11Display::unlock() -{ - X11DisplayPrivate::getSingleInstance().mutex.unlock(); -} -} +void X11Display::unlock() { X11DisplayPrivate::getSingleInstance().mutex.unlock(); } +} // namespace Platform diff --git a/src/modules/im/src/platform/x11_display.h b/src/modules/im/src/platform/x11_display.h index e57bc320..b46b8103 100644 --- a/src/modules/im/src/platform/x11_display.h +++ b/src/modules/im/src/platform/x11_display.h @@ -22,10 +22,10 @@ namespace Platform { namespace X11Display { Display* lock(); void unlock(); -} +} // namespace X11Display -} +} // namespace Platform -#endif // PLATFORM_X11_DISPLAY_H +#endif // PLATFORM_X11_DISPLAY_H -#endif // QTOX_PLATFORM_EXT +#endif // QTOX_PLATFORM_EXT diff --git a/src/modules/im/src/util/strongtype.h b/src/modules/im/src/util/strongtype.h index a455b85d..8b19d9df 100644 --- a/src/modules/im/src/util/strongtype.h +++ b/src/modules/im/src/util/strongtype.h @@ -15,84 +15,62 @@ #include -template -struct Addable -{ +template struct Addable { T operator+(T const& other) const { return static_cast(*this).get() + other.get(); }; }; -template -struct UnderlyingAddable -{ - T operator+(Underlying const& other) const - { +template struct UnderlyingAddable { + T operator+(Underlying const& other) const { return T(static_cast(*this).get() + other); }; }; -template -struct UnitlessDifferencable -{ - T operator-(Underlying const& other) const - { +template struct UnitlessDifferencable { + T operator-(Underlying const& other) const { return T(static_cast(*this).get() - other); }; - Underlying operator-(T const& other) const - { + Underlying operator-(T const& other) const { return static_cast(*this).get() - other.get(); } }; -template -struct Incrementable -{ - T& operator++() - { +template struct Incrementable { + T& operator++() { auto& underlying = static_cast(*this).get(); ++underlying; return static_cast(*this); } - T operator++(int) - { + T operator++(int) { auto ret = T(static_cast(*this)); ++(*this); return ret; } }; - -template -struct EqualityComparible -{ - bool operator==(const T& other) const { return static_cast(*this).get() == other.get(); }; - bool operator!=(const T& other) const - { +template struct EqualityComparible { + bool operator==(const T& other) const { + return static_cast(*this).get() == other.get(); + }; + bool operator!=(const T& other) const { return static_cast(*this).get() != other.get(); }; }; -template -struct Hashable -{ - friend uint qHash(const Hashable& key, uint seed = 0) - { +template struct Hashable { + friend uint qHash(const Hashable& key, uint seed = 0) { return qHash(static_cast(*key).get(), seed); } }; -template -struct Orderable : EqualityComparible -{ +template struct Orderable : EqualityComparible { bool operator<(const T& rhs) const { return static_cast(*this).get() < rhs.get(); } bool operator>(const T& rhs) const { return static_cast(*this).get() > rhs.get(); } bool operator>=(const T& rhs) const { return static_cast(*this).get() >= rhs.get(); } bool operator<=(const T& rhs) const { return static_cast(*this).get() <= rhs.get(); } }; - - /* This class facilitates creating a named class which wraps underlying POD, * avoiding implict casts and arithmetic of the underlying data. * Usage: Declare named type with arbitrary tag, then hook up Qt metatype for use @@ -104,22 +82,21 @@ struct Orderable : EqualityComparible */ template class... Properties> -class NamedType : public Properties, T>... -{ +class NamedType : public Properties, T>... { public: using UnderlyingType = T; NamedType() {} explicit NamedType(T const& value) : value_(value) {} T& get() { return value_; } - T const& get() const {return value_; } + T const& get() const { return value_; } + private: T value_; }; template class... Properties> -uint qHash(const NamedType& key, uint seed = 0) -{ +uint qHash(const NamedType& key, uint seed = 0) { return qHash(key.get(), seed); } -#endif // STRONGTYPE_H +#endif // STRONGTYPE_H diff --git a/src/modules/im/src/video/cameradevice.cpp b/src/modules/im/src/video/cameradevice.cpp index d8221851..67c82126 100644 --- a/src/modules/im/src/video/cameradevice.cpp +++ b/src/modules/im/src/video/cameradevice.cpp @@ -49,7 +49,6 @@ using AvFindInputFormatRet = decltype(av_find_input_format("")); * recursively, and must then be closed recursively */ - /** * @var const QString CameraDevice::devName * @brief Short name of the device @@ -61,21 +60,15 @@ using AvFindInputFormatRet = decltype(av_find_input_format("")); * @brief Number of times the device was opened */ - QHash CameraDevice::openDevices; QMutex CameraDevice::openDeviceLock, CameraDevice::iformatLock; static AvFindInputFormatRet idesktopFormat{nullptr}; static AvFindInputFormatRet iformat{nullptr}; CameraDevice::CameraDevice(const QString& devName, AVFormatContext* context) - : devName{devName} - , context{context} - , refcount{0} -{ -} + : devName{devName}, context{context}, refcount{0} {} -CameraDevice* CameraDevice::open(QString devName, AVDictionary** options) -{ +CameraDevice* CameraDevice::open(QString devName, AVDictionary** options) { openDeviceLock.lock(); AVFormatContext* fctx = nullptr; CameraDevice* dev = openDevices.value(devName); @@ -139,12 +132,11 @@ CameraDevice* CameraDevice::open(QString devName, AVDictionary** options) * @param mode Mode of device to open. * @return CameraDevice if the device could be opened, nullptr otherwise. */ -CameraDevice* CameraDevice::open(QString devName, VideoMode mode) -{ - qDebug() << "Open device:"<< devName; - qDebug() << "Vide mode is:["< 0.0f && mode.FPS <= 30) { FPS = mode.FPS; } else { - qWarning() << "Using default FPS:"<name == QString("video4linux2,v4l2") && mode) { av_dict_set(&options, "video_size", videoSize.c_str(), 0); av_dict_set(&options, "framerate", framerate.c_str(), 0); - const std::string pixelFormatStr = v4l2::getPixelFormatString(mode.pixel_format).toStdString(); + const std::string pixelFormatStr = + v4l2::getPixelFormatString(mode.pixel_format).toStdString(); // don't try to set a format string that doesn't exist if (pixelFormatStr != "unknown" && pixelFormatStr != "invalid") { const char* pixel_format = pixelFormatStr.c_str(); @@ -218,9 +213,9 @@ CameraDevice* CameraDevice::open(QString devName, VideoMode mode) av_dict_set(&options, "offset_x", offsetX.c_str(), 0); av_dict_set(&options, "offset_y", offsetY.c_str(), 0); } else if (iformat->name == QString("dshow") && mode) { - // 可能存在设置异常问题 - // av_dict_set(&options, "video_size", videoSize.c_str(), 0); - // av_dict_set(&options, "framerate", framerate.c_str(), 0); + // 可能存在设置异常问题 + // av_dict_set(&options, "video_size", videoSize.c_str(), 0); + // av_dict_set(&options, "framerate", framerate.c_str(), 0); } #endif #ifdef Q_OS_OSX @@ -251,8 +246,7 @@ CameraDevice* CameraDevice::open(QString devName, VideoMode mode) /** * @brief Opens the device again. Never fails */ -void CameraDevice::open() -{ +void CameraDevice::open() { qDebug() << "Open " << devName; ++refcount; } @@ -263,20 +257,18 @@ void CameraDevice::open() * @return True, if device finally deleted (closed last reference), * false otherwise (if other references exist). */ -bool CameraDevice::close() -{ +bool CameraDevice::close() { qDebug() << "Close " << devName; - if (--refcount > 0) - return false; + if (--refcount > 0) return false; openDeviceLock.lock(); openDevices.remove(devName); openDeviceLock.unlock(); avformat_close_input(&context); - qDebug() << "Device: " << devName << " closed."; + qDebug() << "Device: " << devName << " closed."; - delete this; - return true; + delete this; + return true; } /** @@ -284,17 +276,14 @@ bool CameraDevice::close() * @note Uses avdevice_list_devices * @return Raw device list */ -QVector> CameraDevice::getRawDeviceListGeneric() -{ +QVector> CameraDevice::getRawDeviceListGeneric() { QVector> devices; - if (!getDefaultInputFormat()) - return devices; + if (!getDefaultInputFormat()) return devices; // Alloc an input device context AVFormatContext* s; - if (!(s = avformat_alloc_context())) - return devices; + if (!(s = avformat_alloc_context())) return devices; if (!iformat->priv_class || !AV_IS_INPUT_DEVICE(iformat->priv_class->category)) { avformat_free_context(s); @@ -349,14 +338,12 @@ QVector> CameraDevice::getRawDeviceListGeneric() * @return A list of device names and descriptions. * The names are the first part of the pair and can be passed to open(QString). */ -QVector> CameraDevice::getDeviceList() -{ +QVector> CameraDevice::getDeviceList() { QVector> devices; devices.append({"none", QObject::tr("None", "No camera device set")}); - if (!getDefaultInputFormat()) - return devices; + if (!getDefaultInputFormat()) return devices; if (!iformat) ; @@ -386,16 +373,16 @@ QVector> CameraDevice::getDeviceList() dev += display.constData(); devices.push_back(QPair{ - dev, QObject::tr("Desktop", "Desktop as a camera input for screen sharing")}); + dev, QObject::tr("Desktop", "Desktop as a camera input for screen sharing")}); } if (idesktopFormat->name == QString("gdigrab")) devices.push_back(QPair{ - "gdigrab#desktop", - QObject::tr("Desktop", "Desktop as a camera input for screen sharing")}); + "gdigrab#desktop", + QObject::tr("Desktop", "Desktop as a camera input for screen sharing")}); } - for(auto &device: devices){ - qDebug() <<"device:"<> CameraDevice::getDeviceList() * @return The short name of the default device * This is either the device in the settings or the system default. */ -QString CameraDevice::getDefaultDeviceName() -{ +QString CameraDevice::getDefaultDeviceName() { QString defaultdev = Settings::getInstance().getVideoDev(); qDebug() << "defaultdev:" << defaultdev; - if (!getDefaultInputFormat()) - return defaultdev; + if (!getDefaultInputFormat()) return defaultdev; QVector> devlist = getDeviceList(); for (const QPair& device : devlist) - if (defaultdev == device.first) - return defaultdev; + if (defaultdev == device.first) return defaultdev; - if (devlist.isEmpty()) - return defaultdev; + if (devlist.isEmpty()) return defaultdev; if (devlist.size() > 1) { return devlist[1].first; @@ -431,8 +414,7 @@ QString CameraDevice::getDefaultDeviceName() * @param devName Device name to check. * @return True, if device is screen, false otherwise. */ -bool CameraDevice::isScreen(const QString& devName) -{ +bool CameraDevice::isScreen(const QString& devName) { return devName.startsWith("x11grab") || devName.startsWith("gdigrab"); } @@ -440,8 +422,7 @@ bool CameraDevice::isScreen(const QString& devName) * @brief Get list of resolutions and position of screens * @return Vector of avaliable screen modes with offset */ -QVector CameraDevice::getScreenModes() -{ +QVector CameraDevice::getScreenModes() { QList screens = QApplication::screens(); QVector result; @@ -463,8 +444,7 @@ QVector CameraDevice::getScreenModes() * @param devName Device name to get nodes from. * @return Vector of available modes for the device. */ -QVector CameraDevice::getVideoModes(QString devName) -{ +QVector CameraDevice::getVideoModes(QString devName) { Q_UNUSED(devName); if (!iformat) @@ -494,8 +474,7 @@ QVector CameraDevice::getVideoModes(QString devName) * @param pixel_format Pixel format to get the name from. * @return Name of the pixel format. */ -QString CameraDevice::getPixelFormatString(uint32_t pixel_format) -{ +QString CameraDevice::getPixelFormatString(uint32_t pixel_format) { #if USING_V4L return v4l2::getPixelFormatString(pixel_format); #else @@ -510,8 +489,7 @@ QString CameraDevice::getPixelFormatString(uint32_t pixel_format) * @return True if we prefer format a to b, * false otherwise (such as if there's no preference). */ -bool CameraDevice::betterPixelFormat(uint32_t a, uint32_t b) -{ +bool CameraDevice::betterPixelFormat(uint32_t a, uint32_t b) { #if USING_V4L return v4l2::betterPixelFormat(a, b); #else @@ -523,11 +501,9 @@ bool CameraDevice::betterPixelFormat(uint32_t a, uint32_t b) * @brief Sets CameraDevice::iformat to default. * @return True if success, false if failure. */ -bool CameraDevice::getDefaultInputFormat() -{ +bool CameraDevice::getDefaultInputFormat() { QMutexLocker locker(&iformatLock); - if (iformat) - return true; + if (iformat) return true; avdevice_register_all(); @@ -541,22 +517,17 @@ bool CameraDevice::getDefaultInputFormat() // Webcam input formats #if USING_V4L - if ((iformat = av_find_input_format("v4l2"))) - return true; + if ((iformat = av_find_input_format("v4l2"))) return true; #endif #ifdef Q_OS_WIN - if ((iformat = av_find_input_format("dshow"))) - return true; - if ((iformat = av_find_input_format("vfwcap"))) - return true; + if ((iformat = av_find_input_format("dshow"))) return true; + if ((iformat = av_find_input_format("vfwcap"))) return true; #endif #ifdef Q_OS_OSX - if ((iformat = av_find_input_format("avfoundation"))) - return true; - if ((iformat = av_find_input_format("qtkit"))) - return true; + if ((iformat = av_find_input_format("avfoundation"))) return true; + if ((iformat = av_find_input_format("qtkit"))) return true; #endif qWarning() << "No valid input format found"; diff --git a/src/modules/im/src/video/cameradevice.h b/src/modules/im/src/video/cameradevice.h index e62fcac5..fa3e30d1 100644 --- a/src/modules/im/src/video/cameradevice.h +++ b/src/modules/im/src/video/cameradevice.h @@ -10,24 +10,22 @@ * See the Mulan PubL v2 for more details. */ - #ifndef CAMERADEVICE_H #define CAMERADEVICE_H -#include "videomode.h" #include #include #include #include #include +#include "videomode.h" struct AVFormatContext; struct AVInputFormat; struct AVDeviceInfoList; struct AVDictionary; -class CameraDevice -{ +class CameraDevice { public: static CameraDevice* open(QString devName, VideoMode mode = VideoMode()); void open(); @@ -60,4 +58,4 @@ class CameraDevice static QMutex openDeviceLock, iformatLock; }; -#endif // CAMERADEVICE_H +#endif // CAMERADEVICE_H diff --git a/src/modules/im/src/video/camerasource.cpp b/src/modules/im/src/video/camerasource.cpp index 68a051ef..b444ccae 100644 --- a/src/modules/im/src/video/camerasource.cpp +++ b/src/modules/im/src/video/camerasource.cpp @@ -17,17 +17,17 @@ extern "C" { #include #include } -#include "cameradevice.h" -#include "camerasource.h" -#include "videoframe.h" -#include "src/persistence/settings.h" #include +#include #include #include #include #include #include -#include +#include "cameradevice.h" +#include "camerasource.h" +#include "src/persistence/settings.h" +#include "videoframe.h" /** * @class CameraSource @@ -85,11 +85,11 @@ extern "C" { CameraSource* CameraSource::instance{nullptr}; CameraSource::CameraSource() - : deviceThread{new QThread} - , deviceName{"none"} - , device{nullptr} - , mode(VideoMode()) - // clang-format off + : deviceThread{new QThread} + , deviceName{"none"} + , device{nullptr} + , mode(VideoMode()) + // clang-format off , cctx{nullptr} #if LIBAVCODEC_VERSION_INT < 3747941 , cctxOrig{nullptr} @@ -119,17 +119,14 @@ CameraSource::CameraSource() /** * @brief Returns the singleton instance. */ -CameraSource& CameraSource::getInstance() -{ +CameraSource& CameraSource::getInstance() { qDebug() << __func__; - if (!instance) - instance = new CameraSource(); + if (!instance) instance = new CameraSource(); instance->setupDefault(); return *instance; } -void CameraSource::destroyInstance() -{ +void CameraSource::destroyInstance() { qDebug() << __func__; if (instance) { @@ -142,8 +139,7 @@ void CameraSource::destroyInstance() * @brief Setup default device * @note If a device is already open, the source will seamlessly switch to the new device. */ -void CameraSource::setupDefault() -{ +void CameraSource::setupDefault() { QString deviceName = CameraDevice::getDefaultDeviceName(); qDebug() << "Setup default device:" << deviceName; bool isScreen = CameraDevice::isScreen(deviceName); @@ -160,8 +156,7 @@ void CameraSource::setupDefault() * @brief Change the device and mode. * @note If a device is already open, the source will seamlessly switch to the new device. */ -void CameraSource::setupDevice(const QString&deviceName_, const VideoMode& Mode) -{ +void CameraSource::setupDevice(const QString& deviceName_, const VideoMode& Mode) { qDebug() << "Setup device:" << deviceName_; if (QThread::currentThread() != deviceThread) { QMetaObject::invokeMethod(this, "setupDevice", Q_ARG(const QString&, deviceName_), @@ -192,13 +187,9 @@ void CameraSource::setupDevice(const QString&deviceName_, const VideoMode& Mode) } } -bool CameraSource::isNone() const -{ - return _isNone; -} +bool CameraSource::isNone() const { return _isNone; } -CameraSource::~CameraSource() -{ +CameraSource::~CameraSource() { QWriteLocker locker{&streamMutex}; QWriteLocker locker2{&deviceMutex}; @@ -224,8 +215,7 @@ CameraSource::~CameraSource() #endif if (device) { - for (int i = 0; i < subscriptions; ++i) - device->close(); + for (int i = 0; i < subscriptions; ++i) device->close(); device = nullptr; } @@ -233,20 +223,17 @@ CameraSource::~CameraSource() locker.unlock(); // Synchronize with our stream thread - while (streamFuture.isRunning()) - QThread::yieldCurrentThread(); + while (streamFuture.isRunning()) QThread::yieldCurrentThread(); } -void CameraSource::subscribe() -{ +void CameraSource::subscribe() { QWriteLocker locker{&deviceMutex}; ++subscriptions; openDevice(); } -void CameraSource::unsubscribe() -{ +void CameraSource::unsubscribe() { QWriteLocker locker{&deviceMutex}; --subscriptions; @@ -259,8 +246,7 @@ void CameraSource::unsubscribe() * @brief Opens the video device and starts streaming. * @note Callers must own the biglock. */ -void CameraSource::openDevice() -{ +void CameraSource::openDevice() { if (QThread::currentThread() != deviceThread) { QMetaObject::invokeMethod(this, "openDevice"); return; @@ -273,12 +259,11 @@ void CameraSource::openDevice() qDebug() << "Opening device" << deviceName << "subscriptions:" << subscriptions; - -// if (device) { -// device->open(); -// emit openFailed(); -// return; -// } + // if (device) { + // device->open(); + // emit openFailed(); + // return; + // } // We need to create a new CameraDevice device = CameraDevice::open(deviceName, mode); @@ -332,7 +317,6 @@ void CameraSource::openDevice() return; } - #if LIBAVCODEC_VERSION_INT < 3747941 // Copy context, since we apparently aren't allowed to use the original cctx = avcodec_alloc_context3(codec); @@ -366,8 +350,7 @@ void CameraSource::openDevice() streamFuture = QtConcurrent::run(std::bind(&CameraSource::stream, this)); // Synchronize with our stream thread - while (!streamFuture.isRunning()) - QThread::yieldCurrentThread(); + while (!streamFuture.isRunning()) QThread::yieldCurrentThread(); emit deviceOpened(); } @@ -376,8 +359,7 @@ void CameraSource::openDevice() * @brief Closes the video device and stops streaming. * @note Callers must own the biglock. */ -void CameraSource::closeDevice() -{ +void CameraSource::closeDevice() { if (QThread::currentThread() != deviceThread) { QMetaObject::invokeMethod(this, "closeDevice"); return; @@ -400,7 +382,7 @@ void CameraSource::closeDevice() avcodec_close(cctxOrig); cctxOrig = nullptr; #endif - if(device) { + if (device) { device->close(); device = nullptr; } @@ -410,8 +392,7 @@ void CameraSource::closeDevice() * @brief Blocking. Decodes video stream and emits new frames. * @note Designed to run in its own thread. */ -void CameraSource::stream() -{ +void CameraSource::stream() { auto streamLoop = [this]() { AVPacket packet; if (av_read_frame(device->context, &packet) != 0) { @@ -456,8 +437,7 @@ void CameraSource::stream() av_packet_unref(&packet); }; - forever - { + forever { QReadLocker locker{&streamMutex}; // Exit if device is no longer valid diff --git a/src/modules/im/src/video/camerasource.h b/src/modules/im/src/video/camerasource.h index a3dd8d74..78dc01cd 100644 --- a/src/modules/im/src/video/camerasource.h +++ b/src/modules/im/src/video/camerasource.h @@ -13,20 +13,19 @@ #ifndef CAMERA_H #define CAMERA_H -#include "src/video/videomode.h" -#include "src/video/videosource.h" #include #include #include #include #include #include +#include "src/video/videomode.h" +#include "src/video/videosource.h" class CameraDevice; struct AVCodecContext; -class CameraSource : public VideoSource -{ +class CameraSource : public VideoSource { Q_OBJECT public: @@ -40,7 +39,7 @@ class CameraSource : public VideoSource virtual void unsubscribe() override; public slots: - void setupDevice(const QString&deviceName_, const VideoMode& mode); + void setupDevice(const QString& deviceName_, const VideoMode& mode); signals: void deviceOpened(); @@ -76,4 +75,4 @@ private slots: static CameraSource* instance; }; -#endif // CAMERA_H +#endif // CAMERA_H diff --git a/src/modules/im/src/video/corevideosource.cpp b/src/modules/im/src/video/corevideosource.cpp index d7736351..baf57c35 100644 --- a/src/modules/im/src/video/corevideosource.cpp +++ b/src/modules/im/src/video/corevideosource.cpp @@ -15,9 +15,9 @@ extern "C" { #include } +#include "../core/toxcall.h" #include "corevideosource.h" #include "videoframe.h" -#include "../core/toxcall.h" /** * @class CoreVideoSource @@ -37,21 +37,15 @@ extern "C" { * @note Only CoreAV should create a CoreVideoSource since * only CoreAV can push images to it. */ -CoreVideoSource::CoreVideoSource() - : subscribers{0} - , deleteOnClose{false} - , stopped{false} -{ -} +CoreVideoSource::CoreVideoSource() : subscribers{0}, deleteOnClose{false}, stopped{false} {} /** * @brief Makes a copy of the vpx_image_t and emits it as a new VideoFrame. * @param vpxframe Frame to copy. */ -void CoreVideoSource::pushFrame(const vpx_image_t* vpxframe) -{ - //if (stopped) - // return; +void CoreVideoSource::pushFrame(const vpx_image_t* vpxframe) { + // if (stopped) + // return; QMutexLocker locker(&biglock); @@ -59,20 +53,18 @@ void CoreVideoSource::pushFrame(const vpx_image_t* vpxframe) int width = vpxframe->d_w; int height = vpxframe->d_h; - if (subscribers <= 0) - return; + if (subscribers <= 0) return; AVFrame* avframe = av_frame_alloc(); - if (!avframe) - return; + if (!avframe) return; avframe->width = width; avframe->height = height; avframe->format = AV_PIX_FMT_YUV420P; - int bufSize = - av_image_alloc(avframe->data, avframe->linesize, width, height, - static_cast(AV_PIX_FMT_YUV420P), VideoFrame::dataAlignment); + int bufSize = av_image_alloc(avframe->data, avframe->linesize, width, height, + static_cast(AV_PIX_FMT_YUV420P), + VideoFrame::dataAlignment); if (bufSize < 0) { av_frame_free(&avframe); @@ -88,7 +80,7 @@ void CoreVideoSource::pushFrame(const vpx_image_t* vpxframe) for (int j = 0; j < size; ++j) { uint8_t* dst = avframe->data[i] + dstStride * j; uint8_t* src = vpxframe->planes[i] + srcStride * j; - //TODO: windows10 下在渲染自己视频时存在崩溃可能 + // TODO: windows10 下在渲染自己视频时存在崩溃可能 memcpy(dst, src, minStride); } } @@ -97,14 +89,12 @@ void CoreVideoSource::pushFrame(const vpx_image_t* vpxframe) emit frameAvailable(vframe); } -void CoreVideoSource::subscribe() -{ +void CoreVideoSource::subscribe() { QMutexLocker locker(&biglock); ++subscribers; } -void CoreVideoSource::unsubscribe() -{ +void CoreVideoSource::unsubscribe() { biglock.lock(); if (--subscribers == 0) { if (deleteOnClose) { @@ -121,8 +111,7 @@ void CoreVideoSource::unsubscribe() * @brief Setup delete on close * @param If true, self-delete after the last suscriber is gone */ -void CoreVideoSource::setDeleteOnClose(bool newstate) -{ +void CoreVideoSource::setDeleteOnClose(bool newstate) { QMutexLocker locker(&biglock); deleteOnClose = newstate; } @@ -133,15 +122,13 @@ void CoreVideoSource::setDeleteOnClose(bool newstate) * * Stopping the source will block any pushFrame calls from doing anything */ -void CoreVideoSource::stopSource() -{ +void CoreVideoSource::stopSource() { QMutexLocker locker(&biglock); stopped = true; emit sourceStopped(); } -void CoreVideoSource::restartSource() -{ +void CoreVideoSource::restartSource() { QMutexLocker locker(&biglock); stopped = false; } diff --git a/src/modules/im/src/video/corevideosource.h b/src/modules/im/src/video/corevideosource.h index 62d08611..821e8b50 100644 --- a/src/modules/im/src/video/corevideosource.h +++ b/src/modules/im/src/video/corevideosource.h @@ -10,18 +10,16 @@ * See the Mulan PubL v2 for more details. */ - #ifndef COREVIDEOSOURCE_H #define COREVIDEOSOURCE_H -#include "videosource.h" #include #include +#include "videosource.h" struct vpx_image; -class CoreVideoSource : public VideoSource -{ +class CoreVideoSource : public VideoSource { Q_OBJECT public: CoreVideoSource(); @@ -31,8 +29,6 @@ class CoreVideoSource : public VideoSource virtual void unsubscribe() override; private: - - void pushFrame(const vpx_image* frame); void setDeleteOnClose(bool newstate); @@ -49,4 +45,4 @@ class CoreVideoSource : public VideoSource friend class ToxFriendCall; }; -#endif // COREVIDEOSOURCE_H +#endif // COREVIDEOSOURCE_H diff --git a/src/modules/im/src/video/genericnetcamview.cpp b/src/modules/im/src/video/genericnetcamview.cpp index eec01ce4..65391889 100644 --- a/src/modules/im/src/video/genericnetcamview.cpp +++ b/src/modules/im/src/video/genericnetcamview.cpp @@ -13,25 +13,22 @@ #include "genericnetcamview.h" #include -#include #include #include #include #include +#include #include -namespace -{ +namespace { const auto BTN_STATE_NONE = QVariant("none"); const auto BTN_STATE_RED = QVariant("red"); const int BTN_PANEL_HEIGHT = 55; const int BTN_PANEL_WIDTH = 250; const auto BTN_STYLE_SHEET_PATH = QStringLiteral("chatForm/fullScreenButtons.css"); -} +} // namespace -GenericNetCamView::GenericNetCamView(QWidget* parent) - : QWidget(parent) -{ +GenericNetCamView::GenericNetCamView(QWidget* parent) : QWidget(parent) { verLayout = new QVBoxLayout(this); setWindowTitle(tr("Tox video")); @@ -45,8 +42,10 @@ GenericNetCamView::GenericNetCamView(QWidget* parent) buttonLayout->addWidget(toggleMessagesButton); buttonLayout->addWidget(enterFullScreenButton); - connect(toggleMessagesButton, &QPushButton::clicked, this, &GenericNetCamView::showMessageClicked); - connect(enterFullScreenButton, &QPushButton::clicked, this, &GenericNetCamView::toggleFullScreen); + connect(toggleMessagesButton, &QPushButton::clicked, this, + &GenericNetCamView::showMessageClicked); + connect(enterFullScreenButton, &QPushButton::clicked, this, + &GenericNetCamView::toggleFullScreen); verLayout->addLayout(buttonLayout); verLayout->setContentsMargins(0, 0, 0, 0); @@ -76,11 +75,13 @@ GenericNetCamView::GenericNetCamView(QWidget* parent) exitFullScreenButton = createButton("exitFullScreenButton", "none"); exitFullScreenButton->setToolTip(tr("Exit full screen")); - connect(videoPreviewButton, &QPushButton::clicked, this, &GenericNetCamView::toggleVideoPreview); + connect(videoPreviewButton, &QPushButton::clicked, this, + &GenericNetCamView::toggleVideoPreview); connect(volumeButton, &QPushButton::clicked, this, &GenericNetCamView::volMuteToggle); connect(microphoneButton, &QPushButton::clicked, this, &GenericNetCamView::micMuteToggle); connect(endVideoButton, &QPushButton::clicked, this, &GenericNetCamView::endVideoCall); - connect(exitFullScreenButton, &QPushButton::clicked, this, &GenericNetCamView::toggleFullScreen); + connect(exitFullScreenButton, &QPushButton::clicked, this, + &GenericNetCamView::toggleFullScreen); buttonPanelLayout->addStretch(); buttonPanelLayout->addWidget(videoPreviewButton); @@ -91,8 +92,7 @@ GenericNetCamView::GenericNetCamView(QWidget* parent) buttonPanelLayout->addStretch(); } -QSize GenericNetCamView::getSurfaceMinSize() -{ +QSize GenericNetCamView::getSurfaceMinSize() { QSize surfaceSize = videoSurface->minimumSize(); QSize buttonSize = toggleMessagesButton->size(); QSize panelSize(0, 45); @@ -100,8 +100,7 @@ QSize GenericNetCamView::getSurfaceMinSize() return surfaceSize + buttonSize + panelSize; } -void GenericNetCamView::setShowMessages(bool show, bool notify) -{ +void GenericNetCamView::setShowMessages(bool show, bool notify) { if (!show) { toggleMessagesButton->setText(tr("Hide Messages")); toggleMessagesButton->setIcon(QIcon()); @@ -115,8 +114,7 @@ void GenericNetCamView::setShowMessages(bool show, bool notify) } } -void GenericNetCamView::toggleFullScreen() -{ +void GenericNetCamView::toggleFullScreen() { if (isFullScreen()) { exitFullScreen(); } else { @@ -124,8 +122,7 @@ void GenericNetCamView::toggleFullScreen() } } -void GenericNetCamView::enterFullScreen() -{ +void GenericNetCamView::enterFullScreen() { setWindowFlags(Qt::Window | Qt::CustomizeWindowHint | Qt::FramelessWindowHint); showFullScreen(); enterFullScreenButton->hide(); @@ -136,14 +133,14 @@ void GenericNetCamView::enterFullScreen() const QRect screenSize = QApplication::desktop()->screenGeometry(this); #endif buttonPanel->setGeometry((screenSize.width() / 2) - buttonPanel->width() / 2, - screenSize.height() - BTN_PANEL_HEIGHT - 25, BTN_PANEL_WIDTH, BTN_PANEL_HEIGHT); + screenSize.height() - BTN_PANEL_HEIGHT - 25, BTN_PANEL_WIDTH, + BTN_PANEL_HEIGHT); buttonPanel->show(); buttonPanel->activateWindow(); buttonPanel->raise(); } -void GenericNetCamView::exitFullScreen() -{ +void GenericNetCamView::exitFullScreen() { setWindowFlags(Qt::Widget); showNormal(); buttonPanel->hide(); @@ -151,20 +148,17 @@ void GenericNetCamView::exitFullScreen() toggleMessagesButton->show(); } -void GenericNetCamView::endVideoCall() -{ +void GenericNetCamView::endVideoCall() { toggleFullScreen(); emit videoCallEnd(); } -void GenericNetCamView::toggleVideoPreview() -{ +void GenericNetCamView::toggleVideoPreview() { toggleButtonState(videoPreviewButton); emit videoPreviewToggle(); } -QPushButton *GenericNetCamView::createButton(const QString& name, const QString& state) -{ +QPushButton* GenericNetCamView::createButton(const QString& name, const QString& state) { QPushButton* btn = new QPushButton(); btn->setAttribute(Qt::WA_LayoutUsesWidgetRect); btn->setObjectName(name); @@ -174,18 +168,15 @@ QPushButton *GenericNetCamView::createButton(const QString& name, const QString& return btn; } -void GenericNetCamView::updateMuteVolButton(bool isMuted) -{ +void GenericNetCamView::updateMuteVolButton(bool isMuted) { updateButtonState(volumeButton, !isMuted); } -void GenericNetCamView::updateMuteMicButton(bool isMuted) -{ +void GenericNetCamView::updateMuteMicButton(bool isMuted) { updateButtonState(microphoneButton, !isMuted); } -void GenericNetCamView::toggleButtonState(QPushButton* btn) -{ +void GenericNetCamView::toggleButtonState(QPushButton* btn) { if (btn->property("state") == BTN_STATE_RED) { btn->setProperty("state", BTN_STATE_NONE); } else { @@ -195,8 +186,7 @@ void GenericNetCamView::toggleButtonState(QPushButton* btn) btn->setStyleSheet(Style::getStylesheet(BTN_STYLE_SHEET_PATH)); } -void GenericNetCamView::updateButtonState(QPushButton* btn, bool active) -{ +void GenericNetCamView::updateButtonState(QPushButton* btn, bool active) { if (active) { btn->setProperty("state", BTN_STATE_NONE); } else { @@ -206,16 +196,14 @@ void GenericNetCamView::updateButtonState(QPushButton* btn, bool active) btn->setStyleSheet(Style::getStylesheet(BTN_STYLE_SHEET_PATH)); } -void GenericNetCamView::keyPressEvent(QKeyEvent *event) -{ +void GenericNetCamView::keyPressEvent(QKeyEvent* event) { int key = event->key(); if (key == Qt::Key_Escape && isFullScreen()) { exitFullScreen(); } } -void GenericNetCamView::closeEvent(QCloseEvent *event) -{ +void GenericNetCamView::closeEvent(QCloseEvent* event) { exitFullScreen(); event->ignore(); } diff --git a/src/modules/im/src/video/genericnetcamview.h b/src/modules/im/src/video/genericnetcamview.h index d458f91a..5fb4a130 100644 --- a/src/modules/im/src/video/genericnetcamview.h +++ b/src/modules/im/src/video/genericnetcamview.h @@ -21,8 +21,7 @@ #include "src/lib/settings/style.h" #include "src/video/videosurface.h" -class GenericNetCamView : public QWidget -{ +class GenericNetCamView : public QWidget { Q_OBJECT public: explicit GenericNetCamView(QWidget* parent); @@ -64,8 +63,8 @@ public slots: void toggleVideoPreview(); void toggleButtonState(QPushButton* btn); void updateButtonState(QPushButton* btn, bool active); - void keyPressEvent(QKeyEvent *event) override; - void closeEvent(QCloseEvent *event) override; + void keyPressEvent(QKeyEvent* event) override; + void closeEvent(QCloseEvent* event) override; }; -#endif // GENERICNETCAMVIEW_H +#endif // GENERICNETCAMVIEW_H diff --git a/src/modules/im/src/video/groupnetcamview.cpp b/src/modules/im/src/video/groupnetcamview.cpp index f1d64c59..76c7d665 100644 --- a/src/modules/im/src/video/groupnetcamview.cpp +++ b/src/modules/im/src/video/groupnetcamview.cpp @@ -11,6 +11,11 @@ */ #include "groupnetcamview.h" +#include +#include +#include +#include +#include #include "src/audio/audio.h" #include "src/core/FriendId.h" #include "src/core/core.h" @@ -20,19 +25,13 @@ #include "src/persistence/profile.h" #include "src/video/videosurface.h" #include "src/widget/tool/croppinglabel.h" -#include -#include -#include -#include -#include #include -class LabeledVideo : public QFrame -{ +class LabeledVideo : public QFrame { public: - LabeledVideo(const QPixmap& avatar, QString fontColorString, QWidget* parent = nullptr, bool expanding = true) - : QFrame(parent) - { + LabeledVideo(const QPixmap& avatar, QString fontColorString, QWidget* parent = nullptr, + bool expanding = true) + : QFrame(parent) { qDebug() << "Created expanding? " << expanding; videoSurface = new VideoSurface(avatar, nullptr, expanding); videoSurface->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); @@ -52,23 +51,13 @@ class LabeledVideo : public QFrame ~LabeledVideo() {} - VideoSurface* getVideoSurface() const - { - return videoSurface; - } + VideoSurface* getVideoSurface() const { return videoSurface; } - void setText(const QString& text) - { - label->setText(text); - } + void setText(const QString& text) { label->setText(text); } - QString getText() const - { - return label->text(); - } + QString getText() const { return label->text(); } - void setActive(bool active = true) - { + void setActive(bool active = true) { if (active) setStyleSheet("QFrame { background-color: #414141; border-radius: 10px; }"); else @@ -76,15 +65,13 @@ class LabeledVideo : public QFrame } protected: - void resizeEvent(QResizeEvent* event) final override - { + void resizeEvent(QResizeEvent* event) final override { updateSize(); QWidget::resizeEvent(event); } private slots: - void updateSize() - { + void updateSize() { if (videoSurface->isExpanding()) { int width = videoSurface->height() * videoSurface->getRatio(); videoSurface->setMinimumWidth(width); @@ -98,9 +85,7 @@ private slots: }; GroupNetCamView::GroupNetCamView(QString group, QWidget* parent) - : GenericNetCamView(parent) - , group(group) -{ + : GenericNetCamView(parent), group(group) { videoLabelSurface = new LabeledVideo(QPixmap(), "white", this, false); videoSurface = videoLabelSurface->getVideoSurface(); videoSurface->setMinimumHeight(256); @@ -117,7 +102,8 @@ GroupNetCamView::GroupNetCamView(QString group, QWidget* parent) verLayout->insertWidget(0, splitter, 1); splitter->addWidget(videoLabelSurface); splitter->setStyleSheet( - "QSplitter { background-color: black; } QSplitter::handle { background-color: black; }"); + "QSplitter { background-color: black; } QSplitter::handle { background-color: black; " + "}"); QScrollArea* scrollArea = new QScrollArea(); scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); @@ -153,35 +139,32 @@ GroupNetCamView::GroupNetCamView(QString group, QWidget* parent) setActive(); }); -// connect(Nexus::getProfile(), &Profile::friendAvatarChanged, this, -// &GroupNetCamView::friendAvatarChanged); + // connect(Nexus::getProfile(), &Profile::friendAvatarChanged, this, + // &GroupNetCamView::friendAvatarChanged); selfVideoSurface->setText(Core::getInstance()->getUsername()); } -void GroupNetCamView::clearPeers() -{ +void GroupNetCamView::clearPeers() { for (const auto& peerPk : videoList.keys()) { removePeer(peerPk); } } -void GroupNetCamView::addPeer(const QString& peer, const QString& name) -{ +void GroupNetCamView::addPeer(const QString& peer, const QString& name) { qDebug() << __func__; -// QPixmap groupAvatar = Nexus::getProfile()->loadAvatar(peer); -// LabeledVideo* labeledVideo = new LabeledVideo(groupAvatar, "black", this); -// labeledVideo->setText(name); -// horLayout->insertWidget(horLayout->count() - 1, labeledVideo); -// PeerVideo peerVideo; -// peerVideo.video = labeledVideo; -// videoList.insert(peer, peerVideo); - -// setActive(); + // QPixmap groupAvatar = Nexus::getProfile()->loadAvatar(peer); + // LabeledVideo* labeledVideo = new LabeledVideo(groupAvatar, "black", this); + // labeledVideo->setText(name); + // horLayout->insertWidget(horLayout->count() - 1, labeledVideo); + // PeerVideo peerVideo; + // peerVideo.video = labeledVideo; + // videoList.insert(peer, peerVideo); + + // setActive(); } -void GroupNetCamView::removePeer(const QString& peer) -{ +void GroupNetCamView::removePeer(const QString& peer) { auto peerVideo = videoList.find(peer); if (peerVideo != videoList.end()) { @@ -194,13 +177,9 @@ void GroupNetCamView::removePeer(const QString& peer) } } -void GroupNetCamView::onUpdateActivePeer() -{ - setActive(); -} +void GroupNetCamView::onUpdateActivePeer() { setActive(); } -void GroupNetCamView::setActive(const FriendId& peer) -{ +void GroupNetCamView::setActive(const FriendId& peer) { if (!peer.isValid()) { videoLabelSurface->setText(selfVideoSurface->getText()); activePeer = -1; @@ -230,8 +209,7 @@ void GroupNetCamView::setActive(const FriendId& peer) #endif } -void GroupNetCamView::friendAvatarChanged(QString friendPk, const QPixmap& pixmap) -{ +void GroupNetCamView::friendAvatarChanged(QString friendPk, const QPixmap& pixmap) { auto peerVideo = videoList.find(friendPk); if (peerVideo != videoList.end()) { peerVideo.value().video->getVideoSurface()->setAvatar(pixmap); diff --git a/src/modules/im/src/video/groupnetcamview.h b/src/modules/im/src/video/groupnetcamview.h index 7c52c125..a4053f5c 100644 --- a/src/modules/im/src/video/groupnetcamview.h +++ b/src/modules/im/src/video/groupnetcamview.h @@ -22,8 +22,7 @@ class LabeledVideo; class QHBoxLayout; -class GroupNetCamView : public GenericNetCamView -{ +class GroupNetCamView : public GenericNetCamView { public: GroupNetCamView(QString group, QWidget* parent = nullptr); void clearPeers(); @@ -35,8 +34,7 @@ private slots: void friendAvatarChanged(QString friendPk, const QPixmap& pixmap); private: - struct PeerVideo - { + struct PeerVideo { LabeledVideo* video; }; @@ -50,4 +48,4 @@ private slots: QString group; }; -#endif // GROUPNETCAMVIEW_H +#endif // GROUPNETCAMVIEW_H diff --git a/src/modules/im/src/video/ivideosettings.h b/src/modules/im/src/video/ivideosettings.h index b6b9f5c1..5348c725 100644 --- a/src/modules/im/src/video/ivideosettings.h +++ b/src/modules/im/src/video/ivideosettings.h @@ -15,8 +15,8 @@ #include "src/base/interface.h" -#include #include +#include class IVideoSettings { public: @@ -44,4 +44,4 @@ class IVideoSettings { DECLARE_SIGNAL(camVideoFPSChanged, unsigned short fps); }; -#endif // I_VIDEO_SETTINGS_H +#endif // I_VIDEO_SETTINGS_H diff --git a/src/modules/im/src/video/netcamview.cpp b/src/modules/im/src/video/netcamview.cpp index 3234cf02..743562e3 100644 --- a/src/modules/im/src/video/netcamview.cpp +++ b/src/modules/im/src/video/netcamview.cpp @@ -11,26 +11,22 @@ */ #include "netcamview.h" -#include "src/video/corevideosource.h" +#include +#include +#include +#include #include "src/core/core.h" #include "src/friendlist.h" #include "src/model/friend.h" #include "src/nexus.h" #include "src/persistence/profile.h" #include "src/persistence/settings.h" +#include "src/video/corevideosource.h" #include "src/video/videosurface.h" #include "src/widget/tool/movablewidget.h" -#include -#include -#include -#include NetCamView::NetCamView(FriendId friendPk, QWidget* parent) - : GenericNetCamView(parent) - , selfFrame{nullptr} - , friendPk{friendPk} - , e(false) -{ + : GenericNetCamView(parent), selfFrame{nullptr}, friendPk{friendPk}, e(false) { videoSurface = new VideoSurface(Nexus::getProfile()->loadAvatar(friendPk), this); videoSurface->setMinimumHeight(256); @@ -49,13 +45,12 @@ NetCamView::NetCamView(FriendId friendPk, QWidget* parent) frameLayout->setMargin(0); updateRatio(); - connections += - connect(selfVideoSurface, &VideoSurface::ratioChanged, [this](){ - selfFrame->setMinimumWidth(selfFrame->minimumHeight() * selfVideoSurface->getRatio()); - QRect boundingRect = selfVideoSurface->getBoundingRect(); - updateFrameSize(boundingRect.size()); - selfFrame->resetBoundary(boundingRect); - }); + connections += connect(selfVideoSurface, &VideoSurface::ratioChanged, [this]() { + selfFrame->setMinimumWidth(selfFrame->minimumHeight() * selfVideoSurface->getRatio()); + QRect boundingRect = selfVideoSurface->getBoundingRect(); + updateFrameSize(boundingRect.size()); + selfFrame->resetBoundary(boundingRect); + }); connections += connect(videoSurface, &VideoSurface::boundaryChanged, [this]() { QRect boundingRect = videoSurface->getBoundingRect(); @@ -64,7 +59,7 @@ NetCamView::NetCamView(FriendId friendPk, QWidget* parent) }); connections += connect(videoSurface, &VideoSurface::ratioChanged, [this]() { - selfFrame->setMinimumWidth(selfFrame->minimumHeight() * videoSurface->getRatio()); + selfFrame->setMinimumWidth(selfFrame->minimumHeight() * videoSurface->getRatio()); QRect boundingRect = videoSurface->getBoundingRect(); updateFrameSize(boundingRect.size()); selfFrame->resetBoundary(boundingRect); @@ -75,69 +70,53 @@ NetCamView::NetCamView(FriendId friendPk, QWidget* parent) connections += connect(Nexus::getProfile(), &Profile::friendAvatarChanged, [this](FriendId friendPk, const QPixmap& pixmap) { - if (this->friendPk == friendPk) - videoSurface->setAvatar(pixmap); + if (this->friendPk == friendPk) videoSurface->setAvatar(pixmap); }); QRect videoSize = Settings::getInstance().getCamVideoRes(); qDebug() << "SIZER" << videoSize; } -NetCamView::~NetCamView() -{ - for (QMetaObject::Connection conn : connections) - disconnect(conn); +NetCamView::~NetCamView() { + for (QMetaObject::Connection conn : connections) disconnect(conn); } -void NetCamView::show(VideoSource* source, const QString& title) -{ +void NetCamView::show(VideoSource* source, const QString& title) { setSource(source); setTitle(title); QWidget::show(); const auto av = CoreAV::getInstance(); selfVideoSurface->setSource(av->getSelfVideoSource()); - } -void NetCamView::hide() -{ +void NetCamView::hide() { setSource(nullptr); selfVideoSurface->setSource(nullptr); - if (selfFrame) - selfFrame->deleteLater(); + if (selfFrame) selfFrame->deleteLater(); selfFrame = nullptr; QWidget::hide(); } -void NetCamView::setSource(VideoSource* s) -{ - videoSurface->setSource(s); -} +void NetCamView::setSource(VideoSource* s) { videoSurface->setSource(s); } -void NetCamView::setTitle(const QString& title) -{ - setWindowTitle(title); -} +void NetCamView::setTitle(const QString& title) { setWindowTitle(title); } -void NetCamView::showEvent(QShowEvent* event) -{ +void NetCamView::showEvent(QShowEvent* event) { Q_UNUSED(event); selfFrame->resetBoundary(videoSurface->getBoundingRect()); } -void NetCamView::updateRatio() -{ +void NetCamView::updateRatio() { selfFrame->setMinimumWidth(selfFrame->minimumHeight() * selfVideoSurface->getRatio()); selfFrame->setRatio(selfVideoSurface->getRatio()); selfFrame->update(); } -void NetCamView::updateFrameSize(QSize size) -{ +void NetCamView::updateFrameSize(QSize size) { selfFrame->setMaximumSize(size.height() / 3, size.width() / 3); if (selfFrame->maximumWidth() > selfFrame->maximumHeight()) @@ -146,8 +125,7 @@ void NetCamView::updateFrameSize(QSize size) selfFrame->setMaximumHeight(selfFrame->maximumWidth() / selfVideoSurface->getRatio()); } -void NetCamView::toggleVideoPreview() -{ +void NetCamView::toggleVideoPreview() { if (selfFrame->isHidden()) { selfFrame->show(); } else { diff --git a/src/modules/im/src/video/netcamview.h b/src/modules/im/src/video/netcamview.h index 5c000670..dcb2e303 100644 --- a/src/modules/im/src/video/netcamview.h +++ b/src/modules/im/src/video/netcamview.h @@ -13,9 +13,9 @@ #ifndef NETCAMVIEW_H #define NETCAMVIEW_H +#include #include "genericnetcamview.h" #include "src/core/FriendId.h" -#include struct vpx_image; @@ -24,8 +24,7 @@ class VideoSource; class QFrame; class MovableWidget; -class NetCamView : public GenericNetCamView -{ +class NetCamView : public GenericNetCamView { Q_OBJECT public: @@ -55,4 +54,4 @@ private slots: QVector connections; }; -#endif // NETCAMVIEW_H +#endif // NETCAMVIEW_H diff --git a/src/modules/im/src/video/videoframe.cpp b/src/modules/im/src/video/videoframe.cpp index 863a3aa0..ba4043fa 100644 --- a/src/modules/im/src/video/videoframe.cpp +++ b/src/modules/im/src/video/videoframe.cpp @@ -13,9 +13,9 @@ #include "videoframe.h" extern "C" { +#include #include #include -#include } /** @@ -70,8 +70,9 @@ extern "C" { VideoFrame::AtomicIDType VideoFrame::frameIDs{0}; std::unordered_map VideoFrame::mutexMap{}; -std::unordered_map>> - VideoFrame::refsMap{}; +std::unordered_map>> + VideoFrame::refsMap{}; QReadWriteLock VideoFrame::refsLock{}; @@ -86,65 +87,60 @@ QReadWriteLock VideoFrame::refsLock{}; */ VideoFrame::VideoFrame(IDType sourceID, AVFrame* sourceFrame, QRect dimensions, int pixFmt, bool freeSourceFrame) - : frameID(frameIDs++) - , sourceID(sourceID) - , sourceDimensions(dimensions) - , sourceFrameKey(getFrameKey(dimensions.size(), pixFmt, sourceFrame->linesize[0])) - , freeSourceFrame(freeSourceFrame) -{ - + : frameID(frameIDs++) + , sourceID(sourceID) + , sourceDimensions(dimensions) + , sourceFrameKey(getFrameKey(dimensions.size(), pixFmt, sourceFrame->linesize[0])) + , freeSourceFrame(freeSourceFrame) { // We override the pixel format in the case a deprecated one is used switch (pixFmt) { - case AV_PIX_FMT_YUVJ420P: { - sourcePixelFormat = AV_PIX_FMT_YUV420P; - sourceFrame->color_range = AVCOL_RANGE_MPEG; - break; - } + case AV_PIX_FMT_YUVJ420P: { + sourcePixelFormat = AV_PIX_FMT_YUV420P; + sourceFrame->color_range = AVCOL_RANGE_MPEG; + break; + } - case AV_PIX_FMT_YUVJ411P: { - sourcePixelFormat = AV_PIX_FMT_YUV411P; - sourceFrame->color_range = AVCOL_RANGE_MPEG; - break; - } + case AV_PIX_FMT_YUVJ411P: { + sourcePixelFormat = AV_PIX_FMT_YUV411P; + sourceFrame->color_range = AVCOL_RANGE_MPEG; + break; + } - case AV_PIX_FMT_YUVJ422P: { - sourcePixelFormat = AV_PIX_FMT_YUV422P; - sourceFrame->color_range = AVCOL_RANGE_MPEG; - break; - } + case AV_PIX_FMT_YUVJ422P: { + sourcePixelFormat = AV_PIX_FMT_YUV422P; + sourceFrame->color_range = AVCOL_RANGE_MPEG; + break; + } - case AV_PIX_FMT_YUVJ444P: { - sourcePixelFormat = AV_PIX_FMT_YUV444P; - sourceFrame->color_range = AVCOL_RANGE_MPEG; - break; - } + case AV_PIX_FMT_YUVJ444P: { + sourcePixelFormat = AV_PIX_FMT_YUV444P; + sourceFrame->color_range = AVCOL_RANGE_MPEG; + break; + } - case AV_PIX_FMT_YUVJ440P: { - sourcePixelFormat = AV_PIX_FMT_YUV440P; - sourceFrame->color_range = AVCOL_RANGE_MPEG; - break; - } + case AV_PIX_FMT_YUVJ440P: { + sourcePixelFormat = AV_PIX_FMT_YUV440P; + sourceFrame->color_range = AVCOL_RANGE_MPEG; + break; + } - default: { - sourcePixelFormat = pixFmt; - sourceFrame->color_range = AVCOL_RANGE_UNSPECIFIED; - } + default: { + sourcePixelFormat = pixFmt; + sourceFrame->color_range = AVCOL_RANGE_UNSPECIFIED; + } } frameBuffer[sourceFrameKey] = sourceFrame; } VideoFrame::VideoFrame(IDType sourceID, AVFrame* sourceFrame, bool freeSourceFrame) - : VideoFrame(sourceID, sourceFrame, QRect{0, 0, sourceFrame->width, sourceFrame->height}, - sourceFrame->format, freeSourceFrame) -{ -} + : VideoFrame(sourceID, sourceFrame, QRect{0, 0, sourceFrame->width, sourceFrame->height}, + sourceFrame->format, freeSourceFrame) {} /** * @brief Destructor for VideoFrame. */ -VideoFrame::~VideoFrame() -{ +VideoFrame::~VideoFrame() { // Release frame frameLock.lockForWrite(); @@ -174,8 +170,7 @@ VideoFrame::~VideoFrame() * * @return true if the VideoFrame is valid, false otherwise. */ -bool VideoFrame::isValid() -{ +bool VideoFrame::isValid() { frameLock.lockForRead(); bool retValue = frameBuffer.size() > 0; frameLock.unlock(); @@ -191,8 +186,7 @@ bool VideoFrame::isValid() * * @return a std::shared_ptr holding a reference to this frame. */ -std::shared_ptr VideoFrame::trackFrame() -{ +std::shared_ptr VideoFrame::trackFrame() { // Add frame to tracked reference list refsLock.lockForRead(); @@ -227,8 +221,7 @@ std::shared_ptr VideoFrame::trackFrame() * @param releaseFrames true to release the frames as necessary, false otherwise. Defaults to * false. */ -void VideoFrame::untrackFrames(const VideoFrame::IDType& sourceID, bool releaseFrames) -{ +void VideoFrame::untrackFrames(const VideoFrame::IDType& sourceID, bool releaseFrames) { refsLock.lockForWrite(); if (refsMap.count(sourceID) == 0) { @@ -265,8 +258,7 @@ void VideoFrame::untrackFrames(const VideoFrame::IDType& sourceID, bool releaseF /** * @brief Releases all frames managed by this VideoFrame and invalidates it. */ -void VideoFrame::releaseFrame() -{ +void VideoFrame::releaseFrame() { frameLock.lockForWrite(); deleteFrameBuffer(); @@ -287,14 +279,14 @@ void VideoFrame::releaseFrame() * @return a pointer to a AVFrame with the given parameters or nullptr if the VideoFrame is no * longer valid. */ -const AVFrame* VideoFrame::getAVFrame(QSize frameSize, const int pixelFormat, const bool requireAligned) -{ +const AVFrame* VideoFrame::getAVFrame(QSize frameSize, const int pixelFormat, + const bool requireAligned) { if (!frameSize.isValid()) { frameSize = sourceDimensions.size(); } // Since we are retrieving the AVFrame* directly, we merely need to pass the arguement through - const std::function converter = [](AVFrame* const frame) { + const std::function converter = [](AVFrame* const frame) { return frame; }; @@ -316,14 +308,13 @@ const AVFrame* VideoFrame::getAVFrame(QSize frameSize, const int pixelFormat, co * @return a QImage that represents this VideoFrame, sharing it's buffers or a null image if * this VideoFrame is no longer valid. */ -QImage VideoFrame::toQImage(QSize frameSize) -{ +QImage VideoFrame::toQImage(QSize frameSize) { if (!frameSize.isValid()) { frameSize = sourceDimensions.size(); } // Converter function (constructs QImage out of AVFrame*) - const std::function converter = [&](AVFrame* const frame) { + const std::function converter = [&](AVFrame* const frame) { return QImage{*(frame->data), frameSize.width(), frameSize.height(), *(frame->linesize), QImage::Format_RGB888}; }; @@ -343,14 +334,13 @@ QImage VideoFrame::toQImage(QSize frameSize) * @return a ToxAVFrame structure that represents this VideoFrame, sharing it's buffers or an * empty structure if this VideoFrame is no longer valid. */ -ToxYUVFrame VideoFrame::toToxYUVFrame(QSize frameSize) -{ +ToxYUVFrame VideoFrame::toToxYUVFrame(QSize frameSize) { if (!frameSize.isValid()) { frameSize = sourceDimensions.size(); } // Converter function (constructs ToxAVFrame out of AVFrame*) - const std::function converter = [&](AVFrame* const frame) { + const std::function converter = [&](AVFrame* const frame) { ToxYUVFrame ret{static_cast(frameSize.width()), static_cast(frameSize.height()), frame->data[0], frame->data[1], frame->data[2]}; @@ -369,41 +359,28 @@ ToxYUVFrame VideoFrame::toToxYUVFrame(QSize frameSize) * * @return an integer representing the ID of this frame. */ -VideoFrame::IDType VideoFrame::getFrameID() const -{ - return frameID; -} +VideoFrame::IDType VideoFrame::getFrameID() const { return frameID; } /** * @brief Returns the ID for the VideoSource which created this frame. * * @return an integer representing the ID of the VideoSource which created this frame. */ -VideoFrame::IDType VideoFrame::getSourceID() const -{ - return sourceID; -} +VideoFrame::IDType VideoFrame::getSourceID() const { return sourceID; } /** * @brief Retrieves a copy of the source VideoFrame's dimensions. * * @return QRect copy representing the source VideoFrame's dimensions. */ -QRect VideoFrame::getSourceDimensions() const -{ - return sourceDimensions; -} +QRect VideoFrame::getSourceDimensions() const { return sourceDimensions; } /** * @brief Retrieves a copy of the source VideoFormat's pixel format. * * @return integer copy representing the source VideoFrame's pixel format. */ -int VideoFrame::getSourcePixelFormat() const -{ - return sourcePixelFormat; -} - +int VideoFrame::getSourcePixelFormat() const { return sourcePixelFormat; } /** * @brief Constructs a new FrameBufferKey with the given attributes. @@ -415,12 +392,10 @@ int VideoFrame::getSourcePixelFormat() const */ VideoFrame::FrameBufferKey::FrameBufferKey(const int width, const int height, const int pixFmt, const bool lineAligned) - : frameWidth(width) - , frameHeight(height) - , pixelFormat(pixFmt) - , linesizeAligned(lineAligned) -{ -} + : frameWidth(width) + , frameHeight(height) + , pixelFormat(pixFmt) + , linesizeAligned(lineAligned) {} /** * @brief Comparison operator for FrameBufferKey. @@ -428,10 +403,9 @@ VideoFrame::FrameBufferKey::FrameBufferKey(const int width, const int height, co * @param other instance to compare against. * @return true if instances are equivilent, false otherwise. */ -bool VideoFrame::FrameBufferKey::operator==(const FrameBufferKey& other) const -{ - return pixelFormat == other.pixelFormat && frameWidth == other.frameWidth - && frameHeight == other.frameHeight && linesizeAligned == other.linesizeAligned; +bool VideoFrame::FrameBufferKey::operator==(const FrameBufferKey& other) const { + return pixelFormat == other.pixelFormat && frameWidth == other.frameWidth && + frameHeight == other.frameHeight && linesizeAligned == other.linesizeAligned; } /** @@ -440,8 +414,7 @@ bool VideoFrame::FrameBufferKey::operator==(const FrameBufferKey& other) const * @param other instance to compare against * @return true if instances are not equivilent, false otherwise. */ -bool VideoFrame::FrameBufferKey::operator!=(const FrameBufferKey& other) const -{ +bool VideoFrame::FrameBufferKey::operator!=(const FrameBufferKey& other) const { return !operator==(other); } @@ -453,8 +426,7 @@ bool VideoFrame::FrameBufferKey::operator!=(const FrameBufferKey& other) const * @param key the given instance to compute hash value of. * @return the hash of the given instance. */ -size_t VideoFrame::FrameBufferKey::hash(const FrameBufferKey& key) -{ +size_t VideoFrame::FrameBufferKey::hash(const FrameBufferKey& key) { std::hash intHasher; std::hash boolHasher; @@ -480,8 +452,7 @@ size_t VideoFrame::FrameBufferKey::hash(const FrameBufferKey& key) * @return a FrameBufferKey object representing the key for the frameBuffer map. */ VideoFrame::FrameBufferKey VideoFrame::getFrameKey(const QSize& frameSize, const int pixFmt, - const int linesize) -{ + const int linesize) { return getFrameKey(frameSize, pixFmt, frameSize.width() == linesize); } @@ -494,8 +465,7 @@ VideoFrame::FrameBufferKey VideoFrame::getFrameKey(const QSize& frameSize, const * @return a FrameBufferKey object representing the key for the frameBuffer map. */ VideoFrame::FrameBufferKey VideoFrame::getFrameKey(const QSize& frameSize, const int pixFmt, - const bool frameAligned) -{ + const bool frameAligned) { return {frameSize.width(), frameSize.height(), pixFmt, frameAligned}; } @@ -515,8 +485,7 @@ VideoFrame::FrameBufferKey VideoFrame::getFrameKey(const QSize& frameSize, const * found. */ AVFrame* VideoFrame::retrieveAVFrame(const QSize& dimensions, const int pixelFormat, - const bool requireAligned) -{ + const bool requireAligned) { if (!requireAligned) { /* * We attempt to obtain a unaligned frame first because an unaligned linesize corresponds @@ -549,8 +518,7 @@ AVFrame* VideoFrame::retrieveAVFrame(const QSize& dimensions, const int pixelFor * @return an AVFrame with the given specifications. */ AVFrame* VideoFrame::generateAVFrame(const QSize& dimensions, const int pixelFormat, - const bool requireAligned) -{ + const bool requireAligned) { AVFrame* ret = av_frame_alloc(); if (!ret) { @@ -569,7 +537,8 @@ AVFrame* VideoFrame::generateAVFrame(const QSize& dimensions, const int pixelFor int bufSize; - const bool alreadyAligned = dimensions.width() % dataAlignment == 0 && dimensions.height() % dataAlignment == 0; + const bool alreadyAligned = + dimensions.width() % dataAlignment == 0 && dimensions.height() % dataAlignment == 0; if (!requireAligned || alreadyAligned) { bufSize = av_image_alloc(ret->data, ret->linesize, dimensions.width(), dimensions.height(), @@ -587,11 +556,10 @@ AVFrame* VideoFrame::generateAVFrame(const QSize& dimensions, const int pixelFor // Bilinear is better for shrinking, bicubic better for upscaling int resizeAlgo = sourceDimensions.width() > dimensions.width() ? SWS_BILINEAR : SWS_BICUBIC; - SwsContext* swsCtx = - sws_getContext(sourceDimensions.width(), sourceDimensions.height(), - static_cast(sourcePixelFormat), dimensions.width(), - dimensions.height(), static_cast(pixelFormat), resizeAlgo, - nullptr, nullptr, nullptr); + SwsContext* swsCtx = sws_getContext( + sourceDimensions.width(), sourceDimensions.height(), + static_cast(sourcePixelFormat), dimensions.width(), dimensions.height(), + static_cast(pixelFormat), resizeAlgo, nullptr, nullptr, nullptr); if (!swsCtx) { av_freep(&ret->data[0]); @@ -633,8 +601,7 @@ AVFrame* VideoFrame::generateAVFrame(const QSize& dimensions, const int pixelFor * @param pixelFormat the pixel format of the frame. * @return The given AVFrame* or a pre-existing AVFrame* that already exists in the frameBuffer. */ -AVFrame* VideoFrame::storeAVFrame(AVFrame* frame, const QSize& dimensions, const int pixelFormat) -{ +AVFrame* VideoFrame::storeAVFrame(AVFrame* frame, const QSize& dimensions, const int pixelFormat) { FrameBufferKey frameKey = getFrameKey(dimensions, pixelFormat, frame->linesize[0]); // We check the prescence of the frame in case of double-computation @@ -661,8 +628,7 @@ AVFrame* VideoFrame::storeAVFrame(AVFrame* frame, const QSize& dimensions, const * * This function is not thread-safe and must be called from a thread-safe context. */ -void VideoFrame::deleteFrameBuffer() -{ +void VideoFrame::deleteFrameBuffer() { // An empty framebuffer represents a frame that's already been freed if (frameBuffer.empty()) { return; @@ -713,10 +679,10 @@ void VideoFrame::deleteFrameBuffer() * when the generation process fails. */ template -T VideoFrame::toGenericObject(const QSize& dimensions, const int pixelFormat, const bool requireAligned, +T VideoFrame::toGenericObject(const QSize& dimensions, const int pixelFormat, + const bool requireAligned, const std::function& objectConstructor, - const T& nullObject) -{ + const T& nullObject) { frameLock.lockForRead(); // We return nullObject if the VideoFrame is no longer valid @@ -757,11 +723,12 @@ T VideoFrame::toGenericObject(const QSize& dimensions, const int pixelFormat, co // Explicitly specialize VideoFrame::toGenericObject() function template QImage VideoFrame::toGenericObject( - const QSize& dimensions, const int pixelFormat, const bool requireAligned, - const std::function &objectConstructor, const QImage& nullObject); + const QSize& dimensions, const int pixelFormat, const bool requireAligned, + const std::function& objectConstructor, const QImage& nullObject); template ToxYUVFrame VideoFrame::toGenericObject( - const QSize& dimensions, const int pixelFormat, const bool requireAligned, - const std::function &objectConstructor, const ToxYUVFrame& nullObject); + const QSize& dimensions, const int pixelFormat, const bool requireAligned, + const std::function& objectConstructor, + const ToxYUVFrame& nullObject); /** * @brief Returns whether the given ToxYUVFrame represents a valid frame or not. @@ -770,15 +737,9 @@ template ToxYUVFrame VideoFrame::toGenericObject( * * @return true if the frame is valid, false otherwise. */ -bool ToxYUVFrame::isValid() const -{ - return width > 0 && height > 0; -} +bool ToxYUVFrame::isValid() const { return width > 0 && height > 0; } /** * @brief Checks if the given ToxYUVFrame is valid or not, delegates to isValid(). */ -ToxYUVFrame::operator bool() const -{ - return isValid(); -} +ToxYUVFrame::operator bool() const { return isValid(); } diff --git a/src/modules/im/src/video/videoframe.h b/src/modules/im/src/video/videoframe.h index b80ef3be..6162b120 100644 --- a/src/modules/im/src/video/videoframe.h +++ b/src/modules/im/src/video/videoframe.h @@ -19,7 +19,6 @@ #include #include - #include #include #include @@ -28,8 +27,7 @@ struct AVFrame; -struct ToxYUVFrame -{ +struct ToxYUVFrame { public: bool isValid() const; explicit operator bool() const; @@ -42,8 +40,7 @@ struct ToxYUVFrame const uint8_t* v; }; -class VideoFrame -{ +class VideoFrame { public: // Declare type aliases using IDType = std::uint_fast64_t; @@ -84,8 +81,7 @@ class VideoFrame static constexpr int dataAlignment = 32; private: - class FrameBufferKey - { + class FrameBufferKey { public: FrameBufferKey(const int width, const int height, const int pixFmt, const bool lineAligned); @@ -117,15 +113,18 @@ class VideoFrame static FrameBufferKey getFrameKey(const QSize& frameSize, const int pixFmt, const bool frameAligned); - AVFrame* retrieveAVFrame(const QSize& dimensions, const int pixelFormat, const bool requireAligned); - AVFrame* generateAVFrame(const QSize& dimensions, const int pixelFormat, const bool requireAligned); + AVFrame* retrieveAVFrame(const QSize& dimensions, const int pixelFormat, + const bool requireAligned); + AVFrame* generateAVFrame(const QSize& dimensions, const int pixelFormat, + const bool requireAligned); AVFrame* storeAVFrame(AVFrame* frame, const QSize& dimensions, const int pixelFormat); void deleteFrameBuffer(); template T toGenericObject(const QSize& dimensions, const int pixelFormat, const bool requireAligned, - const std::function& objectConstructor, const T& nullObject); + const std::function& objectConstructor, + const T& nullObject); private: // ID @@ -134,7 +133,7 @@ class VideoFrame // Main framebuffer store std::unordered_map> - frameBuffer{3, FrameBufferKey::hash}; + frameBuffer{3, FrameBufferKey::hash}; // Source frame const QRect sourceDimensions; @@ -146,11 +145,12 @@ class VideoFrame static AtomicIDType frameIDs; static std::unordered_map mutexMap; - static std::unordered_map>> refsMap; + static std::unordered_map>> + refsMap; // Concurrency QReadWriteLock frameLock{}; static QReadWriteLock refsLock; }; -#endif // VIDEOFRAME_H +#endif // VIDEOFRAME_H diff --git a/src/modules/im/src/video/videomode.cpp b/src/modules/im/src/video/videomode.cpp index 99f61443..f765aade 100644 --- a/src/modules/im/src/video/videomode.cpp +++ b/src/modules/im/src/video/videomode.cpp @@ -28,49 +28,30 @@ */ VideoMode::VideoMode(int width, int height, int x, int y, float FPS) - : width(width) - , height(height) - , x(x) - , y(y) - , FPS(FPS) -{ -} + : width(width), height(height), x(x), y(y), FPS(FPS) {} VideoMode::VideoMode(QRect rect) - : width(rect.width()) - , height(rect.height()) - , x(rect.x()) - , y(rect.y()) -{ -} + : width(rect.width()), height(rect.height()), x(rect.x()), y(rect.y()) {} -QRect VideoMode::toRect() const -{ - return QRect(x, y, width, height); -} +QRect VideoMode::toRect() const { return QRect(x, y, width, height); } -bool VideoMode::operator==(const VideoMode& other) const -{ - return width == other.width && height == other.height && x == other.x && y == other.y - && qFuzzyCompare(FPS, other.FPS) && pixel_format == other.pixel_format; +bool VideoMode::operator==(const VideoMode& other) const { + return width == other.width && height == other.height && x == other.x && y == other.y && + qFuzzyCompare(FPS, other.FPS) && pixel_format == other.pixel_format; } -//标准 -uint32_t VideoMode::norm(const VideoMode& other) const -{ +// 标准 +uint32_t VideoMode::norm(const VideoMode& other) const { return qAbs(this->width - other.width) + qAbs(this->height - other.height); } -//容忍 -uint32_t VideoMode::tolerance() const -{ - constexpr uint32_t minTolerance = 300; // keep wider tolerance for low res cameras - constexpr uint32_t toleranceFactor = 10; // video mode must be within 10% to be "close enough" to ideal - return std::max((width + height)/toleranceFactor, minTolerance); +// 容忍 +uint32_t VideoMode::tolerance() const { + constexpr uint32_t minTolerance = 300; // keep wider tolerance for low res cameras + constexpr uint32_t toleranceFactor = + 10; // video mode must be within 10% to be "close enough" to ideal + return std::max((width + height) / toleranceFactor, minTolerance); } /** * @brief All zeros means a default/unspecified mode */ -VideoMode::operator bool() const -{ - return width || height || static_cast(FPS); -} +VideoMode::operator bool() const { return width || height || static_cast(FPS); } diff --git a/src/modules/im/src/video/videomode.h b/src/modules/im/src/video/videomode.h index 589657f0..714c5a35 100644 --- a/src/modules/im/src/video/videomode.h +++ b/src/modules/im/src/video/videomode.h @@ -16,8 +16,7 @@ #include #include -struct VideoMode -{ +struct VideoMode { int width, height; int x, y; float FPS = -1.0f; @@ -35,4 +34,4 @@ struct VideoMode uint32_t tolerance() const; }; -#endif // VIDEOMODE_H +#endif // VIDEOMODE_H diff --git a/src/modules/im/src/video/videosource.h b/src/modules/im/src/video/videosource.h index 17436a74..06c0c268 100644 --- a/src/modules/im/src/video/videosource.h +++ b/src/modules/im/src/video/videosource.h @@ -20,8 +20,7 @@ class VideoFrame; -class VideoSource : public QObject -{ +class VideoSource : public QObject { Q_OBJECT public: @@ -30,10 +29,7 @@ class VideoSource : public QObject using AtomicIDType = std::atomic_uint_fast64_t; public: - VideoSource() - : id(sourceIDs++) - { - } + VideoSource() : id(sourceIDs++) {} virtual ~VideoSource() = default; /** @@ -65,4 +61,4 @@ class VideoSource : public QObject static AtomicIDType sourceIDs; }; -#endif // VIDEOSOURCE_H +#endif // VIDEOSOURCE_H diff --git a/src/modules/im/src/video/videosurface.cpp b/src/modules/im/src/video/videosurface.cpp index 9dde2ba1..5dcc9ba9 100644 --- a/src/modules/im/src/video/videosurface.cpp +++ b/src/modules/im/src/video/videosurface.cpp @@ -29,38 +29,27 @@ * @brief Fast lock for lastFrame. */ -float getSizeRatio(const QSize size) -{ - return size.width() / static_cast(size.height()); -} +float getSizeRatio(const QSize size) { return size.width() / static_cast(size.height()); } VideoSurface::VideoSurface(const QPixmap& avatar, QWidget* parent, bool expanding) - : QWidget{parent} - , source{nullptr} - , frameLock{false} - , hasSubscribed{0} - , avatar{avatar} - , ratio{1.0f} - , expanding{expanding} -{ + : QWidget{parent} + , source{nullptr} + , frameLock{false} + , hasSubscribed{0} + , avatar{avatar} + , ratio{1.0f} + , expanding{expanding} { recalulateBounds(); } VideoSurface::VideoSurface(const QPixmap& avatar, VideoSource* source, QWidget* parent) - : VideoSurface(avatar, parent) -{ + : VideoSurface(avatar, parent) { setSource(source); } -VideoSurface::~VideoSurface() -{ - unsubscribe(); -} +VideoSurface::~VideoSurface() { unsubscribe(); } -bool VideoSurface::isExpanding() const -{ - return expanding; -} +bool VideoSurface::isExpanding() const { return expanding; } /** * @brief Update source. @@ -69,41 +58,30 @@ bool VideoSurface::isExpanding() const * * Unsubscribe from old source and subscribe to new. */ -void VideoSurface::setSource(VideoSource* src) -{ - if (source == src) - return; +void VideoSurface::setSource(VideoSource* src) { + if (source == src) return; unsubscribe(); source = src; subscribe(); } -QRect VideoSurface::getBoundingRect() const -{ +QRect VideoSurface::getBoundingRect() const { QRect bRect = boundingRect; bRect.setBottomRight(QPoint(boundingRect.bottom() + 1, boundingRect.right() + 1)); return boundingRect; } -float VideoSurface::getRatio() const -{ - return ratio; -} +float VideoSurface::getRatio() const { return ratio; } -void VideoSurface::setAvatar(const QPixmap& pixmap) -{ +void VideoSurface::setAvatar(const QPixmap& pixmap) { avatar = pixmap; update(); } -QPixmap VideoSurface::getAvatar() const -{ - return avatar; -} +QPixmap VideoSurface::getAvatar() const { return avatar; } -void VideoSurface::subscribe() -{ +void VideoSurface::subscribe() { if (source && hasSubscribed++ == 0) { source->subscribe(); connect(source, &VideoSource::frameAvailable, this, &VideoSurface::onNewFrameAvailable); @@ -111,13 +89,10 @@ void VideoSurface::subscribe() } } -void VideoSurface::unsubscribe() -{ - if (!source || hasSubscribed == 0) - return; +void VideoSurface::unsubscribe() { + if (!source || hasSubscribed == 0) return; - if (--hasSubscribed != 0) - return; + if (--hasSubscribed != 0) return; lock(); lastFrame.reset(); @@ -133,8 +108,7 @@ void VideoSurface::unsubscribe() source->unsubscribe(); } -void VideoSurface::onNewFrameAvailable(const std::shared_ptr& newFrame) -{ +void VideoSurface::onNewFrameAvailable(const std::shared_ptr& newFrame) { QSize newSize; lock(); @@ -144,7 +118,7 @@ void VideoSurface::onNewFrameAvailable(const std::shared_ptr& newFra float newRatio = getSizeRatio(newSize); - if (!qFuzzyCompare(newRatio, ratio) && isVisible()) { + if (!qFuzzyCompare(newRatio, ratio) && isVisible()) { ratio = newRatio; recalulateBounds(); emit ratioChanged(); @@ -154,23 +128,20 @@ void VideoSurface::onNewFrameAvailable(const std::shared_ptr& newFra update(); } -void VideoSurface::onSourceStopped() -{ +void VideoSurface::onSourceStopped() { // If the source's stream is on hold, just revert back to the avatar view lastFrame.reset(); update(); } -void VideoSurface::paintEvent(QPaintEvent*) -{ +void VideoSurface::paintEvent(QPaintEvent*) { lock(); QPainter painter(this); painter.fillRect(painter.viewport(), Qt::black); if (lastFrame) { QImage frame = lastFrame->toQImage(rect().size()); - if (frame.isNull()) - lastFrame.reset(); + if (frame.isNull()) lastFrame.reset(); painter.drawImage(boundingRect, frame, frame.rect(), Qt::NoFormatConversion); } else { painter.fillRect(boundingRect, Qt::white); @@ -178,7 +149,7 @@ void VideoSurface::paintEvent(QPaintEvent*) if (drawnAvatar.isNull()) drawnAvatar = SvgUtils::scaleSvgImage(":/img/contact_dark.svg", boundingRect.width(), - boundingRect.height()); + boundingRect.height()); painter.drawPixmap(boundingRect, drawnAvatar, drawnAvatar.rect()); } @@ -186,21 +157,18 @@ void VideoSurface::paintEvent(QPaintEvent*) unlock(); } -void VideoSurface::resizeEvent(QResizeEvent* event) -{ +void VideoSurface::resizeEvent(QResizeEvent* event) { QWidget::resizeEvent(event); recalulateBounds(); emit boundaryChanged(); } -void VideoSurface::showEvent(QShowEvent* e) -{ +void VideoSurface::showEvent(QShowEvent* e) { Q_UNUSED(e); emit ratioChanged(); } -void VideoSurface::recalulateBounds() -{ +void VideoSurface::recalulateBounds() { if (expanding) { boundingRect = contentsRect(); } else { @@ -222,15 +190,10 @@ void VideoSurface::recalulateBounds() update(); } -void VideoSurface::lock() -{ +void VideoSurface::lock() { // Fast lock bool expected = false; - while (!frameLock.compare_exchange_weak(expected, true)) - expected = false; + while (!frameLock.compare_exchange_weak(expected, true)) expected = false; } -void VideoSurface::unlock() -{ - frameLock = false; -} +void VideoSurface::unlock() { frameLock = false; } diff --git a/src/modules/im/src/video/videosurface.h b/src/modules/im/src/video/videosurface.h index 94457232..f94ddc1f 100644 --- a/src/modules/im/src/video/videosurface.h +++ b/src/modules/im/src/video/videosurface.h @@ -13,13 +13,12 @@ #ifndef SELFCAMVIEW_H #define SELFCAMVIEW_H -#include "src/video/videosource.h" #include #include #include +#include "src/video/videosource.h" -class VideoSurface : public QWidget -{ +class VideoSurface : public QWidget { Q_OBJECT public: @@ -65,4 +64,4 @@ private slots: bool expanding; }; -#endif // SELFCAMVIEW_H +#endif // SELFCAMVIEW_H diff --git a/src/modules/im/src/widget/ChatWidget.cpp b/src/modules/im/src/widget/ChatWidget.cpp index c2f48264..4c4b5956 100644 --- a/src/modules/im/src/widget/ChatWidget.cpp +++ b/src/modules/im/src/widget/ChatWidget.cpp @@ -15,7 +15,13 @@ // #include "ChatWidget.h" +#include +#include +#include +#include +#include #include "MessageSessionListWidget.h" +#include "application.h" #include "base/OkSettings.h" #include "base/SvgUtils.h" #include "base/utils.h" @@ -36,13 +42,9 @@ #include "src/widget/form/groupinviteform.h" #include "ui_ChatWidget.h" #include "widget.h" -#include -#include -#include -#include -#include #include +#include "src/Bus.h" namespace { @@ -51,75 +53,84 @@ namespace { * @param filepath Path to file which should be deleted. * @return True, if file writeable, false otherwise. */ -bool tryRemoveFile(const QString &filepath) { - QFile tmp(filepath); - bool writable = tmp.open(QIODevice::WriteOnly); - tmp.remove(); - return writable; -} - -void acceptFileTransfer(ToxFile &file, const QString &path) { - QString filepath; - int number = 0; - - QString suffix = QFileInfo(file.fileName).completeSuffix(); - QString base = QFileInfo(file.fileName).baseName(); - - do { - filepath = QString("%1/%2%3.%4").arg(path, base, number > 0 ? QString("(%1)").arg(QString::number(number)) : QString(), suffix); - ++number; - } while (QFileInfo(filepath).exists()); - - - file.setFilePath(filepath); - // Do not automatically accept the file-transfer if the path is not writable. - // The user can still accept it manually. - if (tryRemoveFile(filepath)) { - CoreFile *coreFile = Core::getInstance()->getCoreFile(); - coreFile->acceptFileRecvRequest(file.receiver, file.fileId, filepath); - } else { - qWarning() << "Cannot write to " << filepath; - } -} -} // namespace - -ChatWidget::ChatWidget(QWidget *parent) - : MainLayout(parent), // - ui(new Ui::ChatWidget), // - unreadGroupInvites{0}, core{nullptr}, coreFile{nullptr}, profileInfo{nullptr}, profileForm{nullptr} { - ui->setupUi(this); - layout()->setMargin(0); - layout()->setSpacing(0); - - // 右侧容器 - contentWidget = std::make_unique(this); - contentWidget->setObjectName("ChatContentWidget"); - contentLayout = new ContentLayout(contentWidget.get()); - contentWidget->setLayout(contentLayout); - - // 左侧 - sessionListWidget = std::make_unique(this, contentLayout, false); - sessionListWidget->setGeometry(0, 0, 400, 400); - sessionListWidget->layout()->setAlignment(Qt::AlignTop | Qt::AlignVCenter); - - ui->scrollAreaWidgetContents->setGeometry(0, 0, 200, 500); - ui->scrollAreaWidgetContents->layout()->setAlignment(Qt::AlignTop | Qt::AlignVCenter); - ui->scrollAreaWidgetContents->layout()->addWidget((QWidget *)sessionListWidget.get()); - - ui->mainSplitter->addWidget(contentWidget.get()); - ui->mainSplitter->setSizes(QList() << 200 << 500); - - const Settings &s = Settings::getInstance(); - - reloadTheme(); - setupStatus(); - setupSearch(); - init(); - - retranslateUi(); - - // todo: delete from ui - ui->searchContactFilterBox->setVisible(false); +bool tryRemoveFile(const QString& filepath) { + QFile tmp(filepath); + bool writable = tmp.open(QIODevice::WriteOnly); + tmp.remove(); + return writable; +} + +void acceptFileTransfer(ToxFile& file, const QString& path) { + QString filepath; + int number = 0; + + QString suffix = QFileInfo(file.fileName).completeSuffix(); + QString base = QFileInfo(file.fileName).baseName(); + + do { + filepath = + QString("%1/%2%3.%4") + .arg(path, base, + number > 0 ? QString("(%1)").arg(QString::number(number)) : QString(), + suffix); + ++number; + } while (QFileInfo(filepath).exists()); + + file.setFilePath(filepath); + // Do not automatically accept the file-transfer if the path is not writable. + // The user can still accept it manually. + if (tryRemoveFile(filepath)) { + CoreFile* coreFile = Core::getInstance()->getCoreFile(); + coreFile->acceptFileRecvRequest(file.receiver, file.fileId, filepath); + } else { + qWarning() << "Cannot write to " << filepath; + } +} +} // namespace + +ChatWidget::ChatWidget(QWidget* parent) + : MainLayout(parent) + , // + ui(new Ui::ChatWidget) + , // + unreadGroupInvites{0} + , core{nullptr} + , coreFile{nullptr} + , profileInfo{nullptr} + , profileForm{nullptr} { + ui->setupUi(this); + layout()->setMargin(0); + layout()->setSpacing(0); + + // 右侧容器 + contentWidget = std::make_unique(this); + contentWidget->setObjectName("ChatContentWidget"); + contentLayout = new ContentLayout(contentWidget.get()); + contentWidget->setLayout(contentLayout); + + // 左侧 + sessionListWidget = std::make_unique(this, contentLayout, false); + sessionListWidget->setGeometry(0, 0, 400, 400); + sessionListWidget->layout()->setAlignment(Qt::AlignTop | Qt::AlignVCenter); + + ui->scrollAreaWidgetContents->setGeometry(0, 0, 200, 500); + ui->scrollAreaWidgetContents->layout()->setAlignment(Qt::AlignTop | Qt::AlignVCenter); + ui->scrollAreaWidgetContents->layout()->addWidget((QWidget*)sessionListWidget.get()); + + ui->mainSplitter->addWidget(contentWidget.get()); + ui->mainSplitter->setSizes(QList() << 200 << 500); + + const Settings& s = Settings::getInstance(); + + reloadTheme(); + setupStatus(); + setupSearch(); + init(); + + retranslateUi(); + + // todo: delete from ui + ui->searchContactFilterBox->setVisible(false); } ChatWidget::~ChatWidget() { @@ -128,182 +139,178 @@ ChatWidget::~ChatWidget() { } void ChatWidget::init() { + connect(ui->nameLabel, &CroppingLabel::clicked, this, &ChatWidget::on_nameClicked); - connect(ui->nameLabel, &CroppingLabel::clicked, this, &ChatWidget::on_nameClicked); - - auto widget = Widget::getInstance(); + auto widget = Widget::getInstance(); - connect(widget, &Widget::toSendMessage, this, &ChatWidget::doSendMessage); - connect(widget, &Widget::friendAdded, this, &ChatWidget::onFriendAdded); - connect(widget, &Widget::friendRemoved, this, &ChatWidget::onFriendRemoved); - connect(widget, &Widget::groupAdded, this, &ChatWidget::onGroupAdded); - connect(widget, &Widget::groupRemoved, this, &ChatWidget::onGroupRemoved); + connect(widget, &Widget::toSendMessage, this, &ChatWidget::doSendMessage); + connect(widget, &Widget::friendAdded, this, &ChatWidget::onFriendAdded); + connect(widget, &Widget::friendRemoved, this, &ChatWidget::onFriendRemoved); + connect(widget, &Widget::groupAdded, this, &ChatWidget::onGroupAdded); + connect(widget, &Widget::groupRemoved, this, &ChatWidget::onGroupRemoved); - connect(Nexus::getProfile(), &Profile::coreChanged, this, &ChatWidget::onCoreChanged); + connect(ok::Application::Instance()->bus(), &ok::Bus::coreChanged, this, + [&](Core* core) { connectToCore(core); }); - settings::Translator::registerHandler(std::bind(&ChatWidget::retranslateUi, this), this); + settings::Translator::registerHandler([this] { retranslateUi(); }, this); } void ChatWidget::deinit() { - - settings::Translator::unregister(this); - - disconnect(ui->nameLabel, &CroppingLabel::clicked, this, &ChatWidget::on_nameClicked); - - auto widget = Widget::getInstance(); - - disconnect(widget, &Widget::toSendMessage , this, &ChatWidget::doSendMessage); - disconnect(widget, &Widget::friendAdded, this, &ChatWidget::onFriendAdded); - disconnect(widget, &Widget::friendRemoved, this, &ChatWidget::onFriendRemoved); - disconnect(widget, &Widget::groupAdded, this, &ChatWidget::onGroupAdded); - disconnect(widget, &Widget::groupRemoved, this, &ChatWidget::onGroupRemoved); - - - disconnect(Nexus::getProfile(), &Profile::coreChanged, this, &ChatWidget::onCoreChanged); - - delete profileForm; - delete profileInfo; -} - -void ChatWidget::connectToCore(Core *core) { - qDebug() << __func__ << "core" << core; - connect(core, &Core::usernameSet, this, &ChatWidget::onUsernameSet); - connect(core, &Core::statusSet, this, &ChatWidget::onStatusSet); - connect(core, &Core::statusMessageSet, this, &ChatWidget::onStatusMessageSet); - - connect(core, &Core::messageSessionReceived, this, &ChatWidget::onMessageSessionReceived); - - connect(core, &Core::friendMessageReceived, this, &ChatWidget::onFriendMessageReceived); - - connect(core, &Core::friendStatusChanged, this, &ChatWidget::onFriendStatusChanged); - - connect(core, &Core::friendStatusMessageChanged, this, &ChatWidget::onFriendStatusMessageChanged); - - connect(core, &Core::friendTypingChanged, this, &ChatWidget::onFriendTypingChanged); - connect(core, &Core::receiptRecieved, this, &ChatWidget::onReceiptReceived); - - - connect(core, &Core::groupMessageReceived, this, &ChatWidget::onGroupMessageReceived); - connect(core, &Core::groupPeerlistChanged, this, &ChatWidget::onGroupPeerListChanged); - connect(core, &Core::groupPeerSizeChanged, this, &ChatWidget::onGroupPeerSizeChanged); - connect(core, &Core::groupPeerNameChanged, this, &ChatWidget::onGroupPeerNameChanged); - connect(core, &Core::groupPeerStatusChanged, this, &ChatWidget::onGroupPeerStatusChanged); - - // connect(core, &Core::groupPeerAudioPlaying, this, - // &ChatWidget::onGroupPeerAudioPlaying); - // connect(core, &Core::emptyGroupCreated, this, - // &ChatWidget::onEmptyGroupCreated); - - // connect(&core, &Core::groupSentFailed, this, - // &ChatWidget::onGroupSendFailed); -} - -void ChatWidget::connectToCoreFile(CoreFile *coreFile) { - connect(coreFile, &CoreFile::fileSendStarted, this, &ChatWidget::dispatchFile); - connect(coreFile, &CoreFile::fileReceiveRequested, this, &ChatWidget::dispatchFile); - connect(coreFile, &CoreFile::fileTransferAccepted, this, &ChatWidget::dispatchFile); - connect(coreFile, &CoreFile::fileTransferCancelled, this, &ChatWidget::dispatchFile); - connect(coreFile, &CoreFile::fileTransferNoExisting, this, &ChatWidget::cancelFile); - connect(coreFile, &CoreFile::fileTransferFinished, this, &ChatWidget::dispatchFile); - connect(coreFile, &CoreFile::fileTransferPaused, this, &ChatWidget::dispatchFile); - connect(coreFile, &CoreFile::fileTransferInfo, this, &ChatWidget::dispatchFile); - connect(coreFile, &CoreFile::fileTransferRemotePausedUnpaused, this, &ChatWidget::dispatchFileWithBool); - connect(coreFile, &CoreFile::fileTransferBrokenUnbroken, this, &ChatWidget::dispatchFileWithBool); - connect(coreFile, &CoreFile::fileSendFailed, this, &ChatWidget::dispatchFileSendFailed); -} - -void ChatWidget::onCoreChanged(Core &core_) { - core = &core_; - connectToCore(core); - connectToCoreFile(core->getCoreFile()); - - auto username = core->getUsername(); - qDebug() << "username" << username; - ui->nameLabel->setText(username); - - const CoreAV *av = CoreAV::getInstance(); - connect(av, &CoreAV::avInvite, this, &ChatWidget::onAvInvite); - connect(av, &CoreAV::avStart, this, &ChatWidget::onAvStart); - connect(av, &CoreAV::avEnd, this, &ChatWidget::onAvEnd); -} - -void ChatWidget::onMessageSessionReceived(const ContactId &contactId, const QString &sid) { - qDebug() << __func__ << "contactId:" << contactId.toString() << "sid:" << sid; - sessionListWidget->createMessageSession(contactId, sid, - contactId.isGroup() ? ChatType::GroupChat : ChatType::Chat); -} - -void ChatWidget::onFriendMessageReceived(const FriendId &friendId, const FriendMessage &message, bool isAction) { - qDebug() << __func__ << "content:" << message.content << "from" << message.from; - sessionListWidget->setRecvFriendMessage(friendId, message, isAction); -} - -void ChatWidget::onReceiptReceived(const FriendId &friendId, MsgId receipt) { - qDebug() << __func__ << "receiver:" << friendId.toString() << receipt; - sessionListWidget->setFriendMessageReceipt(friendId, receipt); -} - -void ChatWidget::onFriendStatusChanged(const FriendId &friendPk, Status::Status status) { - qDebug() << __func__ << friendPk.toString() << "status:" << (int)status; - // const auto &friendPk = FriendList::id2Key(friendPk); - // contactListWidget->setFriendStatus(friendPk, status); - Friend *f = FriendList::findFriend(friendPk); - if (!f) { - qWarning() << "Unable to find friend" << friendPk.toString(); - return; - } - f->setStatus(status); - - // bool isActualChange = f->getStatus() != status; - // - // FriendWidget *widget = // friendWidgets[f->getPublicKey()]; - // contactListWidget->getFriend(f->getPublicKey()); - // if (isActualChange) { - // if (!Status::isOnline(f->getStatus())) { - // contactListWidget->moveWidget(widget, Status::Status::Online); - // } else if (status == Status::Status::Offline) { - // contactListWidget->moveWidget(widget, Status::Status::Offline); - // } - // } - // - - // if (widget->isActive()) { - // setWindowTitle(widget->getSubject()); - // } - // - // ContentDialogManager::getInstance()->updateFriendStatus(friendPk); -} - -void ChatWidget::onFriendStatusMessageChanged(const FriendId &friendPk, const QString &message) { - - sessionListWidget->setFriendStatusMsg(friendPk, message); - - // IMFriend *f = FriendList::findFriend(friendPk); - // if (!f) { - // return; - // } - // - // QString str = message; - // str.replace('\n', ' ').remove('\r').remove(QChar('\0')); - // f->setStatusMessage(str); - // - // chatForms[friendPk]->setStatusMessage(str); - // - // auto frd = contactListWidget->getFriend(friendPk); - // if(frd){ - // frd->setStatusMsg(str); - // } -} - -void ChatWidget::onFriendTypingChanged(const FriendId &friendId, bool isTyping) { sessionListWidget->setFriendTyping(friendId, isTyping); } - -void ChatWidget::onGroupAdded(const Group *g) { - sessionListWidget->addGroup(g); -} - -void ChatWidget::onGroupRemoved(const Group *g) { sessionListWidget->removeGroup(g); } - -void ChatWidget::showEvent(QShowEvent *e) {} + settings::Translator::unregister(this); + + disconnect(ui->nameLabel, &CroppingLabel::clicked, this, &ChatWidget::on_nameClicked); + + auto widget = Widget::getInstance(); + + disconnect(widget, &Widget::toSendMessage, this, &ChatWidget::doSendMessage); + disconnect(widget, &Widget::friendAdded, this, &ChatWidget::onFriendAdded); + disconnect(widget, &Widget::friendRemoved, this, &ChatWidget::onFriendRemoved); + disconnect(widget, &Widget::groupAdded, this, &ChatWidget::onGroupAdded); + disconnect(widget, &Widget::groupRemoved, this, &ChatWidget::onGroupRemoved); + + delete profileForm; + delete profileInfo; +} + +void ChatWidget::connectToCore(Core* core_) { + qDebug() << __func__ << "core:" << core_; + core = core_; // TODO: 待优化 + connect(Nexus::getProfile(), &Profile::nickChanged, this, &ChatWidget::onUsernameSet); + + connect(core_, &Core::statusSet, this, &ChatWidget::onStatusSet); + connect(core_, &Core::statusMessageSet, this, &ChatWidget::onStatusMessageSet); + connect(core_, &Core::messageSessionReceived, this, &ChatWidget::onMessageSessionReceived); + connect(core_, &Core::friendUsernameChanged, this, &ChatWidget::onFriendNickChanged); + connect(core_, &Core::friendAvatarChanged, this, &ChatWidget::onFriendAvatarChanged); + connect(core_, &Core::friendMessageReceived, this, &ChatWidget::onFriendMessageReceived); + connect(core_, &Core::friendStatusChanged, this, &ChatWidget::onFriendStatusChanged); + connect(core_, &Core::friendStatusMessageChanged, this, + &ChatWidget::onFriendStatusMessageChanged); + connect(core_, &Core::friendTypingChanged, this, &ChatWidget::onFriendTypingChanged); + connect(core_, &Core::receiptRecieved, this, &ChatWidget::onReceiptReceived); + connect(core_, &Core::groupMessageReceived, this, &ChatWidget::onGroupMessageReceived); + connect(core_, &Core::groupPeerlistChanged, this, &ChatWidget::onGroupPeerListChanged); + connect(core_, &Core::groupPeerSizeChanged, this, &ChatWidget::onGroupPeerSizeChanged); + connect(core_, &Core::groupPeerNameChanged, this, &ChatWidget::onGroupPeerNameChanged); + connect(core_, &Core::groupPeerStatusChanged, this, &ChatWidget::onGroupPeerStatusChanged); + + // connect(core_, &Core::groupPeerAudioPlaying, this, + // &ChatWidget::onGroupPeerAudioPlaying); + // connect(core_, &Core::emptyGroupCreated, this, + // &ChatWidget::onEmptyGroupCreated); + + // connect(&core_, &Core::groupSentFailed, this, + // &ChatWidget::onGroupSendFailed); +} + +void ChatWidget::connectToCoreFile(CoreFile* coreFile) { + connect(coreFile, &CoreFile::fileSendStarted, this, &ChatWidget::dispatchFile); + connect(coreFile, &CoreFile::fileReceiveRequested, this, &ChatWidget::dispatchFile); + connect(coreFile, &CoreFile::fileTransferAccepted, this, &ChatWidget::dispatchFile); + connect(coreFile, &CoreFile::fileTransferCancelled, this, &ChatWidget::dispatchFile); + connect(coreFile, &CoreFile::fileTransferNoExisting, this, &ChatWidget::cancelFile); + connect(coreFile, &CoreFile::fileTransferFinished, this, &ChatWidget::dispatchFile); + connect(coreFile, &CoreFile::fileTransferPaused, this, &ChatWidget::dispatchFile); + connect(coreFile, &CoreFile::fileTransferInfo, this, &ChatWidget::dispatchFile); + connect(coreFile, &CoreFile::fileTransferRemotePausedUnpaused, this, + &ChatWidget::dispatchFileWithBool); + connect(coreFile, &CoreFile::fileTransferBrokenUnbroken, this, + &ChatWidget::dispatchFileWithBool); + connect(coreFile, &CoreFile::fileSendFailed, this, &ChatWidget::dispatchFileSendFailed); +} + +void ChatWidget::onCoreChanged(Core& core_) { + core = &core_; + connectToCore(core); + connectToCoreFile(core->getCoreFile()); + + auto username = core->getUsername(); + qDebug() << "username" << username; + ui->nameLabel->setText(username); + + const CoreAV* av = CoreAV::getInstance(); + connect(av, &CoreAV::avInvite, this, &ChatWidget::onAvInvite); + connect(av, &CoreAV::avStart, this, &ChatWidget::onAvStart); + connect(av, &CoreAV::avEnd, this, &ChatWidget::onAvEnd); +} + +void ChatWidget::onMessageSessionReceived(const ContactId& contactId, const QString& sid) { + qDebug() << __func__ << "contactId:" << contactId.toString() << "sid:" << sid; + sessionListWidget->createMessageSession( + contactId, sid, contactId.isGroup() ? ChatType::GroupChat : ChatType::Chat); +} + +void ChatWidget::onFriendMessageReceived(const FriendId& friendId, const FriendMessage& message, + bool isAction) { + qDebug() << __func__ << "content:" << message.content << "from" << message.from; + sessionListWidget->setRecvFriendMessage(friendId, message, isAction); +} + +void ChatWidget::onReceiptReceived(const FriendId& friendId, MsgId receipt) { + qDebug() << __func__ << "receiver:" << friendId.toString() << receipt; + sessionListWidget->setFriendMessageReceipt(friendId, receipt); +} + +void ChatWidget::onFriendStatusChanged(const FriendId& friendPk, Status::Status status) { + qDebug() << __func__ << friendPk.toString() << "status:" << (int)status; + // const auto &friendPk = FriendList::id2Key(friendPk); + // contactListWidget->setFriendStatus(friendPk, status); + Friend* f = FriendList::findFriend(friendPk); + if (!f) { + qWarning() << "Unable to find friend" << friendPk.toString(); + return; + } + f->setStatus(status); + + // bool isActualChange = f->getStatus() != status; + // + // FriendWidget *widget = // friendWidgets[f->getPublicKey()]; + // contactListWidget->getFriend(f->getPublicKey()); + // if (isActualChange) { + // if (!Status::isOnline(f->getStatus())) { + // contactListWidget->moveWidget(widget, Status::Status::Online); + // } else if (status == Status::Status::Offline) { + // contactListWidget->moveWidget(widget, Status::Status::Offline); + // } + // } + // + + // if (widget->isActive()) { + // setWindowTitle(widget->getSubject()); + // } + // + // ContentDialogManager::getInstance()->updateFriendStatus(friendPk); +} + +void ChatWidget::onFriendStatusMessageChanged(const FriendId& friendPk, const QString& message) { + sessionListWidget->setFriendStatusMsg(friendPk, message); + + // IMFriend *f = FriendList::findFriend(friendPk); + // if (!f) { + // return; + // } + // + // QString str = message; + // str.replace('\n', ' ').remove('\r').remove(QChar('\0')); + // f->setStatusMessage(str); + // + // chatForms[friendPk]->setStatusMessage(str); + // + // auto frd = contactListWidget->getFriend(friendPk); + // if(frd){ + // frd->setStatusMsg(str); + // } +} + +void ChatWidget::onFriendTypingChanged(const FriendId& friendId, bool isTyping) { + sessionListWidget->setFriendTyping(friendId, isTyping); +} + +void ChatWidget::onGroupAdded(const Group* g) { sessionListWidget->addGroup(g); } + +void ChatWidget::onGroupRemoved(const Group* g) { sessionListWidget->removeGroup(g); } + +void ChatWidget::showEvent(QShowEvent* e) {} // void ChatWidget::onFriendDisplayedNameChanged(const ToxPk & friendPk, const // QString &displayed) { @@ -328,65 +335,55 @@ void ChatWidget::showEvent(QShowEvent *e) {} // settings.savePersonal(); //} -void ChatWidget::onUsernameSet(const QString &username) { - qDebug() << __func__ << username; - ui->nameLabel->setText(username); - ui->nameLabel->setToolTip(Qt::convertFromPlainText(username, Qt::WhiteSpaceNormal)); - - auto self = core->getSelfId(); - sessionListWidget->setFriendName(self, username); - - // for overlength names - // sharedMessageProcessorParams.onUserNameSet(username); +void ChatWidget::onUsernameSet(const QString& username) { + qDebug() << __func__ << username; + ui->nameLabel->setText(username); + ui->nameLabel->setToolTip(Qt::convertFromPlainText(username, Qt::WhiteSpaceNormal)); + sessionListWidget->setFriendName(core->getSelfId(), username); } void ChatWidget::onStatusSet(Status::Status status) { - int icon_size = 15; - ui->statusButton->setProperty("status", static_cast(status)); - ui->statusButton->setIcon(SvgUtils::prepareIcon(getIconPath(status), icon_size, icon_size)); + int icon_size = 15; + ui->statusButton->setProperty("status", static_cast(status)); + ui->statusButton->setIcon(SvgUtils::prepareIcon(getIconPath(status), icon_size, icon_size)); - updateIcons(); + updateIcons(); } void ChatWidget::updateIcons() { + QIcon ico; + bool eventIcon = true; - QIcon ico; - bool eventIcon = true; + const QString assetSuffix = Status::getAssetSuffix(static_cast( + ui->statusButton->property("status").toInt())) + + (eventIcon ? "_event" : ""); - const QString assetSuffix = Status::getAssetSuffix(static_cast(ui->statusButton->property("status").toInt())) + (eventIcon ? "_event" : ""); + QString color = Settings::getInstance().getLightTrayIcon() ? "light" : "dark"; + QString path = ":/img/taskbar/" + color + "/taskbar_" + assetSuffix + ".svg"; + QSvgRenderer renderer(path); - QString color = Settings::getInstance().getLightTrayIcon() ? "light" : "dark"; - QString path = ":/img/taskbar/" + color + "/taskbar_" + assetSuffix + ".svg"; - QSvgRenderer renderer(path); - - // Prepare a QImage with desired characteritisc - QImage image = QImage(250, 250, QImage::Format_ARGB32); - image.fill(Qt::transparent); - QPainter painter(&image); - renderer.render(&painter); - ico = QIcon(QPixmap::fromImage(image)); - setWindowIcon(ico); + // Prepare a QImage with desired characteritisc + QImage image = QImage(250, 250, QImage::Format_ARGB32); + image.fill(Qt::transparent); + QPainter painter(&image); + renderer.render(&painter); + ico = QIcon(QPixmap::fromImage(image)); + setWindowIcon(ico); } -void ChatWidget::onStatusMessageSet(const QString &statusMessage) { +void ChatWidget::onStatusMessageSet(const QString& statusMessage) { ui->statusLabel->setText(statusMessage); } -void ChatWidget::onFriendAdded(const Friend *f) { - sessionListWidget->addFriend(f); -} +void ChatWidget::onFriendAdded(const Friend* f) { sessionListWidget->addFriend(f); } -void ChatWidget::onFriendRemoved(const Friend *f) { - sessionListWidget->removeFriend(f); -} +void ChatWidget::onFriendRemoved(const Friend* f) { sessionListWidget->removeFriend(f); } -void ChatWidget::doSendMessage(const QString &to, bool isGroup) -{ - sessionListWidget->toSendMessage(FriendId(to), isGroup); +void ChatWidget::doSendMessage(const QString& to, bool isGroup) { + sessionListWidget->toSendMessage(FriendId(to), isGroup); } - -//void ChatWidget::onGroupInviteReceived(const GroupInvite &inviteInfo) { +// void ChatWidget::onGroupInviteReceived(const GroupInvite &inviteInfo) { // auto confType = inviteInfo.getType(); // if (confType == ConferenceType::TEXT || confType == ConferenceType::AV) { @@ -403,317 +400,316 @@ void ChatWidget::doSendMessage(const QString &to, bool isGroup) // groupInvitesUpdate(); // Widget::getInstance()->newMessageAlert(window(), isActiveWindow(), true, true); -//#if DESKTOP_NOTIFICATIONS -// if (settings.getNotifyHide()) { -// notifier.notifyMessageSimple(DesktopNotify::MessageType::GROUP_INVITE); -// } else { -// notifier.notifyMessagePixmap(f->getDisplayedName() + tr(" invites you to join a group."), {}, Nexus::getProfile()->loadAvatar(f->getPublicKey())); -// } -//#endif -// } -// } else { -// qWarning() << "onGroupInviteReceived: Unknown ConferenceType:" << (int)confType; -// return; -// } -//} +// #if DESKTOP_NOTIFICATIONS +// if (settings.getNotifyHide()) { +// notifier.notifyMessageSimple(DesktopNotify::MessageType::GROUP_INVITE); +// } else { +// notifier.notifyMessagePixmap(f->getDisplayedName() + tr(" invites you to join a group."), +// {}, Nexus::getProfile()->loadAvatar(f->getPublicKey())); +// } +// #endif +// } +// } else { +// qWarning() << "onGroupInviteReceived: Unknown ConferenceType:" << (int)confType; +// return; +// } +// } -void ChatWidget::onGroupInviteAccepted(const GroupInvite &inviteInfo) { - const QString groupId = core->joinGroupchat(inviteInfo); - qDebug() << "onGroupInviteAccepted groupId=>" << groupId; +void ChatWidget::onGroupInviteAccepted(const GroupInvite& inviteInfo) { + const QString groupId = core->joinGroupchat(inviteInfo); + qDebug() << "onGroupInviteAccepted groupId=>" << groupId; - if (groupId == std::numeric_limits::max()) { - qWarning() << "onGroupInviteAccepted: Unable to accept group invite"; - return; - } + if (groupId == std::numeric_limits::max()) { + qWarning() << "onGroupInviteAccepted: Unable to accept group invite"; + return; + } } void ChatWidget::onGroupMessageReceived(GroupId groupId, GroupMessage msg) { - qDebug() << __func__ << msg.toString(); - sessionListWidget->setRecvGroupMessage(groupId, msg); + qDebug() << __func__ << msg.toString(); + sessionListWidget->setRecvGroupMessage(groupId, msg); } void ChatWidget::onGroupPeerListChanged(QString groupnumber) { - // const GroupId &groupId = GroupList::id2Key(groupnumber); - // Group *g = GroupList::findGroup(groupId); - // assert(g); - // g->regeneratePeerList(); + // const GroupId &groupId = GroupList::id2Key(groupnumber); + // Group *g = GroupList::findGroup(groupId); + // assert(g); + // g->regeneratePeerList(); } void ChatWidget::onGroupPeerSizeChanged(QString groupnumber, const uint size) { - const GroupId &groupId = GroupId(groupnumber); - Group *g = GroupList::findGroup(groupId); - if (!g) { - qWarning() << "Can not find the group named:" << groupnumber; - return; - } + const GroupId& groupId = GroupId(groupnumber); + Group* g = GroupList::findGroup(groupId); + if (!g) { + qWarning() << "Can not find the group named:" << groupnumber; + return; + } - g->setPeerCount(size); + g->setPeerCount(size); } -void ChatWidget::onGroupPeerNameChanged(QString groupnumber, const FriendId &peerPk, const QString &newName) { - const GroupId &groupId = GroupId(groupnumber); - Group *g = GroupList::findGroup(groupId); - if (!g) { - qWarning() << "Can not find the group named:" << groupnumber; - return; - } - // const QString &setName = FriendList::decideNickname(peerPk, newName); - // g->updateUsername(peerPk, newName); +void ChatWidget::onGroupPeerNameChanged(QString groupnumber, const FriendId& peerPk, + const QString& newName) { + const GroupId& groupId = GroupId(groupnumber); + Group* g = GroupList::findGroup(groupId); + if (!g) { + qWarning() << "Can not find the group named:" << groupnumber; + return; + } + // const QString &setName = FriendList::decideNickname(peerPk, newName); + // g->updateUsername(peerPk, newName); } -void ChatWidget::onGroupPeerStatusChanged(const QString &groupnumber, const GroupOccupant &go) { - - const GroupId &groupId = GroupId(groupnumber); - Group *g = GroupList::findGroup(groupId); - if (!g) { - qWarning() << "Can not find group named:" << groupId.username; - return; - } - - g->addPeer(go); +void ChatWidget::onGroupPeerStatusChanged(const QString& groupnumber, const GroupOccupant& go) { + const GroupId& groupId = GroupId(groupnumber); + Group* g = GroupList::findGroup(groupId); + if (!g) { + qWarning() << "Can not find group named:" << groupId.username; + return; + } + g->addPeer(go); } -void ChatWidget::onGroupTitleChanged(QString groupnumber, const QString &author, const QString &title) { - qDebug() << __func__ << "group" << groupnumber << title; - const GroupId &groupId = GroupId(groupnumber); - Group *g = GroupList::findGroup(groupId); - if (!g) { - qWarning() << "Can not find group" << groupnumber; - return; - } +void ChatWidget::onGroupTitleChanged(QString groupnumber, const QString& author, + const QString& title) { + qDebug() << __func__ << "group" << groupnumber << title; + const GroupId& groupId = GroupId(groupnumber); + Group* g = GroupList::findGroup(groupId); + if (!g) { + qWarning() << "Can not find group" << groupnumber; + return; + } - // contactListWidget->setGroupTitle(groupId, author, title); + // contactListWidget->setGroupTitle(groupId, author, title); - // FilterCriteria filter = getFilterCriteria(); - // widget->searchName(ui->searchContactText->text(), filterGroups(filter)); + // FilterCriteria filter = getFilterCriteria(); + // widget->searchName(ui->searchContactText->text(), filterGroups(filter)); } void ChatWidget::groupInvitesUpdate() { - if (unreadGroupInvites == 0) { - delete groupInvitesButton; - groupInvitesButton = nullptr; - } else if (!groupInvitesButton) { - groupInvitesButton = new QPushButton(this); - groupInvitesButton->setObjectName("green"); - // ui->statusLayout->insertWidget(2, groupInvitesButton); + if (unreadGroupInvites == 0) { + delete groupInvitesButton; + groupInvitesButton = nullptr; + } else if (!groupInvitesButton) { + groupInvitesButton = new QPushButton(this); + groupInvitesButton->setObjectName("green"); + // ui->statusLayout->insertWidget(2, groupInvitesButton); - connect(groupInvitesButton, &QPushButton::released, this, &ChatWidget::onGroupClicked); - } + connect(groupInvitesButton, &QPushButton::released, this, &ChatWidget::onGroupClicked); + } - if (groupInvitesButton) { - groupInvitesButton->setText(tr("%n New Group Invite(s)", "", unreadGroupInvites)); - } + if (groupInvitesButton) { + groupInvitesButton->setText(tr("%n New Group Invite(s)", "", unreadGroupInvites)); + } } void ChatWidget::groupInvitesClear() { - unreadGroupInvites = 0; - groupInvitesUpdate(); + unreadGroupInvites = 0; + groupInvitesUpdate(); } void ChatWidget::showProfile() { - auto profile = Nexus::getProfile(); - if (!profileForm) { - auto core = Core::getInstance(); - profileInfo = new ProfileInfo(core, profile); - profileForm = new ProfileForm(profileInfo); - } + auto profile = Nexus::getProfile(); + if (!profileForm) { + auto core = Core::getInstance(); + profileInfo = new ProfileInfo(core, profile); + profileForm = new ProfileForm(profileInfo); + } - if (!profileForm->isShown()) { - profileForm->showTo(getContentLayout()); - } + if (!profileForm->isShown()) { + profileForm->showTo(getContentLayout()); + } } -void ChatWidget::clearAllReceipts() -{ - sessionListWidget->clearAllReceipts(); -} +void ChatWidget::clearAllReceipts() { sessionListWidget->clearAllReceipts(); } void ChatWidget::on_nameClicked() { - qDebug() << __func__; - - showProfile(); + qDebug() << __func__; + showProfile(); } void ChatWidget::onGroupClicked() { - auto &settings = Settings::getInstance(); + auto& settings = Settings::getInstance(); - // hideMainForms(nullptr); -// if (!groupInviteForm) { -// groupInviteForm = new GroupInviteForm; -// connect(groupInviteForm, &GroupInviteForm::groupCreate, core, &Core::createGroup); -// } -// groupInviteForm->show(contentLayout); - // setWindowTitle(fromDialogType(DialogType::GroupDialog)); - // setActiveToolMenuButton(ActiveToolMenuButton::GroupButton); + // hideMainForms(nullptr); + // if (!groupInviteForm) { + // groupInviteForm = new GroupInviteForm; + // connect(groupInviteForm, &GroupInviteForm::groupCreate, core, &Core::createGroup); + // } + // groupInviteForm->show(contentLayout); + // setWindowTitle(fromDialogType(DialogType::GroupDialog)); + // setActiveToolMenuButton(ActiveToolMenuButton::GroupButton); } void ChatWidget::reloadTheme() { - setStyleSheet(Style::getStylesheet("window/chat.css")); - QString statusPanelStyle = Style::getStylesheet("window/statusPanel.css"); - // ui->tooliconsZone->setStyleSheet( - // Style::getStylesheet("tooliconsZone/tooliconsZone.css")); - // ui->statusPanel->setStyleSheet(statusPanelStyle); - ui->statusHead->setStyleSheet(statusPanelStyle); - ui->friendList->setStyleSheet(Style::getStylesheet("friendList/friendList.css")); - ui->statusButton->setStyleSheet(Style::getStylesheet("statusButton/statusButton.css")); - sessionListWidget->reDraw(); + setStyleSheet(Style::getStylesheet("window/chat.css")); + QString statusPanelStyle = Style::getStylesheet("window/statusPanel.css"); + // ui->tooliconsZone->setStyleSheet( + // Style::getStylesheet("tooliconsZone/tooliconsZone.css")); + // ui->statusPanel->setStyleSheet(statusPanelStyle); + ui->statusHead->setStyleSheet(statusPanelStyle); + ui->friendList->setStyleSheet(Style::getStylesheet("friendList/friendList.css")); + ui->statusButton->setStyleSheet(Style::getStylesheet("statusButton/statusButton.css")); + sessionListWidget->reDraw(); - // profilePicture->setStyleSheet(Style::getStylesheet("window/profile.css")); + // profilePicture->setStyleSheet(Style::getStylesheet("window/profile.css")); - if (contentLayout != nullptr) { - contentLayout->reloadTheme(); - } + if (contentLayout != nullptr) { + contentLayout->reloadTheme(); + } - // for (IMFriend *f : FriendList::getAllFriends()) { - // contactListWidget->getFriend(f->getPublicKey())->reloadTheme(); - // } + // for (IMFriend *f : FriendList::getAllFriends()) { + // contactListWidget->getFriend(f->getPublicKey())->reloadTheme(); + // } - sessionListWidget->reloadTheme(); + sessionListWidget->reloadTheme(); - ui->friendList->setAutoFillBackground(false); - ui->friendList->viewport()->setAutoFillBackground(false); + ui->friendList->setAutoFillBackground(false); + ui->friendList->viewport()->setAutoFillBackground(false); } void ChatWidget::setupSearch() { + filterMenu = new QMenu(this); + filterGroup = new QActionGroup(this); + filterDisplayGroup = new QActionGroup(this); + + filterDisplayName = new QAction(this); + filterDisplayName->setCheckable(true); + filterDisplayName->setChecked(true); + filterDisplayGroup->addAction(filterDisplayName); + filterMenu->addAction(filterDisplayName); + filterDisplayActivity = new QAction(this); + filterDisplayActivity->setCheckable(true); + filterDisplayGroup->addAction(filterDisplayActivity); + filterMenu->addAction(filterDisplayActivity); + + Settings::getInstance().getFriendSortingMode() == MessageSessionListWidget::SortingMode::Name + ? filterDisplayName->setChecked(true) + : filterDisplayActivity->setChecked(true); + filterMenu->addSeparator(); + + filterAllAction = new QAction(this); + filterAllAction->setCheckable(true); + filterAllAction->setChecked(true); + filterGroup->addAction(filterAllAction); + filterMenu->addAction(filterAllAction); + filterOnlineAction = new QAction(this); + filterOnlineAction->setCheckable(true); + filterGroup->addAction(filterOnlineAction); + filterMenu->addAction(filterOnlineAction); + filterOfflineAction = new QAction(this); + filterOfflineAction->setCheckable(true); + filterGroup->addAction(filterOfflineAction); + filterMenu->addAction(filterOfflineAction); + filterFriendsAction = new QAction(this); + filterFriendsAction->setCheckable(true); + filterGroup->addAction(filterFriendsAction); + filterMenu->addAction(filterFriendsAction); + filterGroupsAction = new QAction(this); + filterGroupsAction->setCheckable(true); + filterGroup->addAction(filterGroupsAction); + filterMenu->addAction(filterGroupsAction); + + filterDisplayName->setText(tr("By Name")); + filterDisplayActivity->setText(tr("By Activity")); + filterAllAction->setText(tr("All")); + filterOnlineAction->setText(tr("Online")); + filterOfflineAction->setText(tr("Offline")); + filterFriendsAction->setText(tr("Friends")); + filterGroupsAction->setText(tr("Groups")); + + ui->searchContactText->setPlaceholderText(tr("Search Contacts")); + connect(ui->searchContactText, &QLineEdit::textChanged, this, &ChatWidget::searchContacts); + + ui->searchContactFilterBox->setMenu(filterMenu); + updateFilterText(); - filterMenu = new QMenu(this); - filterGroup = new QActionGroup(this); - filterDisplayGroup = new QActionGroup(this); - - filterDisplayName = new QAction(this); - filterDisplayName->setCheckable(true); - filterDisplayName->setChecked(true); - filterDisplayGroup->addAction(filterDisplayName); - filterMenu->addAction(filterDisplayName); - filterDisplayActivity = new QAction(this); - filterDisplayActivity->setCheckable(true); - filterDisplayGroup->addAction(filterDisplayActivity); - filterMenu->addAction(filterDisplayActivity); - - Settings::getInstance().getFriendSortingMode() == MessageSessionListWidget::SortingMode::Name ? filterDisplayName->setChecked(true) : filterDisplayActivity->setChecked(true); - filterMenu->addSeparator(); - - filterAllAction = new QAction(this); - filterAllAction->setCheckable(true); - filterAllAction->setChecked(true); - filterGroup->addAction(filterAllAction); - filterMenu->addAction(filterAllAction); - filterOnlineAction = new QAction(this); - filterOnlineAction->setCheckable(true); - filterGroup->addAction(filterOnlineAction); - filterMenu->addAction(filterOnlineAction); - filterOfflineAction = new QAction(this); - filterOfflineAction->setCheckable(true); - filterGroup->addAction(filterOfflineAction); - filterMenu->addAction(filterOfflineAction); - filterFriendsAction = new QAction(this); - filterFriendsAction->setCheckable(true); - filterGroup->addAction(filterFriendsAction); - filterMenu->addAction(filterFriendsAction); - filterGroupsAction = new QAction(this); - filterGroupsAction->setCheckable(true); - filterGroup->addAction(filterGroupsAction); - filterMenu->addAction(filterGroupsAction); - - filterDisplayName->setText(tr("By Name")); - filterDisplayActivity->setText(tr("By Activity")); - filterAllAction->setText(tr("All")); - filterOnlineAction->setText(tr("Online")); - filterOfflineAction->setText(tr("Offline")); - filterFriendsAction->setText(tr("Friends")); - filterGroupsAction->setText(tr("Groups")); - - ui->searchContactText->setPlaceholderText(tr("Search Contacts")); - connect(ui->searchContactText, &QLineEdit::textChanged, this, &ChatWidget::searchContacts); - - ui->searchContactFilterBox->setMenu(filterMenu); - updateFilterText(); - - connect(filterGroup, &QActionGroup::triggered, this, &ChatWidget::searchContacts); - connect(filterDisplayGroup, &QActionGroup::triggered, this, &ChatWidget::changeDisplayMode); + connect(filterGroup, &QActionGroup::triggered, this, &ChatWidget::searchContacts); + connect(filterDisplayGroup, &QActionGroup::triggered, this, &ChatWidget::changeDisplayMode); } void ChatWidget::changeDisplayMode() { - filterDisplayGroup->setEnabled(false); + filterDisplayGroup->setEnabled(false); - // if (filterDisplayGroup->checkedAction() == filterDisplayActivity) { - // contactListWidget->setMode(FriendListWidget::SortingMode::Activity); - // } else if (filterDisplayGroup->checkedAction() == filterDisplayName) { - // contactListWidget->setMode(FriendListWidget::SortingMode::Name); - // } + // if (filterDisplayGroup->checkedAction() == filterDisplayActivity) { + // contactListWidget->setMode(FriendListWidget::SortingMode::Activity); + // } else if (filterDisplayGroup->checkedAction() == filterDisplayName) { + // contactListWidget->setMode(FriendListWidget::SortingMode::Name); + // } - searchContacts(); - filterDisplayGroup->setEnabled(true); + searchContacts(); + filterDisplayGroup->setEnabled(true); - updateFilterText(); + updateFilterText(); } void ChatWidget::searchContacts() { - QString searchString = ui->searchContactText->text(); + QString searchString = ui->searchContactText->text(); - qDebug() << __func__ << searchString; + qDebug() << __func__ << searchString; - FilterCriteria filter = getFilterCriteria(); + FilterCriteria filter = getFilterCriteria(); - sessionListWidget->searchChatrooms(searchString, filterOnline(filter), filterOffline(filter), filterGroups(filter)); - sessionListWidget->reDraw(); - updateFilterText(); + sessionListWidget->searchChatrooms(searchString, filterOnline(filter), filterOffline(filter), + filterGroups(filter)); + sessionListWidget->reDraw(); + updateFilterText(); } void ChatWidget::updateFilterText() { - QString action = filterDisplayGroup->checkedAction()->text(); - QString text = filterGroup->checkedAction()->text(); - text = action + QStringLiteral(" | ") + text; - ui->searchContactFilterBox->setText(text); + QString action = filterDisplayGroup->checkedAction()->text(); + QString text = filterGroup->checkedAction()->text(); + text = action + QStringLiteral(" | ") + text; + ui->searchContactFilterBox->setText(text); } ChatWidget::FilterCriteria ChatWidget::getFilterCriteria() const { - QAction *checked = filterGroup->checkedAction(); + QAction* checked = filterGroup->checkedAction(); - if (checked == filterOnlineAction) - return FilterCriteria::Online; - else if (checked == filterOfflineAction) - return FilterCriteria::Offline; - else if (checked == filterFriendsAction) - return FilterCriteria::Friends; - else if (checked == filterGroupsAction) - return FilterCriteria::Groups; + if (checked == filterOnlineAction) + return FilterCriteria::Online; + else if (checked == filterOfflineAction) + return FilterCriteria::Offline; + else if (checked == filterFriendsAction) + return FilterCriteria::Friends; + else if (checked == filterGroupsAction) + return FilterCriteria::Groups; - return FilterCriteria::All; + return FilterCriteria::All; } bool ChatWidget::filterGroups(FilterCriteria index) { - switch (index) { - case FilterCriteria::Offline: - case FilterCriteria::Friends: - return true; - default: - return false; - } + switch (index) { + case FilterCriteria::Offline: + case FilterCriteria::Friends: + return true; + default: + return false; + } } bool ChatWidget::filterOffline(FilterCriteria index) { - switch (index) { - case FilterCriteria::Online: - case FilterCriteria::Groups: - return true; - default: - return false; - } + switch (index) { + case FilterCriteria::Online: + case FilterCriteria::Groups: + return true; + default: + return false; + } } bool ChatWidget::filterOnline(FilterCriteria index) { - switch (index) { - case FilterCriteria::Offline: - case FilterCriteria::Groups: - return true; - default: - return false; - } + switch (index) { + case FilterCriteria::Offline: + case FilterCriteria::Groups: + return true; + default: + return false; + } } bool ChatWidget::groupsVisible() const { - FilterCriteria filter = getFilterCriteria(); - return !filterGroups(filter); + FilterCriteria filter = getFilterCriteria(); + return !filterGroups(filter); } void ChatWidget::retranslateUi() { @@ -734,153 +730,164 @@ void ChatWidget::retranslateUi() { } void ChatWidget::setupStatus() { - int icon_size = 15; - - // Preparing icons and set their size - statusOnline = new QAction(this); - statusOnline->setIcon(SvgUtils::prepareIcon(Status::getIconPath(Status::Status::Online), icon_size, icon_size)); - connect(statusOnline, &QAction::triggered, this, &ChatWidget::setStatusOnline); - - statusAway = new QAction(this); - statusAway->setIcon(SvgUtils::prepareIcon(Status::getIconPath(Status::Status::Away), icon_size, icon_size)); - connect(statusAway, &QAction::triggered, this, &ChatWidget::setStatusAway); - - statusBusy = new QAction(this); - statusBusy->setIcon(SvgUtils::prepareIcon(Status::getIconPath(Status::Status::Busy), icon_size, icon_size)); - connect(statusBusy, &QAction::triggered, this, &ChatWidget::setStatusBusy); - - QMenu *statusButtonMenu = new QMenu(ui->statusButton); - statusButtonMenu->addAction(statusOnline); - statusButtonMenu->addAction(statusAway); - statusButtonMenu->addAction(statusBusy); - ui->statusButton->setMenu(statusButtonMenu); - - // ui->searchContactText->setPlaceholderText(tr("Search Contacts")); - statusOnline->setText(tr("Online", "Button to set your status to 'Online'")); - statusAway->setText(tr("Away", "Button to set your status to 'Away'")); - statusBusy->setText(tr("Busy", "Button to set your status to 'Busy'")); - // actionLogout->setText(tr("Logout", "Tray action menu to logout user")); - // actionQuit->setText(tr("Exit", "Tray action menu to exit tox")); - // actionShow->setText(tr("Show", "Tray action menu to show qTox window")); + int icon_size = 15; + + // Preparing icons and set their size + statusOnline = new QAction(this); + statusOnline->setIcon(SvgUtils::prepareIcon(Status::getIconPath(Status::Status::Online), + icon_size, icon_size)); + connect(statusOnline, &QAction::triggered, this, &ChatWidget::setStatusOnline); + + statusAway = new QAction(this); + statusAway->setIcon( + SvgUtils::prepareIcon(Status::getIconPath(Status::Status::Away), icon_size, icon_size)); + connect(statusAway, &QAction::triggered, this, &ChatWidget::setStatusAway); + + statusBusy = new QAction(this); + statusBusy->setIcon( + SvgUtils::prepareIcon(Status::getIconPath(Status::Status::Busy), icon_size, icon_size)); + connect(statusBusy, &QAction::triggered, this, &ChatWidget::setStatusBusy); + + QMenu* statusButtonMenu = new QMenu(ui->statusButton); + statusButtonMenu->addAction(statusOnline); + statusButtonMenu->addAction(statusAway); + statusButtonMenu->addAction(statusBusy); + ui->statusButton->setMenu(statusButtonMenu); + + // ui->searchContactText->setPlaceholderText(tr("Search Contacts")); + statusOnline->setText(tr("Online", "Button to set your status to 'Online'")); + statusAway->setText(tr("Away", "Button to set your status to 'Away'")); + statusBusy->setText(tr("Busy", "Button to set your status to 'Busy'")); + // actionLogout->setText(tr("Logout", "Tray action menu to logout user")); + // actionQuit->setText(tr("Exit", "Tray action menu to exit tox")); + // actionShow->setText(tr("Show", "Tray action menu to show qTox window")); } -void ChatWidget::cancelFile(const QString &friendId, const QString &fileId) { - qDebug() << __func__ << "file:" << fileId; - auto frndId = FriendId{friendId}; +void ChatWidget::cancelFile(const QString& friendId, const QString& fileId) { + qDebug() << __func__ << "file:" << fileId; + auto frndId = FriendId{friendId}; - // Friend *f = FriendList::findFriend(frndId); - // if (!f) { - // qWarning() <<"IMFriend is no existing!" << friendId; - // return; - // } + // Friend *f = FriendList::findFriend(frndId); + // if (!f) { + // qWarning() <<"IMFriend is no existing!" << friendId; + // return; + // } - sessionListWidget->setFriendFileCancelled(frndId, fileId); + sessionListWidget->setFriendFileCancelled(frndId, fileId); } void ChatWidget::dispatchFile(ToxFile file) { - qDebug() << __func__ << "file:" << file.toString(); - - const auto &cId = ContactId(file.getFriendId()); - + qDebug() << __func__ << "file:" << file.toString(); - if (file.status == FileStatus::INITIALIZING && file.direction == FileDirection::RECEIVING) { + const auto& cId = ContactId(file.getFriendId()); - const Settings &settings = Settings::getInstance(); -// QString autoAcceptDir = settings.getAutoAcceptDir(cId); -// if (autoAcceptDir.isEmpty() && ok::base::OkSettings::getInstance().getAutoSaveEnabled()) { - auto autoAcceptDir = settings.getGlobalAutoAcceptDir(); -// } + if (file.status == FileStatus::INITIALIZING && file.direction == FileDirection::RECEIVING) { + const Settings& settings = Settings::getInstance(); + // QString autoAcceptDir = settings.getAutoAcceptDir(cId); + // if (autoAcceptDir.isEmpty() && + // ok::base::OkSettings::getInstance().getAutoSaveEnabled()) { + auto autoAcceptDir = settings.getGlobalAutoAcceptDir(); + // } -// auto maxAutoAcceptSize = settings.getMaxAutoAcceptSize(); -// bool autoAcceptSizeCheckPassed = maxAutoAcceptSize == 0 || maxAutoAcceptSize >= file.fileSize; + // auto maxAutoAcceptSize = settings.getMaxAutoAcceptSize(); + // bool autoAcceptSizeCheckPassed = maxAutoAcceptSize == 0 || maxAutoAcceptSize >= + // file.fileSize; -// if (!autoAcceptDir.isEmpty() && autoAcceptSizeCheckPassed) { - acceptFileTransfer(file, autoAcceptDir); -// } - } + // if (!autoAcceptDir.isEmpty() && autoAcceptSizeCheckPassed) { + acceptFileTransfer(file, autoAcceptDir); + // } + } - sessionListWidget->setFriendFileReceived(cId, file); + sessionListWidget->setFriendFileReceived(cId, file); } void ChatWidget::dispatchFileWithBool(ToxFile file, bool) { dispatchFile(file); } -void ChatWidget::dispatchFileSendFailed(QString friendId, const QString &fileName) { // const auto &friendPk = ToxPk(receiver); +void ChatWidget::dispatchFileSendFailed( + QString friendId, const QString& fileName) { // const auto &friendPk = ToxPk(receiver); - // TODO - // chatForm.value()->addSystemInfoMessage( - // tr("Failed to send file \"%1\"").arg(fileName), ChatMessage::ERROR, - // QDateTime::currentDateTime()); + // TODO + // chatForm.value()->addSystemInfoMessage( + // tr("Failed to send file \"%1\"").arg(fileName), ChatMessage::ERROR, + // QDateTime::currentDateTime()); } void ChatWidget::setStatusOnline() { - // if (!ui->statusButton->isEnabled()) { - // return; - // } + // if (!ui->statusButton->isEnabled()) { + // return; + // } - core->setStatus(Status::Status::Online); + core->setStatus(Status::Status::Online); } void ChatWidget::setStatusAway() { - // if (!ui->statusButton->isEnabled()) { - // return; - // } + // if (!ui->statusButton->isEnabled()) { + // return; + // } - core->setStatus(Status::Status::Away); + core->setStatus(Status::Status::Away); } void ChatWidget::setStatusBusy() { - // if (!ui->statusButton->isEnabled()) { - // return; - // } + // if (!ui->statusButton->isEnabled()) { + // return; + // } - core->setStatus(Status::Status::Busy); + core->setStatus(Status::Status::Busy); } void ChatWidget::onAvInvite(ToxPeer peerId, bool video) { - qDebug() << __func__ << "friendId" << peerId << video; - sessionListWidget->setFriendAvInvite(peerId, video); + qDebug() << __func__ << "friendId" << peerId << video; + sessionListWidget->setFriendAvInvite(peerId, video); - // auto testedFlag = video ? - // Settings::AutoAcceptCall::Video : Settings::AutoAcceptCall::Audio; + // auto testedFlag = video ? + // Settings::AutoAcceptCall::Video : Settings::AutoAcceptCall::Audio; - // // AutoAcceptCall is set for this friend - // if (Settings::getInstance() - // .getAutoAcceptCall(*f) - // .testFlag(testedFlag)) { + // // AutoAcceptCall is set for this friend + // if (Settings::getInstance() + // .getAutoAcceptCall(*f) + // .testFlag(testedFlag)) { - // CoreAV *coreav = CoreAV::getInstance(); - // QMetaObject::invokeMethod(coreav, "answerCall", Qt::QueuedConnection, - // Q_ARG(ToxPeer, peerId), Q_ARG(bool, video)); + // CoreAV *coreav = CoreAV::getInstance(); + // QMetaObject::invokeMethod(coreav, "answerCall", Qt::QueuedConnection, + // Q_ARG(ToxPeer, peerId), Q_ARG(bool, video)); - // onAvStart(friendId, video); - // } else { - // headWidget->createCallConfirm(peerId, video); - // headWidget->showCallConfirm(); - // lastCallIsVideo = video; - // emit incomingNotification(fId); - // } + // onAvStart(friendId, video); + // } else { + // headWidget->createCallConfirm(peerId, video); + // headWidget->showCallConfirm(); + // lastCallIsVideo = video; + // emit incomingNotification(fId); + // } } -void ChatWidget::onAvStart(const FriendId &friendId, bool video) { - qDebug() << __func__ << "friendId" << friendId; - sessionListWidget->setFriendAvStart(friendId, video); +void ChatWidget::onAvStart(const FriendId& friendId, bool video) { + qDebug() << __func__ << "friendId" << friendId; + sessionListWidget->setFriendAvStart(friendId, video); } -void ChatWidget::onAvEnd(const FriendId &friendId, bool error) { - qDebug() << __func__ << "friendId" << friendId << "error" << error; - sessionListWidget->setFriendAvEnd(friendId, error); +void ChatWidget::onAvEnd(const FriendId& friendId, bool error) { + qDebug() << __func__ << "friendId" << friendId << "error" << error; + sessionListWidget->setFriendAvEnd(friendId, error); - // headWidget->removeCallConfirm(); - // // Fixes an OS X bug with ending a call while in full screen - // if (netcam && netcam->isFullScreen()) { - // netcam->showNormal(); - // } + // headWidget->removeCallConfirm(); + // // Fixes an OS X bug with ending a call while in full screen + // if (netcam && netcam->isFullScreen()) { + // netcam->showNormal(); + // } - // emit stopNotification(); - // emit endCallNotification(); + // emit stopNotification(); + // emit endCallNotification(); - // auto status = Core::getInstance()->getStatus(); - // updateCallButtons(status); - // stopCounter(error); - // hideNetcam(); + // auto status = Core::getInstance()->getStatus(); + // updateCallButtons(status); + // stopCounter(error); + // hideNetcam(); +} + +void ChatWidget::onFriendNickChanged(const FriendId& friendPk, const QString& nickname) { + sessionListWidget->setFriendName(friendPk, nickname); +} +void ChatWidget::onFriendAvatarChanged(const FriendId& friendPk, const QByteArray& avatar) { + sessionListWidget->setFriendAvatar(friendPk, avatar); } diff --git a/src/modules/im/src/widget/ChatWidget.h b/src/modules/im/src/widget/ChatWidget.h index 303c4898..352b38a4 100644 --- a/src/modules/im/src/widget/ChatWidget.h +++ b/src/modules/im/src/widget/ChatWidget.h @@ -17,12 +17,12 @@ #ifndef CHATWIDGET_H #define CHATWIDGET_H -#include "MainLayout.h" -#include "contentlayout.h" -#include "MessageSessionListWidget.h" #include #include #include +#include "MainLayout.h" +#include "MessageSessionListWidget.h" +#include "contentlayout.h" namespace Ui { class ChatWidget; @@ -39,153 +39,146 @@ class ProfileInfo; * @brief The ChatWidget class */ class ChatWidget : public MainLayout { - Q_OBJECT + Q_OBJECT public: + enum class FilterCriteria { All = 0, Online, Offline, Friends, Groups }; - enum class FilterCriteria { All = 0, Online, Offline, Friends, Groups }; - - ChatWidget(QWidget *parent = nullptr); - ~ChatWidget(); + ChatWidget(QWidget* parent = nullptr); + ~ChatWidget(); - [[nodiscard]] ContentLayout *getContentLayout() const override { + [[nodiscard]] ContentLayout* getContentLayout() const override { assert(contentLayout); - return contentLayout; - } -// void connectCircleWidget(); -// void searchCircle(CircleWidget &circleWidget); - AddFriendForm *openFriendAddForm(); - void reloadTheme(); - void retranslateUi(); - void showProfile(); - void clearAllReceipts(); + return contentLayout; + } + // void connectCircleWidget(); + // void searchCircle(CircleWidget &circleWidget); + AddFriendForm* openFriendAddForm(); + void reloadTheme(); + void retranslateUi(); + void showProfile(); + void clearAllReceipts(); protected: - void showEvent(QShowEvent*) override; -private: - Ui::ChatWidget *ui; - std::unique_ptr contentWidget; - ContentLayout* contentLayout; - std::unique_ptr sessionListWidget; - CircleWidget *circleWidget; - - Core *core; - CoreFile *coreFile; - - QAction *statusOnline; - QAction *statusAway; - QAction *statusBusy; - QAction *actionLogout; - QAction *actionQuit; - QAction *actionShow; - void setStatusOnline(); - void setStatusAway(); - void setStatusBusy(); - - GroupInviteForm *groupInviteForm; - uint32_t unreadGroupInvites; - QPushButton *friendRequestsButton; - QPushButton *groupInvitesButton; - - std::unique_ptr< AddFriendForm > addFriendForm; - - QMenu *filterMenu; - - QActionGroup *filterGroup; - QAction *filterAllAction; - QAction *filterOnlineAction; - QAction *filterOfflineAction; - QAction *filterFriendsAction; - QAction *filterGroupsAction; - - QActionGroup *filterDisplayGroup; - QAction *filterDisplayName; - QAction *filterDisplayActivity; - - ProfileInfo *profileInfo; - ProfileForm *profileForm; - - void init(); - void deinit(); - void updateIcons(); - void setupSearch(); - void searchContacts(); - - void updateFilterText(); - FilterCriteria getFilterCriteria() const; - static bool filterGroups(FilterCriteria index); - static bool filterOnline(FilterCriteria index); - static bool filterOffline(FilterCriteria index); - bool groupsVisible() const; - - void connectToCore(Core* core); - void connectToCoreFile(CoreFile* coreFile); - - void groupInvitesUpdate(); - void groupInvitesClear(); - + void showEvent(QShowEvent*) override; +private: + Ui::ChatWidget* ui; + std::unique_ptr contentWidget; + ContentLayout* contentLayout; + std::unique_ptr sessionListWidget; + CircleWidget* circleWidget; + + Core* core; + CoreFile* coreFile; + + QAction* statusOnline; + QAction* statusAway; + QAction* statusBusy; + QAction* actionLogout; + QAction* actionQuit; + QAction* actionShow; + void setStatusOnline(); + void setStatusAway(); + void setStatusBusy(); + + GroupInviteForm* groupInviteForm; + uint32_t unreadGroupInvites; + QPushButton* friendRequestsButton; + QPushButton* groupInvitesButton; + + std::unique_ptr addFriendForm; + + QMenu* filterMenu; + + QActionGroup* filterGroup; + QAction* filterAllAction; + QAction* filterOnlineAction; + QAction* filterOfflineAction; + QAction* filterFriendsAction; + QAction* filterGroupsAction; + + QActionGroup* filterDisplayGroup; + QAction* filterDisplayName; + QAction* filterDisplayActivity; + + ProfileInfo* profileInfo; + ProfileForm* profileForm; + + void init(); + void deinit(); + void updateIcons(); + void setupSearch(); + void searchContacts(); + + void updateFilterText(); + FilterCriteria getFilterCriteria() const; + static bool filterGroups(FilterCriteria index); + static bool filterOnline(FilterCriteria index); + static bool filterOffline(FilterCriteria index); + bool groupsVisible() const; + + void connectToCore(Core* core_); + void connectToCoreFile(CoreFile* coreFile); + + void groupInvitesUpdate(); + void groupInvitesClear(); public slots: - void on_nameClicked(); + void on_nameClicked(); - void onCoreChanged(Core &core); + void onCoreChanged(Core& core); - void onStatusSet(Status::Status status); - void onUsernameSet(const QString& username); - void onStatusMessageSet(const QString &statusMessage) ; + void onStatusSet(Status::Status status); + void onUsernameSet(const QString& username); + void onStatusMessageSet(const QString& statusMessage); - void onFriendAdded(const Friend* f); - void onFriendRemoved(const Friend* f); - void doSendMessage(const QString &to, bool isGroup); + void onFriendNickChanged(const FriendId& friendPk, const QString& nickname); + void onFriendAvatarChanged(const FriendId& friendPk, const QByteArray& avatar); + void onFriendAdded(const Friend* f); + void onFriendRemoved(const Friend* f); + void doSendMessage(const QString& to, bool isGroup); - void onFriendStatusChanged(const FriendId &friendPk, Status::Status status); - void onFriendStatusMessageChanged(const FriendId &friendPk, - const QString &message); + void onFriendStatusChanged(const FriendId& friendPk, Status::Status status); + void onFriendStatusMessageChanged(const FriendId& friendPk, const QString& message); - void onMessageSessionReceived(const ContactId &contactId, const QString &sid); + void onMessageSessionReceived(const ContactId& contactId, const QString& sid); - void onFriendMessageReceived(const FriendId &friendId, - const FriendMessage &message, - bool isAction); + void onFriendMessageReceived(const FriendId& friendId, + const FriendMessage& message, + bool isAction); - void onReceiptReceived(const FriendId &friendPk, MsgId receipt); + void onReceiptReceived(const FriendId& friendPk, MsgId receipt); - void onFriendTypingChanged(const FriendId &friendnumber, bool isTyping); + void onFriendTypingChanged(const FriendId& friendnumber, bool isTyping); - void onGroupAdded(const Group* g); - void onGroupRemoved(const Group* g); + void onGroupAdded(const Group* g); + void onGroupRemoved(const Group* g); void onGroupMessageReceived(GroupId groupId, GroupMessage msg); + void onGroupInviteAccepted(const GroupInvite& inviteInfo); + void onGroupPeerListChanged(QString groupnumber); -void onGroupInviteAccepted(const GroupInvite &inviteInfo); - -void onGroupPeerListChanged(QString groupnumber); - -void onGroupPeerSizeChanged(QString groupnumber, const uint size); - -void onGroupPeerNameChanged(QString groupnumber, const FriendId &peerPk, - const QString &newName); -void onGroupTitleChanged(QString groupnumber, const QString &author, - const QString &title); - -void onGroupPeerStatusChanged(const QString&, const GroupOccupant&); -void onGroupClicked(); - + void onGroupPeerSizeChanged(QString groupnumber, const uint size); + void onGroupPeerNameChanged(QString groupnumber, const FriendId& peerPk, + const QString& newName); + void onGroupTitleChanged(QString groupnumber, const QString& author, const QString& title); -void changeDisplayMode(); -void setupStatus(); -void cancelFile(const QString &friendId, const QString &fileId); -void dispatchFile(ToxFile file); -void dispatchFileWithBool(ToxFile file, bool); -void dispatchFileSendFailed(QString friendId, const QString &fileName); + void onGroupPeerStatusChanged(const QString&, const GroupOccupant&); + void onGroupClicked(); -void onAvInvite(ToxPeer peerId, bool video); -void onAvStart(const FriendId & friendId, bool video); -void onAvEnd(const FriendId & friendId, bool error); + void changeDisplayMode(); + void setupStatus(); + void cancelFile(const QString& friendId, const QString& fileId); + void dispatchFile(ToxFile file); + void dispatchFileWithBool(ToxFile file, bool); + void dispatchFileSendFailed(QString friendId, const QString& fileName); + void onAvInvite(ToxPeer peerId, bool video); + void onAvStart(const FriendId& friendId, bool video); + void onAvEnd(const FriendId& friendId, bool error); }; -#endif // CHATWIDGET_H +#endif // CHATWIDGET_H diff --git a/src/modules/im/src/widget/ContactWidget.cpp b/src/modules/im/src/widget/ContactWidget.cpp index dcf4cb2c..19680d2a 100644 --- a/src/modules/im/src/widget/ContactWidget.cpp +++ b/src/modules/im/src/widget/ContactWidget.cpp @@ -1,4 +1,6 @@ #include "ContactWidget.h" +#include "Bus.h" +#include "application.h" #include "friendlistwidget.h" #include "src/lib/settings/style.h" #include "src/nexus.h" @@ -15,44 +17,47 @@ #include #include -ContactWidget::ContactWidget(QWidget *parent) : MainLayout(parent), ui(new Ui::ContactWidget), addForm{nullptr} { - ui->setupUi(this); - layout()->setMargin(0); - layout()->setSpacing(0); +ContactWidget::ContactWidget(QWidget* parent) + : MainLayout(parent), ui(new Ui::ContactWidget), addForm{nullptr} { + ui->setupUi(this); + layout()->setMargin(0); + layout()->setSpacing(0); - // 右侧内容容器 - contentWidget = std::make_unique(this); - contentWidget->setObjectName("ContactContentWidget"); - contentWidget->setContentsMargins(8, 8, 8, 8); - contentLayout = std::make_unique(contentWidget.get()); + // 右侧内容容器 + contentWidget = std::make_unique(this); + contentWidget->setObjectName("ContactContentWidget"); + contentWidget->setContentsMargins(8, 8, 8, 8); + contentLayout = std::make_unique(contentWidget.get()); - // 左侧 - contactListWidget = new FriendListWidget(this, contentLayout.get(), false); - contactListWidget->setGeometry(0, 0, 400, 400); - contactListWidget->layout()->setAlignment(Qt::AlignTop | Qt::AlignVCenter); - connect(contactListWidget, &FriendListWidget::deleteFriendWidget, this, &ContactWidget::do_friendDelete); + // 左侧朋友列表 + contactListWidget = new FriendListWidget(this, contentLayout.get(), false); + contactListWidget->setGeometry(0, 0, 400, 400); + contactListWidget->layout()->setAlignment(Qt::AlignTop | Qt::AlignVCenter); + connect(contactListWidget, + &FriendListWidget::deleteFriendWidget, + this, + &ContactWidget::do_friendDelete); - ui->scrollAreaWidgetContents->setGeometry(0, 0, 200, 500); - ui->scrollAreaWidgetContents->layout()->setAlignment(Qt::AlignTop | Qt::AlignVCenter); - ui->scrollAreaWidgetContents->layout()->addWidget((QWidget *)contactListWidget); + ui->scrollAreaWidgetContents->setGeometry(0, 0, 200, 500); + ui->scrollAreaWidgetContents->layout()->setAlignment(Qt::AlignTop | Qt::AlignVCenter); + ui->scrollAreaWidgetContents->layout()->addWidget((QWidget*)contactListWidget); - ui->mainSplitter->addWidget(contentWidget.get()); - ui->mainSplitter->setSizes(QList() << 200 << 500); + ui->mainSplitter->addWidget(contentWidget.get()); + ui->mainSplitter->setSizes(QList() << 200 << 500); - //ui->searchText->setPlaceholderText(tr("Search Contacts")); + // ui->searchText->setPlaceholderText(tr("Search Contacts")); - init(); + init(); - reloadTheme(); + reloadTheme(); } ContactWidget::~ContactWidget() { - deinit(); - delete ui; + deinit(); + delete ui; } -void ContactWidget::reloadTheme() -{ +void ContactWidget::reloadTheme() { setStyleSheet(Style::getStylesheet("contact/ContactWidget.css")); // I don't know why QTimer::singleShot(0, this, [this]() { @@ -62,7 +67,6 @@ void ContactWidget::reloadTheme() style()->polish(ui->addBtn); ui->searchText->updateGeometry(); }); - ui->friendList->setStyleSheet(Style::getStylesheet("contact/ContactList.css")); contactListWidget->reloadTheme(); @@ -72,290 +76,307 @@ void ContactWidget::reloadTheme() ui->friendList->viewport()->setAutoFillBackground(false); } -AddFriendForm *ContactWidget::makeAddForm() { - if (!addForm) { - addForm = new AddFriendForm(this); - - // connect(addForm, &AddFriendForm::friendRequestsSeen, this, - // &ContactWidget::friendRequestsUpdate); - connect(addForm, &AddFriendForm::friendRequested, this, &ContactWidget::do_friendRequest); - connect(addForm, &AddFriendForm::friendRequestAccepted, this, &ContactWidget::do_friendRequestAccept); - connect(addForm, &AddFriendForm::friendRequestRejected, this, &ContactWidget::do_friendRequestReject); - } +AddFriendForm* ContactWidget::makeAddForm() { + if (!addForm) { + addForm = new AddFriendForm(this); + + // connect(addForm, &AddFriendForm::friendRequestsSeen, this, + // &ContactWidget::friendRequestsUpdate); + connect(addForm, &AddFriendForm::friendRequested, this, &ContactWidget::do_friendRequest); + connect(addForm, + &AddFriendForm::friendRequestAccepted, + this, + &ContactWidget::do_friendRequestAccept); + connect(addForm, + &AddFriendForm::friendRequestRejected, + this, + &ContactWidget::do_friendRequestReject); + } - return addForm; + return addForm; } void ContactWidget::do_openAddForm() { makeAddForm()->showTo(getContentLayout()); } void ContactWidget::init() { - connect(Nexus::getProfile(), &Profile::coreChanged, this, &ContactWidget::onCoreChanged); - - connect(ui->addBtn, &QPushButton::released, this, &ContactWidget::do_openAddForm); + connect(ok::Application::Instance()->bus(), + &ok::Bus::coreChanged, + this, + &ContactWidget::onCoreChanged); + connect(ui->addBtn, &QPushButton::released, this, &ContactWidget::do_openAddForm); } void ContactWidget::deinit() { - disconnect(Nexus::getProfile(), &Profile::coreChanged, this, &ContactWidget::onCoreChanged); - disconnect(ui->addBtn, &QPushButton::released, this, &ContactWidget::do_openAddForm); + disconnect(ok::Application::Instance()->bus(), + &ok::Bus::coreChanged, + this, + &ContactWidget::onCoreChanged); + disconnect(ui->addBtn, &QPushButton::released, this, &ContactWidget::do_openAddForm); } -void ContactWidget::onCoreChanged(Core &core_) { - qDebug() << __func__ << &core_; - core = &core_; - connectToCore(core); - - std::list fl; - core->loadFriendList(fl); - for (auto &fk : fl) { - contactListWidget->addFriend(fk); - } - - core->loadGroupList(); +void ContactWidget::onCoreChanged(Core* core_) { + qDebug() << __func__ << &core_; + core = core_; + connectToCore(core); } -void ContactWidget::connectToCore(Core *core) { - qDebug() << __func__ << core; +void ContactWidget::connectToCore(Core* core) { + qDebug() << __func__ << core; + + connect(core, &Core::started, [core, this]() { + std::list fl; + core->loadFriendList(fl); + for (auto& fk : fl) { + contactListWidget->addFriend(fk); + } + core->loadGroupList(); + }); - // 好友请求 - connect(core, &Core::friendRequestReceived, this, &ContactWidget::onFriendRequest); + // 好友请求 + connect(core, &Core::friendRequestReceived, this, &ContactWidget::onFriendRequest); - connect(core, &Core::friendAdded, this, &ContactWidget::onFriendAdded); + connect(core, &Core::friendAdded, this, &ContactWidget::onFriendAdded); - connect(core, &Core::friendUsernameChanged, this, &ContactWidget::onFriendUsernameChanged); + connect(core, &Core::friendUsernameChanged, this, &ContactWidget::onFriendNickChanged); - connect(core, &Core::friendAvatarChanged, this, &ContactWidget::onFriendAvatarChanged); - connect(core, &Core::friendAliasChanged, this, &ContactWidget::onFriendAliasChanged); - connect(core, &Core::friendStatusChanged, this, &ContactWidget::onFriendStatusChanged); - connect(core, &Core::friendStatusMessageChanged, this, &ContactWidget::onFriendStatusMessageChanged); + connect(core, &Core::friendAvatarChanged, this, &ContactWidget::onFriendAvatarChanged); + connect(core, &Core::friendAliasChanged, this, &ContactWidget::onFriendAliasChanged); + connect(core, &Core::friendStatusChanged, this, &ContactWidget::onFriendStatusChanged); + connect(core, + &Core::friendStatusMessageChanged, + this, + &ContactWidget::onFriendStatusMessageChanged); - connect(core, &Core::groupAdded, this, &ContactWidget::onGroupJoined); + connect(core, &Core::groupAdded, this, &ContactWidget::onGroupJoined); - connect(core, &Core::groupInfoReceipt, this, &ContactWidget::onGroupInfoReceived); + connect(core, &Core::groupInfoReceipt, this, &ContactWidget::onGroupInfoReceived); - connect(core, &Core::groupSubjectChanged, this, &ContactWidget::onGroupSubjectChanged); - connect(core, &Core::groupInviteReceived, this, &ContactWidget::onGroupInviteReceived); + connect(core, &Core::groupSubjectChanged, this, &ContactWidget::onGroupSubjectChanged); + connect(core, &Core::groupInviteReceived, this, &ContactWidget::onGroupInviteReceived); - connect(core, &Core::groupPeerlistChanged, this, &ContactWidget::onGroupPeerListChanged); - connect(core, &Core::groupPeerSizeChanged, this, &ContactWidget::onGroupPeerSizeChanged); - connect(core, &Core::groupPeerNameChanged, this, &ContactWidget::onGroupPeerNameChanged); - connect(core, &Core::groupPeerStatusChanged, this, &ContactWidget::onGroupPeerStatusChanged); + connect(core, &Core::groupPeerlistChanged, this, &ContactWidget::onGroupPeerListChanged); + connect(core, &Core::groupPeerSizeChanged, this, &ContactWidget::onGroupPeerSizeChanged); + connect(core, &Core::groupPeerNameChanged, this, &ContactWidget::onGroupPeerNameChanged); + connect(core, &Core::groupPeerStatusChanged, this, &ContactWidget::onGroupPeerStatusChanged); } -void ContactWidget::onFriendAdded(const FriendInfo &frnd) { - qDebug() << __func__ << "friend:" << frnd.getId().toString(); - if (!frnd.getId().isValid()) { - return; - } - contactListWidget->addFriend(frnd); +void ContactWidget::onFriendAdded(const FriendInfo& frnd) { + qDebug() << __func__ << "friend:" << frnd.getId().toString(); + if (!frnd.getId().isValid()) { + return; + } + contactListWidget->addFriend(frnd); } -void ContactWidget::onFriendAvatarChanged(const FriendId &friendnumber, const QByteArray &avatar) { - qDebug() << __func__ << "friend:" << friendnumber.toString() << avatar.size(); - contactListWidget->setFriendAvatar(friendnumber, avatar); +void ContactWidget::onFriendAvatarChanged(const FriendId& friendnumber, const QByteArray& avatar) { + qDebug() << __func__ << "friend:" << friendnumber.toString() << avatar.size(); + contactListWidget->setFriendAvatar(friendnumber, avatar); } -void ContactWidget::onFriendAliasChanged(const FriendId &friendPk, const QString &alias) -{ +void ContactWidget::onFriendAliasChanged(const FriendId& friendPk, const QString& alias) { qDebug() << __func__ << "friend:" << friendPk.toString() << "alias:" << alias; contactListWidget->setFriendAlias(friendPk, alias); } -void ContactWidget::onFriendUsernameChanged(const FriendId &friendPk, const QString &username) { - qDebug() << __func__ << "friend:" << friendPk.toString() << "name:" << username; - contactListWidget->setFriendName(friendPk, username); +void ContactWidget::onFriendNickChanged(const FriendId& friendPk, const QString& nick) { + qDebug() << __func__ << "friend:" << friendPk.toString() << "nick:" << nick; + contactListWidget->setFriendName(friendPk, nick); } -void ContactWidget::onFriendStatusChanged(const FriendId &friendPk, Status::Status status) { - qDebug() << __func__ << friendPk.toString() << "status:" << (int)status; - // const auto &friendPk = FriendList::id2Key(friendPk); - contactListWidget->setFriendStatus(friendPk, status); - // IMFriend *f = FriendList::findFriend(friendPk); - // if (!f) { - // qWarning() << "Unable to find friend" << friendPk; - // return; - // } - // - // bool isActualChange = f->getStatus() != status; - // - // FriendWidget *widget = // friendWidgets[f->getPublicKey()]; - // contactListWidget->getFriend(f->getPublicKey()); - // if (isActualChange) { - // if (!Status::isOnline(f->getStatus())) { - // contactListWidget->moveWidget(widget, Status::Status::Online); - // } else if (status == Status::Status::Offline) { - // contactListWidget->moveWidget(widget, Status::Status::Offline); - // } - // } - // - // f->setStatus(status); - - // if (widget->isActive()) { - // setWindowTitle(widget->getSubject()); - // } - // - // ContentDialogManager::getInstance()->updateFriendStatus(friendPk); +void ContactWidget::onFriendStatusChanged(const FriendId& friendPk, Status::Status status) { + qDebug() << __func__ << friendPk.toString() << "status:" << (int)status; + // const auto &friendPk = FriendList::id2Key(friendPk); + contactListWidget->setFriendStatus(friendPk, status); + // IMFriend *f = FriendList::findFriend(friendPk); + // if (!f) { + // qWarning() << "Unable to find friend" << friendPk; + // return; + // } + // + // bool isActualChange = f->getStatus() != status; + // + // FriendWidget *widget = // friendWidgets[f->getPublicKey()]; + // contactListWidget->getFriend(f->getPublicKey()); + // if (isActualChange) { + // if (!Status::isOnline(f->getStatus())) { + // contactListWidget->moveWidget(widget, Status::Status::Online); + // } else if (status == Status::Status::Offline) { + // contactListWidget->moveWidget(widget, Status::Status::Offline); + // } + // } + // + // f->setStatus(status); + + // if (widget->isActive()) { + // setWindowTitle(widget->getSubject()); + // } + // + // ContentDialogManager::getInstance()->updateFriendStatus(friendPk); } -void ContactWidget::onFriendStatusMessageChanged(const FriendId &friendPk, const QString &message) { - - contactListWidget->setFriendStatusMsg(friendPk, message); - - // IMFriend *f = FriendList::findFriend(friendPk); - // if (!f) { - // return; - // } - // - // QString str = message; - // str.replace('\n', ' ').remove('\r').remove(QChar('\0')); - // f->setStatusMessage(str); - // - // chatForms[friendPk]->setStatusMessage(str); - // - // auto frd = contactListWidget->getFriend(friendPk); - // if(frd){ - // frd->setStatusMsg(str); - // } +void ContactWidget::onFriendStatusMessageChanged(const FriendId& friendPk, const QString& message) { + contactListWidget->setFriendStatusMsg(friendPk, message); + + // IMFriend *f = FriendList::findFriend(friendPk); + // if (!f) { + // return; + // } + // + // QString str = message; + // str.replace('\n', ' ').remove('\r').remove(QChar('\0')); + // f->setStatusMessage(str); + // + // chatForms[friendPk]->setStatusMessage(str); + // + // auto frd = contactListWidget->getFriend(friendPk); + // if(frd){ + // frd->setStatusMsg(str); + // } } -void ContactWidget::onFriendRequest(const FriendId &friendPk, const QString &message) { - qDebug() << __func__ << friendPk.toString() << message; - do_openAddForm(); - Widget::getInstance()->newMessageAlert(window(), isActiveWindow(), true, true); +void ContactWidget::onFriendRequest(const FriendId& friendPk, const QString& message) { + qDebug() << __func__ << friendPk.toString() << message; + do_openAddForm(); + Widget::getInstance()->newMessageAlert(window(), isActiveWindow(), true, true); #if DESKTOP_NOTIFICATIONS - if (settings.getNotifyHide()) { - notifier.notifyMessageSimple(DesktopNotify::MessageType::FRIEND_REQUEST); - } else { - notifier.notifyMessage(friendPk.toString() + tr(" sent you a friend request."), message); - } + if (settings.getNotifyHide()) { + notifier.notifyMessageSimple(DesktopNotify::MessageType::FRIEND_REQUEST); + } else { + notifier.notifyMessage(friendPk.toString() + tr(" sent you a friend request."), message); + } #endif - // } + // } } -void ContactWidget::do_friendRequest(const FriendId &friendPk, const QString &nick, const QString &message) { - qDebug() << __func__ << friendPk.toString(); - core->requestFriendship(friendPk, nick, message); +void ContactWidget::do_friendRequest(const FriendId& friendPk, + const QString& nick, + const QString& message) { + qDebug() << __func__ << friendPk.toString(); + core->requestFriendship(friendPk, nick, message); } -void ContactWidget::do_friendDelete(const FriendId &friendPk) { - qDebug() << __func__ << friendPk.toString(); - core->removeFriend(friendPk.toString()); +void ContactWidget::do_friendDelete(const FriendId& friendPk) { + qDebug() << __func__ << friendPk.toString(); + core->removeFriend(friendPk.toString()); } -void ContactWidget::do_friendRequestAccept(const FriendId &friendPk) { - qDebug() << __func__ << friendPk.toString(); - core->acceptFriendRequest(friendPk); +void ContactWidget::do_friendRequestAccept(const FriendId& friendPk) { + qDebug() << __func__ << friendPk.toString(); + core->acceptFriendRequest(friendPk); } -void ContactWidget::do_friendRequestReject(const FriendId &friendPk) { - qDebug() << __func__ << friendPk.toString(); - core->rejectFriendRequest(friendPk); +void ContactWidget::do_friendRequestReject(const FriendId& friendPk) { + qDebug() << __func__ << friendPk.toString(); + core->rejectFriendRequest(friendPk); } -void ContactWidget::onGroupJoined(const GroupId &groupId, const QString &name) { - qDebug() << __func__ << groupId.toString() << name; - auto group = contactListWidget->addGroup(groupId, name); - qDebug() << "Created group:" << group << "=>" << groupId.toString(); +void ContactWidget::onGroupJoined(const GroupId& groupId, const QString& name) { + qDebug() << __func__ << groupId.toString() << name; + auto group = contactListWidget->addGroup(groupId, name); + qDebug() << "Created group:" << group << "=>" << groupId.toString(); } -void ContactWidget::onGroupInfoReceived(const GroupId &groupId, const GroupInfo &info) { - qDebug() << __func__ << groupId.toString(); - contactListWidget->setGroupInfo(groupId, info); +void ContactWidget::onGroupInfoReceived(const GroupId& groupId, const GroupInfo& info) { + qDebug() << __func__ << groupId.toString(); + contactListWidget->setGroupInfo(groupId, info); } -void ContactWidget::onGroupInviteReceived(const GroupInvite &inviteInfo) { - - auto confType = inviteInfo.getType(); - if (confType == ConferenceType::TEXT || confType == ConferenceType::AV) { - if (false - // settings.getAutoGroupInvite(f->getPublicKey()) - ) { - onGroupInviteAccepted(inviteInfo); - } else { - // if (!groupInviteForm->addGroupInvite(inviteInfo)) { - // return; - // } - - // ++unreadGroupInvites; - // groupInvitesUpdate(); - // Widget::getInstance()->newMessageAlert(window(), isActiveWindow(), true, - // true); +void ContactWidget::onGroupInviteReceived(const GroupInvite& inviteInfo) { + auto confType = inviteInfo.getType(); + if (confType == ConferenceType::TEXT || confType == ConferenceType::AV) { + if (false + // settings.getAutoGroupInvite(f->getPublicKey()) + ) { + onGroupInviteAccepted(inviteInfo); + } else { + // if (!groupInviteForm->addGroupInvite(inviteInfo)) { + // return; + // } + + // ++unreadGroupInvites; + // groupInvitesUpdate(); + // Widget::getInstance()->newMessageAlert(window(), isActiveWindow(), true, + // true); #if DESKTOP_NOTIFICATIONS - if (settings.getNotifyHide()) { - notifier.notifyMessageSimple(DesktopNotify::MessageType::GROUP_INVITE); - } else { - notifier.notifyMessagePixmap(f->getDisplayedName() + tr(" invites you to join a group."), {}, Nexus::getProfile()->loadAvatar(f->getPublicKey())); - } + if (settings.getNotifyHide()) { + notifier.notifyMessageSimple(DesktopNotify::MessageType::GROUP_INVITE); + } else { + notifier.notifyMessagePixmap( + f->getDisplayedName() + tr(" invites you to join a group."), + {}, + Nexus::getProfile()->loadAvatar(f->getPublicKey())); + } #endif + } + } else { + qWarning() << "onGroupInviteReceived: Unknown ConferenceType:" << (int)confType; + return; } - } else { - qWarning() << "onGroupInviteReceived: Unknown ConferenceType:" << (int)confType; - return; - } } -void ContactWidget::onGroupInviteAccepted(const GroupInvite &inviteInfo) { - const QString groupId = core->joinGroupchat(inviteInfo); - qDebug() << "onGroupInviteAccepted groupId=>" << groupId; +void ContactWidget::onGroupInviteAccepted(const GroupInvite& inviteInfo) { + const QString groupId = core->joinGroupchat(inviteInfo); + qDebug() << "onGroupInviteAccepted groupId=>" << groupId; - if (groupId == std::numeric_limits::max()) { - qWarning() << "onGroupInviteAccepted: Unable to accept group invite"; - return; - } + if (groupId == std::numeric_limits::max()) { + qWarning() << "onGroupInviteAccepted: Unable to accept group invite"; + return; + } } void ContactWidget::onGroupPeerListChanged(QString groupnumber) { - const GroupId &groupId = GroupId(groupnumber); - Group *g = GroupList::findGroup(groupId); - assert(g); - // g->regeneratePeerList(); + const GroupId& groupId = GroupId(groupnumber); + Group* g = GroupList::findGroup(groupId); + assert(g); + // g->regeneratePeerList(); } void ContactWidget::onGroupPeerSizeChanged(QString groupnumber, const uint size) { - const GroupId &groupId = GroupId(groupnumber); - Group *g = GroupList::findGroup(groupId); - if (!g) { - qWarning() << "Can not find the group named:" << groupnumber; - return; - } - - g->setPeerCount(size); + const GroupId& groupId = GroupId(groupnumber); + Group* g = GroupList::findGroup(groupId); + if (!g) { + qWarning() << "Can not find the group named:" << groupnumber; + return; + } + + g->setPeerCount(size); } -void ContactWidget::onGroupPeerNameChanged(QString groupnumber, const FriendId &peerPk, const QString &newName) { - const GroupId &groupId = GroupId(groupnumber); - Group *g = GroupList::findGroup(groupId); - if (!g) { - qWarning() << "Can not find the group named:" << groupnumber; - return; - } - // const QString &setName = FriendList::decideNickname(peerPk, newName); - // g->updateUsername(peerPk, newName); +void ContactWidget::onGroupPeerNameChanged(QString groupnumber, + const FriendId& peerPk, + const QString& newName) { + const GroupId& groupId = GroupId(groupnumber); + Group* g = GroupList::findGroup(groupId); + if (!g) { + qWarning() << "Can not find the group named:" << groupnumber; + return; + } + // const QString &setName = FriendList::decideNickname(peerPk, newName); + // g->updateUsername(peerPk, newName); } -void ContactWidget::onGroupPeerStatusChanged(const QString &groupnumber, const GroupOccupant &go) { - qDebug() << __func__ << "group" << groupnumber << "occupant:" << go.nick; +void ContactWidget::onGroupPeerStatusChanged(const QString& groupnumber, const GroupOccupant& go) { + qDebug() << __func__ << "group" << groupnumber << "occupant:" << go.nick; - Group *g = GroupList::findGroup(GroupId(groupnumber)); - if (!g) { - qWarning() << "Can not find group named:" << groupnumber; - return; - } + Group* g = GroupList::findGroup(GroupId(groupnumber)); + if (!g) { + qWarning() << "Can not find group named:" << groupnumber; + return; + } - g->addPeer(go); + g->addPeer(go); } -void ContactWidget::onGroupSubjectChanged(const GroupId& groupId, const QString &subject) -{ - Group *g = GroupList::findGroup(groupId); +void ContactWidget::onGroupSubjectChanged(const GroupId& groupId, const QString& subject) { + Group* g = GroupList::findGroup(groupId); if (!g) { - qWarning() << "Can not find group" << groupId; - return; + qWarning() << "Can not find group" << groupId; + return; } g->setSubject({}, subject); - } // void ContactWidget::groupInvitesUpdate() { @@ -383,39 +404,39 @@ void ContactWidget::onGroupSubjectChanged(const GroupId& groupId, const QString // } void ContactWidget::onGroupClicked() { - auto &settings = Settings::getInstance(); - - // hideMainForms(nullptr); -// if (!groupInviteForm) { -// groupInviteForm = new GroupInviteForm; - -// connect(groupInviteForm, &GroupInviteForm::groupCreate, -// core, &Core::createGroup); -// } -// groupInviteForm->show(contentLayout.get()); - // setWindowTitle(fromDialogType(DialogType::GroupDialog)); - // setActiveToolMenuButton(ActiveToolMenuButton::GroupButton); + auto& settings = Settings::getInstance(); + + // hideMainForms(nullptr); + // if (!groupInviteForm) { + // groupInviteForm = new GroupInviteForm; + + // connect(groupInviteForm, &GroupInviteForm::groupCreate, + // core, &Core::createGroup); + // } + // groupInviteForm->show(contentLayout.get()); + // setWindowTitle(fromDialogType(DialogType::GroupDialog)); + // setActiveToolMenuButton(ActiveToolMenuButton::GroupButton); } void ContactWidget::friendRequestsUpdate() { - auto &settings = Settings::getInstance(); - - unsigned int unreadFriendRequests = settings.getUnreadFriendRequests(); - qDebug() << __func__ << "unreadFriendRequests" << unreadFriendRequests; - // if (unreadFriendRequests == 0) { - // delete friendRequestsButton; - // friendRequestsButton = nullptr; - // } else if (!friendRequestsButton) { - // friendRequestsButton = new QPushButton(this); - // friendRequestsButton->setObjectName("green"); - // connect(friendRequestsButton, &QPushButton::released, [this]() { - //// onAddClicked(); - // addForm->setMode(AddFriendForm::Mode::FriendRequest); - // }); - // ui->statusLayout->insertWidget(2, friendRequestsButton); - // } - - // if (friendRequestsButton) { - // friendRequestsButton->setText(tr("%n New IMFriend Request(s)", "", unreadFriendRequests)); - // } + auto& settings = Settings::getInstance(); + + unsigned int unreadFriendRequests = settings.getUnreadFriendRequests(); + qDebug() << __func__ << "unreadFriendRequests" << unreadFriendRequests; + // if (unreadFriendRequests == 0) { + // delete friendRequestsButton; + // friendRequestsButton = nullptr; + // } else if (!friendRequestsButton) { + // friendRequestsButton = new QPushButton(this); + // friendRequestsButton->setObjectName("green"); + // connect(friendRequestsButton, &QPushButton::released, [this]() { + //// onAddClicked(); + // addForm->setMode(AddFriendForm::Mode::FriendRequest); + // }); + // ui->statusLayout->insertWidget(2, friendRequestsButton); + // } + + // if (friendRequestsButton) { + // friendRequestsButton->setText(tr("%n New IMFriend Request(s)", "", unreadFriendRequests)); + // } } diff --git a/src/modules/im/src/widget/ContactWidget.h b/src/modules/im/src/widget/ContactWidget.h index b070e902..783ade0a 100644 --- a/src/modules/im/src/widget/ContactWidget.h +++ b/src/modules/im/src/widget/ContactWidget.h @@ -1,7 +1,6 @@ #ifndef CONTACTWIDGET_H #define CONTACTWIDGET_H - #include #include #include @@ -26,16 +25,15 @@ class AddFriendForm; * 通讯录界面 * @brief ContactWidget::ContactWidget */ -class ContactWidget : public MainLayout -{ +class ContactWidget : public MainLayout { Q_OBJECT public: - explicit ContactWidget(QWidget *parent = nullptr); + explicit ContactWidget(QWidget* parent = nullptr); ~ContactWidget(); - [[__nodiscard__]] ContentLayout* getContentLayout() const override{ - //MUST to be initialized. + [[__nodiscard__]] ContentLayout* getContentLayout() const override { + // MUST to be initialized. assert(contentLayout); return contentLayout.get(); } @@ -46,75 +44,68 @@ public slots: /** * do开头接受界面事件,调用core执行操作 * on开头接受core事件,操作界面 - */ - - void do_openAddForm(); - - void onCoreChanged(Core &core); - void onFriendAdded(const FriendInfo &frnd); - void onFriendUsernameChanged(const FriendId &friendPk, const QString &username); - - void onFriendStatusChanged(const FriendId &friendPk, Status::Status status); - void onFriendStatusMessageChanged(const FriendId &friendPk, - const QString &message); + */ + void do_openAddForm(); - void onFriendAvatarChanged(const FriendId &friendPk, const QByteArray &avatar); - void onFriendAliasChanged(const FriendId &friendPk, const QString &alias); + void onCoreChanged(Core* core); + void onFriendAdded(const FriendInfo& frnd); + void onFriendNickChanged(const FriendId& friendPk, const QString& nick); - void onFriendRequest(const FriendId &friendPk, const QString &message); + void onFriendStatusChanged(const FriendId& friendPk, Status::Status status); + void onFriendStatusMessageChanged(const FriendId& friendPk, const QString& message); + void onFriendAvatarChanged(const FriendId& friendPk, const QByteArray& avatar); + void onFriendAliasChanged(const FriendId& friendPk, const QString& alias); - void do_friendDelete(const FriendId &friendPk); - //朋友请求 - void do_friendRequest(const FriendId& friendAddress, const QString& nick, const QString& message); - //朋友请求接受 - void do_friendRequestAccept(const FriendId &friendPk); - //朋友请求拒绝 - void do_friendRequestReject(const FriendId &friendPk); + void onFriendRequest(const FriendId& friendPk, const QString& message); - void onGroupJoined( const GroupId & groupId, const QString& name); - void onGroupInfoReceived(const GroupId & groupId, const GroupInfo& info); - void onGroupInviteReceived(const GroupInvite &inviteInfo); + void do_friendDelete(const FriendId& friendPk); + // 朋友请求 + void do_friendRequest(const FriendId& friendAddress, const QString& nick, + const QString& message); + // 朋友请求接受 + void do_friendRequestAccept(const FriendId& friendPk); + // 朋友请求拒绝 + void do_friendRequestReject(const FriendId& friendPk); + void onGroupJoined(const GroupId& groupId, const QString& name); + void onGroupInfoReceived(const GroupId& groupId, const GroupInfo& info); + void onGroupInviteReceived(const GroupInvite& inviteInfo); - void onGroupInviteAccepted(const GroupInvite &inviteInfo); + void onGroupInviteAccepted(const GroupInvite& inviteInfo); void onGroupPeerListChanged(QString groupnumber); void onGroupPeerSizeChanged(QString groupnumber, const uint size); - void onGroupPeerNameChanged(QString groupnumber, const FriendId &peerPk, - const QString &newName); + void onGroupPeerNameChanged(QString groupnumber, const FriendId& peerPk, + const QString& newName); - void onGroupSubjectChanged(const GroupId&, const QString &subject); - void onGroupPeerStatusChanged(const QString & groupnumber,const GroupOccupant &go); + void onGroupSubjectChanged(const GroupId&, const QString& subject); + void onGroupPeerStatusChanged(const QString& groupnumber, const GroupOccupant& go); void onGroupClicked(); - private: void init(); AddFriendForm* makeAddForm(); void deinit(); void connectToCore(Core* core); - void friendRequestsUpdate() ; - + void friendRequestsUpdate(); - Ui::ContactWidget *ui; - Core *core; + Ui::ContactWidget* ui; + Core* core; FriendListWidget* contactListWidget; std::unique_ptr contentWidget; std::unique_ptr contentLayout; + AddFriendForm* addForm; - AddFriendForm *addForm; - - GroupInviteForm *groupInviteForm; + GroupInviteForm* groupInviteForm; uint32_t unreadGroupInvites; - QPushButton *friendRequestsButton; - QPushButton *groupInvitesButton; - + QPushButton* friendRequestsButton; + QPushButton* groupInvitesButton; }; -#endif // CONTACTWIDGET_H +#endif // CONTACTWIDGET_H diff --git a/src/modules/im/src/widget/ContentWidget.cpp b/src/modules/im/src/widget/ContentWidget.cpp index 7e41f795..5ede7044 100644 --- a/src/modules/im/src/widget/ContentWidget.cpp +++ b/src/modules/im/src/widget/ContentWidget.cpp @@ -15,112 +15,91 @@ // #include "ContentWidget.h" +#include +#include #include "chatformheader.h" #include "contentlayout.h" #include "form/chatform.h" #include "src/persistence/settings.h" #include "src/widget/form/groupchatform.h" #include "src/worker/SendWorker.h" -#include -#include static constexpr int HEADER_MARIGN = 8; static constexpr int CONTENT_MARIGN = 8; static constexpr int SEPERATOR_WIDTH = 2; -ContentWidget::ContentWidget(SendWorker* sendWorker, QWidget* parent): QWidget(parent){ - - setLayout(new QVBoxLayout(this)); - - layout()->setMargin(0); - layout()->setSpacing(0); - - mainHead = new QWidget(this); - mainHead->setLayout(new QVBoxLayout); - mainHead->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - mainHead->layout()->setContentsMargins(HEADER_MARIGN, HEADER_MARIGN, HEADER_MARIGN, HEADER_MARIGN); - // mainHead->layout()->setSpacing(0); -// mainHead->setMouseTracking(true); - -// mainHLine = new QFrame(this); -// mainHLine->setFrameShape(QFrame::HLine); -// mainHLine->setFrameShadow(QFrame::Plain); - -// mainHLineLayout=new QHBoxLayout(this); -// mainHLineLayout->addWidget(mainHLine); -// mainHLineLayout->addSpacing(4); -// mainHLineLayout->addSpacing(5); -// layout()->addItem(mainHLineLayout); - - mainContent = new QWidget(this); - mainContent->setLayout(new QVBoxLayout); - mainContent->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - mainContent->layout()->setContentsMargins(CONTENT_MARIGN, 0, CONTENT_MARIGN, CONTENT_MARIGN); - - seperator = new QWidget(this); - seperator->setObjectName("ContentSeperator"); - seperator->setFixedHeight(SEPERATOR_WIDTH); - - layout()->addWidget(mainHead); - layout()->addWidget(seperator); - layout()->addWidget(mainContent); - - mainHead->layout()->addWidget(sendWorker->getHeader()); - mainContent->layout()->addWidget(sendWorker->getChatForm()); +ContentWidget::ContentWidget(SendWorker* sendWorker, QWidget* parent) : QWidget(parent) { + setLayout(new QVBoxLayout(this)); + + layout()->setMargin(0); + layout()->setSpacing(0); + + mainHead = new QWidget(this); + mainHead->setLayout(new QVBoxLayout); + mainHead->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); + mainHead->layout()->setContentsMargins(HEADER_MARIGN, HEADER_MARIGN, HEADER_MARIGN, + HEADER_MARIGN); + // mainHead->layout()->setSpacing(0); + // mainHead->setMouseTracking(true); + + // mainHLine = new QFrame(this); + // mainHLine->setFrameShape(QFrame::HLine); + // mainHLine->setFrameShadow(QFrame::Plain); + + // mainHLineLayout=new QHBoxLayout(this); + // mainHLineLayout->addWidget(mainHLine); + // mainHLineLayout->addSpacing(4); + // mainHLineLayout->addSpacing(5); + // layout()->addItem(mainHLineLayout); + + mainContent = new QWidget(this); + mainContent->setLayout(new QVBoxLayout); + mainContent->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + mainContent->layout()->setContentsMargins(CONTENT_MARIGN, 0, CONTENT_MARIGN, CONTENT_MARIGN); + + seperator = new QWidget(this); + seperator->setObjectName("ContentSeperator"); + seperator->setFixedHeight(SEPERATOR_WIDTH); + + layout()->addWidget(mainHead); + layout()->addWidget(seperator); + layout()->addWidget(mainContent); + + mainHead->layout()->addWidget(sendWorker->getHeader()); + mainContent->layout()->addWidget(sendWorker->getChatForm()); } -ContentWidget::~ContentWidget() -{ - - qDebug() <<__func__; - -} +ContentWidget::~ContentWidget() { qDebug() << __func__; } void ContentWidget::init() { + // QPalette palette = mainHLine.palette(); + // palette.setBrush(QPalette::WindowText, QBrush(QColor(193, 193, 193))); + // mainHLine.setPalette(palette); + // if (QStyleFactory::keys().contains(Settings::getInstance().getStyle()) + // && Settings::getInstance().getStyle() != "None") { + // mainHead->setStyle(QStyleFactory::create(Settings::getInstance().getStyle())); + // mainContent->setStyle(QStyleFactory::create(Settings::getInstance().getStyle())); + // } - - // QPalette palette = mainHLine.palette(); - // palette.setBrush(QPalette::WindowText, QBrush(QColor(193, 193, 193))); - // mainHLine.setPalette(palette); - -// if (QStyleFactory::keys().contains(Settings::getInstance().getStyle()) -// && Settings::getInstance().getStyle() != "None") { -// mainHead->setStyle(QStyleFactory::create(Settings::getInstance().getStyle())); -// mainContent->setStyle(QStyleFactory::create(Settings::getInstance().getStyle())); -// } - -// reloadTheme(); - - - - + // reloadTheme(); } -void ContentWidget::showTo(ContentLayout *layout) { -// auto contentIndex = layout->indexOf(this); -// if(contentIndex < 0 ){ -// contentIndex = layout->addWidget(this); -// } - layout->setCurrentWidget(this); - this->show(); +void ContentWidget::showTo(ContentLayout* layout) { + // auto contentIndex = layout->indexOf(this); + // if(contentIndex < 0 ){ + // contentIndex = layout->addWidget(this); + // } + layout->setCurrentWidget(this); + this->show(); } -void ContentWidget::setChatForm(GenericChatForm * form) { -// auto h = form->getHead(); -// mainHead->layout()->addWidget(form->getHead()); -// mainContent->layout()->addWidget(form); - - +void ContentWidget::setChatForm(GenericChatForm* form) { + // auto h = form->getHead(); + // mainHead->layout()->addWidget(form->getHead()); + // mainContent->layout()->addWidget(form); } -void ContentWidget::showEvent(QShowEvent *event) -{ - -} - -void ContentWidget::hideEvent(QHideEvent *event) -{ - -} +void ContentWidget::showEvent(QShowEvent* event) {} +void ContentWidget::hideEvent(QHideEvent* event) {} diff --git a/src/modules/im/src/widget/ContentWidget.h b/src/modules/im/src/widget/ContentWidget.h index 47cff09a..594b53f0 100644 --- a/src/modules/im/src/widget/ContentWidget.h +++ b/src/modules/im/src/widget/ContentWidget.h @@ -27,24 +27,24 @@ class ContentLayout; class ChatForm; class ContentWidget : public QWidget { - Q_OBJECT + Q_OBJECT public: - explicit ContentWidget(SendWorker* sendWorker, QWidget *parent = nullptr); - ~ContentWidget(); + explicit ContentWidget(SendWorker* sendWorker, QWidget* parent = nullptr); + ~ContentWidget(); - void showTo(ContentLayout *); - void setChatForm(GenericChatForm *); + void showTo(ContentLayout*); + void setChatForm(GenericChatForm*); - virtual void showEvent(QShowEvent *event) override; - virtual void hideEvent(QHideEvent *event) override; + virtual void showEvent(QShowEvent* event) override; + virtual void hideEvent(QHideEvent* event) override; private: - void init(); - QFrame *mainHLine; - QHBoxLayout *mainHLineLayout; - QWidget *mainHead; - QWidget *seperator; - QWidget *mainContent; + void init(); + QFrame* mainHLine; + QHBoxLayout* mainHLineLayout; + QWidget* mainHead; + QWidget* seperator; + QWidget* mainContent; }; -#endif // OKMSG_PROJECT_CONTENTWIDGET_H +#endif // OKMSG_PROJECT_CONTENTWIDGET_H diff --git a/src/modules/im/src/widget/FriendAddWidget.h b/src/modules/im/src/widget/FriendAddWidget.h index 3fb3a5de..decfd6e2 100644 --- a/src/modules/im/src/widget/FriendAddWidget.h +++ b/src/modules/im/src/widget/FriendAddWidget.h @@ -19,4 +19,4 @@ class FriendAddWidget {}; -#endif // OKMSG_PROJECT_FRIENDADDWIDGET_H +#endif // OKMSG_PROJECT_FRIENDADDWIDGET_H diff --git a/src/modules/im/src/widget/MainLayout.cpp b/src/modules/im/src/widget/MainLayout.cpp index 70b94d4f..f86257ee 100644 --- a/src/modules/im/src/widget/MainLayout.cpp +++ b/src/modules/im/src/widget/MainLayout.cpp @@ -1,7 +1,3 @@ #include "MainLayout.h" -MainLayout::MainLayout(QWidget *parent) - : QWidget{parent} -{ - -} +MainLayout::MainLayout(QWidget* parent) : QWidget{parent} {} diff --git a/src/modules/im/src/widget/MainLayout.h b/src/modules/im/src/widget/MainLayout.h index e5b8859b..e4742052 100644 --- a/src/modules/im/src/widget/MainLayout.h +++ b/src/modules/im/src/widget/MainLayout.h @@ -1,21 +1,18 @@ #ifndef MAINLAYOUT_H #define MAINLAYOUT_H - #include #include "src/widget/contentlayout.h" -class MainLayout : public QWidget -{ +class MainLayout : public QWidget { Q_OBJECT public: - explicit MainLayout(QWidget *parent = nullptr); + explicit MainLayout(QWidget* parent = nullptr); - [[nodiscard]] virtual ContentLayout *getContentLayout() const= 0; + [[nodiscard]] virtual ContentLayout* getContentLayout() const = 0; signals: - }; -#endif // MAINLAYOUT_H +#endif // MAINLAYOUT_H diff --git a/src/modules/im/src/widget/MessageSessionListWidget.cpp b/src/modules/im/src/widget/MessageSessionListWidget.cpp index 70e9dcae..546dd3aa 100644 --- a/src/modules/im/src/widget/MessageSessionListWidget.cpp +++ b/src/modules/im/src/widget/MessageSessionListWidget.cpp @@ -11,6 +11,12 @@ */ #include "MessageSessionListWidget.h" +#include +#include +#include +#include +#include +#include #include "ChatWidget.h" #include "base/OkSettings.h" #include "base/times.h" @@ -29,197 +35,186 @@ #include "src/persistence/profile.h" #include "src/persistence/settings.h" #include "widget.h" -#include -#include -#include -#include -#include -#include enum class Time { - Today, - Yesterday, - ThisWeek, - ThisMonth, - Month1Ago, - Month2Ago, - Month3Ago, - Month4Ago, - Month5Ago, - LongAgo, - Never + Today, + Yesterday, + ThisWeek, + ThisMonth, + Month1Ago, + Month2Ago, + Month3Ago, + Month4Ago, + Month5Ago, + LongAgo, + Never }; static const int LAST_TIME = static_cast(Time::Never); -inline QDateTime getActiveTimeFriend(const Friend *contact) { - return Settings::getInstance().getFriendActivity(contact->getPublicKey()); +inline QDateTime getActiveTimeFriend(const Friend* contact) { + return Settings::getInstance().getFriendActivity(contact->getPublicKey()); } -MessageSessionListWidget::MessageSessionListWidget(MainLayout *parent, +MessageSessionListWidget::MessageSessionListWidget(MainLayout* parent, ContentLayout* contentBox, bool groupsOnTop) - : QWidget(parent), m_contentLayout(contentBox), groupsOnTop(groupsOnTop) { - - setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); + : QWidget(parent), m_contentLayout(contentBox), groupsOnTop(groupsOnTop) { + setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); + // Prevent QLayout's add child warning before setting the mode. + listLayout = new FriendListLayout(this); + listLayout->removeItem(listLayout->getLayoutOnline()); + listLayout->removeItem(listLayout->getLayoutOffline()); + setLayout(listLayout); + mode = Settings::getInstance().getFriendSortingMode(); + sortByMode(mode); - // Prevent QLayout's add child warning before setting the mode. - listLayout = new FriendListLayout(this); - listLayout->removeItem(listLayout->getLayoutOnline()); - listLayout->removeItem(listLayout->getLayoutOffline()); - setLayout(listLayout); - - mode = Settings::getInstance().getFriendSortingMode(); - sortByMode(mode); - - - dayTimer = new QTimer(this); - dayTimer->setTimerType(Qt::VeryCoarseTimer); - connect(dayTimer, &QTimer::timeout, this, &MessageSessionListWidget::dayTimeout); - dayTimer->start(base::Times::timeUntilTomorrow()); + dayTimer = new QTimer(this); + dayTimer->setTimerType(Qt::VeryCoarseTimer); + connect(dayTimer, &QTimer::timeout, this, &MessageSessionListWidget::dayTimeout); + dayTimer->start(base::Times::timeUntilTomorrow()); - setAcceptDrops(true); + setAcceptDrops(true); - auto &settings = Settings::getInstance(); - connect(&settings, &Settings::compactLayoutChanged, - this, &MessageSessionListWidget::onCompactChanged); + auto& settings = Settings::getInstance(); + connect(&settings, &Settings::compactLayoutChanged, this, + &MessageSessionListWidget::onCompactChanged); -// connect(&settings, &Settings::groupchatPositionChanged, this, -// &MessageSessionListWidget::onGroupchatPositionChanged); + // connect(&settings, &Settings::groupchatPositionChanged, this, + // &MessageSessionListWidget::onGroupchatPositionChanged); - auto w = Widget::getInstance(); - connect(w, &Widget::toDeleteChat, this, &MessageSessionListWidget::do_deleteSession); - connect(w, &Widget::toClearHistory, this, &MessageSessionListWidget::do_clearHistory); + auto w = Widget::getInstance(); + connect(w, &Widget::toDeleteChat, this, &MessageSessionListWidget::do_deleteSession); + connect(w, &Widget::toClearHistory, this, &MessageSessionListWidget::do_clearHistory); } MessageSessionListWidget::~MessageSessionListWidget() { - auto w = Widget::getInstance(); + auto w = Widget::getInstance(); disconnect(w, &Widget::toDeleteChat, this, &MessageSessionListWidget::do_deleteSession); disconnect(w, &Widget::toClearHistory, this, &MessageSessionListWidget::do_clearHistory); - if (activityLayout != nullptr) { - QLayoutItem *item; - while ((item = activityLayout->takeAt(0)) != nullptr) { - delete item->widget(); - delete item; + if (activityLayout != nullptr) { + QLayoutItem* item; + while ((item = activityLayout->takeAt(0)) != nullptr) { + delete item->widget(); + delete item; + } + delete activityLayout; } - delete activityLayout; - } - // if (circleLayout != nullptr) { - // QLayoutItem *item; - // while ((item = circleLayout->getLayout()->takeAt(0)) != nullptr) { - // delete item->widget(); - // delete item; - // } - // delete circleLayout; - // } + // if (circleLayout != nullptr) { + // QLayoutItem *item; + // while ((item = circleLayout->getLayout()->takeAt(0)) != nullptr) { + // delete item->widget(); + // delete item; + // } + // delete circleLayout; + // } } +MessageSessionWidget* MessageSessionListWidget::createMessageSession(const ContactId& contactId, + const QString& sid, + ChatType type) { + qDebug() << __func__ << "contactId:" << contactId.toString(); -MessageSessionWidget *MessageSessionListWidget::createMessageSession( - const ContactId &contactId, const QString &sid, ChatType type) { - qDebug() << __func__ << "contactId:" << contactId.toString(); - - auto sw = getMessageSession(contactId.toString()); - if(sw){ - qWarning() <<"Message session is existing."; - return sw; - } + auto sw = getMessageSession(contactId.toString()); + if (sw) { + qWarning() << "Message session is existing."; + return sw; + } - sw = new MessageSessionWidget(m_contentLayout, contactId, type); - qDebug() << "create session for:" << contactId.toString() <<"=>" <" << sw; + connectSessionWidget(*sw); - listLayout->addWidget(sw); - sessionWidgets.insert(sw->getContactId().toString(), sw); + listLayout->addWidget(sw); + sessionWidgets.insert(sw->getContactId().toString(), sw); - emit sessionAdded(sw); - return sw; + emit sessionAdded(sw); + return sw; } -void MessageSessionListWidget::connectSessionWidget(MessageSessionWidget &sw) { -// connect(&sw, &MessageSessionWidget::searchCircle, this, -// &MessageSessionListWidget::searchCircle); - connect(&sw, &MessageSessionWidget::updateFriendActivity, this, - &MessageSessionListWidget::updateFriendActivity); - connect(&sw, &MessageSessionWidget::widgetClicked, this, - &MessageSessionListWidget::slot_sessionClicked); +void MessageSessionListWidget::connectSessionWidget(MessageSessionWidget& sw) { + // connect(&sw, &MessageSessionWidget::searchCircle, this, + // &MessageSessionListWidget::searchCircle); + connect(&sw, &MessageSessionWidget::updateFriendActivity, this, + &MessageSessionListWidget::updateFriendActivity); + connect(&sw, &MessageSessionWidget::widgetClicked, this, + &MessageSessionListWidget::slot_sessionClicked); - connect(&sw, &MessageSessionWidget::deleteSession, this, - &MessageSessionListWidget::do_deleteSession); + connect(&sw, &MessageSessionWidget::deleteSession, this, + &MessageSessionListWidget::do_deleteSession); } -void MessageSessionListWidget::updateFriendActivity(const Friend &frnd) { - const FriendId &pk = frnd.getPublicKey(); - auto &settings = Settings::getInstance(); - const auto oldTime = settings.getFriendActivity(pk); - const auto newTime = QDateTime::currentDateTime(); - settings.setFriendActivity(pk, newTime); - MessageSessionWidget *widget = getMessageSession(frnd.getPublicKey().toString()); - moveWidget(widget, frnd.getStatus()); - updateActivityTime(oldTime); // update old category widget +void MessageSessionListWidget::updateFriendActivity(const Friend& frnd) { + const FriendId& pk = frnd.getPublicKey(); + auto& settings = Settings::getInstance(); + const auto oldTime = settings.getFriendActivity(pk); + const auto newTime = QDateTime::currentDateTime(); + settings.setFriendActivity(pk, newTime); + MessageSessionWidget* widget = getMessageSession(frnd.getPublicKey().toString()); + moveWidget(widget, frnd.getStatus()); + updateActivityTime(oldTime); // update old category widget } void MessageSessionListWidget::setMode(SortingMode mode) { - if (this->mode == mode) - return; + if (this->mode == mode) return; - this->mode = mode; - Settings::getInstance().setFriendSortingMode(mode); + this->mode = mode; + Settings::getInstance().setFriendSortingMode(mode); - sortByMode(mode); + sortByMode(mode); } void MessageSessionListWidget::sortByMode(SortingMode mode) { - if (mode == SortingMode::Name) { - // circleLayout = new GenericChatItemLayout; - // circleLayout->getLayout()->setSpacing(0); - // circleLayout->getLayout()->setMargin(0); - - // for (int i = 0; i < Settings::getInstance().getCircleCount(); ++i) { - // addCircleWidget(i); - // CircleWidget::getFromID(i)->setVisible(false); - // } - - // Only display circles once all created to avoid artifacts. - // for (int i = 0; i < Settings::getInstance().getCircleCount(); ++i) - // CircleWidget::getFromID(i)->setVisible(true); - - int count = activityLayout ? activityLayout->count() : 0; - for (int i = 0; i < count; i++) { - QWidget *widget = activityLayout->itemAt(i)->widget(); -// CategoryWidget *categoryWidget = qobject_cast(widget); -// if (categoryWidget) { -// categoryWidget->moveFriendWidgets(this); -// } else { -// qWarning() << "Unexpected widget"; -// } - } - -// listLayout->addLayout(listLayout->getLayout()); - listLayout->addLayout(listLayout->getLayoutOffline()); - // listLayout->addLayout(circleLayout->getLayout()); -// onGroupchatPositionChanged(groupsOnTop); - - if (activityLayout != nullptr) { - QLayoutItem *item; - while ((item = activityLayout->takeAt(0)) != nullptr) { - delete item->widget(); - delete item; - } - delete activityLayout; - activityLayout = nullptr; - } - - reDraw(); - } else if (mode == SortingMode::Activity) { - QLocale ql(Settings::getInstance().getTranslation()); - QDate today = QDate::currentDate(); + if (mode == SortingMode::Name) { + // circleLayout = new GenericChatItemLayout; + // circleLayout->getLayout()->setSpacing(0); + // circleLayout->getLayout()->setMargin(0); + + // for (int i = 0; i < Settings::getInstance().getCircleCount(); ++i) { + // addCircleWidget(i); + // CircleWidget::getFromID(i)->setVisible(false); + // } + + // Only display circles once all created to avoid artifacts. + // for (int i = 0; i < Settings::getInstance().getCircleCount(); ++i) + // CircleWidget::getFromID(i)->setVisible(true); + + int count = activityLayout ? activityLayout->count() : 0; + for (int i = 0; i < count; i++) { + QWidget* widget = activityLayout->itemAt(i)->widget(); + // CategoryWidget *categoryWidget = qobject_cast(widget); + // if (categoryWidget) { + // categoryWidget->moveFriendWidgets(this); + // } else { + // qWarning() << "Unexpected widget"; + // } + } + + // listLayout->addLayout(listLayout->getLayout()); + listLayout->addLayout(listLayout->getLayoutOffline()); + // listLayout->addLayout(circleLayout->getLayout()); + // onGroupchatPositionChanged(groupsOnTop); + + if (activityLayout != nullptr) { + QLayoutItem* item; + while ((item = activityLayout->takeAt(0)) != nullptr) { + delete item->widget(); + delete item; + } + delete activityLayout; + activityLayout = nullptr; + } + + reDraw(); + } else if (mode == SortingMode::Activity) { + QLocale ql(Settings::getInstance().getTranslation()); + QDate today = QDate::currentDate(); #define COMMENT "Category for sorting friends by activity" - // clang-format off + // clang-format off const QMap names { { Time::Today, tr("Today", COMMENT) }, { Time::Yesterday, tr("Yesterday", COMMENT) }, @@ -236,566 +231,525 @@ void MessageSessionListWidget::sortByMode(SortingMode mode) { // clang-format on #undef COMMENT - activityLayout = new QVBoxLayout(); -// bool compact = Settings::getInstance().getCompactLayout(); -// for (Time t : names.keys()) { -// CategoryWidget *category = new CategoryWidget(compact, this); -// category->setName(names[t]); -// activityLayout->addWidget(category); -// } - - moveFriends(listLayout->getLayoutOffline()); - moveFriends(listLayout->getLayoutOnline()); - // if (circleLayout != nullptr) { - // moveFriends(circleLayout->getLayout()); - // } - - for (int i = 0; i < activityLayout->count(); ++i) { - QWidget *widget = activityLayout->itemAt(i)->widget(); -// CategoryWidget *categoryWidget = qobject_cast(widget); -// categoryWidget->setVisible(categoryWidget->hasChatrooms()); + activityLayout = new QVBoxLayout(); + // bool compact = Settings::getInstance().getCompactLayout(); + // for (Time t : names.keys()) { + // CategoryWidget *category = new CategoryWidget(compact, this); + // category->setName(names[t]); + // activityLayout->addWidget(category); + // } + + moveFriends(listLayout->getLayoutOffline()); + moveFriends(listLayout->getLayoutOnline()); + // if (circleLayout != nullptr) { + // moveFriends(circleLayout->getLayout()); + // } + + for (int i = 0; i < activityLayout->count(); ++i) { + QWidget* widget = activityLayout->itemAt(i)->widget(); + // CategoryWidget *categoryWidget = qobject_cast(widget); + // categoryWidget->setVisible(categoryWidget->hasChatrooms()); + } + + listLayout->removeItem(listLayout->getLayoutOnline()); + listLayout->removeItem(listLayout->getLayoutOffline()); + + // if (circleLayout != nullptr) { + // listLayout->removeItem(circleLayout->getLayout()); + // + // QLayoutItem *item; + // while ((item = circleLayout->getLayout()->takeAt(0)) != nullptr) { + // delete item->widget(); + // delete item; + // } + // delete circleLayout; + // circleLayout = nullptr; + // } + + listLayout->insertLayout(1, activityLayout); + + reDraw(); } - - listLayout->removeItem(listLayout->getLayoutOnline()); - listLayout->removeItem(listLayout->getLayoutOffline()); - - // if (circleLayout != nullptr) { - // listLayout->removeItem(circleLayout->getLayout()); - // - // QLayoutItem *item; - // while ((item = circleLayout->getLayout()->takeAt(0)) != nullptr) { - // delete item->widget(); - // delete item; - // } - // delete circleLayout; - // circleLayout = nullptr; - // } - - listLayout->insertLayout(1, activityLayout); - - reDraw(); - } } -void MessageSessionListWidget::moveFriends(QLayout *layout) { - while (!layout->isEmpty()) { - QWidget *widget = layout->itemAt(0)->widget(); - FriendWidget *friendWidget = qobject_cast(widget); -// CircleWidget *circleWidget = qobject_cast(widget); -// if (circleWidget) { -// circleWidget->moveFriendWidgets(this); -// } else if (friendWidget) { -// const IMFriend *contact = friendWidget->getFriend(); -// auto *categoryWidget = getTimeCategoryWidget(contact); -// categoryWidget->addFriendWidget(friendWidget, contact->getStatus()); -// } - } +void MessageSessionListWidget::moveFriends(QLayout* layout) { + while (!layout->isEmpty()) { + QWidget* widget = layout->itemAt(0)->widget(); + FriendWidget* friendWidget = qobject_cast(widget); + // CircleWidget *circleWidget = qobject_cast(widget); + // if (circleWidget) { + // circleWidget->moveFriendWidgets(this); + // } else if (friendWidget) { + // const IMFriend *contact = friendWidget->getFriend(); + // auto *categoryWidget = getTimeCategoryWidget(contact); + // categoryWidget->addFriendWidget(friendWidget, contact->getStatus()); + // } + } } - MessageSessionListWidget::SortingMode MessageSessionListWidget::getMode() const { return mode; } - -void MessageSessionListWidget::searchChatrooms(const QString &searchString, - bool hideOnline, bool hideOffline, - bool hideGroups) { - - listLayout->searchChatrooms(searchString, hideOnline, hideOffline); - -} - -void MessageSessionListWidget::onFriendWidgetRenamed(FriendWidget *friendWidget) { - const Friend *contact = friendWidget->getFriend(); - auto status = contact->getStatus(); -// if (mode == SortingMode::Activity) { -// auto *categoryWidget = getTimeCategoryWidget(contact); -// categoryWidget->removeFriendWidget(friendWidget, status); -// categoryWidget->addFriendWidget(friendWidget, status); -// } else { -// int id = Settings::getInstance().getFriendCircleID(contact->getPublicKey()); -// CircleWidget *circleWidget = CircleWidget::getFromID(id); -// if (circleWidget != nullptr) { -// circleWidget->removeFriendWidget(friendWidget, status); -// circleWidget->addFriendWidget(friendWidget, status); -// emit searchCircle(*circleWidget); -// } else { - listLayout->removeFriendWidget(friendWidget); - listLayout->addFriendWidget(friendWidget, status); -// } -// } +void MessageSessionListWidget::searchChatrooms(const QString& searchString, bool hideOnline, + bool hideOffline, bool hideGroups) { + listLayout->searchChatrooms(searchString, hideOnline, hideOffline); +} + +void MessageSessionListWidget::onFriendWidgetRenamed(FriendWidget* friendWidget) { + const Friend* contact = friendWidget->getFriend(); + auto status = contact->getStatus(); + // if (mode == SortingMode::Activity) { + // auto *categoryWidget = getTimeCategoryWidget(contact); + // categoryWidget->removeFriendWidget(friendWidget, status); + // categoryWidget->addFriendWidget(friendWidget, status); + // } else { + // int id = Settings::getInstance().getFriendCircleID(contact->getPublicKey()); + // CircleWidget *circleWidget = CircleWidget::getFromID(id); + // if (circleWidget != nullptr) { + // circleWidget->removeFriendWidget(friendWidget, status); + // circleWidget->addFriendWidget(friendWidget, status); + // emit searchCircle(*circleWidget); + // } else { + listLayout->removeFriendWidget(friendWidget); + listLayout->addFriendWidget(friendWidget, status); + // } + // } } +void MessageSessionListWidget::cycleContacts(GenericChatroomWidget* activeChatroomWidget, + bool forward) { + if (!activeChatroomWidget) { + return; + } + int index = -1; + FriendWidget* friendWidget = qobject_cast(activeChatroomWidget); + + if (mode == SortingMode::Activity) { + if (!friendWidget) { + return; + } + + const auto activityTime = getActiveTimeFriend(friendWidget->getFriend()); + index = static_cast(base::getTimeBucket(activityTime)); + QWidget* widget = activityLayout->itemAt(index)->widget(); + // CategoryWidget *categoryWidget = qobject_cast(widget); + // if (categoryWidget == nullptr || + // categoryWidget->cycleContacts(friendWidget, forward)) { + // return; + // } + + index += forward ? 1 : -1; + + for (;;) { + // Bounds checking. + if (index < 0) { + index = LAST_TIME; + continue; + } else if (index > LAST_TIME) { + index = 0; + continue; + } + + auto* widget = activityLayout->itemAt(index)->widget(); + // categoryWidget = qobject_cast(widget); + + // if (categoryWidget != nullptr) { + // if (!categoryWidget->cycleContacts(forward)) { + // Skip empty or finished categories. + // index += forward ? 1 : -1; + // continue; + // } + // } + + break; + } -void MessageSessionListWidget::cycleContacts( - GenericChatroomWidget *activeChatroomWidget, bool forward) { - if (!activeChatroomWidget) { - return; - } - - int index = -1; - FriendWidget *friendWidget = - qobject_cast(activeChatroomWidget); - - if (mode == SortingMode::Activity) { - if (!friendWidget) { - return; + return; } - const auto activityTime = getActiveTimeFriend(friendWidget->getFriend()); - index = static_cast(base::getTimeBucket(activityTime)); - QWidget *widget = activityLayout->itemAt(index)->widget(); -// CategoryWidget *categoryWidget = qobject_cast(widget); -// if (categoryWidget == nullptr || -// categoryWidget->cycleContacts(friendWidget, forward)) { -// return; -// } + QLayout* currentLayout = nullptr; + // CircleWidget *circleWidget = nullptr; + + if (friendWidget != nullptr) { + const FriendId& pk = friendWidget->getFriend()->getPublicKey(); + uint32_t circleId = Settings::getInstance().getFriendCircleID(pk); + // circleWidget = CircleWidget::getFromID(circleId); + // if (circleWidget != nullptr) { + // if (circleWidget->cycleContacts(friendWidget, forward)) { + // return; + // } + + // // index = circleLayout->indexOfSortedWidget(circleWidget); + // // currentLayout = circleLayout->getLayout(); + // } else { + currentLayout = listLayout->getLayoutOnline(); + index = listLayout->indexOfFriendWidget(friendWidget, true); + if (index == -1) { + currentLayout = listLayout->getLayoutOffline(); + index = listLayout->indexOfFriendWidget(friendWidget, false); + } + } + // } index += forward ? 1 : -1; for (;;) { - // Bounds checking. - if (index < 0) { - index = LAST_TIME; - continue; - } else if (index > LAST_TIME) { - index = 0; - continue; - } - - auto *widget = activityLayout->itemAt(index)->widget(); -// categoryWidget = qobject_cast(widget); - -// if (categoryWidget != nullptr) { -// if (!categoryWidget->cycleContacts(forward)) { - // Skip empty or finished categories. -// index += forward ? 1 : -1; -// continue; -// } -// } - - break; - } - - return; - } - - QLayout *currentLayout = nullptr; -// CircleWidget *circleWidget = nullptr; - - if (friendWidget != nullptr) { - const FriendId &pk = friendWidget->getFriend()->getPublicKey(); - uint32_t circleId = Settings::getInstance().getFriendCircleID(pk); -// circleWidget = CircleWidget::getFromID(circleId); -// if (circleWidget != nullptr) { -// if (circleWidget->cycleContacts(friendWidget, forward)) { -// return; -// } - -// // index = circleLayout->indexOfSortedWidget(circleWidget); -// // currentLayout = circleLayout->getLayout(); -// } else { - currentLayout = listLayout->getLayoutOnline(); - index = listLayout->indexOfFriendWidget(friendWidget, true); - if (index == -1) { - currentLayout = listLayout->getLayoutOffline(); - index = listLayout->indexOfFriendWidget(friendWidget, false); - } - } -// } - - index += forward ? 1 : -1; - - for (;;) { - // Bounds checking. - if (index < 0) { - currentLayout = nextLayout(currentLayout, forward); - index = currentLayout->count() - 1; - continue; - } else if (index >= currentLayout->count()) { - currentLayout = nextLayout(currentLayout, forward); - index = 0; - continue; - } - - // Go to the actual next index. - if (currentLayout == listLayout->getLayoutOnline() || - currentLayout == listLayout->getLayoutOffline() ) { - GenericChatroomWidget *chatWidget = qobject_cast( - currentLayout->itemAt(index)->widget()); - - if (chatWidget != nullptr) - emit chatWidget->chatroomWidgetClicked(chatWidget); - - return; - } - // else if (currentLayout == circleLayout->getLayout()) { - // circleWidget = - // qobject_cast(currentLayout->itemAt(index)->widget()); - // if (circleWidget != nullptr) { - // if (!circleWidget->cycleContacts(forward)) { - // Skip empty or finished circles. - // index += forward ? 1 : -1; - // continue; - // } - // } - // return; - // } else { - // return; - // } - } + // Bounds checking. + if (index < 0) { + currentLayout = nextLayout(currentLayout, forward); + index = currentLayout->count() - 1; + continue; + } else if (index >= currentLayout->count()) { + currentLayout = nextLayout(currentLayout, forward); + index = 0; + continue; + } + + // Go to the actual next index. + if (currentLayout == listLayout->getLayoutOnline() || + currentLayout == listLayout->getLayoutOffline()) { + GenericChatroomWidget* chatWidget = + qobject_cast(currentLayout->itemAt(index)->widget()); + + if (chatWidget != nullptr) emit chatWidget->chatroomWidgetClicked(chatWidget); + + return; + } + // else if (currentLayout == circleLayout->getLayout()) { + // circleWidget = + // qobject_cast(currentLayout->itemAt(index)->widget()); + // if (circleWidget != nullptr) { + // if (!circleWidget->cycleContacts(forward)) { + // Skip empty or finished circles. + // index += forward ? 1 : -1; + // continue; + // } + // } + // return; + // } else { + // return; + // } + } } -void MessageSessionListWidget::dragEnterEvent(QDragEnterEvent *event) { - if (!event->mimeData()->hasFormat("toxPk")) { - return; - } - FriendId toxPk(event->mimeData()->data("toxPk")); - Friend *frnd = FriendList::findFriend(toxPk); - if (frnd) - event->acceptProposedAction(); +void MessageSessionListWidget::dragEnterEvent(QDragEnterEvent* event) { + if (!event->mimeData()->hasFormat("toxPk")) { + return; + } + FriendId toxPk(event->mimeData()->data("toxPk")); + Friend* frnd = FriendList::findFriend(toxPk); + if (frnd) event->acceptProposedAction(); } -void MessageSessionListWidget::dropEvent(QDropEvent *event) { - // Check, that the element is dropped from qTox - QObject *o = event->source(); - auto widget = qobject_cast(o); - if (!widget) - return; +void MessageSessionListWidget::dropEvent(QDropEvent* event) { + // Check, that the element is dropped from qTox + QObject* o = event->source(); + auto widget = qobject_cast(o); + if (!widget) return; - // Check, that the user has a friend with the same ToxPk - assert(event->mimeData()->hasFormat("toxPk")); - const FriendId toxPk{event->mimeData()->data("toxPk")}; - Friend *f = FriendList::findFriend(toxPk); - if (!f) - return; + // Check, that the user has a friend with the same ToxPk + assert(event->mimeData()->hasFormat("toxPk")); + const FriendId toxPk{event->mimeData()->data("toxPk")}; + Friend* f = FriendList::findFriend(toxPk); + if (!f) return; - // Save CircleWidget before changing the Id -// int circleId = Settings::getInstance().getFriendCircleID(f->getPublicKey()); -// CircleWidget *circleWidget = CircleWidget::getFromID(circleId); + // Save CircleWidget before changing the Id + // int circleId = Settings::getInstance().getFriendCircleID(f->getPublicKey()); + // CircleWidget *circleWidget = CircleWidget::getFromID(circleId); - moveWidget(widget, f->getStatus(), true); + moveWidget(widget, f->getStatus(), true); -// if (circleWidget) -// circleWidget->updateStatus(); + // if (circleWidget) + // circleWidget->updateStatus(); } -void MessageSessionListWidget::showEvent(QShowEvent *event) { - // auto core = Core::getInstance(); - // connect(core, &Core::friendAdded, this, &MessageSessionListWidget::addFriend); - // for (auto &receiver : core->loadFriendList()) { - // qDebug() << "receiver:" << receiver; - // }; +void MessageSessionListWidget::showEvent(QShowEvent* event) { + // auto core = Core::getInstance(); + // connect(core, &Core::friendAdded, this, &MessageSessionListWidget::addFriend); + // for (auto &receiver : core->loadFriendList()) { + // qDebug() << "receiver:" << receiver; + // }; } void MessageSessionListWidget::dayTimeout() { - if (mode == SortingMode::Activity) { - setMode(SortingMode::Name); - setMode(SortingMode::Activity); // Refresh all. - } + if (mode == SortingMode::Activity) { + setMode(SortingMode::Name); + setMode(SortingMode::Activity); // Refresh all. + } - dayTimer->start(base::Times::timeUntilTomorrow()); + dayTimer->start(base::Times::timeUntilTomorrow()); } -void MessageSessionListWidget::moveWidget(MessageSessionWidget *widget, Status::Status s, - bool add) { -// if (mode == SortingMode::Name) { -// const IMFriend *f = widget->getFriend(); -// int circleId = Settings::getInstance().getFriendCircleID(f->getPublicKey()); -// CircleWidget *circleWidget = CircleWidget::getFromID(circleId); +void MessageSessionListWidget::moveWidget(MessageSessionWidget* widget, Status::Status s, + bool add) { + // if (mode == SortingMode::Name) { + // const IMFriend *f = widget->getFriend(); + // int circleId = Settings::getInstance().getFriendCircleID(f->getPublicKey()); + // CircleWidget *circleWidget = CircleWidget::getFromID(circleId); -// if (circleWidget == nullptr || add) { -// if (circleId != -1) -// Settings::getInstance().setFriendCircleID(f->getPublicKey(), -1); -// listLayout->addWidget(widget); -// return; -// } + // if (circleWidget == nullptr || add) { + // if (circleId != -1) + // Settings::getInstance().setFriendCircleID(f->getPublicKey(), -1); + // listLayout->addWidget(widget); + // return; + // } -// circleWidget->addFriendWidget(widget, s); -// } else { -// const IMFriend *contact = widget->getFriend(); -// auto *categoryWidget = getTimeCategoryWidget(contact); -// categoryWidget->addFriendWidget(widget, contact->getStatus()); -// categoryWidget->show(); -// } + // circleWidget->addFriendWidget(widget, s); + // } else { + // const IMFriend *contact = widget->getFriend(); + // auto *categoryWidget = getTimeCategoryWidget(contact); + // categoryWidget->addFriendWidget(widget, contact->getStatus()); + // categoryWidget->show(); + // } } -void MessageSessionListWidget::updateActivityTime(const QDateTime &time) { - if (mode != SortingMode::Activity) - return; +void MessageSessionListWidget::updateActivityTime(const QDateTime& time) { + if (mode != SortingMode::Activity) return; -// int timeIndex = static_cast(base::getTimeBucket(time)); -// QWidget *widget = activityLayout->itemAt(timeIndex)->widget(); -// CategoryWidget *categoryWidget = static_cast(widget); -// categoryWidget->updateStatus(); -// categoryWidget->setVisible(categoryWidget->hasChatrooms()); + // int timeIndex = static_cast(base::getTimeBucket(time)); + // QWidget *widget = activityLayout->itemAt(timeIndex)->widget(); + // CategoryWidget *categoryWidget = static_cast(widget); + // categoryWidget->updateStatus(); + // categoryWidget->setVisible(categoryWidget->hasChatrooms()); } // update widget after add/delete/hide/show void MessageSessionListWidget::reDraw() { - hide(); - show(); - resize(QSize()); // lifehack + hide(); + show(); + resize(QSize()); // lifehack } -void MessageSessionListWidget::setRecvGroupMessage(const GroupId &groupId, const GroupMessage &msg) -{ - +void MessageSessionListWidget::setRecvGroupMessage(const GroupId& groupId, + const GroupMessage& msg) { auto ms = getMessageSession(groupId.toString()); - if(!ms){ - ms = createMessageSession(groupId,"", ChatType::GroupChat); + if (!ms) { + ms = createMessageSession(groupId, "", ChatType::GroupChat); } ms->setRecvGroupMessage(msg); - } - -void MessageSessionListWidget::toSendMessage(const FriendId &pk, bool isGroup) -{ - qDebug() << __func__<< pk.toString(); +void MessageSessionListWidget::toSendMessage(const FriendId& pk, bool isGroup) { + qDebug() << __func__ << pk.toString(); auto w = sessionWidgets.value(pk.toString()); - if(!w){ - qDebug() << "Create session for"<chatroomWidgetClicked(w); - } -void MessageSessionListWidget::setFriendAvInvite(const ToxPeer &peerId, bool video) -{ +void MessageSessionListWidget::setFriendAvInvite(const ToxPeer& peerId, bool video) { auto friendId = peerId.toFriendId(); auto w = sessionWidgets.value(friendId.toString()); - if(!w){ - qDebug() << "Create session for friend"<< friendId; + if (!w) { + qDebug() << "Create session for friend" << friendId; w = createMessageSession(friendId, "", ChatType::Chat); } w->setAvInvite(peerId, video); } -void MessageSessionListWidget::setFriendAvStart(const FriendId& friendId, bool video) -{ +void MessageSessionListWidget::setFriendAvStart(const FriendId& friendId, bool video) { auto w = sessionWidgets.value(friendId.toString()); - if(!w){ + if (!w) { qWarning() << "The message session is no existing!"; return; } w->setAvStart(friendId, video); } -void MessageSessionListWidget::setFriendAvEnd(const FriendId &friendId, bool error) -{ +void MessageSessionListWidget::setFriendAvEnd(const FriendId& friendId, bool error) { auto w = sessionWidgets.value(friendId.toString()); - if(!w){ + if (!w) { qWarning() << "The message session is no existing!"; return; } w->setAvEnd(friendId, error); } -void MessageSessionListWidget::addGroup(const Group *g) -{ +void MessageSessionListWidget::addGroup(const Group* g) { auto ms = getMessageSession(g->getId()); - if(!ms){ - qWarning() <<"Unable to find message session" << g->getId(); - return; + if (!ms) { + qWarning() << "Unable to find message session" << g->getId(); + return; } ms->setGroup(g); } -void MessageSessionListWidget::removeGroup(const Group *g) -{ +void MessageSessionListWidget::removeGroup(const Group* g) { auto ms = getMessageSession(g->getId()); - if(!ms){ - qWarning() <<"Unable to find message session" << g->getId(); - return; + if (!ms) { + qWarning() << "Unable to find message session" << g->getId(); + return; } ms->removeGroup(); } -void MessageSessionListWidget::clearAllReceipts() -{ - for(auto sw: sessionWidgets){ - sw->clearReceipts(); - } +void MessageSessionListWidget::clearAllReceipts() { + for (auto sw : sessionWidgets) { + sw->clearReceipts(); + } } -QLayout *MessageSessionListWidget::nextLayout(QLayout *layout, bool forward) const { - qDebug() <<"nextLayout:"<getLayoutOnline(); + if (groupsOnTop) return listLayout->getLayoutOnline(); - return listLayout->getLayoutOffline(); + return listLayout->getLayoutOffline(); } else { - if (groupsOnTop) - // return circleLayout->getLayout(); + if (groupsOnTop) + // return circleLayout->getLayout(); - return listLayout->getLayoutOnline(); + return listLayout->getLayoutOnline(); } return nullptr; } -MessageSessionWidget *MessageSessionListWidget::getMessageSession(const QString &contactId) { +MessageSessionWidget* MessageSessionListWidget::getMessageSession(const QString& contactId) { return sessionWidgets.value(contactId); } -void MessageSessionListWidget::addFriend(const Friend *f) -{ +void MessageSessionListWidget::addFriend(const Friend* f) { auto ms = getMessageSession(f->getId().toString()); - if(!ms){ - qWarning() <<"Unable to find message session" <getId(); - return; + if (!ms) { + qWarning() << "Unable to find message session" << f->getId(); + return; } ms->setFriend(f); - } -void MessageSessionListWidget::removeFriend(const Friend *f) -{ +void MessageSessionListWidget::removeFriend(const Friend* f) { auto ms = getMessageSession(f->getId().toString()); - if(!ms){ - qWarning() <<"Unable to find message session" <getId(); - return; + if (!ms) { + qWarning() << "Unable to find message session" << f->getId(); + return; } ms->removeFriend(); } - -void MessageSessionListWidget::slot_sessionClicked(MessageSessionWidget *actived) { - for (auto w : sessionWidgets) { - if (w != actived) { - w->setActive(false); - } else { - w->setActive(true); +void MessageSessionListWidget::slot_sessionClicked(MessageSessionWidget* actived) { + for (auto w : sessionWidgets) { + if (w != actived) { + w->setActive(false); + } else { + w->setActive(true); + } } - } } -void MessageSessionListWidget::do_deleteSession(const QString &cid) -{ +void MessageSessionListWidget::do_deleteSession(const QString& cid) { qDebug() << __func__ << cid; - auto w = sessionWidgets.value(cid ); - if(w){ - qDebug() <<"delete"<deleteLater(); } } -void MessageSessionListWidget::do_clearHistory(const QString &cid) -{ - qDebug() << __func__ << cid; - auto ms = getMessageSession(cid); - if(ms){ +void MessageSessionListWidget::do_clearHistory(const QString& cid) { + qDebug() << __func__ << cid; + auto ms = getMessageSession(cid); + if (ms) { ms->clearHistory(); - } + } } +void MessageSessionListWidget::setRecvFriendMessage(FriendId friendnumber, + const FriendMessage& message, bool isAction) { + auto fw = getMessageSession(friendnumber.toString()); + if (!fw) { + /** + * 陌生人消息(可能是已经将对方删除,通讯录没有对方记录) + */ + qWarning() << "Can not find friend:" << friendnumber.toString() + << ", so add it to contact."; + fw = createMessageSession(friendnumber, message.id, ChatType::Chat); + } -void MessageSessionListWidget::setRecvFriendMessage( - FriendId friendnumber, const FriendMessage &message, - bool isAction) { - - auto fw = getMessageSession(friendnumber.toString()); - if(!fw){ - /** - * 陌生人消息(可能是已经将对方删除,通讯录没有对方记录) - */ - qWarning() << "Can not find friend:" << friendnumber.toString() - << ", so add it to contact."; - fw=createMessageSession(friendnumber, message.id, ChatType::Chat); - - } - - fw->setRecvMessage(message, isAction); + fw->setRecvMessage(message, isAction); } -void MessageSessionListWidget::setFriendMessageReceipt(const FriendId &friendId, - const MsgId &msgId) -{ +void MessageSessionListWidget::setFriendMessageReceipt(const FriendId& friendId, + const MsgId& msgId) { auto fw = getMessageSession(friendId.toString()); - if(!fw){ + if (!fw) { return; } fw->setMessageReceipt(msgId); } - -void MessageSessionListWidget::setFriendStatus(const FriendId &friendPk, Status::Status status) { - auto fw = getMessageSession(friendPk.toString()); - if (!fw) { - qWarning() << "friend widget is no existing."; - return; - } - fw->setStatus(status, false); +void MessageSessionListWidget::setFriendStatus(const FriendId& friendPk, Status::Status status) { + auto fw = getMessageSession(friendPk.toString()); + if (!fw) { + qWarning() << "friend widget is no existing."; + return; + } + fw->setStatus(status, false); } -void MessageSessionListWidget::setFriendStatusMsg(const FriendId &friendPk, - const QString &statusMsg) { - auto fw = getMessageSession(friendPk.toString()); - if (!fw) { - qWarning() << "friend widget no exist."; - return; - } - fw->setStatusMsg(statusMsg); +void MessageSessionListWidget::setFriendStatusMsg(const FriendId& friendPk, + const QString& statusMsg) { + auto fw = getMessageSession(friendPk.toString()); + if (!fw) { + qWarning() << "friend widget no exist."; + return; + } + fw->setStatusMsg(statusMsg); } -void MessageSessionListWidget::setFriendName(const FriendId &friendPk, const QString &name) { +void MessageSessionListWidget::setFriendName(const FriendId& friendPk, const QString& name) { auto fw = getMessageSession(friendPk.toString()); if (!fw) { - qWarning() << "friend is no exist."; - return; + qWarning() << "friend is no exist."; + return; } fw->setName(name); } -void MessageSessionListWidget::setFriendAvatar(const FriendId &friendPk, const QByteArray &avatar) { - auto fw = getMessageSession(friendPk.toString()); - if (!fw) { - qWarning() << "friend is no exist."; - return; - } +void MessageSessionListWidget::setFriendAvatar(const FriendId& friendPk, const QByteArray& avatar) { + auto fw = getMessageSession(friendPk.toString()); + if (!fw) { + qWarning() << "message session is no exist."; + return; + } - QPixmap p; - p.loadFromData(avatar); - fw->setAvatar(p); + QPixmap p; + p.loadFromData(avatar); + fw->setAvatar(p); } -void MessageSessionListWidget::setFriendTyping(const ContactId &f, bool isTyping) { - auto fw = getMessageSession(f.toString()); - if (fw) - fw->setTyping(isTyping); +void MessageSessionListWidget::setFriendTyping(const ContactId& f, bool isTyping) { + auto fw = getMessageSession(f.toString()); + if (fw) fw->setTyping(isTyping); } -void MessageSessionListWidget::setFriendFileReceived(const ContactId &f, const ToxFile &file) -{ +void MessageSessionListWidget::setFriendFileReceived(const ContactId& f, const ToxFile& file) { auto ms = getMessageSession(f.toString()); - if(ms){ + if (ms) { ms->setFileReceived(file); } - } -void MessageSessionListWidget::setFriendFileCancelled(const ContactId &f, const QString &fileId) -{ +void MessageSessionListWidget::setFriendFileCancelled(const ContactId& f, const QString& fileId) { auto ms = getMessageSession(f.toString()); - if(ms){ + if (ms) { ms->setFileCancelled(fileId); } } void MessageSessionListWidget::reloadTheme() { auto p = palette(); - p.setColor(QPalette::Window, Style::getColor(Style::ThemeMedium)); // Base background color - p.setColor(QPalette::Highlight, Style::getColor(Style::ThemeHighlight)); // On mouse over + p.setColor(QPalette::Window, Style::getColor(Style::ThemeMedium)); // Base background color + p.setColor(QPalette::Highlight, Style::getColor(Style::ThemeHighlight)); // On mouse over p.setColor(QPalette::Light, Style::getColor(Style::ThemeLight)); // When active setPalette(p); - for (auto fw: sessionWidgets) { - fw->reloadTheme(); - } + for (auto fw : sessionWidgets) { + fw->reloadTheme(); + } } diff --git a/src/modules/im/src/widget/MessageSessionListWidget.h b/src/modules/im/src/widget/MessageSessionListWidget.h index 65727fac..8cbd09c0 100644 --- a/src/modules/im/src/widget/MessageSessionListWidget.h +++ b/src/modules/im/src/widget/MessageSessionListWidget.h @@ -13,7 +13,7 @@ #ifndef MESSAGE_SESSION_LIST_WIDGET_H #define MESSAGE_SESSION_LIST_WIDGET_H - +#include #include "MessageSessionWidget.h" #include "genericchatitemlayout.h" #include "src/core/core.h" @@ -21,7 +21,6 @@ #include "src/model/message.h" #include "src/model/status.h" #include "src/persistence/settings.h" -#include class QVBoxLayout; class QGridLayout; @@ -29,8 +28,8 @@ class QPixmap; class Widget; class FriendWidget; class GroupWidget; -//class CircleWidget; -//class CategoryWidget; +// class CircleWidget; +// class CategoryWidget; class FriendListLayout; class GenericChatroomWidget; class Friend; @@ -38,114 +37,109 @@ class ContentLayout; class MainLayout; class MessageSessionListWidget : public QWidget { - Q_OBJECT + Q_OBJECT public: + using SortingMode = Settings::FriendListSortingMode; + explicit MessageSessionListWidget(MainLayout* parent, + ContentLayout* contentBox, + bool groupsOnTop = true); + ~MessageSessionListWidget(); + void setMode(SortingMode mode); + SortingMode getMode() const; + void reloadTheme(); - using SortingMode = Settings::FriendListSortingMode; - explicit MessageSessionListWidget(MainLayout *parent, - ContentLayout *contentBox, - bool groupsOnTop = true); - ~MessageSessionListWidget(); - void setMode(SortingMode mode); - SortingMode getMode() const; - void reloadTheme(); - - MessageSessionWidget *createMessageSession(const ContactId &cId, - const QString &sid, - ChatType type); + MessageSessionWidget* createMessageSession(const ContactId& cId, + const QString& sid, + ChatType type); - MessageSessionWidget *getMessageSession(const QString &contactId); + MessageSessionWidget* getMessageSession(const QString& contactId); - void removeSessionWidget(MessageSessionWidget *w); + void removeSessionWidget(MessageSessionWidget* w); - void addFriend(const Friend *f); - void removeFriend(const Friend *f); + void addFriend(const Friend* f); + void removeFriend(const Friend* f); - void setFriendStatus(const FriendId &friendPk, Status::Status status); - void setFriendStatusMsg(const FriendId &friendPk, const QString& statusMsg); - void setFriendName(const FriendId &fId, const QString& name); - void setFriendAvatar(const FriendId &fId, const QByteArray& avatar); - void setFriendTyping(const ContactId &cId, bool typing); - void setFriendFileReceived(const ContactId &cId, const ToxFile &file); - void setFriendFileCancelled(const ContactId &cId, const QString &fileId); + void setFriendStatus(const FriendId& friendPk, Status::Status status); + void setFriendStatusMsg(const FriendId& friendPk, const QString& statusMsg); + void setFriendName(const FriendId& fId, const QString& name); + void setFriendAvatar(const FriendId& fId, const QByteArray& avatar); + void setFriendTyping(const ContactId& cId, bool typing); + void setFriendFileReceived(const ContactId& cId, const ToxFile& file); + void setFriendFileCancelled(const ContactId& cId, const QString& fileId); - void searchChatrooms(const QString &searchString, bool hideOnline = false, - bool hideOffline = false, bool hideGroups = false); + void searchChatrooms(const QString& searchString, bool hideOnline = false, + bool hideOffline = false, bool hideGroups = false); - void cycleContacts(GenericChatroomWidget *activeChatroomWidget, bool forward); + void cycleContacts(GenericChatroomWidget* activeChatroomWidget, bool forward); - void updateActivityTime(const QDateTime &date); - void reDraw(); + void updateActivityTime(const QDateTime& date); + void reDraw(); - void setRecvGroupMessage(const GroupId& groupId, const GroupMessage& msg); + void setRecvGroupMessage(const GroupId& groupId, const GroupMessage& msg); - void setRecvFriendMessage(FriendId friendnumber, // - const FriendMessage &message, // - bool isAction); + void setRecvFriendMessage(FriendId friendnumber, // + const FriendMessage& message, // + bool isAction); - void setFriendMessageReceipt(const FriendId &friendId, const MsgId& receipt); + void setFriendMessageReceipt(const FriendId& friendId, const MsgId& receipt); -// CircleWidget *createCircleWidget(int id = -1); + // CircleWidget *createCircleWidget(int id = -1); - void toSendMessage(const FriendId &pk, bool isGroup); + void toSendMessage(const FriendId& pk, bool isGroup); - //av - void setFriendAvInvite(const ToxPeer &peer, bool video); - void setFriendAvStart(const FriendId &friendId, bool video); - void setFriendAvEnd(const FriendId &friendId, bool error); + // av + void setFriendAvInvite(const ToxPeer& peer, bool video); + void setFriendAvStart(const FriendId& friendId, bool video); + void setFriendAvEnd(const FriendId& friendId, bool error); + void addGroup(const Group* f); + void removeGroup(const Group* f); - void addGroup(const Group *f); - void removeGroup(const Group *f); - - void clearAllReceipts(); + void clearAllReceipts(); signals: - void sessionAdded(MessageSessionWidget* widget); - void onCompactChanged(bool compact); -// void connectCircleWidget(CircleWidget &circleWidget); -// void searchCircle(CircleWidget &circleWidget); + void sessionAdded(MessageSessionWidget* widget); + void onCompactChanged(bool compact); + // void connectCircleWidget(CircleWidget &circleWidget); + // void searchCircle(CircleWidget &circleWidget); public slots: -// void renameGroupWidget(GroupWidget *groupWidget, const QString &newName); - -// void renameCircleWidget(CircleWidget *circleWidget, const QString &newName); - void onFriendWidgetRenamed(FriendWidget *friendWidget); + // void renameGroupWidget(GroupWidget *groupWidget, const QString &newName); - void slot_sessionClicked(MessageSessionWidget *w); - void do_deleteSession(const QString &contactId); - void do_clearHistory(const QString &contactId); + // void renameCircleWidget(CircleWidget *circleWidget, const QString &newName); + void onFriendWidgetRenamed(FriendWidget* friendWidget); - void moveWidget(MessageSessionWidget *w, Status::Status s, bool add = false); + void slot_sessionClicked(MessageSessionWidget* w); + void do_deleteSession(const QString& contactId); + void do_clearHistory(const QString& contactId); + void moveWidget(MessageSessionWidget* w, Status::Status s, bool add = false); - void dayTimeout(); + void dayTimeout(); protected: - void dragEnterEvent(QDragEnterEvent *event) override; - void dropEvent(QDropEvent *event) override; - void showEvent(QShowEvent *event) override; - + void dragEnterEvent(QDragEnterEvent* event) override; + void dropEvent(QDropEvent* event) override; + void showEvent(QShowEvent* event) override; private: - QLayout *nextLayout(QLayout *layout, bool forward) const; - void moveFriends(QLayout *layout); -// CategoryWidget *getTimeCategoryWidget(const IMFriend *frd) const; - void sortByMode(SortingMode mode); - void connectSessionWidget(MessageSessionWidget &sw); - void updateFriendActivity(const Friend &frnd); - - SortingMode mode; + QLayout* nextLayout(QLayout* layout, bool forward) const; + void moveFriends(QLayout* layout); + // CategoryWidget *getTimeCategoryWidget(const IMFriend *frd) const; + void sortByMode(SortingMode mode); + void connectSessionWidget(MessageSessionWidget& sw); + void updateFriendActivity(const Friend& frnd); - bool groupsOnTop; - FriendListLayout *listLayout; -// GenericChatItemLayout *circleLayout = nullptr; - QVBoxLayout *activityLayout = nullptr; - QTimer *dayTimer; + SortingMode mode; - ContentLayout *m_contentLayout; + bool groupsOnTop; + FriendListLayout* listLayout; + // GenericChatItemLayout *circleLayout = nullptr; + QVBoxLayout* activityLayout = nullptr; + QTimer* dayTimer; - QMap sessionWidgets; + ContentLayout* m_contentLayout; + QMap sessionWidgets; }; -#endif // FRIENDLISTWIDGET_H +#endif // FRIENDLISTWIDGET_H diff --git a/src/modules/im/src/widget/MessageSessionWidget.cpp b/src/modules/im/src/widget/MessageSessionWidget.cpp index cd35e818..22555897 100644 --- a/src/modules/im/src/widget/MessageSessionWidget.cpp +++ b/src/modules/im/src/widget/MessageSessionWidget.cpp @@ -48,12 +48,12 @@ #include +#include +#include #include "form/chatform.h" #include "src/model/chathistory.h" #include "src/persistence/profile.h" #include "src/widget/chatformheader.h" -#include -#include #include @@ -64,163 +64,173 @@ * For example, used on friend list. * When you click should open the chat with friend. Widget has a context menu. */ -MessageSessionWidget::MessageSessionWidget(ContentLayout *layout, const ContactId &cId, ChatType chatType) - : GenericChatroomWidget(chatType, cId), contentLayout(layout), sendWorker{nullptr}, contactId(cId) { - +MessageSessionWidget::MessageSessionWidget(ContentLayout* layout, const ContactId& cId, + ChatType chatType) + : GenericChatroomWidget(chatType, cId) + , contentLayout(layout) + , sendWorker{nullptr} + , contactId(cId) { setAutoFillBackground(false); - qDebug() << __func__ << "contactId:" << cId.toString(); - - auto profile = Nexus::getProfile(); - auto core = Core::getInstance(); - auto &settings = Settings::getInstance(); - auto history = profile->getHistory(); - auto dialogManager = ContentDialogManager::getInstance(); - auto widget = Widget::getInstance(); - - if (chatType == ChatType::Chat) { - friendId = FriendId(contactId); - - sendWorker = std::move(SendWorker::forFriend(friendId)); - connect(sendWorker->dispacher(), &IMessageDispatcher::messageSent, this, &MessageSessionWidget::onMessageSent); - connect(sendWorker.get(), &SendWorker::acceptCall, this, &MessageSessionWidget::doAcceptCall); - connect(sendWorker.get(), &SendWorker::rejectCall, this, &MessageSessionWidget::doRejectCall); - connect(sendWorker.get(), &SendWorker::endCall, this, &MessageSessionWidget::endCall); - connect(sendWorker.get(), &SendWorker::onCallTriggered, this, &MessageSessionWidget::doCall); - connect(sendWorker.get(), &SendWorker::onVideoCallTriggered, this, &MessageSessionWidget::doVideoCall); - connect(sendWorker.get(), &SendWorker::muteMicrophone, this, &MessageSessionWidget::doMuteMicrophone); - connect(sendWorker.get(), &SendWorker::muteSpeaker, this, &MessageSessionWidget::doSilenceSpeaker); - - } else if (chatType == ChatType::GroupChat) { - auto nick = core->getNick(); - groupId = GroupId(contactId); - groupId.nick = nick; - - sendWorker = std::move(SendWorker::forGroup(groupId)); - - connect(sendWorker->dispacher(), &IMessageDispatcher::messageSent, this, &MessageSessionWidget::onMessageSent); - - // connect(g, &Group::displayedNameChanged, this, - // [this](const QString &newName) { - // setName(newName); - // }); - } - - contentWidget = std::make_unique(sendWorker.get(), this); - - // contentWidget->hide(); - contentLayout->addWidget(contentWidget.get()); - - auto chatForm = sendWorker->getChatForm(); - connect(chatForm->getChatLog(), &ChatLog::readAll, this, [&]() { - if (contentWidget->isVisible()) { - // 已经阅读完消息,信号灯还原 - updateStatusLight(Core::getInstance()->getFriendStatus(contactId.toString()), false); + qDebug() << __func__ << "contactId:" << cId.toString(); + + auto profile = Nexus::getProfile(); + auto core = Core::getInstance(); + auto& settings = Settings::getInstance(); + auto history = profile->getHistory(); + auto dialogManager = ContentDialogManager::getInstance(); + auto widget = Widget::getInstance(); + + if (chatType == ChatType::Chat) { + friendId = FriendId(contactId); + + sendWorker = std::move(SendWorker::forFriend(friendId)); + connect(sendWorker->dispacher(), &IMessageDispatcher::messageSent, this, + &MessageSessionWidget::onMessageSent); + connect(sendWorker.get(), &SendWorker::acceptCall, this, + &MessageSessionWidget::doAcceptCall); + connect(sendWorker.get(), &SendWorker::rejectCall, this, + &MessageSessionWidget::doRejectCall); + connect(sendWorker.get(), &SendWorker::endCall, this, &MessageSessionWidget::endCall); + connect(sendWorker.get(), &SendWorker::onCallTriggered, this, + &MessageSessionWidget::doCall); + connect(sendWorker.get(), &SendWorker::onVideoCallTriggered, this, + &MessageSessionWidget::doVideoCall); + connect(sendWorker.get(), &SendWorker::muteMicrophone, this, + &MessageSessionWidget::doMuteMicrophone); + connect(sendWorker.get(), &SendWorker::muteSpeaker, this, + &MessageSessionWidget::doSilenceSpeaker); + + } else if (chatType == ChatType::GroupChat) { + auto nick = core->getNick(); + groupId = GroupId(contactId); + groupId.nick = nick; + + sendWorker = std::move(SendWorker::forGroup(groupId)); + + connect(sendWorker->dispacher(), &IMessageDispatcher::messageSent, this, + &MessageSessionWidget::onMessageSent); + + // connect(g, &Group::displayedNameChanged, this, + // [this](const QString &newName) { + // setName(newName); + // }); } - }); - - // const auto compact = settings.getCompactLayout(); - - // const auto activityTime = settings.getFriendActivity(toxPk); - // const auto chatTime = sendWorker->getChatForm()->getLatestTime(); - // if (chatTime > activityTime && chatTime.isValid()) { - // settings.setFriendActivity(toxPk, chatTime); - // } - - // chatRoom = std::make_unique(m_friend, dialogManager); - // auto frnd = chatRoom->getFriend(); - - // nameLabel->setText(getContact()->getDisplayedName());; - - // update alias when edited - // connect(nameLabel, &CroppingLabel::editFinished, // - // m_friend, &IMFriend::setAlias); - - // connect(m_friend, &IMFriend::displayedNameChanged, // - // nameLabel, &CroppingLabel::setText); - - // connect(m_friend, &IMFriend::displayedNameChanged, this, - // [this](const QString &newName) { - // Q_UNUSED(newName); - // emit widgetRenamed(this); - // }); - - // connect(sendWorker->getChatroom(), - // &Chatroom::activeChanged, - // this, - // &MessageSessionWidget::setActive); - // statusMessageLabel->setTextFormat(Qt::PlainText); - - // connect(this, &MessageSessionWidget::middleMouseClicked, dialog, - // [this]() { dialog->removeFriend(friendPk); }); - // connect(MessageSessionWidget, &MessageSessionWidget::copyFriendIdToClipboard, this, - // &Widget::copyFriendIdToClipboard); - // connect(MessageSessionWidget, &MessageSessionWidget::newWindowOpened, this, - // &Widget::openNewDialog); - - // Signal transmission from the created `MessageSessionWidget` (which shown in - // ContentDialog) to the `widget` (which shown in main widget) - // FIXME: emit should be removed - // connect( - // this, &MessageSessionWidget::contextMenuCalled, this, - // [this](QContextMenuEvent *event) { emit contextMenuCalled(event); }); - // - connect(this, &MessageSessionWidget::chatroomWidgetClicked, [=, this](GenericChatroomWidget *w) { - Q_UNUSED(w); - do_widgetClicked(); - emit widgetClicked(this); - }); - - // connect(getContact(), &Contact::avatarChanged, - // [&](auto& pic) { - // setAvatar(pic); - // }); -} - -MessageSessionWidget::~MessageSessionWidget() { - qDebug() << __func__ << contactId; -} -void MessageSessionWidget::do_widgetClicked() { - // qDebug() << __func__ << "contactId:" << contactId.toString(); - contentWidget->showTo(contentLayout); -} - -void MessageSessionWidget::showEvent(QShowEvent *e) { - GenericChatroomWidget::showEvent(e); - if (isGroup()) { - auto group = GroupList::findGroup(GroupId{contactId.toString()}); - if (group) { - setContact(*group); - sendWorker->getHeader()->setContact(contact); - sendWorker->getChatForm()->setContact(contact); - } - } else { - auto f = FriendList::findFriend(contactId); - if (f) { - setContact(*f); - sendWorker->getHeader()->setContact(contact); - sendWorker->getChatForm()->setContact(contact); - } + contentWidget = std::make_unique(sendWorker.get(), this); + + // contentWidget->hide(); + contentLayout->addWidget(contentWidget.get()); + + auto chatForm = sendWorker->getChatForm(); + connect(chatForm->getChatLog(), &ChatLog::readAll, this, [&]() { + if (contentWidget->isVisible()) { + // 已经阅读完消息,信号灯还原 + updateStatusLight(Core::getInstance()->getFriendStatus(contactId.toString()), false); + } + }); + + // const auto compact = settings.getCompactLayout(); + + // const auto activityTime = settings.getFriendActivity(toxPk); + // const auto chatTime = sendWorker->getChatForm()->getLatestTime(); + // if (chatTime > activityTime && chatTime.isValid()) { + // settings.setFriendActivity(toxPk, chatTime); + // } + + // chatRoom = std::make_unique(m_friend, dialogManager); + // auto frnd = chatRoom->getFriend(); + + // nameLabel->setText(getContact()->getDisplayedName());; + + // update alias when edited + // connect(nameLabel, &CroppingLabel::editFinished, // + // m_friend, &IMFriend::setAlias); + + // connect(m_friend, &IMFriend::displayedNameChanged, // + // nameLabel, &CroppingLabel::setText); + + // connect(m_friend, &IMFriend::displayedNameChanged, this, + // [this](const QString &newName) { + // Q_UNUSED(newName); + // emit widgetRenamed(this); + // }); + + // connect(sendWorker->getChatroom(), + // &Chatroom::activeChanged, + // this, + // &MessageSessionWidget::setActive); + // statusMessageLabel->setTextFormat(Qt::PlainText); + + // connect(this, &MessageSessionWidget::middleMouseClicked, dialog, + // [this]() { dialog->removeFriend(friendPk); }); + // connect(MessageSessionWidget, &MessageSessionWidget::copyFriendIdToClipboard, this, + // &Widget::copyFriendIdToClipboard); + // connect(MessageSessionWidget, &MessageSessionWidget::newWindowOpened, this, + // &Widget::openNewDialog); + + // Signal transmission from the created `MessageSessionWidget` (which shown in + // ContentDialog) to the `widget` (which shown in main widget) + // FIXME: emit should be removed + // connect( + // this, &MessageSessionWidget::contextMenuCalled, this, + // [this](QContextMenuEvent *event) { emit contextMenuCalled(event); }); + // + connect(this, &MessageSessionWidget::chatroomWidgetClicked, + [=, this](GenericChatroomWidget* w) { + Q_UNUSED(w); + do_widgetClicked(); + emit widgetClicked(this); + }); + + // connect(getContact(), &Contact::avatarChanged, + // [&](auto& pic) { + // setAvatar(pic); + // }); +} + +MessageSessionWidget::~MessageSessionWidget() { qDebug() << __func__ << contactId; } - updateStatusLight(Core::getInstance()->getFriendStatus(contactId.toString()), false); - - auto msgs = sendWorker->getLastTextMessage(); - for (auto m : msgs) { - updateLastMessage(m); - break; +void MessageSessionWidget::do_widgetClicked() { + // qDebug() << __func__ << "contactId:" << contactId.toString(); + contentWidget->showTo(contentLayout); +} + +void MessageSessionWidget::showEvent(QShowEvent* e) { + GenericChatroomWidget::showEvent(e); + if (isGroup()) { + auto group = GroupList::findGroup(GroupId{contactId.toString()}); + if (group) { + setContact(*group); + sendWorker->getHeader()->setContact(contact); + sendWorker->getChatForm()->setContact(contact); + } + } else { + auto f = FriendList::findFriend(contactId); + if (f) { + setContact(*f); + sendWorker->getHeader()->setContact(contact); + sendWorker->getChatForm()->setContact(contact); + } + + updateStatusLight(Core::getInstance()->getFriendStatus(contactId.toString()), false); + + auto msgs = sendWorker->getLastTextMessage(); + for (auto m : msgs) { + updateLastMessage(m); + break; + } } - } - // auto chatForm = sendWorker->getChatForm(); - // auto cl= chatForm->getChatLog(); - // auto vbv = cl->getVScrollBarValue(); - // if(vbv<=0){ - // //无滚动条,设置用户默认信号灯 - // updateStatusLight(Core::getInstance()->getFriendStatus(contactId.toString()), false); - // } - // QScrollBar *sb = cl->verticalScrollBar(); - // auto sbv= sb->value(); - // qDebug() << sbv; + // auto chatForm = sendWorker->getChatForm(); + // auto cl= chatForm->getChatLog(); + // auto vbv = cl->getVScrollBarValue(); + // if(vbv<=0){ + // //无滚动条,设置用户默认信号灯 + // updateStatusLight(Core::getInstance()->getFriendStatus(contactId.toString()), false); + // } + // QScrollBar *sb = cl->verticalScrollBar(); + // auto sbv= sb->value(); + // qDebug() << sbv; } /** @@ -230,9 +240,9 @@ void MessageSessionWidget::showEvent(QShowEvent *e) { * Default context menu event handler. * Redirect all event information to the signal. */ -void MessageSessionWidget::contextMenuEvent(QContextMenuEvent *event) { - onContextMenuCalled(event); - emit contextMenuCalled(event); +void MessageSessionWidget::contextMenuEvent(QContextMenuEvent* event) { + onContextMenuCalled(event); + emit contextMenuCalled(event); } /** @@ -241,104 +251,104 @@ void MessageSessionWidget::contextMenuEvent(QContextMenuEvent *event) { * * Context menu handler. Always should be called to MessageSessionWidget from FriendList */ -void MessageSessionWidget::onContextMenuCalled(QContextMenuEvent *event) { - if (!active) { - setBackgroundRole(QPalette::Highlight); - } - - installEventFilter(this); // Disable leave event. - - auto chatRoom = sendWorker->getChatroom(); - - QMenu menu; - // menu.addSeparator(); - auto deleteAct = menu.addAction(tr("Delete the session")); - // inviteMenu->setEnabled(chatRoom->canBeInvited()); - - connect(deleteAct, &QAction::triggered, this, &MessageSessionWidget::removeChat); - // inviteMenu->addSeparator(); - - // for (const auto &group : chatRoom->getGroups()) { - // const auto groupAction = - // inviteMenu->addAction(tr("Invite to group '%1'").arg(group.name)); - // connect(groupAction, &QAction::triggered, - // [=, this]() { chatRoom->inviteFriend(group.group); }); - // } - // - // const auto circleId = chatRoom->getCircleId(); - // auto circleMenu = menu.addMenu( - // tr("Move to circle...", "Menu to move a friend into a different - // circle")); - // - // const auto newCircleAction = circleMenu->addAction(tr("To new circle")); - // connect(newCircleAction, &QAction::triggered, this, - // &MessageSessionWidget::moveToNewCircle); - // - // if (circleId != -1) { - // const auto circleName = chatRoom->getCircleName(); - // const auto removeCircleAction = - // circleMenu->addAction(tr("Remove from circle - // '%1'").arg(circleName)); - // connect(removeCircleAction, &QAction::triggered, this, - // &MessageSessionWidget::removeFromCircle); - // } - // circleMenu->addSeparator(); - // - // for (const auto &circle : chatRoom->getOtherCircles()) { - // QAction *action = - // new QAction(tr("Move to circle \"%1\"").arg(circle.name), - // circleMenu); - // connect(action, &QAction::triggered, - // [this]() { moveToCircle(circle.circleId); }); - // circleMenu->addAction(action); - // } - - // const auto setAlias = menu.addAction(tr("Set alias...")); - // connect(setAlias, &QAction::triggered, nameLabel, &CroppingLabel::editBegin); - - // 自动接收文件 - // menu.addSeparator(); - // auto autoAccept = menu.addAction( - // tr("Auto accept files from this friend", "context menu entry")); - // autoAccept->setCheckable(true); - // autoAccept->setChecked(!chatRoom->autoAcceptEnabled()); - // connect(autoAccept, &QAction::triggered, this, - // &MessageSessionWidget::changeAutoAccept); - - // menu.addSeparator(); - - // auto fnd = chatRoom->getFriend(); - // if (chatRoom->friendCanBeRemoved()) { - // const auto friendPk = fnd->getPublicKey(); - // const auto removeAction = menu.addAction( - // tr("Remove friend", "Menu to remove the friend from our friendlist")); - // connect( - // removeAction, &QAction::triggered, this, - // [=, this]() { emit removeFriend(friendPk); }, Qt::QueuedConnection); - // } - - // menu.addSeparator(); - - // if (!fnd->isFriend()) { - // const auto friendPk = fnd->getPublicKey(); - // const auto addAction = menu.addAction("添加好友"); - // connect( - // addAction, &QAction::triggered, this, - // [=, this]() { emit addFriend(friendPk); }, Qt::QueuedConnection); - // } - - // menu.addSeparator(); - const auto aboutWindow = menu.addAction(tr("Show details")); - connect(aboutWindow, &QAction::triggered, this, &MessageSessionWidget::showDetails); - - const auto pos = event->globalPos(); - menu.exec(pos); - - removeEventFilter(this); - - if (!active) { - setBackgroundRole(QPalette::Window); - } +void MessageSessionWidget::onContextMenuCalled(QContextMenuEvent* event) { + if (!active) { + setBackgroundRole(QPalette::Highlight); + } + + installEventFilter(this); // Disable leave event. + + auto chatRoom = sendWorker->getChatroom(); + + QMenu menu; + // menu.addSeparator(); + auto deleteAct = menu.addAction(tr("Delete the session")); + // inviteMenu->setEnabled(chatRoom->canBeInvited()); + + connect(deleteAct, &QAction::triggered, this, &MessageSessionWidget::removeChat); + // inviteMenu->addSeparator(); + + // for (const auto &group : chatRoom->getGroups()) { + // const auto groupAction = + // inviteMenu->addAction(tr("Invite to group '%1'").arg(group.name)); + // connect(groupAction, &QAction::triggered, + // [=, this]() { chatRoom->inviteFriend(group.group); }); + // } + // + // const auto circleId = chatRoom->getCircleId(); + // auto circleMenu = menu.addMenu( + // tr("Move to circle...", "Menu to move a friend into a different + // circle")); + // + // const auto newCircleAction = circleMenu->addAction(tr("To new circle")); + // connect(newCircleAction, &QAction::triggered, this, + // &MessageSessionWidget::moveToNewCircle); + // + // if (circleId != -1) { + // const auto circleName = chatRoom->getCircleName(); + // const auto removeCircleAction = + // circleMenu->addAction(tr("Remove from circle + // '%1'").arg(circleName)); + // connect(removeCircleAction, &QAction::triggered, this, + // &MessageSessionWidget::removeFromCircle); + // } + // circleMenu->addSeparator(); + // + // for (const auto &circle : chatRoom->getOtherCircles()) { + // QAction *action = + // new QAction(tr("Move to circle \"%1\"").arg(circle.name), + // circleMenu); + // connect(action, &QAction::triggered, + // [this]() { moveToCircle(circle.circleId); }); + // circleMenu->addAction(action); + // } + + // const auto setAlias = menu.addAction(tr("Set alias...")); + // connect(setAlias, &QAction::triggered, nameLabel, &CroppingLabel::editBegin); + + // 自动接收文件 + // menu.addSeparator(); + // auto autoAccept = menu.addAction( + // tr("Auto accept files from this friend", "context menu entry")); + // autoAccept->setCheckable(true); + // autoAccept->setChecked(!chatRoom->autoAcceptEnabled()); + // connect(autoAccept, &QAction::triggered, this, + // &MessageSessionWidget::changeAutoAccept); + + // menu.addSeparator(); + + // auto fnd = chatRoom->getFriend(); + // if (chatRoom->friendCanBeRemoved()) { + // const auto friendPk = fnd->getPublicKey(); + // const auto removeAction = menu.addAction( + // tr("Remove friend", "Menu to remove the friend from our friendlist")); + // connect( + // removeAction, &QAction::triggered, this, + // [=, this]() { emit removeFriend(friendPk); }, Qt::QueuedConnection); + // } + + // menu.addSeparator(); + + // if (!fnd->isFriend()) { + // const auto friendPk = fnd->getPublicKey(); + // const auto addAction = menu.addAction("添加好友"); + // connect( + // addAction, &QAction::triggered, this, + // [=, this]() { emit addFriend(friendPk); }, Qt::QueuedConnection); + // } + + // menu.addSeparator(); + const auto aboutWindow = menu.addAction(tr("Show details")); + connect(aboutWindow, &QAction::triggered, this, &MessageSessionWidget::showDetails); + + const auto pos = event->globalPos(); + menu.exec(pos); + + removeEventFilter(this); + + if (!active) { + setBackgroundRole(QPalette::Window); + } } void MessageSessionWidget::removeChat() { emit deleteSession(contactId.toString()); } @@ -359,293 +369,283 @@ void MessageSessionWidget::removeChat() { emit deleteSession(contactId.toString( //} // namespace void MessageSessionWidget::moveToNewCircle() { - // const auto frnd = chatRoom->getFriend(); - // CircleWidget *circleWidget; - // FriendListWidget *friendList; - // std::tie(circleWidget, friendList) = getCircleAndFriendList(frnd, this); + // const auto frnd = chatRoom->getFriend(); + // CircleWidget *circleWidget; + // FriendListWidget *friendList; + // std::tie(circleWidget, friendList) = getCircleAndFriendList(frnd, this); - // if (circleWidget != nullptr) { - // circleWidget->updateStatus(); - // } + // if (circleWidget != nullptr) { + // circleWidget->updateStatus(); + // } - // if (friendList != nullptr) { - // friendList->addCircleWidget(this); - // } else { - // const auto pk = frnd->getPublicKey(); - // auto &s = Settings::getInstance(); - // auto circleId = s.addCircle(); - // s.setFriendCircleID(pk, circleId); - // } + // if (friendList != nullptr) { + // friendList->addCircleWidget(this); + // } else { + // const auto pk = frnd->getPublicKey(); + // auto &s = Settings::getInstance(); + // auto circleId = s.addCircle(); + // s.setFriendCircleID(pk, circleId); + // } } void MessageSessionWidget::removeFromCircle() { - // const auto frnd = chatRoom->getFriend(); - // CircleWidget *circleWidget; - // FriendListWidget *friendList; - // std::tie(circleWidget, friendList) = getCircleAndFriendList(frnd, this); + // const auto frnd = chatRoom->getFriend(); + // CircleWidget *circleWidget; + // FriendListWidget *friendList; + // std::tie(circleWidget, friendList) = getCircleAndFriendList(frnd, this); - // if (friendList != nullptr) { - // friendList->moveWidget(this, frnd->getStatus(), true); - // } else { - // const auto pk = frnd->getPublicKey(); - // auto &s = Settings::getInstance(); - // s.setFriendCircleID(pk, -1); - // } + // if (friendList != nullptr) { + // friendList->moveWidget(this, frnd->getStatus(), true); + // } else { + // const auto pk = frnd->getPublicKey(); + // auto &s = Settings::getInstance(); + // s.setFriendCircleID(pk, -1); + // } - // if (circleWidget != nullptr) { - // circleWidget->updateStatus(); - // emit searchCircle(*circleWidget); - // } + // if (circleWidget != nullptr) { + // circleWidget->updateStatus(); + // emit searchCircle(*circleWidget); + // } } void MessageSessionWidget::moveToCircle(int newCircleId) { - // const auto frnd = getFriend(); - // const auto pk = frnd->getPublicKey(); - // const auto oldCircleId = Settings::getInstance().getFriendCircleID(pk); - // auto &s = Settings::getInstance(); - // auto oldCircleWidget = CircleWidget::getFromID(oldCircleId); - // auto newCircleWidget = CircleWidget::getFromID(newCircleId); - - // if (newCircleWidget) { - // newCircleWidget->addFriendWidget(this, frnd->getStatus()); - // newCircleWidget->setExpanded(true); - // emit searchCircle(*newCircleWidget); - // s.savePersonal(); - // } else { - // s.setFriendCircleID(pk, newCircleId); - // } - - // if (oldCircleWidget) { - // oldCircleWidget->updateStatus(); - // emit searchCircle(*oldCircleWidget); - // } + // const auto frnd = getFriend(); + // const auto pk = frnd->getPublicKey(); + // const auto oldCircleId = Settings::getInstance().getFriendCircleID(pk); + // auto &s = Settings::getInstance(); + // auto oldCircleWidget = CircleWidget::getFromID(oldCircleId); + // auto newCircleWidget = CircleWidget::getFromID(newCircleId); + + // if (newCircleWidget) { + // newCircleWidget->addFriendWidget(this, frnd->getStatus()); + // newCircleWidget->setExpanded(true); + // emit searchCircle(*newCircleWidget); + // s.savePersonal(); + // } else { + // s.setFriendCircleID(pk, newCircleId); + // } + + // if (oldCircleWidget) { + // oldCircleWidget->updateStatus(); + // emit searchCircle(*oldCircleWidget); + // } } void MessageSessionWidget::changeAutoAccept(bool enable) { - // auto chatRoom = sendWorker->getChatroom(); - // if (enable) { - // const auto oldDir = chatRoom->getAutoAcceptDir(); - // const auto newDir = QFileDialog::getExistingDirectory( - // Q_NULLPTR, tr("Choose an auto accept directory", "popup title"), - // oldDir); - // chatRoom->setAutoAcceptDir(newDir); - // } else { - // chatRoom->disableAutoAccept(); - // } + // auto chatRoom = sendWorker->getChatroom(); + // if (enable) { + // const auto oldDir = chatRoom->getAutoAcceptDir(); + // const auto newDir = QFileDialog::getExistingDirectory( + // Q_NULLPTR, tr("Choose an auto accept directory", "popup title"), + // oldDir); + // chatRoom->setAutoAcceptDir(newDir); + // } else { + // chatRoom->disableAutoAccept(); + // } } void MessageSessionWidget::showDetails() { - // const auto frnd = chatRoom->getFriend(); - // const auto iabout = new AboutFriend(frnd, &Settings::getInstance()); - // std::unique_ptr about = std::unique_ptr(iabout); - // const auto aboutUser = new AboutFriendForm(std::move(about), this); - // connect(aboutUser, &AboutFriendForm::histroyRemoved, this, - // &MessageSessionWidget::friendHistoryRemoved); - // aboutUser->show(); + // const auto frnd = chatRoom->getFriend(); + // const auto iabout = new AboutFriend(frnd, &Settings::getInstance()); + // std::unique_ptr about = std::unique_ptr(iabout); + // const auto aboutUser = new AboutFriendForm(std::move(about), this); + // connect(aboutUser, &AboutFriendForm::histroyRemoved, this, + // &MessageSessionWidget::friendHistoryRemoved); + // aboutUser->show(); - auto w = Widget::getInstance(); - if (w) { - emit w->toShowDetails(getContactId()); - } + auto w = Widget::getInstance(); + if (w) { + emit w->toShowDetails(getContactId()); + } } -void MessageSessionWidget::onMessageSent(DispatchedMessageId id, const Message &message) { +void MessageSessionWidget::onMessageSent(DispatchedMessageId id, const Message& message) { updateLastMessage(message); } -void MessageSessionWidget::setFriend(const Friend *f) { - qDebug() << __func__ << f; - if (!f) { - return; - } - - connect(f, &Friend::displayedNameChanged, this, [&](const QString &name) { setName(name); }); - - connect(f, &Friend::statusChanged, this, [this](Status::Status status, bool event) { setStatus(status, event); }); +void MessageSessionWidget::setFriend(const Friend* f) { + qDebug() << __func__ << f; + if (!f) { + return; + } - connect(f, &Friend::avatarChanged, this, [this](const QPixmap &avatar) { setAvatar(avatar); }); + connect(f, &Friend::displayedNameChanged, this, [&](const QString& name) { setName(name); }); + connect(f, &Friend::statusChanged, this, + [this](Status::Status status, bool event) { setStatus(status, event); }); + connect(f, &Friend::avatarChanged, this, [this](const QPixmap& avatar) { setAvatar(avatar); }); - setContact(*f); + setContact(*f); - sendWorker->getChatForm()->setContact(f); - sendWorker->getHeader()->setContact(f); + sendWorker->getChatForm()->setContact(f); + sendWorker->getHeader()->setContact(f); } void MessageSessionWidget::removeFriend() { - removeContact(); + removeContact(); - sendWorker->getChatForm()->removeContact(); - sendWorker->getHeader()->removeContact(); + sendWorker->getChatForm()->removeContact(); + sendWorker->getHeader()->removeContact(); } -void MessageSessionWidget::setAvInvite(const ToxPeer &peerId, bool video) { - qDebug() << __func__ << peerId.toString(); +void MessageSessionWidget::setAvInvite(const ToxPeer& peerId, bool video) { + qDebug() << __func__ << peerId.toString(); - QString friendId0 = peerId.toFriendId().toString(); - auto f = FriendList::findFriend(peerId); + QString friendId0 = peerId.toFriendId().toString(); + auto f = FriendList::findFriend(peerId); - QString displayedName = f ? f->getDisplayedName() : peerId.username; - qDebug() << "show displayedName:" << displayedName; + QString displayedName = f ? f->getDisplayedName() : peerId.username; + qDebug() << "show displayedName:" << displayedName; - // 显示呼叫请求框 - auto header = sendWorker->getHeader(); - header->createCallConfirm(peerId, video, displayedName); - header->showCallConfirm(); + // 显示呼叫请求框 + auto header = sendWorker->getHeader(); + header->createCallConfirm(peerId, video, displayedName); + header->showCallConfirm(); - // 发送来电声音 - auto w = Widget::getInstance(); - w->incomingNotification(friendId0); + // 发送来电声音 + auto w = Widget::getInstance(); + w->incomingNotification(friendId0); } -void MessageSessionWidget::setAvStart(const FriendId &friendId, bool video) { - qDebug() << __func__ << friendId.toString(); - // 显示呼叫请求框 - auto chatForm = (ChatForm *)sendWorker->getChatForm(); - sendWorker->startCounter(video); - - auto frd = FriendList::findFriend(friendId); - if (frd) { - auto header = sendWorker->getHeader(); - header->updateCallButtons(frd->getStatus()); - header->removeCallConfirm(); +void MessageSessionWidget::setAvStart(const FriendId& friendId, bool video) { + qDebug() << __func__ << friendId.toString(); + // 显示呼叫请求框 + auto chatForm = (ChatForm*)sendWorker->getChatForm(); + sendWorker->startCounter(video); - } + auto frd = FriendList::findFriend(friendId); + if (frd) { + auto header = sendWorker->getHeader(); + header->updateCallButtons(frd->getStatus()); + header->removeCallConfirm(); + } - auto w = Widget::getInstance(); - w->onStopNotification(); + auto w = Widget::getInstance(); + w->onStopNotification(); } -void MessageSessionWidget::setAvEnd(const FriendId &friendId, bool error) { - qDebug() << __func__ << friendId.toString(); +void MessageSessionWidget::setAvEnd(const FriendId& friendId, bool error) { + qDebug() << __func__ << friendId.toString(); - auto header = sendWorker->getHeader(); - header->removeCallConfirm(); - header->updateCallButtons(); + auto header = sendWorker->getHeader(); + header->removeCallConfirm(); + header->updateCallButtons(); - auto f = FriendList::findFriend(friendId); - if (f) { - header->updateCallButtons(f->getStatus() == Status::Status::Online, false, false); - } + auto f = FriendList::findFriend(friendId); + if (f) { + header->updateCallButtons(f->getStatus() == Status::Status::Online, false, false); + } - auto chatForm = (ChatForm *)sendWorker->getChatForm(); - // 关闭呼叫请求框 + auto chatForm = (ChatForm*)sendWorker->getChatForm(); + // 关闭呼叫请求框 - chatForm->stopNotification(); - // 关计时器 - sendWorker->stopCounter(error); + chatForm->stopNotification(); + // 关计时器 + sendWorker->stopCounter(error); - auto w = Widget::getInstance(); - w->onStopNotification(); + auto w = Widget::getInstance(); + w->onStopNotification(); } -void MessageSessionWidget::setGroup(const Group *g) { - qDebug() << __func__ << g; - if (!g) { - return; - } +void MessageSessionWidget::setGroup(const Group* g) { + qDebug() << __func__ << g; + if (!g) { + return; + } - connect(g, &Friend::displayedNameChanged, this, [&](const QString &name) { setName(name); }); + connect(g, &Friend::displayedNameChanged, this, [&](const QString& name) { setName(name); }); - connect(g, &Friend::avatarChanged, this, [this](const QPixmap &avatar) { setAvatar(avatar); }); + connect(g, &Friend::avatarChanged, this, [this](const QPixmap& avatar) { setAvatar(avatar); }); - setContact(*g); + setContact(*g); - sendWorker->getChatForm()->setContact(g); - sendWorker->getHeader()->setContact(g); + sendWorker->getChatForm()->setContact(g); + sendWorker->getHeader()->setContact(g); } void MessageSessionWidget::removeGroup() { - sendWorker->getChatForm()->removeContact(); - sendWorker->getHeader()->removeContact(); + sendWorker->getChatForm()->removeContact(); + sendWorker->getHeader()->removeContact(); } -void MessageSessionWidget::clearReceipts() -{ - sendWorker->dispacher()->clearOutgoingMessages(); -} +void MessageSessionWidget::clearReceipts() { sendWorker->dispacher()->clearOutgoingMessages(); } -void MessageSessionWidget::doAcceptCall(const ToxPeer &p, bool video) { - qDebug() << __func__ << p.toString(); +void MessageSessionWidget::doAcceptCall(const ToxPeer& p, bool video) { + qDebug() << __func__ << p.toString(); - // 关闭声音 - auto w = Widget::getInstance(); - w->onStopNotification(); + // 关闭声音 + auto w = Widget::getInstance(); + w->onStopNotification(); - // 发送接收应答 - CoreAV *coreav = CoreAV::getInstance(); - coreav->answerCall(p, video); + // 发送接收应答 + CoreAV* coreav = CoreAV::getInstance(); + coreav->answerCall(p, video); } -void MessageSessionWidget::doRejectCall(const ToxPeer &p) { - qDebug() << __func__ << p.toString(); +void MessageSessionWidget::doRejectCall(const ToxPeer& p) { + qDebug() << __func__ << p.toString(); - auto header = sendWorker->getHeader(); - header->removeCallConfirm(); + auto header = sendWorker->getHeader(); + header->removeCallConfirm(); - // 关闭声音 - auto w = Widget::getInstance(); - w->onStopNotification(); + // 关闭声音 + auto w = Widget::getInstance(); + w->onStopNotification(); - // 发送拒绝应答 - CoreAV *coreav = CoreAV::getInstance(); - coreav->rejectCall(p); + // 发送拒绝应答 + CoreAV* coreav = CoreAV::getInstance(); + coreav->rejectCall(p); } void MessageSessionWidget::doCall() { - auto fId = contactId.getId(); - qDebug() << __func__ << fId; - auto av = CoreAV::getInstance(); - if (av->isCallStarted(&contactId)) { - av->cancelCall(fId); - } else if (av->startCall(fId, false)) { - auto w = Widget::getInstance(); - w->outgoingNotification(); - } + auto fId = contactId.getId(); + qDebug() << __func__ << fId; + auto av = CoreAV::getInstance(); + if (av->isCallStarted(&contactId)) { + av->cancelCall(fId); + } else if (av->startCall(fId, false)) { + auto w = Widget::getInstance(); + w->outgoingNotification(); + } } void MessageSessionWidget::doVideoCall() { - QString cId = contactId.getId(); - qDebug() << __func__ << cId; - auto av = CoreAV::getInstance(); - if (av->isCallStarted(&contactId)) { - if (av->isCallVideoEnabled(&contactId)) { - av->cancelCall(cId); + QString cId = contactId.getId(); + qDebug() << __func__ << cId; + auto av = CoreAV::getInstance(); + if (av->isCallStarted(&contactId)) { + if (av->isCallVideoEnabled(&contactId)) { + av->cancelCall(cId); + } + } else if (av->startCall(cId, true)) { + auto w = Widget::getInstance(); + w->outgoingNotification(); } - } else if (av->startCall(cId, true)) { - auto w = Widget::getInstance(); - w->outgoingNotification(); - } } -void MessageSessionWidget::endCall() -{ +void MessageSessionWidget::endCall() { auto fId = contactId.getId(); qDebug() << __func__ << fId; auto av = CoreAV::getInstance(); if (av->isCallStarted(&contactId)) { - av->cancelCall(fId); + av->cancelCall(fId); } } -void MessageSessionWidget::doMuteMicrophone(bool mute) -{ - +void MessageSessionWidget::doMuteMicrophone(bool mute) { auto fId = contactId.getId(); qDebug() << __func__ << fId; auto av = CoreAV::getInstance(); if (av->isCallStarted(&contactId)) { - av->muteCallOutput(&contactId, mute); + av->muteCallOutput(&contactId, mute); } - } -void MessageSessionWidget::doSilenceSpeaker(bool mute) -{ +void MessageSessionWidget::doSilenceSpeaker(bool mute) { auto fId = contactId.getId(); qDebug() << __func__ << fId; auto av = CoreAV::getInstance(); if (av->isCallStarted(&contactId)) { - av->muteCallInput(&contactId, mute); + av->muteCallInput(&contactId, mute); } } @@ -653,40 +653,36 @@ void MessageSessionWidget::setAsActiveChatroom() { setActive(true); } void MessageSessionWidget::setAsInactiveChatroom() { setActive(false); } -void MessageSessionWidget::onActiveSet(bool active) { - setBackgroundRole(QPalette::Window); -} +void MessageSessionWidget::onActiveSet(bool active) { setBackgroundRole(QPalette::Window); } -void MessageSessionWidget::paintEvent(QPaintEvent *e) -{ +void MessageSessionWidget::paintEvent(QPaintEvent* e) { QPainter painter(this); QStyleOptionFrame opt; initStyleOption(&opt); - if (active) - { + if (active) { opt.state |= QStyle::State_Selected; } style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this); } QString MessageSessionWidget::getStatusString() const { - qDebug() << __func__; - // auto contactId = sendWorker->getChatroom()->getContactId(); - // auto frnd = FriendList::findFriend(ToxPk(contact)); + qDebug() << __func__; + // auto contactId = sendWorker->getChatroom()->getContactId(); + // auto frnd = FriendList::findFriend(ToxPk(contact)); - // const int status = static_cast(frnd->getStatus()); - // const bool event = frnd->getEventFlag(); + // const int status = static_cast(frnd->getStatus()); + // const bool event = frnd->getEventFlag(); - // static const QVector names = { - // tr("Online"), - // tr("Away"), - // tr("Busy"), - // tr("Offline"), - // }; + // static const QVector names = { + // tr("Online"), + // tr("Away"), + // tr("Busy"), + // tr("Offline"), + // }; - // return event ? tr("New message") : names.value(status); + // return event ? tr("New message") : names.value(status); - return {}; + return {}; } // IMFriend *MessageSessionWidget::getFriend() const { @@ -699,167 +695,169 @@ QString MessageSessionWidget::getStatusString() const { // const ContactId& MessageSessionWidget::getContactId() const { return contactId; } -void MessageSessionWidget::search(const QString &searchString, bool hide) { - // const auto frnd = chatRoom->getFriend(); - // searchName(searchString, hide); - // const Settings &s = Settings::getInstance(); - // const uint32_t circleId = s.getFriendCircleID(frnd->getPublicKey()); - // CircleWidget *circleWidget = CircleWidget::getFromID(circleId); - // if (circleWidget) { - // circleWidget->search(searchString); - // } +void MessageSessionWidget::search(const QString& searchString, bool hide) { + // const auto frnd = chatRoom->getFriend(); + // searchName(searchString, hide); + // const Settings &s = Settings::getInstance(); + // const uint32_t circleId = s.getFriendCircleID(frnd->getPublicKey()); + // CircleWidget *circleWidget = CircleWidget::getFromID(circleId); + // if (circleWidget) { + // circleWidget->search(searchString); + // } } void MessageSessionWidget::resetEventFlags() { - // getFriend()->setEventFlag(false); + // getFriend()->setEventFlag(false); } -void MessageSessionWidget::onAvatarSet(const FriendId &friendPk, const QPixmap &pic) { - // const auto frnd = getFriend();; - // if (friendPk != frnd->getPublicKey()) { - // return; - // } - qDebug() << __func__ << "onAvatarSet:" << friendPk.toString() << "pic:" << pic.size(); +void MessageSessionWidget::onAvatarSet(const FriendId& friendPk, const QPixmap& pic) { + // const auto frnd = getFriend();; + // if (friendPk != frnd->getPublicKey()) { + // return; + // } + qDebug() << __func__ << "onAvatarSet:" << friendPk.toString() << "pic:" << pic.size(); - if (!pic.isNull()) { - setAvatar(pic); - } - // auto c = getContact(); - // if(c){ - // c->setAvatar(pic); - // } + if (!pic.isNull()) { + setAvatar(pic); + } + // auto c = getContact(); + // if(c){ + // c->setAvatar(pic); + // } } -void MessageSessionWidget::onAvatarRemoved(const FriendId &friendPk) { - qDebug() << __func__ << friendPk.toString(); - // 清空联系人头像 - // auto c = getContact(); - // c->clearAvatar(); +void MessageSessionWidget::onAvatarRemoved(const FriendId& friendPk) { + qDebug() << __func__ << friendPk.toString(); + // 清空联系人头像 + // auto c = getContact(); + // c->clearAvatar(); } -void MessageSessionWidget::mousePressEvent(QMouseEvent *ev) { - if (ev->button() == Qt::LeftButton) { - dragStartPos = ev->pos(); - } +void MessageSessionWidget::mousePressEvent(QMouseEvent* ev) { + if (ev->button() == Qt::LeftButton) { + dragStartPos = ev->pos(); + } - GenericChatroomWidget::mousePressEvent(ev); + GenericChatroomWidget::mousePressEvent(ev); } -void MessageSessionWidget::mouseMoveEvent(QMouseEvent *ev) { - if (!(ev->buttons() & Qt::LeftButton)) { - return; - } - - const int distance = (dragStartPos - ev->pos()).manhattanLength(); - if (distance > QApplication::startDragDistance()) { - QMimeData *mdata = new QMimeData; - // const IMFriend *frnd = getFriend(); - // mdata->setText(frnd->getDisplayedName()); - // mdata->setData("toxPk", frnd->getPublicKey().getByteArray()); +void MessageSessionWidget::mouseMoveEvent(QMouseEvent* ev) { + if (!(ev->buttons() & Qt::LeftButton)) { + return; + } - QDrag *drag = new QDrag(this); - drag->setMimeData(mdata); - drag->setPixmap(avatar->getPixmap()); - drag->exec(Qt::CopyAction | Qt::MoveAction); - } + const int distance = (dragStartPos - ev->pos()).manhattanLength(); + if (distance > QApplication::startDragDistance()) { + QMimeData* mdata = new QMimeData; + // const IMFriend *frnd = getFriend(); + // mdata->setText(frnd->getDisplayedName()); + // mdata->setData("toxPk", frnd->getPublicKey().getByteArray()); + + QDrag* drag = new QDrag(this); + drag->setMimeData(mdata); + drag->setPixmap(avatar->getPixmap()); + drag->exec(Qt::CopyAction | Qt::MoveAction); + } } -void MessageSessionWidget::setRecvMessage(const FriendMessage &msg, bool isAction) { - - FriendMessage m = msg; - m.from = ContactId(m.from).toString(); +void MessageSessionWidget::setRecvMessage(const FriendMessage& msg, bool isAction) { + FriendMessage m = msg; + m.from = ContactId(m.from).toString(); - auto frd = FriendList::findFriend(contactId); - if (frd) { - m.displayName = frd->getDisplayedName(); - } + auto frd = FriendList::findFriend(contactId); + if (frd) { + m.displayName = frd->getDisplayedName(); + } - auto md = (FriendMessageDispatcher *)sendWorker->dispacher(); - md->onMessageReceived(m); + auto md = (FriendMessageDispatcher*)sendWorker->dispacher(); + md->onMessageReceived(m); - updateLastMessage(m); + updateLastMessage(m); - auto vis = contentWidget->isVisible(); - if (!vis) { - // 更新状态信号灯 - auto status = Core::getInstance()->getFriendStatus(contactId.toString()); - updateStatusLight(status, true); - // 聊天界面不显示,消息提示。 - Widget::getInstance()->newGroupMessageAlert(GroupId(contactId), FriendId(msg.from), msg.content, true); - } + auto vis = contentWidget->isVisible(); + if (!vis) { + // 更新状态信号灯 + auto status = Core::getInstance()->getFriendStatus(contactId.toString()); + updateStatusLight(status, true); + // 聊天界面不显示,消息提示。 + Widget::getInstance()->newGroupMessageAlert(GroupId(contactId), FriendId(msg.from), + msg.content, true); + } } -void MessageSessionWidget::setMessageReceipt(const MsgId &msgId) { - auto md = (FriendMessageDispatcher *)sendWorker->dispacher(); - md->onReceiptReceived(msgId); +void MessageSessionWidget::setMessageReceipt(const MsgId& msgId) { + auto md = (FriendMessageDispatcher*)sendWorker->dispacher(); + md->onReceiptReceived(msgId); } -void MessageSessionWidget::setRecvGroupMessage(const GroupMessage &msg) { - GroupMessage m = msg; - m.from = ContactId(m.from).toString(); +void MessageSessionWidget::setRecvGroupMessage(const GroupMessage& msg) { + GroupMessage m = msg; + m.from = ContactId(m.from).toString(); - auto frd = FriendList::findFriend(contactId); - if (frd) { - m.displayName = frd->getDisplayedName(); - }else{ - auto g = GroupList::findGroup(GroupId(msg.from)); - if (g) - m.displayName = g->getPeerDisplayName(ToxPeer(msg.from).getResource()); - } + auto frd = FriendList::findFriend(contactId); + if (frd) { + m.displayName = frd->getDisplayedName(); + } else { + auto g = GroupList::findGroup(GroupId(msg.from)); + if (g) m.displayName = g->getPeerDisplayName(ToxPeer(msg.from).getResource()); + } - auto md = (GroupMessageDispatcher *)sendWorker->dispacher(); - md->onMessageReceived(m); + auto md = (GroupMessageDispatcher*)sendWorker->dispacher(); + md->onMessageReceived(m); - updateLastMessage(m); + updateLastMessage(m); - auto vis = contentWidget->isVisible(); - if (!vis) { - // 更新状态信号灯 - updateStatusLight(Status::Status::Online, true); - // 聊天界面不显示,消息提示。 - Widget::getInstance()->newGroupMessageAlert(GroupId(contactId), FriendId(msg.from), msg.content, true); - } + auto vis = contentWidget->isVisible(); + if (!vis) { + // 更新状态信号灯 + updateStatusLight(Status::Status::Online, true); + // 聊天界面不显示,消息提示。 + Widget::getInstance()->newGroupMessageAlert(GroupId(contactId), FriendId(msg.from), + msg.content, true); + } } -void MessageSessionWidget::setFileReceived(const ToxFile &file) { - qDebug() << __func__ << file.toString(); - auto md = (FriendMessageDispatcher *)sendWorker->dispacher(); - if (md) - md->onFileReceived(file); +void MessageSessionWidget::setFileReceived(const ToxFile& file) { + qDebug() << __func__ << file.toString(); + auto md = (FriendMessageDispatcher*)sendWorker->dispacher(); + if (md) md->onFileReceived(file); } -void MessageSessionWidget::setFileCancelled(const QString &fileId) { - qDebug() << __func__ << fileId; - auto md = (FriendMessageDispatcher *)sendWorker->dispacher(); - if (md) - md->onFileCancelled(fileId); +void MessageSessionWidget::setFileCancelled(const QString& fileId) { + qDebug() << __func__ << fileId; + auto md = (FriendMessageDispatcher*)sendWorker->dispacher(); + if (md) md->onFileCancelled(fileId); } void MessageSessionWidget::clearHistory() { sendWorker->clearHistory(); } void MessageSessionWidget::setStatus(Status::Status status, bool event) { - updateStatusLight(status, event); - auto f = FriendList::findFriend(contactId); - if (!f) { - qWarning() << "friend is no existing."; - return; - } - f->setStatus(status); + updateStatusLight(status, event); + auto f = FriendList::findFriend(contactId); + if (!f) { + qWarning() << "friend is no existing."; + return; + } + f->setStatus(status); } -void MessageSessionWidget::setStatusMsg(const QString &msg) { - // m_friend->setStatusMessage(msg); - GenericChatroomWidget::setStatusMsg(msg); +void MessageSessionWidget::setStatusMsg(const QString& msg) { + // m_friend->setStatusMessage(msg); + GenericChatroomWidget::setStatusMsg(msg); } void MessageSessionWidget::setTyping(bool typing) { - qDebug() << __func__ << typing; - auto chatForm = (ChatForm *)sendWorker->getChatForm(); - if (chatForm) - chatForm->setFriendTyping(typing); + qDebug() << __func__ << typing; + auto chatForm = (ChatForm*)sendWorker->getChatForm(); + if (chatForm) chatForm->setFriendTyping(typing); +} + +void MessageSessionWidget::setName(const QString& name) { + GenericChatroomWidget::setName(name); + sendWorker->getHeader()->setName(name); } -void MessageSessionWidget::setName(const QString &name) { - qDebug() << __func__ << name; - GenericChatroomWidget::setName(name); +void MessageSessionWidget::setAvatar(const QPixmap& avatar) { + GenericChatroomWidget::setAvatar(avatar); + sendWorker->getHeader()->setAvatar(avatar); } diff --git a/src/modules/im/src/widget/MessageSessionWidget.h b/src/modules/im/src/widget/MessageSessionWidget.h index 54951007..174b1c9a 100644 --- a/src/modules/im/src/widget/MessageSessionWidget.h +++ b/src/modules/im/src/widget/MessageSessionWidget.h @@ -36,48 +36,43 @@ class ContentLayout; class Widget; class FriendWidget; -class MessageSessionWidget : public GenericChatroomWidget -{ +class MessageSessionWidget : public GenericChatroomWidget { Q_OBJECT - public: - MessageSessionWidget(ContentLayout* layout, - const ContactId &cid, - ChatType); +public: + MessageSessionWidget(ContentLayout* layout, const ContactId& cid, ChatType); ~MessageSessionWidget(); void contextMenuEvent(QContextMenuEvent* event) override final; void setAsActiveChatroom() override final; void setAsInactiveChatroom() override final; - + void setAvatar(const QPixmap& avatar) override final; void setStatus(Status::Status status, bool event); - void setStatusMsg(const QString& msg) ; + void setStatusMsg(const QString& msg); void setTyping(bool typing); void setName(const QString& name); + void resetEventFlags() override final; QString getStatusString() const override final; - void search(const QString& searchString, bool hide = false); - void setRecvMessage(const FriendMessage &message, - bool isAction); - - void setMessageReceipt(const MsgId &msgId); + void setRecvMessage(const FriendMessage& message, bool isAction); + void setMessageReceipt(const MsgId& msgId); void setRecvGroupMessage(const GroupMessage& msg); void setFileReceived(const ToxFile& file); - void setFileCancelled(const QString &fileId); + void setFileCancelled(const QString& fileId); void clearHistory(); void setFriend(const Friend* f); void removeFriend(); - void setAvInvite(const ToxPeer &peerId, bool video); + void setAvInvite(const ToxPeer& peerId, bool video); void setAvStart(const FriendId& friendId, bool video); void setAvEnd(const FriendId& friendId, bool error); @@ -95,15 +90,15 @@ class MessageSessionWidget : public GenericChatroomWidget void widgetRenamed(MessageSessionWidget* widget); void searchCircle(CircleWidget& circleWidget); void updateFriendActivity(Friend& frnd); -// void setActive(bool active); - void deleteSession(const QString &contactId); + // void setActive(bool active); + void deleteSession(const QString& contactId); public slots: - void onAvatarSet(const FriendId& friendPk, const QPixmap& pic); - void onAvatarRemoved(const FriendId& friendPk); - void onContextMenuCalled(QContextMenuEvent* event); - void do_widgetClicked( ); - void showEvent(QShowEvent *) override; + void onAvatarSet(const FriendId& friendPk, const QPixmap& pic); + void onAvatarRemoved(const FriendId& friendPk); + void onContextMenuCalled(QContextMenuEvent* event); + void do_widgetClicked(); + void showEvent(QShowEvent*) override; private slots: void removeChat(); @@ -112,7 +107,7 @@ private slots: void moveToCircle(int circleId); void changeAutoAccept(bool enable); void showDetails(); - void onMessageSent(DispatchedMessageId id, const Message & message); + void onMessageSent(DispatchedMessageId id, const Message& message); void doAcceptCall(const ToxPeer& p, bool video); void doRejectCall(const ToxPeer& p); void doCall(); @@ -126,20 +121,18 @@ private slots: virtual void mouseMoveEvent(QMouseEvent* ev) override; void setFriendAlias(); void onActiveSet(bool active) override; - void paintEvent(QPaintEvent *e) override; + void paintEvent(QPaintEvent* e) override; private: - ContentLayout* contentLayout; std::unique_ptr contentWidget; std::unique_ptr sendWorker; - //联系人ID(朋友ID、群聊ID共享) + // 联系人ID(朋友ID、群聊ID共享) ContactId contactId; FriendId friendId; GroupId groupId; - }; -#endif // FRIENDWIDGET_H +#endif // FRIENDWIDGET_H diff --git a/src/modules/im/src/widget/categorywidget.cpp b/src/modules/im/src/widget/categorywidget.cpp index b5b2a983..5d1adb19 100644 --- a/src/modules/im/src/widget/categorywidget.cpp +++ b/src/modules/im/src/widget/categorywidget.cpp @@ -11,19 +11,18 @@ */ #include "categorywidget.h" +#include +#include #include "friendlistlayout.h" #include "friendlistwidget.h" #include "friendwidget.h" #include "src/lib/settings/style.h" #include "src/model/status.h" #include "tool/croppinglabel.h" -#include -#include #include -void CategoryWidget::emitChatroomWidget(QLayout* layout, int index) -{ +void CategoryWidget::emitChatroomWidget(QLayout* layout, int index) { QWidget* widget = layout->itemAt(index)->widget(); GenericChatroomWidget* chatWidget = qobject_cast(widget); if (chatWidget != nullptr) { @@ -32,8 +31,7 @@ void CategoryWidget::emitChatroomWidget(QLayout* layout, int index) } CategoryWidget::CategoryWidget(bool compact, QWidget* parent) - : GenericChatItemWidget(compact, parent) -{ + : GenericChatItemWidget(compact, parent) { container = new QWidget(this); container->setObjectName("circleWidgetContainer"); container->setLayoutDirection(Qt::LeftToRight); @@ -68,13 +66,9 @@ CategoryWidget::CategoryWidget(bool compact, QWidget* parent) updateStatus(); } -bool CategoryWidget::isExpanded() const -{ - return expanded; -} +bool CategoryWidget::isExpanded() const { return expanded; } -void CategoryWidget::setExpanded(bool isExpanded, bool save) -{ +void CategoryWidget::setExpanded(bool isExpanded, bool save) { if (expanded == isExpanded) { return; } @@ -94,62 +88,47 @@ void CategoryWidget::setExpanded(bool isExpanded, bool save) container->hide(); container->show(); - if (save) - onExpand(); + if (save) onExpand(); } -void CategoryWidget::leaveEvent(QEvent* event) -{ - event->ignore(); -} +void CategoryWidget::leaveEvent(QEvent* event) { event->ignore(); } -void CategoryWidget::setName(const QString& name, bool save) -{ +void CategoryWidget::setName(const QString& name, bool save) { nameLabel->setText(name); - if (isCompact()) - nameLabel->minimizeMaximumWidth(); + if (isCompact()) nameLabel->minimizeMaximumWidth(); - if (save) - onSetName(); + if (save) onSetName(); } -void CategoryWidget::editName() -{ +void CategoryWidget::editName() { nameLabel->editBegin(); nameLabel->setMaximumWidth(QWIDGETSIZE_MAX); } -void CategoryWidget::addFriendWidget(FriendWidget* w, Status::Status s) -{ +void CategoryWidget::addFriendWidget(FriendWidget* w, Status::Status s) { listLayout->addFriendWidget(w, s); updateStatus(); onAddFriendWidget(w); - w->reloadTheme(); // Otherwise theme will change when moving to another circle. + w->reloadTheme(); // Otherwise theme will change when moving to another circle. } -void CategoryWidget::removeFriendWidget(FriendWidget* w, Status::Status s) -{ +void CategoryWidget::removeFriendWidget(FriendWidget* w, Status::Status s) { listLayout->removeFriendWidget(w, s); updateStatus(); } -void CategoryWidget::updateStatus() -{ +void CategoryWidget::updateStatus() { QString online = QString::number(listLayout->friendOnlineCount()); QString offline = QString::number(listLayout->friendTotalCount()); QString text = online + QStringLiteral(" / ") + offline; statusLabel->setText(text); } -bool CategoryWidget::hasChatrooms() const -{ - return listLayout->hasChatrooms(); -} +bool CategoryWidget::hasChatrooms() const { return listLayout->hasChatrooms(); } void CategoryWidget::search(const QString& searchString, bool updateAll, bool hideOnline, - bool hideOffline) -{ + bool hideOffline) { if (updateAll) { listLayout->searchChatrooms(searchString, hideOnline, hideOffline); } @@ -157,8 +136,7 @@ void CategoryWidget::search(const QString& searchString, bool updateAll, bool hi setVisible(inCategory || listLayout->hasChatrooms()); } -bool CategoryWidget::cycleContacts(bool forward) -{ +bool CategoryWidget::cycleContacts(bool forward) { if (listLayout->friendTotalCount() == 0) { return false; } @@ -188,14 +166,12 @@ bool CategoryWidget::cycleContacts(bool forward) return false; } -bool CategoryWidget::cycleContacts(FriendWidget* activeChatroomWidget, bool forward) -{ +bool CategoryWidget::cycleContacts(FriendWidget* activeChatroomWidget, bool forward) { int index = -1; QLayout* currentLayout = nullptr; FriendWidget* friendWidget = qobject_cast(activeChatroomWidget); - if (friendWidget == nullptr) - return false; + if (friendWidget == nullptr) return false; currentLayout = listLayout->getLayoutOnline(); index = listLayout->indexOfFriendWidget(friendWidget, true); @@ -226,17 +202,15 @@ bool CategoryWidget::cycleContacts(FriendWidget* activeChatroomWidget, bool forw } GenericChatroomWidget* chatWidget = - qobject_cast(currentLayout->itemAt(index)->widget()); - if (chatWidget != nullptr) - emit chatWidget->chatroomWidgetClicked(chatWidget); + qobject_cast(currentLayout->itemAt(index)->widget()); + if (chatWidget != nullptr) emit chatWidget->chatroomWidgetClicked(chatWidget); return true; } return false; } -void CategoryWidget::onCompactChanged(bool _compact) -{ +void CategoryWidget::onCompactChanged(bool _compact) { delete topLayout; delete mainLayout; @@ -267,29 +241,19 @@ void CategoryWidget::onCompactChanged(bool _compact) Style::repolish(this); } -void CategoryWidget::mouseReleaseEvent(QMouseEvent* event) -{ - if (event->button() == Qt::LeftButton) - setExpanded(!expanded); +void CategoryWidget::mouseReleaseEvent(QMouseEvent* event) { + if (event->button() == Qt::LeftButton) setExpanded(!expanded); } -void CategoryWidget::setContainerAttribute(Qt::WidgetAttribute attribute, bool enabled) -{ +void CategoryWidget::setContainerAttribute(Qt::WidgetAttribute attribute, bool enabled) { container->setAttribute(attribute, enabled); Style::repolish(container); } -QLayout* CategoryWidget::friendOfflineLayout() const -{ - return listLayout->getLayoutOffline(); -} +QLayout* CategoryWidget::friendOfflineLayout() const { return listLayout->getLayoutOffline(); } -QLayout* CategoryWidget::friendOnlineLayout() const -{ - return listLayout->getLayoutOnline(); -} +QLayout* CategoryWidget::friendOnlineLayout() const { return listLayout->getLayoutOnline(); } -void CategoryWidget::moveFriendWidgets(FriendListWidget* friendList) -{ +void CategoryWidget::moveFriendWidgets(FriendListWidget* friendList) { listLayout->moveFriendWidgets(friendList); } diff --git a/src/modules/im/src/widget/categorywidget.h b/src/modules/im/src/widget/categorywidget.h index 34d9131a..f69be80a 100644 --- a/src/modules/im/src/widget/categorywidget.h +++ b/src/modules/im/src/widget/categorywidget.h @@ -23,8 +23,7 @@ class FriendWidget; class QVBoxLayout; class QHBoxLayout; -class CategoryWidget : public GenericChatItemWidget -{ +class CategoryWidget : public GenericChatItemWidget { Q_OBJECT public: explicit CategoryWidget(bool compact, QWidget* parent = nullptr); @@ -58,15 +57,9 @@ public slots: void emitChatroomWidget(QLayout* layout, int index); private: - virtual void onSetName() - { - } - virtual void onExpand() - { - } - virtual void onAddFriendWidget(FriendWidget*) - { - } + virtual void onSetName() {} + virtual void onExpand() {} + virtual void onAddFriendWidget(FriendWidget*) {} QWidget* listWidget; FriendListLayout* listLayout; @@ -79,4 +72,4 @@ public slots: bool expanded = false; }; -#endif // CATEGORYWIDGET_H +#endif // CATEGORYWIDGET_H diff --git a/src/modules/im/src/widget/chatformheader.cpp b/src/modules/im/src/widget/chatformheader.cpp index 6d7338bd..193da45a 100644 --- a/src/modules/im/src/widget/chatformheader.cpp +++ b/src/modules/im/src/widget/chatformheader.cpp @@ -31,10 +31,10 @@ #include #include -#include #include -#include "src/persistence/profile.h" +#include #include "src/nexus.h" +#include "src/persistence/profile.h" static const QSize AVATAR_SIZE{40, 40}; static const short HEAD_LAYOUT_SPACING = 5; @@ -45,44 +45,39 @@ namespace { const QString STYLE_PATH = QStringLiteral("chatForm/buttons.css"); const QString STATE_NAME[] = { - QString{}, - QStringLiteral("green"), - QStringLiteral("red"), - QStringLiteral("yellow"), - QStringLiteral("yellow"), + QString{}, + QStringLiteral("green"), + QStringLiteral("red"), + QStringLiteral("yellow"), + QStringLiteral("yellow"), }; const QString CALL_TOOL_TIP[] = { - ChatFormHeader::tr("Can't start audio call"), - ChatFormHeader::tr("Start audio call"), - ChatFormHeader::tr("End audio call"), - ChatFormHeader::tr("Cancel audio call"), - ChatFormHeader::tr("Accept audio call"), + ChatFormHeader::tr("Can't start audio call"), ChatFormHeader::tr("Start audio call"), + ChatFormHeader::tr("End audio call"), ChatFormHeader::tr("Cancel audio call"), + ChatFormHeader::tr("Accept audio call"), }; const QString VIDEO_TOOL_TIP[] = { - ChatFormHeader::tr("Can't start video call"), - ChatFormHeader::tr("Start video call"), - ChatFormHeader::tr("End video call"), - ChatFormHeader::tr("Cancel video call"), - ChatFormHeader::tr("Accept video call"), + ChatFormHeader::tr("Can't start video call"), ChatFormHeader::tr("Start video call"), + ChatFormHeader::tr("End video call"), ChatFormHeader::tr("Cancel video call"), + ChatFormHeader::tr("Accept video call"), }; const QString VOL_TOOL_TIP[] = { - ChatFormHeader::tr("Sound can be disabled only during a call"), - ChatFormHeader::tr("Mute call"), - ChatFormHeader::tr("Unmute call"), + ChatFormHeader::tr("Sound can be disabled only during a call"), + ChatFormHeader::tr("Mute call"), + ChatFormHeader::tr("Unmute call"), }; const QString MIC_TOOL_TIP[] = { - ChatFormHeader::tr("Microphone can be muted only during a call"), - ChatFormHeader::tr("Mute microphone"), - ChatFormHeader::tr("Unmute microphone"), + ChatFormHeader::tr("Microphone can be muted only during a call"), + ChatFormHeader::tr("Mute microphone"), + ChatFormHeader::tr("Unmute microphone"), }; template -QPushButton* createButton(const QString& name, T* self, Fun onClickSlot) -{ +QPushButton* createButton(const QString& name, T* self, Fun onClickSlot) { QPushButton* btn = new QPushButton(); btn->setAttribute(Qt::WA_LayoutUsesWidgetRect); btn->setObjectName(name); @@ -91,37 +86,33 @@ QPushButton* createButton(const QString& name, T* self, Fun onClickSlot) return btn; } -template -void setStateToolTip(QAbstractButton* btn, State state, const QString toolTip[]) -{ +template +void setStateToolTip(QAbstractButton* btn, State state, const QString toolTip[]) { const int index = static_cast(state); btn->setToolTip(toolTip[index]); } -template -void setStateName(QAbstractButton* btn, State state) -{ +template void setStateName(QAbstractButton* btn, State state) { const int index = static_cast(state); btn->setProperty("state", STATE_NAME[index]); btn->setEnabled(index != 0); } -} +} // namespace -ChatFormHeader::ChatFormHeader(const ContactId &contactId, QWidget* parent) - : QWidget(parent) - , contactId(contactId) - , mode{Mode::AV} - , callState{CallButtonState::Disabled} - , videoState{CallButtonState::Disabled} -{ +ChatFormHeader::ChatFormHeader(const ContactId& contactId, QWidget* parent) + : QWidget(parent) + , contactId(contactId) + , mode{Mode::AV} + , callState{CallButtonState::Disabled} + , videoState{CallButtonState::Disabled} { QHBoxLayout* headLayout = new QHBoxLayout(this); headLayout->setContentsMargins(0, 0, 0, 0); - //头像 + // 头像 avatar = new MaskablePixmapWidget(this, AVATAR_SIZE, ":/img/avatar_mask.svg"); avatar->setObjectName("avatar"); headLayout->addWidget(avatar); - //名称 + // 名称 nameLabel = new CroppingLabel(this); nameLabel->setObjectName("nameLabel"); nameLabel->setMinimumHeight(Style::getFont(Style::Medium).pixelSize()); @@ -135,7 +126,7 @@ ChatFormHeader::ChatFormHeader(const ContactId &contactId, QWidget* parent) statusIcon = new QToolButton(this); statusIcon->setIconSize(QSize(10, 10)); statusIcon->setStyleSheet("border:0px solid; padding:0px"); - QHBoxLayout *status_lyt = new QHBoxLayout(); + QHBoxLayout* status_lyt = new QHBoxLayout(); status_lyt->addWidget(statusIcon); status_lyt->addWidget(statusLabel); status_lyt->addStretch(1); @@ -146,13 +137,13 @@ ChatFormHeader::ChatFormHeader(const ContactId &contactId, QWidget* parent) headTextLayout->addStretch(); headLayout->addLayout(headTextLayout, 1); - //空间 + // 空间 headLayout->addSpacing(HEAD_LAYOUT_SPACING); - //控制按钮 + // 控制按钮 callButton = createButton("callButton", this, &ChatFormHeader::callTriggered); videoButton = createButton("videoButton", this, &ChatFormHeader::videoCallTriggered); - QHBoxLayout *buttonsLayout = new QHBoxLayout(this); + QHBoxLayout* buttonsLayout = new QHBoxLayout(this); buttonsLayout->addWidget(callButton); buttonsLayout->addWidget(videoButton); buttonsLayout->setSpacing(BUTTONS_LAYOUT_HOR_SPACING); @@ -170,9 +161,7 @@ ChatFormHeader::ChatFormHeader(const ContactId &contactId, QWidget* parent) isSelf = self.toString() == contactId.toString(); if (!isSelf) { setContact(FriendList::findFriend(contactId)); - } - else - { + } else { // todo: 接口不统一 setName(Core::getInstance()->getNick()); setAvatar(Nexus::getProfile()->loadAvatar(contactId)); @@ -184,43 +173,37 @@ ChatFormHeader::ChatFormHeader(const ContactId &contactId, QWidget* parent) retranslateUi(); } -ChatFormHeader::~ChatFormHeader() { - settings::Translator::unregister(this); -} +ChatFormHeader::~ChatFormHeader() { settings::Translator::unregister(this); } -void ChatFormHeader::setContact(const Contact *contact_) -{ - if (!contact_ || contactId != contact_->getPersistentId()) - { - if (Friend* old = FriendList::findFriend(contactId)) - { +void ChatFormHeader::setContact(const Contact* contact_) { + if (!contact_ || contactId != contact_->getPersistentId()) { + if (Friend* old = FriendList::findFriend(contactId)) { old->disconnect(this); // 是否有必要? if (!old->isGroup()) { - auto f = static_cast(old); + auto f = static_cast(old); f->disconnect(this); } } // 如果是自己,则通过profile连接更新 - if (contactId.getId() == Core::getInstance()->getSelfId().getId()) - { + if (contactId.getId() == Core::getInstance()->getSelfId().getId()) { Nexus::getProfile()->disconnect(this); Core::getInstance()->disconnect(this); } contactId = ContactId(); } - if (!contact_ || contactId == contact_->getPersistentId()) - return; + if (!contact_ || contactId == contact_->getPersistentId()) return; contactId = contact_->getPersistentId(); - connect(contact_, &Contact::displayedNameChanged, this, &ChatFormHeader::onDisplayedNameChanged); + connect(contact_, &Contact::displayedNameChanged, this, + &ChatFormHeader::onDisplayedNameChanged); connect(contact_, &Contact::avatarChanged, this, &ChatFormHeader::setAvatar); setName(contact_->getDisplayedName()); setAvatar(contact_->getAvatar()); if (!contact_->isGroup()) { - auto f = static_cast(contact_); + auto f = static_cast(contact_); updateCallButtons(f->getStatus()); updateContactStatus(f->getStatus()); @@ -231,34 +214,26 @@ void ChatFormHeader::setContact(const Contact *contact_) statusLabel->setVisible(true); statusIcon->setVisible(true); - } - else - { + } else { statusLabel->setVisible(false); statusIcon->setVisible(false); } } -void ChatFormHeader::removeContact() -{ - qDebug()<<__func__; +void ChatFormHeader::removeContact() { + qDebug() << __func__; contactId = ContactId(); } -const Contact *ChatFormHeader::getContact() const -{ - return FriendList::findFriend(contactId); -} +const Contact* ChatFormHeader::getContact() const { return FriendList::findFriend(contactId); } -void ChatFormHeader::setName(const QString& newName) -{ +void ChatFormHeader::setName(const QString& newName) { nameLabel->setText(newName); // for overlength names nameLabel->setToolTip(Qt::convertFromPlainText(newName, Qt::WhiteSpaceNormal)); } -void ChatFormHeader::setMode(ChatFormHeader::Mode mode) -{ +void ChatFormHeader::setMode(ChatFormHeader::Mode mode) { this->mode = mode; if (mode == Mode::None) { callButton->hide(); @@ -266,32 +241,30 @@ void ChatFormHeader::setMode(ChatFormHeader::Mode mode) } } -void ChatFormHeader::retranslateUi() -{ +void ChatFormHeader::retranslateUi() { setStateToolTip(callButton, callState, CALL_TOOL_TIP); setStateToolTip(videoButton, videoState, VIDEO_TOOL_TIP); } -void ChatFormHeader::updateButtonsView() -{ +void ChatFormHeader::updateButtonsView() { callButton->setEnabled(callState != CallButtonState::Disabled); videoButton->setEnabled(videoState != CallButtonState::Disabled); Style::repolish(this); } -void ChatFormHeader::onDisplayedNameChanged(const QString &name) -{ - setName(name); -} +void ChatFormHeader::onDisplayedNameChanged(const QString& name) { setName(name); } -void ChatFormHeader::nameChanged(const QString &name){ - if (auto f = FriendList::findFriend(contactId)){ +void ChatFormHeader::nameChanged(const QString& name) { + if (Core::getInstance()->getSelfId().getId() == contactId.getId()) { + auto profile = Nexus::getProfile(); + profile->setNick(name, true); + return; + } + + if (auto f = FriendList::findFriend(contactId)) { f->setAlias(name); Core::getInstance()->setFriendAlias(contactId.getId(), name); } - else if (Core::getInstance()->getSelfId().getId() == contactId.getId()){ - Core::getInstance()->setUsername(name); - } } void ChatFormHeader::updateContactStatus(Status::Status status) { @@ -300,44 +273,38 @@ void ChatFormHeader::updateContactStatus(Status::Status status) { statusLabel->setText(Status::getTitle(status)); } -void ChatFormHeader::showOutgoingCall(bool video) -{ +void ChatFormHeader::showOutgoingCall(bool video) { CallButtonState& state = video ? videoState : callState; state = CallButtonState::Outgoing; updateButtonsView(); } -void ChatFormHeader::createCallConfirm(const ToxPeer &peer, bool video, QString &displayedName) -{ +void ChatFormHeader::createCallConfirm(const ToxPeer& peer, bool video, QString& displayedName) { qDebug() << __func__ << "peer:" << peer << "video?" << video; QWidget* btn = video ? videoButton : callButton; callConfirm = std::make_unique(btn); -// callConfirm->move(btn->pos()); + // callConfirm->move(btn->pos()); - connect(callConfirm.get(), &CallConfirmWidget::accepted, this, [=](){ + connect(callConfirm.get(), &CallConfirmWidget::accepted, this, [=]() { removeCallConfirm(); emit callAccepted(peer, video); }); - connect(callConfirm.get(), &CallConfirmWidget::rejected, this, [=](){ + connect(callConfirm.get(), &CallConfirmWidget::rejected, this, [=]() { removeCallConfirm(); emit callRejected(peer); }); } -void ChatFormHeader::showCallConfirm() -{ - callConfirm->show(); -// callConfirm->setVisible(true); +void ChatFormHeader::showCallConfirm() { + callConfirm->show(); + // callConfirm->setVisible(true); } -void ChatFormHeader::removeCallConfirm() -{ - callConfirm.reset(nullptr); -} +void ChatFormHeader::removeCallConfirm() { callConfirm.reset(nullptr); } void ChatFormHeader::updateMuteVolButton() { - const CoreAV *av = CoreAV::getInstance(); + const CoreAV* av = CoreAV::getInstance(); bool active = av->isCallActive(&contactId); bool outputMuted = av->isCallOutputMuted(&contactId); updateMuteVolButton(active, outputMuted); @@ -346,9 +313,8 @@ void ChatFormHeader::updateMuteVolButton() { // } } - void ChatFormHeader::updateMuteMicButton() { - const CoreAV *av = CoreAV::getInstance(); + const CoreAV* av = CoreAV::getInstance(); bool active = av->isCallActive(&contactId); bool inputMuted = av->isCallInputMuted(&contactId); updateMuteMicButton(active, inputMuted); @@ -357,8 +323,7 @@ void ChatFormHeader::updateMuteMicButton() { // } } -void ChatFormHeader::updateCallButtons(bool online, bool audio, bool video) -{ +void ChatFormHeader::updateCallButtons(bool online, bool audio, bool video) { const bool audioAvaliable = online && (mode & Mode::Audio); const bool videoAvaliable = online && (mode & Mode::Video); if (!audioAvaliable) { @@ -384,26 +349,18 @@ void ChatFormHeader::updateCallButtons(bool online, bool audio, bool video) updateButtonsView(); } -void ChatFormHeader::updateMuteMicButton(bool active, bool inputMuted) -{ - updateButtonsView(); -} +void ChatFormHeader::updateMuteMicButton(bool active, bool inputMuted) { updateButtonsView(); } -void ChatFormHeader::updateMuteVolButton(bool active, bool outputMuted) -{ - updateButtonsView(); -} +void ChatFormHeader::updateMuteVolButton(bool active, bool outputMuted) { updateButtonsView(); } -void ChatFormHeader::updateCallButtons() -{ +void ChatFormHeader::updateCallButtons() { updateMuteMicButton(); updateMuteVolButton(); } -void ChatFormHeader::updateCallButtons(Status::Status status) -{ -// qDebug() << __func__ << (int)status; - CoreAV *av = CoreAV::getInstance(); +void ChatFormHeader::updateCallButtons(Status::Status status) { + // qDebug() << __func__ << (int)status; + CoreAV* av = CoreAV::getInstance(); const bool audio = av->isCallActive(&contactId); const bool video = av->isCallVideoEnabled(&contactId); const bool online = Status::isOnline(status); @@ -412,50 +369,33 @@ void ChatFormHeader::updateCallButtons(Status::Status status) updateCallButtons(); } -void ChatFormHeader::setAvatar(const QPixmap &img) -{ - avatar->setPixmap(img); -} +void ChatFormHeader::setAvatar(const QPixmap& img) { avatar->setPixmap(img); } -QSize ChatFormHeader::getAvatarSize() const -{ - return QSize{avatar->width(), avatar->height()}; -} +QSize ChatFormHeader::getAvatarSize() const { return QSize{avatar->width(), avatar->height()}; } -void ChatFormHeader::reloadTheme() -{ +void ChatFormHeader::reloadTheme() { callButton->setStyleSheet(Style::getStylesheet(STYLE_PATH)); videoButton->setStyleSheet(Style::getStylesheet(STYLE_PATH)); - } -void ChatFormHeader::addWidget(QWidget* widget, int stretch, Qt::Alignment alignment) -{ +void ChatFormHeader::addWidget(QWidget* widget, int stretch, Qt::Alignment alignment) { headTextLayout->addWidget(widget, stretch, alignment); } -void ChatFormHeader::addLayout(QLayout* layout) -{ - headTextLayout->addLayout(layout); -} - -void ChatFormHeader::addStretch() -{ - headTextLayout->addStretch(); -} +void ChatFormHeader::addLayout(QLayout* layout) { headTextLayout->addLayout(layout); } +void ChatFormHeader::addStretch() { headTextLayout->addStretch(); } - -//void ChatFormHeader::updateCallButtons() +// void ChatFormHeader::updateCallButtons() //{ -// qDebug() << __func__; -// updateMuteMicButton(); -// updateMuteVolButton(); -//} +// qDebug() << __func__; +// updateMuteMicButton(); +// updateMuteVolButton(); +// } -//void ChatFormHeader::updateCallButtons(Status::Status status) +// void ChatFormHeader::updateCallButtons(Status::Status status) //{ -// qDebug() << __func__ << (int)status; +// qDebug() << __func__ << (int)status; // CoreAV *av = CoreAV::getInstance(); // const bool audio = av->isCallActive(contactId); @@ -466,23 +406,22 @@ void ChatFormHeader::addStretch() // updateCallButtons(); //} - -//void ChatFormHeader::updateMuteMicButton() { -// const CoreAV *av = CoreAV::getInstance(); -// bool active = av->isCallActive(contactId); -// bool inputMuted = av->isCallInputMuted(contactId); -// headWidget->updateMuteMicButton(active, inputMuted); -// if (netcam) { -// netcam->updateMuteMicButton(inputMuted); -// } -//} - -//void ChatFormHeader::updateMuteVolButton() { -// const CoreAV *av = CoreAV::getInstance(); -// bool active = av->isCallActive(contactId); -// bool outputMuted = av->isCallOutputMuted(contactId); -// headWidget->updateMuteVolButton(active, outputMuted); -// if (netcam) { -// netcam->updateMuteVolButton(outputMuted); -// } -//} +// void ChatFormHeader::updateMuteMicButton() { +// const CoreAV *av = CoreAV::getInstance(); +// bool active = av->isCallActive(contactId); +// bool inputMuted = av->isCallInputMuted(contactId); +// headWidget->updateMuteMicButton(active, inputMuted); +// if (netcam) { +// netcam->updateMuteMicButton(inputMuted); +// } +// } + +// void ChatFormHeader::updateMuteVolButton() { +// const CoreAV *av = CoreAV::getInstance(); +// bool active = av->isCallActive(contactId); +// bool outputMuted = av->isCallOutputMuted(contactId); +// headWidget->updateMuteVolButton(active, outputMuted); +// if (netcam) { +// netcam->updateMuteVolButton(outputMuted); +// } +// } diff --git a/src/modules/im/src/widget/chatformheader.h b/src/modules/im/src/widget/chatformheader.h index a8845aa0..5a655e69 100644 --- a/src/modules/im/src/widget/chatformheader.h +++ b/src/modules/im/src/widget/chatformheader.h @@ -31,47 +31,39 @@ class ToxPeer; class Contact; class QLabel; - -class ChatFormHeader : public QWidget -{ +class ChatFormHeader : public QWidget { Q_OBJECT public: enum class CallButtonState { - Disabled = 0, // Grey - Avaliable = 1, // Green - InCall = 2, // Red - Outgoing = 3, // Yellow - Incoming = 4, // Yellow + Disabled = 0, // Grey + Avaliable = 1, // Green + InCall = 2, // Red + Outgoing = 3, // Yellow + Incoming = 4, // Yellow }; enum class ToolButtonState { - Disabled = 0, // Grey - Off = 1, // Green - On = 2, // Red - }; - enum Mode { - None = 0, - Audio = 1, - Video = 2, - AV = Audio | Video + Disabled = 0, // Grey + Off = 1, // Green + On = 2, // Red }; + enum Mode { None = 0, Audio = 1, Video = 2, AV = Audio | Video }; - ChatFormHeader(const ContactId &contactId, QWidget* parent = nullptr); + ChatFormHeader(const ContactId& contactId, QWidget* parent = nullptr); ~ChatFormHeader(); void setContact(const Contact* contact); void removeContact(); - const Contact *getContact() const; + const Contact* getContact() const; void setName(const QString& newName); void setMode(Mode mode); void showOutgoingCall(bool video); - void createCallConfirm(const ToxPeer& peer, bool video, QString &displayedName); + void createCallConfirm(const ToxPeer& peer, bool video, QString& displayedName); void showCallConfirm(); void removeCallConfirm(); - void updateMuteMicButton(bool active, bool inputMuted); void updateMuteVolButton(bool active, bool outputMuted); @@ -82,8 +74,7 @@ class ChatFormHeader : public QWidget void updateMuteMicButton(); void updateMuteVolButton(); - void showCallConfirm(const ToxPeer &peerId, bool video, const QString &displayedName); - + void showCallConfirm(const ToxPeer& peerId, bool video, const QString& displayedName); void setAvatar(const QPixmap& img); QSize getAvatarSize() const; @@ -101,7 +92,6 @@ class ChatFormHeader : public QWidget void micMuteToggle(); void volMuteToggle(); - void callAccepted(const ToxPeer& peerId, bool video); void callRejected(const ToxPeer& peerId); @@ -111,7 +101,7 @@ private slots: void onDisplayedNameChanged(const QString& name); private: - void nameChanged(const QString &name); + void nameChanged(const QString& name); void updateContactStatus(Status::Status status); private: @@ -122,8 +112,8 @@ private slots: MaskablePixmapWidget* avatar; QVBoxLayout* headTextLayout; CroppingLabel* nameLabel; - QLabel *statusLabel = nullptr; - QToolButton *statusIcon = nullptr; + QLabel* statusLabel = nullptr; + QToolButton* statusIcon = nullptr; QPushButton* callButton; QPushButton* videoButton; @@ -132,6 +122,6 @@ private slots: CallButtonState videoState; std::unique_ptr callConfirm; -}; +}; -#endif // CHAT_FORM_HEADER +#endif // CHAT_FORM_HEADER diff --git a/src/modules/im/src/widget/circlewidget.cpp b/src/modules/im/src/widget/circlewidget.cpp index 2cb3f485..bfd4f270 100644 --- a/src/modules/im/src/widget/circlewidget.cpp +++ b/src/modules/im/src/widget/circlewidget.cpp @@ -23,8 +23,8 @@ #include "contentdialog.h" #include "friendlistwidget.h" #include "friendwidget.h" -#include "widget.h" #include "tool/croppinglabel.h" +#include "widget.h" #include "src/friendlist.h" #include "src/model/friend.h" @@ -33,50 +33,37 @@ QHash CircleWidget::circleList; -CircleWidget::CircleWidget(FriendListWidget* parent, int id) - : CategoryWidget(parent) - , id(id) -{ +CircleWidget::CircleWidget(FriendListWidget* parent, int id) : CategoryWidget(parent), id(id) { setName(Settings::getInstance().getCircleName(id), false); circleList[id] = this; connect(nameLabel, &CroppingLabel::editFinished, [this](const QString& newName) { - if (!newName.isEmpty()) - emit renameRequested(this, newName); + if (!newName.isEmpty()) emit renameRequested(this, newName); }); connect(nameLabel, &CroppingLabel::editRemoved, [this]() { - if (isCompact()) - nameLabel->minimizeMaximumWidth(); + if (isCompact()) nameLabel->minimizeMaximumWidth(); }); setExpanded(Settings::getInstance().getCircleExpanded(id), false); updateStatus(); } -CircleWidget::~CircleWidget() -{ - if (circleList[id] == this) - circleList.remove(id); +CircleWidget::~CircleWidget() { + if (circleList[id] == this) circleList.remove(id); } -void CircleWidget::editName() -{ - CategoryWidget::editName(); -} +void CircleWidget::editName() { CategoryWidget::editName(); } -CircleWidget* CircleWidget::getFromID(int id) -{ +CircleWidget* CircleWidget::getFromID(int id) { auto circleIt = circleList.find(id); - if (circleIt != circleList.end()) - return circleIt.value(); + if (circleIt != circleList.end()) return circleIt.value(); return nullptr; } -void CircleWidget::contextMenuEvent(QContextMenuEvent* event) -{ +void CircleWidget::contextMenuEvent(QContextMenuEvent* event) { QMenu menu; QAction* renameAction = menu.addAction(tr("Rename circle", "Menu for renaming a circle")); QAction* removeAction = menu.addAction(tr("Remove circle", "Menu for removing a circle")); @@ -102,7 +89,7 @@ void CircleWidget::contextMenuEvent(QContextMenuEvent* event) if (circleReplace != circleList.end()) circleReplace.value()->updateID(id); else - assert(true); // This should never happen. + assert(true); // This should never happen. circleList.remove(replacedCircle); } else if (selectedItem == openAction) { @@ -133,33 +120,28 @@ void CircleWidget::contextMenuEvent(QContextMenuEvent* event) setContainerAttribute(Qt::WA_UnderMouse, false); } -void CircleWidget::dragEnterEvent(QDragEnterEvent* event) -{ +void CircleWidget::dragEnterEvent(QDragEnterEvent* event) { if (!event->mimeData()->hasFormat("toxPk")) { return; } ToxPk toxPk(event->mimeData()->data("toxPk")); Friend* f = FriendList::findFriend(toxPk); - if (f != nullptr) - event->acceptProposedAction(); + if (f != nullptr) event->acceptProposedAction(); - setContainerAttribute(Qt::WA_UnderMouse, true); // Simulate hover. + setContainerAttribute(Qt::WA_UnderMouse, true); // Simulate hover. } -void CircleWidget::dragLeaveEvent(QDragLeaveEvent*) -{ +void CircleWidget::dragLeaveEvent(QDragLeaveEvent*) { setContainerAttribute(Qt::WA_UnderMouse, false); } -void CircleWidget::dropEvent(QDropEvent* event) -{ +void CircleWidget::dropEvent(QDropEvent* event) { setExpanded(true, false); // Check, that the element is dropped from qTox QObject* o = event->source(); FriendWidget* widget = qobject_cast(o); - if (!widget) - return; + if (!widget) return; if (!event->mimeData()->hasFormat("toxPk")) { return; @@ -167,8 +149,7 @@ void CircleWidget::dropEvent(QDropEvent* event) // Check, that the user has a friend with the same ToxId ToxPk toxPk{event->mimeData()->data("toxPk")}; Friend* f = FriendList::findFriend(toxPk); - if (!f) - return; + if (!f) return; // Save CircleWidget before changing the Id int circleId = Settings::getInstance().getFriendCircleID(toxPk); @@ -185,26 +166,20 @@ void CircleWidget::dropEvent(QDropEvent* event) setContainerAttribute(Qt::WA_UnderMouse, false); } -void CircleWidget::onSetName() -{ - Settings::getInstance().setCircleName(id, getName()); -} +void CircleWidget::onSetName() { Settings::getInstance().setCircleName(id, getName()); } -void CircleWidget::onExpand() -{ +void CircleWidget::onExpand() { Settings::getInstance().setCircleExpanded(id, isExpanded()); Settings::getInstance().savePersonal(); } -void CircleWidget::onAddFriendWidget(FriendWidget* w) -{ +void CircleWidget::onAddFriendWidget(FriendWidget* w) { const Friend* f = w->getFriend(); ToxPk toxId = f->getPublicKey(); Settings::getInstance().setFriendCircleID(toxId, id); } -void CircleWidget::updateID(int index) -{ +void CircleWidget::updateID(int index) { // For when a circle gets destroyed, another takes its id. // This function updates all friends widgets for this new id. diff --git a/src/modules/im/src/widget/circlewidget.h b/src/modules/im/src/widget/circlewidget.h index c10ca592..dde61596 100644 --- a/src/modules/im/src/widget/circlewidget.h +++ b/src/modules/im/src/widget/circlewidget.h @@ -17,8 +17,7 @@ class ContentDialog; -class CircleWidget : public CategoryWidget -{ +class CircleWidget : public CategoryWidget { Q_OBJECT public: explicit CircleWidget(FriendListWidget* parent, int id); @@ -48,4 +47,4 @@ class CircleWidget : public CategoryWidget int id; }; -#endif // CIRCLEWIDGET_H +#endif // CIRCLEWIDGET_H diff --git a/src/modules/im/src/widget/contentdialog.cpp b/src/modules/im/src/widget/contentdialog.cpp index c150298f..00918184 100644 --- a/src/modules/im/src/widget/contentdialog.cpp +++ b/src/modules/im/src/widget/contentdialog.cpp @@ -45,13 +45,12 @@ static const QSize minSize(minHeight, minWidget); static const QSize defaultSize(720, 400); ContentDialog::ContentDialog(QWidget* parent) - : ActivateDialog(parent, Qt::Window) - , splitter{new QSplitter(this)} - , friendLayout{new FriendListLayout(this)} - , activeChatroomWidget(nullptr) - , videoSurfaceSize(QSize()) - , videoCount(0) -{ + : ActivateDialog(parent, Qt::Window) + , splitter{new QSplitter(this)} + , friendLayout{new FriendListLayout(this)} + , activeChatroomWidget(nullptr) + , videoSurfaceSize(QSize()) + , videoCount(0) { const Settings& s = Settings::getInstance(); setStyleSheet(Style::getStylesheet("contentDialog/contentDialog.css")); @@ -121,61 +120,43 @@ ContentDialog::ContentDialog(QWidget* parent) setAcceptDrops(true); - new QShortcut(QKeySequence(Qt::CTRL , Qt::Key_Q), this, SLOT(close())); - new QShortcut(QKeySequence(Qt::CTRL , Qt::SHIFT , Qt::Key_Tab), this, SLOT(previousContact())); - new QShortcut(QKeySequence(Qt::CTRL , Qt::Key_Tab), this, SLOT(nextContact())); - new QShortcut(QKeySequence(Qt::CTRL , Qt::Key_PageUp), this, SLOT(previousContact())); - new QShortcut(QKeySequence(Qt::CTRL , Qt::Key_PageDown), this, SLOT(nextContact())); + new QShortcut(QKeySequence(Qt::CTRL, Qt::Key_Q), this, SLOT(close())); + new QShortcut(QKeySequence(Qt::CTRL, Qt::SHIFT, Qt::Key_Tab), this, SLOT(previousContact())); + new QShortcut(QKeySequence(Qt::CTRL, Qt::Key_Tab), this, SLOT(nextContact())); + new QShortcut(QKeySequence(Qt::CTRL, Qt::Key_PageUp), this, SLOT(previousContact())); + new QShortcut(QKeySequence(Qt::CTRL, Qt::Key_PageDown), this, SLOT(nextContact())); - connect(&s, &Settings::groupchatPositionChanged, this, &ContentDialog::onGroupchatPositionChanged); + connect(&s, + &Settings::groupchatPositionChanged, + this, + &ContentDialog::onGroupchatPositionChanged); connect(splitter, &QSplitter::splitterMoved, this, &ContentDialog::saveSplitterState); settings::Translator::registerHandler(std::bind(&ContentDialog::retranslateUi, this), this); } -ContentDialog::~ContentDialog() -{ - settings::Translator::unregister(this); -} +ContentDialog::~ContentDialog() { settings::Translator::unregister(this); } -void ContentDialog::closeEvent(QCloseEvent* event) -{ +void ContentDialog::closeEvent(QCloseEvent* event) { emit willClose(); event->accept(); } -void ContentDialog::addFriend(FriendChatroom* chatroom, - GenericChatForm* form) -{ - -} - -void ContentDialog::addGroup(GroupChatroom* chatroom, GenericChatForm* form) -{ +void ContentDialog::addFriend(FriendChatroom* chatroom, GenericChatForm* form) {} -} - -void ContentDialog::removeFriend(const FriendId& friendPk) -{ - -} +void ContentDialog::addGroup(GroupChatroom* chatroom, GenericChatForm* form) {} -void ContentDialog::removeGroup(const GroupId& groupId) -{ -} +void ContentDialog::removeFriend(const FriendId& friendPk) {} -void ContentDialog::closeIfEmpty() -{ +void ContentDialog::removeGroup(const GroupId& groupId) {} -} +void ContentDialog::closeIfEmpty() {} -int ContentDialog::chatroomCount() const -{ +int ContentDialog::chatroomCount() const { return friendLayout->friendTotalCount() + groupLayout.getLayout()->count(); } -void ContentDialog::ensureSplitterVisible() -{ +void ContentDialog::ensureSplitterVisible() { if (splitter->sizes().at(0) == 0) { splitter->setSizes({1, 1}); } @@ -190,8 +171,7 @@ void ContentDialog::ensureSplitterVisible() * @param[out] layout Current layout * @return Index of current widget in current layout. */ -int ContentDialog::getCurrentLayout(QLayout*& layout) -{ +int ContentDialog::getCurrentLayout(QLayout*& layout) { layout = friendLayout->getLayoutOnline(); int index = friendLayout->indexOfFriendWidget(activeChatroomWidget, true); if (index != -1) { @@ -219,8 +199,7 @@ int ContentDialog::getCurrentLayout(QLayout*& layout) * @param forward If true, activate next contace, previous otherwise. * @param inverse ??? TODO: Add docs. */ -void ContentDialog::cycleContacts(bool forward, bool inverse) -{ +void ContentDialog::cycleContacts(bool forward, bool inverse) { QLayout* currentLayout; int index = getCurrentLayout(currentLayout); if (!currentLayout || index == -1) { @@ -235,9 +214,9 @@ void ContentDialog::cycleContacts(bool forward, bool inverse) bool isCurOffline = currentLayout == friendLayout->getLayoutOffline(); bool isCurOnline = currentLayout == friendLayout->getLayoutOnline(); bool isCurGroup = currentLayout == groupLayout.getLayout(); - bool nextIsEmpty = (isCurOnline && offlineEmpty && (groupsEmpty || groupsOnTop)) - || (isCurGroup && offlineEmpty && (onlineEmpty || !groupsOnTop)) - || (isCurOffline); + bool nextIsEmpty = (isCurOnline && offlineEmpty && (groupsEmpty || groupsOnTop)) || + (isCurGroup && offlineEmpty && (onlineEmpty || !groupsOnTop)) || + (isCurOffline); if (nextIsEmpty) { forward = !forward; @@ -266,8 +245,7 @@ void ContentDialog::cycleContacts(bool forward, bool inverse) } } -void ContentDialog::onVideoShow(QSize size) -{ +void ContentDialog::onVideoShow(QSize size) { ++videoCount; if (videoCount > 1) { return; @@ -278,8 +256,7 @@ void ContentDialog::onVideoShow(QSize size) setMinimumSize(minSize + videoSurfaceSize); } -void ContentDialog::onVideoHide() -{ +void ContentDialog::onVideoHide() { videoCount--; if (videoCount > 0) { return; @@ -290,12 +267,10 @@ void ContentDialog::onVideoHide() videoSurfaceSize = QSize(); } - /** * @brief Update window title and icon. */ -void ContentDialog::updateTitleAndStatusIcon() -{ +void ContentDialog::updateTitleAndStatusIcon() { if (!activeChatroomWidget) { setWindowTitle(username); return; @@ -308,16 +283,15 @@ void ContentDialog::updateTitleAndStatusIcon() return; } -// Status::Status currentStatus = activeChatroomWidget->getFriend()->getStatus(); -// setWindowIcon(QIcon{Status::getIconPath(currentStatus)}); + // Status::Status currentStatus = activeChatroomWidget->getFriend()->getStatus(); + // setWindowIcon(QIcon{Status::getIconPath(currentStatus)}); } /** * @brief Update layouts order according to settings. * @param groupOnTop If true move groupchat layout on the top. Move under online otherwise. */ -void ContentDialog::reorderLayouts(bool newGroupOnTop) -{ +void ContentDialog::reorderLayouts(bool newGroupOnTop) { bool oldGroupOnTop = layouts.first() == groupLayout.getLayout(); if (newGroupOnTop != oldGroupOnTop) { // Kriby: Maintain backwards compatibility @@ -329,59 +303,50 @@ void ContentDialog::reorderLayouts(bool newGroupOnTop) } } -void ContentDialog::previousContact() -{ - cycleContacts(false); -} +void ContentDialog::previousContact() { cycleContacts(false); } /** * @brief Enable next contact. */ -void ContentDialog::nextContact() -{ - cycleContacts(true); -} +void ContentDialog::nextContact() { cycleContacts(true); } /** * @brief Update username to show in the title. * @param newName New name to display. */ -void ContentDialog::setUsername(const QString& newName) -{ +void ContentDialog::setUsername(const QString& newName) { username = newName; updateTitleAndStatusIcon(); } -bool ContentDialog::event(QEvent* event) -{ -// switch (event->type()) { -// case QEvent::WindowActivate: -// if (activeChatroomWidget) { -// activeChatroomWidget->resetEventFlags(); -// activeChatroomWidget->updateStatusLight(); +bool ContentDialog::event(QEvent* event) { + // switch (event->type()) { + // case QEvent::WindowActivate: + // if (activeChatroomWidget) { + // activeChatroomWidget->resetEventFlags(); + // activeChatroomWidget->updateStatusLight(); -// updateTitleAndStatusIcon(); + // updateTitleAndStatusIcon(); -// const IMFriend* frnd = activeChatroomWidget->getFriend(); -// const Group* group = activeChatroomWidget->getGroup(); + // const IMFriend* frnd = activeChatroomWidget->getFriend(); + // const Group* group = activeChatroomWidget->getGroup(); -// if (frnd) { -// emit friendDialogShown(frnd); -// } else if (group) { -// emit groupDialogShown(group); -// } -// } + // if (frnd) { + // emit friendDialogShown(frnd); + // } else if (group) { + // emit groupDialogShown(group); + // } + // } -// emit activated(); -// default: -// break; -// } + // emit activated(); + // default: + // break; + // } return ActivateDialog::event(event); } -void ContentDialog::dragEnterEvent(QDragEnterEvent* event) -{ +void ContentDialog::dragEnterEvent(QDragEnterEvent* event) { QObject* o = event->source(); FriendWidget* frnd = qobject_cast(o); GroupWidget* group = qobject_cast(o); @@ -413,8 +378,7 @@ void ContentDialog::dragEnterEvent(QDragEnterEvent* event) } } -void ContentDialog::dropEvent(QDropEvent* event) -{ +void ContentDialog::dropEvent(QDropEvent* event) { QObject* o = event->source(); FriendWidget* frnd = qobject_cast(o); GroupWidget* group = qobject_cast(o); @@ -441,8 +405,7 @@ void ContentDialog::dropEvent(QDropEvent* event) } } -void ContentDialog::changeEvent(QEvent* event) -{ +void ContentDialog::changeEvent(QEvent* event) { QWidget::changeEvent(event); if (event->type() == QEvent::ActivationChange) { if (isActiveWindow()) { @@ -451,33 +414,29 @@ void ContentDialog::changeEvent(QEvent* event) } } -void ContentDialog::resizeEvent(QResizeEvent* event) -{ +void ContentDialog::resizeEvent(QResizeEvent* event) { saveDialogGeometry(); QDialog::resizeEvent(event); } -void ContentDialog::moveEvent(QMoveEvent* event) -{ +void ContentDialog::moveEvent(QMoveEvent* event) { saveDialogGeometry(); QDialog::moveEvent(event); } -void ContentDialog::keyPressEvent(QKeyEvent* event) -{ +void ContentDialog::keyPressEvent(QKeyEvent* event) { // Ignore escape keyboard shortcut. if (event->key() != Qt::Key_Escape) { QDialog::keyPressEvent(event); } } -void ContentDialog::focusContact(const ContactId& contactId) -{ -// focusCommon(contactId, contactWidgets); +void ContentDialog::focusContact(const ContactId& contactId) { + // focusCommon(contactId, contactWidgets); } -void ContentDialog::focusCommon(const ContactId& id, QHash list) -{ +void ContentDialog::focusCommon( + const ContactId& id, QHash list) { auto it = list.find(id); if (it == list.end()) { return; @@ -490,8 +449,7 @@ void ContentDialog::focusCommon(const ContactId& id, QHashgetContact(); -// contactChatForms[contact->getPersistentId()]->show(contentLayout); + // const Contact* contact = widget->getContact(); + // contactChatForms[contact->getPersistentId()]->show(contentLayout); widget->setAsActiveChatroom(); widget->resetEventFlags(); -// widget->updateStatusLight(); + // widget->updateStatusLight(); updateTitleAndStatusIcon(); } -void ContentDialog::updateFriendStatus(const FriendId& friendPk, Status::Status status) -{ -// auto widget = qobject_cast(contactWidgets.value(friendPk)); -// addFriendWidget(widget, status); +void ContentDialog::updateFriendStatus(const FriendId& friendPk, Status::Status status) { + // auto widget = qobject_cast(contactWidgets.value(friendPk)); + // addFriendWidget(widget, status); } -void ContentDialog::updateContactStatusLight(const ContactId& contactId) -{ -// auto widget = contactWidgets.value(contactId); -// if (widget != nullptr) { -// widget->updateStatusLight(); -// } +void ContentDialog::updateContactStatusLight(const ContactId& contactId) { + // auto widget = contactWidgets.value(contactId); + // if (widget != nullptr) { + // widget->updateStatusLight(); + // } } -bool ContentDialog::isContactActive(const ContactId& contactId) const -{ -// auto widget = contactWidgets.value(contactId); -// if (widget == nullptr) { -// return false; -// } -return false; -// return widget->isActive(); +bool ContentDialog::isContactActive(const ContactId& contactId) const { + // auto widget = contactWidgets.value(contactId); + // if (widget == nullptr) { + // return false; + // } + return false; + // return widget->isActive(); } // TODO: Connect to widget directly -void ContentDialog::setStatusMessage(const FriendId& friendPk, const QString& message) -{ -// auto widget = contactWidgets.value(friendPk); -// if (widget != nullptr) { -// widget->setStatusMsg(message); -// } +void ContentDialog::setStatusMessage(const FriendId& friendPk, const QString& message) { + // auto widget = contactWidgets.value(friendPk); + // if (widget != nullptr) { + // widget->setStatusMsg(message); + // } } /** @@ -551,8 +505,7 @@ void ContentDialog::setStatusMessage(const FriendId& friendPk, const QString& me * @param friendId IMFriend Id. * @param alias Alias to display on widget. */ -void ContentDialog::updateFriendWidget(const FriendId& friendPk, QString alias) -{ +void ContentDialog::updateFriendWidget(const FriendId& friendPk, QString alias) { Friend* f = FriendList::findFriend(friendPk); FriendWidget* friendWidget = qobject_cast(contactWidget); @@ -566,8 +519,7 @@ void ContentDialog::updateFriendWidget(const FriendId& friendPk, QString alias) * * @param top If true, move group layout on the top, false otherwise. */ -void ContentDialog::onGroupchatPositionChanged(bool top) -{ +void ContentDialog::onGroupchatPositionChanged(bool top) { friendLayout->removeItem(groupLayout.getLayout()); friendLayout->insertLayout(top ? 0 : 1, groupLayout.getLayout()); } @@ -575,31 +527,23 @@ void ContentDialog::onGroupchatPositionChanged(bool top) /** * @brief Retranslate all elements in the form. */ -void ContentDialog::retranslateUi() -{ - updateTitleAndStatusIcon(); -} +void ContentDialog::retranslateUi() { updateTitleAndStatusIcon(); } /** * @brief Save size of dialog window. */ -void ContentDialog::saveDialogGeometry() -{ +void ContentDialog::saveDialogGeometry() { Settings::getInstance().setDialogGeometry(saveGeometry()); } /** * @brief Save state of splitter between dialog and dialog list. */ -void ContentDialog::saveSplitterState() -{ +void ContentDialog::saveSplitterState() { Settings::getInstance().setDialogSplitterState(splitter->saveState()); } -bool ContentDialog::hasContact(const ContactId& contactId) const -{ - return true; -} +bool ContentDialog::hasContact(const ContactId& contactId) const { return true; } /** * @brief Find the next or previous layout in layout list. @@ -607,8 +551,7 @@ bool ContentDialog::hasContact(const ContactId& contactId) const * @param forward If true, move forward, backward othwerwise. * @return Next/previous layout. */ -QLayout* ContentDialog::nextLayout(QLayout* layout, bool forward) const -{ +QLayout* ContentDialog::nextLayout(QLayout* layout, bool forward) const { int index = layouts.indexOf(layout); if (index == -1) { return nullptr; @@ -621,12 +564,10 @@ QLayout* ContentDialog::nextLayout(QLayout* layout, bool forward) const return layouts[next]; } -void ContentDialog::addFriendWidget(FriendWidget* widget, Status::Status status) -{ +void ContentDialog::addFriendWidget(FriendWidget* widget, Status::Status status) { friendLayout->addFriendWidget(widget, status); } -bool ContentDialog::isActiveWidget(GenericChatroomWidget* widget) -{ +bool ContentDialog::isActiveWidget(GenericChatroomWidget* widget) { return activeChatroomWidget == widget; } diff --git a/src/modules/im/src/widget/contentdialog.h b/src/modules/im/src/widget/contentdialog.h index dfe9cf2c..d503ea78 100644 --- a/src/modules/im/src/widget/contentdialog.h +++ b/src/modules/im/src/widget/contentdialog.h @@ -39,94 +39,93 @@ class QCloseEvent; class QSplitter; class ContentDialog : public ActivateDialog, public IDialogs { - Q_OBJECT + Q_OBJECT public: - explicit ContentDialog(QWidget *parent = nullptr); - ~ContentDialog() override; + explicit ContentDialog(QWidget* parent = nullptr); + ~ContentDialog() override; - void addFriend(FriendChatroom *chatroom, GenericChatForm *form); - void addGroup(GroupChatroom *chatroom, GenericChatForm *form); - void removeFriend(const FriendId &friendPk) override; - void removeGroup(const GroupId &groupId) override; - int chatroomCount() const override; - void ensureSplitterVisible(); - void updateTitleAndStatusIcon(); + void addFriend(FriendChatroom* chatroom, GenericChatForm* form); + void addGroup(GroupChatroom* chatroom, GenericChatForm* form); + void removeFriend(const FriendId& friendPk) override; + void removeGroup(const GroupId& groupId) override; + int chatroomCount() const override; + void ensureSplitterVisible(); + void updateTitleAndStatusIcon(); - void cycleContacts(bool forward, bool loop = true); - void onVideoShow(QSize size); - void onVideoHide(); + void cycleContacts(bool forward, bool loop = true); + void onVideoShow(QSize size); + void onVideoHide(); - void addFriendWidget(FriendWidget *widget, Status::Status status); - bool isActiveWidget(GenericChatroomWidget *widget); + void addFriendWidget(FriendWidget* widget, Status::Status status); + bool isActiveWidget(GenericChatroomWidget* widget); - bool hasContact(const ContactId &contactId) const override; - bool isContactActive(const ContactId &contactId) const override; + bool hasContact(const ContactId& contactId) const override; + bool isContactActive(const ContactId& contactId) const override; - void focusContact(const ContactId &friendPk); - void updateFriendStatus(const FriendId &friendPk, Status::Status status); - void updateContactStatusLight(const ContactId &contactId); + void focusContact(const ContactId& friendPk); + void updateFriendStatus(const FriendId& friendPk, Status::Status status); + void updateContactStatusLight(const ContactId& contactId); - void setStatusMessage(const FriendId &friendPk, const QString &message); + void setStatusMessage(const FriendId& friendPk, const QString& message); signals: - void friendDialogShown(const Friend *f); - void groupDialogShown(const Group *g); - void addFriendDialog(Friend *frnd, ContentDialog *contentDialog); - void addGroupDialog(Group *group, ContentDialog *contentDialog); - void activated(); - void willClose(); - void connectFriendWidget(FriendWidget &friendWidget); + void friendDialogShown(const Friend* f); + void groupDialogShown(const Group* g); + void addFriendDialog(Friend* frnd, ContentDialog* contentDialog); + void addGroupDialog(Group* group, ContentDialog* contentDialog); + void activated(); + void willClose(); + void connectFriendWidget(FriendWidget& friendWidget); public slots: - void reorderLayouts(bool newGroupOnTop); - void previousContact(); - void nextContact(); - void setUsername(const QString &newName); + void reorderLayouts(bool newGroupOnTop); + void previousContact(); + void nextContact(); + void setUsername(const QString& newName); protected: - bool event(QEvent *event) final override; - void dragEnterEvent(QDragEnterEvent *event) final override; - void dropEvent(QDropEvent *event) final override; - void changeEvent(QEvent *event) override; - void resizeEvent(QResizeEvent *event) override; - void moveEvent(QMoveEvent *event) override; - void keyPressEvent(QKeyEvent *event) override; + bool event(QEvent* event) final override; + void dragEnterEvent(QDragEnterEvent* event) final override; + void dropEvent(QDropEvent* event) final override; + void changeEvent(QEvent* event) override; + void resizeEvent(QResizeEvent* event) override; + void moveEvent(QMoveEvent* event) override; + void keyPressEvent(QKeyEvent* event) override; public slots: - void activate(GenericChatroomWidget *widget); + void activate(GenericChatroomWidget* widget); private slots: - void updateFriendWidget(const FriendId &friendPk, QString alias); - void onGroupchatPositionChanged(bool top); + void updateFriendWidget(const FriendId& friendPk, QString alias); + void onGroupchatPositionChanged(bool top); private: - void closeIfEmpty(); - void closeEvent(QCloseEvent *event) override; + void closeIfEmpty(); + void closeEvent(QCloseEvent* event) override; - void retranslateUi(); - void saveDialogGeometry(); - void saveSplitterState(); - QLayout *nextLayout(QLayout *layout, bool forward) const; - int getCurrentLayout(QLayout *&layout); - void focusCommon(const ContactId &id, - QHash list); + void retranslateUi(); + void saveDialogGeometry(); + void saveSplitterState(); + QLayout* nextLayout(QLayout* layout, bool forward) const; + int getCurrentLayout(QLayout*& layout); + void focusCommon(const ContactId& id, QHash list); private: - QList layouts; - QSplitter *splitter; - FriendListLayout *friendLayout; - GenericChatItemLayout groupLayout; - ContentLayout *contentLayout; - GenericChatroomWidget *activeChatroomWidget; - QSize videoSurfaceSize; - int videoCount; + QList layouts; + QSplitter* splitter; + FriendListLayout* friendLayout; + GenericChatItemLayout groupLayout; + ContentLayout* contentLayout; + GenericChatroomWidget* activeChatroomWidget; + QSize videoSurfaceSize; + int videoCount; - GenericChatroomWidget *contactWidget; + GenericChatroomWidget* contactWidget; - GenericChatForm *m_chatForm; - Chatroom *m_chatroom; + GenericChatForm* m_chatForm; + Chatroom* m_chatroom; - QString username; + QString username; }; -#endif // CONTENTDIALOG_H +#endif // CONTENTDIALOG_H diff --git a/src/modules/im/src/widget/contentdialogmanager.cpp b/src/modules/im/src/widget/contentdialogmanager.cpp index c7a0e3fd..5c8ee575 100644 --- a/src/modules/im/src/widget/contentdialogmanager.cpp +++ b/src/modules/im/src/widget/contentdialogmanager.cpp @@ -22,8 +22,7 @@ #include namespace { -void removeDialog(ContentDialog* dialog, QHash& dialogs) -{ +void removeDialog(ContentDialog* dialog, QHash& dialogs) { for (auto it = dialogs.begin(); it != dialogs.end();) { if (*it == dialog) { it = dialogs.erase(it); @@ -32,17 +31,13 @@ void removeDialog(ContentDialog* dialog, QHash } } } -} // namespace +} // namespace ContentDialogManager* ContentDialogManager::instance; -ContentDialog* ContentDialogManager::current() -{ - return currentDialog; -} +ContentDialog* ContentDialogManager::current() { return currentDialog; } -bool ContentDialogManager::contactWidgetExists(const ContactId& contactId) -{ +bool ContentDialogManager::contactWidgetExists(const ContactId& contactId) { const auto dialog = contactDialogs.value(contactId, nullptr); if (dialog == nullptr) { return false; @@ -52,10 +47,9 @@ bool ContentDialogManager::contactWidgetExists(const ContactId& contactId) } void ContentDialogManager::addFriendToDialog(const FriendId& friendPk, - ContentDialog* dialog, - FriendChatroom* chatroom, - GenericChatForm* form) -{ + ContentDialog* dialog, + FriendChatroom* chatroom, + GenericChatForm* form) { dialog->addFriend(chatroom, form); ContentDialog* lastDialog = getFriendDialog(friendPk); @@ -68,9 +62,8 @@ void ContentDialogManager::addFriendToDialog(const FriendId& friendPk, ContentDialog* ContentDialogManager::addGroupToDialog(const GroupId& groupId, ContentDialog* dialog, - GroupChatroom* chatroom, - GenericChatForm* form) -{ + GroupChatroom* chatroom, + GenericChatForm* form) { dialog->addGroup(chatroom, form); ContentDialog* lastDialog = getGroupDialog(groupId); @@ -82,8 +75,7 @@ ContentDialog* ContentDialogManager::addGroupToDialog(const GroupId& groupId, return lastDialog; } -void ContentDialogManager::focusContact(const ContactId& contactId) -{ +void ContentDialogManager::focusContact(const ContactId& contactId) { auto dialog = focusDialog(contactId, contactDialogs); if (dialog != nullptr) { dialog->focusContact(contactId); @@ -96,9 +88,8 @@ void ContentDialogManager::focusContact(const ContactId& contactId) * @param list List with dialogs * @return ContentDialog if found, nullptr otherwise */ -ContentDialog* ContentDialogManager::focusDialog(const ContactId& id, - const QHash& list) -{ +ContentDialog* ContentDialogManager::focusDialog( + const ContactId& id, const QHash& list) { auto iter = list.find(id); if (iter == list.end()) { return nullptr; @@ -114,8 +105,7 @@ ContentDialog* ContentDialogManager::focusDialog(const ContactId& id, return dialog; } -void ContentDialogManager::updateFriendStatus(const FriendId& friendPk) -{ +void ContentDialogManager::updateFriendStatus(const FriendId& friendPk) { auto dialog = contactDialogs.value(friendPk); if (dialog == nullptr) { return; @@ -130,8 +120,7 @@ void ContentDialogManager::updateFriendStatus(const FriendId& friendPk) dialog->updateFriendStatus(friendPk, f->getStatus()); } -void ContentDialogManager::updateGroupStatus(const GroupId& groupId) -{ +void ContentDialogManager::updateGroupStatus(const GroupId& groupId) { auto dialog = contactDialogs.value(groupId); if (dialog == nullptr) { return; @@ -143,8 +132,7 @@ void ContentDialogManager::updateGroupStatus(const GroupId& groupId) } } -bool ContentDialogManager::isContactActive(const ContactId& contactId) -{ +bool ContentDialogManager::isContactActive(const ContactId& contactId) { const auto dialog = contactDialogs.value(contactId); if (dialog == nullptr) { return false; @@ -153,18 +141,15 @@ bool ContentDialogManager::isContactActive(const ContactId& contactId) return dialog->isContactActive(contactId); } -ContentDialog* ContentDialogManager::getFriendDialog(const FriendId& friendPk) const -{ +ContentDialog* ContentDialogManager::getFriendDialog(const FriendId& friendPk) const { return contactDialogs.value(friendPk); } -ContentDialog* ContentDialogManager::getGroupDialog(const GroupId& groupId) const -{ +ContentDialog* ContentDialogManager::getGroupDialog(const GroupId& groupId) const { return contactDialogs.value(groupId); } -ContentDialogManager* ContentDialogManager::getInstance() -{ +ContentDialogManager* ContentDialogManager::getInstance() { if (instance == nullptr) { instance = new ContentDialogManager(); } @@ -172,21 +157,18 @@ ContentDialogManager* ContentDialogManager::getInstance() return instance; } -void ContentDialogManager::addContentDialog(ContentDialog& dialog) -{ +void ContentDialogManager::addContentDialog(ContentDialog& dialog) { currentDialog = &dialog; connect(&dialog, &ContentDialog::willClose, this, &ContentDialogManager::onDialogClose); connect(&dialog, &ContentDialog::activated, this, &ContentDialogManager::onDialogActivate); } -void ContentDialogManager::onDialogActivate() -{ +void ContentDialogManager::onDialogActivate() { ContentDialog* dialog = qobject_cast(sender()); currentDialog = dialog; } -void ContentDialogManager::onDialogClose() -{ +void ContentDialogManager::onDialogClose() { ContentDialog* dialog = qobject_cast(sender()); if (currentDialog == dialog) { currentDialog = nullptr; @@ -195,12 +177,10 @@ void ContentDialogManager::onDialogClose() removeDialog(dialog, contactDialogs); } -IDialogs* ContentDialogManager::getFriendDialogs(const FriendId& friendPk) const -{ +IDialogs* ContentDialogManager::getFriendDialogs(const FriendId& friendPk) const { return getFriendDialog(friendPk); } -IDialogs* ContentDialogManager::getGroupDialogs(const GroupId& groupId) const -{ +IDialogs* ContentDialogManager::getGroupDialogs(const GroupId& groupId) const { return getGroupDialog(groupId); } diff --git a/src/modules/im/src/widget/contentdialogmanager.h b/src/modules/im/src/widget/contentdialogmanager.h index ea5a792e..741e69c1 100644 --- a/src/modules/im/src/widget/contentdialogmanager.h +++ b/src/modules/im/src/widget/contentdialogmanager.h @@ -24,8 +24,7 @@ /** * @breaf Manage all content dialogs */ -class ContentDialogManager : public QObject, public IDialogsManager -{ +class ContentDialogManager : public QObject, public IDialogsManager { Q_OBJECT public: ContentDialog* current(); @@ -41,9 +40,9 @@ class ContentDialogManager : public QObject, public IDialogsManager IDialogs* getGroupDialogs(const GroupId& groupId) const; void addFriendToDialog(const FriendId& friendPx, - ContentDialog* dialog, - FriendChatroom* chatroom, - GenericChatForm* form); + ContentDialog* dialog, + FriendChatroom* chatroom, + GenericChatForm* form); ContentDialog* addGroupToDialog(const GroupId& groupId, ContentDialog* dialog, @@ -69,4 +68,4 @@ private slots: static ContentDialogManager* instance; }; -#endif // _CONTENT_DIALOG_MANAGER_H_ +#endif // _CONTENT_DIALOG_MANAGER_H_ diff --git a/src/modules/im/src/widget/contentlayout.cpp b/src/modules/im/src/widget/contentlayout.cpp index 19e691df..7ec29b1a 100644 --- a/src/modules/im/src/widget/contentlayout.cpp +++ b/src/modules/im/src/widget/contentlayout.cpp @@ -11,79 +11,67 @@ */ #include "contentlayout.h" -#include "src/lib/settings/style.h" -#include "src/persistence/settings.h" #include #include +#include "src/lib/settings/style.h" +#include "src/persistence/settings.h" -ContentLayout::ContentLayout() - : QStackedLayout() -{ - init(); -} +ContentLayout::ContentLayout() : QStackedLayout() { init(); } -ContentLayout::ContentLayout(QWidget* parent) - : QStackedLayout(parent) -{ +ContentLayout::ContentLayout(QWidget* parent) : QStackedLayout(parent) { init(); -// QPalette palette = parent->palette(); -// palette.setBrush(QPalette::WindowText, QColor(0, 0, 0)); -// palette.setBrush(QPalette::Button, QColor(255, 255, 255)); -// palette.setBrush(QPalette::Light, QColor(255, 255, 255)); -// palette.setBrush(QPalette::Midlight, QColor(255, 255, 255)); -// palette.setBrush(QPalette::Dark, QColor(127, 127, 127)); -// palette.setBrush(QPalette::Mid, QColor(170, 170, 170)); -// palette.setBrush(QPalette::Text, QColor(0, 0, 0)); -// palette.setBrush(QPalette::BrightText, QColor(255, 255, 255)); -// palette.setBrush(QPalette::ButtonText, QColor(0, 0, 0)); -// palette.setBrush(QPalette::Base, QColor(255, 255, 255)); -// palette.setBrush(QPalette::Window, QColor(255, 255, 255)); -// palette.setBrush(QPalette::Shadow, QColor(0, 0, 0)); -// palette.setBrush(QPalette::AlternateBase, QColor(255, 255, 255)); -// palette.setBrush(QPalette::ToolTipBase, QColor(255, 255, 220)); -// palette.setBrush(QPalette::ToolTipText, QColor(0, 0, 0)); + // QPalette palette = parent->palette(); + // palette.setBrush(QPalette::WindowText, QColor(0, 0, 0)); + // palette.setBrush(QPalette::Button, QColor(255, 255, 255)); + // palette.setBrush(QPalette::Light, QColor(255, 255, 255)); + // palette.setBrush(QPalette::Midlight, QColor(255, 255, 255)); + // palette.setBrush(QPalette::Dark, QColor(127, 127, 127)); + // palette.setBrush(QPalette::Mid, QColor(170, 170, 170)); + // palette.setBrush(QPalette::Text, QColor(0, 0, 0)); + // palette.setBrush(QPalette::BrightText, QColor(255, 255, 255)); + // palette.setBrush(QPalette::ButtonText, QColor(0, 0, 0)); + // palette.setBrush(QPalette::Base, QColor(255, 255, 255)); + // palette.setBrush(QPalette::Window, QColor(255, 255, 255)); + // palette.setBrush(QPalette::Shadow, QColor(0, 0, 0)); + // palette.setBrush(QPalette::AlternateBase, QColor(255, 255, 255)); + // palette.setBrush(QPalette::ToolTipBase, QColor(255, 255, 220)); + // palette.setBrush(QPalette::ToolTipText, QColor(0, 0, 0)); -// palette.setBrush(QPalette::Disabled, QPalette::WindowText, QColor(127, 127, 127)); -// palette.setBrush(QPalette::Disabled, QPalette::Text, QColor(127, 127, 127)); -// palette.setBrush(QPalette::Disabled, QPalette::ButtonText, QColor(127, 127, 127)); + // palette.setBrush(QPalette::Disabled, QPalette::WindowText, QColor(127, 127, 127)); + // palette.setBrush(QPalette::Disabled, QPalette::Text, QColor(127, 127, 127)); + // palette.setBrush(QPalette::Disabled, QPalette::ButtonText, QColor(127, 127, 127)); -//// parent->setPalette(palette); + //// parent->setPalette(palette); } -ContentLayout::~ContentLayout() -{ +ContentLayout::~ContentLayout() { clear(); -// mainHead->deleteLater(); -// mainContent->deleteLater(); + // mainHead->deleteLater(); + // mainContent->deleteLater(); } -void ContentLayout::reloadTheme() -{ +void ContentLayout::reloadTheme() { #ifndef Q_OS_MAC // mainHead->setStyleSheet(Style::getStylesheet("settings/mainHead.css")); // mainContent->setStyleSheet(Style::getStylesheet("window/general.css")); #endif } -void ContentLayout::clear() -{ -// QLayoutItem* item; -// while ((item = mainHead->layout()->takeAt(0)) != nullptr) { -// item->widget()->hide(); -// item->widget()->setParent(nullptr); -// delete item; -// } -// -// while ((item = mainContent->layout()->takeAt(0)) != nullptr) { -// item->widget()->hide(); -// item->widget()->setParent(nullptr); -// delete item; -// } +void ContentLayout::clear() { + // QLayoutItem* item; + // while ((item = mainHead->layout()->takeAt(0)) != nullptr) { + // item->widget()->hide(); + // item->widget()->setParent(nullptr); + // delete item; + // } + // + // while ((item = mainContent->layout()->takeAt(0)) != nullptr) { + // item->widget()->hide(); + // item->widget()->setParent(nullptr); + // delete item; + // } } -void ContentLayout::init() -{ - -} +void ContentLayout::init() {} diff --git a/src/modules/im/src/widget/contentlayout.h b/src/modules/im/src/widget/contentlayout.h index b6e8edc1..84051212 100644 --- a/src/modules/im/src/widget/contentlayout.h +++ b/src/modules/im/src/widget/contentlayout.h @@ -17,8 +17,7 @@ #include #include -class ContentLayout : public QStackedLayout -{ +class ContentLayout : public QStackedLayout { public: ContentLayout(); explicit ContentLayout(QWidget* parent); @@ -27,13 +26,13 @@ class ContentLayout : public QStackedLayout void reloadTheme(); void clear(); -// QFrame mainHLine; -// QHBoxLayout mainHLineLayout; -// QWidget* mainContent; -// QWidget* mainHead; + // QFrame mainHLine; + // QHBoxLayout mainHLineLayout; + // QWidget* mainContent; + // QWidget* mainHead; private: void init(); }; -#endif // CONTENTLAYOUT_H +#endif // CONTENTLAYOUT_H diff --git a/src/modules/im/src/widget/emoticonswidget.cpp b/src/modules/im/src/widget/emoticonswidget.cpp index ede38606..d25eef33 100644 --- a/src/modules/im/src/widget/emoticonswidget.cpp +++ b/src/modules/im/src/widget/emoticonswidget.cpp @@ -15,16 +15,16 @@ #include "src/persistence/settings.h" #include "src/persistence/smileypack.h" +#include +#include #include #include #include #include +#include #include #include -#include #include -#include -#include #include @@ -33,7 +33,7 @@ constexpr int emoji_layout_cols = 8; constexpr int emoji_layout_spacing = 4; class PageDotButton : public QRadioButton { - public: +public: using QRadioButton::QRadioButton; QSize sizeHint() const override { QSize s = QRadioButton::sizeHint(); @@ -41,16 +41,14 @@ class PageDotButton : public QRadioButton { } }; -EmoticonsWidget::EmoticonsWidget(QWidget* parent) - : QMenu(parent) -{ +EmoticonsWidget::EmoticonsWidget(QWidget* parent) : QMenu(parent) { setStyleSheet(Style::getStylesheet("emoticonWidget/emoticonWidget.css")); setLayout(&layout); layout.addWidget(&stack); QWidget* pageButtonsContainer = new QWidget; pageButtonsContainer->setObjectName("PageIndexContainer"); - QHBoxLayout *buttonLayout = new QHBoxLayout(pageButtonsContainer); + QHBoxLayout* buttonLayout = new QHBoxLayout(pageButtonsContainer); pageIndexGroup = new QButtonGroup(this); layout.addWidget(pageButtonsContainer); @@ -70,7 +68,7 @@ EmoticonsWidget::EmoticonsWidget(QWidget* parent) // create pages buttonLayout->addStretch(); for (int i = 0; i < pageCount; ++i) { - EmoticonsPageView *page = new EmoticonsPageView(this); + EmoticonsPageView* page = new EmoticonsPageView(this); page->setRange(itemsPerPage * i, std::min(itemsPerPage * (i + 1), itemCount) - 1); stack.addWidget(page); connect(page, &EmoticonsPageView::clicked, this, [this](int index) { @@ -80,7 +78,7 @@ EmoticonsWidget::EmoticonsWidget(QWidget* parent) // page buttons are only needed if there is more than 1 page if (pageCount > 1) { - QRadioButton *pageButton = new PageDotButton(pageButtonsContainer); + QRadioButton* pageButton = new PageDotButton(pageButtonsContainer); pageButton->setCheckable(true); pageButton->setProperty("pageIndex", i); pageButton->setCursor(Qt::PointingHandCursor); @@ -88,7 +86,8 @@ EmoticonsWidget::EmoticonsWidget(QWidget* parent) buttonLayout->addWidget(pageButton); pageIndexGroup->addButton(pageButton); - connect(pageButton, &QRadioButton::clicked, this, &EmoticonsWidget::onPageButtonClicked); + connect(pageButton, &QRadioButton::clicked, this, + &EmoticonsWidget::onPageButtonClicked); } } buttonLayout->addStretch(); @@ -97,39 +96,30 @@ EmoticonsWidget::EmoticonsWidget(QWidget* parent) layout.activate(); } -void EmoticonsWidget::onSmileyClicked(const QString &text) { +void EmoticonsWidget::onSmileyClicked(const QString& text) { // emit insert emoticon QString sequence = text; sequence.replace("<", "<").replace(">", ">"); emit insertEmoticon(sequence); } -void EmoticonsWidget::onPageButtonClicked() -{ - QWidget *sender = qobject_cast(QObject::sender()); +void EmoticonsWidget::onPageButtonClicked() { + QWidget* sender = qobject_cast(QObject::sender()); if (sender) { int page = sender->property("pageIndex").toInt(); stack.setCurrentIndex(page); } } -QSize EmoticonsWidget::sizeHint() const -{ - return layout.sizeHint(); -} +QSize EmoticonsWidget::sizeHint() const { return layout.sizeHint(); } -void EmoticonsWidget::mouseReleaseEvent(QMouseEvent* ev) -{ - if (!rect().contains(ev->pos())) - hide(); +void EmoticonsWidget::mouseReleaseEvent(QMouseEvent* ev) { + if (!rect().contains(ev->pos())) hide(); } -void EmoticonsWidget::mousePressEvent(QMouseEvent*) -{ -} +void EmoticonsWidget::mousePressEvent(QMouseEvent*) {} -void EmoticonsWidget::wheelEvent(QWheelEvent* e) -{ +void EmoticonsWidget::wheelEvent(QWheelEvent* e) { #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) const bool vertical = qAbs(e->angleDelta().y()) >= qAbs(e->angleDelta().x()); const int delta = vertical ? e->angleDelta().y() : e->angleDelta().x(); @@ -148,10 +138,9 @@ void EmoticonsWidget::wheelEvent(QWheelEvent* e) } } -void EmoticonsWidget::PageButtonsUpdate() -{ - QList pageButtons = pageIndexGroup->buttons(); - foreach (QAbstractButton *t_pageButton, pageButtons) { +void EmoticonsWidget::PageButtonsUpdate() { + QList pageButtons = pageIndexGroup->buttons(); + foreach (QAbstractButton* t_pageButton, pageButtons) { if (t_pageButton->property("pageIndex").toInt() == stack.currentIndex()) t_pageButton->setChecked(true); else @@ -159,15 +148,12 @@ void EmoticonsWidget::PageButtonsUpdate() } } -void EmoticonsWidget::keyPressEvent(QKeyEvent* e) -{ +void EmoticonsWidget::keyPressEvent(QKeyEvent* e) { Q_UNUSED(e) hide(); } -EmoticonsPageView::EmoticonsPageView(QWidget *parent) - : QWidget(parent) -{ +EmoticonsPageView::EmoticonsPageView(QWidget* parent) : QWidget(parent) { setMouseTracking(true); int s = Settings::getInstance().getEmojiFontPointSize(); @@ -178,13 +164,9 @@ EmoticonsPageView::EmoticonsPageView(QWidget *parent) invisible_button->setToolButtonStyle(Qt::ToolButtonIconOnly); } -QSize EmoticonsPageView::sizeHint() const -{ - return minimumSizeHint(); -} +QSize EmoticonsPageView::sizeHint() const { return minimumSizeHint(); } -QSize EmoticonsPageView::minimumSizeHint() const -{ +QSize EmoticonsPageView::minimumSizeHint() const { QMargins m = this->contentsMargins(); int baseSize = itemSize(); int w = (baseSize + emoji_layout_spacing) * emoji_layout_cols - emoji_layout_spacing; @@ -192,72 +174,55 @@ QSize EmoticonsPageView::minimumSizeHint() const return QSize(w + m.top() + m.bottom(), h + m.left() + m.right()); } -void EmoticonsPageView::setRange(int start, int end) -{ +void EmoticonsPageView::setRange(int start, int end) { this->start = std::max(start, 0); this->end = std::max(end, 0); - if (this->end < this->start) - std::swap(this->start, this->end); + if (this->end < this->start) std::swap(this->start, this->end); const auto emoticons = SmileyPack::getInstance().getEmoticons(); - for (int i = this->start; i <= this->end && i < emoticons.count(); i++) - { + for (int i = this->start; i <= this->end && i < emoticons.count(); i++) { displayCache.append(emoticons.at(i).at(0)); } updateGeometry(); } -void EmoticonsPageView::mouseMoveEvent(QMouseEvent *event) -{ +void EmoticonsPageView::mouseMoveEvent(QMouseEvent* event) { int index = indexAtPostion(event->pos()); - if (index != hoverIndex) - { - if (hoverIndex >= 0) - updateIndex(hoverIndex); + if (index != hoverIndex) { + if (hoverIndex >= 0) updateIndex(hoverIndex); hoverIndex = index; - if (hoverIndex >= 0) - updateIndex(hoverIndex); + if (hoverIndex >= 0) updateIndex(hoverIndex); } } -void EmoticonsPageView::mousePressEvent(QMouseEvent *event) -{ - if (event->button() == Qt::LeftButton) - { +void EmoticonsPageView::mousePressEvent(QMouseEvent* event) { + if (event->button() == Qt::LeftButton) { pressedIndex = indexAtPostion(event->pos()); } } -void EmoticonsPageView::mouseDoubleClickEvent(QMouseEvent *event) -{ - if (event->button() == Qt::LeftButton) - { +void EmoticonsPageView::mouseDoubleClickEvent(QMouseEvent* event) { + if (event->button() == Qt::LeftButton) { int index = indexAtPostion(event->pos()); - if (pressedIndex != index) - pressedIndex = -1; + if (pressedIndex != index) pressedIndex = -1; } } -void EmoticonsPageView::mouseReleaseEvent(QMouseEvent *event) -{ - if (event->button() == Qt::LeftButton) - { +void EmoticonsPageView::mouseReleaseEvent(QMouseEvent* event) { + if (event->button() == Qt::LeftButton) { int index = indexAtPostion(event->pos()); - if (pressedIndex == index && pressedIndex >= 0) - { + if (pressedIndex == index && pressedIndex >= 0) { int tmp = pressedIndex + start; const auto emoticons = SmileyPack::getInstance().getEmoticons(); - if (tmp < emoticons.count()) - emit clicked(tmp); + if (tmp < emoticons.count()) emit clicked(tmp); } } } -void EmoticonsPageView::paintEvent(QPaintEvent *event) -{ +void EmoticonsPageView::paintEvent(QPaintEvent* event) { QWidget::paintEvent(event); QRect dirty = event->rect(); @@ -266,28 +231,23 @@ void EmoticonsPageView::paintEvent(QPaintEvent *event) int last = qBound(0, indexAtPostion(dirty.bottomRight(), false), displayCache.count() - 1); QPainter painter(this); - if (first == last) - { + if (first == last) { drawCell(&painter, first); - } - else - { + } else { int row_start = first / emoji_layout_cols; int row_end = last / emoji_layout_cols; int col_start = first % emoji_layout_cols; int col_end = last % emoji_layout_cols; for (int r = row_start; r <= row_end; r++) { - for (int c = col_start; c <= col_end; c++) - { - int i = r *emoji_layout_cols + c; + for (int c = col_start; c <= col_end; c++) { + int i = r * emoji_layout_cols + c; drawCell(&painter, i); } } } } -int EmoticonsPageView::indexAtPostion(const QPoint &pos, bool accurately) -{ +int EmoticonsPageView::indexAtPostion(const QPoint& pos, bool accurately) { QRect rc = this->contentsRect(); if (accurately && !rc.contains(pos)) { return -1; @@ -315,8 +275,7 @@ void EmoticonsPageView::updateIndex(int index) { update(indexRect(index)); } -QRect EmoticonsPageView::indexRect(int index) -{ +QRect EmoticonsPageView::indexRect(int index) { int baseSize = itemSize(); int row = index / emoji_layout_cols; int col = index % emoji_layout_cols; @@ -325,8 +284,7 @@ QRect EmoticonsPageView::indexRect(int index) return QRect(col * grid_w + rc.left(), row * grid_w + rc.top(), baseSize, baseSize); } -void EmoticonsPageView::drawCell(QPainter *painter, int index) -{ +void EmoticonsPageView::drawCell(QPainter* painter, int index) { QStyleOptionToolButton opt; opt.initFrom(invisible_button); opt.subControls = QStyle::SC_ToolButton; @@ -336,10 +294,8 @@ void EmoticonsPageView::drawCell(QPainter *painter, int index) opt.iconSize = invisible_button->iconSize(); opt.rect = indexRect(index); - if (hoverIndex == index) - opt.state |= QStyle::State_MouseOver; - if (pressedIndex == index) - opt.state |= QStyle::State_Sunken; + if (hoverIndex == index) opt.state |= QStyle::State_MouseOver; + if (pressedIndex == index) opt.state |= QStyle::State_Sunken; opt.icon = *SmileyPack::getInstance().getAsIcon(displayCache.at(index)); painter->save(); @@ -348,9 +304,7 @@ void EmoticonsPageView::drawCell(QPainter *painter, int index) painter->restore(); } -int EmoticonsPageView::itemSize() const -{ - if (_itemSize < 0) - _itemSize = invisible_button->sizeHint().width(); +int EmoticonsPageView::itemSize() const { + if (_itemSize < 0) _itemSize = invisible_button->sizeHint().width(); return _itemSize; } diff --git a/src/modules/im/src/widget/emoticonswidget.h b/src/modules/im/src/widget/emoticonswidget.h index 3ecfbba2..a3ceef14 100644 --- a/src/modules/im/src/widget/emoticonswidget.h +++ b/src/modules/im/src/widget/emoticonswidget.h @@ -13,13 +13,13 @@ #ifndef EMOTICONSWIDGET_H #define EMOTICONSWIDGET_H +#include #include #include +#include +#include #include #include -#include -#include -#include #include @@ -27,8 +27,7 @@ class QIcon; class QToolButton; class QButtonGroup; -class EmoticonsWidget : public QMenu -{ +class EmoticonsWidget : public QMenu { Q_OBJECT public: explicit EmoticonsWidget(QWidget* parent = nullptr); @@ -37,7 +36,7 @@ class EmoticonsWidget : public QMenu void insertEmoticon(QString str); private slots: - void onSmileyClicked(const QString & text); + void onSmileyClicked(const QString& text); void onPageButtonClicked(); void PageButtonsUpdate(); @@ -51,40 +50,39 @@ private slots: QStackedWidget stack; QVBoxLayout layout; QList> emoticonsIcons; - QButtonGroup *pageIndexGroup = nullptr; + QButtonGroup* pageIndexGroup = nullptr; public: QSize sizeHint() const override; }; -class EmoticonsPageView : public QWidget -{ +class EmoticonsPageView : public QWidget { Q_OBJECT signals: void clicked(int offset); - public: - EmoticonsPageView(QWidget *parent); +public: + EmoticonsPageView(QWidget* parent); QSize sizeHint() const override; QSize minimumSizeHint() const override; void setRange(int start, int end); - protected: - void mouseMoveEvent(QMouseEvent *event) override; - void mousePressEvent(QMouseEvent *event) override; - void mouseDoubleClickEvent(QMouseEvent *event) override; - void mouseReleaseEvent(QMouseEvent *event) override; - void paintEvent(QPaintEvent *event) override; +protected: + void mouseMoveEvent(QMouseEvent* event) override; + void mousePressEvent(QMouseEvent* event) override; + void mouseDoubleClickEvent(QMouseEvent* event) override; + void mouseReleaseEvent(QMouseEvent* event) override; + void paintEvent(QPaintEvent* event) override; - private: - int indexAtPostion(const QPoint &pos, bool accurately = false); +private: + int indexAtPostion(const QPoint& pos, bool accurately = false); void updateIndex(int index); QRect indexRect(int index); - void drawCell(QPainter * painter, int index); + void drawCell(QPainter* painter, int index); int itemSize() const; - private: - QToolButton *invisible_button = nullptr; +private: + QToolButton* invisible_button = nullptr; int start = -1; int end = -1; int hoverIndex = -1; @@ -93,4 +91,4 @@ class EmoticonsPageView : public QWidget QStringList displayCache; }; -#endif // EMOTICONSWIDGET_H +#endif // EMOTICONSWIDGET_H diff --git a/src/modules/im/src/widget/flowlayout.cpp b/src/modules/im/src/widget/flowlayout.cpp index 18822cba..24b3cc06 100644 --- a/src/modules/im/src/widget/flowlayout.cpp +++ b/src/modules/im/src/widget/flowlayout.cpp @@ -14,105 +14,72 @@ #include "flowlayout.h" FlowLayout::FlowLayout(QWidget* parent, int margin, int hSpacing, int vSpacing) - : QLayout(parent) - , m_hSpace(hSpacing) - , m_vSpace(vSpacing) -{ + : QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing) { setContentsMargins(margin, margin, margin, margin); } FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing) - : m_hSpace(hSpacing) - , m_vSpace(vSpacing) -{ + : m_hSpace(hSpacing), m_vSpace(vSpacing) { setContentsMargins(margin, margin, margin, margin); } -FlowLayout::~FlowLayout() -{ +FlowLayout::~FlowLayout() { QLayoutItem* item; - while ((item = takeAt(0))) - delete item; + while ((item = takeAt(0))) delete item; } -void FlowLayout::addItem(QLayoutItem* item) -{ - itemList.append(item); -} +void FlowLayout::addItem(QLayoutItem* item) { itemList.append(item); } -int FlowLayout::horizontalSpacing() const -{ +int FlowLayout::horizontalSpacing() const { if (m_hSpace >= 0) return m_hSpace; else return smartSpacing(QStyle::PM_LayoutHorizontalSpacing); } -int FlowLayout::verticalSpacing() const -{ +int FlowLayout::verticalSpacing() const { if (m_vSpace >= 0) return m_vSpace; else return smartSpacing(QStyle::PM_LayoutVerticalSpacing); } -int FlowLayout::count() const -{ - return itemList.size(); -} +int FlowLayout::count() const { return itemList.size(); } -QLayoutItem* FlowLayout::itemAt(int index) const -{ - return itemList.value(index); -} +QLayoutItem* FlowLayout::itemAt(int index) const { return itemList.value(index); } -QLayoutItem* FlowLayout::takeAt(int index) -{ +QLayoutItem* FlowLayout::takeAt(int index) { if (index >= 0 && index < itemList.size()) return itemList.takeAt(index); else return nullptr; } -Qt::Orientations FlowLayout::expandingDirections() const -{ - return {}; -} +Qt::Orientations FlowLayout::expandingDirections() const { return {}; } -bool FlowLayout::hasHeightForWidth() const -{ - return true; -} +bool FlowLayout::hasHeightForWidth() const { return true; } -int FlowLayout::heightForWidth(int width) const -{ +int FlowLayout::heightForWidth(int width) const { int height = doLayout(QRect(0, 0, width, 0), true); return height; } -void FlowLayout::setGeometry(const QRect& rect) -{ +void FlowLayout::setGeometry(const QRect& rect) { QLayout::setGeometry(rect); doLayout(rect, false); } -QSize FlowLayout::sizeHint() const -{ - return minimumSize(); -} +QSize FlowLayout::sizeHint() const { return minimumSize(); } -QSize FlowLayout::minimumSize() const -{ +QSize FlowLayout::minimumSize() const { QSize size; - foreach (QLayoutItem* item, itemList) - size = size.expandedTo(item->minimumSize()); + foreach (QLayoutItem* item, itemList) size = size.expandedTo(item->minimumSize()); size += QSize(2 * margin(), 2 * margin()); return size; } -int FlowLayout::doLayout(const QRect& rect, bool testOnly) const -{ +int FlowLayout::doLayout(const QRect& rect, bool testOnly) const { int left, top, right, bottom; getContentsMargins(&left, &top, &right, &bottom); QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom); @@ -141,16 +108,14 @@ int FlowLayout::doLayout(const QRect& rect, bool testOnly) const lineHeight = 0; } - if (!testOnly) - item->setGeometry(QRect(QPoint(x, y), item->sizeHint())); + if (!testOnly) item->setGeometry(QRect(QPoint(x, y), item->sizeHint())); x = nextX; lineHeight = qMax(lineHeight, item->sizeHint().height()); } return y + lineHeight - rect.y() + bottom; } -int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const -{ +int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const { QObject* parent = this->parent(); if (!parent) { return -1; diff --git a/src/modules/im/src/widget/flowlayout.h b/src/modules/im/src/widget/flowlayout.h index 4cc0e299..16e39d1a 100644 --- a/src/modules/im/src/widget/flowlayout.h +++ b/src/modules/im/src/widget/flowlayout.h @@ -16,8 +16,7 @@ #include #include #include -class FlowLayout : public QLayout -{ +class FlowLayout : public QLayout { public: explicit FlowLayout(QWidget* parent, int margin = -1, int hSpacing = -1, int vSpacing = -1); explicit FlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1); @@ -45,4 +44,4 @@ class FlowLayout : public QLayout int m_vSpace; }; -#endif // FLOWLAYOUT_H +#endif // FLOWLAYOUT_H diff --git a/src/modules/im/src/widget/form/CallDurationForm.cpp b/src/modules/im/src/widget/form/CallDurationForm.cpp index 60cc5da0..70af4812 100644 --- a/src/modules/im/src/widget/form/CallDurationForm.cpp +++ b/src/modules/im/src/widget/form/CallDurationForm.cpp @@ -1,138 +1,141 @@ #include "CallDurationForm.h" #include "ui_CallDurationForm.h" +#include +#include #include "base/times.h" #include "src/core/coreav.h" #include "src/lib/settings/style.h" #include "src/video/netcamview.h" -#include -#include - -CallDurationForm::CallDurationForm(QWidget *parent) - :QWidget(parent),// - ui(new Ui::CallDurationForm), contact{nullptr},// - callDurationTimer{new QTimer()}, // - muteOut{false}, muteIn{false}, netcam{nullptr} -{ - ui->setupUi(this); - setWindowFlags(Qt::FramelessWindowHint); - setWindowFlags(Qt::WindowMinMaxButtonsHint); - - ui->videoButton->hide(); - - connect(ui->callButton, &QPushButton::clicked, this, &CallDurationForm::onCallEnd); - connect(ui->micButton, &QPushButton::clicked, this, &CallDurationForm::onMuteOut); - connect(ui->volButton, &QPushButton::clicked, this, &CallDurationForm::onMuteIn); - - reloadTheme(); - connect(callDurationTimer, &QTimer::timeout, this, &CallDurationForm::onUpdateTime); - callDurationTimer->start(1000); - timeElapsed.start(); +CallDurationForm::CallDurationForm(QWidget* parent) + : QWidget(parent) + , // + ui(new Ui::CallDurationForm) + , contact{nullptr} + , // + callDurationTimer{new QTimer()} + , // + muteOut{false} + , muteIn{false} + , netcam{nullptr} { + ui->setupUi(this); + + setWindowFlags(Qt::FramelessWindowHint); + setWindowFlags(Qt::WindowMinMaxButtonsHint); + + ui->videoButton->hide(); + + connect(ui->callButton, &QPushButton::clicked, this, &CallDurationForm::onCallEnd); + connect(ui->micButton, &QPushButton::clicked, this, &CallDurationForm::onMuteOut); + connect(ui->volButton, &QPushButton::clicked, this, &CallDurationForm::onMuteIn); + + reloadTheme(); + connect(callDurationTimer, &QTimer::timeout, this, &CallDurationForm::onUpdateTime); + callDurationTimer->start(1000); + timeElapsed.start(); } CallDurationForm::~CallDurationForm() { - QString dhms = base::secondsToDHMS(timeElapsed.elapsed() / 1000); + QString dhms = base::secondsToDHMS(timeElapsed.elapsed() / 1000); - // QString mess = error ? tr("Call with %1 ended unexpectedly. %2") - // : tr("Call with %1 ended. %2"); + // QString mess = error ? tr("Call with %1 ended unexpectedly. %2") + // : tr("Call with %1 ended. %2"); - // addSystemInfoMessage(mess.arg(name, dhms), ChatMessage::INFO, - // QDateTime::currentDateTime()); - callDurationTimer->stop(); + // addSystemInfoMessage(mess.arg(name, dhms), ChatMessage::INFO, + // QDateTime::currentDateTime()); + callDurationTimer->stop(); - delete callDurationTimer; - callDurationTimer = nullptr; + delete callDurationTimer; + callDurationTimer = nullptr; - delete ui; + delete ui; } -void CallDurationForm::setContact(const Contact *c) { - if (!c) - return; - contact = c; +void CallDurationForm::setContact(const Contact* c) { + if (!c) return; + contact = c; } -void CallDurationForm::reloadTheme() { setStyleSheet(Style::getStylesheet(QStringLiteral("CallDurationForm/CallDurationForm.css"))); } +void CallDurationForm::reloadTheme() { + setStyleSheet(Style::getStylesheet(QStringLiteral("CallDurationForm/CallDurationForm.css"))); +} -void CallDurationForm::closeEvent(QCloseEvent *e) {} +void CallDurationForm::closeEvent(QCloseEvent* e) {} void CallDurationForm::onUpdateTime() { - auto time = tr("Call duration: ") + base::secondsToDHMS(timeElapsed.elapsed() / 1000); - ui->duration->setText(time); + auto time = tr("Call duration: ") + base::secondsToDHMS(timeElapsed.elapsed() / 1000); + ui->duration->setText(time); } void CallDurationForm::onCallEnd() { emit endCall(); } void CallDurationForm::onMuteOut() { - muteOut = !muteOut; - ui->micButton->setProperty("state",muteOut?"disabled":""); - emit muteMicrophone(muteOut); - reloadTheme(); + muteOut = !muteOut; + ui->micButton->setProperty("state", muteOut ? "disabled" : ""); + emit muteMicrophone(muteOut); + reloadTheme(); } void CallDurationForm::onMuteIn() { - muteIn = !muteIn; - ui->volButton->setProperty("state", muteIn?"disabled":""); - emit muteSpeaker(muteIn); - reloadTheme(); + muteIn = !muteIn; + ui->volButton->setProperty("state", muteIn ? "disabled" : ""); + emit muteSpeaker(muteIn); + reloadTheme(); } +GenericNetCamView* CallDurationForm::createNetcam() { + qDebug() << __func__ << "..."; -GenericNetCamView *CallDurationForm::createNetcam() { - qDebug() <<__func__<< "..."; - - if(!contact){ - qWarning()<<"contact is no existing!"; - return nullptr; - } + if (!contact) { + qWarning() << "contact is no existing!"; + return nullptr; + } - auto fId = FriendId(contact->getId()); + auto fId = FriendId(contact->getId()); - NetCamView *view = new NetCamView(fId, this); - CoreAV *av = CoreAV::getInstance(); + NetCamView* view = new NetCamView(fId, this); + CoreAV* av = CoreAV::getInstance(); - VideoSource *source = av->getVideoSourceFromCall(fId.getId()); - view->show(source, contact->getDisplayedName()); + VideoSource* source = av->getVideoSourceFromCall(fId.getId()); + view->show(source, contact->getDisplayedName()); - // connect(view, &GenericNetCamView::videoCallEnd, this, - // &ChatForm::onVideoCallTriggered); + // connect(view, &GenericNetCamView::videoCallEnd, this, + // &ChatForm::onVideoCallTriggered); - // connect(view, &GenericNetCamView::volMuteToggle, this, - // &ChatForm::onVolMuteToggle); - // connect(view, &GenericNetCamView::micMuteToggle, this, - // &ChatForm::onMicMuteToggle); + // connect(view, &GenericNetCamView::volMuteToggle, this, + // &ChatForm::onVolMuteToggle); + // connect(view, &GenericNetCamView::micMuteToggle, this, + // &ChatForm::onMicMuteToggle); - connect(view, &GenericNetCamView::videoPreviewToggle, view, - &NetCamView::toggleVideoPreview); - return view; + connect(view, &GenericNetCamView::videoPreviewToggle, view, &NetCamView::toggleVideoPreview); + return view; } void CallDurationForm::showNetcam() { - if (!netcam){ - netcam = createNetcam(); - ui->viewbar->layout()->addWidget(netcam); - } - netcam->show(); + if (!netcam) { + netcam = createNetcam(); + ui->viewbar->layout()->addWidget(netcam); + } + netcam->show(); } void CallDurationForm::hideNetcam() { - if (!netcam) - return; + if (!netcam) return; - ui->viewbar->layout()->removeWidget(netcam); + ui->viewbar->layout()->removeWidget(netcam); - netcam->close(); - netcam->hide(); - delete netcam; - netcam = nullptr; + netcam->close(); + netcam->hide(); + delete netcam; + netcam = nullptr; } void CallDurationForm::showAvatar() { - if(contact){ - auto c = new QLabel(); - c->setFixedSize(86,86); - c->setPixmap(contact->getAvatar().scaled(c->size())); - ui->viewbar->layout()->addWidget(c); - } + if (contact) { + auto c = new QLabel(); + c->setFixedSize(86, 86); + c->setPixmap(contact->getAvatar().scaled(c->size())); + ui->viewbar->layout()->addWidget(c); + } } diff --git a/src/modules/im/src/widget/form/CallDurationForm.h b/src/modules/im/src/widget/form/CallDurationForm.h index 8cba2d3b..b663a0e3 100644 --- a/src/modules/im/src/widget/form/CallDurationForm.h +++ b/src/modules/im/src/widget/form/CallDurationForm.h @@ -5,19 +5,18 @@ #include #include -#include "src/video/genericnetcamview.h" #include +#include "src/video/genericnetcamview.h" namespace Ui { class CallDurationForm; } -class CallDurationForm : public QWidget -{ +class CallDurationForm : public QWidget { Q_OBJECT public: - explicit CallDurationForm(QWidget *parent = nullptr); + explicit CallDurationForm(QWidget* parent = nullptr); ~CallDurationForm(); void setContact(const Contact* c); void reloadTheme(); @@ -27,17 +26,17 @@ class CallDurationForm : public QWidget void hideNetcam(); void showAvatar(); signals: - void endCall(); - void muteMicrophone(bool); - void muteSpeaker(bool); + void endCall(); + void muteMicrophone(bool); + void muteSpeaker(bool); protected: - void closeEvent(QCloseEvent*e ) override; + void closeEvent(QCloseEvent* e) override; private: - Ui::CallDurationForm *ui; - const Contact *contact; - QTimer *callDurationTimer; + Ui::CallDurationForm* ui; + const Contact* contact; + QTimer* callDurationTimer; QElapsedTimer timeElapsed; bool muteOut; @@ -47,10 +46,10 @@ class CallDurationForm : public QWidget private slots: void onUpdateTime(); void onCallEnd(); - //禁止麦克风 + // 禁止麦克风 void onMuteOut(); - //禁止扬声器 + // 禁止扬声器 void onMuteIn(); }; -#endif // CALLDURATTIONFORM_H +#endif // CALLDURATTIONFORM_H diff --git a/src/modules/im/src/widget/form/GroupCreateForm.cpp b/src/modules/im/src/widget/form/GroupCreateForm.cpp index a58b2bd8..4fe70ee4 100644 --- a/src/modules/im/src/widget/form/GroupCreateForm.cpp +++ b/src/modules/im/src/widget/form/GroupCreateForm.cpp @@ -1,25 +1,21 @@ #include "GroupCreateForm.h" #include "ui_GroupCreateForm.h" -GroupCreateForm::GroupCreateForm(QWidget *parent) : - QWidget(parent), - ui(new Ui::GroupCreateForm) -{ +GroupCreateForm::GroupCreateForm(QWidget* parent) : QWidget(parent), ui(new Ui::GroupCreateForm) { ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose, true); setWindowTitle(tr("Create new group")); - connect(ui->confirm, &QPushButton::released, [&](){ + connect(ui->confirm, &QPushButton::released, [&]() { auto name = ui->group->text(); - if(name.trimmed().isEmpty()){ + if (name.trimmed().isEmpty()) { return; } emit confirmed(name); }); } -GroupCreateForm::~GroupCreateForm() -{ +GroupCreateForm::~GroupCreateForm() { disconnect(ui->confirm); delete ui; } diff --git a/src/modules/im/src/widget/form/GroupCreateForm.h b/src/modules/im/src/widget/form/GroupCreateForm.h index d0a434c9..fdedc23e 100644 --- a/src/modules/im/src/widget/form/GroupCreateForm.h +++ b/src/modules/im/src/widget/form/GroupCreateForm.h @@ -7,21 +7,18 @@ namespace Ui { class GroupCreateForm; } -class GroupCreateForm : public QWidget -{ +class GroupCreateForm : public QWidget { Q_OBJECT public: - explicit GroupCreateForm(QWidget *parent = nullptr); + explicit GroupCreateForm(QWidget* parent = nullptr); ~GroupCreateForm(); signals: void confirmed(const QString& groupName); private: - Ui::GroupCreateForm *ui; - - + Ui::GroupCreateForm* ui; }; -#endif // GROUPCREATEFORM_H +#endif // GROUPCREATEFORM_H diff --git a/src/modules/im/src/widget/form/aboutfriendform.cpp b/src/modules/im/src/widget/form/aboutfriendform.cpp index f04654d5..b95304e7 100644 --- a/src/modules/im/src/widget/form/aboutfriendform.cpp +++ b/src/modules/im/src/widget/form/aboutfriendform.cpp @@ -22,18 +22,17 @@ #include #include #include -#include #include +#include #include AboutFriendForm::AboutFriendForm(std::unique_ptr _about, QWidget* parent) - : QWidget(parent) - , ui(new Ui::AboutFriendForm) - , about{std::move(_about)} - , widget{Widget::getInstance()} - , profile{Nexus::getInstance().getProfile()} -{ + : QWidget(parent) + , ui(new Ui::AboutFriendForm) + , about{std::move(_about)} + , widget{Widget::getInstance()} + , profile{Nexus::getInstance().getProfile()} { ui->setupUi(this); setAttribute(Qt::WA_StyledBackground); @@ -42,17 +41,20 @@ AboutFriendForm::AboutFriendForm(std::unique_ptr _about, QWidget* reloadTheme(); connect(ui->sendMessage, &QPushButton::clicked, this, &AboutFriendForm::onSendMessageClicked); - connect(ui->autoacceptfile, &QCheckBox::clicked, this, &AboutFriendForm::onAutoAcceptDirClicked); + connect(ui->autoacceptfile, &QCheckBox::clicked, this, + &AboutFriendForm::onAutoAcceptDirClicked); connect(ui->autoacceptcall, SIGNAL(activated(int)), this, SLOT(onAutoAcceptCallClicked(void))); connect(ui->selectSaveDir, &QPushButton::clicked, this, &AboutFriendForm::onSelectDirClicked); - connect(ui->removeHistory, &QPushButton::clicked, this, &AboutFriendForm::onRemoveHistoryClicked); - about->connectTo_autoAcceptDirChanged(this, [this](const QString& dir){ onAutoAcceptDirChanged(dir); }); + connect(ui->removeHistory, &QPushButton::clicked, this, + &AboutFriendForm::onRemoveHistoryClicked); + about->connectTo_autoAcceptDirChanged( + this, [this](const QString& dir) { onAutoAcceptDirChanged(dir); }); const QString dir = about->getAutoAcceptDir(); ui->autoacceptfile->setChecked(!dir.isEmpty()); -// ui->removeHistory->setEnabled(about->isHistoryExistence()); + // ui->removeHistory->setEnabled(about->isHistoryExistence()); const int index = static_cast(about->getAutoAcceptCall()); ui->autoacceptcall->setCurrentIndex(index); @@ -63,38 +65,34 @@ AboutFriendForm::AboutFriendForm(std::unique_ptr _about, QWidget* ui->selectSaveDir->setText(about->getAutoAcceptDir()); } - ui->id->setText(about->getPublicKey().toString()); ui->statusMessage->setText(about->getStatusMessage()); ui->avatar->setPixmap(about->getAvatar()); ui->userName->setText(about->getName()); - connect(about->getFriend(), &Friend::nameChanged, [&](auto name){ + connect(about->getFriend(), &Friend::nameChanged, [&](auto name) { ui->userName->setText(name); ui->alias->setPlaceholderText(name); }); ui->alias->setText(about->getAlias()); ui->alias->setPlaceholderText(about->getName()); - connect(about->getFriend(), &Contact::aliasChanged, [&](auto alias){ - ui->alias->setText(alias); - }); + connect(about->getFriend(), &Contact::aliasChanged, + [&](auto alias) { ui->alias->setText(alias); }); connect(ui->alias, &QLineEdit::textChanged, this, &AboutFriendForm::onAliasChanged); connect(&GUI::getInstance(), &GUI::themeApplyRequest, this, &AboutFriendForm::reloadTheme); } -static QString getAutoAcceptDir(const QString& dir) -{ +static QString getAutoAcceptDir(const QString& dir) { //: popup title const QString title = AboutFriendForm::tr("Choose an auto accept directory"); return QFileDialog::getExistingDirectory(Q_NULLPTR, title, dir); } -void AboutFriendForm::onAutoAcceptDirClicked() -{ - const QString dir = [&]{ +void AboutFriendForm::onAutoAcceptDirClicked() { + const QString dir = [&] { if (!ui->autoacceptfile->isChecked()) { return QString{}; } @@ -105,24 +103,20 @@ void AboutFriendForm::onAutoAcceptDirClicked() about->setAutoAcceptDir(dir); } -void AboutFriendForm::onAutoAcceptDirChanged(const QString& path) -{ +void AboutFriendForm::onAutoAcceptDirChanged(const QString& path) { const bool enabled = !path.isNull(); ui->autoacceptfile->setChecked(enabled); ui->selectSaveDir->setEnabled(enabled); ui->selectSaveDir->setText(enabled ? path : tr("Auto accept for this contact is disabled")); } - -void AboutFriendForm::onAutoAcceptCallClicked() -{ +void AboutFriendForm::onAutoAcceptCallClicked() { const int index = ui->autoacceptcall->currentIndex(); const IFriendSettings::AutoAcceptCallFlags flag{index}; about->setAutoAcceptCall(flag); } -void AboutFriendForm::onSelectDirClicked() -{ +void AboutFriendForm::onSelectDirClicked() { const QString dir = getAutoAcceptDir(about->getAutoAcceptDir()); about->setAutoAcceptDir(dir); } @@ -130,54 +124,45 @@ void AboutFriendForm::onSelectDirClicked() /** * @brief Called when user clicks the bottom OK button, save all settings */ -void AboutFriendForm::onSendMessageClicked() -{ +void AboutFriendForm::onSendMessageClicked() { auto w = Widget::getInstance(); emit w->toSendMessage(ui->id->text()); } -void AboutFriendForm::onRemoveHistoryClicked() -{ - const bool retYes = GUI::askQuestion(tr("Confirmation"), - tr("Are you sure to remove %1 chat history?").arg(about->getName()), - /* defaultAns = */ false, /* warning = */ true, /* yesno = */ true); +void AboutFriendForm::onRemoveHistoryClicked() { + const bool retYes = GUI::askQuestion( + tr("Confirmation"), tr("Are you sure to remove %1 chat history?").arg(about->getName()), + /* defaultAns = */ false, /* warning = */ true, /* yesno = */ true); if (!retYes) { return; } - auto w = Widget::getInstance(); emit w->toClearHistory(ui->id->text()); -// const bool result = about->clearHistory(); -// if (!result) { -// GUI::showWarning(tr("History removed"), -// tr("Failed to remove chat history with %1!").arg(about->getName()).toHtmlEscaped()); -// return; -// } -// emit histroyRemoved(); -// ui->removeHistory->setEnabled(false); // For know clearly to has removed the history + // const bool result = about->clearHistory(); + // if (!result) { + // GUI::showWarning(tr("History removed"), + // tr("Failed to remove chat history with + // %1!").arg(about->getName()).toHtmlEscaped()); + // return; + // } + // emit histroyRemoved(); + // ui->removeHistory->setEnabled(false); // For know clearly to has removed the history } -AboutFriendForm::~AboutFriendForm() -{ +AboutFriendForm::~AboutFriendForm() { qDebug() << __func__; delete ui; } -void AboutFriendForm::setName(const QString &name) -{ - ui->userName->setText(name); -} +void AboutFriendForm::setName(const QString& name) { ui->userName->setText(name); } -void AboutFriendForm::reloadTheme() -{ +void AboutFriendForm::reloadTheme() { setStyleSheet(Style::getStylesheet("window/aboutFriend.css")); } -void AboutFriendForm::onAliasChanged(const QString &text) -{ - +void AboutFriendForm::onAliasChanged(const QString& text) { auto fid = ui->id->text(); auto f = FriendList::findFriend(ContactId(fid)); diff --git a/src/modules/im/src/widget/form/aboutfriendform.h b/src/modules/im/src/widget/form/aboutfriendform.h index a40e4e08..efe91d18 100644 --- a/src/modules/im/src/widget/form/aboutfriendform.h +++ b/src/modules/im/src/widget/form/aboutfriendform.h @@ -27,22 +27,21 @@ class AboutFriendForm; class Widget; class Profile; -class AboutFriendForm : public QWidget -{ +class AboutFriendForm : public QWidget { Q_OBJECT public: AboutFriendForm(std::unique_ptr about, QWidget* parent = nullptr); ~AboutFriendForm(); - void setName(const QString &name); + void setName(const QString& name); private: void reloadTheme(); Ui::AboutFriendForm* ui; const std::unique_ptr about; - Widget *widget; - Profile *profile; + Widget* widget; + Profile* profile; signals: void histroyRemoved(); @@ -56,4 +55,4 @@ private slots: void onRemoveHistoryClicked(); }; -#endif // ABOUT_USER_FORM_H +#endif // ABOUT_USER_FORM_H diff --git a/src/modules/im/src/widget/form/aboutgroupform.cpp b/src/modules/im/src/widget/form/aboutgroupform.cpp index cc9d5b2b..a4448c82 100644 --- a/src/modules/im/src/widget/form/aboutgroupform.cpp +++ b/src/modules/im/src/widget/form/aboutgroupform.cpp @@ -1,19 +1,18 @@ #include "aboutgroupform.h" - +#include #include -#include "ui_aboutgroupform.h" #include "src/grouplist.h" #include "src/model/group.h" -#include "src/widget/widget.h" -#include #include "src/persistence/profile.h" +#include "src/widget/widget.h" +#include "ui_aboutgroupform.h" -AboutGroupForm::AboutGroupForm(const GroupId& groupId_, QWidget *parent) : - QWidget(parent), - ui(new Ui::AboutGroupForm), - groupId{groupId_}, group{GroupList::findGroup(groupId_)} -{ +AboutGroupForm::AboutGroupForm(const GroupId& groupId_, QWidget* parent) + : QWidget(parent) + , ui(new Ui::AboutGroupForm) + , groupId{groupId_} + , group{GroupList::findGroup(groupId_)} { ui->setupUi(this); ui->id->setText(group->getId()); @@ -21,53 +20,48 @@ AboutGroupForm::AboutGroupForm(const GroupId& groupId_, QWidget *parent) : ui->avatar->setPixmap(group->getAvatar()); ui->desc->setText(group->getDesc()); - connect(ui->desc, &QLineEdit::textChanged, this, &AboutGroupForm::doDescChanged); + connect(ui->desc, &QLineEdit::textChanged, this, &AboutGroupForm::doDescChanged); - connect(group, &Group::descChanged, [&](auto desc){ - ui->desc->setText(desc); - }); + connect(group, &Group::descChanged, [&](auto desc) { ui->desc->setText(desc); }); - //不可变(只接收来自服务器修改的推送) + // 不可变(只接收来自服务器修改的推送) ui->groupName->setText(group->getName()); - connect(group, &Group::nameChanged , this, [&](const QString& name){ + connect(group, &Group::nameChanged, this, [&](const QString& name) { ui->groupName->setText(name); ui->name->setText(name); }); - //名称 + // 名称 ui->name->setText(group->getName()); connect(ui->name, &QLineEdit::textChanged, this, &AboutGroupForm::doNameChanged); - //备注名 + // 备注名 ui->alias->setText(group->getDisplayedName()); connect(ui->alias, &QLineEdit::textChanged, this, &AboutGroupForm::doAliasChanged); - //主题 - connect(ui->notice, &QLineEdit::textChanged, this, &AboutGroupForm::doSubjectChanged); + // 主题 + connect(ui->notice, &QLineEdit::textChanged, this, &AboutGroupForm::doSubjectChanged); ui->subject->setText(group->getSubject()); - connect(group, &Group::subjectChanged , this, [&](const QString& name){ - ui->subject->setText(name); - }); + connect(group, &Group::subjectChanged, this, + [&](const QString& name) { ui->subject->setText(name); }); - connect(group, &Group::subjectChanged, this, [&](const QString& author,const QString &title){ - ui->subject->setText(title); - }); - connect(group, &Group::peerCountChanged, this, [&](uint32_t count){ - ui->occupants->setText(QString::number(count)); - }); + connect(group, &Group::subjectChanged, this, + [&](const QString& author, const QString& title) { ui->subject->setText(title); }); + connect(group, &Group::peerCountChanged, this, + [&](uint32_t count) { ui->occupants->setText(QString::number(count)); }); - connect(group, &Group::descChanged, this, [&](const QString& desc){ - ui->desc->setText(desc); - }); + connect(group, &Group::descChanged, this, + [&](const QString& desc) { ui->desc->setText(desc); }); - connect(group, &Group::privilegesChanged, this, [&](const Group::Role &role, const Group::Affiliation &aff, const QList codes){ - updateUI(); - }); + connect(group, &Group::privilegesChanged, this, + [&](const Group::Role& role, const Group::Affiliation& aff, const QList codes) { + updateUI(); + }); connect(ui->sendMessage, &QPushButton::clicked, this, &AboutGroupForm::onSendMessageClicked); auto map = group->getPeerList(); - for(auto peer : map){ + for (auto peer : map) { auto f = new QLabel(peer); ui->friendListLayout->addWidget(f); } @@ -75,71 +69,61 @@ AboutGroupForm::AboutGroupForm(const GroupId& groupId_, QWidget *parent) : updateUI(); } -AboutGroupForm::~AboutGroupForm() -{ - delete ui; -} +AboutGroupForm::~AboutGroupForm() { delete ui; } -void AboutGroupForm::updateUI() -{ - auto role= group->getRole(); - if(role >= Group::Role::Participant){ +void AboutGroupForm::updateUI() { + auto role = group->getRole(); + if (role >= Group::Role::Participant) { ui->subject->setEnabled(true); - }else{ + } else { ui->subject->setDisabled(true); } auto aff = group->getAffiliation(); - if(aff == Group::Affiliation::Owner){ - //https://xmpp.org/extensions/xep-0045.html#table-6 - //具有权限:“Change Room Configuration”, - //涉及字段:https://xmpp.org/extensions/xep-0045.html#registrar-formtype-owner + if (aff == Group::Affiliation::Owner) { + // https://xmpp.org/extensions/xep-0045.html#table-6 + // 具有权限:“Change Room Configuration”, + // 涉及字段:https://xmpp.org/extensions/xep-0045.html#registrar-formtype-owner ui->name->setEnabled(true); ui->desc->setEnabled(true); ui->subject->setEnabled(true); - }else{ + } else { ui->name->setEnabled(false); ui->desc->setEnabled(false); ui->subject->setEnabled(false); } } -void AboutGroupForm::onSendMessageClicked() -{ +void AboutGroupForm::onSendMessageClicked() { auto widget = Widget::getInstance(); - if(widget){ - qDebug() <<"toSendMessage:"<< ui->id->text(); - emit widget->toSendMessage(ui->id->text(), true); + if (widget) { + qDebug() << "toSendMessage:" << ui->id->text(); + emit widget->toSendMessage(ui->id->text(), true); } } -void AboutGroupForm::doNameChanged(const QString &text) -{ +void AboutGroupForm::doNameChanged(const QString& text) { qDebug() << __func__ << text; group->setName(text); Core::getInstance()->setGroupName(groupId.toString(), text); } -void AboutGroupForm::doAliasChanged(const QString &text) -{ +void AboutGroupForm::doAliasChanged(const QString& text) { qDebug() << __func__ << text; -// auto profile = Nexus::getInstance().getProfile(); -// profile->saveFriendAlias(groupId.toString(), text); + // auto profile = Nexus::getInstance().getProfile(); + // profile->saveFriendAlias(groupId.toString(), text); group->setAlias(text); Core::getInstance()->setGroupAlias(groupId.toString(), text); } -void AboutGroupForm::doSubjectChanged(const QString &text) -{ +void AboutGroupForm::doSubjectChanged(const QString& text) { qDebug() << __func__ << text; group->setSubject({}, text); Core::getInstance()->setGroupSubject(groupId.toString(), text); } -void AboutGroupForm::doDescChanged(const QString &text) -{ +void AboutGroupForm::doDescChanged(const QString& text) { qDebug() << __func__ << text; group->setDesc(text); Core::getInstance()->setGroupDesc(groupId.toString(), text); - } diff --git a/src/modules/im/src/widget/form/aboutgroupform.h b/src/modules/im/src/widget/form/aboutgroupform.h index a44eab3d..9b2f2886 100644 --- a/src/modules/im/src/widget/form/aboutgroupform.h +++ b/src/modules/im/src/widget/form/aboutgroupform.h @@ -8,22 +8,20 @@ namespace Ui { class AboutGroupForm; } -class AboutGroupForm : public QWidget -{ +class AboutGroupForm : public QWidget { Q_OBJECT public: - explicit AboutGroupForm(const GroupId & gId, QWidget *parent = nullptr); + explicit AboutGroupForm(const GroupId& gId, QWidget* parent = nullptr); ~AboutGroupForm(); void init(); void updateUI(); private: - - Ui::AboutGroupForm *ui; + Ui::AboutGroupForm* ui; GroupId groupId; - Group* group; + Group* group; private slots: void onSendMessageClicked(); @@ -33,4 +31,4 @@ private slots: void doDescChanged(const QString& text); }; -#endif // ABOUTGROUPFORM_H +#endif // ABOUTGROUPFORM_H diff --git a/src/modules/im/src/widget/form/addfriendform.cpp b/src/modules/im/src/widget/form/addfriendform.cpp index 40b09b5e..35e1d304 100644 --- a/src/modules/im/src/widget/form/addfriendform.cpp +++ b/src/modules/im/src/widget/form/addfriendform.cpp @@ -11,6 +11,18 @@ */ #include "addfriendform.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "application.h" #include "friendform.h" #include "lib/backend/UserService.h" #include "lib/session/AuthSession.h" @@ -23,174 +35,164 @@ #include "src/widget/gui.h" #include "src/widget/tool/croppinglabel.h" #include "ui_addfriendform.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include namespace { -QString getToxId(const QString &id) { return id.trimmed(); } +QString getToxId(const QString& id) { return id.trimmed(); } -} // namespace +} // namespace /** * @var QString AddFriendForm::lastUsername * @brief Cached username so we can retranslate the invite message */ -AddFriendForm::AddFriendForm(QWidget *parent) : QWidget(parent), addUi{new Ui::AddFriendForm} { +AddFriendForm::AddFriendForm(QWidget* parent) : QWidget(parent), addUi{new Ui::AddFriendForm} { + setAttribute(Qt::WA_StyledBackground); + setLayout(new QGridLayout); + layout()->setMargin(0); + layout()->setSpacing(0); - setAttribute(Qt::WA_StyledBackground); - setLayout(new QGridLayout); - layout()->setMargin(0); - layout()->setSpacing(0); + tabWidget = new QTabWidget(this); + layout()->addWidget(tabWidget); - tabWidget = new QTabWidget(this); - layout()->addWidget(tabWidget); + main = new QWidget(tabWidget); + addUi->setupUi(main); - main = new QWidget(tabWidget); - addUi->setupUi(main); + connect(addUi->search, &QPushButton::clicked, this, &AddFriendForm::onSearchTriggered); - connect(addUi->search, &QPushButton::clicked, this, &AddFriendForm::onSearchTriggered); + connect(this, &AddFriendForm::friendReceipts, this, &AddFriendForm::onFriendReceipts); - connect(this, &AddFriendForm::friendReceipts, this, &AddFriendForm::onFriendReceipts); + friendLayout = new QVBoxLayout(main); + friendLayout->setAlignment(Qt::AlignTop); - friendLayout = new QVBoxLayout(main); - friendLayout->setAlignment(Qt::AlignTop); + addUi->scrollArea->widget()->setLayout(friendLayout); - addUi->scrollArea->widget()->setLayout(friendLayout); + tabWidget->addTab(main, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); - tabWidget->addTab(main, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); + // accessibility stuff + addUi->input->setPlaceholderText(tr("Account/E-Mail/Phone Number")); - // accessibility stuff - addUi->input->setPlaceholderText(tr("Account/E-Mail/Phone Number")); + retranslateUi(); + settings::Translator::registerHandler(std::bind(&AddFriendForm::retranslateUi, this), this); - retranslateUi(); - settings::Translator::registerHandler(std::bind(&AddFriendForm::retranslateUi, this), this); - - signIn = &ok::session::AuthSession::Instance()->getSignInInfo(); - userService = std::make_unique(signIn->stackUrl); + auto _session = ok::Application::Instance()->getSession(); + signIn = &_session->getSignInInfo(); + userService = std::make_unique(signIn->stackUrl); } AddFriendForm::~AddFriendForm() { - settings::Translator::unregister(this); - delete addUi; + settings::Translator::unregister(this); + delete addUi; } bool AddFriendForm::isShown() const { return true; } -void AddFriendForm::showTo(ContentLayout *contentLayout) { - // contentLayout->mainContent->layout()->addWidget(tabWidget); - // contentLayout->mainHead->layout()->addWidget(head); - // tabWidget->show(); +void AddFriendForm::showTo(ContentLayout* contentLayout) { + // contentLayout->mainContent->layout()->addWidget(tabWidget); + // contentLayout->mainHead->layout()->addWidget(head); + // tabWidget->show(); - // setIdFromClipboard(); - // toxId.setFocus(); + // setIdFromClipboard(); + // toxId.setFocus(); - // Fix #3421 - // Needed to update tab after opening window - const int index = tabWidget->currentIndex(); - onCurrentChanged(index); + // Fix #3421 + // Needed to update tab after opening window + const int index = tabWidget->currentIndex(); + onCurrentChanged(index); - int idx = contentLayout->addWidget(this); - contentLayout->setCurrentIndex(idx); + int idx = contentLayout->addWidget(this); + contentLayout->setCurrentIndex(idx); } QString AddFriendForm::getMessage() { - // message.setPlaceholderText(tr("%1 here! OkEDU me maybe?").arg(Core::getInstance()->getNick())); - // const QString msg = message.toPlainText(); - // return !msg.isEmpty() ? msg : message.placeholderText(); - return tr("hello,I'm ") + Core::getInstance()->getNick(); + // message.setPlaceholderText(tr("%1 here! OkEDU me + // maybe?").arg(Core::getInstance()->getNick())); const QString msg = message.toPlainText(); + // return !msg.isEmpty() ? msg : message.placeholderText(); + return tr("hello,I'm ") + Core::getInstance()->getNick(); } -void AddFriendForm::onUsernameSet(const QString &username) { lastUsername = username; } +void AddFriendForm::onUsernameSet(const QString& username) { lastUsername = username; } -void AddFriendForm::showEvent(QShowEvent *e) { - // onSearchTriggered(); +void AddFriendForm::showEvent(QShowEvent* e) { + // onSearchTriggered(); } -void AddFriendForm::onFriendReceipts(const QList &qList) { - // auto friendLayout = addUi->scrollAreaWidgetContents; - qDebug() << "Exist friends:" << friendLayout->count(); - - while (friendLayout->count() > 0) { - auto w = friendLayout->itemAt(0)->widget(); - friendLayout->removeWidget(w); - disconnect(w); - delete w; - } - - for (auto item : qList) { - if (item->username.isEmpty()){ - qWarning() << item->name<<" have not username!"; - continue; +void AddFriendForm::onFriendReceipts(const QList& qList) { + // auto friendLayout = addUi->scrollAreaWidgetContents; + qDebug() << "Exist friends:" << friendLayout->count(); + + while (friendLayout->count() > 0) { + auto w = friendLayout->itemAt(0)->widget(); + friendLayout->removeWidget(w); + disconnect(w); + delete w; } - item->host = signIn->host; - auto form = new FriendForm(*item); - friendLayout->addWidget(form); - connect(form, &FriendForm::add, [&](const QString &username, QString &nick) { - qDebug() << "Send request to" << username; - addFriend(username, nick); - }); - } + for (auto item : qList) { + if (item->username.isEmpty()) { + qWarning() << item->name << " have not username!"; + continue; + } + + item->host = signIn->host; + auto form = new FriendForm(*item); + friendLayout->addWidget(form); + connect(form, &FriendForm::add, [&](const QString& username, QString& nick) { + qDebug() << "Send request to" << username; + addFriend(username, nick); + }); + } } -void AddFriendForm::searchFriend(const QString &idText) { - qDebug() << "searchFriend" << idText; - // 查询账号信息 - userService->search(idText, [this](const QList &qList) { emit friendReceipts(qList); }); +void AddFriendForm::searchFriend(const QString& idText) { + qDebug() << "searchFriend" << idText; + // 查询账号信息 + userService->search(idText, [this](const QList& qList) { + emit friendReceipts(qList); + }); } -void AddFriendForm::addFriend(const QString &idText, const QString &nick) { - qDebug() << "addFriend" << idText << nick; - FriendId friendId(idText); - if (!friendId.isValid()) { - GUI::showWarning(tr("Couldn't add friend"), tr("%1 Ok ID is invalid", "Tox address error").arg(idText)); - return; - } - - if (friendId == Core::getInstance()->getSelfId()) { - // When trying to add your own Ok ID as friend - GUI::showWarning(tr("Couldn't add friend"), tr("You can't add yourself as a friend!")); - return; - } - - auto msg = getMessage(); - emit friendRequested(friendId, nick, msg); +void AddFriendForm::addFriend(const QString& idText, const QString& nick) { + qDebug() << "addFriend" << idText << nick; + FriendId friendId(idText); + if (!friendId.isValid()) { + GUI::showWarning(tr("Couldn't add friend"), + tr("%1 Ok ID is invalid", "Tox address error").arg(idText)); + return; + } + + if (friendId == Core::getInstance()->getSelfId()) { + // When trying to add your own Ok ID as friend + GUI::showWarning(tr("Couldn't add friend"), tr("You can't add yourself as a friend!")); + return; + } + + auto msg = getMessage(); + emit friendRequested(friendId, nick, msg); } void AddFriendForm::onSearchTriggered() { - const QString id = addUi->input->text(); - searchFriend(id); + const QString id = addUi->input->text(); + searchFriend(id); - // this->toxId.clear(); - // this->message.clear(); + // this->toxId.clear(); + // this->message.clear(); } void AddFriendForm::setIdFromClipboard() { - const QClipboard *clipboard = QApplication::clipboard(); - const QString trimmedId = clipboard->text().trimmed(); - const QString strippedId = getToxId(trimmedId); - const Core *core = Core::getInstance(); - const bool isSelf = ToxId::isToxId(strippedId) && ToxId(strippedId) != core->getSelfPeerId(); - if (!strippedId.isEmpty() && ToxId::isToxId(strippedId) && isSelf) { - // toxId.setText(trimmedId); - } + const QClipboard* clipboard = QApplication::clipboard(); + const QString trimmedId = clipboard->text().trimmed(); + const QString strippedId = getToxId(trimmedId); + const Core* core = Core::getInstance(); + const bool isSelf = ToxId::isToxId(strippedId) && ToxId(strippedId) != core->getSelfPeerId(); + if (!strippedId.isEmpty() && ToxId::isToxId(strippedId) && isSelf) { + // toxId.setText(trimmedId); + } } -void AddFriendForm::onCurrentChanged(int index) { - -} +void AddFriendForm::onCurrentChanged(int index) {} void AddFriendForm::retranslateUi() { - searchButton.setText(tr("Search users")); - tabWidget->setTabText(0, tr("Add a friend")); + searchButton.setText(tr("Search users")); + tabWidget->setTabText(0, tr("Add a friend")); } diff --git a/src/modules/im/src/widget/form/addfriendform.h b/src/modules/im/src/widget/form/addfriendform.h index d8ebdd0b..ecc4c0ff 100644 --- a/src/modules/im/src/widget/form/addfriendform.h +++ b/src/modules/im/src/widget/form/addfriendform.h @@ -36,71 +36,69 @@ class AddFriendForm; namespace ok::backend { class UserService; struct OrgStaff; -} // namespace ok::backend +} // namespace ok::backend namespace ok::session { class SignInInfo; } class AddFriendForm : public QWidget { - Q_OBJECT + Q_OBJECT public: + AddFriendForm(QWidget* parent); + ~AddFriendForm(); + bool isShown() const; + void showTo(ContentLayout* contentLayout); - AddFriendForm(QWidget *parent); - ~AddFriendForm(); - - bool isShown() const; - void showTo(ContentLayout *contentLayout); - - - bool addFriendRequest(const QString &friendAddress, const QString &message); + bool addFriendRequest(const QString& friendAddress, const QString& message); signals: - void friendRequested(const FriendId &friendAddress, const QString &nick, const QString &message); - void friendRequestAccepted(const FriendId &friendAddress); - void friendRequestRejected(const FriendId &friendAddress); - void friendRequestsSeen(); - void friendReceipts(const QList &qList); + void friendRequested(const FriendId& friendAddress, const QString& nick, + const QString& message); + void friendRequestAccepted(const FriendId& friendAddress); + void friendRequestRejected(const FriendId& friendAddress); + void friendRequestsSeen(); + void friendReceipts(const QList& qList); public slots: - void onUsernameSet(const QString &userName); + void onUsernameSet(const QString& userName); protected: - virtual void showEvent(QShowEvent *e) override; + virtual void showEvent(QShowEvent* e) override; private slots: - void onSearchTriggered(); - void onCurrentChanged(int index); - void onFriendReceipts(const QList &qList); + void onSearchTriggered(); + void onCurrentChanged(int index); + void onFriendReceipts(const QList& qList); private: - void searchFriend(const QString &idText); - void addFriend(const QString &idText, const QString &nick); - void retranslateUi(); + void searchFriend(const QString& idText); + void addFriend(const QString& idText, const QString& nick); + void retranslateUi(); - void setIdFromClipboard(); - QString getMessage(); + void setIdFromClipboard(); + QString getMessage(); - Ui::AddFriendForm *addUi; + Ui::AddFriendForm* addUi; - QLabel messageLabel; + QLabel messageLabel; - QVBoxLayout *friendLayout; + QVBoxLayout* friendLayout; - QPushButton searchButton; - QScrollArea friendArea; + QPushButton searchButton; + QScrollArea friendArea; - QWidget *main; + QWidget* main; - QString lastUsername; - QTabWidget *tabWidget; - QVBoxLayout *requestsLayout; - QList acceptButtons; - QList rejectButtons; + QString lastUsername; + QTabWidget* tabWidget; + QVBoxLayout* requestsLayout; + QList acceptButtons; + QList rejectButtons; - const ok::session::SignInInfo *signIn; - std::unique_ptr userService; + const ok::session::SignInInfo* signIn; + std::unique_ptr userService; }; -#endif // ADDFRIENDFORM_H +#endif // ADDFRIENDFORM_H diff --git a/src/modules/im/src/widget/form/chatform.cpp b/src/modules/im/src/widget/form/chatform.cpp index 3f164c01..1772f5ed 100644 --- a/src/modules/im/src/widget/form/chatform.cpp +++ b/src/modules/im/src/widget/form/chatform.cpp @@ -30,7 +30,7 @@ #include "src/widget/chatformheader.h" #include "src/widget/form/loadhistorydialog.h" #include "src/widget/maskablepixmapwidget.h" -//#include "src/widget/searchform.h" +// #include "src/widget/searchform.h" #include "lib/settings/translator.h" #include "src/lib/settings/style.h" #include "src/widget/tool/callconfirmwidget.h" @@ -67,355 +67,323 @@ static constexpr int TYPING_NOTIFICATION_DURATION = 3000; const QString ChatForm::ACTION_PREFIX = QStringLiteral("/me "); - - -ChatForm::ChatForm(const FriendId *chatFriend, - IChatLog &chatLog_, - IMessageDispatcher &messageDispatcher) - : GenericChatForm(chatFriend, chatLog_, messageDispatcher), - f(chatFriend), isTyping{false}{ - - -// headWidget->setAvatar(QPixmap(":/img/contact_dark.svg")); - - statusMessageLabel = new CroppingLabel(); - statusMessageLabel->setObjectName("statusLabel"); - statusMessageLabel->setFont(Style::getFont(Style::Medium)); - statusMessageLabel->setMinimumHeight(Style::getFont(Style::Medium).pixelSize()); - statusMessageLabel->setTextFormat(Qt::PlainText); - statusMessageLabel->setContextMenuPolicy(Qt::CustomContextMenu); - - typingTimer.setSingleShot(true); - - - - chatLog->setTypingNotification(ChatMessage::createTypingNotification()); - chatLog->setMinimumHeight(CHAT_WIDGET_MIN_HEIGHT); - -// headWidget->addWidget(statusMessageLabel); -// headWidget->addStretch(); -// headWidget->addWidget(callDuration, 1, Qt::AlignCenter); - - copyStatusAction = - statusMessageMenu.addAction(QString(), this, SLOT(onCopyStatusMessage())); - -// const Core *core = Core::getInstance(); -// const Profile *profile = Nexus::getProfile(); -// const CoreFile *coreFile = core->getCoreFile(); -// connect(profile, &Profile::friendAvatarChanged, this, -// &ChatForm::onAvatarChanged); -// connect(coreFile, &CoreFile::fileReceiveRequested, this, -// &ChatForm::updateFriendActivityForFile); -// connect(coreFile, &CoreFile::fileSendStarted, this, -// &ChatForm::updateFriendActivityForFile); - - -// connect(coreFile, &CoreFile::fileNameChanged, this, -// &ChatForm::onFileNameChanged); - - - - -// connect(headWidget, &ChatFormHeader::micMuteToggle, this, -// &ChatForm::onMicMuteToggle); -// connect(headWidget, &ChatFormHeader::volMuteToggle, this, -// &ChatForm::onVolMuteToggle); - - connect(sendButton, &QPushButton::pressed, this, - &ChatForm::callUpdateFriendActivity); - connect(msgEdit, &ChatTextEdit::enterPressed, this, - &ChatForm::callUpdateFriendActivity); - connect(msgEdit, &ChatTextEdit::textChanged, this, - &ChatForm::onTextEditChanged); - connect(msgEdit, &ChatTextEdit::pasteImage, this, &ChatForm::sendImage); - connect(statusMessageLabel, &CroppingLabel::customContextMenuRequested, this, - [&](const QPoint &pos) { - if (!statusMessageLabel->text().isEmpty()) { - QWidget *sender = static_cast(this->sender()); - statusMessageMenu.exec(sender->mapToGlobal(pos)); - } - }); - - connect(&typingTimer, &QTimer::timeout, this, [this] { - Core::getInstance()->sendTyping(f->toString(), false); - isTyping = false; - }); - - setAcceptDrops(true); - retranslateUi(); - settings::Translator::registerHandler(std::bind(&ChatForm::retranslateUi, this), this); +ChatForm::ChatForm(const FriendId* chatFriend, + IChatLog& chatLog_, + IMessageDispatcher& messageDispatcher) + : GenericChatForm(chatFriend, chatLog_, messageDispatcher), f(chatFriend), isTyping{false} { + // headWidget->setAvatar(QPixmap(":/img/contact_dark.svg")); + + statusMessageLabel = new CroppingLabel(); + statusMessageLabel->setObjectName("statusLabel"); + statusMessageLabel->setFont(Style::getFont(Style::Medium)); + statusMessageLabel->setMinimumHeight(Style::getFont(Style::Medium).pixelSize()); + statusMessageLabel->setTextFormat(Qt::PlainText); + statusMessageLabel->setContextMenuPolicy(Qt::CustomContextMenu); + + typingTimer.setSingleShot(true); + + chatLog->setTypingNotification(ChatMessage::createTypingNotification()); + chatLog->setMinimumHeight(CHAT_WIDGET_MIN_HEIGHT); + + // headWidget->addWidget(statusMessageLabel); + // headWidget->addStretch(); + // headWidget->addWidget(callDuration, 1, Qt::AlignCenter); + + copyStatusAction = statusMessageMenu.addAction(QString(), this, SLOT(onCopyStatusMessage())); + + // const Core *core = Core::getInstance(); + // const Profile *profile = Nexus::getProfile(); + // const CoreFile *coreFile = core->getCoreFile(); + // connect(profile, &Profile::friendAvatarChanged, this, + // &ChatForm::onAvatarChanged); + // connect(coreFile, &CoreFile::fileReceiveRequested, this, + // &ChatForm::updateFriendActivityForFile); + // connect(coreFile, &CoreFile::fileSendStarted, this, + // &ChatForm::updateFriendActivityForFile); + + // connect(coreFile, &CoreFile::fileNameChanged, this, + // &ChatForm::onFileNameChanged); + + // connect(headWidget, &ChatFormHeader::micMuteToggle, this, + // &ChatForm::onMicMuteToggle); + // connect(headWidget, &ChatFormHeader::volMuteToggle, this, + // &ChatForm::onVolMuteToggle); + + connect(sendButton, &QPushButton::pressed, this, &ChatForm::callUpdateFriendActivity); + connect(msgEdit, &ChatTextEdit::enterPressed, this, &ChatForm::callUpdateFriendActivity); + connect(msgEdit, &ChatTextEdit::textChanged, this, &ChatForm::onTextEditChanged); + connect(msgEdit, &ChatTextEdit::pasteImage, this, &ChatForm::sendImage); + connect(statusMessageLabel, &CroppingLabel::customContextMenuRequested, this, + [&](const QPoint& pos) { + if (!statusMessageLabel->text().isEmpty()) { + QWidget* sender = static_cast(this->sender()); + statusMessageMenu.exec(sender->mapToGlobal(pos)); + } + }); + + connect(&typingTimer, &QTimer::timeout, this, [this] { + Core::getInstance()->sendTyping(f->toString(), false); + isTyping = false; + }); + + setAcceptDrops(true); + retranslateUi(); + settings::Translator::registerHandler(std::bind(&ChatForm::retranslateUi, this), this); } -ChatForm::~ChatForm() { - settings::Translator::unregister(this); -} +ChatForm::~ChatForm() { settings::Translator::unregister(this); } -void ChatForm::setStatusMessage(const QString &newMessage) { - statusMessageLabel->setText(newMessage); - // for long messsages - statusMessageLabel->setToolTip( - Qt::convertFromPlainText(newMessage, Qt::WhiteSpaceNormal)); +void ChatForm::setStatusMessage(const QString& newMessage) { + statusMessageLabel->setText(newMessage); + // for long messsages + statusMessageLabel->setToolTip(Qt::convertFromPlainText(newMessage, Qt::WhiteSpaceNormal)); } void ChatForm::callUpdateFriendActivity() { emit updateFriendActivity(*f); } -void ChatForm::updateFriendActivityForFile(const ToxFile &file) { - if (file.receiver != f->getId()) { - return; - } - emit updateFriendActivity(*f); +void ChatForm::updateFriendActivityForFile(const ToxFile& file) { + if (file.receiver != f->getId()) { + return; + } + emit updateFriendActivity(*f); } -void ChatForm::onFileNameChanged(const FriendId &friendPk) { - if (friendPk != *f) { - return; - } +void ChatForm::onFileNameChanged(const FriendId& friendPk) { + if (friendPk != *f) { + return; + } - QMessageBox::warning(this, tr("Filename contained illegal characters"), - tr("Illegal characters have been changed to _ \n" - "so you can save the file on windows.")); + QMessageBox::warning(this, tr("Filename contained illegal characters"), + tr("Illegal characters have been changed to _ \n" + "so you can save the file on windows.")); } void ChatForm::onTextEditChanged() { - if (!Settings::getInstance().getTypingNotification()) { - if (isTyping) { - isTyping = false; - Core::getInstance()->sendTyping(f->getId(), false); - } + if (!Settings::getInstance().getTypingNotification()) { + if (isTyping) { + isTyping = false; + Core::getInstance()->sendTyping(f->getId(), false); + } - return; - } - bool isTypingNow = !msgEdit->toPlainText().isEmpty(); - if (isTyping != isTypingNow) { - Core::getInstance()->sendTyping(f->getId(), isTypingNow); - if (isTypingNow) { - typingTimer.start(TYPING_NOTIFICATION_DURATION); + return; + } + bool isTypingNow = !msgEdit->toPlainText().isEmpty(); + if (isTyping != isTypingNow) { + Core::getInstance()->sendTyping(f->getId(), isTypingNow); + if (isTypingNow) { + typingTimer.start(TYPING_NOTIFICATION_DURATION); + } + + isTyping = isTypingNow; } - - isTyping = isTypingNow; - } } void ChatForm::onAttachClicked() { - qDebug() <<__func__; - - QStringList paths = QFileDialog::getOpenFileNames( - Q_NULLPTR, tr("Send a file"), QDir::homePath(), nullptr, nullptr); - - if (paths.isEmpty()) { - return; - } - - Core *core = Core::getInstance(); - for (QString path : paths) { - QFile file(path); - QString fileName = QFileInfo(path).fileName(); - if (!file.exists() || !file.open(QIODevice::ReadOnly)) { - QMessageBox::warning(this, tr("Unable to open"), - tr("Wasn't able to open %1").arg(fileName)); - continue; - } + qDebug() << __func__; + + QStringList paths = QFileDialog::getOpenFileNames(Q_NULLPTR, tr("Send a file"), + QDir::homePath(), nullptr, nullptr); - file.close(); - if (file.isSequential()) { - QMessageBox::critical(this, tr("Bad idea"), - tr("You're trying to send a sequential file, " - "which is not going to work!")); - continue; + if (paths.isEmpty()) { + return; } - qint64 filesize = file.size(); - qDebug() <<"sending"<getCoreFile()->sendFile(f->getId(), fileName, path, filesize); - } + Core* core = Core::getInstance(); + for (QString path : paths) { + QFile file(path); + QString fileName = QFileInfo(path).fileName(); + if (!file.exists() || !file.open(QIODevice::ReadOnly)) { + QMessageBox::warning(this, tr("Unable to open"), + tr("Wasn't able to open %1").arg(fileName)); + continue; + } + + file.close(); + if (file.isSequential()) { + QMessageBox::critical(this, tr("Bad idea"), + tr("You're trying to send a sequential file, " + "which is not going to work!")); + continue; + } + + qint64 filesize = file.size(); + qDebug() << "sending" << file << "size" << filesize; + core->getCoreFile()->sendFile(f->getId(), fileName, path, filesize); + } } - void ChatForm::showOutgoingCall(bool video) { -// headWidget->showOutgoingCall(video); - addSystemInfoMessage(tr("Calling %1").arg(f->username), - ChatMessage::INFO, QDateTime::currentDateTime()); - emit outgoingNotification(); - emit updateFriendActivity(*f); + // headWidget->showOutgoingCall(video); + addSystemInfoMessage(tr("Calling %1").arg(f->username), ChatMessage::INFO, + QDateTime::currentDateTime()); + emit outgoingNotification(); + emit updateFriendActivity(*f); } void ChatForm::onFriendStatusChanged(const FriendId& friendId, Status::Status status) { - qDebug() << __func__ <getId()) { - return; - } + qDebug() << __func__ << friendId.toString() << (int)status; + // Disable call buttons if friend is offline + if (friendId.toString() != f->getId()) { + return; + } -// if (!Status::isOnline(f->getStatus())) { + // if (!Status::isOnline(f->getStatus())) { // Hide the "is typing" message when a friend goes offline -// setFriendTyping(false); -// } - -// updateCallButtons(); - -// if (Settings::getInstance().getStatusChangeNotificationEnabled()) { -// QString fStatus = Status::getSubject(status); -// addSystemInfoMessage(tr("%1 is now %2", "e.g. \"Dubslow is now online\"") -// .arg(f->getDisplayedName()) -// .arg(fStatus), -// ChatMessage::INFO, QDateTime::currentDateTime()); -// } + // setFriendTyping(false); + // } + + // updateCallButtons(); + + // if (Settings::getInstance().getStatusChangeNotificationEnabled()) { + // QString fStatus = Status::getSubject(status); + // addSystemInfoMessage(tr("%1 is now %2", "e.g. \"Dubslow is now online\"") + // .arg(f->getDisplayedName()) + // .arg(fStatus), + // ChatMessage::INFO, QDateTime::currentDateTime()); + // } } -void ChatForm::onFriendNameChanged(const QString &name) { - qDebug()<<__func__ <toString()) { -// setName(name); -// } +void ChatForm::onFriendNameChanged(const QString& name) { + qDebug() << __func__ << name; + // if (sender() == f->toString()) { + // setName(name); + // } } -void ChatForm::onStatusMessage(const QString &message) { - qDebug()<<__func__ <mimeData()->hasUrls()) { - ev->acceptProposedAction(); - } +void ChatForm::onStatusMessage(const QString& message) { + qDebug() << __func__ << message; + // if (sender() == f) { + // setStatusMessage(message); + // } } -void ChatForm::dropEvent(QDropEvent *ev) { - if (!ev->mimeData()->hasUrls()) { - return; - } - - Core *core = Core::getInstance(); - for (const QUrl &url : ev->mimeData()->urls()) { - QFileInfo info(url.path()); - QFile file(info.absoluteFilePath()); - - QString urlString = url.toString(); - if (url.isValid() && !url.isLocalFile() && - urlString.length() < 1024 ) { - messageDispatcher.sendMessage(false, urlString); - - continue; - } - - QString fileName = info.fileName(); - if (!file.exists() || !file.open(QIODevice::ReadOnly)) { - info.setFile(url.toLocalFile()); - file.setFileName(info.absoluteFilePath()); - if (!file.exists() || !file.open(QIODevice::ReadOnly)) { - QMessageBox::warning(this, tr("Unable to open"), - tr("qTox wasn't able to open %1").arg(fileName)); - continue; - } +void ChatForm::dragEnterEvent(QDragEnterEvent* ev) { + if (ev->mimeData()->hasUrls()) { + ev->acceptProposedAction(); } +} - file.close(); - if (file.isSequential()) { - QMessageBox::critical(nullptr, tr("Bad idea"), - tr("You're trying to send a sequential file, " - "which is not going to work!")); - continue; +void ChatForm::dropEvent(QDropEvent* ev) { + if (!ev->mimeData()->hasUrls()) { + return; } - if (info.exists()) { - core->getCoreFile()->sendFile(f->getId(), fileName, - info.absoluteFilePath(), info.size()); + Core* core = Core::getInstance(); + for (const QUrl& url : ev->mimeData()->urls()) { + QFileInfo info(url.path()); + QFile file(info.absoluteFilePath()); + + QString urlString = url.toString(); + if (url.isValid() && !url.isLocalFile() && urlString.length() < 1024) { + messageDispatcher.sendMessage(false, urlString); + + continue; + } + + QString fileName = info.fileName(); + if (!file.exists() || !file.open(QIODevice::ReadOnly)) { + info.setFile(url.toLocalFile()); + file.setFileName(info.absoluteFilePath()); + if (!file.exists() || !file.open(QIODevice::ReadOnly)) { + QMessageBox::warning(this, tr("Unable to open"), + tr("qTox wasn't able to open %1").arg(fileName)); + continue; + } + } + + file.close(); + if (file.isSequential()) { + QMessageBox::critical(nullptr, tr("Bad idea"), + tr("You're trying to send a sequential file, " + "which is not going to work!")); + continue; + } + + if (info.exists()) { + core->getCoreFile()->sendFile(f->getId(), fileName, info.absoluteFilePath(), + info.size()); + } } - } } void ChatForm::clearChatArea() { - GenericChatForm::clearChatArea(/* confirm = */ false, /* inform = */ true); + GenericChatForm::clearChatArea(/* confirm = */ false, /* inform = */ true); } void ChatForm::onScreenshotClicked() { - doScreenshot(); - // Give the window manager a moment to open the fullscreen grabber window - QTimer::singleShot(SCREENSHOT_GRABBER_OPENING_DELAY, this, - SLOT(hideFileMenu())); + doScreenshot(); + // Give the window manager a moment to open the fullscreen grabber window + QTimer::singleShot(SCREENSHOT_GRABBER_OPENING_DELAY, this, SLOT(hideFileMenu())); } void ChatForm::doScreenshot() { - // note: grabber is self-managed and will destroy itself when done - ScreenshotGrabber *grabber = new ScreenshotGrabber; - connect(grabber, &ScreenshotGrabber::screenshotTaken, this, - &ChatForm::sendImage); - grabber->showGrabber(); + // note: grabber is self-managed and will destroy itself when done + ScreenshotGrabber* grabber = new ScreenshotGrabber; + connect(grabber, &ScreenshotGrabber::screenshotTaken, this, &ChatForm::sendImage); + grabber->showGrabber(); } -void ChatForm::sendImage(const QPixmap &pixmap) { - QDir(Settings::getInstance().getAppDataDirPath()).mkpath("images"); - - // use ~ISO 8601 for screenshot timestamp, considering FS limitations - // https://en.wikipedia.org/wiki/ISO_8601 - // Windows has to be supported, thus filename can't have `:` in it :/ - // Format should be: `qTox_Screenshot_yyyy-MM-dd HH-mm-ss.zzz.png` - QString filepath = QString("%1images%2qTox_Image_%3.png") - .arg(Settings::getInstance().getAppDataDirPath()) - .arg(QDir::separator()) - .arg(QDateTime::currentDateTime().toString( - "yyyy-MM-dd HH-mm-ss.zzz")); - QFile file(filepath); - - if (file.open(QFile::ReadWrite)) { - pixmap.save(&file, "PNG"); - qint64 filesize = file.size(); - file.close(); - QFileInfo fi(file); - CoreFile *coreFile = Core::getInstance()->getCoreFile(); - coreFile->sendFile(f->getId(), fi.fileName(), fi.filePath(), filesize); - } else { - QMessageBox::warning( - this, - tr("Failed to open temporary file", "Temporary file for screenshot"), - tr("qTox wasn't able to save the screenshot")); - } +void ChatForm::sendImage(const QPixmap& pixmap) { + QDir(Settings::getInstance().getAppDataDirPath()).mkpath("images"); + + // use ~ISO 8601 for screenshot timestamp, considering FS limitations + // https://en.wikipedia.org/wiki/ISO_8601 + // Windows has to be supported, thus filename can't have `:` in it :/ + // Format should be: `qTox_Screenshot_yyyy-MM-dd HH-mm-ss.zzz.png` + QString filepath = + QString("%1images%2qTox_Image_%3.png") + .arg(Settings::getInstance().getAppDataDirPath()) + .arg(QDir::separator()) + .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH-mm-ss.zzz")); + QFile file(filepath); + + if (file.open(QFile::ReadWrite)) { + pixmap.save(&file, "PNG"); + qint64 filesize = file.size(); + file.close(); + QFileInfo fi(file); + CoreFile* coreFile = Core::getInstance()->getCoreFile(); + coreFile->sendFile(f->getId(), fi.fileName(), fi.filePath(), filesize); + } else { + QMessageBox::warning(this, + tr("Failed to open temporary file", "Temporary file for screenshot"), + tr("qTox wasn't able to save the screenshot")); + } } -void ChatForm::insertChatMessage(IChatItem::Ptr msg) { - GenericChatForm::insertChatMessage(msg); -} +void ChatForm::insertChatMessage(IChatItem::Ptr msg) { GenericChatForm::insertChatMessage(msg); } void ChatForm::onCopyStatusMessage() { - qDebug() <<__func__; -// QString text = f->getStatusMessage(); -// QClipboard *clipboard = QApplication::clipboard(); -// if (clipboard) { -// clipboard->setText(text, QClipboard::Clipboard); -// } + qDebug() << __func__; + // QString text = f->getStatusMessage(); + // QClipboard *clipboard = QApplication::clipboard(); + // if (clipboard) { + // clipboard->setText(text, QClipboard::Clipboard); + // } } void ChatForm::setFriendTyping(bool typing) { - isTyping = typing; - if(chatLog) - chatLog->setTypingNotificationVisible(typing); -// QString typingDiv = "
%1
"; -// QString name = f->getDisplayedName(); -// Text *text = static_cast(chatLog->getTypingNotification()->centerContent()); -// text->setText(typingDiv.arg(tr("%1 is typing").arg(name))); + isTyping = typing; + if (chatLog) chatLog->setTypingNotificationVisible(typing); + // QString typingDiv = "
%1
"; + // QString name = f->getDisplayedName(); + // Text *text = static_cast(chatLog->getTypingNotification()->centerContent()); + // text->setText(typingDiv.arg(tr("%1 is typing").arg(name))); } -void ChatForm::show(ContentLayout *contentLayout) { - GenericChatForm::show(contentLayout); -} +void ChatForm::show(ContentLayout* contentLayout) { GenericChatForm::show(contentLayout); } void ChatForm::reloadTheme() { - chatLog->setTypingNotification(ChatMessage::createTypingNotification()); - GenericChatForm::reloadTheme(); + chatLog->setTypingNotification(ChatMessage::createTypingNotification()); + GenericChatForm::reloadTheme(); } -void ChatForm::showEvent(QShowEvent *event) { -// GenericChatForm::showEvent(event); +void ChatForm::showEvent(QShowEvent* event) { + // GenericChatForm::showEvent(event); } -void ChatForm::hideEvent(QHideEvent *event) { -// GenericChatForm::hideEvent(event); +void ChatForm::hideEvent(QHideEvent* event) { + // GenericChatForm::hideEvent(event); } -void ChatForm::retranslateUi() { - copyStatusAction->setText(tr("Copy")); -} +void ChatForm::retranslateUi() { copyStatusAction->setText(tr("Copy")); } diff --git a/src/modules/im/src/widget/form/chatform.h b/src/modules/im/src/widget/form/chatform.h index 7143c54b..89b15f86 100644 --- a/src/modules/im/src/widget/form/chatform.h +++ b/src/modules/im/src/widget/form/chatform.h @@ -41,83 +41,75 @@ class QMoveEvent; * @brief The ChatForm class */ class ChatForm : public GenericChatForm { - Q_OBJECT + Q_OBJECT public: - static const QString ACTION_PREFIX; + static const QString ACTION_PREFIX; - ChatForm(const FriendId *contact, - IChatLog &chatLog, - IMessageDispatcher &messageDispatcher); - ~ChatForm(); + ChatForm(const FriendId* contact, IChatLog& chatLog, IMessageDispatcher& messageDispatcher); + ~ChatForm(); - void setStatusMessage(const QString &newMessage); + void setStatusMessage(const QString& newMessage); - void setFriendTyping(bool isTyping); + void setFriendTyping(bool isTyping); - virtual void show(ContentLayout *contentLayout) final override; + virtual void show(ContentLayout* contentLayout) final override; - virtual void reloadTheme() final override; - - void insertChatMessage(IChatItem::Ptr msg) final override; + virtual void reloadTheme() final override; + void insertChatMessage(IChatItem::Ptr msg) final override; signals: - void incomingNotification(QString friendId); - void outgoingNotification(); - void stopNotification(); - void endCallNotification(); + void incomingNotification(QString friendId); + void outgoingNotification(); + void stopNotification(); + void endCallNotification(); - void updateFriendActivity(const FriendId &frnd); + void updateFriendActivity(const FriendId& frnd); public slots: - void onFileNameChanged(const FriendId &friendPk); - void clearChatArea(); + void onFileNameChanged(const FriendId& friendPk); + void clearChatArea(); private slots: - void updateFriendActivityForFile(const ToxFile &file); - void onAttachClicked() override; - void onScreenshotClicked() override; - - void onTextEditChanged(); -// void onCallTriggered(); -// void onVideoCallTriggered(); -// void onAcceptCallTriggered(const ToxPeer &peer, bool video); -// void onRejectCallTriggered(const ToxPeer &peer); -// void onMicMuteToggle(); -// void onVolMuteToggle(); - - void onFriendStatusChanged(const FriendId& friendId, Status::Status status); - void onFriendNameChanged(const QString &name); - void onStatusMessage(const QString &message); - - void sendImage(const QPixmap &pixmap); - void doScreenshot(); - void onCopyStatusMessage(); - void callUpdateFriendActivity(); + void updateFriendActivityForFile(const ToxFile& file); + void onAttachClicked() override; + void onScreenshotClicked() override; + + void onTextEditChanged(); + // void onCallTriggered(); + // void onVideoCallTriggered(); + // void onAcceptCallTriggered(const ToxPeer &peer, bool video); + // void onRejectCallTriggered(const ToxPeer &peer); + // void onMicMuteToggle(); + // void onVolMuteToggle(); + + void onFriendStatusChanged(const FriendId& friendId, Status::Status status); + void onFriendNameChanged(const QString& name); + void onStatusMessage(const QString& message); + + void sendImage(const QPixmap& pixmap); + void doScreenshot(); + void onCopyStatusMessage(); + void callUpdateFriendActivity(); protected: - - void dragEnterEvent(QDragEnterEvent *ev) final override; - void dropEvent(QDropEvent *ev) final override; - void hideEvent(QHideEvent *event) final override; - void showEvent(QShowEvent *event) final override; + void dragEnterEvent(QDragEnterEvent* ev) final override; + void dropEvent(QDropEvent* ev) final override; + void hideEvent(QHideEvent* event) final override; + void showEvent(QShowEvent* event) final override; private: + void retranslateUi(); + void showOutgoingCall(bool video); - void retranslateUi(); - void showOutgoingCall(bool video); - - - const FriendId *f; - CroppingLabel *statusMessageLabel; - QMenu statusMessageMenu; - - QTimer typingTimer; - QAction *copyStatusAction; - bool isTyping; - + const FriendId* f; + CroppingLabel* statusMessageLabel; + QMenu statusMessageMenu; + QTimer typingTimer; + QAction* copyStatusAction; + bool isTyping; }; -#endif // CHATFORM_H +#endif // CHATFORM_H diff --git a/src/modules/im/src/widget/form/filesform.cpp b/src/modules/im/src/widget/form/filesform.cpp index c5f08c4e..0440d1ac 100644 --- a/src/modules/im/src/widget/form/filesform.cpp +++ b/src/modules/im/src/widget/form/filesform.cpp @@ -11,17 +11,15 @@ */ #include "filesform.h" +#include +#include #include "lib/settings/translator.h" #include "src/lib/settings/style.h" #include "src/widget/contentlayout.h" #include "src/widget/widget.h" -#include -#include FilesForm::FilesForm() - : QObject() - , doneIcon(Style::getImagePath("fileTransferWidget/fileDone.svg")) -{ + : QObject(), doneIcon(Style::getImagePath("fileTransferWidget/fileDone.svg")) { head = new QWidget(); QFont bold; bold.setBold(true); @@ -42,16 +40,14 @@ FilesForm::FilesForm() settings::Translator::registerHandler(std::bind(&FilesForm::retranslateUi, this), this); } -FilesForm::~FilesForm() -{ +FilesForm::~FilesForm() { settings::Translator::unregister(this); delete recvd; delete sent; head->deleteLater(); } -bool FilesForm::isShown() const -{ +bool FilesForm::isShown() const { if (main.isVisible()) { head->window()->windowHandle()->alert(0); return true; @@ -60,23 +56,20 @@ bool FilesForm::isShown() const return false; } -void FilesForm::show(ContentLayout* contentLayout) -{ -// contentLayout->mainContent->layout()->addWidget(&main); -// contentLayout->mainHead->layout()->addWidget(head); +void FilesForm::show(ContentLayout* contentLayout) { + // contentLayout->mainContent->layout()->addWidget(&main); + // contentLayout->mainHead->layout()->addWidget(head); main.show(); head->show(); } -void FilesForm::onFileDownloadComplete(const QString& path) -{ +void FilesForm::onFileDownloadComplete(const QString& path) { QListWidgetItem* tmp = new QListWidgetItem(doneIcon, QFileInfo(path).fileName()); tmp->setData(Qt::UserRole, path); recvd->addItem(tmp); } -void FilesForm::onFileUploadComplete(const QString& path) -{ +void FilesForm::onFileUploadComplete(const QString& path) { QListWidgetItem* tmp = new QListWidgetItem(doneIcon, QFileInfo(path).fileName()); tmp->setData(Qt::UserRole, path); sent->addItem(tmp); @@ -87,13 +80,11 @@ void FilesForm::onFileUploadComplete(const QString& path) // whenever they're not saved anywhere custom, thanks to the hack) // I could do some digging around, but for now I'm tired and others already // might know it without me needing to dig, so... -void FilesForm::onFileActivated(QListWidgetItem* item) -{ +void FilesForm::onFileActivated(QListWidgetItem* item) { Widget::confirmExecutableOpen(QFileInfo(item->data(Qt::UserRole).toString())); } -void FilesForm::retranslateUi() -{ +void FilesForm::retranslateUi() { headLabel.setText(tr("Transferred Files", "\"Headline\" of the window")); main.setTabText(0, tr("Downloads")); main.setTabText(1, tr("Uploads")); diff --git a/src/modules/im/src/widget/form/filesform.h b/src/modules/im/src/widget/form/filesform.h index 07955120..2ef2826a 100644 --- a/src/modules/im/src/widget/form/filesform.h +++ b/src/modules/im/src/widget/form/filesform.h @@ -22,8 +22,7 @@ class ContentLayout; class QListWidget; -class FilesForm : public QObject -{ +class FilesForm : public QObject { Q_OBJECT public: @@ -52,4 +51,4 @@ private slots: QListWidget *sent, *recvd; }; -#endif // FILESFORM_H +#endif // FILESFORM_H diff --git a/src/modules/im/src/widget/form/friendform.cpp b/src/modules/im/src/widget/form/friendform.cpp index c2db4e46..dde60d22 100644 --- a/src/modules/im/src/widget/form/friendform.cpp +++ b/src/modules/im/src/widget/form/friendform.cpp @@ -14,20 +14,20 @@ #include "lib/backend/UserService.h" #include "ui_friendform.h" -FriendForm::FriendForm(const ok::backend::OrgStaff& staff_, QWidget *parent) - : QFrame(parent), ui(new Ui::FriendForm), staff(staff_) { - ui->setupUi(this); - ui->no->setText(staff.no); - ui->posts->setText(staff.posts); - ui->name->setText(staff.name); - ui->phone->setText(staff.phone); - ui->email->setText(staff.email); +FriendForm::FriendForm(const ok::backend::OrgStaff& staff_, QWidget* parent) + : QFrame(parent), ui(new Ui::FriendForm), staff(staff_) { + ui->setupUi(this); + ui->no->setText(staff.no); + ui->posts->setText(staff.posts); + ui->name->setText(staff.name); + ui->phone->setText(staff.phone); + ui->email->setText(staff.email); - connect(ui->addFriend, &QPushButton::released, - [&]() { emit add(staff.toContactId(), staff.name); }); + connect(ui->addFriend, &QPushButton::released, + [&]() { emit add(staff.toContactId(), staff.name); }); } FriendForm::~FriendForm() { - disconnect(ui->addFriend); - delete ui; + disconnect(ui->addFriend); + delete ui; } diff --git a/src/modules/im/src/widget/form/friendform.h b/src/modules/im/src/widget/form/friendform.h index 8ec45649..a48baced 100644 --- a/src/modules/im/src/widget/form/friendform.h +++ b/src/modules/im/src/widget/form/friendform.h @@ -13,7 +13,6 @@ #ifndef FRIENDFORM_H #define FRIENDFORM_H - #include #include @@ -23,26 +22,24 @@ namespace Ui { class FriendForm; } -namespace ok::backend{ +namespace ok::backend { struct OrgStaff; } -class FriendForm : public QFrame -{ +class FriendForm : public QFrame { Q_OBJECT public: - explicit FriendForm(const ok::backend::OrgStaff& staff, QWidget *parent = nullptr); + explicit FriendForm(const ok::backend::OrgStaff& staff, QWidget* parent = nullptr); ~FriendForm(); - private: - Ui::FriendForm *ui; + Ui::FriendForm* ui; ok::backend::OrgStaff staff; - signals: - void add(const QString &cId, QString &nick); +signals: + void add(const QString& cId, QString& nick); }; -#endif // FRIENDFORM_H +#endif // FRIENDFORM_H diff --git a/src/modules/im/src/widget/form/genericchatform.cpp b/src/modules/im/src/widget/form/genericchatform.cpp index b05b5675..2088c98b 100644 --- a/src/modules/im/src/widget/form/genericchatform.cpp +++ b/src/modules/im/src/widget/form/genericchatform.cpp @@ -16,16 +16,16 @@ #include "src/chatlog/chatlinecontentproxy.h" #include "src/chatlog/chatlog.h" #include "src/chatlog/content/filetransferwidget.h" -#include "src/chatlog/content/timestamp.h" #include "src/chatlog/content/simpletext.h" +#include "src/chatlog/content/timestamp.h" #include "src/core/core.h" #include "src/friendlist.h" #include "src/grouplist.h" #include "src/model/friend.h" #include "src/model/group.h" +#include "src/persistence/profile.h" #include "src/persistence/settings.h" #include "src/persistence/smileypack.h" -#include "src/persistence/profile.h" #include "src/video/genericnetcamview.h" #include "src/widget/chatformheader.h" #include "src/widget/contentdialog.h" @@ -35,7 +35,7 @@ #include "src/widget/form/chatform.h" #include "src/widget/form/loadhistorydialog.h" #include "src/widget/maskablepixmapwidget.h" -//#include "src/widget/searchform.h" +// #include "src/widget/searchform.h" #include "src/lib/settings/style.h" #include "src/widget/gui.h" #include "src/widget/tool/chattextedit.h" @@ -60,7 +60,6 @@ #include -#include #include #include @@ -85,16 +84,14 @@ static const QString FONT_STYLE[]{"normal", "italic", "oblique"}; * @param name Class name * @return Style string */ -static QString fontToCss(const QFont &font, const QString &name) { - QString result{"%1{" - "font-family: \"%2\"; " - "font-size: %3px; " - "font-style: \"%4\"; " - "font-weight: normal;}"}; - return result.arg(name) - .arg(font.family()) - .arg(font.pixelSize()) - .arg(FONT_STYLE[font.style()]); +static QString fontToCss(const QFont& font, const QString& name) { + QString result{ + "%1{" + "font-family: \"%2\"; " + "font-size: %3px; " + "font-style: \"%4\"; " + "font-weight: normal;}"}; + return result.arg(name).arg(font.family()).arg(font.pixelSize()).arg(FONT_STYLE[font.style()]); } /** @@ -104,20 +101,20 @@ static QString fontToCss(const QFont &font, const QString &name) { * @return Name or alias of someone with such public key, or public key string * representation if no one was found */ -QString GenericChatForm::resolveToxPk(const FriendId &pk) { - Friend *f = FriendList::findFriend(pk); - if (f) { - return f->getDisplayedName(); - } - -// for (Group *it : GroupList::getAllGroups()) { -// QString res = it->resolveToxId(pk); -// if (!res.isEmpty()) { -// return res; -// } -// } - - return pk.toString(); +QString GenericChatForm::resolveToxPk(const FriendId& pk) { + Friend* f = FriendList::findFriend(pk); + if (f) { + return f->getDisplayedName(); + } + + // for (Group *it : GroupList::getAllGroups()) { + // QString res = it->resolveToxId(pk); + // if (!res.isEmpty()) { + // return res; + // } + // } + + return pk.toString(); } namespace { @@ -127,493 +124,460 @@ const QString STYLE_PATH = QStringLiteral("chatForm/buttons.css"); namespace { template -QPushButton *createButton(const QString &name, T *self, Fun onClickSlot) { - QPushButton *btn = new QPushButton(); - // Fix for incorrect layouts on OS X as per - // https://bugreports.qt-project.org/browse/QTBUG-14591 - btn->setAttribute(Qt::WA_LayoutUsesWidgetRect); - btn->setCursor(Qt::PointingHandCursor); - btn->setObjectName(name); - //btn->setProperty("state", "green"); - btn->setStyleSheet(Style::getStylesheet(STYLE_PATH)); - btn->setCheckable(true); - QObject::connect(btn, &QPushButton::clicked, self, onClickSlot); - return btn; -} - -IChatItem::Ptr -getChatMessageForIdx(ChatLogIdx idx, - const std::map &messages) { - - auto existingMessageIt = messages.find(idx); - if (existingMessageIt == messages.end()) { - return IChatItem::Ptr(); - } +QPushButton* createButton(const QString& name, T* self, Fun onClickSlot) { + QPushButton* btn = new QPushButton(); + // Fix for incorrect layouts on OS X as per + // https://bugreports.qt-project.org/browse/QTBUG-14591 + btn->setAttribute(Qt::WA_LayoutUsesWidgetRect); + btn->setCursor(Qt::PointingHandCursor); + btn->setObjectName(name); + // btn->setProperty("state", "green"); + btn->setStyleSheet(Style::getStylesheet(STYLE_PATH)); + btn->setCheckable(true); + QObject::connect(btn, &QPushButton::clicked, self, onClickSlot); + return btn; +} + +IChatItem::Ptr getChatMessageForIdx(ChatLogIdx idx, + const std::map& messages) { + auto existingMessageIt = messages.find(idx); + if (existingMessageIt == messages.end()) { + return IChatItem::Ptr(); + } - return existingMessageIt->second; + return existingMessageIt->second; } -bool shouldRenderDate(ChatLogIdx idxToRender, const IChatLog &chatLog) { - if (idxToRender.get() == chatLog.getFirstIdx().get()) - return true; +bool shouldRenderDate(ChatLogIdx idxToRender, const IChatLog& chatLog) { + if (idxToRender.get() == chatLog.getFirstIdx().get()) return true; + auto prev = chatLog.at(idxToRender - 1); + auto cur = chatLog.at(idxToRender); + if (!prev || !cur) return false; - auto prev = chatLog.at(idxToRender - 1); - auto cur = chatLog.at(idxToRender); - if(!prev || !cur) - return false; - - return prev->getTimestamp().date() != - cur->getTimestamp().date(); + return prev->getTimestamp().date() != cur->getTimestamp().date(); } -IChatItem::Ptr dateMessageForItem(const ChatLogItem &item) { - const auto &s = Settings::getInstance(); - const auto date = item.getTimestamp().date(); - auto dateText = date.toString(s.getDateFormat()); - return ChatMessage::createChatInfoMessage(dateText, ChatMessage::INFO, - QDateTime()); +IChatItem::Ptr dateMessageForItem(const ChatLogItem& item) { + const auto& s = Settings::getInstance(); + const auto date = item.getTimestamp().date(); + auto dateText = date.toString(s.getDateFormat()); + return ChatMessage::createChatInfoMessage(dateText, ChatMessage::INFO, QDateTime()); } -IChatItem::Ptr createMessage(const ChatLogItem &item, bool isSelf, - bool colorizeNames, - const ChatLogMessage &chatLogMessage) { -// qDebug() << "createMessage displayName:" << displayName; - auto messageType = chatLogMessage.message.isAction - ? ChatMessage::MessageType::ACTION - : ChatMessage::MessageType::NORMAL; - - const bool bSelfMentioned = - std::any_of(chatLogMessage.message.metadata.begin(), - chatLogMessage.message.metadata.end(), - [](const MessageMetadata &metadata) { - return metadata.type == MessageMetadataType::selfMention; - }); - - if (bSelfMentioned) { - messageType = ChatMessage::MessageType::ALERT; - } - - - return ChatMessage::createChatMessage( - item, chatLogMessage.message.content, messageType,isSelf, - chatLogMessage.state, chatLogMessage.message.timestamp, colorizeNames); -} +IChatItem::Ptr createMessage(const ChatLogItem& item, bool isSelf, bool colorizeNames, + const ChatLogMessage& chatLogMessage) { + // qDebug() << "createMessage displayName:" << displayName; + auto messageType = chatLogMessage.message.isAction ? ChatMessage::MessageType::ACTION + : ChatMessage::MessageType::NORMAL; + const bool bSelfMentioned = + std::any_of(chatLogMessage.message.metadata.begin(), + chatLogMessage.message.metadata.end(), + [](const MessageMetadata& metadata) { + return metadata.type == MessageMetadataType::selfMention; + }); -void renderMessage(const ChatLogItem &item, bool isSelf, bool colorizeNames, - const ChatLogMessage &chatLogMessage, - IChatItem::Ptr &chatMessage) { - if (chatMessage) { - if (chatLogMessage.state == MessageState::complete) { - chatMessage->markAsDelivered(chatLogMessage.message.timestamp); + if (bSelfMentioned) { + messageType = ChatMessage::MessageType::ALERT; } - } else { - chatMessage = createMessage(item, isSelf, colorizeNames, chatLogMessage); - } + + return ChatMessage::createChatMessage(item, chatLogMessage.message.content, messageType, isSelf, + chatLogMessage.state, chatLogMessage.message.timestamp, + colorizeNames); } -void renderFile(const ChatLogItem &item, ToxFile file, bool isSelf, - QDateTime timestamp, IChatItem::Ptr &chatMessage) { +void renderMessage(const ChatLogItem& item, bool isSelf, bool colorizeNames, + const ChatLogMessage& chatLogMessage, IChatItem::Ptr& chatMessage) { + if (chatMessage) { + if (chatLogMessage.state == MessageState::complete) { + chatMessage->markAsDelivered(chatLogMessage.message.timestamp); + } + } else { + chatMessage = createMessage(item, isSelf, colorizeNames, chatLogMessage); + } +} - qDebug() << __func__ <<"file"<(chatMessage->centerContent()); - if(proxy->getWidgetType() == ChatLineContentProxy::FileTransferWidgetType){ - auto ftWidget = static_cast(proxy->getWidget()); - ftWidget->onFileTransferUpdate(file); - qDebug() <<"update file"<(chatMessage->centerContent()); + if (proxy->getWidgetType() == ChatLineContentProxy::FileTransferWidgetType) { + auto ftWidget = static_cast(proxy->getWidget()); + ftWidget->onFileTransferUpdate(file); + qDebug() << "update file" << file.fileName; + } } - } } -void renderItem(const ChatLogItem &item, +void renderItem(const ChatLogItem& item, bool hideName, bool colorizeNames, - IChatItem::Ptr &chatMessage) { - - const Core *core = Core::getInstance(); - - const auto &sender = item.getSender(); - const auto &selfPk = core->getSelfPeerId().getPublicKey(); - - bool isSelf = sender == selfPk; // || sender.getResource() == selfPk.getUsername(); - - switch (item.getContentType()) { - case ChatLogItem::ContentType::message: { - const auto &chatLogMessage = item.getContentAsMessage(); - renderMessage(item, isSelf, colorizeNames, chatLogMessage,chatMessage); - break; - } - case ChatLogItem::ContentType::fileTransfer: { - const auto &file = item.getContentAsFile(); - renderFile(item,file.file,isSelf,item.getTimestamp(),chatMessage); - break; - } - } + IChatItem::Ptr& chatMessage) { + const Core* core = Core::getInstance(); + + const auto& sender = item.getSender(); + const auto& selfPk = core->getSelfPeerId().getPublicKey(); + + bool isSelf = sender == selfPk; // || sender.getResource() == selfPk.getUsername(); + + switch (item.getContentType()) { + case ChatLogItem::ContentType::message: { + const auto& chatLogMessage = item.getContentAsMessage(); + renderMessage(item, isSelf, colorizeNames, chatLogMessage, chatMessage); + break; + } + case ChatLogItem::ContentType::fileTransfer: { + const auto& file = item.getContentAsFile(); + renderFile(item, file.file, isSelf, item.getTimestamp(), chatMessage); + break; + } + } } -ChatLogIdx firstItemAfterDate(QDate date, const IChatLog &chatLog) { - auto idxs = chatLog.getDateIdxs(date, 1); - if (idxs.size()) { - return idxs[0].idx; - } else { - return chatLog.getNextIdx(); - } +ChatLogIdx firstItemAfterDate(QDate date, const IChatLog& chatLog) { + auto idxs = chatLog.getDateIdxs(date, 1); + if (idxs.size()) { + return idxs[0].idx; + } else { + return chatLog.getNextIdx(); + } } -} // namespace - -GenericChatForm::GenericChatForm(const ContactId *contact_, - IChatLog &iChatLog_, - IMessageDispatcher &messageDispatcher, - QWidget *parent) - : QWidget(parent, Qt::Window), contactId(contact_), contact(nullptr), - audioInputFlag(false), - audioOutputFlag(false), - isEncrypt(false), - iChatLog(iChatLog_), - emoticonsWidget{nullptr}, - messageDispatcher(messageDispatcher) { - - setContentsMargins(0, 0, 0, 0); - - qDebug() << __func__ << "contact:" << contact_; - - curRow = 0; - //searchForm = new SearchForm(); - //searchForm->hide(); - - chatLog = new ChatLog(this); - chatLog->setBusyNotification(ChatMessage::createBusyNotification()); - -// dateInfo = new QLabel(this); -// dateInfo->setAlignment(Qt::AlignHCenter); -// dateInfo->setVisible(false); - - // settings - const Settings &s = Settings::getInstance(); - connect(&s, &Settings::emojiFontPointSizeChanged, chatLog, - &ChatLog::forceRelayout); - connect(&s, &Settings::chatMessageFontChanged, this, - &GenericChatForm::onChatMessageFontChanged); - - msgEdit = new ChatTextEdit(); +} // namespace + +GenericChatForm::GenericChatForm(const ContactId* contact_, + IChatLog& iChatLog_, + IMessageDispatcher& messageDispatcher, + QWidget* parent) + : QWidget(parent, Qt::Window) + , contactId(contact_) + , contact(nullptr) + , audioInputFlag(false) + , audioOutputFlag(false) + , isEncrypt(false) + , iChatLog(iChatLog_) + , emoticonsWidget{nullptr} + , messageDispatcher(messageDispatcher) { + setContentsMargins(0, 0, 0, 0); + + qDebug() << __func__ << "contact:" << contact_; + + curRow = 0; + // searchForm = new SearchForm(); + // searchForm->hide(); + + chatLog = new ChatLog(this); + chatLog->setBusyNotification(ChatMessage::createBusyNotification()); + + // dateInfo = new QLabel(this); + // dateInfo->setAlignment(Qt::AlignHCenter); + // dateInfo->setVisible(false); + + // settings + const Settings& s = Settings::getInstance(); + connect(&s, &Settings::emojiFontPointSizeChanged, chatLog, &ChatLog::forceRelayout); + connect(&s, &Settings::chatMessageFontChanged, this, + &GenericChatForm::onChatMessageFontChanged); + + msgEdit = new ChatTextEdit(); #ifdef SPELL_CHECKING - if (s.getSpellCheckingEnabled()) { - decorator = new Sonnet::SpellCheckDecorator(msgEdit); - } + if (s.getSpellCheckingEnabled()) { + decorator = new Sonnet::SpellCheckDecorator(msgEdit); + } #endif - encryptButton = createButton("encryptButton", this, - &GenericChatForm::onEncryptButtonClicked); - - sendButton = - createButton("sendButton", this, &GenericChatForm::onSendTriggered); - - emoteButton = - createButton("emoteButton", this, &GenericChatForm::onEmoteButtonClicked); - - fileButton = - createButton("fileButton", this, &GenericChatForm::onAttachClicked); - screenshotButton = createButton("screenshotButton", this, - &GenericChatForm::onScreenshotClicked); - - // TODO: Make updateCallButtons (see ChatForm) abstract - // and call here to set tooltips. - - msgEdit->setFixedHeight(MESSAGE_EDIT_HEIGHT); - msgEdit->setFrameStyle(QFrame::NoFrame); - - bodySplitter = new QSplitter(Qt::Vertical, this); - connect(bodySplitter, &QSplitter::splitterMoved, this, - &GenericChatForm::onSplitterMoved); - QWidget *contentWidget = new QWidget(this); - contentWidget->setObjectName("ChatContentContainer"); - bodySplitter->addWidget(contentWidget); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addWidget(bodySplitter); - mainLayout->setMargin(0); - - setLayout(mainLayout); - - QWidget *footContainer = new QFrame(contentWidget); - footContainer->setAttribute(Qt::WA_StyledBackground); - footContainer->setAutoFillBackground(true); - footContainer->setObjectName("ChatFootContainer"); - QHBoxLayout *footButtonsSmall = new QHBoxLayout(); - footButtonsSmall->setSpacing(FOOT_BUTTONS_SPACING); - footButtonsSmall->addWidget(emoteButton); - footButtonsSmall->addWidget(fileButton); - footButtonsSmall->addWidget(screenshotButton); + encryptButton = createButton("encryptButton", this, &GenericChatForm::onEncryptButtonClicked); + + sendButton = createButton("sendButton", this, &GenericChatForm::onSendTriggered); + + emoteButton = createButton("emoteButton", this, &GenericChatForm::onEmoteButtonClicked); + + fileButton = createButton("fileButton", this, &GenericChatForm::onAttachClicked); + screenshotButton = + createButton("screenshotButton", this, &GenericChatForm::onScreenshotClicked); + + // TODO: Make updateCallButtons (see ChatForm) abstract + // and call here to set tooltips. + + msgEdit->setFixedHeight(MESSAGE_EDIT_HEIGHT); + msgEdit->setFrameStyle(QFrame::NoFrame); + + bodySplitter = new QSplitter(Qt::Vertical, this); + connect(bodySplitter, &QSplitter::splitterMoved, this, &GenericChatForm::onSplitterMoved); + QWidget* contentWidget = new QWidget(this); + contentWidget->setObjectName("ChatContentContainer"); + bodySplitter->addWidget(contentWidget); + + QVBoxLayout* mainLayout = new QVBoxLayout(); + mainLayout->addWidget(bodySplitter); + mainLayout->setMargin(0); + + setLayout(mainLayout); + + QWidget* footContainer = new QFrame(contentWidget); + footContainer->setAttribute(Qt::WA_StyledBackground); + footContainer->setAutoFillBackground(true); + footContainer->setObjectName("ChatFootContainer"); + QHBoxLayout* footButtonsSmall = new QHBoxLayout(); + footButtonsSmall->setSpacing(FOOT_BUTTONS_SPACING); + footButtonsSmall->addWidget(emoteButton); + footButtonsSmall->addWidget(fileButton); + footButtonsSmall->addWidget(screenshotButton); #ifdef OK_PLUGIN - auto pm = ok::plugin::PluginManager::instance(); - connect(pm, &ok::plugin::PluginManager::pluginEnabled, // - this, &::GenericChatForm::onPluginEnabled); - connect(pm, &ok::plugin::PluginManager::pluginDisabled, // - this, &::GenericChatForm::onPluginDisabled); - auto omemo = pm->plugin("omemo"); - if (omemo) { - footButtonsSmall->addWidget(encryptButton); - } + auto pm = ok::plugin::PluginManager::instance(); + connect(pm, &ok::plugin::PluginManager::pluginEnabled, // + this, &::GenericChatForm::onPluginEnabled); + connect(pm, &ok::plugin::PluginManager::pluginDisabled, // + this, &::GenericChatForm::onPluginDisabled); + auto omemo = pm->plugin("omemo"); + if (omemo) { + footButtonsSmall->addWidget(encryptButton); + } #endif - footButtonsSmall->addStretch(1); - - QVBoxLayout *sendButtonLyt = new QVBoxLayout(); - sendButtonLyt->addStretch(1); - sendButtonLyt->addWidget(sendButton); - - QVBoxLayout *inputLayout = new QVBoxLayout(); - inputLayout->addLayout(footButtonsSmall); - inputLayout->setSpacing(FOOT_BUTTONS_SPACING); - inputLayout->addWidget(msgEdit); - - mainFootLayout = new QHBoxLayout(footContainer); - mainFootLayout->setContentsMargins(MAIN_FOOT_MARGIN, MAIN_FOOT_MARGIN, MAIN_FOOT_MARGIN, MAIN_FOOT_MARGIN); - mainFootLayout->setSpacing(EDIT_SEND_SPACING); - mainFootLayout->addLayout(inputLayout); - mainFootLayout->addLayout(sendButtonLyt); - - QVBoxLayout *contentLayout = new QVBoxLayout(contentWidget); - contentLayout->setContentsMargins(0, 0, 0, 0); - //contentLayout->addWidget(searchForm); -// contentLayout->addWidget(dateInfo); - contentLayout->addWidget(chatLog, 1); - contentLayout->addWidget(footContainer, 0); - - quoteAction = - menu.addAction(QIcon(), QString(), this, SLOT(quoteSelectedText()), - QKeySequence(Qt::ALT , Qt::Key_Q)); - addAction(quoteAction); - menu.addSeparator(); - - // searchAction = - // menu.addAction(QIcon(), QString(), this, SLOT(searchFormShow()), - // QKeySequence(Qt::CTRL + Qt::Key_F)); - // addAction(searchAction); - - menu.addSeparator(); - - menu.addActions(chatLog->actions()); - menu.addSeparator(); - - clearAction = menu.addAction(QIcon::fromTheme("edit-clear"), QString(), this, - SLOT(clearChatArea()), - QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_L)); - addAction(clearAction); - - copyLinkAction = menu.addAction(QIcon(), QString(), this, SLOT(copyLink())); - menu.addSeparator(); - - // loadHistoryAction = - // menu.addAction(QIcon(), QString(), this, SLOT(onLoadHistory())); - // exportChatAction = menu.addAction(QIcon::fromTheme("document-save"), - // QString(), this, SLOT(onExportChat())); - - connect(chatLog, &ChatLog::customContextMenuRequested, this, - &GenericChatForm::onChatContextMenuRequested); - connect(chatLog, &ChatLog::firstVisibleLineChanged, this, - &GenericChatForm::updateShowDateInfo); - connect(chatLog, &ChatLog::loadHistoryLower, this, - &GenericChatForm::loadHistoryLower); - - connect(&iChatLog, &IChatLog::itemUpdated, - this,&GenericChatForm::renderMessage); - - //connect(searchForm, &SearchForm::searchInBegin, this, - // &GenericChatForm::searchInBegin); - //connect(searchForm, &SearchForm::searchUp, this, - // &GenericChatForm::onSearchUp); - //connect(searchForm, &SearchForm::searchDown, this, - // &GenericChatForm::onSearchDown); - //connect(searchForm, &SearchForm::visibleChanged, this, - // &GenericChatForm::onSearchTriggered); - //connect(this, &GenericChatForm::messageNotFoundShow, searchForm, - // &SearchForm::showMessageNotFound); - - connect(msgEdit, &ChatTextEdit::enterPressed, this, - &GenericChatForm::onSendTriggered); - - connect(&GUI::getInstance(), &GUI::themeApplyRequest, this, &GenericChatForm::reloadTheme); - reloadTheme(); - - settings::Translator::registerHandler([this] { retranslateUi(); }, this); - retranslateUi(); - - auto chatLogIdxRange = iChatLog.getNextIdx() - iChatLog.getFirstIdx(); - auto firstChatLogIdx = chatLogIdxRange < 100 ? iChatLog.getFirstIdx() : iChatLog.getNextIdx() - 100; - - renderMessages(firstChatLogIdx, iChatLog.getNextIdx()); + footButtonsSmall->addStretch(1); + + QVBoxLayout* sendButtonLyt = new QVBoxLayout(); + sendButtonLyt->addStretch(1); + sendButtonLyt->addWidget(sendButton); + + QVBoxLayout* inputLayout = new QVBoxLayout(); + inputLayout->addLayout(footButtonsSmall); + inputLayout->setSpacing(FOOT_BUTTONS_SPACING); + inputLayout->addWidget(msgEdit); + + mainFootLayout = new QHBoxLayout(footContainer); + mainFootLayout->setContentsMargins(MAIN_FOOT_MARGIN, MAIN_FOOT_MARGIN, MAIN_FOOT_MARGIN, + MAIN_FOOT_MARGIN); + mainFootLayout->setSpacing(EDIT_SEND_SPACING); + mainFootLayout->addLayout(inputLayout); + mainFootLayout->addLayout(sendButtonLyt); + + QVBoxLayout* contentLayout = new QVBoxLayout(contentWidget); + contentLayout->setContentsMargins(0, 0, 0, 0); + // contentLayout->addWidget(searchForm); + // contentLayout->addWidget(dateInfo); + contentLayout->addWidget(chatLog, 1); + contentLayout->addWidget(footContainer, 0); + + quoteAction = menu.addAction(QIcon(), QString(), this, SLOT(quoteSelectedText()), + QKeySequence(Qt::ALT, Qt::Key_Q)); + addAction(quoteAction); + menu.addSeparator(); + + // searchAction = + // menu.addAction(QIcon(), QString(), this, SLOT(searchFormShow()), + // QKeySequence(Qt::CTRL + Qt::Key_F)); + // addAction(searchAction); + + menu.addSeparator(); + + menu.addActions(chatLog->actions()); + menu.addSeparator(); + + clearAction = + menu.addAction(QIcon::fromTheme("edit-clear"), QString(), this, SLOT(clearChatArea()), + QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_L)); + addAction(clearAction); + + copyLinkAction = menu.addAction(QIcon(), QString(), this, SLOT(copyLink())); + menu.addSeparator(); + + // loadHistoryAction = + // menu.addAction(QIcon(), QString(), this, SLOT(onLoadHistory())); + // exportChatAction = menu.addAction(QIcon::fromTheme("document-save"), + // QString(), this, SLOT(onExportChat())); + + connect(chatLog, &ChatLog::customContextMenuRequested, this, + &GenericChatForm::onChatContextMenuRequested); + connect(chatLog, &ChatLog::firstVisibleLineChanged, this, &GenericChatForm::updateShowDateInfo); + connect(chatLog, &ChatLog::loadHistoryLower, this, &GenericChatForm::loadHistoryLower); + + connect(&iChatLog, &IChatLog::itemUpdated, this, &GenericChatForm::renderMessage); + + // connect(searchForm, &SearchForm::searchInBegin, this, + // &GenericChatForm::searchInBegin); + // connect(searchForm, &SearchForm::searchUp, this, + // &GenericChatForm::onSearchUp); + // connect(searchForm, &SearchForm::searchDown, this, + // &GenericChatForm::onSearchDown); + // connect(searchForm, &SearchForm::visibleChanged, this, + // &GenericChatForm::onSearchTriggered); + // connect(this, &GenericChatForm::messageNotFoundShow, searchForm, + // &SearchForm::showMessageNotFound); + + connect(msgEdit, &ChatTextEdit::enterPressed, this, &GenericChatForm::onSendTriggered); + + connect(&GUI::getInstance(), &GUI::themeApplyRequest, this, &GenericChatForm::reloadTheme); + reloadTheme(); + + settings::Translator::registerHandler([this] { retranslateUi(); }, this); + retranslateUi(); + + auto chatLogIdxRange = iChatLog.getNextIdx() - iChatLog.getFirstIdx(); + auto firstChatLogIdx = + chatLogIdxRange < 100 ? iChatLog.getFirstIdx() : iChatLog.getNextIdx() - 100; + + renderMessages(firstChatLogIdx, iChatLog.getNextIdx()); } GenericChatForm::~GenericChatForm() { - qDebug()<<__func__; - settings::Translator::unregister(this); -// delete searchForm; + qDebug() << __func__; + settings::Translator::unregister(this); + // delete searchForm; } #ifdef OK_PLUGIN -void GenericChatForm::onPluginEnabled(const QString &shortName) { -// qDebug() << "Plugin is enabled" << shortName <<"for"<getDisplayedName(); - if (shortName == "omemo") { - auto encryptButton_ = - mainFootLayout->findChild("encryptButton"); - if (!encryptButton_) { - mainFootLayout->insertWidget(0, encryptButton); +void GenericChatForm::onPluginEnabled(const QString& shortName) { + // qDebug() << "Plugin is enabled" << shortName <<"for"<getDisplayedName(); + if (shortName == "omemo") { + auto encryptButton_ = mainFootLayout->findChild("encryptButton"); + if (!encryptButton_) { + mainFootLayout->insertWidget(0, encryptButton); + } + encryptButton->show(); } - encryptButton->show(); - } } -void GenericChatForm::onPluginDisabled(const QString &shortName) { - qDebug() << "Plugin is disabled." << shortName; - if (shortName == "omemo") { - encryptButton->hide(); - // mainFootLayout->removeWidget(encryptButton); - } +void GenericChatForm::onPluginDisabled(const QString& shortName) { + qDebug() << "Plugin is disabled." << shortName; + if (shortName == "omemo") { + encryptButton->hide(); + // mainFootLayout->removeWidget(encryptButton); + } } #endif -QDateTime GenericChatForm::getLatestTime() const { - return getTime(chatLog->getLatestLine()); -} +QDateTime GenericChatForm::getLatestTime() const { return getTime(chatLog->getLatestLine()); } -QDateTime GenericChatForm::getFirstTime() const { - return getTime(chatLog->getFirstLine()); -} +QDateTime GenericChatForm::getFirstTime() const { return getTime(chatLog->getFirstLine()); } void GenericChatForm::reloadTheme() { - const Settings &s = Settings::getInstance(); - setStyleSheet(Style::getStylesheet("genericChatForm/genericChatForm.css")); + const Settings& s = Settings::getInstance(); + setStyleSheet(Style::getStylesheet("genericChatForm/genericChatForm.css")); - msgEdit->setStyleSheet(Style::getStylesheet("msgEdit/msgEdit.css") + - fontToCss(s.getChatMessageFont(), "QTextEdit")); + msgEdit->setStyleSheet(Style::getStylesheet("msgEdit/msgEdit.css") + + fontToCss(s.getChatMessageFont(), "QTextEdit")); -// searchForm->reloadTheme(); + // searchForm->reloadTheme(); -// headWidget->setStyleSheet(Style::getStylesheet("chatArea/chatHead.css")); -// headWidget->reloadTheme(); + // headWidget->setStyleSheet(Style::getStylesheet("chatArea/chatHead.css")); + // headWidget->reloadTheme(); - chatLog->setStyleSheet(Style::getStylesheet("chatArea/chatArea.css")); - chatLog->reloadTheme(); + chatLog->setStyleSheet(Style::getStylesheet("chatArea/chatArea.css")); + chatLog->reloadTheme(); - fileButton->setStyleSheet(Style::getStylesheet(STYLE_PATH)); - emoteButton->setStyleSheet(Style::getStylesheet(STYLE_PATH)); - screenshotButton->setStyleSheet(Style::getStylesheet(STYLE_PATH)); - sendButton->setStyleSheet(Style::getStylesheet(STYLE_PATH)); + fileButton->setStyleSheet(Style::getStylesheet(STYLE_PATH)); + emoteButton->setStyleSheet(Style::getStylesheet(STYLE_PATH)); + screenshotButton->setStyleSheet(Style::getStylesheet(STYLE_PATH)); + sendButton->setStyleSheet(Style::getStylesheet(STYLE_PATH)); } -void GenericChatForm::setContact(const Contact *contact_) -{ -// qDebug()<<__func__<isGroup()){ + connect(contact, &Contact::displayedNameChanged, this, + &GenericChatForm::onDisplayedNameChanged); - }else{ + if (contact->isGroup()) { + } else { const Friend* f = static_cast(contact); - for(auto msg: messages){ - auto p = (ChatMessageBox *)msg.second.get(); + for (auto msg : messages) { + auto p = (ChatMessageBox*)msg.second.get(); p->nickname()->setText(f->getDisplayedName()); } } } -void GenericChatForm::removeContact() -{ - qDebug()<<__func__; +void GenericChatForm::removeContact() { + qDebug() << __func__; contact = nullptr; } -void GenericChatForm::show(ContentLayout *contentLayout) { - -} - -void GenericChatForm::showEvent(QShowEvent *) { - msgEdit->setFocus(); - if(contact){ - if (!contact->isGroup()) { - auto f = FriendList::findFriend(*contactId); - if (f) { - setContact(f); - } - } - } -} +void GenericChatForm::show(ContentLayout* contentLayout) {} -bool GenericChatForm::event(QEvent *e) { - // If the user accidentally starts typing outside of the msgEdit, focus it - // automatically - /* if (e->type() == QEvent::KeyPress) { - QKeyEvent *ke = static_cast(e); - if ((ke->modifiers() == Qt::NoModifier || - ke->modifiers() == Qt::ShiftModifier) && - !ke->text().isEmpty()) { - if (searchForm->isHidden()) { - msgEdit->sendKeyEvent(ke); - msgEdit->setFocus(); - } else { - searchForm->insertEditor(ke->text()); - searchForm->setFocusEditor(); - } +void GenericChatForm::showEvent(QShowEvent*) { + msgEdit->setFocus(); + if (contact) { + if (!contact->isGroup()) { + auto f = FriendList::findFriend(*contactId); + if (f) { + setContact(f); + } + } } - }*/ - return QWidget::event(e); } -void GenericChatForm::onDisplayedNameChanged(const QString &name) -{ - qDebug() <<__func__<< contactId->toString() << name; -// headWidget->setName(name); - for(auto msg: messages){ - auto it =msg.second; - auto p = (ChatMessageBox *)it.get(); +bool GenericChatForm::event(QEvent* e) { + // If the user accidentally starts typing outside of the msgEdit, focus it + // automatically + /* if (e->type() == QEvent::KeyPress) { + QKeyEvent *ke = static_cast(e); + if ((ke->modifiers() == Qt::NoModifier || + ke->modifiers() == Qt::ShiftModifier) && + !ke->text().isEmpty()) { + if (searchForm->isHidden()) { + msgEdit->sendKeyEvent(ke); + msgEdit->setFocus(); + } else { + searchForm->insertEditor(ke->text()); + searchForm->setFocusEditor(); + } + } + }*/ + return QWidget::event(e); +} + +void GenericChatForm::onDisplayedNameChanged(const QString& name) { + qDebug() << __func__ << contactId->toString() << name; + // headWidget->setName(name); + for (auto msg : messages) { + auto it = msg.second; + auto p = (ChatMessageBox*)it.get(); p->nickname()->setText(name); } } void GenericChatForm::onChatContextMenuRequested(QPoint pos) { - QWidget *sender = static_cast(QObject::sender()); - pos = sender->mapToGlobal(pos); - - // If we right-clicked on a link, give the option to copy it - bool clickedOnLink = false; - Text *clickedText = - qobject_cast(chatLog->getContentFromGlobalPos(pos)); - if (clickedText) { - QPointF scenePos = chatLog->mapToScene(chatLog->mapFromGlobal(pos)); - QString linkTarget = clickedText->getLinkAt(scenePos); - if (!linkTarget.isEmpty()) { - clickedOnLink = true; - copyLinkAction->setData(linkTarget); + QWidget* sender = static_cast(QObject::sender()); + pos = sender->mapToGlobal(pos); + + // If we right-clicked on a link, give the option to copy it + bool clickedOnLink = false; + Text* clickedText = qobject_cast(chatLog->getContentFromGlobalPos(pos)); + if (clickedText) { + QPointF scenePos = chatLog->mapToScene(chatLog->mapFromGlobal(pos)); + QString linkTarget = clickedText->getLinkAt(scenePos); + if (!linkTarget.isEmpty()) { + clickedOnLink = true; + copyLinkAction->setData(linkTarget); + } } - } - copyLinkAction->setVisible(clickedOnLink); + copyLinkAction->setVisible(clickedOnLink); - menu.exec(pos); + menu.exec(pos); } void GenericChatForm::onSendTriggered() { - auto msg = msgEdit->toPlainText(); + auto msg = msgEdit->toPlainText(); - bool isAction = msg.startsWith(ChatForm::ACTION_PREFIX, Qt::CaseInsensitive); - if (isAction) { - msg.remove(0, ChatForm::ACTION_PREFIX.length()); - } + bool isAction = msg.startsWith(ChatForm::ACTION_PREFIX, Qt::CaseInsensitive); + if (isAction) { + msg.remove(0, ChatForm::ACTION_PREFIX.length()); + } - if (msg.isEmpty()) { - return; - } + if (msg.isEmpty()) { + return; + } - msgEdit->setLastMessage(msg); - msgEdit->clear(); + msgEdit->setLastMessage(msg); + msgEdit->clear(); - qDebug() << "Input text:" << msg; - auto sent= messageDispatcher.sendMessage(isAction, msg, isEncrypt); - qDebug() << &messageDispatcher << "sendMessage=>" << sent.first.get() <" << sent.first.get() << sent.second; } /** @@ -622,432 +586,416 @@ void GenericChatForm::onSendTriggered() { * @return True if the name should be hidden, false otherwise */ bool GenericChatForm::needsToHideName(ChatLogIdx idx) const { - // If the previous message is not rendered we should show the name - // regardless of other constraints - auto itemBefore = messages.find(idx - 1); - if (itemBefore == messages.end()) { - return false; - } - - const auto prevItem = iChatLog.at(idx - 1); - const auto currentItem = iChatLog.at(idx); - if(!prevItem || !currentItem){ - return false; - } - // Always show the * in the name field for action messages - if (currentItem->getContentType() == ChatLogItem::ContentType::message && - currentItem->getContentAsMessage().message.isAction) { - return false; - } + // If the previous message is not rendered we should show the name + // regardless of other constraints + auto itemBefore = messages.find(idx - 1); + if (itemBefore == messages.end()) { + return false; + } + + const auto prevItem = iChatLog.at(idx - 1); + const auto currentItem = iChatLog.at(idx); + if (!prevItem || !currentItem) { + return false; + } + // Always show the * in the name field for action messages + if (currentItem->getContentType() == ChatLogItem::ContentType::message && + currentItem->getContentAsMessage().message.isAction) { + return false; + } - qint64 messagesTimeDiff = prevItem->getTimestamp().secsTo(currentItem->getTimestamp()); - return currentItem->getSender() == prevItem->getSender() && - messagesTimeDiff < chatLog->repNameAfter; + qint64 messagesTimeDiff = prevItem->getTimestamp().secsTo(currentItem->getTimestamp()); + return currentItem->getSender() == prevItem->getSender() && + messagesTimeDiff < chatLog->repNameAfter; } void GenericChatForm::onEncryptButtonClicked() { - auto btn = dynamic_cast(sender()); - btn->setChecked(!isEncrypt); - isEncrypt = btn->isChecked(); - qDebug() << "isEncrypt changed=>" << isEncrypt; + auto btn = dynamic_cast(sender()); + btn->setChecked(!isEncrypt); + isEncrypt = btn->isChecked(); + qDebug() << "isEncrypt changed=>" << isEncrypt; } void GenericChatForm::onEmoteButtonClicked() { - // don't show the smiley selection widget if there are no smileys available - if (SmileyPack::getInstance().getEmoticons().empty()) - return; - - - if(!emoticonsWidget){ - emoticonsWidget = new EmoticonsWidget(this); - emoticonsWidget->installEventFilter(this); - connect(emoticonsWidget, SIGNAL(insertEmoticon(QString)), - this, SLOT(onEmoteInsertRequested(QString))); - } - - QWidget *sender = qobject_cast(QObject::sender()); - if (sender) { - QPoint pos = - -QPoint(emoticonsWidget->sizeHint().width() / 2, emoticonsWidget->sizeHint().height()) - -QPoint(0, 10); - emoticonsWidget->exec(sender->mapToGlobal(pos)); - } + // don't show the smiley selection widget if there are no smileys available + if (SmileyPack::getInstance().getEmoticons().empty()) return; + + if (!emoticonsWidget) { + emoticonsWidget = new EmoticonsWidget(this); + emoticonsWidget->installEventFilter(this); + connect(emoticonsWidget, SIGNAL(insertEmoticon(QString)), this, + SLOT(onEmoteInsertRequested(QString))); + } + + QWidget* sender = qobject_cast(QObject::sender()); + if (sender) { + QPoint pos = -QPoint(emoticonsWidget->sizeHint().width() / 2, + emoticonsWidget->sizeHint().height()) - + QPoint(0, 10); + emoticonsWidget->exec(sender->mapToGlobal(pos)); + } } void GenericChatForm::onEmoteInsertRequested(QString str) { - // insert the emoticon - QWidget *sender = qobject_cast(QObject::sender()); - if (sender) - msgEdit->insertPlainText(str); - - // refocus so that we can continue typing - msgEdit->setFocus(); - - if(emoticonsWidget) - { - //close - emoticonsWidget->close(); - } + // insert the emoticon + QWidget* sender = qobject_cast(QObject::sender()); + if (sender) msgEdit->insertPlainText(str); + + // refocus so that we can continue typing + msgEdit->setFocus(); + + if (emoticonsWidget) { + // close + emoticonsWidget->close(); + } } void GenericChatForm::onCopyLogClicked() { chatLog->copySelectedText(); } void GenericChatForm::focusInput() { msgEdit->setFocus(); } -void GenericChatForm::onChatMessageFontChanged(const QFont &font) { - // chat log - chatLog->fontChanged(font); - chatLog->forceRelayout(); - // message editor - msgEdit->setStyleSheet(Style::getStylesheet("msgEdit/msgEdit.css") + - fontToCss(font, "QTextEdit")); +void GenericChatForm::onChatMessageFontChanged(const QFont& font) { + // chat log + chatLog->fontChanged(font); + chatLog->forceRelayout(); + // message editor + msgEdit->setStyleSheet(Style::getStylesheet("msgEdit/msgEdit.css") + + fontToCss(font, "QTextEdit")); } void GenericChatForm::setColorizedNames(bool enable) { colorizeNames = enable; } -void GenericChatForm::addSystemInfoMessage(const QString &message, +void GenericChatForm::addSystemInfoMessage(const QString& message, ChatMessage::SystemMessageType type, - const QDateTime &datetime) { - insertChatMessage( - ChatMessage::createChatInfoMessage(message, type, datetime)); + const QDateTime& datetime) { + insertChatMessage(ChatMessage::createChatInfoMessage(message, type, datetime)); } -void GenericChatForm::addSystemDateMessage(const QDate &date) { - const Settings &s = Settings::getInstance(); - QString dateText = date.toString(s.getDateFormat()); +void GenericChatForm::addSystemDateMessage(const QDate& date) { + const Settings& s = Settings::getInstance(); + QString dateText = date.toString(s.getDateFormat()); - insertChatMessage(ChatMessage::createChatInfoMessage( - dateText, ChatMessage::INFO, QDateTime())); + insertChatMessage(ChatMessage::createChatInfoMessage(dateText, ChatMessage::INFO, QDateTime())); } -QDateTime GenericChatForm::getTime(const IChatItem::Ptr &chatLine) const { - if (chatLine) { - return chatLine->getTime(); - } - return QDateTime(); +QDateTime GenericChatForm::getTime(const IChatItem::Ptr& chatLine) const { + if (chatLine) { + return chatLine->getTime(); + } + return QDateTime(); } void GenericChatForm::disableSearchText() { - auto msgIt = messages.find(searchPos.logIdx); - if (msgIt != messages.end()) { - auto text = qobject_cast(msgIt->second->centerContent()); - text->deselectText(); - } + auto msgIt = messages.find(searchPos.logIdx); + if (msgIt != messages.end()) { + auto text = qobject_cast(msgIt->second->centerContent()); + text->deselectText(); + } } - -void GenericChatForm::clearChatArea() { - clearChatArea(/* confirm = */ true, /* inform = */ true); -} +void GenericChatForm::clearChatArea() { clearChatArea(/* confirm = */ true, /* inform = */ true); } void GenericChatForm::clearChatArea(bool confirm, bool inform) { - if (confirm) { - QMessageBox::StandardButton mboxResult = QMessageBox::question( - this, tr("Confirmation"), - tr("You are sure that you want to clear all displayed messages?"), - QMessageBox::Yes | QMessageBox::No, QMessageBox::No); - if (mboxResult == QMessageBox::No) { - return; + if (confirm) { + QMessageBox::StandardButton mboxResult = QMessageBox::question( + this, tr("Confirmation"), + tr("You are sure that you want to clear all displayed messages?"), + QMessageBox::Yes | QMessageBox::No, QMessageBox::No); + if (mboxResult == QMessageBox::No) { + return; + } } - } - chatLog->clear(); + chatLog->clear(); - if (inform) - addSystemInfoMessage(tr("Cleared"), ChatMessage::INFO, - QDateTime::currentDateTime()); + if (inform) + addSystemInfoMessage(tr("Cleared"), ChatMessage::INFO, QDateTime::currentDateTime()); - messages.clear(); + messages.clear(); } void GenericChatForm::onSelectAllClicked() { chatLog->selectAll(); } void GenericChatForm::insertChatMessage(IChatItem::Ptr msg) { - chatLog->insertChatlineAtBottom(msg); - emit messageInserted(); + chatLog->insertChatlineAtBottom(msg); + emit messageInserted(); } -bool GenericChatForm::eventFilter(QObject *object, QEvent *event) { - EmoticonsWidget *ev = qobject_cast(object); - if (ev && event->type() == QEvent::KeyPress) { - QKeyEvent *key = static_cast(event); - msgEdit->sendKeyEvent(key); - msgEdit->setFocus(); +bool GenericChatForm::eventFilter(QObject* object, QEvent* event) { + EmoticonsWidget* ev = qobject_cast(object); + if (ev && event->type() == QEvent::KeyPress) { + QKeyEvent* key = static_cast(event); + msgEdit->sendKeyEvent(key); + msgEdit->setFocus(); + return false; + } return false; - } - return false; } void GenericChatForm::onSplitterMoved(int, int) { -// if (netcam) -// netcam->setShowMessages(bodySplitter->sizes()[1] == 0); + // if (netcam) + // netcam->setShowMessages(bodySplitter->sizes()[1] == 0); } void GenericChatForm::onShowMessagesClicked() { -// if (netcam) { -// if (bodySplitter->sizes()[1] == 0) -// bodySplitter->setSizes({1, 1}); -// else -// bodySplitter->setSizes({1, 0}); -// -// onSplitterMoved(0, 0); -// } + // if (netcam) { + // if (bodySplitter->sizes()[1] == 0) + // bodySplitter->setSizes({1, 1}); + // else + // bodySplitter->setSizes({1, 0}); + // + // onSplitterMoved(0, 0); + // } } void GenericChatForm::quoteSelectedText() { - QString selectedText = chatLog->getSelectedText(); + QString selectedText = chatLog->getSelectedText(); - if (selectedText.isEmpty()) - return; + if (selectedText.isEmpty()) return; - // forming pretty quote text - // 1. insert "> " to the begining of quote; - // 2. replace all possible line terminators with "\n> "; - // 3. append new line to the end of quote. - QString quote = selectedText; + // forming pretty quote text + // 1. insert "> " to the begining of quote; + // 2. replace all possible line terminators with "\n> "; + // 3. append new line to the end of quote. + QString quote = selectedText; - quote.insert(0, "> "); - quote.replace(QRegExp(QString("\r\n|[\r\n\u2028\u2029]")), QString("\n> ")); - quote.append("\n"); + quote.insert(0, "> "); + quote.replace(QRegExp(QString("\r\n|[\r\n\u2028\u2029]")), QString("\n> ")); + quote.append("\n"); - msgEdit->append(quote); + msgEdit->append(quote); } /** * @brief Callback of GenericChatForm::copyLinkAction */ void GenericChatForm::copyLink() { - QString linkText = copyLinkAction->data().toString(); - QApplication::clipboard()->setText(linkText); + QString linkText = copyLinkAction->data().toString(); + QApplication::clipboard()->setText(linkText); } void GenericChatForm::searchFormShow() { - /* if (searchForm->isHidden()) { - searchForm->show(); - searchForm->setFocusEditor(); - }*/ + /* if (searchForm->isHidden()) { + searchForm->show(); + searchForm->setFocusEditor(); + }*/ } void GenericChatForm::onLoadHistory() { - LoadHistoryDialog dlg(&iChatLog); - if (dlg.exec()) { - QDateTime time = dlg.getFromDate(); - auto idx = firstItemAfterDate(dlg.getFromDate().date(), iChatLog); - renderMessages(idx, iChatLog.getNextIdx()); - } + LoadHistoryDialog dlg(&iChatLog); + if (dlg.exec()) { + QDateTime time = dlg.getFromDate(); + auto idx = firstItemAfterDate(dlg.getFromDate().date(), iChatLog); + renderMessages(idx, iChatLog.getNextIdx()); + } } void GenericChatForm::onExportChat() { - QString path = QFileDialog::getSaveFileName(Q_NULLPTR, tr("Save chat log")); - if (path.isEmpty()) { - return; - } - - QFile file(path); - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { - return; - } - - QString buffer; - for (auto i = iChatLog.getFirstIdx(); i < iChatLog.getNextIdx(); ++i) { - const auto &item = iChatLog.at(i); - if (!item || item->getContentType() != ChatLogItem::ContentType::message) { - continue; + QString path = QFileDialog::getSaveFileName(Q_NULLPTR, tr("Save chat log")); + if (path.isEmpty()) { + return; } - QString timestamp = item->getTimestamp().time().toString("hh:mm:ss"); - QString datestamp = item->getTimestamp().date().toString("yyyy-MM-dd"); - QString author = item->getDisplayName(); + QFile file(path); + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { + return; + } - buffer = - buffer % QString{datestamp % '\t' % timestamp % '\t' % author % '\t' % - item->getContentAsMessage().message.content % '\n'}; - } - file.write(buffer.toUtf8()); - file.close(); + QString buffer; + for (auto i = iChatLog.getFirstIdx(); i < iChatLog.getNextIdx(); ++i) { + const auto& item = iChatLog.at(i); + if (!item || item->getContentType() != ChatLogItem::ContentType::message) { + continue; + } + + QString timestamp = item->getTimestamp().time().toString("hh:mm:ss"); + QString datestamp = item->getTimestamp().date().toString("yyyy-MM-dd"); + QString author = item->getDisplayName(); + + buffer = buffer % QString{datestamp % '\t' % timestamp % '\t' % author % '\t' % + item->getContentAsMessage().message.content % '\n'}; + } + file.write(buffer.toUtf8()); + file.close(); } void GenericChatForm::onSearchTriggered() { - //if (searchForm->isHidden()) { - // searchForm->removeSearchPhrase(); - //} - disableSearchText(); -} + // if (searchForm->isHidden()) { + // searchForm->removeSearchPhrase(); + // } + disableSearchText(); +} + +void GenericChatForm::searchInBegin(const QString& phrase, const ParameterSearch& parameter) { + disableSearchText(); + + bool bForwardSearch = false; + switch (parameter.period) { + case PeriodSearch::WithTheFirst: { + bForwardSearch = true; + searchPos.logIdx = iChatLog.getFirstIdx(); + searchPos.numMatches = 0; + break; + } + case PeriodSearch::WithTheEnd: + case PeriodSearch::None: { + bForwardSearch = false; + searchPos.logIdx = iChatLog.getNextIdx(); + searchPos.numMatches = 0; + break; + } + case PeriodSearch::AfterDate: { + bForwardSearch = true; + searchPos.logIdx = firstItemAfterDate(parameter.date, iChatLog); + searchPos.numMatches = 0; + break; + } + case PeriodSearch::BeforeDate: { + bForwardSearch = false; + searchPos.logIdx = firstItemAfterDate(parameter.date, iChatLog); + searchPos.numMatches = 0; + break; + } + } -void GenericChatForm::searchInBegin(const QString &phrase, - const ParameterSearch ¶meter) { - disableSearchText(); - - bool bForwardSearch = false; - switch (parameter.period) { - case PeriodSearch::WithTheFirst: { - bForwardSearch = true; - searchPos.logIdx = iChatLog.getFirstIdx(); - searchPos.numMatches = 0; - break; - } - case PeriodSearch::WithTheEnd: - case PeriodSearch::None: { - bForwardSearch = false; - searchPos.logIdx = iChatLog.getNextIdx(); - searchPos.numMatches = 0; - break; - } - case PeriodSearch::AfterDate: { - bForwardSearch = true; - searchPos.logIdx = firstItemAfterDate(parameter.date, iChatLog); - searchPos.numMatches = 0; - break; - } - case PeriodSearch::BeforeDate: { - bForwardSearch = false; - searchPos.logIdx = firstItemAfterDate(parameter.date, iChatLog); - searchPos.numMatches = 0; - break; - } - } - - if (bForwardSearch) { - onSearchDown(phrase, parameter); - } else { - onSearchUp(phrase, parameter); - } + if (bForwardSearch) { + onSearchDown(phrase, parameter); + } else { + onSearchUp(phrase, parameter); + } } -void GenericChatForm::onSearchUp(const QString &phrase, - const ParameterSearch ¶meter) { - auto result = iChatLog.searchBackward(searchPos, phrase, parameter); - handleSearchResult(result, SearchDirection::Up); +void GenericChatForm::onSearchUp(const QString& phrase, const ParameterSearch& parameter) { + auto result = iChatLog.searchBackward(searchPos, phrase, parameter); + handleSearchResult(result, SearchDirection::Up); } -void GenericChatForm::onSearchDown(const QString &phrase, - const ParameterSearch ¶meter) { - auto result = iChatLog.searchForward(searchPos, phrase, parameter); - handleSearchResult(result, SearchDirection::Down); +void GenericChatForm::onSearchDown(const QString& phrase, const ParameterSearch& parameter) { + auto result = iChatLog.searchForward(searchPos, phrase, parameter); + handleSearchResult(result, SearchDirection::Down); } -void GenericChatForm::handleSearchResult(SearchResult result, - SearchDirection direction) { - if (!result.found) { - emit messageNotFoundShow(direction); - return; - } +void GenericChatForm::handleSearchResult(SearchResult result, SearchDirection direction) { + if (!result.found) { + emit messageNotFoundShow(direction); + return; + } - disableSearchText(); + disableSearchText(); - searchPos = result.pos; + searchPos = result.pos; - auto const firstRenderedIdx = - (messages.empty()) ? iChatLog.getNextIdx() : messages.begin()->first; + auto const firstRenderedIdx = + (messages.empty()) ? iChatLog.getNextIdx() : messages.begin()->first; - renderMessages(searchPos.logIdx, firstRenderedIdx, [this, result] { - auto msg = messages.at(searchPos.logIdx); - chatLog->scrollToLine(msg); + renderMessages(searchPos.logIdx, firstRenderedIdx, [this, result] { + auto msg = messages.at(searchPos.logIdx); + chatLog->scrollToLine(msg); - auto text = qobject_cast(msg->centerContent()); - text->selectText(result.exp, std::make_pair(result.start, result.len)); - }); + auto text = qobject_cast(msg->centerContent()); + text->selectText(result.exp, std::make_pair(result.start, result.len)); + }); } void GenericChatForm::renderMessage(ChatLogIdx idx) { - qDebug()<<__func__ << "for contact:" << contactId->toString() << "message log index:"<toString() + << "message log index:" << idx.get(); + renderMessages(idx, idx + 1); } -void GenericChatForm::renderMessages(ChatLogIdx begin, ChatLogIdx end, std::function onCompletion) { - QList beforeLines; - QList afterLines; +void GenericChatForm::renderMessages(ChatLogIdx begin, ChatLogIdx end, + std::function onCompletion) { + QList beforeLines; + QList afterLines; - for (auto i = begin; i < end; ++i) { - auto item = iChatLog.at(i); - if(!item){ - qWarning() <<"chatLog have no msg idx is:" << i.get(); - continue; - } + for (auto i = begin; i < end; ++i) { + auto item = iChatLog.at(i); + if (!item) { + qWarning() << "chatLog have no msg idx is:" << i.get(); + continue; + } - auto chatMessage = getChatMessageForIdx(i, messages); - renderItem(*item, needsToHideName(i), colorizeNames, chatMessage); + auto chatMessage = getChatMessageForIdx(i, messages); + renderItem(*item, needsToHideName(i), colorizeNames, chatMessage); - if (messages.find(i) == messages.end()) { - QList *lines = - (messages.empty() || i > messages.rbegin()->first) ? &afterLines - : &beforeLines; + if (messages.find(i) == messages.end()) { + QList* lines = + (messages.empty() || i > messages.rbegin()->first) ? &afterLines : &beforeLines; - messages.insert({i, chatMessage}); + messages.insert({i, chatMessage}); - if (shouldRenderDate(i, iChatLog)) { - auto msg=iChatLog.at(i); - if(msg) - lines->push_back(dateMessageForItem(*msg)); - } - lines->push_back(chatMessage); + if (shouldRenderDate(i, iChatLog)) { + auto msg = iChatLog.at(i); + if (msg) lines->push_back(dateMessageForItem(*msg)); + } + lines->push_back(chatMessage); + } } - } - - for (auto const &line : afterLines) { - chatLog->insertChatlineAtBottom(line); - } - - if (!beforeLines.empty()) { - // Rendering upwards is expensive and has async behavior for chatLog. - // Once rendering completes we call our completion callback once and - // then disconnect the signal - if (onCompletion) { - auto connection = std::make_shared(); - *connection = connect(chatLog, &ChatLog::workerTimeoutFinished, - [onCompletion, connection] { - onCompletion(); - disconnect(*connection); - }); + + for (auto const& line : afterLines) { + chatLog->insertChatlineAtBottom(line); } - chatLog->insertChatlinesOnTop(beforeLines); - } else if (onCompletion) { - onCompletion(); - } + if (!beforeLines.empty()) { + // Rendering upwards is expensive and has async behavior for chatLog. + // Once rendering completes we call our completion callback once and + // then disconnect the signal + if (onCompletion) { + auto connection = std::make_shared(); + *connection = + connect(chatLog, &ChatLog::workerTimeoutFinished, [onCompletion, connection] { + onCompletion(); + disconnect(*connection); + }); + } + + chatLog->insertChatlinesOnTop(beforeLines); + } else if (onCompletion) { + onCompletion(); + } } void GenericChatForm::loadHistoryLower() { - auto begin = messages.begin()->first; + auto begin = messages.begin()->first; - if (begin.get() > 100) { - begin = ChatLogIdx(begin.get() - 100); - } else { - begin = ChatLogIdx(0); - } - - renderMessages(begin, iChatLog.getNextIdx()); -} + if (begin.get() > 100) { + begin = ChatLogIdx(begin.get() - 100); + } else { + begin = ChatLogIdx(0); + } -void GenericChatForm::updateShowDateInfo(const IChatItem::Ptr &prevLine, - const IChatItem::Ptr &topLine) { - // If the dateInfo is visible we need to pretend the top line is the one - // covered by the date to prevent oscillations -// const auto effectiveTopLine = -// (dateInfo->isVisible() && prevLine) ? prevLine : topLine; -// -// const auto date = getTime(effectiveTopLine); -// -// if (date.isValid() && date.date() != QDate::currentDate()) { -// const auto dateText = -// QStringLiteral("%1<\b>") -// .arg(date.toString(Settings::getInstance().getDateFormat())); -// dateInfo->setText(dateText); -// dateInfo->setVisible(true); -// } else { -// dateInfo->setVisible(false); -// } + renderMessages(begin, iChatLog.getNextIdx()); +} + +void GenericChatForm::updateShowDateInfo(const IChatItem::Ptr& prevLine, + const IChatItem::Ptr& topLine) { + // If the dateInfo is visible we need to pretend the top line is the one + // covered by the date to prevent oscillations + // const auto effectiveTopLine = + // (dateInfo->isVisible() && prevLine) ? prevLine : topLine; + // + // const auto date = getTime(effectiveTopLine); + // + // if (date.isValid() && date.date() != QDate::currentDate()) { + // const auto dateText = + // QStringLiteral("%1<\b>") + // .arg(date.toString(Settings::getInstance().getDateFormat())); + // dateInfo->setText(dateText); + // dateInfo->setVisible(true); + // } else { + // dateInfo->setVisible(false); + // } } void GenericChatForm::retranslateUi() { - sendButton->setToolTip(tr("Send message")); - emoteButton->setToolTip(tr("Smileys")); - fileButton->setToolTip(tr("Send file(s)")); - screenshotButton->setToolTip(tr("Send a screenshot")); - clearAction->setText(tr("Clear displayed messages")); - quoteAction->setText(tr("Quote")); - copyLinkAction->setText(tr("Copy link address")); - // searchAction->setText(tr("Search in text")); - // loadHistoryAction->setText(tr("Load chat history..."));selected text - // exportChatAction->setText(tr("Export to file")); + sendButton->setToolTip(tr("Send message")); + emoteButton->setToolTip(tr("Smileys")); + fileButton->setToolTip(tr("Send file(s)")); + screenshotButton->setToolTip(tr("Send a screenshot")); + clearAction->setText(tr("Clear displayed messages")); + quoteAction->setText(tr("Quote")); + copyLinkAction->setText(tr("Copy link address")); + // searchAction->setText(tr("Search in text")); + // loadHistoryAction->setText(tr("Load chat history..."));selected text + // exportChatAction->setText(tr("Export to file")); } diff --git a/src/modules/im/src/widget/form/genericchatform.h b/src/modules/im/src/widget/form/genericchatform.h index c8914259..3c4d94f9 100644 --- a/src/modules/im/src/widget/form/genericchatform.h +++ b/src/modules/im/src/widget/form/genericchatform.h @@ -59,8 +59,7 @@ class SpellCheckDecorator; } #endif -class GenericChatForm : public QWidget -{ +class GenericChatForm : public QWidget { Q_OBJECT public: GenericChatForm(const ContactId* contact, @@ -69,7 +68,6 @@ class GenericChatForm : public QWidget QWidget* parent = nullptr); ~GenericChatForm() override; - void setContact(const Contact* contact); void removeContact(); @@ -83,9 +81,7 @@ class GenericChatForm : public QWidget QDateTime getLatestTime() const; QDateTime getFirstTime() const; - [[__nodiscard__]] inline ChatLog *getChatLog() const{ - return chatLog; - } + [[__nodiscard__]] inline ChatLog* getChatLog() const { return chatLog; } signals: void messageInserted(); @@ -119,7 +115,7 @@ protected slots: void onExportChat(); void searchFormShow(); void onSearchTriggered(); - void updateShowDateInfo(const IChatItem::Ptr &prevLine, const IChatItem::Ptr &topLine); + void updateShowDateInfo(const IChatItem::Ptr& prevLine, const IChatItem::Ptr& topLine); void searchInBegin(const QString& phrase, const ParameterSearch& parameter); void onSearchUp(const QString& phrase, const ParameterSearch& parameter); @@ -132,8 +128,8 @@ protected slots: void loadHistoryLower(); #ifdef OK_PLUGIN - void onPluginEnabled(const QString &shortName); - void onPluginDisabled(const QString &shortName); + void onPluginEnabled(const QString& shortName); + void onPluginDisabled(const QString& shortName); #endif private: @@ -143,13 +139,16 @@ protected slots: protected: // ChatMessage::Ptr createMessage(const ToxPk& author, const QString& message, - // const QDateTime& datetime, bool isAction, bool isSent, bool colorizeName = false); + // const QDateTime& datetime, bool isAction, bool isSent, bool + // colorizeName = false); bool needsToHideName(ChatLogIdx idx) const; void disableSearchText(); - bool searchInText(const QString& phrase, const ParameterSearch& parameter, SearchDirection direction); - std::pair indexForSearchInLine(const QString& txt, const QString& phrase, const ParameterSearch& parameter, SearchDirection direction); - + bool searchInText(const QString& phrase, const ParameterSearch& parameter, + SearchDirection direction); + std::pair indexForSearchInLine(const QString& txt, const QString& phrase, + const ParameterSearch& parameter, + SearchDirection direction); virtual void insertChatMessage(IChatItem::Ptr msg); @@ -157,11 +156,9 @@ protected slots: virtual bool event(QEvent*) final override; virtual bool eventFilter(QObject* object, QEvent* event) final override; - protected: const ContactId* contactId; - const Contact *contact = nullptr; - + const Contact* contact = nullptr; bool audioInputFlag; bool audioOutputFlag; @@ -175,7 +172,7 @@ protected slots: // QAction* exportChatAction; QMenu menu; - QHBoxLayout *mainFootLayout; + QHBoxLayout* mainFootLayout; bool isEncrypt; QPushButton* encryptButton; @@ -186,9 +183,9 @@ protected slots: QSplitter* bodySplitter; -// SearchForm *searchForm; + // SearchForm *searchForm; -// QLabel *dateInfo; + // QLabel *dateInfo; ChatLog* chatLog; ChatTextEdit* msgEdit; #ifdef SPELL_CHECKING @@ -205,4 +202,4 @@ protected slots: EmoticonsWidget* emoticonsWidget; }; -#endif // GENERICCHATFORM_H +#endif // GENERICCHATFORM_H diff --git a/src/modules/im/src/widget/form/groupchatform.cpp b/src/modules/im/src/widget/form/groupchatform.cpp index 9428e713..457b6192 100644 --- a/src/modules/im/src/widget/form/groupchatform.cpp +++ b/src/modules/im/src/widget/form/groupchatform.cpp @@ -38,14 +38,13 @@ #include #include -namespace -{ +namespace { const auto LABEL_PEER_TYPE_OUR = QVariant(QStringLiteral("our")); const auto LABEL_PEER_TYPE_MUTED = QVariant(QStringLiteral("muted")); const auto LABEL_PEER_PLAYING_AUDIO = QVariant(QStringLiteral("true")); const auto LABEL_PEER_NOT_PLAYING_AUDIO = QVariant(QStringLiteral("false")); const auto PEER_LABEL_STYLE_SHEET_PATH = QStringLiteral("chatArea/chatHead.css"); -} +} // namespace /** * @brief Edit name for correct representation if it is needed @@ -53,8 +52,7 @@ const auto PEER_LABEL_STYLE_SHEET_PATH = QStringLiteral("chatArea/chatHead.css") * @return Source name if it does not contain any newline character, otherwise it chops characters * starting with first newline character and appends "..." */ -QString editName(const QString& name) -{ +QString editName(const QString& name) { const int pos = name.indexOf(QRegularExpression(QStringLiteral("[\n\r]"))); if (pos == -1) { return name; @@ -63,7 +61,7 @@ QString editName(const QString& name) QString result = name; const int len = result.length(); result.chop(len - pos); - //TODO: ... result.append(("…")); // \u2026 Unicode symbol, not just three separate dots + // TODO: ... result.append(("…")); // \u2026 Unicode symbol, not just three separate dots return result; } @@ -75,70 +73,69 @@ QString editName(const QString& name) * @brief Timeout = peer stopped sending audio. */ -GroupChatForm::GroupChatForm(const GroupId* chatGroup, IChatLog& chatLog, IMessageDispatcher& messageDispatcher, IGroupSettings& _settings) - : GenericChatForm(chatGroup, chatLog, messageDispatcher) - , group(chatGroup) - , inCall(false) - , settings(_settings) -{ +GroupChatForm::GroupChatForm(const GroupId* chatGroup, IChatLog& chatLog, + IMessageDispatcher& messageDispatcher, IGroupSettings& _settings) + : GenericChatForm(chatGroup, chatLog, messageDispatcher) + , group(chatGroup) + , inCall(false) + , settings(_settings) { nusersLabel = new QLabel(); -// tabber = new TabCompleter(msgEdit, group); + // tabber = new TabCompleter(msgEdit, group); fileButton->setEnabled(false); fileButton->setProperty("state", ""); ChatFormHeader::Mode mode = ChatFormHeader::Mode::None; -// if (group->isAvGroupchat()) { -// mode = ChatFormHeader::Mode::Audio; -// } + // if (group->isAvGroupchat()) { + // mode = ChatFormHeader::Mode::Audio; + // } -// headWidget->setMode(mode); -// setName(group->getName()); + // headWidget->setMode(mode); + // setName(group->getName()); nusersLabel->setFont(Style::getFont(Style::Medium)); nusersLabel->setObjectName("statusLabel"); retranslateUi(); -// const QSize& size = headWidget->getAvatarSize(); -// headWidget->setAvatar(Style::scaleSvgImage(":/img/group_dark.svg", size.width(), size.height())); + // const QSize& size = headWidget->getAvatarSize(); + // headWidget->setAvatar(Style::scaleSvgImage(":/img/group_dark.svg", size.width(), + // size.height())); msgEdit->setObjectName("group"); -// namesListLayout = new FlowLayout(0, 5, 0); -// headWidget->addWidget(nusersLabel); -// headWidget->addLayout(namesListLayout); -// headWidget->addStretch(); + // namesListLayout = new FlowLayout(0, 5, 0); + // headWidget->addWidget(nusersLabel); + // headWidget->addLayout(namesListLayout); + // headWidget->addStretch(); -// nameLabel->setMinimumHeight(12); + // nameLabel->setMinimumHeight(12); nusersLabel->setMinimumHeight(12); -// connect(msgEdit, &ChatTextEdit::tabPressed, tabber, &TabCompleter::complete); -// connect(msgEdit, &ChatTextEdit::keyPressed, tabber, &TabCompleter::reset); + // connect(msgEdit, &ChatTextEdit::tabPressed, tabber, &TabCompleter::complete); + // connect(msgEdit, &ChatTextEdit::keyPressed, tabber, &TabCompleter::reset); -// connect(headWidget, &ChatFormHeader::callTriggered, this, &GroupChatForm::onCallClicked); -// connect(headWidget, &ChatFormHeader::micMuteToggle, this, &GroupChatForm::onMicMuteToggle); -// connect(headWidget, &ChatFormHeader::volMuteToggle, this, &GroupChatForm::onVolMuteToggle); + // connect(headWidget, &ChatFormHeader::callTriggered, this, &GroupChatForm::onCallClicked); + // connect(headWidget, &ChatFormHeader::micMuteToggle, this, + // &GroupChatForm::onMicMuteToggle); connect(headWidget, &ChatFormHeader::volMuteToggle, + // this, &GroupChatForm::onVolMuteToggle); -// connect(headWidget, &ChatFormHeader::nameChanged, chatGroup, &Group::setName); -// connect(group, &Group::subjectChanged, this, &GroupChatForm::onTitleChanged); -// connect(group, &Group::userJoined, this, &GroupChatForm::onUserJoined); -// connect(group, &Group::userLeft, this, &GroupChatForm::onUserLeft); -// connect(group, &Group::peerNameChanged, this, &GroupChatForm::onPeerNameChanged); -// connect(group, &Group::peerCountChanged, this, &GroupChatForm::updateUserCount); - settings.connectTo_blackListChanged(this, [this](QStringList const&) { this->updateUserNames(); }); + // connect(headWidget, &ChatFormHeader::nameChanged, chatGroup, &Group::setName); + // connect(group, &Group::subjectChanged, this, &GroupChatForm::onTitleChanged); + // connect(group, &Group::userJoined, this, &GroupChatForm::onUserJoined); + // connect(group, &Group::userLeft, this, &GroupChatForm::onUserLeft); + // connect(group, &Group::peerNameChanged, this, &GroupChatForm::onPeerNameChanged); + // connect(group, &Group::peerCountChanged, this, &GroupChatForm::updateUserCount); + settings.connectTo_blackListChanged(this, + [this](QStringList const&) { this->updateUserNames(); }); -// updateUserNames(); + // updateUserNames(); setAcceptDrops(true); settings::Translator::registerHandler(std::bind(&GroupChatForm::retranslateUi, this), this); } -GroupChatForm::~GroupChatForm() -{ - settings::Translator::unregister(this); -} +GroupChatForm::~GroupChatForm() { settings::Translator::unregister(this); } -void GroupChatForm::onTitleChanged(const QString& author, const QString& title) -{ +void GroupChatForm::onTitleChanged(const QString& author, const QString& title) { if (author.isEmpty()) { return; } @@ -148,21 +145,18 @@ void GroupChatForm::onTitleChanged(const QString& author, const QString& title) addSystemInfoMessage(message, ChatMessage::INFO, curTime); } -void GroupChatForm::onScreenshotClicked() -{ +void GroupChatForm::onScreenshotClicked() { // Unsupported } -void GroupChatForm::onAttachClicked() -{ +void GroupChatForm::onAttachClicked() { // Unsupported } /** * @brief Updates user names' labels at the top of group chat */ -void GroupChatForm::updateUserNames() -{ +void GroupChatForm::updateUserNames() { QLayoutItem* child; while ((child = namesListLayout->takeAt(0))) { child->widget()->hide(); @@ -171,51 +165,50 @@ void GroupChatForm::updateUserNames() } peerLabels.clear(); -// const auto peers = group->getPeerList(); + // const auto peers = group->getPeerList(); // no need to do anything without any peers -// if (peers.isEmpty()) { -// return; -// } + // if (peers.isEmpty()) { + // return; + // } /* we store the peer labels by their ToxPk, but the namelist layout * needs it in alphabetical order, so we first create and store the labels * and then sort them by their text and add them to the layout in that order */ const auto selfPk = Core::getInstance()->getSelfId(); -// for (const auto& peerPk : peers.keys()) { -// const QString peerName = peers.value(peerPk); -// const QString editedName = editName(peerName); -// QLabel* const label = new QLabel(editedName + QLatin1String(", ")); -// if (editedName != peerName) { -// label->setToolTip(peerName + " (" + peerPk + ")"); -// } else if (peerName != peerPk ) { -// label->setToolTip(peerPk ); -// } // else their name is just their Pk, no tooltip needed -// label->setTextFormat(Qt::PlainText); -// label->setContextMenuPolicy(Qt::CustomContextMenu); - -// connect(label, &QLabel::customContextMenuRequested, this, &GroupChatForm::onLabelContextMenuRequested); - -// if (peerPk == selfPk.toString()) { -// label->setProperty("peerType", LABEL_PEER_TYPE_OUR); -// } else if (settings.getBlackList().contains(peerPk)) { -// label->setProperty("peerType", LABEL_PEER_TYPE_MUTED); -// } - -// label->setStyleSheet(Style::getStylesheet(PEER_LABEL_STYLE_SHEET_PATH)); -// peerLabels.insert(peerPk, label); -// } - + // for (const auto& peerPk : peers.keys()) { + // const QString peerName = peers.value(peerPk); + // const QString editedName = editName(peerName); + // QLabel* const label = new QLabel(editedName + QLatin1String(", ")); + // if (editedName != peerName) { + // label->setToolTip(peerName + " (" + peerPk + ")"); + // } else if (peerName != peerPk ) { + // label->setToolTip(peerPk ); + // } // else their name is just their Pk, no tooltip needed + // label->setTextFormat(Qt::PlainText); + // label->setContextMenuPolicy(Qt::CustomContextMenu); + + // connect(label, &QLabel::customContextMenuRequested, this, + // &GroupChatForm::onLabelContextMenuRequested); + + // if (peerPk == selfPk.toString()) { + // label->setProperty("peerType", LABEL_PEER_TYPE_OUR); + // } else if (settings.getBlackList().contains(peerPk)) { + // label->setProperty("peerType", LABEL_PEER_TYPE_MUTED); + // } + + // label->setStyleSheet(Style::getStylesheet(PEER_LABEL_STYLE_SHEET_PATH)); + // peerLabels.insert(peerPk, label); + // } // add the labels in alphabetical order into the layout auto nickLabelList = peerLabels.values(); - std::sort(nickLabelList.begin(), nickLabelList.end(), [](const QLabel* a, const QLabel* b) - { + std::sort(nickLabelList.begin(), nickLabelList.end(), [](const QLabel* a, const QLabel* b) { return a->text().toLower() < b->text().toLower(); }); // remove comma from last sorted label - if(!nickLabelList.isEmpty()){ + if (!nickLabelList.isEmpty()) { QLabel* const lastLabel = nickLabelList.last(); QString labelText = lastLabel->text(); labelText.chop(2); @@ -226,30 +219,30 @@ void GroupChatForm::updateUserNames() } } -void GroupChatForm::onUserJoined(const FriendId& user, const QString& name) -{ +void GroupChatForm::onUserJoined(const FriendId& user, const QString& name) { if (settings.getShowGroupJoinLeaveMessages()) { - addSystemInfoMessage(tr("%1 has joined the group").arg(name), ChatMessage::INFO, QDateTime::currentDateTime()); + addSystemInfoMessage(tr("%1 has joined the group").arg(name), ChatMessage::INFO, + QDateTime::currentDateTime()); } updateUserNames(); } -void GroupChatForm::onUserLeft(const FriendId& user, const QString& name) -{ +void GroupChatForm::onUserLeft(const FriendId& user, const QString& name) { if (settings.getShowGroupJoinLeaveMessages()) { - addSystemInfoMessage(tr("%1 has left the group").arg(name), ChatMessage::INFO, QDateTime::currentDateTime()); + addSystemInfoMessage(tr("%1 has left the group").arg(name), ChatMessage::INFO, + QDateTime::currentDateTime()); } updateUserNames(); } -void GroupChatForm::onPeerNameChanged(const FriendId& peer, const QString& oldName, const QString& newName) -{ - addSystemInfoMessage(tr("%1 is now known as %2").arg(oldName, newName), ChatMessage::INFO, QDateTime::currentDateTime()); +void GroupChatForm::onPeerNameChanged(const FriendId& peer, const QString& oldName, + const QString& newName) { + addSystemInfoMessage(tr("%1 is now known as %2").arg(oldName, newName), ChatMessage::INFO, + QDateTime::currentDateTime()); updateUserNames(); } -void GroupChatForm::peerAudioPlaying(QString peerPk) -{ +void GroupChatForm::peerAudioPlaying(QString peerPk) { peerLabels[peerPk]->setProperty("playingAudio", LABEL_PEER_PLAYING_AUDIO); peerLabels[peerPk]->style()->unpolish(peerLabels[peerPk]); peerLabels[peerPk]->style()->polish(peerLabels[peerPk]); @@ -273,113 +266,98 @@ void GroupChatForm::peerAudioPlaying(QString peerPk) peerAudioTimers[peerPk]->start(500); } -void GroupChatForm::dragEnterEvent(QDragEnterEvent* ev) -{ +void GroupChatForm::dragEnterEvent(QDragEnterEvent* ev) { if (!ev->mimeData()->hasFormat("toxPk")) { return; } FriendId toxPk{ev->mimeData()->data("toxPk")}; Friend* frnd = FriendList::findFriend(toxPk); - if (frnd) - ev->acceptProposedAction(); + if (frnd) ev->acceptProposedAction(); } -void GroupChatForm::dropEvent(QDropEvent* ev) -{ +void GroupChatForm::dropEvent(QDropEvent* ev) { if (!ev->mimeData()->hasFormat("toxPk")) { return; } FriendId toxPk{ev->mimeData()->data("toxPk")}; Friend* frnd = FriendList::findFriend(toxPk); - if (!frnd) - return; + if (!frnd) return; QString friendId = frnd->getId().toString(); QString cid = contactId->toString(); if (Status::isOnline(frnd->getStatus())) { -// Core::getInstance()->groupInviteFriend(friendId, cid); + // Core::getInstance()->groupInviteFriend(friendId, cid); } } -void GroupChatForm::onMicMuteToggle() -{ +void GroupChatForm::onMicMuteToggle() { if (audioInputFlag) { -// CoreAV* av = Core::getInstance()->getAv(); -// const bool oldMuteState = av->isGroupCallInputMuted(group); -// const bool newMute = !oldMuteState; -// av->muteCallInput(group, newMute); -// headWidget->updateMuteMicButton(inCall, newMute); + // CoreAV* av = Core::getInstance()->getAv(); + // const bool oldMuteState = av->isGroupCallInputMuted(group); + // const bool newMute = !oldMuteState; + // av->muteCallInput(group, newMute); + // headWidget->updateMuteMicButton(inCall, newMute); } } -void GroupChatForm::onVolMuteToggle() -{ +void GroupChatForm::onVolMuteToggle() { if (audioOutputFlag) { -// CoreAV* av = Core::getInstance()->getAv(); -// const bool oldMuteState = av->isGroupCallOutputMuted(group); -// const bool newMute = !oldMuteState; -// av->muteCallOutput(group, newMute); -// headWidget->updateMuteVolButton(inCall, newMute); + // CoreAV* av = Core::getInstance()->getAv(); + // const bool oldMuteState = av->isGroupCallOutputMuted(group); + // const bool newMute = !oldMuteState; + // av->muteCallOutput(group, newMute); + // headWidget->updateMuteVolButton(inCall, newMute); } } -void GroupChatForm::onCallClicked() -{ - +void GroupChatForm::onCallClicked() { if (!inCall) { joinGroupCall(); } else { leaveGroupCall(); } -// headWidget->updateCallButtons(true, inCall); + // headWidget->updateCallButtons(true, inCall); -// CoreAV* av = Core::getInstance()->getAv(); -// const bool inMute = av->isGroupCallInputMuted(group); -// headWidget->updateMuteMicButton(inCall, inMute); + // CoreAV* av = Core::getInstance()->getAv(); + // const bool inMute = av->isGroupCallInputMuted(group); + // headWidget->updateMuteMicButton(inCall, inMute); -// const bool outMute = av->isGroupCallOutputMuted(group); -// headWidget->updateMuteVolButton(inCall, outMute); + // const bool outMute = av->isGroupCallOutputMuted(group); + // headWidget->updateMuteVolButton(inCall, outMute); } -void GroupChatForm::keyPressEvent(QKeyEvent* ev) -{ +void GroupChatForm::keyPressEvent(QKeyEvent* ev) { // Push to talk (CTRL+P) if (ev->key() == Qt::Key_P && (ev->modifiers() & Qt::ControlModifier) && inCall) { onMicMuteToggle(); } - if (msgEdit->hasFocus()) - return; + if (msgEdit->hasFocus()) return; } -void GroupChatForm::keyReleaseEvent(QKeyEvent* ev) -{ +void GroupChatForm::keyReleaseEvent(QKeyEvent* ev) { // Push to talk (CTRL+P) if (ev->key() == Qt::Key_P && (ev->modifiers() & Qt::ControlModifier) && inCall) { onMicMuteToggle(); } - if (msgEdit->hasFocus()) - return; + if (msgEdit->hasFocus()) return; } /** * @brief Updates users' count label text */ -void GroupChatForm::updateUserCount(int numPeers) -{ +void GroupChatForm::updateUserCount(int numPeers) { nusersLabel->setText(tr("%n user(s) in chat", "Number of users in chat", numPeers)); -// headWidget->updateCallButtons(true, inCall); + // headWidget->updateCallButtons(true, inCall); } -void GroupChatForm::retranslateUi() -{ -// updateUserCount(group->getPeersCount()); +void GroupChatForm::retranslateUi() { + // updateUserCount(group->getPeersCount()); } -void GroupChatForm::onLabelContextMenuRequested(const QPoint& localPos) -{ +void GroupChatForm::onLabelContextMenuRequested(const QPoint& localPos) { QLabel* label = static_cast(QObject::sender()); if (label == nullptr) { @@ -408,7 +386,7 @@ void GroupChatForm::onLabelContextMenuRequested(const QPoint& localPos) menuTitle.chop(2); } QAction* menuTitleAction = contextMenu->addAction(menuTitle); - menuTitleAction->setEnabled(false); // make sure the title is not clickable + menuTitleAction->setEnabled(false); // make sure the title is not clickable contextMenu->addSeparator(); const QAction* toggleMuteAction; @@ -422,31 +400,29 @@ void GroupChatForm::onLabelContextMenuRequested(const QPoint& localPos) const QAction* selectedItem = contextMenu->exec(pos); if (selectedItem == toggleMuteAction) { if (isPeerBlocked) { - const int index = blackList.indexOf(peerPk ); + const int index = blackList.indexOf(peerPk); if (index != -1) { blackList.removeAt(index); } } else { - blackList << peerPk ; + blackList << peerPk; } settings.setBlackList(blackList); } } -void GroupChatForm::joinGroupCall() -{ -// CoreAV* av = Core::getInstance()->getAv(); -// av->joinGroupCall(*group); +void GroupChatForm::joinGroupCall() { + // CoreAV* av = Core::getInstance()->getAv(); + // av->joinGroupCall(*group); audioInputFlag = true; audioOutputFlag = true; inCall = true; } -void GroupChatForm::leaveGroupCall() -{ -// CoreAV* av = Core::getInstance()->getAv(); -// av->leaveGroupCall(group->getId()); +void GroupChatForm::leaveGroupCall() { + // CoreAV* av = Core::getInstance()->getAv(); + // av->leaveGroupCall(group->getId()); audioInputFlag = false; audioOutputFlag = false; inCall = false; diff --git a/src/modules/im/src/widget/form/groupchatform.h b/src/modules/im/src/widget/form/groupchatform.h index ffa39a66..7330e0ce 100644 --- a/src/modules/im/src/widget/form/groupchatform.h +++ b/src/modules/im/src/widget/form/groupchatform.h @@ -13,9 +13,9 @@ #ifndef GROUPCHATFORM_H #define GROUPCHATFORM_H +#include #include "genericchatform.h" #include "src/core/FriendId.h" -#include namespace Ui { class MainWindow; @@ -29,8 +29,7 @@ class IMessageDispatcher; struct Message; class IGroupSettings; -class GroupChatForm : public GenericChatForm -{ +class GroupChatForm : public GenericChatForm { Q_OBJECT public: GroupChatForm(const GroupId* chatGroup, @@ -54,7 +53,6 @@ private slots: void onLabelContextMenuRequested(const QPoint& localPos); protected: - virtual void keyPressEvent(QKeyEvent* ev) final override; virtual void keyReleaseEvent(QKeyEvent* ev) final override; // drag & drop @@ -79,4 +77,4 @@ private slots: IGroupSettings& settings; }; -#endif // GROUPCHATFORM_H +#endif // GROUPCHATFORM_H diff --git a/src/modules/im/src/widget/form/groupinviteform.cpp b/src/modules/im/src/widget/form/groupinviteform.cpp index 9a685c0f..e15c0b1d 100644 --- a/src/modules/im/src/widget/form/groupinviteform.cpp +++ b/src/modules/im/src/widget/form/groupinviteform.cpp @@ -12,13 +12,13 @@ #include "groupinviteform.h" -#include "ui_mainwindow.h" +#include "lib/settings/translator.h" #include "src/core/core.h" #include "src/model/groupinvite.h" #include "src/persistence/settings.h" #include "src/widget/contentlayout.h" #include "src/widget/form/groupinvitewidget.h" -#include "lib/settings/translator.h" +#include "ui_mainwindow.h" #include #include @@ -31,7 +31,6 @@ #include - /** * @class GroupInviteForm * @@ -39,12 +38,11 @@ */ GroupInviteForm::GroupInviteForm() - : headWidget(new QWidget(this)) - , headLabel(new QLabel(this)) - , createButton(new QPushButton(this)) - , inviteBox(new QGroupBox(this)) - , scroll(new QScrollArea(this)) -{ + : headWidget(new QWidget(this)) + , headLabel(new QLabel(this)) + , createButton(new QPushButton(this)) + , inviteBox(new QGroupBox(this)) + , scroll(new QScrollArea(this)) { QVBoxLayout* layout = new QVBoxLayout(this); connect(createButton, &QPushButton::clicked, [this]() { emit groupCreate(ConferenceType::AV); }); @@ -72,17 +70,13 @@ GroupInviteForm::GroupInviteForm() settings::Translator::registerHandler(std::bind(&GroupInviteForm::retranslateUi, this), this); } -GroupInviteForm::~GroupInviteForm() -{ - settings::Translator::unregister(this); -} +GroupInviteForm::~GroupInviteForm() { settings::Translator::unregister(this); } /** * @brief Detects that form is shown * @return True if form is visible */ -bool GroupInviteForm::isShown() const -{ +bool GroupInviteForm::isShown() const { bool result = isVisible(); if (result) { headWidget->window()->windowHandle()->alert(0); @@ -94,10 +88,9 @@ bool GroupInviteForm::isShown() const * @brief Shows the form * @param contentLayout Main layout that contains all components of the form */ -void GroupInviteForm::show(ContentLayout* contentLayout) -{ -// contentLayout->mainContent->layout()->addWidget(this); -// contentLayout->mainHead->layout()->addWidget(headWidget); +void GroupInviteForm::show(ContentLayout* contentLayout) { + // contentLayout->mainContent->layout()->addWidget(this); + // contentLayout->mainHead->layout()->addWidget(headWidget); QWidget::show(); headWidget->show(); } @@ -107,8 +100,7 @@ void GroupInviteForm::show(ContentLayout* contentLayout) * @param inviteInfo Object which contains info about group invitation * @return true if notification is needed, false otherwise */ -bool GroupInviteForm::addGroupInvite(const GroupInvite& inviteInfo) -{ +bool GroupInviteForm::addGroupInvite(const GroupInvite& inviteInfo) { // supress duplicate invite messages for (GroupInviteWidget* existing : invites) { if (existing->getInviteInfo().getInvite() == inviteInfo.getInvite()) { @@ -119,14 +111,13 @@ bool GroupInviteForm::addGroupInvite(const GroupInvite& inviteInfo) GroupInviteWidget* widget = new GroupInviteWidget(this, inviteInfo); scroll->widget()->layout()->addWidget(widget); invites.append(widget); - connect(widget, &GroupInviteWidget::accepted, [this] (const GroupInvite& inviteInfo) { + connect(widget, &GroupInviteWidget::accepted, [this](const GroupInvite& inviteInfo) { deleteInviteWidget(inviteInfo); emit groupInviteAccepted(inviteInfo); }); - connect(widget, &GroupInviteWidget::rejected, [this] (const GroupInvite& inviteInfo) { - deleteInviteWidget(inviteInfo); - }); + connect(widget, &GroupInviteWidget::rejected, + [this](const GroupInvite& inviteInfo) { deleteInviteWidget(inviteInfo); }); if (isVisible()) { emit groupInvitesSeen(); return false; @@ -134,8 +125,7 @@ bool GroupInviteForm::addGroupInvite(const GroupInvite& inviteInfo) return true; } -void GroupInviteForm::showEvent(QShowEvent* event) -{ +void GroupInviteForm::showEvent(QShowEvent* event) { QWidget::showEvent(event); emit groupInvitesSeen(); } @@ -144,19 +134,16 @@ void GroupInviteForm::showEvent(QShowEvent* event) * @brief Deletes accepted/declined group invite widget * @param inviteInfo Invite information of accepted/declined widget */ -void GroupInviteForm::deleteInviteWidget(const GroupInvite& inviteInfo) -{ - auto deletingWidget = - std::find_if(invites.begin(), invites.end(), [&](const GroupInviteWidget* widget) { - return inviteInfo == widget->getInviteInfo(); - }); +void GroupInviteForm::deleteInviteWidget(const GroupInvite& inviteInfo) { + auto deletingWidget = std::find_if( + invites.begin(), invites.end(), + [&](const GroupInviteWidget* widget) { return inviteInfo == widget->getInviteInfo(); }); (*deletingWidget)->deleteLater(); scroll->widget()->layout()->removeWidget(*deletingWidget); invites.erase(deletingWidget); } -void GroupInviteForm::retranslateUi() -{ +void GroupInviteForm::retranslateUi() { headLabel->setText(tr("Groups")); if (createButton) { createButton->setText(tr("Create new group")); diff --git a/src/modules/im/src/widget/form/groupinviteform.h b/src/modules/im/src/widget/form/groupinviteform.h index d9d1d0eb..7538b778 100644 --- a/src/modules/im/src/widget/form/groupinviteform.h +++ b/src/modules/im/src/widget/form/groupinviteform.h @@ -33,8 +33,7 @@ namespace Ui { class MainWindow; } -class GroupInviteForm : public QWidget -{ +class GroupInviteForm : public QWidget { Q_OBJECT public: GroupInviteForm(); @@ -65,4 +64,4 @@ class GroupInviteForm : public QWidget QScrollArea* scroll; }; -#endif // GROUPINVITEFORM_H +#endif // GROUPINVITEFORM_H diff --git a/src/modules/im/src/widget/form/groupinvitewidget.cpp b/src/modules/im/src/widget/form/groupinvitewidget.cpp index 9666d8b6..7d3e8fa0 100644 --- a/src/modules/im/src/widget/form/groupinvitewidget.cpp +++ b/src/modules/im/src/widget/form/groupinvitewidget.cpp @@ -29,13 +29,12 @@ */ GroupInviteWidget::GroupInviteWidget(QWidget* parent, const GroupInvite& invite) - : QWidget(parent) - , acceptButton(new QPushButton(this)) - , rejectButton(new QPushButton(this)) - , inviteMessageLabel(new CroppingLabel(this)) - , widgetLayout(new QHBoxLayout(this)) - , inviteInfo(invite) -{ + : QWidget(parent) + , acceptButton(new QPushButton(this)) + , rejectButton(new QPushButton(this)) + , inviteMessageLabel(new CroppingLabel(this)) + , widgetLayout(new QHBoxLayout(this)) + , inviteInfo(invite) { connect(acceptButton, &QPushButton::clicked, [this]() { emit accepted(inviteInfo); }); connect(rejectButton, &QPushButton::clicked, [this]() { emit rejected(inviteInfo); }); widgetLayout->addWidget(inviteMessageLabel); @@ -48,15 +47,15 @@ GroupInviteWidget::GroupInviteWidget(QWidget* parent, const GroupInvite& invite) /** * @brief Retranslate all elements in the form. */ -void GroupInviteWidget::retranslateUi() -{ +void GroupInviteWidget::retranslateUi() { QString name = Nexus::getCore()->getFriendUsername(inviteInfo.getFriendId()); QDateTime inviteDate = inviteInfo.getInviteDate(); QString date = inviteDate.toString(Settings::getInstance().getDateFormat()); QString time = inviteDate.toString(Settings::getInstance().getTimestampFormat()); - inviteMessageLabel->setText( - tr("Invited by %1 on %2 at %3.").arg("%1").arg(name.toHtmlEscaped(), date, time)); + inviteMessageLabel->setText(tr("Invited by %1 on %2 at %3.") + .arg("%1") + .arg(name.toHtmlEscaped(), date, time)); acceptButton->setText(tr("Join")); rejectButton->setText(tr("Decline")); } @@ -65,7 +64,4 @@ void GroupInviteWidget::retranslateUi() * @brief Returns infomation about invitation - e.g., who and when sent * @return Invite information object */ -const GroupInvite GroupInviteWidget::getInviteInfo() const -{ - return inviteInfo; -} +const GroupInvite GroupInviteWidget::getInviteInfo() const { return inviteInfo; } diff --git a/src/modules/im/src/widget/form/groupinvitewidget.h b/src/modules/im/src/widget/form/groupinvitewidget.h index be6502d2..298cddfe 100644 --- a/src/modules/im/src/widget/form/groupinvitewidget.h +++ b/src/modules/im/src/widget/form/groupinvitewidget.h @@ -22,8 +22,7 @@ class CroppingLabel; class QHBoxLayout; class QPushButton; -class GroupInviteWidget : public QWidget -{ +class GroupInviteWidget : public QWidget { Q_OBJECT public: GroupInviteWidget(QWidget* parent, const GroupInvite& invite); @@ -42,4 +41,4 @@ class GroupInviteWidget : public QWidget GroupInvite inviteInfo; }; -#endif // GROUPINVITEWIDGET_H +#endif // GROUPINVITEWIDGET_H diff --git a/src/modules/im/src/widget/form/loadhistorydialog.cpp b/src/modules/im/src/widget/form/loadhistorydialog.cpp index 1d36fbb5..44b63772 100644 --- a/src/modules/im/src/widget/form/loadhistorydialog.cpp +++ b/src/modules/im/src/widget/form/loadhistorydialog.cpp @@ -11,20 +11,17 @@ */ #include "loadhistorydialog.h" -#include "ui_loadhistorydialog.h" +#include +#include +#include #include "src/model/ichatlog.h" #include "src/nexus.h" #include "src/persistence/history.h" #include "src/persistence/profile.h" -#include -#include -#include +#include "ui_loadhistorydialog.h" LoadHistoryDialog::LoadHistoryDialog(const IChatLog* chatLog, QWidget* parent) - : QDialog(parent) - , ui(new Ui::LoadHistoryDialog) - , chatLog(chatLog) -{ + : QDialog(parent), ui(new Ui::LoadHistoryDialog), chatLog(chatLog) { ui->setupUi(this); highlightDates(QDate::currentDate().year(), QDate::currentDate().month()); connect(ui->fromDate, &QCalendarWidget::currentPageChanged, this, @@ -32,26 +29,20 @@ LoadHistoryDialog::LoadHistoryDialog(const IChatLog* chatLog, QWidget* parent) } LoadHistoryDialog::LoadHistoryDialog(QWidget* parent) - : QDialog(parent) - , ui(new Ui::LoadHistoryDialog) -{ + : QDialog(parent), ui(new Ui::LoadHistoryDialog) { ui->setupUi(this); } -LoadHistoryDialog::~LoadHistoryDialog() -{ - delete ui; -} +LoadHistoryDialog::~LoadHistoryDialog() { delete ui; } -QDateTime LoadHistoryDialog::getFromDate() -{ +QDateTime LoadHistoryDialog::getFromDate() { #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) QDateTime res(ui->fromDate->selectedDate().startOfDay()); #else QDateTime res(ui->fromDate->selectedDate()); #endif - if (res.date().month() != ui->fromDate->monthShown() - || res.date().year() != ui->fromDate->yearShown()) { + if (res.date().month() != ui->fromDate->monthShown() || + res.date().year() != ui->fromDate->yearShown()) { QDate newDate(ui->fromDate->yearShown(), ui->fromDate->monthShown(), 1); res.setDate(newDate); } @@ -59,18 +50,11 @@ QDateTime LoadHistoryDialog::getFromDate() return res; } -void LoadHistoryDialog::setTitle(const QString& title) -{ - setWindowTitle(title); -} +void LoadHistoryDialog::setTitle(const QString& title) { setWindowTitle(title); } -void LoadHistoryDialog::setInfoLabel(const QString& info) -{ - ui->fromLabel->setText(info); -} +void LoadHistoryDialog::setInfoLabel(const QString& info) { ui->fromLabel->setText(info); } -void LoadHistoryDialog::highlightDates(int year, int month) -{ +void LoadHistoryDialog::highlightDates(int year, int month) { History* history = Nexus::getProfile()->getHistory(); QDate monthStart(year, month, 1); QDate monthEnd(year, month + 1, 1); diff --git a/src/modules/im/src/widget/form/loadhistorydialog.h b/src/modules/im/src/widget/form/loadhistorydialog.h index 12f5a5d8..c95568f0 100644 --- a/src/modules/im/src/widget/form/loadhistorydialog.h +++ b/src/modules/im/src/widget/form/loadhistorydialog.h @@ -13,17 +13,16 @@ #ifndef LOADHISTORYDIALOG_H #define LOADHISTORYDIALOG_H -#include "src/core/FriendId.h" #include #include +#include "src/core/FriendId.h" namespace Ui { class LoadHistoryDialog; } class IChatLog; -class LoadHistoryDialog : public QDialog -{ +class LoadHistoryDialog : public QDialog { Q_OBJECT public: @@ -43,4 +42,4 @@ public slots: const IChatLog* chatLog; }; -#endif // LOADHISTORYDIALOG_H +#endif // LOADHISTORYDIALOG_H diff --git a/src/modules/im/src/widget/form/profileform.cpp b/src/modules/im/src/widget/form/profileform.cpp index c8305629..23b10ec0 100644 --- a/src/modules/im/src/widget/form/profileform.cpp +++ b/src/modules/im/src/widget/form/profileform.cpp @@ -11,21 +11,7 @@ */ #include "profileform.h" -#include "lib/settings/translator.h" -#include "src/core/core.h" -#include "src/lib/settings/style.h" -#include "src/model/profile/iprofileinfo.h" -#include "src/persistence/profile.h" -#include "src/persistence/profilelocker.h" -#include "src/persistence/settings.h" -#include "src/widget/contentlayout.h" -#include "src/widget/form/setpassworddialog.h" -#include "src/widget/form/settingswidget.h" -#include "src/widget/gui.h" -#include "src/widget/maskablepixmapwidget.h" -#include "src/widget/tool/croppinglabel.h" -#include "src/widget/widget.h" -#include "ui_profileform.h" +#include #include #include #include @@ -41,65 +27,67 @@ #include #include #include -#include +#include "lib/settings/translator.h" +#include "src/core/core.h" +#include "src/lib/settings/style.h" +#include "src/model/profile/iprofileinfo.h" +#include "src/persistence/profile.h" +#include "src/persistence/profilelocker.h" +#include "src/persistence/settings.h" +#include "src/widget/contentlayout.h" +#include "src/widget/form/setpassworddialog.h" +#include "src/widget/form/settingswidget.h" +#include "src/widget/gui.h" +#include "src/widget/maskablepixmapwidget.h" +#include "src/widget/tool/croppinglabel.h" +#include "src/widget/widget.h" +#include "ui_profileform.h" static const QMap SET_AVATAR_ERROR = { - { IProfileInfo::SetAvatarResult::CanNotOpen, - ProfileForm::tr("Unable to open this file.") }, - { IProfileInfo::SetAvatarResult::CanNotRead, - ProfileForm::tr("Unable to read this image.") }, - { IProfileInfo::SetAvatarResult::TooLarge, - ProfileForm::tr("The supplied image is too large.\nPlease use another image.") }, - { IProfileInfo::SetAvatarResult::EmptyPath, - ProfileForm::tr("Empty path is unavaliable") }, + {IProfileInfo::SetAvatarResult::CanNotOpen, ProfileForm::tr("Unable to open this file.")}, + {IProfileInfo::SetAvatarResult::CanNotRead, ProfileForm::tr("Unable to read this image.")}, + {IProfileInfo::SetAvatarResult::TooLarge, + ProfileForm::tr("The supplied image is too large.\nPlease use another image.")}, + {IProfileInfo::SetAvatarResult::EmptyPath, ProfileForm::tr("Empty path is unavaliable")}, }; static const QMap> RENAME_ERROR = { - { IProfileInfo::RenameResult::Error, - { ProfileForm::tr("Failed to rename"), - ProfileForm::tr("Couldn't rename the profile to \"%1\"") } - } , - { IProfileInfo::RenameResult::ProfileAlreadyExists, - { ProfileForm::tr("Profile already exists"), - ProfileForm::tr("A profile named \"%1\" already exists.") } - }, - { IProfileInfo::RenameResult::EmptyName, - { ProfileForm::tr("Empty name"), - ProfileForm::tr("Empty name is unavaliable") } - }, + {IProfileInfo::RenameResult::Error, + {ProfileForm::tr("Failed to rename"), + ProfileForm::tr("Couldn't rename the profile to \"%1\"")}}, + {IProfileInfo::RenameResult::ProfileAlreadyExists, + {ProfileForm::tr("Profile already exists"), + ProfileForm::tr("A profile named \"%1\" already exists.")}}, + {IProfileInfo::RenameResult::EmptyName, + {ProfileForm::tr("Empty name"), ProfileForm::tr("Empty name is unavaliable")}}, }; static const QMap> SAVE_ERROR = { - { IProfileInfo::SaveResult::NoWritePermission, - { ProfileForm::tr("Location not writable", "Title of permissions popup"), - ProfileForm::tr("You do not have permission to write that location. Choose " - "another, or cancel the save dialog.", "text of permissions popup") }, - }, - { IProfileInfo::SaveResult::Error, - { ProfileForm::tr("Failed to copy file"), - ProfileForm::tr("The file you chose could not be written to.") } - }, - { IProfileInfo::SaveResult::EmptyPath, - { ProfileForm::tr("Empty path"), - ProfileForm::tr("Empty path is unavaliable") } - }, + { + IProfileInfo::SaveResult::NoWritePermission, + {ProfileForm::tr("Location not writable", "Title of permissions popup"), + ProfileForm::tr("You do not have permission to write that location. Choose " + "another, or cancel the save dialog.", + "text of permissions popup")}, + }, + {IProfileInfo::SaveResult::Error, + {ProfileForm::tr("Failed to copy file"), + ProfileForm::tr("The file you chose could not be written to.")}}, + {IProfileInfo::SaveResult::EmptyPath, + {ProfileForm::tr("Empty path"), ProfileForm::tr("Empty path is unavaliable")}}, }; static const QPair CAN_NOT_CHANGE_PASSWORD = { - ProfileForm::tr("Couldn't change password"), - ProfileForm::tr("Couldn't change password on the database, " - "it might be corrupted or use the old password.") -}; + ProfileForm::tr("Couldn't change password"), + ProfileForm::tr("Couldn't change password on the database, " + "it might be corrupted or use the old password.")}; ProfileForm::ProfileForm(IProfileInfo* profileInfo, QWidget* parent) - : QWidget{parent} - , qr{nullptr} - , profileInfo{profileInfo} -{ + : QWidget{parent}, qr{nullptr}, profileInfo{profileInfo} { bodyUI = new Ui::IdentitySettings; bodyUI->setupUi(this); - const uint32_t maxNameLength = 1024;//TODO tox_max_name_length(); + const uint32_t maxNameLength = 1024; // TODO tox_max_name_length(); const QString toolTip = tr("Tox user names cannot exceed %1 characters.").arg(maxNameLength); bodyUI->userNameLabel->setToolTip(toolTip); bodyUI->userName->setMaxLength(static_cast(maxNameLength)); @@ -110,7 +98,7 @@ ProfileForm::ProfileForm(IProfileInfo* profileInfo, QWidget* parent) toxId->setToolTip(bodyUI->toxId->toolTip()); QVBoxLayout* toxIdGroup = qobject_cast(bodyUI->toxGroup->layout()); - delete toxIdGroup->replaceWidget(bodyUI->toxId, toxId); // Original toxId is in heap, delete it + delete toxIdGroup->replaceWidget(bodyUI->toxId, toxId); // Original toxId is in heap, delete it bodyUI->toxId->hide(); profilePicture = new MaskablePixmapWidget(this, QSize(64, 64), ":/img/avatar_mask.svg"); @@ -121,12 +109,12 @@ ProfileForm::ProfileForm(IProfileInfo* profileInfo, QWidget* parent) profilePicture->installEventFilter(this); profilePicture->setAccessibleName("Profile avatar"); profilePicture->setAccessibleDescription("Set a profile avatar shown to all contacts"); - + setStyleSheet(Style::getStylesheet("window/profile.css")); connect(profilePicture, &MaskablePixmapWidget::clicked, this, &ProfileForm::onAvatarClicked); - connect(profilePicture, &MaskablePixmapWidget::customContextMenuRequested, - this, &ProfileForm::showProfilePictureContextMenu); + connect(profilePicture, &MaskablePixmapWidget::customContextMenuRequested, this, + &ProfileForm::showProfilePictureContextMenu); QHBoxLayout* publicGrouplayout = qobject_cast(bodyUI->publicGroup->layout()); publicGrouplayout->insertWidget(0, profilePicture); publicGrouplayout->insertSpacing(1, 7); @@ -143,29 +131,27 @@ ProfileForm::ProfileForm(IProfileInfo* profileInfo, QWidget* parent) connect(toxId, &ClickableTE::clicked, this, &ProfileForm::copyIdClicked); profileInfo->connectTo_idChanged(this, [this](const ToxId& id) { setToxId(id); }); connect(bodyUI->userName, &QLineEdit::editingFinished, this, &ProfileForm::onUserNameEdited); - connect(bodyUI->statusMessage, &QLineEdit::editingFinished, - this, &ProfileForm::onStatusMessageEdited); + connect(bodyUI->statusMessage, &QLineEdit::editingFinished, this, + &ProfileForm::onStatusMessageEdited); connect(bodyUI->exportButton, &QPushButton::clicked, this, &ProfileForm::onExportClicked); connect(bodyUI->logoutButton, &QPushButton::clicked, this, &ProfileForm::onLogoutClicked); connect(bodyUI->exitButton, &QPushButton::clicked, this, &ProfileForm::onExitClicked); -// connect(bodyUI->deleteButton, &QPushButton::clicked, this, &ProfileForm::onDeleteClicked); -// connect(bodyUI->deletePassButton, &QPushButton::clicked, -// this, &ProfileForm::onDeletePassClicked); -// connect(bodyUI->deletePassButton, &QPushButton::clicked, -// this, &ProfileForm::setPasswordButtonsText); -// connect(bodyUI->changePassButton, &QPushButton::clicked, -// this, &ProfileForm::onChangePassClicked); -// connect(bodyUI->changePassButton, &QPushButton::clicked, -// this, &ProfileForm::setPasswordButtonsText); + // connect(bodyUI->deleteButton, &QPushButton::clicked, this, &ProfileForm::onDeleteClicked); + // connect(bodyUI->deletePassButton, &QPushButton::clicked, + // this, &ProfileForm::onDeletePassClicked); + // connect(bodyUI->deletePassButton, &QPushButton::clicked, + // this, &ProfileForm::setPasswordButtonsText); + // connect(bodyUI->changePassButton, &QPushButton::clicked, + // this, &ProfileForm::onChangePassClicked); + // connect(bodyUI->changePassButton, &QPushButton::clicked, + // this, &ProfileForm::setPasswordButtonsText); connect(bodyUI->saveQr, &QPushButton::clicked, this, &ProfileForm::onSaveQrClicked); connect(bodyUI->copyQr, &QPushButton::clicked, this, &ProfileForm::onCopyQrClicked); profileInfo->connectTo_usernameChanged( - this, - [this](const QString& val) { bodyUI->userName->setText(val); }); + this, [this](const QString& val) { bodyUI->userName->setText(val); }); profileInfo->connectTo_statusMessageChanged( - this, - [this](const QString& val) { bodyUI->statusMessage->setText(val); }); + this, [this](const QString& val) { bodyUI->statusMessage->setText(val); }); for (QComboBox* cb : findChildren()) { cb->installEventFilter(this); @@ -176,20 +162,17 @@ ProfileForm::ProfileForm(IProfileInfo* profileInfo, QWidget* parent) settings::Translator::registerHandler(std::bind(&ProfileForm::retranslateUi, this), this); } -void ProfileForm::prFileLabelUpdate() -{ +void ProfileForm::prFileLabelUpdate() { const QString name = profileInfo->getUsername(); bodyUI->prFileLabel->setText(tr("Current profile: ") + name + ".tox"); } -ProfileForm::~ProfileForm() -{ +ProfileForm::~ProfileForm() { settings::Translator::unregister(this); delete bodyUI; } -bool ProfileForm::isShown() const -{ +bool ProfileForm::isShown() const { if (profilePicture->isVisible()) { window()->windowHandle()->alert(0); return true; @@ -198,10 +181,9 @@ bool ProfileForm::isShown() const return false; } -void ProfileForm::showTo(ContentLayout* contentLayout) -{ +void ProfileForm::showTo(ContentLayout* contentLayout) { auto idx = contentLayout->indexOf(this); - if(idx < 0){ + if (idx < 0) { contentLayout->addWidget(this); } contentLayout->setCurrentWidget(this); @@ -212,37 +194,35 @@ void ProfileForm::showTo(ContentLayout* contentLayout) QString appPath = QApplication::applicationDirPath(); QString dirPath = portable ? appPath : defaultPath; - QString dirPrLink = - tr("Current profile location: %1").arg(QString("%1").arg(dirPath)); + QString dirPrLink = tr("Current profile location: %1") + .arg(QString("%1").arg(dirPath)); bodyUI->dirPrLink->setText(dirPrLink); bodyUI->dirPrLink->setOpenExternalLinks(true); - bodyUI->dirPrLink->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::TextSelectableByMouse); + bodyUI->dirPrLink->setTextInteractionFlags(Qt::LinksAccessibleByMouse | + Qt::TextSelectableByMouse); bodyUI->dirPrLink->setMaximumSize(bodyUI->dirPrLink->sizeHint()); bodyUI->userName->setFocus(); bodyUI->userName->selectAll(); } -bool ProfileForm::eventFilter(QObject* object, QEvent* event) -{ - if (object == static_cast(profilePicture) && event->type() == QEvent::MouseButtonPress) { +bool ProfileForm::eventFilter(QObject* object, QEvent* event) { + if (object == static_cast(profilePicture) && + event->type() == QEvent::MouseButtonPress) { QMouseEvent* mouseEvent = static_cast(event); - if (mouseEvent->button() == Qt::RightButton) - return true; + if (mouseEvent->button() == Qt::RightButton) return true; } return false; } -void ProfileForm::showEvent(QShowEvent *e) -{ +void ProfileForm::showEvent(QShowEvent* e) { auto avt = profileInfo->getAvatar(); onSelfAvatarLoaded(avt); bodyUI->userName->setText(profileInfo->getDisplayName()); } -void ProfileForm::showProfilePictureContextMenu(const QPoint& point) -{ +void ProfileForm::showProfilePictureContextMenu(const QPoint& point) { const QPoint pos = profilePicture->mapToGlobal(point); QMenu contextMenu; @@ -255,48 +235,38 @@ void ProfileForm::showProfilePictureContextMenu(const QPoint& point) } } -void ProfileForm::copyIdClicked() -{ +void ProfileForm::copyIdClicked() { profileInfo->copyId(); if (!hasCheck) { - bodyUI->toxIdLabel->setText(bodyUI->toxIdLabel->text()); //TODO: + " ✔" + bodyUI->toxIdLabel->setText(bodyUI->toxIdLabel->text()); // TODO: + " ✔" hasCheck = true; } timer.start(); } -void ProfileForm::onUserNameEdited() -{ - profileInfo->setUsername(bodyUI->userName->text()); -} +void ProfileForm::onUserNameEdited() { profileInfo->setUsername(bodyUI->userName->text()); } -void ProfileForm::onStatusMessageEdited() -{ +void ProfileForm::onStatusMessageEdited() { profileInfo->setStatusMessage(bodyUI->statusMessage->text()); } -void ProfileForm::onSelfAvatarLoaded(const QPixmap& pic) -{ - profilePicture->setPixmap(pic); -} +void ProfileForm::onSelfAvatarLoaded(const QPixmap& pic) { profilePicture->setPixmap(pic); } -void ProfileForm::setToxId(const ToxId& id) -{ +void ProfileForm::setToxId(const ToxId& id) { QString idString = id.toString(); - qDebug()<<"setToxId id:"<setText(idString); setQrCode(idString); } -void ProfileForm::setQrCode(const QString &id) { - qr = std::make_unique(); - qr->setQRData(id); - bodyUI->qrCode->setPixmap(QPixmap::fromImage(qr->getImage()->scaledToWidth(150))); +void ProfileForm::setQrCode(const QString& id) { + qr = std::make_unique(); + qr->setQRData(id); + bodyUI->qrCode->setPixmap(QPixmap::fromImage(qr->getImage()->scaledToWidth(150))); } -QString ProfileForm::getSupportedImageFilter() -{ +QString ProfileForm::getSupportedImageFilter() { QString res; for (auto type : QImageReader::supportedImageFormats()) { res += QString("*.%1 ").arg(QString(type)); @@ -305,25 +275,23 @@ QString ProfileForm::getSupportedImageFilter() return tr("Images (%1)", "filetype filter").arg(res.left(res.size() - 1)); } -void ProfileForm::onAvatarClicked() -{ +void ProfileForm::onAvatarClicked() { const QString filter = getSupportedImageFilter(); const QString path = QFileDialog::getOpenFileName(Q_NULLPTR, tr("Choose a profile picture"), - QDir::homePath(), filter, nullptr); + QDir::homePath(), filter, nullptr); if (path.isEmpty()) { return; } const IProfileInfo::SetAvatarResult result = profileInfo->setAvatar(path); - if (result == IProfileInfo::SetAvatarResult::OK) { + if (result == IProfileInfo::SetAvatarResult::OK) { return; } GUI::showError(tr("Error"), SET_AVATAR_ERROR[result]); } -void ProfileForm::onRenameClicked() -{ +void ProfileForm::onRenameClicked() { const QString cur = profileInfo->getUsername(); const QString title = tr("Rename \"%1\"", "renaming a profile").arg(cur); const QString name = QInputDialog::getText(this, title, title + ":"); @@ -340,10 +308,9 @@ void ProfileForm::onRenameClicked() prFileLabelUpdate(); } -void ProfileForm::onExportClicked() -{ +void ProfileForm::onExportClicked() { const QString current = profileInfo->getUsername() + Core::TOX_EXT; - //:save dialog title + //: save dialog title const QString path = QFileDialog::getSaveFileName(Q_NULLPTR, tr("Export profile"), current, //: save dialog filter tr("Tox save file (*.tox)")); @@ -360,11 +327,10 @@ void ProfileForm::onExportClicked() GUI::showWarning(error.first, error.second); } -void ProfileForm::onDeleteClicked() -{ +void ProfileForm::onDeleteClicked() { const QString title = tr("Really delete profile?", "deletion confirmation title"); - const QString question = tr("Are you sure you want to delete this profile?", - "deletion confirmation text"); + const QString question = + tr("Are you sure you want to delete this profile?", "deletion confirmation text"); if (!GUI::askQuestion(title, question)) { return; } @@ -386,40 +352,31 @@ void ProfileForm::onDeleteClicked() GUI::showError(tr("Files could not be deleted!", "deletion failed title"), message); } -void ProfileForm::onLogoutClicked() -{ - profileInfo->logout(); -} +void ProfileForm::onLogoutClicked() { profileInfo->logout(); } -void ProfileForm::onExitClicked() -{ - profileInfo->exit(); -} +void ProfileForm::onExitClicked() { profileInfo->exit(); } -void ProfileForm::setPasswordButtonsText() -{ -// if (profileInfo->isEncrypted()) { -// bodyUI->changePassButton->setText(tr("Change password", "button text")); -// bodyUI->deletePassButton->setVisible(true); -// } else { -// bodyUI->changePassButton->setText(tr("Set profile password", "button text")); -// bodyUI->deletePassButton->setVisible(false); -// } +void ProfileForm::setPasswordButtonsText() { + // if (profileInfo->isEncrypted()) { + // bodyUI->changePassButton->setText(tr("Change password", "button text")); + // bodyUI->deletePassButton->setVisible(true); + // } else { + // bodyUI->changePassButton->setText(tr("Set profile password", "button text")); + // bodyUI->deletePassButton->setVisible(false); + // } } -void ProfileForm::onCopyQrClicked() -{ - if(!qr) return; - profileInfo->copyQr(*qr->getImage()); +void ProfileForm::onCopyQrClicked() { + if (!qr) return; + profileInfo->copyQr(*qr->getImage()); } -void ProfileForm::onSaveQrClicked() -{ +void ProfileForm::onSaveQrClicked() { const QString current = profileInfo->getUsername() + ".png"; - const QString path = QFileDialog::getSaveFileName( - Q_NULLPTR, tr("Save", "save qr image"), current, - tr("Save QrCode (*.png)", "save dialog filter")); + const QString path = + QFileDialog::getSaveFileName(Q_NULLPTR, tr("Save", "save qr image"), current, + tr("Save QrCode (*.png)", "save dialog filter")); if (path.isEmpty()) { return; } @@ -433,8 +390,7 @@ void ProfileForm::onSaveQrClicked() GUI::showWarning(error.first, error.second); } -void ProfileForm::onDeletePassClicked() -{ +void ProfileForm::onDeletePassClicked() { if (!profileInfo->isEncrypted()) { GUI::showInfo(tr("Nothing to remove"), tr("Your profile does not have a password!")); return; @@ -452,8 +408,7 @@ void ProfileForm::onDeletePassClicked() } } -void ProfileForm::onChangePassClicked() -{ +void ProfileForm::onChangePassClicked() { const QString title = tr("Please enter a new password."); SetPasswordDialog* dialog = new SetPasswordDialog(title, QString{}, nullptr); if (dialog->exec() == QDialog::Rejected) { @@ -466,13 +421,13 @@ void ProfileForm::onChangePassClicked() } } -void ProfileForm::retranslateUi() -{ +void ProfileForm::retranslateUi() { bodyUI->retranslateUi(this); setPasswordButtonsText(); // We have to add the toxId tooltip here and not in the .ui or Qt won't know how to translate it // dynamically - toxId->setToolTip(tr("This bunch of characters tells other Tox clients how to contact " - "you.\nShare it with your friends to communicate.\n\n" - "This ID includes the NoSpam code (in blue), and the checksum (in gray).")); + toxId->setToolTip( + tr("This bunch of characters tells other Tox clients how to contact " + "you.\nShare it with your friends to communicate.\n\n" + "This ID includes the NoSpam code (in blue), and the checksum (in gray).")); } diff --git a/src/modules/im/src/widget/form/profileform.h b/src/modules/im/src/widget/form/profileform.h index fc4f633f..366fa636 100644 --- a/src/modules/im/src/widget/form/profileform.h +++ b/src/modules/im/src/widget/form/profileform.h @@ -13,11 +13,11 @@ #ifndef IDENTITYFORM_H #define IDENTITYFORM_H -#include "src/widget/qrwidget.h" #include #include #include #include +#include "src/widget/qrwidget.h" class ContentLayout; class CroppingLabel; @@ -28,22 +28,17 @@ namespace Ui { class IdentitySettings; } class ToxId; -class ClickableTE : public QLabel -{ +class ClickableTE : public QLabel { Q_OBJECT public: signals: void clicked(); protected: - virtual void mouseReleaseEvent(QMouseEvent*) final override - { - emit clicked(); - } + virtual void mouseReleaseEvent(QMouseEvent*) final override { emit clicked(); } }; -class ProfileForm : public QWidget -{ +class ProfileForm : public QWidget { Q_OBJECT public: ProfileForm(IProfileInfo* profileInfo, QWidget* parent = nullptr); @@ -60,7 +55,7 @@ public slots: protected: virtual bool eventFilter(QObject* object, QEvent* event) override; - virtual void showEvent(QShowEvent *e) override; + virtual void showEvent(QShowEvent* e) override; private slots: void setPasswordButtonsText(); diff --git a/src/modules/im/src/widget/form/searchsettingsform.cpp b/src/modules/im/src/widget/form/searchsettingsform.cpp index 18e26b51..9d3c0c02 100644 --- a/src/modules/im/src/widget/form/searchsettingsform.cpp +++ b/src/modules/im/src/widget/form/searchsettingsform.cpp @@ -16,10 +16,8 @@ #include "src/widget/form/loadhistorydialog.h" #include "ui_searchsettingsform.h" -SearchSettingsForm::SearchSettingsForm(QWidget *parent) : - QWidget(parent), - ui(new Ui::SearchSettingsForm) -{ +SearchSettingsForm::SearchSettingsForm(QWidget* parent) + : QWidget(parent), ui(new Ui::SearchSettingsForm) { ui->setupUi(this); ui->choiceDateButton->setEnabled(false); @@ -33,22 +31,22 @@ SearchSettingsForm::SearchSettingsForm(QWidget *parent) : #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) connect(ui->startSearchComboBox, QOverload::of(&QComboBox::currentIndexChanged), #else - connect(ui->startSearchComboBox, static_cast(&QComboBox::currentIndexChanged), + connect(ui->startSearchComboBox, + static_cast(&QComboBox::currentIndexChanged), #endif this, &SearchSettingsForm::onStartSearchSelected); - connect(ui->registerCheckBox, &QCheckBox::clicked, this, &SearchSettingsForm::onRegisterClicked); - connect(ui->wordsOnlyRadioButton, &QCheckBox::clicked, this, &SearchSettingsForm::onWordsOnlyClicked); - connect(ui->regularRadioButton, &QCheckBox::clicked, this, &SearchSettingsForm::onRegularClicked); + connect(ui->registerCheckBox, &QCheckBox::clicked, this, + &SearchSettingsForm::onRegisterClicked); + connect(ui->wordsOnlyRadioButton, &QCheckBox::clicked, this, + &SearchSettingsForm::onWordsOnlyClicked); + connect(ui->regularRadioButton, &QCheckBox::clicked, this, + &SearchSettingsForm::onRegularClicked); connect(ui->choiceDateButton, &QPushButton::clicked, this, &SearchSettingsForm::onChoiceDate); } -SearchSettingsForm::~SearchSettingsForm() -{ - delete ui; -} +SearchSettingsForm::~SearchSettingsForm() { delete ui; } -ParameterSearch SearchSettingsForm::getParameterSearch() -{ +ParameterSearch SearchSettingsForm::getParameterSearch() { ParameterSearch ps; if (ui->regularRadioButton->isChecked()) { @@ -66,21 +64,21 @@ ParameterSearch SearchSettingsForm::getParameterSearch() } switch (ui->startSearchComboBox->currentIndex()) { - case 0: - ps.period = PeriodSearch::WithTheEnd; - break; - case 1: - ps.period = PeriodSearch::WithTheFirst; - break; - case 2: - ps.period = PeriodSearch::AfterDate; - break; - case 3: - ps.period = PeriodSearch::BeforeDate; - break; - default: - ps.period = PeriodSearch::WithTheEnd; - break; + case 0: + ps.period = PeriodSearch::WithTheEnd; + break; + case 1: + ps.period = PeriodSearch::WithTheFirst; + break; + case 2: + ps.period = PeriodSearch::AfterDate; + break; + case 3: + ps.period = PeriodSearch::BeforeDate; + break; + default: + ps.period = PeriodSearch::WithTheEnd; + break; } ps.date = startDate; @@ -90,31 +88,29 @@ ParameterSearch SearchSettingsForm::getParameterSearch() return ps; } -void SearchSettingsForm::reloadTheme() -{ - ui->choiceDateButton->setStyleSheet(Style::getStylesheet(QStringLiteral("chatForm/buttons.css"))); +void SearchSettingsForm::reloadTheme() { + ui->choiceDateButton->setStyleSheet( + Style::getStylesheet(QStringLiteral("chatForm/buttons.css"))); ui->startDateLabel->setStyleSheet(Style::getStylesheet(QStringLiteral("chatForm/labels.css"))); } -void SearchSettingsForm::updateStartDateLabel() -{ +void SearchSettingsForm::updateStartDateLabel() { ui->startDateLabel->setText(startDate.toString(Settings::getInstance().getDateFormat())); } -void SearchSettingsForm::setUpdate(const bool isUpdate) -{ +void SearchSettingsForm::setUpdate(const bool isUpdate) { this->isUpdate = isUpdate; emit updateSettings(isUpdate); } -void SearchSettingsForm::onStartSearchSelected(const int index) -{ +void SearchSettingsForm::onStartSearchSelected(const int index) { if (index > 1) { ui->choiceDateButton->setEnabled(true); ui->startDateLabel->setEnabled(true); ui->choiceDateButton->setProperty("state", QStringLiteral("green")); - ui->choiceDateButton->setStyleSheet(Style::getStylesheet(QStringLiteral("chatForm/buttons.css"))); + ui->choiceDateButton->setStyleSheet( + Style::getStylesheet(QStringLiteral("chatForm/buttons.css"))); if (startDate.isNull()) { startDate = QDate::currentDate(); @@ -126,20 +122,19 @@ void SearchSettingsForm::onStartSearchSelected(const int index) ui->startDateLabel->setEnabled(false); ui->choiceDateButton->setProperty("state", QString()); - ui->choiceDateButton->setStyleSheet(Style::getStylesheet(QStringLiteral("chatForm/buttons.css"))); + ui->choiceDateButton->setStyleSheet( + Style::getStylesheet(QStringLiteral("chatForm/buttons.css"))); } setUpdate(true); } -void SearchSettingsForm::onRegisterClicked(const bool checked) -{ +void SearchSettingsForm::onRegisterClicked(const bool checked) { Q_UNUSED(checked) setUpdate(true); } -void SearchSettingsForm::onWordsOnlyClicked(const bool checked) -{ +void SearchSettingsForm::onWordsOnlyClicked(const bool checked) { if (checked) { ui->regularRadioButton->setChecked(false); } @@ -147,8 +142,7 @@ void SearchSettingsForm::onWordsOnlyClicked(const bool checked) setUpdate(true); } -void SearchSettingsForm::onRegularClicked(const bool checked) -{ +void SearchSettingsForm::onRegularClicked(const bool checked) { if (checked) { ui->wordsOnlyRadioButton->setChecked(false); } @@ -156,8 +150,7 @@ void SearchSettingsForm::onRegularClicked(const bool checked) setUpdate(true); } -void SearchSettingsForm::onChoiceDate() -{ +void SearchSettingsForm::onChoiceDate() { LoadHistoryDialog dlg; dlg.setTitle(tr("Select Date Dialog")); dlg.setInfoLabel(tr("Select a date")); diff --git a/src/modules/im/src/widget/form/searchsettingsform.h b/src/modules/im/src/widget/form/searchsettingsform.h index f62d77e3..7c8ecde1 100644 --- a/src/modules/im/src/widget/form/searchsettingsform.h +++ b/src/modules/im/src/widget/form/searchsettingsform.h @@ -20,19 +20,18 @@ namespace Ui { class SearchSettingsForm; } -class SearchSettingsForm : public QWidget -{ +class SearchSettingsForm : public QWidget { Q_OBJECT public: - explicit SearchSettingsForm(QWidget *parent = nullptr); + explicit SearchSettingsForm(QWidget* parent = nullptr); ~SearchSettingsForm(); ParameterSearch getParameterSearch(); void reloadTheme(); private: - Ui::SearchSettingsForm *ui; + Ui::SearchSettingsForm* ui; QDate startDate; bool isUpdate{false}; @@ -50,4 +49,4 @@ private slots: void updateSettings(const bool isUpdate); }; -#endif // SEARCHSETTINGSFORM_H +#endif // SEARCHSETTINGSFORM_H diff --git a/src/modules/im/src/widget/form/setpassworddialog.cpp b/src/modules/im/src/widget/form/setpassworddialog.cpp index b1e6ae6e..c452f1bc 100644 --- a/src/modules/im/src/widget/form/setpassworddialog.cpp +++ b/src/modules/im/src/widget/form/setpassworddialog.cpp @@ -19,10 +19,7 @@ const double SetPasswordDialog::reasonablePasswordLength = 8.; SetPasswordDialog::SetPasswordDialog(QString body, QString extraButton, QWidget* parent) - : QDialog(parent) - , ui(new Ui::SetPasswordDialog) - , body(body + "\n\n") -{ + : QDialog(parent), ui(new Ui::SetPasswordDialog), body(body + "\n\n") { ui->setupUi(this); connect(ui->passwordlineEdit, SIGNAL(textChanged(QString)), this, SLOT(onPasswordEdit())); @@ -42,13 +39,9 @@ SetPasswordDialog::SetPasswordDialog(QString body, QString extraButton, QWidget* } } -SetPasswordDialog::~SetPasswordDialog() -{ - delete ui; -} +SetPasswordDialog::~SetPasswordDialog() { delete ui; } -void SetPasswordDialog::onPasswordEdit() -{ +void SetPasswordDialog::onPasswordEdit() { QString pswd = ui->passwordlineEdit->text(); if (pswd.isEmpty()) { @@ -68,10 +61,8 @@ void SetPasswordDialog::onPasswordEdit() ui->passStrengthMeter->setValue(getPasswordStrength(pswd)); } -int SetPasswordDialog::getPasswordStrength(QString pass) -{ - if (pass.size() < 6) - return 0; +int SetPasswordDialog::getPasswordStrength(QString pass) { + if (pass.size() < 6) return 0; double fscore = 0; QHash charCounts; @@ -95,7 +86,4 @@ int SetPasswordDialog::getPasswordStrength(QString pass) return score; } -QString SetPasswordDialog::getPassword() -{ - return ui->passwordlineEdit->text(); -} +QString SetPasswordDialog::getPassword() { return ui->passwordlineEdit->text(); } diff --git a/src/modules/im/src/widget/form/setpassworddialog.h b/src/modules/im/src/widget/form/setpassworddialog.h index 850f1aa4..f9d67994 100644 --- a/src/modules/im/src/widget/form/setpassworddialog.h +++ b/src/modules/im/src/widget/form/setpassworddialog.h @@ -19,17 +19,11 @@ namespace Ui { class SetPasswordDialog; } -class SetPasswordDialog : public QDialog -{ +class SetPasswordDialog : public QDialog { Q_OBJECT public: - enum ReturnCode - { - Rejected = QDialog::Rejected, - Accepted = QDialog::Accepted, - Tertiary - }; + enum ReturnCode { Rejected = QDialog::Rejected, Accepted = QDialog::Accepted, Tertiary }; explicit SetPasswordDialog(QString body, QString extraButton, QWidget* parent = nullptr); ~SetPasswordDialog(); QString getPassword(); @@ -44,4 +38,4 @@ private slots: static const double reasonablePasswordLength; }; -#endif // SETPASSWORDDIALOG_H +#endif // SETPASSWORDDIALOG_H diff --git a/src/modules/im/src/widget/form/settings/advancedform.cpp b/src/modules/im/src/widget/form/settings/advancedform.cpp index a51689e4..1c1beb82 100644 --- a/src/modules/im/src/widget/form/settings/advancedform.cpp +++ b/src/modules/im/src/widget/form/settings/advancedform.cpp @@ -37,151 +37,144 @@ */ AdvancedForm::AdvancedForm() - : GenericForm(QPixmap(":/img/settings/general.png")), - bodyUI(new Ui::AdvancedSettings) { - bodyUI->setupUi(this); - - // block all child signals during initialization - const RecursiveSignalBlocker signalBlocker(this); - - Settings &s = Settings::getInstance(); - bodyUI->cbEnableIPv6->setChecked(s.getEnableIPv6()); - bodyUI->proxyAddr->setText(s.getProxyAddr()); - quint16 port = s.getProxyPort(); - if (port > 0) { - bodyUI->proxyPort->setValue(port); - } - - int index = static_cast(s.getProxyType()); - bodyUI->proxyType->setCurrentIndex(index); - on_proxyType_currentIndexChanged(index); - const bool udpEnabled = - !s.getForceTCP() && (s.getProxyType() == Settings::ProxyType::ptNone); - bodyUI->cbEnableUDP->setChecked(udpEnabled); - bodyUI->cbEnableLanDiscovery->setChecked(s.getEnableLanDiscovery() && - udpEnabled); - bodyUI->cbEnableLanDiscovery->setEnabled(udpEnabled); - - eventsInit(); - settings::Translator::registerHandler( - std::bind(&AdvancedForm::retranslateUi, this), this); + : GenericForm(QPixmap(":/img/settings/general.png")), bodyUI(new Ui::AdvancedSettings) { + bodyUI->setupUi(this); + + // block all child signals during initialization + const RecursiveSignalBlocker signalBlocker(this); + + Settings& s = Settings::getInstance(); + bodyUI->cbEnableIPv6->setChecked(s.getEnableIPv6()); + bodyUI->proxyAddr->setText(s.getProxyAddr()); + quint16 port = s.getProxyPort(); + if (port > 0) { + bodyUI->proxyPort->setValue(port); + } + + int index = static_cast(s.getProxyType()); + bodyUI->proxyType->setCurrentIndex(index); + on_proxyType_currentIndexChanged(index); + const bool udpEnabled = !s.getForceTCP() && (s.getProxyType() == Settings::ProxyType::ptNone); + bodyUI->cbEnableUDP->setChecked(udpEnabled); + bodyUI->cbEnableLanDiscovery->setChecked(s.getEnableLanDiscovery() && udpEnabled); + bodyUI->cbEnableLanDiscovery->setEnabled(udpEnabled); + + eventsInit(); + settings::Translator::registerHandler(std::bind(&AdvancedForm::retranslateUi, this), this); } AdvancedForm::~AdvancedForm() { - settings::Translator::unregister(this); - delete bodyUI; + settings::Translator::unregister(this); + delete bodyUI; } void AdvancedForm::on_btnExportLog_clicked() { - QString savefile = QFileDialog::getSaveFileName( - Q_NULLPTR, tr("Save File"), QString{}, tr("Logs (*.log)")); - - if (savefile.isNull() || savefile.isEmpty()) { - qDebug() << "Debug log save file was not properly chosen"; - return; - } - - auto &logManager = ok::lib::LogManager::Instance(); - auto &file = logManager.getFile(); - if (!file.exists()) { - qDebug() << "No log file found!"; - return; - } - - if (QFile::copy(file.fileName(), savefile)) - qDebug() << "Successfully copied to: " << savefile; - else - qDebug() << "File was not copied"; + QString savefile = + QFileDialog::getSaveFileName(Q_NULLPTR, tr("Save File"), QString{}, tr("Logs (*.log)")); + + if (savefile.isNull() || savefile.isEmpty()) { + qDebug() << "Debug log save file was not properly chosen"; + return; + } + + auto& logManager = ok::lib::LogManager::Instance(); + auto& file = logManager.getFile(); + if (!file.exists()) { + qDebug() << "No log file found!"; + return; + } + + if (QFile::copy(file.fileName(), savefile)) + qDebug() << "Successfully copied to: " << savefile; + else + qDebug() << "File was not copied"; } void AdvancedForm::on_btnCopyDebug_clicked() { - auto &logManager = ok::lib::LogManager::Instance(); - auto &file = logManager.getFile(); - if (!file.exists()) { - qDebug() << "No log file found!"; - return; - } - - QClipboard *clipboard = QApplication::clipboard(); - if (clipboard) { - QString debugtext; - if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { - QTextStream in(&file); - debugtext = in.readAll(); - file.close(); - } else { - qDebug() << "Unable to open file for copying to clipboard"; - return; + auto& logManager = ok::lib::LogManager::Instance(); + auto& file = logManager.getFile(); + if (!file.exists()) { + qDebug() << "No log file found!"; + return; } - clipboard->setText(debugtext, QClipboard::Clipboard); - qDebug() << "Debug log copied to clipboard"; - } else { - qDebug() << "Unable to access clipboard"; - } + QClipboard* clipboard = QApplication::clipboard(); + if (clipboard) { + QString debugtext; + if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { + QTextStream in(&file); + debugtext = in.readAll(); + file.close(); + } else { + qDebug() << "Unable to open file for copying to clipboard"; + return; + } + + clipboard->setText(debugtext, QClipboard::Clipboard); + qDebug() << "Debug log copied to clipboard"; + } else { + qDebug() << "Unable to access clipboard"; + } } void AdvancedForm::on_resetButton_clicked() { - const QString titile = tr("Reset settings"); - bool result = GUI::askQuestion( - titile, tr("All settings will be reset to default. Are you sure?"), - tr("Yes"), tr("No")); + const QString titile = tr("Reset settings"); + bool result = + GUI::askQuestion(titile, tr("All settings will be reset to default. Are you sure?"), + tr("Yes"), tr("No")); - if (!result) - return; + if (!result) return; - Settings::getInstance().resetToDefault(); - GUI::showInfo(titile, "Changes will take effect after restart"); + Settings::getInstance().resetToDefault(); + GUI::showInfo(titile, "Changes will take effect after restart"); } void AdvancedForm::on_cbEnableIPv6_stateChanged() { - Settings::getInstance().setEnableIPv6(bodyUI->cbEnableIPv6->isChecked()); + Settings::getInstance().setEnableIPv6(bodyUI->cbEnableIPv6->isChecked()); } void AdvancedForm::on_cbEnableUDP_stateChanged() { - const bool enableUdp = bodyUI->cbEnableUDP->isChecked(); - Settings::getInstance().setForceTCP(!enableUdp); - const bool enableLanDiscovery = - Settings::getInstance().getEnableLanDiscovery(); - bodyUI->cbEnableLanDiscovery->setEnabled(enableUdp); - bodyUI->cbEnableLanDiscovery->setChecked(enableUdp && enableLanDiscovery); + const bool enableUdp = bodyUI->cbEnableUDP->isChecked(); + Settings::getInstance().setForceTCP(!enableUdp); + const bool enableLanDiscovery = Settings::getInstance().getEnableLanDiscovery(); + bodyUI->cbEnableLanDiscovery->setEnabled(enableUdp); + bodyUI->cbEnableLanDiscovery->setChecked(enableUdp && enableLanDiscovery); } void AdvancedForm::on_cbEnableLanDiscovery_stateChanged() { - Settings::getInstance().setEnableLanDiscovery( - bodyUI->cbEnableLanDiscovery->isChecked()); + Settings::getInstance().setEnableLanDiscovery(bodyUI->cbEnableLanDiscovery->isChecked()); } void AdvancedForm::on_proxyAddr_editingFinished() { - Settings::getInstance().setProxyAddr(bodyUI->proxyAddr->text()); + Settings::getInstance().setProxyAddr(bodyUI->proxyAddr->text()); } void AdvancedForm::on_proxyPort_valueChanged(int port) { - if (port <= 0) { - port = 0; - } + if (port <= 0) { + port = 0; + } - Settings::getInstance().setProxyPort(port); + Settings::getInstance().setProxyPort(port); } void AdvancedForm::on_proxyType_currentIndexChanged(int index) { - Settings::ProxyType proxytype = static_cast(index); - const bool proxyEnabled = proxytype != Settings::ProxyType::ptNone; + Settings::ProxyType proxytype = static_cast(index); + const bool proxyEnabled = proxytype != Settings::ProxyType::ptNone; - bodyUI->proxyAddr->setEnabled(proxyEnabled); - bodyUI->proxyPort->setEnabled(proxyEnabled); - // enabling UDP and proxy can be a privacy issue - bodyUI->cbEnableUDP->setEnabled(!proxyEnabled); - bodyUI->cbEnableUDP->setChecked(!proxyEnabled); + bodyUI->proxyAddr->setEnabled(proxyEnabled); + bodyUI->proxyPort->setEnabled(proxyEnabled); + // enabling UDP and proxy can be a privacy issue + bodyUI->cbEnableUDP->setEnabled(!proxyEnabled); + bodyUI->cbEnableUDP->setChecked(!proxyEnabled); - Settings::getInstance().setProxyType(proxytype); + Settings::getInstance().setProxyType(proxytype); } /** * @brief Retranslate all elements in the form. */ void AdvancedForm::retranslateUi() { - int proxyType = bodyUI->proxyType->currentIndex(); - bodyUI->retranslateUi(this); - bodyUI->proxyType->setCurrentIndex(proxyType); + int proxyType = bodyUI->proxyType->currentIndex(); + bodyUI->retranslateUi(this); + bodyUI->proxyType->setCurrentIndex(proxyType); } diff --git a/src/modules/im/src/widget/form/settings/advancedform.h b/src/modules/im/src/widget/form/settings/advancedform.h index 803541fc..65249788 100644 --- a/src/modules/im/src/widget/form/settings/advancedform.h +++ b/src/modules/im/src/widget/form/settings/advancedform.h @@ -21,16 +21,12 @@ namespace Ui { class AdvancedSettings; } -class AdvancedForm : public GenericForm -{ +class AdvancedForm : public GenericForm { Q_OBJECT public: AdvancedForm(); ~AdvancedForm(); - virtual QString getFormName() final override - { - return tr("Advanced"); - } + virtual QString getFormName() final override { return tr("Advanced"); } private slots: // Portable @@ -54,4 +50,4 @@ private slots: Ui::AdvancedSettings* bodyUI; }; -#endif // ADVANCEDFORM_H +#endif // ADVANCEDFORM_H diff --git a/src/modules/im/src/widget/form/settings/avform.cpp b/src/modules/im/src/widget/form/settings/avform.cpp index 8b2df4ca..74c12a59 100644 --- a/src/modules/im/src/widget/form/settings/avform.cpp +++ b/src/modules/im/src/widget/form/settings/avform.cpp @@ -38,15 +38,13 @@ #define ALC_ALL_DEVICES_SPECIFIER ALC_DEVICE_SPECIFIER #endif -AVForm::AVForm(CameraSource& camera, - IAudioSettings* audioSettings, IVideoSettings* videoSettings) - : GenericForm(QPixmap(":/img/settings/av.png")) - , audioSettings{audioSettings} - , videoSettings{videoSettings} - , camVideoSurface(nullptr) - , camera(camera) - , audio{std::unique_ptr(Audio::makeAudio(Settings::getInstance()))} -{ +AVForm::AVForm(CameraSource& camera, IAudioSettings* audioSettings, IVideoSettings* videoSettings) + : GenericForm(QPixmap(":/img/settings/av.png")) + , audioSettings{audioSettings} + , videoSettings{videoSettings} + , camVideoSurface(nullptr) + , camera(camera) + , audio{std::unique_ptr(Audio::makeAudio(Settings::getInstance()))} { setupUi(this); // block all child signals during initialization @@ -64,12 +62,11 @@ AVForm::AVForm(CameraSource& camera, audioSettings->getOutVolumeMax())); playbackSlider->installEventFilter(this); - - //audio settings + // audio settings microphoneSlider->setToolTip(tr("Use slider to set the gain of your input device ranging" " from %1dB to %2dB.") - .arg(audio->minInputGain()) - .arg(audio->maxInputGain())); + .arg(audio->minInputGain()) + .arg(audio->maxInputGain())); microphoneSlider->setMaximum(totalSliderSteps); microphoneSlider->setTickPosition(QSlider::TicksBothSides); static const int numTicks = 4; @@ -77,11 +74,11 @@ AVForm::AVForm(CameraSource& camera, microphoneSlider->setTracking(false); microphoneSlider->installEventFilter(this); + microphoneSlider->setValue( + getStepsFromValue(audio->inputGain(), audio->minInputGain(), audio->maxInputGain())); - microphoneSlider->setValue(getStepsFromValue(audio->inputGain(), audio->minInputGain(), - audio->maxInputGain())); - - audioThresholdSlider->setToolTip(tr("Use slider to set the activation volume for your input device.")); + audioThresholdSlider->setToolTip( + tr("Use slider to set the activation volume for your input device.")); audioThresholdSlider->setMaximum(totalSliderSteps); audioThresholdSlider->setValue(getStepsFromValue(audioSettings->getAudioThreshold(), audio->minInputThreshold(), @@ -99,23 +96,20 @@ AVForm::AVForm(CameraSource& camera, for (QScreen* qScreen : QGuiApplication::screens()) { connect(qScreen, &QScreen::geometryChanged, this, &AVForm::rescanDevices); } - auto* qGUIApp = qobject_cast(qApp); - assert (qGUIApp); + auto* qGUIApp = qobject_cast(qApp); + assert(qGUIApp); connect(qGUIApp, &QGuiApplication::screenAdded, this, &AVForm::trackNewScreenGeometry); connect(qGUIApp, &QGuiApplication::screenAdded, this, &AVForm::rescanDevices); connect(qGUIApp, &QGuiApplication::screenRemoved, this, &AVForm::rescanDevices); settings::Translator::registerHandler(std::bind(&AVForm::retranslateUi, this), this); - } -AVForm::~AVForm() -{ +AVForm::~AVForm() { killVideoSurface(); settings::Translator::unregister(this); } -void AVForm::hideEvent(QHideEvent* event) -{ +void AVForm::hideEvent(QHideEvent* event) { audioSink.reset(); audioSrc.reset(); @@ -128,8 +122,7 @@ void AVForm::hideEvent(QHideEvent* event) GenericForm::hideEvent(event); } -void AVForm::showEvent(QShowEvent* event) -{ +void AVForm::showEvent(QShowEvent* event) { getAudioOutDevices(); getAudioInDevices(); createVideoSurface(); @@ -147,8 +140,7 @@ void AVForm::showEvent(QShowEvent* event) GenericForm::showEvent(event); } -void AVForm::open(const QString& devName, const VideoMode& mode) -{ +void AVForm::open(const QString& devName, const VideoMode& mode) { QRect rect = mode.toRect(); videoSettings->setCamVideoRes(rect); videoSettings->setCamVideoFPS(static_cast(mode.FPS)); @@ -159,22 +151,18 @@ void AVForm::trackNewScreenGeometry(QScreen* qScreen) { connect(qScreen, &QScreen::geometryChanged, this, &AVForm::rescanDevices); } -void AVForm::rescanDevices() -{ +void AVForm::rescanDevices() { getAudioInDevices(); getAudioOutDevices(); getVideoDevices(); } -void AVForm::setVolume(float value) -{ - volumeDisplay->setValue(getStepsFromValue(value, - audio->minOutputVolume(), - audio->maxOutputVolume())); +void AVForm::setVolume(float value) { + volumeDisplay->setValue( + getStepsFromValue(value, audio->minOutputVolume(), audio->maxOutputVolume())); } -void AVForm::on_videoModescomboBox_currentIndexChanged(int index) -{ +void AVForm::on_videoModescomboBox_currentIndexChanged(int index) { assert(0 <= index && index < videoModes.size()); int devIndex = videoDevCombobox->currentIndex(); assert(0 <= devIndex && devIndex < videoDeviceList.size()); @@ -218,8 +206,7 @@ void AVForm::on_videoModescomboBox_currentIndexChanged(int index) open(devName, mode); } -void AVForm::selectBestModes(QVector& allVideoModes) -{ +void AVForm::selectBestModes(QVector& allVideoModes) { if (allVideoModes.isEmpty()) { qCritical() << "Trying to select best mode from empty modes list"; return; @@ -242,8 +229,7 @@ void AVForm::selectBestModes(QVector& allVideoModes) VideoMode mode = allVideoModes[i]; // PS3-Cam protection, everything above 60fps makes no sense - if (mode.FPS > 60) - continue; + if (mode.FPS > 60) continue; for (auto iter = idealModes.begin(); iter != idealModes.end(); ++iter) { int res = iter->first; @@ -251,8 +237,7 @@ void AVForm::selectBestModes(QVector& allVideoModes) // don't take approximately correct resolutions unless they really // are close qDebug("norm:%d tolerance:%d", mode.norm(idealMode), idealMode.tolerance()); - if (mode.norm(idealMode) > idealMode.tolerance()) - continue; + if (mode.norm(idealMode) > idealMode.tolerance()) continue; if (bestModeInds.find(res) == bestModeInds.end()) { bestModeInds[res] = i; @@ -274,8 +259,7 @@ void AVForm::selectBestModes(QVector& allVideoModes) } bool better = CameraDevice::betterPixelFormat(mode.pixel_format, best.pixel_format); - if (mode.FPS >= best.FPS && better) - bestModeInds[res] = i; + if (mode.FPS >= best.FPS && better) bestModeInds[res] = i; } } } @@ -288,18 +272,17 @@ void AVForm::selectBestModes(QVector& allVideoModes) newVideoModes.push_back(mode); } else { int size = getModeSize(mode); - auto result = std::find_if(newVideoModes.cbegin(), newVideoModes.cend(), - [size](VideoMode mode) { return getModeSize(mode) == size; }); + auto result = + std::find_if(newVideoModes.cbegin(), newVideoModes.cend(), + [size](VideoMode mode) { return getModeSize(mode) == size; }); - if (result == newVideoModes.end()) - newVideoModes.push_back(mode); + if (result == newVideoModes.end()) newVideoModes.push_back(mode); } } allVideoModes = newVideoModes; } -void AVForm::fillCameraModesComboBox() -{ +void AVForm::fillCameraModesComboBox() { qDebug() << "selected Modes"; bool previouslyBlocked = videoModescomboBox->blockSignals(true); videoModescomboBox->clear(); @@ -308,7 +291,8 @@ void AVForm::fillCameraModesComboBox() VideoMode mode = videoModes[i]; QString str; - std::string pixelFormat = CameraDevice::getPixelFormatString(mode.pixel_format).toStdString(); + std::string pixelFormat = + CameraDevice::getPixelFormatString(mode.pixel_format).toStdString(); qDebug("width: %d, height: %d, FPS: %f, pixel format: %s\n", mode.width, mode.height, mode.FPS, pixelFormat.c_str()); @@ -321,21 +305,19 @@ void AVForm::fillCameraModesComboBox() videoModescomboBox->addItem(str); } - if (videoModes.isEmpty()) - videoModescomboBox->addItem(tr("Default resolution")); + if (videoModes.isEmpty()) videoModescomboBox->addItem(tr("Default resolution")); videoModescomboBox->blockSignals(previouslyBlocked); } -int AVForm::searchPreferredIndex() -{ +int AVForm::searchPreferredIndex() { QRect prefRes = videoSettings->getCamVideoRes(); float prefFPS = videoSettings->getCamVideoFPS(); for (int i = 0; i < videoModes.size(); ++i) { VideoMode mode = videoModes[i]; - if (mode.width == prefRes.width() && mode.height == prefRes.height() - && (qAbs(mode.FPS - prefFPS) < 0.0001f)) { + if (mode.width == prefRes.width() && mode.height == prefRes.height() && + (qAbs(mode.FPS - prefFPS) < 0.0001f)) { return i; } } @@ -343,14 +325,14 @@ int AVForm::searchPreferredIndex() return -1; } -void AVForm::fillScreenModesComboBox() -{ +void AVForm::fillScreenModesComboBox() { bool previouslyBlocked = videoModescomboBox->blockSignals(true); videoModescomboBox->clear(); for (int i = 0; i < videoModes.size(); ++i) { VideoMode mode = videoModes[i]; - std::string pixelFormat = CameraDevice::getPixelFormatString(mode.pixel_format).toStdString(); + std::string pixelFormat = + CameraDevice::getPixelFormatString(mode.pixel_format).toStdString(); qDebug("%dx%d+%d,%d FPS: %f, pixel format: %s\n", mode.width, mode.height, mode.x, mode.y, mode.FPS, pixelFormat.c_str()); @@ -366,8 +348,7 @@ void AVForm::fillScreenModesComboBox() videoModescomboBox->blockSignals(previouslyBlocked); } -void AVForm::fillAudioQualityComboBox() -{ +void AVForm::fillAudioQualityComboBox() { const bool previouslyBlocked = audioQualityComboBox->blockSignals(true); audioQualityComboBox->addItem(tr("High (64 kbps)"), 64); @@ -382,8 +363,7 @@ void AVForm::fillAudioQualityComboBox() audioQualityComboBox->blockSignals(previouslyBlocked); } -void AVForm::updateVideoModes(int curIndex) -{ +void AVForm::updateVideoModes(int curIndex) { if (curIndex < 0 || curIndex >= videoDeviceList.size()) { qWarning() << "Invalid index:" << curIndex; return; @@ -433,8 +413,7 @@ void AVForm::updateVideoModes(int curIndex) videoModescomboBox->setCurrentIndex(mid); } -void AVForm::on_videoDevCombobox_currentIndexChanged(int index) -{ +void AVForm::on_videoDevCombobox_currentIndexChanged(int index) { assert(0 <= index && index < videoDeviceList.size()); videoSettings->setScreenGrabbed(false); @@ -457,17 +436,15 @@ void AVForm::on_videoDevCombobox_currentIndexChanged(int index) camera.setupDevice(dev, mode); if (dev == "none") { // TODO: Use injected `coreAv` currently injected `nullptr` -// Core::getInstance()->getAv()->sendNoVideo(); + // Core::getInstance()->getAv()->sendNoVideo(); } } -void AVForm::on_audioQualityComboBox_currentIndexChanged(int index) -{ +void AVForm::on_audioQualityComboBox_currentIndexChanged(int index) { audioSettings->setAudioBitrate(audioQualityComboBox->currentData().toInt()); } -void AVForm::getVideoDevices() -{ +void AVForm::getVideoDevices() { QString settingsInDev = videoSettings->getVideoDev(); int videoDevIndex = 0; videoDeviceList = CameraDevice::getDeviceList(); @@ -476,21 +453,16 @@ void AVForm::getVideoDevices() videoDevCombobox->clear(); for (QPair device : videoDeviceList) { videoDevCombobox->addItem(device.second); - if (device.first == settingsInDev) - videoDevIndex = videoDevCombobox->count() - 1; + if (device.first == settingsInDev) videoDevIndex = videoDevCombobox->count() - 1; } videoDevCombobox->setCurrentIndex(videoDevIndex); videoDevCombobox->blockSignals(false); updateVideoModes(videoDevIndex); } -int AVForm::getModeSize(VideoMode mode) -{ - return qRound(mode.height / 120.0) * 120; -} +int AVForm::getModeSize(VideoMode mode) { return qRound(mode.height / 120.0) * 120; } -void AVForm::getAudioInDevices() -{ +void AVForm::getAudioInDevices() { QStringList deviceNames; deviceNames << tr("Disabled") << audio->inDeviceNames(); @@ -508,8 +480,7 @@ void AVForm::getAudioInDevices() inDevCombobox->setCurrentIndex(idx); } -void AVForm::getAudioOutDevices() -{ +void AVForm::getAudioOutDevices() { QStringList deviceNames; deviceNames << tr("Disabled") << audio->outDeviceNames(); @@ -527,8 +498,7 @@ void AVForm::getAudioOutDevices() outDevCombobox->setCurrentIndex(idx); } -void AVForm::on_inDevCombobox_currentIndexChanged(int deviceIndex) -{ +void AVForm::on_inDevCombobox_currentIndexChanged(int deviceIndex) { const bool inputEnabled = deviceIndex > 0; audioSettings->setAudioInDevEnabled(inputEnabled); @@ -551,8 +521,7 @@ void AVForm::on_inDevCombobox_currentIndexChanged(int deviceIndex) } } -void AVForm::on_outDevCombobox_currentIndexChanged(int deviceIndex) -{ +void AVForm::on_outDevCombobox_currentIndexChanged(int deviceIndex) { const bool outputEnabled = deviceIndex > 0; audioSettings->setAudioOutDevEnabled(outputEnabled); @@ -572,14 +541,14 @@ void AVForm::on_outDevCombobox_currentIndexChanged(int deviceIndex) playbackSlider->setEnabled(outputEnabled); } -void AVForm::on_playbackSlider_valueChanged(int sliderSteps) -{ +void AVForm::on_playbackSlider_valueChanged(int sliderSteps) { const int settingsVolume = getValueFromSteps(sliderSteps, audioSettings->getOutVolumeMin(), audioSettings->getOutVolumeMax()); audioSettings->setOutVolume(settingsVolume); if (audio->isOutputReady()) { - const qreal volume = getValueFromSteps(sliderSteps, audio->minOutputVolume(), audio->maxOutputVolume()); + const qreal volume = + getValueFromSteps(sliderSteps, audio->minOutputVolume(), audio->maxOutputVolume()); audio->setOutputVolume(volume); if (cbEnableTestSound->isChecked() && audioSink) { @@ -588,8 +557,7 @@ void AVForm::on_playbackSlider_valueChanged(int sliderSteps) } } -void AVForm::on_cbEnableTestSound_stateChanged() -{ +void AVForm::on_cbEnableTestSound_stateChanged() { audioSettings->setEnableTestSound(cbEnableTestSound->isChecked()); if (cbEnableTestSound->isChecked() && audio->isOutputReady() && audioSink) { @@ -597,24 +565,20 @@ void AVForm::on_cbEnableTestSound_stateChanged() } } -void AVForm::on_microphoneSlider_valueChanged(int sliderSteps) -{ +void AVForm::on_microphoneSlider_valueChanged(int sliderSteps) { const qreal dB = getValueFromSteps(sliderSteps, audio->minInputGain(), audio->maxInputGain()); audioSettings->setAudioInGainDecibel(dB); audio->setInputGain(dB); } -void AVForm::on_audioThresholdSlider_valueChanged(int sliderSteps) -{ +void AVForm::on_audioThresholdSlider_valueChanged(int sliderSteps) { const qreal normThreshold = - getValueFromSteps(sliderSteps, audio->minInputThreshold(), audio->maxInputThreshold()); + getValueFromSteps(sliderSteps, audio->minInputThreshold(), audio->maxInputThreshold()); audioSettings->setAudioThreshold(normThreshold); audio->setInputThreshold(normThreshold); } -void AVForm::createVideoSurface() -{ - if (camVideoSurface) - return; +void AVForm::createVideoSurface() { + if (camVideoSurface) return; camVideoSurface = new VideoSurface(QPixmap(), CamFrame); camVideoSurface->setObjectName(QStringLiteral("CamVideoSurface")); @@ -623,32 +587,24 @@ void AVForm::createVideoSurface() gridLayout->addWidget(camVideoSurface, 0, 0, 1, 1); } -void AVForm::killVideoSurface() -{ - if (!camVideoSurface) - return; +void AVForm::killVideoSurface() { + if (!camVideoSurface) return; QLayoutItem* child; - while ((child = gridLayout->takeAt(0)) != nullptr) - delete child; + while ((child = gridLayout->takeAt(0)) != nullptr) delete child; camVideoSurface->close(); delete camVideoSurface; camVideoSurface = nullptr; } -void AVForm::retranslateUi() -{ - Ui::AVForm::retranslateUi(this); -} +void AVForm::retranslateUi() { Ui::AVForm::retranslateUi(this); } -int AVForm::getStepsFromValue(qreal val, qreal valMin, qreal valMax) -{ +int AVForm::getStepsFromValue(qreal val, qreal valMin, qreal valMax) { const float norm = (val - valMin) / (valMax - valMin); return norm * totalSliderSteps; } -qreal AVForm::getValueFromSteps(int steps, qreal valMin, qreal valMax) -{ +qreal AVForm::getValueFromSteps(int steps, qreal valMin, qreal valMax) { return (static_cast(steps) / totalSliderSteps) * (valMax - valMin) + valMin; } diff --git a/src/modules/im/src/widget/form/settings/avform.h b/src/modules/im/src/widget/form/settings/avform.h index 9666324d..0d82a12d 100644 --- a/src/modules/im/src/widget/form/settings/avform.h +++ b/src/modules/im/src/widget/form/settings/avform.h @@ -18,8 +18,8 @@ #include #include "genericsettings.h" -#include "ui_avform.h" #include "src/video/videomode.h" +#include "ui_avform.h" #include @@ -31,17 +31,12 @@ class CameraSource; class CoreAV; class IVideoSettings; class VideoSurface; -class AVForm : public GenericForm, private Ui::AVForm -{ +class AVForm : public GenericForm, private Ui::AVForm { Q_OBJECT public: - AVForm(CameraSource& camera, - IAudioSettings* audioSettings, IVideoSettings* videoSettings); + AVForm(CameraSource& camera, IAudioSettings* audioSettings, IVideoSettings* videoSettings); ~AVForm() override; - QString getFormName() final override - { - return tr("Audio/Video"); - } + QString getFormName() final override { return tr("Audio/Video"); } private: void getAudioInDevices(); @@ -102,7 +97,7 @@ private slots: QVector> videoDeviceList; QVector videoModes; uint alSource; - const uint totalSliderSteps = 100; // arbitrary number of steps to give slider a good "feel" + const uint totalSliderSteps = 100; // arbitrary number of steps to give slider a good "feel" }; #endif diff --git a/src/modules/im/src/widget/form/settings/generalform.cpp b/src/modules/im/src/widget/form/settings/generalform.cpp index 590338b9..1a2badc9 100644 --- a/src/modules/im/src/widget/form/settings/generalform.cpp +++ b/src/modules/im/src/widget/form/settings/generalform.cpp @@ -29,16 +29,13 @@ #include "src/widget/widget.h" - /** * @class GeneralForm * * This form contains all settings that are not suited to other forms */ GeneralForm::GeneralForm(SettingsWidget* myParent) - : GenericForm(QPixmap(":/img/settings/general.png")) - , bodyUI(new Ui::GeneralSettings) -{ + : GenericForm(QPixmap(":/img/settings/general.png")), bodyUI(new Ui::GeneralSettings) { parent = myParent; bodyUI->setupUi(this); @@ -47,71 +44,63 @@ GeneralForm::GeneralForm(SettingsWidget* myParent) const RecursiveSignalBlocker signalBlocker(this); Settings& s = Settings::getInstance(); - //先获取当前语言 - auto & okSettings = ok::base::OkSettings::getInstance(); - + // 先获取当前语言 + auto& okSettings = ok::base::OkSettings::getInstance(); bodyUI->statusChanges->setChecked(s.getStatusChangeNotificationEnabled()); bodyUI->groupJoinLeaveMessages->setChecked(s.getShowGroupJoinLeaveMessages()); bodyUI->autoAwaySpinBox->setValue(s.getAutoAwayTime()); bodyUI->autoSaveFilesDir->setText(s.getGlobalAutoAcceptDir()); - bodyUI->maxAutoAcceptSizeMB->setValue(static_cast(s.getMaxAutoAcceptSize()) / 1024 / 1024); + bodyUI->maxAutoAcceptSizeMB->setValue(static_cast(s.getMaxAutoAcceptSize()) / 1024 / + 1024); bodyUI->autoacceptFiles->setChecked(okSettings.getAutoSaveEnabled()); - #ifndef QTOX_PLATFORM_EXT - bodyUI->autoAwayLabel->setEnabled(false); // these don't seem to change the appearance of the widgets, - bodyUI->autoAwaySpinBox->setEnabled(false); // though they are unusable + bodyUI->autoAwayLabel->setEnabled( + false); // these don't seem to change the appearance of the widgets, + bodyUI->autoAwaySpinBox->setEnabled(false); // though they are unusable #endif eventsInit(); settings::Translator::registerHandler(std::bind(&GeneralForm::retranslateUi, this), this); } -GeneralForm::~GeneralForm() -{ +GeneralForm::~GeneralForm() { settings::Translator::unregister(this); delete bodyUI; } -void GeneralForm::on_statusChanges_stateChanged() -{ +void GeneralForm::on_statusChanges_stateChanged() { Settings::getInstance().setStatusChangeNotificationEnabled(bodyUI->statusChanges->isChecked()); } -void GeneralForm::on_groupJoinLeaveMessages_stateChanged() -{ - Settings::getInstance().setShowGroupJoinLeaveMessages(bodyUI->groupJoinLeaveMessages->isChecked()); +void GeneralForm::on_groupJoinLeaveMessages_stateChanged() { + Settings::getInstance().setShowGroupJoinLeaveMessages( + bodyUI->groupJoinLeaveMessages->isChecked()); } -void GeneralForm::on_autoAwaySpinBox_editingFinished() -{ +void GeneralForm::on_autoAwaySpinBox_editingFinished() { int minutes = bodyUI->autoAwaySpinBox->value(); Settings::getInstance().setAutoAwayTime(minutes); } -void GeneralForm::on_autoacceptFiles_stateChanged() -{ +void GeneralForm::on_autoacceptFiles_stateChanged() { ok::base::OkSettings::getInstance().setAutoSaveEnabled(bodyUI->autoacceptFiles->isChecked()); } -void GeneralForm::on_autoSaveFilesDir_clicked() -{ +void GeneralForm::on_autoSaveFilesDir_clicked() { QString previousDir = Settings::getInstance().getGlobalAutoAcceptDir(); - QString directory = - QFileDialog::getExistingDirectory(Q_NULLPTR, - tr("Choose an auto accept directory", "popup title"), - QDir::homePath()); - if (directory.isEmpty()) // cancel was pressed + QString directory = QFileDialog::getExistingDirectory( + Q_NULLPTR, tr("Choose an auto accept directory", "popup title"), QDir::homePath()); + if (directory.isEmpty()) // cancel was pressed directory = previousDir; Settings::getInstance().setGlobalAutoAcceptDir(directory); bodyUI->autoSaveFilesDir->setText(directory); } -void GeneralForm::on_maxAutoAcceptSizeMB_editingFinished() -{ +void GeneralForm::on_maxAutoAcceptSizeMB_editingFinished() { auto newMaxSizeMB = bodyUI->maxAutoAcceptSizeMB->value(); auto newMaxSizeB = std::lround(newMaxSizeMB * 1024 * 1024); @@ -121,7 +110,4 @@ void GeneralForm::on_maxAutoAcceptSizeMB_editingFinished() /** * @brief Retranslate all elements in the form. */ -void GeneralForm::retranslateUi() -{ - bodyUI->retranslateUi(this); -} +void GeneralForm::retranslateUi() { bodyUI->retranslateUi(this); } diff --git a/src/modules/im/src/widget/form/settings/generalform.h b/src/modules/im/src/widget/form/settings/generalform.h index 7e416b99..2e35b641 100644 --- a/src/modules/im/src/widget/form/settings/generalform.h +++ b/src/modules/im/src/widget/form/settings/generalform.h @@ -21,16 +21,12 @@ class GeneralSettings; class SettingsWidget; -class GeneralForm : public GenericForm -{ +class GeneralForm : public GenericForm { Q_OBJECT public: explicit GeneralForm(SettingsWidget* parent); ~GeneralForm(); - virtual QString getFormName() final override - { - return tr("General"); - } + virtual QString getFormName() final override { return tr("General"); } signals: void updateIcons(); diff --git a/src/modules/im/src/widget/form/settings/genericsettings.cpp b/src/modules/im/src/widget/form/settings/genericsettings.cpp index c30ffb3d..62af0c17 100644 --- a/src/modules/im/src/widget/form/settings/genericsettings.cpp +++ b/src/modules/im/src/widget/form/settings/genericsettings.cpp @@ -24,15 +24,9 @@ * It provides correct behaviour of controls for settings forms. */ -GenericForm::GenericForm(const QPixmap& icon, QWidget* parent) - : QWidget(parent), formIcon(icon) -{ -} +GenericForm::GenericForm(const QPixmap& icon, QWidget* parent) : QWidget(parent), formIcon(icon) {} -QPixmap GenericForm::getFormIcon() -{ - return formIcon; -} +QPixmap GenericForm::getFormIcon() { return formIcon; } /** * @brief Prevent stealing mouse wheel scroll. @@ -42,8 +36,7 @@ QPixmap GenericForm::getFormIcon() * theme / skin / icons etc. * @see GenericForm::eventFilter(QObject *o, QEvent *e) at the bottom of this file for more */ -void GenericForm::eventsInit() -{ +void GenericForm::eventsInit() { for (QComboBox* cb : findChildren()) { cb->installEventFilter(this); cb->setFocusPolicy(Qt::StrongFocus); @@ -54,7 +47,8 @@ void GenericForm::eventsInit() sp->setFocusPolicy(Qt::WheelFocus); } - for (QCheckBox* cb : findChildren()) // this one is to allow scrolling on checkboxes + for (QCheckBox* cb : + findChildren()) // this one is to allow scrolling on checkboxes cb->installEventFilter(this); } @@ -64,11 +58,10 @@ void GenericForm::eventsInit() * @param e Event object. * @return True to stop it being handled further, false otherwise. */ -bool GenericForm::eventFilter(QObject* o, QEvent* e) -{ - if ((e->type() == QEvent::Wheel) - && (qobject_cast(o) || qobject_cast(o) - || qobject_cast(o))) { +bool GenericForm::eventFilter(QObject* o, QEvent* e) { + if ((e->type() == QEvent::Wheel) && + (qobject_cast(o) || qobject_cast(o) || + qobject_cast(o))) { e->ignore(); return true; } diff --git a/src/modules/im/src/widget/form/settings/genericsettings.h b/src/modules/im/src/widget/form/settings/genericsettings.h index b53d90af..4ad23663 100644 --- a/src/modules/im/src/widget/form/settings/genericsettings.h +++ b/src/modules/im/src/widget/form/settings/genericsettings.h @@ -15,14 +15,11 @@ #include -class GenericForm : public QWidget -{ +class GenericForm : public QWidget { Q_OBJECT public: - explicit GenericForm(const QPixmap& icon, QWidget* parent=nullptr); - virtual ~GenericForm() - { - } + explicit GenericForm(const QPixmap& icon, QWidget* parent = nullptr); + virtual ~GenericForm() {} virtual QString getFormName() = 0; QPixmap getFormIcon(); diff --git a/src/modules/im/src/widget/form/settings/privacyform.cpp b/src/modules/im/src/widget/form/settings/privacyform.cpp index 52fadb29..5aab9c6b 100644 --- a/src/modules/im/src/widget/form/settings/privacyform.cpp +++ b/src/modules/im/src/widget/form/settings/privacyform.cpp @@ -33,9 +33,7 @@ #include "src/widget/widget.h" PrivacyForm::PrivacyForm() - : GenericForm(QPixmap(":/img/settings/privacy.png")) - , bodyUI(new Ui::PrivacySettings) -{ + : GenericForm(QPixmap(":/img/settings/privacy.png")), bodyUI(new Ui::PrivacySettings) { bodyUI->setupUi(this); // block all child signals during initialization @@ -45,91 +43,87 @@ PrivacyForm::PrivacyForm() settings::Translator::registerHandler(std::bind(&PrivacyForm::retranslateUi, this), this); } -PrivacyForm::~PrivacyForm() -{ +PrivacyForm::~PrivacyForm() { settings::Translator::unregister(this); delete bodyUI; } -void PrivacyForm::on_cbKeepHistory_stateChanged() -{ - Settings::getInstance().setEnableLogging(bodyUI->cbKeepHistory->isChecked()); - if (!bodyUI->cbKeepHistory->isChecked()) { - emit clearAllReceipts(); - QMessageBox::StandardButton dialogDelHistory; - dialogDelHistory = - QMessageBox::question(nullptr, tr("Confirmation"), - tr("Do you want to permanently delete all chat history?"), - QMessageBox::Yes | QMessageBox::No); - if (dialogDelHistory == QMessageBox::Yes) { - Nexus::getProfile()->getHistory()->eraseHistory(); - } - } -} - -void PrivacyForm::on_cbTypingNotification_stateChanged() -{ - Settings::getInstance().setTypingNotification(bodyUI->cbTypingNotification->isChecked()); -} - -void PrivacyForm::on_nospamLineEdit_editingFinished() -{ -// QString newNospam = bodyUI->nospamLineEdit->text(); - -// bool ok; -// uint32_t nospam = newNospam.toLongLong(&ok, 16); -// if (ok) -// Core::getInstance()->setNospam(nospam); -} - -void PrivacyForm::showEvent(QShowEvent*) -{ +// void PrivacyForm::on_cbKeepHistory_stateChanged() +//{ +// Settings::getInstance().setEnableLogging(bodyUI->cbKeepHistory->isChecked()); +// if (!bodyUI->cbKeepHistory->isChecked()) { +// emit clearAllReceipts(); +// QMessageBox::StandardButton dialogDelHistory; +// dialogDelHistory = +// QMessageBox::question(nullptr, tr("Confirmation"), +// tr("Do you want to permanently delete all chat history?"), +// QMessageBox::Yes | QMessageBox::No); +// if (dialogDelHistory == QMessageBox::Yes) { +// Nexus::getProfile()->getHistory()->eraseHistory(); +// } +// } +// } +// +// void PrivacyForm::on_cbTypingNotification_stateChanged() +//{ +// Settings::getInstance().setTypingNotification(bodyUI->cbTypingNotification->isChecked()); +// } +// +// void PrivacyForm::on_nospamLineEdit_editingFinished() +//{ +//// QString newNospam = bodyUI->nospamLineEdit->text(); +// +//// bool ok; +//// uint32_t nospam = newNospam.toLongLong(&ok, 16); +//// if (ok) +//// Core::getInstance()->setNospam(nospam); +//} + +void PrivacyForm::showEvent(QShowEvent*) { const Settings& s = Settings::getInstance(); -// bodyUI->nospamLineEdit->setText(Core::getInstance()->getSelfId().getNoSpamString()); + // bodyUI->nospamLineEdit->setText(Core::getInstance()->getSelfId().getNoSpamString()); bodyUI->cbTypingNotification->setChecked(s.getTypingNotification()); bodyUI->cbKeepHistory->setChecked(Settings::getInstance().getEnableLogging()); bodyUI->blackListTextEdit->setText(s.getBlackList().join('\n')); } - -void PrivacyForm::on_randomNosapamButton_clicked() -{ - QTime time = QTime::currentTime(); -#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) - QRandomGenerator((uint)time.msec()); -#else - qsrand((uint)time.msec()); -#endif - - uint32_t newNospam{0}; - for (int i = 0; i < 4; ++i) -#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) - newNospam = (newNospam << 8) + (QRandomGenerator::global()->generate() % 256); // Generate byte by byte. For some reason. -#else - newNospam = (newNospam << 8) + (qrand() % 256); // Generate byte by byte. For some reason. -#endif - -// Core::getInstance()->setNospam(newNospam); -// bodyUI->nospamLineEdit->setText(Core::getInstance()->getSelfId().getNoSpamString()); -} - -void PrivacyForm::on_nospamLineEdit_textChanged() -{ -// QString str = bodyUI->nospamLineEdit->text(); -// int curs = bodyUI->nospamLineEdit->cursorPosition(); -// if (str.length() != 8) { -// str = QString("00000000").replace(0, str.length(), str); -// bodyUI->nospamLineEdit->setText(str); -// bodyUI->nospamLineEdit->setCursorPosition(curs); -// }; -} - -void PrivacyForm::on_blackListTextEdit_textChanged() -{ - const QStringList strlist = bodyUI->blackListTextEdit->toPlainText().split('\n'); - Settings::getInstance().setBlackList(strlist); -} - -void PrivacyForm::retranslateUi() -{ - bodyUI->retranslateUi(this); -} +// +// void PrivacyForm::on_randomNosapamButton_clicked() +//{ +// QTime time = QTime::currentTime(); +// #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) +// QRandomGenerator((uint)time.msec()); +// #else +// qsrand((uint)time.msec()); +// #endif +// +// uint32_t newNospam{0}; +// for (int i = 0; i < 4; ++i) +// #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) +// newNospam = (newNospam << 8) + (QRandomGenerator::global()->generate() % 256); // Generate +// byte by byte. For some reason. +// #else +// newNospam = (newNospam << 8) + (qrand() % 256); // Generate byte by byte. For some reason. +// #endif +// +//// Core::getInstance()->setNospam(newNospam); +//// bodyUI->nospamLineEdit->setText(Core::getInstance()->getSelfId().getNoSpamString()); +//} + +// void PrivacyForm::on_nospamLineEdit_textChanged() +//{ +// QString str = bodyUI->nospamLineEdit->text(); +// int curs = bodyUI->nospamLineEdit->cursorPosition(); +// if (str.length() != 8) { +// str = QString("00000000").replace(0, str.length(), str); +// bodyUI->nospamLineEdit->setText(str); +// bodyUI->nospamLineEdit->setCursorPosition(curs); +// }; +// } + +// void PrivacyForm::on_blackListTextEdit_textChanged() +//{ +// const QStringList strlist = bodyUI->blackListTextEdit->toPlainText().split('\n'); +// Settings::getInstance().setBlackList(strlist); +// } + +void PrivacyForm::retranslateUi() { bodyUI->retranslateUi(this); } diff --git a/src/modules/im/src/widget/form/settings/privacyform.h b/src/modules/im/src/widget/form/settings/privacyform.h index 190f586e..cd01c225 100644 --- a/src/modules/im/src/widget/form/settings/privacyform.h +++ b/src/modules/im/src/widget/form/settings/privacyform.h @@ -19,27 +19,17 @@ namespace Ui { class PrivacySettings; } -class PrivacyForm : public GenericForm -{ +class PrivacyForm : public GenericForm { Q_OBJECT public: PrivacyForm(); ~PrivacyForm(); - virtual QString getFormName() final override - { - return tr("Privacy"); - } + virtual QString getFormName() final override { return tr("Privacy"); } signals: void clearAllReceipts(); private slots: - void on_cbKeepHistory_stateChanged(); - void on_cbTypingNotification_stateChanged(); - void on_nospamLineEdit_editingFinished(); - void on_randomNosapamButton_clicked(); - void on_nospamLineEdit_textChanged(); - void on_blackListTextEdit_textChanged(); virtual void showEvent(QShowEvent*) final override; private: diff --git a/src/modules/im/src/widget/form/settings/userinterfaceform.cpp b/src/modules/im/src/widget/form/settings/userinterfaceform.cpp index d9804243..8b3bde83 100644 --- a/src/modules/im/src/widget/form/settings/userinterfaceform.cpp +++ b/src/modules/im/src/widget/form/settings/userinterfaceform.cpp @@ -48,9 +48,8 @@ * Restores all controls from the settings. */ UserInterfaceForm::UserInterfaceForm(SettingsWidget* myParent) - : GenericForm(QPixmap(":/img/settings/general.png"), myParent), - bodyUI{new Ui::UserInterfaceSettings} -{ + : GenericForm(QPixmap(":/img/settings/general.png"), myParent) + , bodyUI{new Ui::UserInterfaceSettings} { bodyUI->setupUi(this); parent = myParent; @@ -83,12 +82,12 @@ UserInterfaceForm::UserInterfaceForm(SettingsWidget* myParent) bodyUI->showWindow->setChecked(s.getShowWindow()); -// bodyUI->cbGroupchatPosition->setChecked(s.getGroupchatPosition()); -// bodyUI->cbCompactLayout->setChecked(s.getCompactLayout()); -// bodyUI->cbSeparateWindow->setChecked(s.getSeparateWindow()); -// bodyUI->cbDontGroupWindows->setChecked(s.getDontGroupWindows()); -// bodyUI->cbDontGroupWindows->setEnabled(s.getSeparateWindow()); -// bodyUI->cbShowIdenticons->setChecked(s.getShowIdenticons()); + // bodyUI->cbGroupchatPosition->setChecked(s.getGroupchatPosition()); + // bodyUI->cbCompactLayout->setChecked(s.getCompactLayout()); + // bodyUI->cbSeparateWindow->setChecked(s.getSeparateWindow()); + // bodyUI->cbDontGroupWindows->setChecked(s.getDontGroupWindows()); + // bodyUI->cbDontGroupWindows->setEnabled(s.getSeparateWindow()); + // bodyUI->cbShowIdenticons->setChecked(s.getShowIdenticons()); bodyUI->useEmoticons->setChecked(s.getUseEmoticons()); for (auto entry : SmileyPack::listSmileyPacks()) @@ -112,8 +111,7 @@ UserInterfaceForm::UserInterfaceForm(SettingsWidget* myParent) bodyUI->styleBrowser->setCurrentText(style); - for (QString color : Style::getThemeColorNames()) - bodyUI->themeColorCBox->addItem(color); + for (QString color : Style::getThemeColorNames()) bodyUI->themeColorCBox->addItem(color); bodyUI->themeColorCBox->setCurrentIndex(s.getThemeColor()); bodyUI->emoticonSize->setValue(s.getEmojiFontPointSize()); @@ -121,9 +119,7 @@ UserInterfaceForm::UserInterfaceForm(SettingsWidget* myParent) QLocale ql; QStringList timeFormats; timeFormats << ql.timeFormat(QLocale::ShortFormat) << ql.timeFormat(QLocale::LongFormat) - << "hh:mm AP" - << "hh:mm:ss AP" - << "hh:mm:ss"; + << "hh:mm AP" << "hh:mm:ss AP" << "hh:mm:ss"; timeFormats.removeDuplicates(); bodyUI->timestamp->addItems(timeFormats); @@ -131,28 +127,24 @@ UserInterfaceForm::UserInterfaceForm(SettingsWidget* myParent) QRegularExpressionValidator* validator = new QRegularExpressionValidator(re, this); QString timeFormat = s.getTimestampFormat(); - if (!re.match(timeFormat).hasMatch()) - timeFormat = timeFormats[0]; + if (!re.match(timeFormat).hasMatch()) timeFormat = timeFormats[0]; bodyUI->timestamp->setCurrentText(timeFormat); bodyUI->timestamp->setValidator(validator); on_timestamp_editTextChanged(timeFormat); QStringList dateFormats; - dateFormats << QStringLiteral("yyyy-MM-dd") // ISO 8601 - // format strings from system locale + dateFormats << QStringLiteral("yyyy-MM-dd") // ISO 8601 + // format strings from system locale << ql.dateFormat(QLocale::LongFormat) << ql.dateFormat(QLocale::ShortFormat) - << ql.dateFormat(QLocale::NarrowFormat) << "dd-MM-yyyy" - << "d-MM-yyyy" - << "dddd dd-MM-yyyy" - << "dddd d-MM"; + << ql.dateFormat(QLocale::NarrowFormat) << "dd-MM-yyyy" << "d-MM-yyyy" + << "dddd dd-MM-yyyy" << "dddd d-MM"; dateFormats.removeDuplicates(); bodyUI->dateFormats->addItems(dateFormats); QString dateFormat = s.getDateFormat(); - if (!re.match(dateFormat).hasMatch()) - dateFormat = dateFormats[0]; + if (!re.match(dateFormat).hasMatch()) dateFormat = dateFormats[0]; bodyUI->dateFormats->setCurrentText(dateFormat); bodyUI->dateFormats->setValidator(validator); @@ -162,14 +154,12 @@ UserInterfaceForm::UserInterfaceForm(SettingsWidget* myParent) settings::Translator::registerHandler(std::bind(&UserInterfaceForm::retranslateUi, this), this); } -UserInterfaceForm::~UserInterfaceForm() -{ +UserInterfaceForm::~UserInterfaceForm() { settings::Translator::unregister(this); delete bodyUI; } -void UserInterfaceForm::on_styleBrowser_currentIndexChanged(QString style) -{ +void UserInterfaceForm::on_styleBrowser_currentIndexChanged(QString style) { if (bodyUI->styleBrowser->currentIndex() == 0) Settings::getInstance().setStyle("None"); else @@ -179,13 +169,11 @@ void UserInterfaceForm::on_styleBrowser_currentIndexChanged(QString style) parent->setBodyHeadStyle(style); } -void UserInterfaceForm::on_emoticonSize_editingFinished() -{ +void UserInterfaceForm::on_emoticonSize_editingFinished() { Settings::getInstance().setEmojiFontPointSize(bodyUI->emoticonSize->value()); } -void UserInterfaceForm::on_timestamp_editTextChanged(const QString& format) -{ +void UserInterfaceForm::on_timestamp_editTextChanged(const QString& format) { QString timeExample = QTime::currentTime().toString(format); bodyUI->timeExample->setText(timeExample); @@ -194,8 +182,7 @@ void UserInterfaceForm::on_timestamp_editTextChanged(const QString& format) settings::Translator::translate(OK_IM_MODULE, locale); } -void UserInterfaceForm::on_dateFormats_editTextChanged(const QString& format) -{ +void UserInterfaceForm::on_dateFormats_editTextChanged(const QString& format) { QString dateExample = QDate::currentDate().toString(format); bodyUI->dateExample->setText(dateExample); @@ -204,21 +191,18 @@ void UserInterfaceForm::on_dateFormats_editTextChanged(const QString& format) settings::Translator::translate(OK_IM_MODULE, locale); } -void UserInterfaceForm::on_useEmoticons_stateChanged() -{ +void UserInterfaceForm::on_useEmoticons_stateChanged() { Settings::getInstance().setUseEmoticons(bodyUI->useEmoticons->isChecked()); bodyUI->smileyPackBrowser->setEnabled(bodyUI->useEmoticons->isChecked()); } -void UserInterfaceForm::on_textStyleComboBox_currentTextChanged() -{ +void UserInterfaceForm::on_textStyleComboBox_currentTextChanged() { Settings::StyleType styleType = - static_cast(bodyUI->textStyleComboBox->currentIndex()); + static_cast(bodyUI->textStyleComboBox->currentIndex()); Settings::getInstance().setStylePreference(styleType); } -void UserInterfaceForm::on_smileyPackBrowser_currentIndexChanged(int index) -{ +void UserInterfaceForm::on_smileyPackBrowser_currentIndexChanged(int index) { QString filename = bodyUI->smileyPackBrowser->itemData(index).toString(); Settings::getInstance().setSmileyPack(filename); reloadSmileys(); @@ -227,8 +211,7 @@ void UserInterfaceForm::on_smileyPackBrowser_currentIndexChanged(int index) /** * @brief Reload smileys and size information. */ -void UserInterfaceForm::reloadSmileys() -{ +void UserInterfaceForm::reloadSmileys() { QList emoticons = SmileyPack::getInstance().getEmoticons(); // sometimes there are no emoticons available, don't crash in this case @@ -238,8 +221,7 @@ void UserInterfaceForm::reloadSmileys() } QStringList smileys; - for (int i = 0; i < emoticons.size(); ++i) - smileys.push_front(emoticons.at(i).first()); + for (int i = 0; i < emoticons.size(); ++i) smileys.push_front(emoticons.at(i).first()); emoticonsIcons.clear(); const QSize size(18, 18); @@ -254,15 +236,15 @@ void UserInterfaceForm::reloadSmileys() QDesktopWidget desktop; // 8 is the count of row and column in emoji's in widget const int sideSize = 8; - int maxSide = qMin(desktop.geometry().height() / sideSize, desktop.geometry().width() / sideSize); + int maxSide = + qMin(desktop.geometry().height() / sideSize, desktop.geometry().width() / sideSize); QSize maxSize(maxSide, maxSide); QSize actualSize = emoticonsIcons.first()->actualSize(maxSize); bodyUI->emoticonSize->setMaximum(actualSize.width()); } -void UserInterfaceForm::on_notify_stateChanged() -{ +void UserInterfaceForm::on_notify_stateChanged() { const bool notify = bodyUI->notify->isChecked(); Settings::getInstance().setNotify(notify); bodyUI->groupOnlyNotfiyWhenMentioned->setEnabled(notify); @@ -271,38 +253,32 @@ void UserInterfaceForm::on_notify_stateChanged() bodyUI->desktopNotify->setEnabled(notify); } -void UserInterfaceForm::on_notifySound_stateChanged() -{ +void UserInterfaceForm::on_notifySound_stateChanged() { const bool notify = bodyUI->notifySound->isChecked(); Settings::getInstance().setNotifySound(notify); bodyUI->busySound->setEnabled(notify); } -void UserInterfaceForm::on_desktopNotify_stateChanged() -{ +void UserInterfaceForm::on_desktopNotify_stateChanged() { const bool notify = bodyUI->desktopNotify->isChecked(); Settings::getInstance().setDesktopNotify(notify); } -void UserInterfaceForm::on_busySound_stateChanged() -{ +void UserInterfaceForm::on_busySound_stateChanged() { Settings::getInstance().setBusySound(bodyUI->busySound->isChecked()); } -void UserInterfaceForm::on_showWindow_stateChanged() -{ +void UserInterfaceForm::on_showWindow_stateChanged() { Settings::getInstance().setShowWindow(bodyUI->showWindow->isChecked()); } -void UserInterfaceForm::on_groupOnlyNotfiyWhenMentioned_stateChanged() -{ +void UserInterfaceForm::on_groupOnlyNotfiyWhenMentioned_stateChanged() { // Note: UI is boolean inversed from settings to maintain setting file backwards compatibility - Settings::getInstance().setGroupAlwaysNotify(!bodyUI->groupOnlyNotfiyWhenMentioned->isChecked()); + Settings::getInstance().setGroupAlwaysNotify( + !bodyUI->groupOnlyNotfiyWhenMentioned->isChecked()); } - -void UserInterfaceForm::on_themeColorCBox_currentIndexChanged(int) -{ +void UserInterfaceForm::on_themeColorCBox_currentIndexChanged(int) { int index = bodyUI->themeColorCBox->currentIndex(); Settings::getInstance().setThemeColor(index); Style::setThemeColor(index); @@ -312,8 +288,7 @@ void UserInterfaceForm::on_themeColorCBox_currentIndexChanged(int) /** * @brief Retranslate all elements in the form. */ -void UserInterfaceForm::retranslateUi() -{ +void UserInterfaceForm::retranslateUi() { // Block signals during translation to prevent settings change RecursiveSignalBlocker signalBlocker{this}; @@ -321,7 +296,7 @@ void UserInterfaceForm::retranslateUi() // Restore text style index once translation is complete bodyUI->textStyleComboBox->setCurrentIndex( - static_cast(Settings::getInstance().getStylePreference())); + static_cast(Settings::getInstance().getStylePreference())); QStringList colorThemes(Style::getThemeColorNames()); for (int i = 0; i < colorThemes.size(); ++i) { @@ -331,19 +306,16 @@ void UserInterfaceForm::retranslateUi() bodyUI->styleBrowser->setItemText(0, tr("None")); } -void UserInterfaceForm::on_txtChatFont_currentFontChanged(const QFont& f) -{ +void UserInterfaceForm::on_txtChatFont_currentFontChanged(const QFont& f) { QFont tmpFont = f; const int px = bodyUI->txtChatFontSize->value(); - if (QFontInfo(tmpFont).pixelSize() != px) - tmpFont.setPixelSize(px); + if (QFontInfo(tmpFont).pixelSize() != px) tmpFont.setPixelSize(px); Settings::getInstance().setChatMessageFont(tmpFont); } -void UserInterfaceForm::on_txtChatFontSize_valueChanged(int px) -{ +void UserInterfaceForm::on_txtChatFontSize_valueChanged(int px) { Settings& s = Settings::getInstance(); QFont tmpFont = s.getChatMessageFont(); const int fontSize = QFontInfo(tmpFont).pixelSize(); @@ -354,13 +326,10 @@ void UserInterfaceForm::on_txtChatFontSize_valueChanged(int px) } } -void UserInterfaceForm::on_useNameColors_stateChanged(int value) -{ +void UserInterfaceForm::on_useNameColors_stateChanged(int value) { Settings::getInstance().setEnableGroupChatsColor(value); } -void UserInterfaceForm::on_notifyHide_stateChanged(int value) -{ +void UserInterfaceForm::on_notifyHide_stateChanged(int value) { Settings::getInstance().setNotifyHide(value); } - diff --git a/src/modules/im/src/widget/form/settings/userinterfaceform.h b/src/modules/im/src/widget/form/settings/userinterfaceform.h index 6458cb1a..33468924 100644 --- a/src/modules/im/src/widget/form/settings/userinterfaceform.h +++ b/src/modules/im/src/widget/form/settings/userinterfaceform.h @@ -22,16 +22,12 @@ namespace Ui { class UserInterfaceSettings; } -class UserInterfaceForm : public GenericForm -{ +class UserInterfaceForm : public GenericForm { Q_OBJECT public: explicit UserInterfaceForm(SettingsWidget* myParent); ~UserInterfaceForm(); - virtual QString getFormName() final override - { - return tr("User Interface"); - } + virtual QString getFormName() final override { return tr("User Interface"); } private slots: void on_smileyPackBrowser_currentIndexChanged(int index); @@ -49,8 +45,6 @@ private slots: void on_showWindow_stateChanged(); void on_groupOnlyNotfiyWhenMentioned_stateChanged(); - - void on_themeColorCBox_currentIndexChanged(int); void on_txtChatFont_currentFontChanged(const QFont& f); diff --git a/src/modules/im/src/widget/form/settings/verticalonlyscroller.cpp b/src/modules/im/src/widget/form/settings/verticalonlyscroller.cpp index cfe8eda7..5f2cd5c8 100644 --- a/src/modules/im/src/widget/form/settings/verticalonlyscroller.cpp +++ b/src/modules/im/src/widget/form/settings/verticalonlyscroller.cpp @@ -15,21 +15,14 @@ #include "verticalonlyscroller.h" -VerticalOnlyScroller::VerticalOnlyScroller(QWidget* parent) - : QScrollArea(parent) -{ -} +VerticalOnlyScroller::VerticalOnlyScroller(QWidget* parent) : QScrollArea(parent) {} -void VerticalOnlyScroller::resizeEvent(QResizeEvent* event) -{ +void VerticalOnlyScroller::resizeEvent(QResizeEvent* event) { QScrollArea::resizeEvent(event); - if (widget()) - widget()->setMaximumWidth(event->size().width()); + if (widget()) widget()->setMaximumWidth(event->size().width()); } -void VerticalOnlyScroller::showEvent(QShowEvent* event) -{ +void VerticalOnlyScroller::showEvent(QShowEvent* event) { QScrollArea::showEvent(event); - if (widget()) - widget()->setMaximumWidth(size().width()); + if (widget()) widget()->setMaximumWidth(size().width()); } diff --git a/src/modules/im/src/widget/form/settings/verticalonlyscroller.h b/src/modules/im/src/widget/form/settings/verticalonlyscroller.h index 8237428e..26c59f5d 100644 --- a/src/modules/im/src/widget/form/settings/verticalonlyscroller.h +++ b/src/modules/im/src/widget/form/settings/verticalonlyscroller.h @@ -18,8 +18,7 @@ class QResizeEvent; class QShowEvent; -class VerticalOnlyScroller : public QScrollArea -{ +class VerticalOnlyScroller : public QScrollArea { Q_OBJECT public: explicit VerticalOnlyScroller(QWidget* parent = nullptr); @@ -29,4 +28,4 @@ class VerticalOnlyScroller : public QScrollArea virtual void showEvent(QShowEvent* event) final override; }; -#endif // VERTICALONLYSCROLLER_H +#endif // VERTICALONLYSCROLLER_H diff --git a/src/modules/im/src/widget/form/settingswidget.cpp b/src/modules/im/src/widget/form/settingswidget.cpp index 4db587a8..617e8c3b 100644 --- a/src/modules/im/src/widget/form/settingswidget.cpp +++ b/src/modules/im/src/widget/form/settingswidget.cpp @@ -12,6 +12,7 @@ #include "settingswidget.h" +#include "lib/settings/translator.h" #include "src/audio/audio.h" #include "src/core/core.h" #include "src/core/coreav.h" @@ -23,7 +24,6 @@ #include "src/widget/form/settings/generalform.h" #include "src/widget/form/settings/privacyform.h" #include "src/widget/form/settings/userinterfaceform.h" -#include "lib/settings/translator.h" #include "src/widget/widget.h" #include @@ -32,10 +32,7 @@ #include -SettingsWidget::SettingsWidget(Widget* parent) - : QWidget(parent, Qt::Window) -{ - +SettingsWidget::SettingsWidget(Widget* parent) : QWidget(parent, Qt::Window) { IAudioSettings* audioSettings = &Settings::getInstance(); IVideoSettings* videoSettings = &Settings::getInstance(); CameraSource& camera = CameraSource::getInstance(); @@ -55,13 +52,14 @@ SettingsWidget::SettingsWidget(Widget* parent) std::unique_ptr pfrm(new PrivacyForm()); connect(pfrm.get(), &PrivacyForm::clearAllReceipts, parent, &Widget::clearAllReceipts); - AVForm* rawAvfrm = new AVForm( camera, audioSettings, videoSettings); + AVForm* rawAvfrm = new AVForm(camera, audioSettings, videoSettings); std::unique_ptr avfrm(rawAvfrm); std::unique_ptr expfrm(new AdvancedForm()); #if UPDATE_CHECK_ENABLED if (updateCheck != nullptr) { - connect(updateCheck, &UpdateCheck::updateAvailable, this, &SettingsWidget::onUpdateAvailable); + connect(updateCheck, &UpdateCheck::updateAvailable, this, + &SettingsWidget::onUpdateAvailable); } else { qWarning() << "SettingsWidget passed null UpdateCheck!"; } @@ -71,34 +69,26 @@ SettingsWidget::SettingsWidget(Widget* parent) std::move(uifrm), // std::move(pfrm), // std::move(avfrm), // - std::move(expfrm) - }}; + std::move(expfrm)}}; for (auto& cfgForm : cfgForms) settingsWidgets->addTab(cfgForm.get(), cfgForm->getFormIcon(), cfgForm->getFormName()); - connect(settingsWidgets.get(), &QTabWidget::currentChanged, this, &SettingsWidget::onTabChanged); + connect(settingsWidgets.get(), &QTabWidget::currentChanged, this, + &SettingsWidget::onTabChanged); settings::Translator::registerHandler(std::bind(&SettingsWidget::retranslateUi, this), this); } -SettingsWidget::~SettingsWidget() -{ - settings::Translator::unregister(this); -} +SettingsWidget::~SettingsWidget() { settings::Translator::unregister(this); } -void SettingsWidget::setBodyHeadStyle(QString style) -{ +void SettingsWidget::setBodyHeadStyle(QString style) { settingsWidgets->setStyle(QStyleFactory::create(style)); } -void SettingsWidget::showAbout() -{ - onTabChanged(settingsWidgets->count() - 1); -} +void SettingsWidget::showAbout() { onTabChanged(settingsWidgets->count() - 1); } -bool SettingsWidget::isShown() const -{ +bool SettingsWidget::isShown() const { if (settingsWidgets->isVisible()) { settingsWidgets->window()->windowHandle()->alert(0); return true; @@ -107,27 +97,21 @@ bool SettingsWidget::isShown() const return false; } -void SettingsWidget::show(ContentLayout* contentLayout) -{ -// contentLayout->mainContent->layout()->addWidget(settingsWidgets.get()); +void SettingsWidget::show(ContentLayout* contentLayout) { + // contentLayout->mainContent->layout()->addWidget(settingsWidgets.get()); settingsWidgets->show(); onTabChanged(settingsWidgets->currentIndex()); } -void SettingsWidget::onTabChanged(int index) -{ - settingsWidgets->setCurrentIndex(index); -} +void SettingsWidget::onTabChanged(int index) { settingsWidgets->setCurrentIndex(index); } -void SettingsWidget::onUpdateAvailable(void) -{ +void SettingsWidget::onUpdateAvailable(void) { settingsWidgets->tabBar()->setProperty("update-available", true); settingsWidgets->tabBar()->style()->unpolish(settingsWidgets->tabBar()); settingsWidgets->tabBar()->style()->polish(settingsWidgets->tabBar()); } -void SettingsWidget::retranslateUi() -{ +void SettingsWidget::retranslateUi() { for (size_t i = 0; i < cfgForms.size(); ++i) settingsWidgets->setTabText(i, cfgForms[i]->getFormName()); } diff --git a/src/modules/im/src/widget/form/settingswidget.h b/src/modules/im/src/widget/form/settingswidget.h index 9f2266a1..a7477fd6 100644 --- a/src/modules/im/src/widget/form/settingswidget.h +++ b/src/modules/im/src/widget/form/settingswidget.h @@ -31,8 +31,7 @@ class QTabWidget; class ContentLayout; class Widget; -class SettingsWidget : public QWidget -{ +class SettingsWidget : public QWidget { Q_OBJECT public: SettingsWidget(Widget* parent = nullptr); @@ -60,4 +59,4 @@ private slots: int currentIndex; }; -#endif // SETTINGSWIDGET_H +#endif // SETTINGSWIDGET_H diff --git a/src/modules/im/src/widget/form/tabcompleter.cpp b/src/modules/im/src/widget/form/tabcompleter.cpp index 4e61e276..d5369e1d 100644 --- a/src/modules/im/src/widget/form/tabcompleter.cpp +++ b/src/modules/im/src/widget/form/tabcompleter.cpp @@ -27,15 +27,12 @@ const QString TabCompleter::nickSuffix = QString(": "); -TabCompleter::TabCompleter(ChatTextEdit* msgEdit, - const Group* group) - : QObject{msgEdit} - , msgEdit{msgEdit} - , group{group} - , enabled{false} - , lastCompletionLength{0} -{ -} +TabCompleter::TabCompleter(ChatTextEdit* msgEdit, const Group* group) + : QObject{msgEdit} + , msgEdit{msgEdit} + , group{group} + , enabled{false} + , lastCompletionLength{0} {} /* from quassel/src/uisupport/multilineedit.h // Compatibility methods with the rest of the classes which still expect this to be a QLineEdit @@ -47,8 +44,7 @@ TabCompleter::TabCompleter(ChatTextEdit* msgEdit, Qt::NoModifier)); } */ -void TabCompleter::buildCompletionList() -{ +void TabCompleter::buildCompletionList() { // ensure a safe state in case we return early. completionMap.clear(); nextCompletion = completionMap.begin(); @@ -56,8 +52,8 @@ void TabCompleter::buildCompletionList() // split the string on the given RE (not chars, nums or braces/brackets) and take the last // section QString tabAbbrev = msgEdit->toPlainText() - .left(msgEdit->textCursor().position()) - .section(QRegExp("[^\\w\\d\\$:@--_\\[\\]{}|`^.\\\\]"), -1, -1); + .left(msgEdit->textCursor().position()) + .section(QRegExp("[^\\w\\d\\$:@--_\\[\\]{}|`^.\\\\]"), -1, -1); // that section is then used as the completion regex QRegExp regex(QString("^[-_\\[\\]{}|`^.\\\\]*").append(QRegExp::escape(tabAbbrev)), Qt::CaseInsensitive); @@ -65,7 +61,7 @@ void TabCompleter::buildCompletionList() const QString ownNick = group->getName(); for (const auto& name : group->getPeerList()) { if (name == ownNick) { - continue; // don't auto complete own name + continue; // don't auto complete own name } if (regex.indexIn(name) > -1) { SortableString lower = SortableString(name.toLower()); @@ -77,9 +73,7 @@ void TabCompleter::buildCompletionList() lastCompletionLength = tabAbbrev.length(); } - -void TabCompleter::complete() -{ +void TabCompleter::complete() { if (!enabled) { buildCompletionList(); enabled = true; @@ -106,7 +100,7 @@ void TabCompleter::complete() msgEdit->insertPlainText(nickSuffix); lastCompletionLength += nickSuffix.length(); } - } else { // we're at the end of the list -> start over again + } else { // we're at the end of the list -> start over again if (!completionMap.isEmpty()) { nextCompletion = completionMap.begin(); complete(); @@ -114,23 +108,19 @@ void TabCompleter::complete() } } -void TabCompleter::reset() -{ - enabled = false; -} +void TabCompleter::reset() { enabled = false; } // this determines the sort order -bool TabCompleter::SortableString::operator<(const SortableString& other) const -{ +bool TabCompleter::SortableString::operator<(const SortableString& other) const { /* QDateTime thisTime = thisUser->lastChannelActivity(_currentBufferId); QDateTime thatTime = thatUser->lastChannelActivity(_currentBufferId); if (thisTime.isValid() || thatTime.isValid()) return thisTime > thatTime; -*/ // this could be a - // useful feature at - // some point +*/ // this could be a + // useful feature at + // some point return QString::localeAwareCompare(this->contents, other.contents) < 0; } diff --git a/src/modules/im/src/widget/form/tabcompleter.h b/src/modules/im/src/widget/form/tabcompleter.h index 38d64b5f..c9466af8 100644 --- a/src/modules/im/src/widget/form/tabcompleter.h +++ b/src/modules/im/src/widget/form/tabcompleter.h @@ -13,13 +13,12 @@ #ifndef TABCOMPLETER_H #define TABCOMPLETER_H -#include "src/model/group.h" -#include "src/widget/tool/chattextedit.h" #include #include +#include "src/model/group.h" +#include "src/widget/tool/chattextedit.h" -class TabCompleter : public QObject -{ +class TabCompleter : public QObject { Q_OBJECT public: TabCompleter(ChatTextEdit* msgEdit, const Group* group); @@ -29,12 +28,8 @@ public slots: void reset(); private: - struct SortableString - { - explicit SortableString(const QString& n) - : contents{n} - { - } + struct SortableString { + explicit SortableString(const QString& n) : contents{n} {} bool operator<(const SortableString& other) const; QString contents; }; @@ -51,5 +46,4 @@ public slots: void buildCompletionList(); }; - #endif diff --git a/src/modules/im/src/widget/friendlistlayout.cpp b/src/modules/im/src/widget/friendlistlayout.cpp index 809cf543..6fd078a1 100644 --- a/src/modules/im/src/widget/friendlistlayout.cpp +++ b/src/modules/im/src/widget/friendlistlayout.cpp @@ -11,27 +11,18 @@ */ #include "friendlistlayout.h" +#include #include "friendlistwidget.h" #include "friendwidget.h" +#include "src/friendlist.h" #include "src/model/friend.h" #include "src/model/status.h" -#include "src/friendlist.h" -#include - - -FriendListLayout::FriendListLayout(QWidget* parent) - : QVBoxLayout(parent) -{ - init(); -} -FriendListLayout::~FriendListLayout() -{ +FriendListLayout::FriendListLayout(QWidget* parent) : QVBoxLayout(parent) { init(); } -} +FriendListLayout::~FriendListLayout() {} -void FriendListLayout::init() -{ +void FriendListLayout::init() { setSpacing(0); setMargin(0); @@ -45,8 +36,7 @@ void FriendListLayout::init() addLayout(friendOfflineLayout.getLayout()); } -void FriendListLayout::addFriendWidget(FriendWidget* w, Status::Status s) -{ +void FriendListLayout::addFriendWidget(FriendWidget* w, Status::Status s) { friendOfflineLayout.removeSortedWidget(w); friendOnlineLayout.removeSortedWidget(w); @@ -58,23 +48,18 @@ void FriendListLayout::addFriendWidget(FriendWidget* w, Status::Status s) friendOnlineLayout.addSortedWidget(w); } -void FriendListLayout::removeFriendWidget(FriendWidget* widget ) -{ - - friendOfflineLayout.removeSortedWidget(widget); +void FriendListLayout::removeFriendWidget(FriendWidget* widget) { + friendOfflineLayout.removeSortedWidget(widget); - friendOnlineLayout.removeSortedWidget(widget); + friendOnlineLayout.removeSortedWidget(widget); } -int FriendListLayout::indexOfFriendWidget(GenericChatItemWidget* widget, bool online) const -{ - if (online) - return friendOnlineLayout.indexOfSortedWidget(widget); +int FriendListLayout::indexOfFriendWidget(GenericChatItemWidget* widget, bool online) const { + if (online) return friendOnlineLayout.indexOfSortedWidget(widget); return friendOfflineLayout.indexOfSortedWidget(widget); } -void FriendListLayout::moveFriendWidgets(FriendListWidget* listWidget) -{ +void FriendListLayout::moveFriendWidgets(FriendListWidget* listWidget) { while (!friendOnlineLayout.getLayout()->isEmpty()) { QWidget* getWidget = friendOnlineLayout.getLayout()->takeAt(0)->widget(); @@ -91,38 +76,28 @@ void FriendListLayout::moveFriendWidgets(FriendListWidget* listWidget) } } -int FriendListLayout::friendOnlineCount() const -{ - return friendOnlineLayout.getLayout()->count(); -} +int FriendListLayout::friendOnlineCount() const { return friendOnlineLayout.getLayout()->count(); } -int FriendListLayout::friendTotalCount() const -{ +int FriendListLayout::friendTotalCount() const { return friendOfflineLayout.getLayout()->count() + friendOnlineCount(); } -bool FriendListLayout::hasChatrooms() const -{ - return !(friendOfflineLayout.getLayout()->isEmpty() && friendOnlineLayout.getLayout()->isEmpty()); +bool FriendListLayout::hasChatrooms() const { + return !(friendOfflineLayout.getLayout()->isEmpty() && + friendOnlineLayout.getLayout()->isEmpty()); } -void FriendListLayout::searchChatrooms(const QString& searchString, bool hideOnline, bool hideOffline) -{ +void FriendListLayout::searchChatrooms(const QString& searchString, bool hideOnline, + bool hideOffline) { friendOnlineLayout.search(searchString, hideOnline); friendOfflineLayout.search(searchString, hideOffline); } -QLayout* FriendListLayout::getLayoutOnline() const -{ - return friendOnlineLayout.getLayout(); -} +QLayout* FriendListLayout::getLayoutOnline() const { return friendOnlineLayout.getLayout(); } -QLayout* FriendListLayout::getLayoutOffline() const -{ - return friendOfflineLayout.getLayout(); -} +QLayout* FriendListLayout::getLayoutOffline() const { return friendOfflineLayout.getLayout(); } -QLayout* FriendListLayout::getFriendLayout(Status::Status s) const -{ - return s == Status::Status::Offline ? friendOfflineLayout.getLayout() : friendOnlineLayout.getLayout(); +QLayout* FriendListLayout::getFriendLayout(Status::Status s) const { + return s == Status::Status::Offline ? friendOfflineLayout.getLayout() + : friendOnlineLayout.getLayout(); } diff --git a/src/modules/im/src/widget/friendlistlayout.h b/src/modules/im/src/widget/friendlistlayout.h index 75259e45..a03a3223 100644 --- a/src/modules/im/src/widget/friendlistlayout.h +++ b/src/modules/im/src/widget/friendlistlayout.h @@ -13,19 +13,17 @@ #ifndef FRIENDLISTLAYOUT_H #define FRIENDLISTLAYOUT_H +#include #include "genericchatitemlayout.h" -#include "src/model/status.h" #include "src/core/core.h" -#include +#include "src/model/status.h" class FriendWidget; class FriendListWidget; -class FriendListLayout : public QVBoxLayout -{ +class FriendListLayout : public QVBoxLayout { Q_OBJECT public: - explicit FriendListLayout(QWidget* parent); ~FriendListLayout(); @@ -51,4 +49,4 @@ class FriendListLayout : public QVBoxLayout GenericChatItemLayout friendOfflineLayout; }; -#endif // FRIENDLISTLAYOUT_H +#endif // FRIENDLISTLAYOUT_H diff --git a/src/modules/im/src/widget/friendlistwidget.cpp b/src/modules/im/src/widget/friendlistwidget.cpp index 7a20dd40..b0aafdb5 100644 --- a/src/modules/im/src/widget/friendlistwidget.cpp +++ b/src/modules/im/src/widget/friendlistwidget.cpp @@ -28,171 +28,156 @@ #include "src/nexus.h" #include "src/persistence/profile.h" #include "src/persistence/settings.h" -//#include "src/widget/categorywidget.h" -#include "widget.h" +// #include "src/widget/categorywidget.h" #include #include #include #include #include #include +#include "widget.h" -inline QDateTime getActiveTimeFriend(const Friend *contact) { - return Settings::getInstance().getFriendActivity(contact->getPublicKey()); +inline QDateTime getActiveTimeFriend(const Friend* contact) { + return Settings::getInstance().getFriendActivity(contact->getPublicKey()); } -FriendListWidget::FriendListWidget(MainLayout *parent, ContentLayout*contentLayout, bool groupsOnTop) - : QWidget(parent), m_contentLayout{contentLayout}, groupsOnTop(groupsOnTop) { - setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); - - - - groupLayout.getLayout()->setSpacing(0); - groupLayout.getLayout()->setMargin(0); +FriendListWidget::FriendListWidget(MainLayout* parent, ContentLayout* contentLayout, + bool groupsOnTop) + : QWidget(parent), m_contentLayout{contentLayout}, groupsOnTop(groupsOnTop) { + setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); - // Prevent QLayout's add child warning before setting the mode. - listLayout = new FriendListLayout(this); - listLayout->removeItem(listLayout->getLayoutOnline()); - listLayout->removeItem(listLayout->getLayoutOffline()); - setLayout(listLayout); + groupLayout.getLayout()->setSpacing(0); + groupLayout.getLayout()->setMargin(0); - mode = Settings::getInstance().getFriendSortingMode(); - sortByMode(mode); - - onGroupchatPositionChanged(groupsOnTop); - dayTimer = new QTimer(this); - dayTimer->setTimerType(Qt::VeryCoarseTimer); - connect(dayTimer, &QTimer::timeout, this, &FriendListWidget::dayTimeout); - dayTimer->start(base::Times::timeUntilTomorrow()); + // Prevent QLayout's add child warning before setting the mode. + listLayout = new FriendListLayout(this); + listLayout->removeItem(listLayout->getLayoutOnline()); + listLayout->removeItem(listLayout->getLayoutOffline()); + setLayout(listLayout); - setAcceptDrops(true); + mode = Settings::getInstance().getFriendSortingMode(); + sortByMode(mode); - auto &settings = Settings::getInstance(); + onGroupchatPositionChanged(groupsOnTop); + dayTimer = new QTimer(this); + dayTimer->setTimerType(Qt::VeryCoarseTimer); + connect(dayTimer, &QTimer::timeout, this, &FriendListWidget::dayTimeout); + dayTimer->start(base::Times::timeUntilTomorrow()); + setAcceptDrops(true); - connect(&settings, &Settings::groupchatPositionChanged, this, - &FriendListWidget::onGroupchatPositionChanged); + auto& settings = Settings::getInstance(); - auto widget = Widget::getInstance(); - connect(widget, &Widget::toShowDetails, this, - &FriendListWidget::do_toShowDetails); + connect(&settings, &Settings::groupchatPositionChanged, this, + &FriendListWidget::onGroupchatPositionChanged); - connect(Nexus::getProfile(), &Profile::coreChanged, - this, &FriendListWidget::onCoreChanged); + auto widget = Widget::getInstance(); + connect(widget, &Widget::toShowDetails, this, &FriendListWidget::do_toShowDetails); + // connect(Nexus::getProfile(), &Profile::coreChanged, + // this, &FriendListWidget::onCoreChanged); } FriendListWidget::~FriendListWidget() { - if (activityLayout != nullptr) { - QLayoutItem *item; - while ((item = activityLayout->takeAt(0)) != nullptr) { - delete item->widget(); - delete item; + if (activityLayout != nullptr) { + QLayoutItem* item; + while ((item = activityLayout->takeAt(0)) != nullptr) { + delete item->widget(); + delete item; + } + delete activityLayout; } - delete activityLayout; - } - } -FriendWidget *FriendListWidget::addFriend(const FriendInfo &friendInfo) { - qDebug() << __func__ << friendInfo; - auto exist = getFriend(friendInfo.id); - if (exist) { - qWarning() <<"Exist friend"<< friendInfo.id; - return exist; - } - - auto core = Core::getInstance(); - auto profile = Nexus::getProfile(); - - auto &settings = Settings::getInstance(); - const auto compact = settings.getCompactLayout(); +FriendWidget* FriendListWidget::addFriend(const FriendInfo& friendInfo) { + qDebug() << __func__ << friendInfo; + auto exist = getFriend(friendInfo.id); + if (exist) { + qWarning() << "Exist friend" << friendInfo.id; + return exist; + } - auto fw = new FriendWidget(m_contentLayout, friendInfo, this); - connectFriendWidget(*fw); - friendWidgets.insert(friendInfo.getId().toString(), fw); - // CircleWidget *circleWidget = CircleWidget::getFromID(circleIndex); - // if (circleWidget == nullptr) - // moveWidget(fw, s, true); - // else - // circleWidget->addFriendWidget(fw, s); - auto status = core->getFriendStatus(friendInfo.toString()); - listLayout->addFriendWidget(fw,status); - setFriendStatus(friendInfo.getId(), status); + auto core = Core::getInstance(); + auto profile = Nexus::getProfile(); + auto& settings = Settings::getInstance(); + const auto compact = settings.getCompactLayout(); + auto fw = new FriendWidget(m_contentLayout, friendInfo, this); + connectFriendWidget(*fw); + friendWidgets.insert(friendInfo.getId().toString(), fw); + // CircleWidget *circleWidget = CircleWidget::getFromID(circleIndex); + // if (circleWidget == nullptr) + // moveWidget(fw, s, true); + // else + // circleWidget->addFriendWidget(fw, s); + auto status = core->getFriendStatus(friendInfo.toString()); + listLayout->addFriendWidget(fw, status); + setFriendStatus(friendInfo.getId(), status); - return fw; + return fw; } -void FriendListWidget::connectFriendWidget(FriendWidget &fw) { -// connect(&friendWidget, &FriendWidget::searchCircle, this, -// &FriendListWidget::searchCircle); - connect(&fw, &FriendWidget::updateFriendActivity, this, - &FriendListWidget::updateFriendActivity); +void FriendListWidget::connectFriendWidget(FriendWidget& fw) { + // connect(&friendWidget, &FriendWidget::searchCircle, this, + // &FriendListWidget::searchCircle); + connect(&fw, &FriendWidget::updateFriendActivity, this, + &FriendListWidget::updateFriendActivity); - connect(&fw, &FriendWidget::removeFriend, this, - &FriendListWidget::removeFriend); + connect(&fw, &FriendWidget::removeFriend, this, &FriendListWidget::removeFriend); // connect(fw, &FriendWidget::friendWidgetRenamed, this, // &FriendListWidget::onFriendWidgetRenamed); - connect(&fw, &FriendWidget::friendWidgetClicked, this, - &FriendListWidget::slot_friendClicked); + connect(&fw, &FriendWidget::friendWidgetClicked, this, &FriendListWidget::slot_friendClicked); } -void FriendListWidget::updateFriendActivity(const Friend &frnd) { - const FriendId &pk = frnd.getPublicKey(); - auto &settings = Settings::getInstance(); - const auto oldTime = settings.getFriendActivity(pk); - const auto newTime = QDateTime::currentDateTime(); - settings.setFriendActivity(pk, newTime); - FriendWidget *widget = getFriend(frnd.getPublicKey()); - moveWidget(widget, frnd.getStatus()); - updateActivityTime(oldTime); // update old category widget +void FriendListWidget::updateFriendActivity(const Friend& frnd) { + const FriendId& pk = frnd.getPublicKey(); + auto& settings = Settings::getInstance(); + const auto oldTime = settings.getFriendActivity(pk); + const auto newTime = QDateTime::currentDateTime(); + settings.setFriendActivity(pk, newTime); + FriendWidget* widget = getFriend(frnd.getPublicKey()); + moveWidget(widget, frnd.getStatus()); + updateActivityTime(oldTime); // update old category widget } -void FriendListWidget::connectToCore(Core *core) -{ - -} +void FriendListWidget::connectToCore(Core* core) {} void FriendListWidget::setMode(SortingMode mode) { - if (this->mode == mode) - return; + if (this->mode == mode) return; - this->mode = mode; - Settings::getInstance().setFriendSortingMode(mode); + this->mode = mode; + Settings::getInstance().setFriendSortingMode(mode); - sortByMode(mode); + sortByMode(mode); } void FriendListWidget::sortByMode(SortingMode mode) { - if (mode == SortingMode::Name) { - - int count = activityLayout ? activityLayout->count() : 0; - - - listLayout->addLayout(listLayout->getLayoutOnline()); - listLayout->addLayout(listLayout->getLayoutOffline()); - // listLayout->addLayout(circleLayout->getLayout()); - onGroupchatPositionChanged(groupsOnTop); - - if (activityLayout != nullptr) { - QLayoutItem *item; - while ((item = activityLayout->takeAt(0)) != nullptr) { - delete item->widget(); - delete item; - } - delete activityLayout; - activityLayout = nullptr; - } - - reDraw(); - } else if (mode == SortingMode::Activity) { - QLocale ql(Settings::getInstance().getTranslation()); - QDate today = QDate::currentDate(); + if (mode == SortingMode::Name) { + int count = activityLayout ? activityLayout->count() : 0; + + listLayout->addLayout(listLayout->getLayoutOnline()); + listLayout->addLayout(listLayout->getLayoutOffline()); + // listLayout->addLayout(circleLayout->getLayout()); + onGroupchatPositionChanged(groupsOnTop); + + if (activityLayout != nullptr) { + QLayoutItem* item; + while ((item = activityLayout->takeAt(0)) != nullptr) { + delete item->widget(); + delete item; + } + delete activityLayout; + activityLayout = nullptr; + } + + reDraw(); + } else if (mode == SortingMode::Activity) { + QLocale ql(Settings::getInstance().getTranslation()); + QDate today = QDate::currentDate(); #define COMMENT "Category for sorting friends by activity" - // clang-format off + // clang-format off const QMap names { { base::ReadableTime::Today, tr("Today", COMMENT) }, { base::ReadableTime::Yesterday, tr("Yesterday", COMMENT) }, @@ -209,65 +194,55 @@ void FriendListWidget::sortByMode(SortingMode mode) { // clang-format on #undef COMMENT - activityLayout = new QVBoxLayout(); + activityLayout = new QVBoxLayout(); - listLayout->removeItem(listLayout->getLayoutOnline()); - listLayout->removeItem(listLayout->getLayoutOffline()); + listLayout->removeItem(listLayout->getLayoutOnline()); + listLayout->removeItem(listLayout->getLayoutOffline()); - listLayout->insertLayout(1, activityLayout); + listLayout->insertLayout(1, activityLayout); - reDraw(); - } + reDraw(); + } } FriendListWidget::SortingMode FriendListWidget::getMode() const { return mode; } -GroupWidget *FriendListWidget::addGroup(const GroupId &groupId, - const QString &groupName) { - - qDebug() << __func__ << groupId.toString(); - - Group *g = GroupList::findGroup(groupId); - if (g) { - qWarning() << "Group already exist."; - return groupWidgets.value(groupId.toString()); - } - g = GroupList::addGroup(groupId, groupName); +GroupWidget* FriendListWidget::addGroup(const GroupId& groupId, const QString& groupName) { + qDebug() << __func__ << groupId.toString(); + Group* g = GroupList::findGroup(groupId); + if (g) { + qWarning() << "Group already exist."; + return groupWidgets.value(groupId.toString()); + } + g = GroupList::addGroup(groupId, groupName); - auto &settings = Settings::getInstance(); + auto& settings = Settings::getInstance(); -// const bool enabled = core->getGroupAvEnabled(groupId.toString()); + // const bool enabled = core->getGroupAvEnabled(groupId.toString()); - const auto compact = settings.getCompactLayout(); - auto gw = new GroupWidget(m_contentLayout, - groupId.toString(), - groupId, - groupName, - compact); - groupWidgets[groupId.toString()] = gw; - groupLayout.addSortedWidget(gw); + const auto compact = settings.getCompactLayout(); + auto gw = new GroupWidget(m_contentLayout, groupId.toString(), groupId, groupName, compact); + groupWidgets[groupId.toString()] = gw; + groupLayout.addSortedWidget(gw); - connect(g, &Group::subjectChanged, - [=, this](const QString &author, const QString &name) { - Q_UNUSED(author); - renameGroupWidget(gw, name); - }); + connect(g, &Group::subjectChanged, [=, this](const QString& author, const QString& name) { + Q_UNUSED(author); + renameGroupWidget(gw, name); + }); - connect(gw, &GroupWidget::chatroomWidgetClicked, this, - &FriendListWidget::slot_groupClicked); - connect(gw, &GroupWidget::removeGroup, this, &FriendListWidget::do_groupDeleted); + connect(gw, &GroupWidget::chatroomWidgetClicked, this, &FriendListWidget::slot_groupClicked); + connect(gw, &GroupWidget::removeGroup, this, &FriendListWidget::do_groupDeleted); - return gw; + return gw; } -void FriendListWidget::do_groupDeleted(const ContactId &cid) -{ +void FriendListWidget::do_groupDeleted(const ContactId& cid) { qDebug() << __func__ << cid.toString(); removeGroup(GroupId(cid)); } -void FriendListWidget::removeGroup(const GroupId &cid) { +void FriendListWidget::removeGroup(const GroupId& cid) { qDebug() << __func__ << cid.toString(); auto gw = groupWidgets.value(cid.toString()); gw->deleteLater(); @@ -276,22 +251,20 @@ void FriendListWidget::removeGroup(const GroupId &cid) { } void FriendListWidget::setGroupTitle(const GroupId& groupId, - const QString &author, - const QString &title) -{ + const QString& author, + const QString& title) { auto g = GroupList::findGroup(groupId); - if(!g){ - qWarning() << "group is no existing."<setSubject(author, title); } -void FriendListWidget::setGroupInfo(const GroupId &groupId, const GroupInfo &info) -{ +void FriendListWidget::setGroupInfo(const GroupId& groupId, const GroupInfo& info) { auto g = GroupList::findGroup(groupId); - if(!g){ - qWarning() << "group is no existing."<setDesc(info.description); g->setSubject("", info.subject); g->setPeerCount(info.occupants); - } - - - -void FriendListWidget::searchChatrooms(const QString &searchString, - bool hideOnline, bool hideOffline, - bool hideGroups) { - groupLayout.search(searchString, hideGroups); - listLayout->searchChatrooms(searchString, hideOnline, hideOffline); - // - // if (circleLayout != nullptr) { - // for (int i = 0; i != circleLayout->getLayout()->count(); ++i) { - // CircleWidget *circleWidget = static_cast( - // circleLayout->getLayout()->itemAt(i)->widget()); - // circleWidget->search(searchString, true, hideOnline, hideOffline); - // } - // } else if (activityLayout != nullptr) { - // for (int i = 0; i != activityLayout->count(); ++i) { - // CategoryWidget *categoryWidget = - // static_cast(activityLayout->itemAt(i)->widget()); - // categoryWidget->search(searchString, true, hideOnline, hideOffline); - // categoryWidget->setVisible(categoryWidget->hasChatrooms()); - // } - // } +void FriendListWidget::searchChatrooms(const QString& searchString, bool hideOnline, + bool hideOffline, bool hideGroups) { + groupLayout.search(searchString, hideGroups); + listLayout->searchChatrooms(searchString, hideOnline, hideOffline); + // + // if (circleLayout != nullptr) { + // for (int i = 0; i != circleLayout->getLayout()->count(); ++i) { + // CircleWidget *circleWidget = static_cast( + // circleLayout->getLayout()->itemAt(i)->widget()); + // circleWidget->search(searchString, true, hideOnline, hideOffline); + // } + // } else if (activityLayout != nullptr) { + // for (int i = 0; i != activityLayout->count(); ++i) { + // CategoryWidget *categoryWidget = + // static_cast(activityLayout->itemAt(i)->widget()); + // categoryWidget->search(searchString, true, hideOnline, hideOffline); + // categoryWidget->setVisible(categoryWidget->hasChatrooms()); + // } + // } } -void FriendListWidget::renameGroupWidget(GroupWidget *groupWidget, - const QString &newName) { -// groupLayout.removeSortedWidget(groupWidget); -// groupLayout.addSortedWidget(groupWidget); +void FriendListWidget::renameGroupWidget(GroupWidget* groupWidget, const QString& newName) { + // groupLayout.removeSortedWidget(groupWidget); + // groupLayout.addSortedWidget(groupWidget); - groupWidget->setName(newName); + groupWidget->setName(newName); } - void FriendListWidget::onGroupchatPositionChanged(bool top) { - groupsOnTop = top; + groupsOnTop = top; - if (mode != SortingMode::Name) - return; + if (mode != SortingMode::Name) return; - listLayout->removeItem(groupLayout.getLayout()); + listLayout->removeItem(groupLayout.getLayout()); - if (top) - listLayout->insertLayout(0, groupLayout.getLayout()); - else - listLayout->insertLayout(1, groupLayout.getLayout()); + if (top) + listLayout->insertLayout(0, groupLayout.getLayout()); + else + listLayout->insertLayout(1, groupLayout.getLayout()); - reDraw(); + reDraw(); } - -void FriendListWidget::dragEnterEvent(QDragEnterEvent *event) { - if (!event->mimeData()->hasFormat("toxPk")) { - return; - } - FriendId toxPk(event->mimeData()->data("toxPk")); - Friend *frnd = FriendList::findFriend(toxPk); - if (frnd) - event->acceptProposedAction(); +void FriendListWidget::dragEnterEvent(QDragEnterEvent* event) { + if (!event->mimeData()->hasFormat("toxPk")) { + return; + } + FriendId toxPk(event->mimeData()->data("toxPk")); + Friend* frnd = FriendList::findFriend(toxPk); + if (frnd) event->acceptProposedAction(); } -void FriendListWidget::dropEvent(QDropEvent *event) { - // Check, that the element is dropped from qTox - QObject *o = event->source(); - FriendWidget *widget = qobject_cast(o); - if (!widget) - return; +void FriendListWidget::dropEvent(QDropEvent* event) { + // Check, that the element is dropped from qTox + QObject* o = event->source(); + FriendWidget* widget = qobject_cast(o); + if (!widget) return; - // Check, that the user has a friend with the same ToxPk - assert(event->mimeData()->hasFormat("toxPk")); - const FriendId toxPk{event->mimeData()->data("toxPk")}; - Friend *f = FriendList::findFriend(toxPk); - if (!f) - return; + // Check, that the user has a friend with the same ToxPk + assert(event->mimeData()->hasFormat("toxPk")); + const FriendId toxPk{event->mimeData()->data("toxPk")}; + Friend* f = FriendList::findFriend(toxPk); + if (!f) return; - // Save CircleWidget before changing the Id -// int circleId = Settings::getInstance().getFriendCircleID(f->getPublicKey()); -// CircleWidget *circleWidget = CircleWidget::getFromID(circleId); + // Save CircleWidget before changing the Id + // int circleId = Settings::getInstance().getFriendCircleID(f->getPublicKey()); + // CircleWidget *circleWidget = CircleWidget::getFromID(circleId); - moveWidget(widget, f->getStatus(), true); + moveWidget(widget, f->getStatus(), true); -// if (circleWidget) -// circleWidget->updateStatus(); + // if (circleWidget) + // circleWidget->updateStatus(); } -void FriendListWidget::showEvent(QShowEvent *event) { - // auto core = Core::getInstance(); - // connect(core, &Core::friendAdded, this, &FriendListWidget::addFriend); - // for (auto &receiver : core->loadFriendList()) { - // qDebug() << "receiver:" << receiver; +void FriendListWidget::showEvent(QShowEvent* event) { + // auto core = Core::getInstance(); + // connect(core, &Core::friendAdded, this, &FriendListWidget::addFriend); + // for (auto &receiver : core->loadFriendList()) { + // qDebug() << "receiver:" << receiver; // }; } -void FriendListWidget::onCoreChanged(Core &core_) -{ +void FriendListWidget::onCoreChanged(Core& core_) { core = &core_; connectToCore(core); } void FriendListWidget::dayTimeout() { - if (mode == SortingMode::Activity) { - setMode(SortingMode::Name); - setMode(SortingMode::Activity); // Refresh all. - } + if (mode == SortingMode::Activity) { + setMode(SortingMode::Name); + setMode(SortingMode::Activity); // Refresh all. + } - dayTimer->start(base::Times::timeUntilTomorrow()); + dayTimer->start(base::Times::timeUntilTomorrow()); } -void FriendListWidget::moveWidget(FriendWidget *widget, Status::Status s, - bool add) { - if (mode == SortingMode::Name) { - const Friend *f = widget->getFriend(); -// int circleId = Settings::getInstance().getFriendCircleID(f->getPublicKey()); -// CircleWidget *circleWidget = CircleWidget::getFromID(circleId); +void FriendListWidget::moveWidget(FriendWidget* widget, Status::Status s, bool add) { + if (mode == SortingMode::Name) { + const Friend* f = widget->getFriend(); + // int circleId = Settings::getInstance().getFriendCircleID(f->getPublicKey()); + // CircleWidget *circleWidget = CircleWidget::getFromID(circleId); -// if (circleWidget == nullptr || add) { -// if (circleId != -1) -// Settings::getInstance().setFriendCircleID(f->getPublicKey(), -1); + // if (circleWidget == nullptr || add) { + // if (circleId != -1) + // Settings::getInstance().setFriendCircleID(f->getPublicKey(), -1); -// listLayout->addFriendWidget(widget, s); -// return; -// } + // listLayout->addFriendWidget(widget, s); + // return; + // } -// circleWidget->addFriendWidget(widget, s); - } else { -// const IMFriend *contact = widget->getFriend(); -// auto *categoryWidget = getTimeCategoryWidget(contact); -// categoryWidget->addFriendWidget(widget, contact->getStatus()); -// categoryWidget->show(); - } + // circleWidget->addFriendWidget(widget, s); + } else { + // const IMFriend *contact = widget->getFriend(); + // auto *categoryWidget = getTimeCategoryWidget(contact); + // categoryWidget->addFriendWidget(widget, contact->getStatus()); + // categoryWidget->show(); + } } -void FriendListWidget::updateActivityTime(const QDateTime &time) { - if (mode != SortingMode::Activity) - return; +void FriendListWidget::updateActivityTime(const QDateTime& time) { + if (mode != SortingMode::Activity) return; - int timeIndex = static_cast(base::getTimeBucket(time)); -// QWidget *widget = activityLayout->itemAt(timeIndex)->widget(); -// CategoryWidget *categoryWidget = static_cast(widget); -// categoryWidget->updateStatus(); + int timeIndex = static_cast(base::getTimeBucket(time)); + // QWidget *widget = activityLayout->itemAt(timeIndex)->widget(); + // CategoryWidget *categoryWidget = static_cast(widget); + // categoryWidget->updateStatus(); -// categoryWidget->setVisible(categoryWidget->hasChatrooms()); + // categoryWidget->setVisible(categoryWidget->hasChatrooms()); } // update widget after add/delete/hide/show void FriendListWidget::reDraw() { - hide(); - show(); - resize(QSize()); // lifehack -} - - -QLayout *FriendListWidget::nextLayout(QLayout *layout, bool forward) const { - if (layout == groupLayout.getLayout()) { - if (forward) { - if (groupsOnTop) - return listLayout->getLayoutOnline(); - - return listLayout->getLayoutOffline(); - } else { - if (groupsOnTop) - // return circleLayout->getLayout(); + hide(); + show(); + resize(QSize()); // lifehack +} + +QLayout* FriendListWidget::nextLayout(QLayout* layout, bool forward) const { + if (layout == groupLayout.getLayout()) { + if (forward) { + if (groupsOnTop) return listLayout->getLayoutOnline(); + + return listLayout->getLayoutOffline(); + } else { + if (groupsOnTop) + // return circleLayout->getLayout(); + + return listLayout->getLayoutOnline(); + } + } else if (layout == listLayout->getLayoutOnline()) { + if (forward) { + if (groupsOnTop) return listLayout->getLayoutOffline(); + + return groupLayout.getLayout(); + } else { + if (groupsOnTop) return groupLayout.getLayout(); + + // return circleLayout->getLayout(); + } + } else if (layout == listLayout->getLayoutOffline()) { + // if (forward) + // return circleLayout->getLayout(); + // else if (groupsOnTop) + // return listLayout->getLayoutOnline(); - return listLayout->getLayoutOnline(); - } - } else if (layout == listLayout->getLayoutOnline()) { - if (forward) { - if (groupsOnTop) - return listLayout->getLayoutOffline(); - - return groupLayout.getLayout(); - } else { - if (groupsOnTop) return groupLayout.getLayout(); - - // return circleLayout->getLayout(); } - } else if (layout == listLayout->getLayoutOffline()) { - // if (forward) - // return circleLayout->getLayout(); - // else if (groupsOnTop) + // else if (layout == circleLayout->getLayout()) { + // if (forward) { + // if (groupsOnTop) + // return groupLayout.getLayout(); + // // return listLayout->getLayoutOnline(); - - return groupLayout.getLayout(); - } - // else if (layout == circleLayout->getLayout()) { - // if (forward) { - // if (groupsOnTop) - // return groupLayout.getLayout(); - // - // return listLayout->getLayoutOnline(); - // } else - // return listLayout->getLayoutOffline(); - // } - return nullptr; + // } else + // return listLayout->getLayoutOffline(); + // } + return nullptr; } -FriendWidget *FriendListWidget::getFriend(const ContactId &friendPk) { - return friendWidgets.value(friendPk.toString()); +FriendWidget* FriendListWidget::getFriend(const ContactId& friendPk) { + return friendWidgets.value(friendPk.toString()); } -void FriendListWidget::removeFriend(const FriendId &friendPk) { - qDebug() << __func__ << friendPk.toString(); +void FriendListWidget::removeFriend(const FriendId& friendPk) { + qDebug() << __func__ << friendPk.toString(); - auto fw = friendWidgets.value(friendPk.toString()); - if(!fw){ - qWarning() <<"Unable to find friendWidget"; - return; - } + auto fw = friendWidgets.value(friendPk.toString()); + if (!fw) { + qWarning() << "Unable to find friendWidget"; + return; + } listLayout->removeFriendWidget(fw); friendWidgets.remove(friendPk.toString()); emit deleteFriendWidget(friendPk); delete fw; - } -GroupWidget *FriendListWidget::getGroup(const GroupId &id) { - return groupWidgets.value(id.toString()); +GroupWidget* FriendListWidget::getGroup(const GroupId& id) { + return groupWidgets.value(id.toString()); } -void FriendListWidget::slot_groupClicked(GenericChatroomWidget *actived) { - for (auto fw : friendWidgets) { - fw->setActive(false); - } - for (auto gw : groupWidgets) { - if (gw != actived) { - gw->setActive(false); - } else { - actived->setActive(true); +void FriendListWidget::slot_groupClicked(GenericChatroomWidget* actived) { + for (auto fw : friendWidgets) { + fw->setActive(false); + } + for (auto gw : groupWidgets) { + if (gw != actived) { + gw->setActive(false); + } else { + actived->setActive(true); + } } - } } -void FriendListWidget::slot_friendClicked(GenericChatroomWidget *actived) { - for (auto gw : groupWidgets) { - gw->setActive(false); - } +void FriendListWidget::slot_friendClicked(GenericChatroomWidget* actived) { + for (auto gw : groupWidgets) { + gw->setActive(false); + } - for (auto fw : friendWidgets) { - if (fw != actived) { - fw->setActive(false); - } else { - fw->setActive(true); + for (auto fw : friendWidgets) { + if (fw != actived) { + fw->setActive(false); + } else { + fw->setActive(true); + } } - } } void FriendListWidget::setRecvGroupMessage(const GroupMessage& msg) { -// const GroupId &groupId = msg.groupId; -// auto gw = getGroup(groupId); -// if (!gw) { -// qWarning() <<"group is no existing"; -// return; -// } -// gw->setRecvMessage(msg); - -} - -void FriendListWidget::setFriendStatus(const ContactId &friendPk, - Status::Status status) { - auto fw = getFriend(friendPk); - if (!fw) { - qWarning() << "friend"<< friendPk.toString() << "widget is no existing."; - return; - } - fw->setStatus(status, false); + // const GroupId &groupId = msg.groupId; + // auto gw = getGroup(groupId); + // if (!gw) { + // qWarning() <<"group is no existing"; + // return; + // } + // gw->setRecvMessage(msg); +} + +void FriendListWidget::setFriendStatus(const ContactId& friendPk, Status::Status status) { + auto fw = getFriend(friendPk); + if (!fw) { + qWarning() << "friend" << friendPk.toString() << "widget is no existing."; + return; + } + fw->setStatus(status, false); } -void FriendListWidget::setFriendStatusMsg(const FriendId &friendPk, - const QString &statusMsg) { - auto fw = getFriend(friendPk); - if (!fw) { - qWarning() << "friend widget no exist."; - return; - } +void FriendListWidget::setFriendStatusMsg(const FriendId& friendPk, const QString& statusMsg) { + auto fw = getFriend(friendPk); + if (!fw) { + qWarning() << "friend widget no exist."; + return; + } - fw->setStatusMsg(statusMsg); + fw->setStatusMsg(statusMsg); } -void FriendListWidget::setFriendName(const FriendId &friendPk, const QString &name) { - qDebug() << __func__ << friendPk.toString() << name; - auto f = FriendList::findFriend(friendPk); - if(!f){ - qWarning() <<"friend is no existing."; - return; - } - f->setName(name); +void FriendListWidget::setFriendName(const FriendId& friendPk, const QString& name) { + qDebug() << __func__ << friendPk.toString() << name; + auto f = FriendList::findFriend(friendPk); + if (!f) { + qWarning() << "friend is no existing."; + return; + } + f->setName(name); } -void FriendListWidget::setFriendAlias(const FriendId &friendPk, const QString &alias) -{ +void FriendListWidget::setFriendAlias(const FriendId& friendPk, const QString& alias) { qDebug() << __func__ << friendPk.toString() << alias; auto f = FriendList::findFriend(friendPk); - if(!f){ - qWarning() <<"friend is no existing."; + if (!f) { + qWarning() << "friend is no existing."; return; } f->setAlias(alias); } -void FriendListWidget::setFriendAvatar(const FriendId &friendPk, - const QByteArray &avatar) { - auto fw = getFriend(friendPk); - if (!fw) { - qWarning() << "friend is no exist."; - return; - } +void FriendListWidget::setFriendAvatar(const FriendId& friendPk, const QByteArray& avatar) { + auto fw = getFriend(friendPk); + if (!fw) { + qWarning() << "friend is no exist."; + return; + } - QPixmap p; - p.loadFromData(avatar); - fw->setAvatar(p); + QPixmap p; + p.loadFromData(avatar); + fw->setAvatar(p); } -void FriendListWidget::setFriendTyping(const FriendId &friendId, bool isTyping) { - auto fw = getFriend(friendId); - if (fw) - fw->setTyping(isTyping); +void FriendListWidget::setFriendTyping(const FriendId& friendId, bool isTyping) { + auto fw = getFriend(friendId); + if (fw) fw->setTyping(isTyping); } void FriendListWidget::reloadTheme() { - for (auto gw: groupWidgets) { - gw->reloadTheme(); - } + for (auto gw : groupWidgets) { + gw->reloadTheme(); + } - for (auto fw: friendWidgets) { - fw->reloadTheme(); - } + for (auto fw : friendWidgets) { + fw->reloadTheme(); + } } -void FriendListWidget::do_toShowDetails(const ContactId &cid) { - qDebug() << __func__ << cid.toString(); - for (auto fw: friendWidgets) { - if(fw->getContactId()==cid){ - emit fw->chatroomWidgetClicked(fw); - break; +void FriendListWidget::do_toShowDetails(const ContactId& cid) { + qDebug() << __func__ << cid.toString(); + for (auto fw : friendWidgets) { + if (fw->getContactId() == cid) { + emit fw->chatroomWidgetClicked(fw); + break; + } } - } - for(auto gw: groupWidgets){ - if(gw->getContactId() == cid){ - emit gw->chatroomWidgetClicked(gw); - break; - } - } + for (auto gw : groupWidgets) { + if (gw->getContactId() == cid) { + emit gw->chatroomWidgetClicked(gw); + break; + } + } } - diff --git a/src/modules/im/src/widget/friendlistwidget.h b/src/modules/im/src/widget/friendlistwidget.h index dcd89ea5..ef7c8766 100644 --- a/src/modules/im/src/widget/friendlistwidget.h +++ b/src/modules/im/src/widget/friendlistwidget.h @@ -13,14 +13,13 @@ #ifndef FRIENDLISTWIDGET_H #define FRIENDLISTWIDGET_H - +#include #include "genericchatitemlayout.h" #include "src/core/core.h" #include "src/model/friendmessagedispatcher.h" #include "src/model/message.h" #include "src/model/status.h" #include "src/persistence/settings.h" -#include class QVBoxLayout; class QGridLayout; @@ -36,96 +35,94 @@ class ContentLayout; class MainLayout; class FriendListWidget : public QWidget { - Q_OBJECT + Q_OBJECT public: - - using SortingMode = Settings::FriendListSortingMode; - explicit FriendListWidget(MainLayout *parent,ContentLayout*contentLayout, bool groupsOnTop = true); - ~FriendListWidget(); - void setMode(SortingMode mode); - SortingMode getMode() const; - void reloadTheme(); - - FriendWidget *addFriend(const FriendInfo &friendInfo); - FriendWidget *getFriend(const ContactId &friendPk); - void removeFriend(const FriendId &cid); - - void setFriendStatus(const ContactId &friendPk, Status::Status status); - void setFriendStatusMsg(const FriendId &friendPk, const QString& statusMsg); - void setFriendName(const FriendId &friendPk, const QString& name); - void setFriendAlias(const FriendId &friendPk, const QString& alias); - void setFriendAvatar(const FriendId &friendPk, const QByteArray& avatar); - void setFriendTyping(const FriendId &pk, bool typing); - - GroupWidget *addGroup(const GroupId &groupId, const QString &groupName = ""); - GroupWidget *getGroup(const GroupId &id); - void removeGroup(const GroupId &groupId); - void setGroupTitle(const GroupId &groupId, const QString &author,const QString& title); - void setGroupInfo(const GroupId &groupId, const GroupInfo &info); - -// void addCircleWidget(int id); -// void addCircleWidget(FriendWidget *widget = nullptr); -// void removeCircleWidget(CircleWidget *widget); - void searchChatrooms(const QString &searchString, bool hideOnline = false, - bool hideOffline = false, bool hideGroups = false); - - void cycleContacts(GenericChatroomWidget *activeChatroomWidget, bool forward); - - void updateActivityTime(const QDateTime &date); - void reDraw(); - - void setRecvGroupMessage(const GroupMessage& msg); + using SortingMode = Settings::FriendListSortingMode; + explicit FriendListWidget(MainLayout* parent, ContentLayout* contentLayout, + bool groupsOnTop = true); + ~FriendListWidget(); + void setMode(SortingMode mode); + SortingMode getMode() const; + void reloadTheme(); + + FriendWidget* addFriend(const FriendInfo& friendInfo); + FriendWidget* getFriend(const ContactId& friendPk); + void removeFriend(const FriendId& cid); + + void setFriendStatus(const ContactId& friendPk, Status::Status status); + void setFriendStatusMsg(const FriendId& friendPk, const QString& statusMsg); + void setFriendName(const FriendId& friendPk, const QString& name); + void setFriendAlias(const FriendId& friendPk, const QString& alias); + void setFriendAvatar(const FriendId& friendPk, const QByteArray& avatar); + void setFriendTyping(const FriendId& pk, bool typing); + + GroupWidget* addGroup(const GroupId& groupId, const QString& groupName = ""); + GroupWidget* getGroup(const GroupId& id); + void removeGroup(const GroupId& groupId); + void setGroupTitle(const GroupId& groupId, const QString& author, const QString& title); + void setGroupInfo(const GroupId& groupId, const GroupInfo& info); + + // void addCircleWidget(int id); + // void addCircleWidget(FriendWidget *widget = nullptr); + // void removeCircleWidget(CircleWidget *widget); + void searchChatrooms(const QString& searchString, bool hideOnline = false, + bool hideOffline = false, bool hideGroups = false); + + void cycleContacts(GenericChatroomWidget* activeChatroomWidget, bool forward); + + void updateActivityTime(const QDateTime& date); + void reDraw(); + + void setRecvGroupMessage(const GroupMessage& msg); signals: - void deleteFriendWidget(const FriendId &friendPk); - void deleteGroupWidget(const FriendId &friendPk); + void deleteFriendWidget(const FriendId& friendPk); + void deleteGroupWidget(const FriendId& friendPk); public slots: - void renameGroupWidget(GroupWidget *groupWidget, const QString &newName); + void renameGroupWidget(GroupWidget* groupWidget, const QString& newName); - void slot_friendClicked(GenericChatroomWidget *); - void moveWidget(FriendWidget *w, Status::Status s, bool add = false); + void slot_friendClicked(GenericChatroomWidget*); + void moveWidget(FriendWidget* w, Status::Status s, bool add = false); - void onGroupchatPositionChanged(bool top); + void onGroupchatPositionChanged(bool top); - void slot_groupClicked(GenericChatroomWidget *); - void do_toShowDetails(const ContactId& cid); - void do_groupDeleted(const ContactId& cid); + void slot_groupClicked(GenericChatroomWidget*); + void do_toShowDetails(const ContactId& cid); + void do_groupDeleted(const ContactId& cid); protected: - void dragEnterEvent(QDragEnterEvent *event) override; - void dropEvent(QDropEvent *event) override; - void showEvent(QShowEvent *event) override; + void dragEnterEvent(QDragEnterEvent* event) override; + void dropEvent(QDropEvent* event) override; + void showEvent(QShowEvent* event) override; private slots: - void onCoreChanged(Core &core); - void dayTimeout(); + void onCoreChanged(Core& core); + void dayTimeout(); private: + QLayout* nextLayout(QLayout* layout, bool forward) const; - QLayout *nextLayout(QLayout *layout, bool forward) const; - - void sortByMode(SortingMode mode); - void connectFriendWidget(FriendWidget &friendWidget); - void updateFriendActivity(const Friend &frnd); - - void connectToCore(Core* core); - Core *core; + void sortByMode(SortingMode mode); + void connectFriendWidget(FriendWidget& friendWidget); + void updateFriendActivity(const Friend& frnd); - SortingMode mode; + void connectToCore(Core* core); + Core* core; - bool groupsOnTop; - FriendListLayout *listLayout; -// GenericChatItemLayout *circleLayout = nullptr; - QVBoxLayout *activityLayout = nullptr; - QTimer *dayTimer; + SortingMode mode; - ContentLayout *m_contentLayout; + bool groupsOnTop; + FriendListLayout* listLayout; + // GenericChatItemLayout *circleLayout = nullptr; + QVBoxLayout* activityLayout = nullptr; + QTimer* dayTimer; - QMap friendWidgets; - QMap groupWidgets; - GenericChatItemLayout groupLayout; + ContentLayout* m_contentLayout; + QMap friendWidgets; + QMap groupWidgets; + GenericChatItemLayout groupLayout; }; -#endif // FRIENDLISTWIDGET_H +#endif // FRIENDLISTWIDGET_H diff --git a/src/modules/im/src/widget/friendwidget.cpp b/src/modules/im/src/widget/friendwidget.cpp index 6de8781c..c449491b 100644 --- a/src/modules/im/src/widget/friendwidget.cpp +++ b/src/modules/im/src/widget/friendwidget.cpp @@ -51,7 +51,6 @@ #include "src/persistence/profile.h" #include "src/widget/form/GroupCreateForm.h" - /** * @class FriendWidget * @@ -59,174 +58,156 @@ * For example, used on friend list. * When you click should open the chat with friend. Widget has a context menu. */ -FriendWidget::FriendWidget(ContentLayout *layout, - const FriendInfo &f, - QWidget* parent) - : GenericChatroomWidget(ChatType::Chat, f.id, parent), - contentLayout(layout), menu{nullptr}, about{nullptr} -{ - - qDebug() <<__func__ <<"friend:"<getHistory(); - auto dialogManager = ContentDialogManager::getInstance(); - - m_friend = FriendList::addFriend(f); - nameLabel->setText(m_friend->getDisplayedName()); - - - // update alias when edited - connect(nameLabel, &CroppingLabel::editFinished, // - m_friend, &Friend::setAlias); - - // update on changes of the displayed name - connect(m_friend, &Friend::displayedNameChanged, // - nameLabel, &CroppingLabel::setText); - - connect(m_friend, &Friend::displayedNameChanged, this, - [this](const QString &newName) { - Q_UNUSED(newName); - emit friendWidgetRenamed(this); - }); - - - -// connect(getContact(), &Contact::avatarChanged, -// [&](auto& pic) { -// setAvatar(pic); -// }); - -// connect(chatRoom.get(), &Chatroom::activeChanged, this, -// &FriendWidget::setActive); - // statusMessageLabel->setTextFormat(Qt::PlainText); - - - // connect(friendWidget, &FriendWidget::copyFriendIdToClipboard, this, - // &Widget::copyFriendIdToClipboard); +FriendWidget::FriendWidget(ContentLayout* layout, const FriendInfo& f, QWidget* parent) + : GenericChatroomWidget(ChatType::Chat, f.id, parent) + , contentLayout(layout) + , menu{nullptr} + , about{nullptr} { + qDebug() << __func__ << "friend:" << f.toString(); + + auto profile = Nexus::getProfile(); + + auto core = Core::getInstance(); + auto& settings = Settings::getInstance(); + auto history = profile->getHistory(); + auto dialogManager = ContentDialogManager::getInstance(); + + m_friend = FriendList::addFriend(f); + nameLabel->setText(m_friend->getDisplayedName()); + + // update alias when edited + connect(nameLabel, &CroppingLabel::editFinished, // + m_friend, &Friend::setAlias); + + // update on changes of the displayed name + connect(m_friend, &Friend::displayedNameChanged, // + nameLabel, &CroppingLabel::setText); + + connect(m_friend, &Friend::displayedNameChanged, this, [this](const QString& newName) { + Q_UNUSED(newName); + emit friendWidgetRenamed(this); + }); + // connect(getContact(), &Contact::avatarChanged, + // [&](auto& pic) { + // setAvatar(pic); + // }); - // Signal transmission from the created `friendWidget` (which shown in - // ContentDialog) to the `widget` (which shown in main widget) + // connect(chatRoom.get(), &Chatroom::activeChanged, this, + // &FriendWidget::setActive); + // statusMessageLabel->setTextFormat(Qt::PlainText); - // - connect(this, &FriendWidget::chatroomWidgetClicked, - [=, this](GenericChatroomWidget *w) { - Q_UNUSED(w); - do_widgetClicked(this); - emit friendWidgetClicked(this); - }); - // connect(friendWidget, &FriendWidget::newWindowOpened, - // [this](GenericChatroomWidget *w) { - // Q_UNUSED(w); - // emit friendWidget->newWindowOpened(friendWidget); - // }); + // connect(friendWidget, &FriendWidget::copyFriendIdToClipboard, this, + // &Widget::copyFriendIdToClipboard); - statusPic->hide(); + // Signal transmission from the created `friendWidget` (which shown in + // ContentDialog) to the `widget` (which shown in main widget) - // Try to get the avatar from the cache -// QPixmap avatar = Nexus::getProfile()->loadAvatar(friendPk); -// if (!avatar.isNull()) { -// sendWorker->onAvatarChanged(friendPk, avatar); -// setAvatar(avatar); -// } + // + connect(this, &FriendWidget::chatroomWidgetClicked, [=, this](GenericChatroomWidget* w) { + Q_UNUSED(w); + do_widgetClicked(this); + emit friendWidgetClicked(this); + }); + // connect(friendWidget, &FriendWidget::newWindowOpened, + // [this](GenericChatroomWidget *w) { + // Q_UNUSED(w); + // emit friendWidget->newWindowOpened(friendWidget); + // }); + + statusPic->hide(); + + // Try to get the avatar from the cache + // QPixmap avatar = Nexus::getProfile()->loadAvatar(friendPk); + // if (!avatar.isNull()) { + // sendWorker->onAvatarChanged(friendPk, avatar); + // setAvatar(avatar); + // } - menu = new QMenu(this); - inviteToGrp= menu->addAction(tr("Invite to group")); - newGroupAction = menu->addAction(tr("To new group")); + menu = new QMenu(this); + inviteToGrp = menu->addAction(tr("Invite to group")); + newGroupAction = menu->addAction(tr("To new group")); - connect(newGroupAction, &QAction::triggered, this, - &FriendWidget::inviteToNewGroup); + connect(newGroupAction, &QAction::triggered, this, &FriendWidget::inviteToNewGroup); - // inviteMenu->addSeparator(); + // inviteMenu->addSeparator(); - menu->addSeparator(); - removeAct = menu->addAction(tr("Remove friend")); + menu->addSeparator(); + removeAct = menu->addAction(tr("Remove friend")); - init(); + init(); - emit Widget::getInstance()->friendAdded(m_friend); + emit Widget::getInstance() -> friendAdded(m_friend); } -FriendWidget::~FriendWidget() -{ +FriendWidget::~FriendWidget() { qDebug() << __func__; - emit Widget::getInstance()->friendRemoved(m_friend); + emit Widget::getInstance() -> friendRemoved(m_friend); removeDetails(); deinit(); FriendList::removeFriend(FriendId{contactId}); } -void FriendWidget::init() -{ +void FriendWidget::init() {} +void FriendWidget::deinit() {} + +void FriendWidget::do_widgetClicked(GenericChatroomWidget* w) { + qDebug() << __func__ << "show friend:" << m_friend->getId().toString(); + showDetails(); } -void FriendWidget::deinit() -{ +ContentDialog* FriendWidget::addFriendDialog(const Friend* frnd) { + QString friendId = frnd->getId().toString(); + qDebug() << __func__ << friendId; -} + const FriendId& friendPk = frnd->getPublicKey(); + qDebug() << "friendPk" << friendPk.toString(); -void FriendWidget::do_widgetClicked(GenericChatroomWidget *w) { - qDebug() << __func__ << "show friend:" << m_friend->getId().toString(); - showDetails(); -} + ContentDialog* dialog = ContentDialogManager::getInstance()->getFriendDialog(friendPk); + qDebug() << "Find contentDialog:" << dialog; + if (!dialog) { + dialog = createContentDialog(); + } + + auto& settings = Settings::getInstance(); + + // FriendWidget *widget = friendWidgets[friendPk]; + // bool isCurrent = activeChatroomWidget == widget; + // if (!contentDialog && !isSeparate && isCurrent) { + // onAddClicked(); + // } -ContentDialog *FriendWidget::addFriendDialog(const Friend *frnd) { - QString friendId = frnd->getId().toString(); - qDebug() << __func__ << friendId; - - const FriendId &friendPk = frnd->getPublicKey(); - qDebug() << "friendPk" << friendPk.toString(); - - ContentDialog *dialog = - ContentDialogManager::getInstance()->getFriendDialog(friendPk); - qDebug() << "Find contentDialog:" << dialog; - if (!dialog) { - dialog = createContentDialog(); - } - - auto &settings = Settings::getInstance(); - - // FriendWidget *widget = friendWidgets[friendPk]; - // bool isCurrent = activeChatroomWidget == widget; - // if (!contentDialog && !isSeparate && isCurrent) { - // onAddClicked(); - // } - -// ContentDialogManager::getInstance()->addFriendToDialog( -// friendPk, dialog, chatRoom.get(), chatForm.get()); - - // friendWidget->setStatusMsg(widget->getStatusMsg()); - - // #if (QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)) - // auto widgetRemoveFriend = QOverload::of(&Widget::removeFriend); - // #else - // auto widgetRemoveFriend = - // static_cast(&Widget::removeFriend); - // #endif - // connect(friendWidget, &FriendWidget::removeFriend, this, - // widgetRemoveFriend); connect(friendWidget, &FriendWidget::addFriend, - // this, &Widget::addFriend0); - - // FIXME: emit should be removed - // emit friendWidget->chatroomWidgetClicked(friendWidget); - -// Profile *profile = Nexus::getProfile(); -// connect(profile, &Profile::friendAvatarSet, this, &FriendWidget::onAvatarSet); -// connect(profile, &Profile::friendAvatarRemoved, this, -// &FriendWidget::onAvatarRemoved); - - QPixmap avatar = Nexus::getProfile()->loadAvatar(frnd->getPublicKey()); - if (!avatar.isNull()) { - setAvatar(avatar); - } - - return dialog; + // ContentDialogManager::getInstance()->addFriendToDialog( + // friendPk, dialog, chatRoom.get(), chatForm.get()); + + // friendWidget->setStatusMsg(widget->getStatusMsg()); + + // #if (QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)) + // auto widgetRemoveFriend = QOverload::of(&Widget::removeFriend); + // #else + // auto widgetRemoveFriend = + // static_cast(&Widget::removeFriend); + // #endif + // connect(friendWidget, &FriendWidget::removeFriend, this, + // widgetRemoveFriend); connect(friendWidget, &FriendWidget::addFriend, + // this, &Widget::addFriend0); + + // FIXME: emit should be removed + // emit friendWidget->chatroomWidgetClicked(friendWidget); + + // Profile *profile = Nexus::getProfile(); + // connect(profile, &Profile::friendAvatarSet, this, &FriendWidget::onAvatarSet); + // connect(profile, &Profile::friendAvatarRemoved, this, + // &FriendWidget::onAvatarRemoved); + + QPixmap avatar = Nexus::getProfile()->loadAvatar(frnd->getPublicKey()); + if (!avatar.isNull()) { + setAvatar(avatar); + } + + return dialog; } /** @@ -236,9 +217,9 @@ ContentDialog *FriendWidget::addFriendDialog(const Friend *frnd) { * Default context menu event handler. * Redirect all event information to the signal. */ -void FriendWidget::contextMenuEvent(QContextMenuEvent *event) { - onContextMenuCalled(event); -// emit contextMenuCalled(event); +void FriendWidget::contextMenuEvent(QContextMenuEvent* event) { + onContextMenuCalled(event); + // emit contextMenuCalled(event); } /** @@ -247,140 +228,134 @@ void FriendWidget::contextMenuEvent(QContextMenuEvent *event) { * * Context menu handler. Always should be called to FriendWidget from FriendList */ -void FriendWidget::onContextMenuCalled(QContextMenuEvent *event) { - if (!active) { - setBackgroundRole(QPalette::Highlight); - } - - installEventFilter(this); // Disable leave event. - - -// const auto newGroupAction = inviteMenu->addAction(tr("To new group")); -// connect(newGroupAction, &QAction::triggered, chatRoom.get(), -// &FriendChatroom::inviteToNewGroup); -// inviteMenu->addSeparator(); - -// for (const auto &group : chatRoom->getGroups()) { -// const auto groupAction = -// inviteMenu->addAction(tr("Invite to group '%1'").arg(group.name)); -// connect(groupAction, &QAction::triggered, -// [=, this]() { chatRoom->inviteFriend(group.group); }); -// } - // - // const auto circleId = chatRoom->getCircleId(); - // auto circleMenu = menu.addMenu( - // tr("Move to circle...", "Menu to move a friend into a different - // circle")); - // - // const auto newCircleAction = circleMenu->addAction(tr("To new circle")); - // connect(newCircleAction, &QAction::triggered, this, - // &FriendWidget::moveToNewCircle); - // - // if (circleId != -1) { - // const auto circleName = chatRoom->getCircleName(); - // const auto removeCircleAction = - // circleMenu->addAction(tr("Remove from circle - // '%1'").arg(circleName)); - // connect(removeCircleAction, &QAction::triggered, this, - // &FriendWidget::removeFromCircle); - // } - // circleMenu->addSeparator(); - // - // for (const auto &circle : chatRoom->getOtherCircles()) { - // QAction *action = - // new QAction(tr("Move to circle \"%1\"").arg(circle.name), - // circleMenu); - // connect(action, &QAction::triggered, - // [this]() { moveToCircle(circle.circleId); }); - // circleMenu->addAction(action); - // } - -// const auto setAlias = menu.addAction(tr("Set alias...")); -// connect(setAlias, &QAction::triggered, nameLabel, &CroppingLabel::editBegin); - - // 自动接收文件 - // menu.addSeparator(); - // auto autoAccept = menu.addAction( - // tr("Auto accept files from this friend", "context menu entry")); - // autoAccept->setCheckable(true); - // autoAccept->setChecked(!chatRoom->autoAcceptEnabled()); - // connect(autoAccept, &QAction::triggered, this, - // &FriendWidget::changeAutoAccept); - - - -// menu.addSeparator(); -// if (chatRoom->friendCanBeRemoved()) { -// const auto friendPk = fnd->getPublicKey(); -// const auto removeAction = menu.addAction( -// tr("Remove friend", "Menu to remove the friend from our friendlist")); -// connect( -// removeAction, &QAction::triggered, this, -// [=, this]() { emit removeFriend(friendPk); }, Qt::QueuedConnection); -// } - -// menu.addSeparator(); - -// if (!fnd->isFriend()) { -// const auto friendPk = fnd->getPublicKey(); -// const auto addAction = menu.addAction("添加好友"); -// connect( -// addAction, &QAction::triggered, this, -// [=, this]() { emit addFriend(friendPk); }, Qt::QueuedConnection); -// } - - // menu.addSeparator(); - // const auto aboutWindow = menu.addAction(tr("Show details")); - // connect(aboutWindow, &QAction::triggered, this, - // &FriendWidget::showDetails); - - const auto pos = event->globalPos(); - auto selected= menu->exec(pos); - qDebug()<<"selected"<addAction(tr("To new group")); + // connect(newGroupAction, &QAction::triggered, chatRoom.get(), + // &FriendChatroom::inviteToNewGroup); + // inviteMenu->addSeparator(); + + // for (const auto &group : chatRoom->getGroups()) { + // const auto groupAction = + // inviteMenu->addAction(tr("Invite to group '%1'").arg(group.name)); + // connect(groupAction, &QAction::triggered, + // [=, this]() { chatRoom->inviteFriend(group.group); }); + // } + // + // const auto circleId = chatRoom->getCircleId(); + // auto circleMenu = menu.addMenu( + // tr("Move to circle...", "Menu to move a friend into a different + // circle")); + // + // const auto newCircleAction = circleMenu->addAction(tr("To new circle")); + // connect(newCircleAction, &QAction::triggered, this, + // &FriendWidget::moveToNewCircle); + // + // if (circleId != -1) { + // const auto circleName = chatRoom->getCircleName(); + // const auto removeCircleAction = + // circleMenu->addAction(tr("Remove from circle + // '%1'").arg(circleName)); + // connect(removeCircleAction, &QAction::triggered, this, + // &FriendWidget::removeFromCircle); + // } + // circleMenu->addSeparator(); + // + // for (const auto &circle : chatRoom->getOtherCircles()) { + // QAction *action = + // new QAction(tr("Move to circle \"%1\"").arg(circle.name), + // circleMenu); + // connect(action, &QAction::triggered, + // [this]() { moveToCircle(circle.circleId); }); + // circleMenu->addAction(action); + // } + + // const auto setAlias = menu.addAction(tr("Set alias...")); + // connect(setAlias, &QAction::triggered, nameLabel, &CroppingLabel::editBegin); + + // 自动接收文件 + // menu.addSeparator(); + // auto autoAccept = menu.addAction( + // tr("Auto accept files from this friend", "context menu entry")); + // autoAccept->setCheckable(true); + // autoAccept->setChecked(!chatRoom->autoAcceptEnabled()); + // connect(autoAccept, &QAction::triggered, this, + // &FriendWidget::changeAutoAccept); + + // menu.addSeparator(); + // if (chatRoom->friendCanBeRemoved()) { + // const auto friendPk = fnd->getPublicKey(); + // const auto removeAction = menu.addAction( + // tr("Remove friend", "Menu to remove the friend from our friendlist")); + // connect( + // removeAction, &QAction::triggered, this, + // [=, this]() { emit removeFriend(friendPk); }, Qt::QueuedConnection); + // } + + // menu.addSeparator(); + + // if (!fnd->isFriend()) { + // const auto friendPk = fnd->getPublicKey(); + // const auto addAction = menu.addAction("添加好友"); + // connect( + // addAction, &QAction::triggered, this, + // [=, this]() { emit addFriend(friendPk); }, Qt::QueuedConnection); + // } + + // menu.addSeparator(); + // const auto aboutWindow = menu.addAction(tr("Show details")); + // connect(aboutWindow, &QAction::triggered, this, + // &FriendWidget::showDetails); + + const auto pos = event->globalPos(); + auto selected = menu->exec(pos); + qDebug() << "selected" << selected; + + removeEventFilter(this); + + if (!active) { + setBackgroundRole(QPalette::Window); + } + + if (selected == removeAct) { + const bool retYes = GUI::askQuestion(tr("Confirmation"), + tr("Are you sure to remove %1 ?").arg(getName()), + false, + true, + true); + if (!retYes) { + return; + } + + emit removeFriend(FriendId(contactId)); + } else if (selected == inviteToGrp) { + } } void FriendWidget::changeAutoAccept(bool enable) { -// if (enable) { -// const auto oldDir = chatRoom->getAutoAcceptDir(); -// const auto newDir = QFileDialog::getExistingDirectory( -// Q_NULLPTR, tr("Choose an auto accept directory", "popup title"), -// oldDir); -// chatRoom->setAutoAcceptDir(newDir); -// } else { -// chatRoom->disableAutoAccept(); + // if (enable) { + // const auto oldDir = chatRoom->getAutoAcceptDir(); + // const auto newDir = QFileDialog::getExistingDirectory( + // Q_NULLPTR, tr("Choose an auto accept directory", "popup title"), + // oldDir); + // chatRoom->setAutoAcceptDir(newDir); + // } else { + // chatRoom->disableAutoAccept(); // } } -void FriendWidget::inviteToNewGroup() -{ +void FriendWidget::inviteToNewGroup() { auto groupCreate = new GroupCreateForm(); - connect(groupCreate, &GroupCreateForm::confirmed, [&, groupCreate](const QString name){ + connect(groupCreate, &GroupCreateForm::confirmed, [&, groupCreate](const QString name) { auto core = Core::getInstance(); auto groupId = core->createGroup(name); - qDebug() << "Create group successful:"<inviteToGroup(m_friend->getId(), groupId); groupCreate->close(); } @@ -389,104 +364,93 @@ void FriendWidget::inviteToNewGroup() } void FriendWidget::showDetails() { - qDebug() <<__func__; - if(!about){ - qDebug() << "create about for:" << m_friend->getId().toString(); - const auto af = new AboutFriend(m_friend, &Settings::getInstance()); - std::unique_ptr iabout = std::unique_ptr(af); - about = new AboutFriendForm(std::move(iabout), this); - connect(about, &AboutFriendForm::histroyRemoved, - this, &FriendWidget::friendHistoryRemoved); - contentLayout->addWidget(about); - } - - contentLayout->setCurrentWidget(about); -} + qDebug() << __func__; + if (!about) { + qDebug() << "create about for:" << m_friend->getId().toString(); + const auto af = new AboutFriend(m_friend, &Settings::getInstance()); + std::unique_ptr iabout = std::unique_ptr(af); + about = new AboutFriendForm(std::move(iabout), this); + connect(about, &AboutFriendForm::histroyRemoved, this, &FriendWidget::friendHistoryRemoved); + contentLayout->addWidget(about); + } -void FriendWidget::removeDetails() -{ -// if(about){ -// contentLayout->removeWidget(about); -// about = nullptr; -// } + contentLayout->setCurrentWidget(about); +} +void FriendWidget::removeDetails() { + // if(about){ + // contentLayout->removeWidget(about); + // about = nullptr; + // } } void FriendWidget::setAsActiveChatroom() { setActive(true); } void FriendWidget::setAsInactiveChatroom() { setActive(false); } - -void FriendWidget::onActiveSet(bool active) { - setBackgroundRole(QPalette::Window); -} - - +void FriendWidget::onActiveSet(bool active) { setBackgroundRole(QPalette::Window); } QString FriendWidget::getStatusString() const { + const int status = static_cast(m_friend->getStatus()); + const bool event = m_friend->getEventFlag(); - const int status = static_cast(m_friend->getStatus()); - const bool event = m_friend->getEventFlag(); - - static const QVector names = { - tr("Online"), - tr("Away"), - tr("Busy"), - tr("Offline"), - }; + static const QVector names = { + tr("Online"), + tr("Away"), + tr("Busy"), + tr("Offline"), + }; - return event ? tr("New message") : names.value(status); + return event ? tr("New message") : names.value(status); } -const Friend *FriendWidget::getFriend() const { return m_friend; } +const Friend* FriendWidget::getFriend() const { return m_friend; } -const Contact *FriendWidget::getContact() const { return getFriend(); } +const Contact* FriendWidget::getContact() const { return getFriend(); } -void FriendWidget::search(const QString &searchString, bool hide) { -// const auto frnd = chatRoom->getFriend(); -// searchName(searchString, hide); -// const Settings &s = Settings::getInstance(); -// const uint32_t circleId = s.getFriendCircleID(frnd->getPublicKey()); -// CircleWidget *circleWidget = CircleWidget::getFromID(circleId); -// if (circleWidget) { -// circleWidget->search(searchString); -// } +void FriendWidget::search(const QString& searchString, bool hide) { + // const auto frnd = chatRoom->getFriend(); + // searchName(searchString, hide); + // const Settings &s = Settings::getInstance(); + // const uint32_t circleId = s.getFriendCircleID(frnd->getPublicKey()); + // CircleWidget *circleWidget = CircleWidget::getFromID(circleId); + // if (circleWidget) { + // circleWidget->search(searchString); + // } } void FriendWidget::resetEventFlags() { - //resetEventFlags(); + // resetEventFlags(); } +void FriendWidget::mousePressEvent(QMouseEvent* ev) { + if (ev->button() == Qt::LeftButton) { + dragStartPos = ev->pos(); + } -void FriendWidget::mousePressEvent(QMouseEvent *ev) { - if (ev->button() == Qt::LeftButton) { - dragStartPos = ev->pos(); - } - - GenericChatroomWidget::mousePressEvent(ev); + GenericChatroomWidget::mousePressEvent(ev); } -void FriendWidget::mouseMoveEvent(QMouseEvent *ev) { - if (!(ev->buttons() & Qt::LeftButton)) { - return; - } - - const int distance = (dragStartPos - ev->pos()).manhattanLength(); - if (distance > QApplication::startDragDistance()) { - QMimeData *mdata = new QMimeData; - const Friend *frnd = getFriend(); - mdata->setText(frnd->getDisplayedName()); - mdata->setData("toxPk", frnd->getPublicKey().getByteArray()); - - QDrag *drag = new QDrag(this); - drag->setMimeData(mdata); - drag->setPixmap(avatar->getPixmap()); - drag->exec(Qt::CopyAction | Qt::MoveAction); - } +void FriendWidget::mouseMoveEvent(QMouseEvent* ev) { + if (!(ev->buttons() & Qt::LeftButton)) { + return; + } + + const int distance = (dragStartPos - ev->pos()).manhattanLength(); + if (distance > QApplication::startDragDistance()) { + QMimeData* mdata = new QMimeData; + const Friend* frnd = getFriend(); + mdata->setText(frnd->getDisplayedName()); + mdata->setData("toxPk", frnd->getPublicKey().getByteArray()); + + QDrag* drag = new QDrag(this); + drag->setMimeData(mdata); + drag->setPixmap(avatar->getPixmap()); + drag->exec(Qt::CopyAction | Qt::MoveAction); + } } -void FriendWidget::paintEvent(QPaintEvent *e) -{ +void FriendWidget::paintEvent(QPaintEvent* e) { QPainter painter(this); QStyleOptionFrame opt; initStyleOption(&opt); @@ -496,27 +460,28 @@ void FriendWidget::paintEvent(QPaintEvent *e) style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this); } -ContentDialog *FriendWidget::createContentDialog() const { - qDebug() << __func__; +ContentDialog* FriendWidget::createContentDialog() const { + qDebug() << __func__; + + ContentDialog* contentDialog = new ContentDialog(); + // connect(contentDialog, &ContentDialog::friendDialogShown, this, + // &Widget::onFriendDialogShown); + // connect(contentDialog, &ContentDialog::groupDialogShown, this, + // &Widget::onGroupDialogShown); - ContentDialog *contentDialog = new ContentDialog(); - // connect(contentDialog, &ContentDialog::friendDialogShown, this, - // &Widget::onFriendDialogShown); - // connect(contentDialog, &ContentDialog::groupDialogShown, this, - // &Widget::onGroupDialogShown); + auto core = Core::getInstance(); - auto core = Core::getInstance(); + connect(core, &Core::usernameSet, contentDialog, &ContentDialog::setUsername); - connect(core, &Core::usernameSet, contentDialog, &ContentDialog::setUsername); + // connect(&settings, &Settings::groupchatPositionChanged, &contentDialog, + // &ContentDialog::reorderLayouts); + // connect(&contentDialog, &ContentDialog::addFriendDialog, this, + // &Widget::addFriendDialog); + // connect(&contentDialog, &ContentDialog::addGroupDialog, this, + // &Widget::addGroupDialog); + // connect(&contentDialog, &ContentDialog::connectFriendWidget, this, + // &Widget::connectFriendWidget); - // connect(&settings, &Settings::groupchatPositionChanged, &contentDialog, - // &ContentDialog::reorderLayouts); - // connect(&contentDialog, &ContentDialog::addFriendDialog, this, - // &Widget::addFriendDialog); - // connect(&contentDialog, &ContentDialog::addGroupDialog, this, - // &Widget::addGroupDialog); - // connect(&contentDialog, &ContentDialog::connectFriendWidget, this, - // &Widget::connectFriendWidget); // #ifdef Q_OS_MAC // Nexus &n = Nexus::getInstance(); @@ -529,27 +494,24 @@ ContentDialog *FriendWidget::createContentDialog() const { // n.updateWindows(); // #endif - ContentDialogManager::getInstance()->addContentDialog(*contentDialog); - return contentDialog; -} - -void FriendWidget::setStatus(Status::Status status, bool event) { - updateStatusLight(status, event); + ContentDialogManager::getInstance()->addContentDialog(*contentDialog); + return contentDialog; } -void FriendWidget::setStatusMsg(const QString &msg) { - m_friend->setStatusMessage(msg); - GenericChatroomWidget::setStatusMsg(msg); +void FriendWidget::setStatus(Status::Status status, bool event) { + updateStatusLight(status, event); } -void FriendWidget::setTyping(bool typing) { +void FriendWidget::setStatusMsg(const QString& msg) { + m_friend->setStatusMessage(msg); + GenericChatroomWidget::setStatusMsg(msg); } +void FriendWidget::setTyping(bool typing) {} -void FriendWidget::setName(const QString &name) -{ +void FriendWidget::setName(const QString& name) { GenericChatroomWidget::setName(name); - if(about){ + if (about) { about->setName(name); } } diff --git a/src/modules/im/src/widget/friendwidget.h b/src/modules/im/src/widget/friendwidget.h index 777e9599..c19d348c 100644 --- a/src/modules/im/src/widget/friendwidget.h +++ b/src/modules/im/src/widget/friendwidget.h @@ -32,38 +32,37 @@ class ContentLayout; class Widget; class AboutFriendForm; -class FriendWidget : public GenericChatroomWidget -{ +class FriendWidget : public GenericChatroomWidget { Q_OBJECT - public: - FriendWidget(ContentLayout* layout, const FriendInfo& f, QWidget* parent=nullptr); +public: + FriendWidget(ContentLayout* layout, const FriendInfo& f, QWidget* parent = nullptr); ~FriendWidget(); void contextMenuEvent(QContextMenuEvent* event) override final; void setAsActiveChatroom() override final; void setAsInactiveChatroom() override final; void setStatus(Status::Status status, bool event); - void setStatusMsg(const QString& msg) ; + void setStatusMsg(const QString& msg); void setTyping(bool typing); void setName(const QString& name); void resetEventFlags() override final; QString getStatusString() const override final; - const Friend* getFriend() const ; - const Contact* getContact() const ; + const Friend* getFriend() const; + const Contact* getContact() const; void search(const QString& searchString, bool hide = false); - void setRecvMessage(const FriendMessage &message, - bool isAction); + void setRecvMessage(const FriendMessage& message, bool isAction); protected: virtual void mousePressEvent(QMouseEvent* ev) override; virtual void mouseMoveEvent(QMouseEvent* ev) override; - void paintEvent(QPaintEvent *e) override; + void paintEvent(QPaintEvent* e) override; void onActiveSet(bool active) override; + private: void init(); void deinit(); @@ -72,24 +71,24 @@ class FriendWidget : public GenericChatroomWidget AboutFriendForm* about; - Friend *m_friend; + Friend* m_friend; - ContentDialog *createContentDialog() const; - ContentDialog * addFriendDialog(const Friend *frnd ); + ContentDialog* createContentDialog() const; + ContentDialog* addFriendDialog(const Friend* frnd); - //右键菜单 - QMenu *menu; - QAction *inviteToGrp; - QAction *removeAct; - QAction *newGroupAction; + // 右键菜单 + QMenu* menu; + QAction* inviteToGrp; + QAction* removeAct; + QAction* newGroupAction; public slots: - void onContextMenuCalled(QContextMenuEvent* event); - void do_widgetClicked(GenericChatroomWidget *w); - void showDetails(); - void removeDetails(); - void changeAutoAccept(bool enable); - void inviteToNewGroup(); + void onContextMenuCalled(QContextMenuEvent* event); + void do_widgetClicked(GenericChatroomWidget* w); + void showDetails(); + void removeDetails(); + void changeAutoAccept(bool enable); + void inviteToNewGroup(); signals: void friendWidgetClicked(FriendWidget* widget); @@ -101,7 +100,7 @@ public slots: void friendWidgetRenamed(FriendWidget* friendWidget); void searchCircle(CircleWidget& circleWidget); void updateFriendActivity(const Friend& frnd); -// void setActive(bool active); + // void setActive(bool active); }; -#endif // FRIENDWIDGET_H +#endif // FRIENDWIDGET_H diff --git a/src/modules/im/src/widget/genericchatitemlayout.cpp b/src/modules/im/src/widget/genericchatitemlayout.cpp index 866f167c..f7fcf6a4 100644 --- a/src/modules/im/src/widget/genericchatitemlayout.cpp +++ b/src/modules/im/src/widget/genericchatitemlayout.cpp @@ -11,100 +11,79 @@ */ #include "genericchatitemlayout.h" -#include "genericchatitemwidget.h" #include #include #include +#include "genericchatitemwidget.h" // As this layout sorts widget, extra care must be taken when inserting widgets. // Prefer using the build in add and remove functions for modifying widgets. // Inserting widgets other ways would cause this layout to be unable to sort. // As such, they are protected using asserts. -GenericChatItemLayout::GenericChatItemLayout() - : layout(new QVBoxLayout()) -{ -} +GenericChatItemLayout::GenericChatItemLayout() : layout(new QVBoxLayout()) {} -GenericChatItemLayout::~GenericChatItemLayout() -{ - delete layout; -} +GenericChatItemLayout::~GenericChatItemLayout() { delete layout; } void GenericChatItemLayout::addSortedWidget(GenericChatItemWidget* widget, int stretch, - Qt::Alignment alignment) -{ + Qt::Alignment alignment) { int closest = indexOfClosestSortedWidget(widget); layout->insertWidget(closest, widget, stretch, alignment); } -int GenericChatItemLayout::indexOfSortedWidget(GenericChatItemWidget* widget) const -{ - if (layout->isEmpty()) - return -1; +int GenericChatItemLayout::indexOfSortedWidget(GenericChatItemWidget* widget) const { + if (layout->isEmpty()) return -1; int index = indexOfClosestSortedWidget(widget); - if (index >= layout->count()) - return -1; + if (index >= layout->count()) return -1; GenericChatItemWidget* atMid = - qobject_cast(layout->itemAt(index)->widget()); + qobject_cast(layout->itemAt(index)->widget()); assert(atMid != nullptr); - if (atMid == widget) - return index; + if (atMid == widget) return index; return -1; } -bool GenericChatItemLayout::existsSortedWidget(GenericChatItemWidget* widget) const -{ +bool GenericChatItemLayout::existsSortedWidget(GenericChatItemWidget* widget) const { return indexOfSortedWidget(widget) != -1; } -void GenericChatItemLayout::removeSortedWidget(GenericChatItemWidget* widget) -{ - if (layout->isEmpty()) - return; +void GenericChatItemLayout::removeSortedWidget(GenericChatItemWidget* widget) { + if (layout->isEmpty()) return; int index = indexOfClosestSortedWidget(widget); - if (layout->itemAt(index) == nullptr) - return; + if (layout->itemAt(index) == nullptr) return; GenericChatItemWidget* atMid = - qobject_cast(layout->itemAt(index)->widget()); + qobject_cast(layout->itemAt(index)->widget()); assert(atMid != nullptr); - if (atMid == widget) - layout->removeWidget(widget); + if (atMid == widget) layout->removeWidget(widget); } -void GenericChatItemLayout::search(const QString& searchString, bool hideAll) -{ +void GenericChatItemLayout::search(const QString& searchString, bool hideAll) { for (int index = 0; index < layout->count(); ++index) { GenericChatItemWidget* widgetAt = - qobject_cast(layout->itemAt(index)->widget()); + qobject_cast(layout->itemAt(index)->widget()); assert(widgetAt != nullptr); widgetAt->searchName(searchString, hideAll); } } -QLayout* GenericChatItemLayout::getLayout() const -{ - return layout; -} +QLayout* GenericChatItemLayout::getLayout() const { return layout; } -int GenericChatItemLayout::indexOfClosestSortedWidget(GenericChatItemWidget* widget) const -{ +int GenericChatItemLayout::indexOfClosestSortedWidget(GenericChatItemWidget* widget) const { // Binary search: Deferred test of equality. int min = 0, max = layout->count(); while (min < max) { int mid = (max - min) / 2 + min; GenericChatItemWidget* atMid = - qobject_cast(layout->itemAt(mid)->widget()); + qobject_cast(layout->itemAt(mid)->widget()); assert(atMid != nullptr); bool lessThan = false; @@ -117,7 +96,7 @@ int GenericChatItemLayout::indexOfClosestSortedWidget(GenericChatItemWidget* wid if (compareValue < 0) lessThan = true; else if (compareValue == 0) - lessThan = atMid < widget; // Consistent ordering. + lessThan = atMid < widget; // Consistent ordering. if (lessThan) min = mid + 1; diff --git a/src/modules/im/src/widget/genericchatitemlayout.h b/src/modules/im/src/widget/genericchatitemlayout.h index 49871aa8..440c9532 100644 --- a/src/modules/im/src/widget/genericchatitemlayout.h +++ b/src/modules/im/src/widget/genericchatitemlayout.h @@ -19,17 +19,18 @@ class QLayout; class QVBoxLayout; class GenericChatItemWidget; -class GenericChatItemLayout -{ +class GenericChatItemLayout { public: GenericChatItemLayout(); GenericChatItemLayout(const GenericChatItemLayout& layout) = delete; ~GenericChatItemLayout(); #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) - void addSortedWidget(GenericChatItemWidget* widget, int stretch = 0, Qt::Alignment alignment = Qt::Alignment()); + void addSortedWidget(GenericChatItemWidget* widget, int stretch = 0, + Qt::Alignment alignment = Qt::Alignment()); #else - void addSortedWidget(GenericChatItemWidget* widget, int stretch = 0, Qt::Alignment alignment = nullptr); + void addSortedWidget(GenericChatItemWidget* widget, int stretch = 0, + Qt::Alignment alignment = nullptr); #endif int indexOfSortedWidget(GenericChatItemWidget* widget) const; bool existsSortedWidget(GenericChatItemWidget* widget) const; @@ -43,4 +44,4 @@ class GenericChatItemLayout QVBoxLayout* layout; }; -#endif // GENERICCHATITEMLAYOUT_H +#endif // GENERICCHATITEMLAYOUT_H diff --git a/src/modules/im/src/widget/genericchatitemwidget.cpp b/src/modules/im/src/widget/genericchatitemwidget.cpp index 851d8b5a..7db2540a 100644 --- a/src/modules/im/src/widget/genericchatitemwidget.cpp +++ b/src/modules/im/src/widget/genericchatitemwidget.cpp @@ -11,6 +11,10 @@ */ #include "genericchatitemwidget.h" +#include +#include +#include +#include #include "maskablepixmapwidget.h" #include "src/lib/settings/style.h" #include "src/model/friend.h" @@ -18,18 +22,15 @@ #include "src/persistence/profile.h" #include "src/persistence/settings.h" #include "src/widget/tool/croppinglabel.h" -#include -#include -#include -#include -GenericChatItemWidget::GenericChatItemWidget(ChatType type, const ContactId &cid, QWidget* parent) - : QFrame(parent) - , chatType(type), statusPic{nullptr}, - contactId{cid}, contact{nullptr}, - prevStatus{Status::Status::None}, - active{false} -{ +GenericChatItemWidget::GenericChatItemWidget(ChatType type, const ContactId& cid, QWidget* parent) + : QFrame(parent) + , chatType(type) + , statusPic{nullptr} + , contactId{cid} + , contact{nullptr} + , prevStatus{Status::Status::None} + , active{false} { nameLabel = new CroppingLabel(this); nameLabel->setObjectName("nameLabel"); nameLabel->setTextFormat(Qt::PlainText); @@ -39,159 +40,130 @@ GenericChatItemWidget::GenericChatItemWidget(ChatType type, const ContactId &cid lastMessageLabel->setObjectName("lastMessageLabel"); lastMessageLabel->setTextFormat(Qt::PlainText); lastMessageLabel->setText(""); - auto p = lastMessageLabel->palette(); - p.setColor(QPalette::WindowText, Style::getColor(Style::GroundExtra)); - - auto newFont= lastMessageLabel->font(); - newFont.setPixelSize(newFont.pixelSize()*.7); - - lastMessageLabel->setFont(newFont); - lastMessageLabel->setPalette(p); -// lastMessageLabel->setForegroundRole(QPalette::WindowText); - - statusPic = new QLabel(this); - if(type == ChatType::Chat){ - updateStatusLight(Status::Status::Offline, false); - }else{ - clearStatusLight(); - } - - avatar = new MaskablePixmapWidget(this, QSize(40, 40), ":/img/avatar_mask.svg"); - auto profile = Nexus::getProfile(); - auto avt = profile->loadAvatar(contactId); - if(!avt.isNull()){ - avatar->setPixmap(avt); - }else{ - setDefaultAvatar(); - } -} + auto p = lastMessageLabel->palette(); + p.setColor(QPalette::WindowText, Style::getColor(Style::GroundExtra)); + auto newFont = lastMessageLabel->font(); + newFont.setPixelSize(newFont.pixelSize() * .7); -QString GenericChatItemWidget::getName() const -{ - return nameLabel->fullText(); -} + lastMessageLabel->setFont(newFont); + lastMessageLabel->setPalette(p); + // lastMessageLabel->setForegroundRole(QPalette::WindowText); + + statusPic = new QLabel(this); + if (type == ChatType::Chat) { + updateStatusLight(Status::Status::Offline, false); + } else { + clearStatusLight(); + } -void GenericChatItemWidget::setName(const QString &name) -{ - nameLabel->setText(name); + avatar = new MaskablePixmapWidget(this, QSize(40, 40), ":/img/avatar_mask.svg"); + auto profile = Nexus::getProfile(); + auto avt = profile->loadAvatar(contactId); + if (!avt.isNull()) { + avatar->setPixmap(avt); + } else { + setDefaultAvatar(); + } } -void GenericChatItemWidget::searchName(const QString& searchString, bool hide) -{ +QString GenericChatItemWidget::getName() const { return nameLabel->fullText(); } + +void GenericChatItemWidget::setName(const QString& name) { nameLabel->setText(name); } + +void GenericChatItemWidget::searchName(const QString& searchString, bool hide) { setVisible(!hide && getName().contains(searchString, Qt::CaseInsensitive)); } -void GenericChatItemWidget::setLastMessage(const QString &msg) -{ - lastMessageLabel->setText(msg); -} +void GenericChatItemWidget::setLastMessage(const QString& msg) { lastMessageLabel->setText(msg); } -void GenericChatItemWidget::updateLastMessage(const Message &m) -{ +void GenericChatItemWidget::updateLastMessage(const Message& m) { QString prefix; auto core = Core::getInstance(); - if(m.isGroup){ - //群聊显示前缀,单聊不显示 - if(ContactId(m.from).username == core->getUsername()){ + if (m.isGroup) { + // 群聊显示前缀,单聊不显示 + if (ContactId(m.from).username == core->getUsername()) { prefix = tr("I:"); - }else{ + } else { auto f = FriendList::findFriend(ContactId(m.from)); - if(f){ - prefix=f->getDisplayedName()+tr(":"); - }else{ - prefix=m.displayName+tr(":"); + if (f) { + prefix = f->getDisplayedName() + tr(":"); + } else { + prefix = m.displayName + tr(":"); } } } - setLastMessage(prefix+m.content); + setLastMessage(prefix + m.content); } -void GenericChatItemWidget::updateStatusLight(Status::Status status, bool event) -{ - if(!statusPic) - return; +void GenericChatItemWidget::updateStatusLight(Status::Status status, bool event) { + if (!statusPic) return; auto pix = Status::getIconPath(status, event); - if(pix.isEmpty()) - return; + if (pix.isEmpty()) return; statusPic->setPixmap(QPixmap(pix)); } -void GenericChatItemWidget::clearStatusLight() -{ - statusPic->clear(); -} +void GenericChatItemWidget::clearStatusLight() { statusPic->clear(); } -bool GenericChatItemWidget::isActive() -{ - return active; -} +bool GenericChatItemWidget::isActive() { return active; } -void GenericChatItemWidget::setActive(bool _active) -{ +void GenericChatItemWidget::setActive(bool _active) { active = _active; if (active) { setBackgroundRole(QPalette::Highlight); -// statusMessageLabel->setForegroundRole(QPalette::HighlightedText); + // statusMessageLabel->setForegroundRole(QPalette::HighlightedText); nameLabel->setForegroundRole(QPalette::HighlightedText); } else { setBackgroundRole(QPalette::Window); -// statusMessageLabel->setForegroundRole(QPalette::WindowText); + // statusMessageLabel->setForegroundRole(QPalette::WindowText); nameLabel->setForegroundRole(QPalette::WindowText); } -// if(avatarSetStatus == Status::AvatarSet::DefaultSet){ -// setDefaultAvatar(); -// } + // if(avatarSetStatus == Status::AvatarSet::DefaultSet){ + // setDefaultAvatar(); + // } onActiveSet(active); } -void GenericChatItemWidget::setAvatar(const QPixmap &pic) -{ -// qDebug() << __func__ << "pic:" << pic; - if(pic.isNull()){ +void GenericChatItemWidget::setAvatar(const QPixmap& pic) { + qDebug() << __func__ << "pic:" << pic; + if (pic.isNull()) { return; } avatar->setPixmap(pic); - } -void GenericChatItemWidget::clearAvatar() -{ +void GenericChatItemWidget::clearAvatar() { qDebug() << __func__; avatar->clear(); } -void GenericChatItemWidget::setDefaultAvatar() -{ +void GenericChatItemWidget::setDefaultAvatar() { qDebug() << __func__; auto name = (chatType == ChatType::Chat) ? "contact" : "group"; auto uri = QString(":img/%1_dark.svg").arg(name); avatar->setPixmap(QPixmap(uri)); } -void GenericChatItemWidget::setContact(const Contact &contact_) -{ +void GenericChatItemWidget::setContact(const Contact& contact_) { contact = &contact_; - if(contact){ + if (contact) { setName(contact->getDisplayedName()); setAvatar(contact->getAvatar()); } } -void GenericChatItemWidget::removeContact() -{ +void GenericChatItemWidget::removeContact() { qDebug() << __func__; contact = nullptr; } -void GenericChatItemWidget::showEvent(QShowEvent *e) -{ - if(contact){ - setName(contact->getDisplayedName()); - setAvatar(contact->getAvatar()); - } +void GenericChatItemWidget::showEvent(QShowEvent* e) { + if (contact) { + setName(contact->getDisplayedName()); + setAvatar(contact->getAvatar()); + } } diff --git a/src/modules/im/src/widget/genericchatitemwidget.h b/src/modules/im/src/widget/genericchatitemwidget.h index ae2c9776..16c70c86 100644 --- a/src/modules/im/src/widget/genericchatitemwidget.h +++ b/src/modules/im/src/widget/genericchatitemwidget.h @@ -13,37 +13,29 @@ #ifndef GENERICCHATITEMWIDGET_H #define GENERICCHATITEMWIDGET_H -#include -#include #include #include #include +#include +#include #include "src/model/message.h" - class CroppingLabel; class MaskablePixmapWidget; - - /** * 聊天控件基类 */ -class GenericChatItemWidget : public QFrame -{ +class GenericChatItemWidget : public QFrame { Q_OBJECT public: - enum ItemType - { - GroupItem, - FriendOfflineItem, - FriendOnlineItem - }; + enum ItemType { GroupItem, FriendOfflineItem, FriendOnlineItem }; - explicit GenericChatItemWidget(ChatType chatType, const ContactId &cid, QWidget* parent = nullptr); + explicit GenericChatItemWidget(ChatType chatType, const ContactId& cid, + QWidget* parent = nullptr); - bool isCompact() const{return compact;}; - void setCompact(bool compact_){compact = compact_;}; + bool isCompact() const { return compact; }; + void setCompact(bool compact_) { compact = compact_; }; Q_PROPERTY(bool compact READ isCompact WRITE setCompact) QString getName() const; @@ -51,12 +43,11 @@ class GenericChatItemWidget : public QFrame void searchName(const QString& searchString, bool hideAll); - - ChatType getChatType() const{return chatType;}; - void setChatType(ChatType type){chatType = type;}; + ChatType getChatType() const { return chatType; }; + void setChatType(ChatType type) { chatType = type; }; Q_PROPERTY(ChatType chatType READ getChatType WRITE setChatType) - inline bool isGroup() const {return chatType == ChatType::GroupChat;}; + inline bool isGroup() const { return chatType == ChatType::GroupChat; }; void setLastMessage(const QString& msg); @@ -69,22 +60,22 @@ class GenericChatItemWidget : public QFrame void setActive(bool active); virtual void onActiveSet(bool active) = 0; - void setAvatar(const QPixmap& pic); + virtual void setAvatar(const QPixmap& pic); void clearAvatar(); void setDefaultAvatar(); - void setContact(const Contact &contact) ; + void setContact(const Contact& contact); void removeContact(); -protected: +protected: virtual void showEvent(QShowEvent* e) override; - //名称 + // 名称 CroppingLabel* nameLabel; CroppingLabel* lastMessageLabel; - //信号状态 + // 信号状态 QLabel* statusPic; - //头像 + // 头像 MaskablePixmapWidget* avatar; bool compact; @@ -96,10 +87,10 @@ class GenericChatItemWidget : public QFrame * 1、好友添加时被设置为friend、group的指针。 * 2、删除好友时,设置为nullptr。 */ - const Contact *contact; + const Contact* contact; Status::Status prevStatus; bool active; }; -#endif // GENERICCHATITEMWIDGET_H +#endif // GENERICCHATITEMWIDGET_H diff --git a/src/modules/im/src/widget/genericchatroomwidget.cpp b/src/modules/im/src/widget/genericchatroomwidget.cpp index 571cb1ab..4004de66 100644 --- a/src/modules/im/src/widget/genericchatroomwidget.cpp +++ b/src/modules/im/src/widget/genericchatroomwidget.cpp @@ -11,18 +11,15 @@ */ #include "genericchatroomwidget.h" +#include +#include #include "maskablepixmapwidget.h" #include "src/lib/settings/style.h" #include "src/persistence/settings.h" #include "src/widget/tool/croppinglabel.h" -#include -#include - -GenericChatroomWidget::GenericChatroomWidget(ChatType type, const ContactId &cid, QWidget* parent) - : GenericChatItemWidget(type, cid, parent), - contactId(cid) -{ +GenericChatroomWidget::GenericChatroomWidget(ChatType type, const ContactId& cid, QWidget* parent) + : GenericChatItemWidget(type, cid, parent), contactId(cid) { Settings& s = Settings::getInstance(); connect(&s, &Settings::compactLayoutChanged, this, &GenericChatroomWidget::compactChange); @@ -32,15 +29,13 @@ GenericChatroomWidget::GenericChatroomWidget(ChatType type, const ContactId &ci compactChange(false); } -bool GenericChatroomWidget::eventFilter(QObject*, QEvent*) -{ - return true; // Disable all events. +bool GenericChatroomWidget::eventFilter(QObject*, QEvent*) { + return true; // Disable all events. } -void GenericChatroomWidget::compactChange(bool _compact) -{ -// if (!isCompact()) -// delete textLayout; // has to be first, deleted by layout +void GenericChatroomWidget::compactChange(bool _compact) { + // if (!isCompact()) + // delete textLayout; // has to be first, deleted by layout setCompact(_compact); @@ -52,18 +47,18 @@ void GenericChatroomWidget::compactChange(bool _compact) setLayout(mainLayout); textLayout->setSpacing(0); textLayout->setMargin(0); - setLayoutDirection(Qt::LeftToRight); // parent might have set Qt::RightToLeft + setLayoutDirection(Qt::LeftToRight); // parent might have set Qt::RightToLeft // avatar if (isCompact()) { mainLayout->setContentsMargins(5, 5, 5, 5); mainLayout->setSpacing(5); - delete textLayout; // Not needed + delete textLayout; // Not needed avatar->setSize(QSize(20, 20)); mainLayout->addWidget(avatar); mainLayout->addWidget(nameLabel); mainLayout->addWidget(lastMessageLabel); - if(statusPic){ + if (statusPic) { mainLayout->addWidget(statusPic); } mainLayout->activate(); @@ -78,33 +73,29 @@ void GenericChatroomWidget::compactChange(bool _compact) textLayout->addStretch(); mainLayout->addWidget(avatar); mainLayout->addLayout(textLayout); - if(statusPic){ - mainLayout->addWidget(statusPic); + if (statusPic) { + mainLayout->addWidget(statusPic); } mainLayout->activate(); nameLabel->setFont(Style::getFont(Style::Big)); } } -void GenericChatroomWidget::setName(const QString& name) -{ +void GenericChatroomWidget::setName(const QString& name) { GenericChatItemWidget::setName(name); nameLabel->setText(name); } -void GenericChatroomWidget::setStatusMsg(const QString& status) -{ -// statusMessageLabel->setText(status); +void GenericChatroomWidget::setStatusMsg(const QString& status) { + // statusMessageLabel->setText(status); } -QString GenericChatroomWidget::getStatusMsg() const -{ -// return statusMessageLabel->text(); +QString GenericChatroomWidget::getStatusMsg() const { + // return statusMessageLabel->text(); return QString{}; } -QString GenericChatroomWidget::getTitle() const -{ +QString GenericChatroomWidget::getTitle() const { QString title = getName(); if (!getStatusString().isNull()) @@ -113,34 +104,29 @@ QString GenericChatroomWidget::getTitle() const return title; } -void GenericChatroomWidget::reloadTheme() -{ +void GenericChatroomWidget::reloadTheme() { QPalette p; -// p = statusMessageLabel->palette(); -// p.setColor(QPalette::WindowText, Style::getColor(Style::GroundExtra)); // Base color -// p.setColor(QPalette::HighlightedText, Style::getColor(Style::StatusActive)); // Color when active -// statusMessageLabel->setPalette(p); + // p = statusMessageLabel->palette(); + // p.setColor(QPalette::WindowText, Style::getColor(Style::GroundExtra)); // Base color + // p.setColor(QPalette::HighlightedText, Style::getColor(Style::StatusActive)); // Color when + // active statusMessageLabel->setPalette(p); p = nameLabel->palette(); - p.setColor(QPalette::WindowText, Style::getColor(Style::MainText)); // Base color - p.setColor(QPalette::HighlightedText, Style::getColor(Style::NameActive)); // Color when active + p.setColor(QPalette::WindowText, Style::getColor(Style::MainText)); // Base color + p.setColor(QPalette::HighlightedText, Style::getColor(Style::NameActive)); // Color when active nameLabel->setPalette(p); p = palette(); - p.setColor(QPalette::Window, Style::getColor(Style::ThemeMedium)); // Base background color - p.setColor(QPalette::Highlight, Style::getColor(Style::ThemeHighlight)); // On mouse over + p.setColor(QPalette::Window, Style::getColor(Style::ThemeMedium)); // Base background color + p.setColor(QPalette::Highlight, Style::getColor(Style::ThemeHighlight)); // On mouse over p.setColor(QPalette::Light, Style::getColor(Style::ThemeLight)); // When active setPalette(p); } -void GenericChatroomWidget::activate() -{ - emit chatroomWidgetClicked(this); -} +void GenericChatroomWidget::activate() { emit chatroomWidgetClicked(this); } -void GenericChatroomWidget::mouseReleaseEvent(QMouseEvent* event) -{ +void GenericChatroomWidget::mouseReleaseEvent(QMouseEvent* event) { if (event->button() == Qt::LeftButton) { emit chatroomWidgetClicked(this); } else if (event->button() == Qt::MiddleButton) { @@ -150,15 +136,11 @@ void GenericChatroomWidget::mouseReleaseEvent(QMouseEvent* event) } } -void GenericChatroomWidget::enterEvent(QEvent*) -{ - if (!active) - setBackgroundRole(QPalette::Light); +void GenericChatroomWidget::enterEvent(QEvent*) { + if (!active) setBackgroundRole(QPalette::Light); } -void GenericChatroomWidget::leaveEvent(QEvent* event) -{ - if (!active) - setBackgroundRole(QPalette::Window); +void GenericChatroomWidget::leaveEvent(QEvent* event) { + if (!active) setBackgroundRole(QPalette::Window); QWidget::leaveEvent(event); } diff --git a/src/modules/im/src/widget/genericchatroomwidget.h b/src/modules/im/src/widget/genericchatroomwidget.h index 4310be0d..8768971f 100644 --- a/src/modules/im/src/widget/genericchatroomwidget.h +++ b/src/modules/im/src/widget/genericchatroomwidget.h @@ -26,26 +26,22 @@ class Friend; class Group; class Contact; - - -class GenericChatroomWidget : public GenericChatItemWidget -{ +class GenericChatroomWidget : public GenericChatItemWidget { Q_OBJECT public: - explicit GenericChatroomWidget(ChatType chatType, const ContactId &cid, QWidget* parent = nullptr); + explicit GenericChatroomWidget(ChatType chatType, const ContactId& cid, + QWidget* parent = nullptr); public slots: virtual void setAsActiveChatroom() = 0; virtual void setAsInactiveChatroom() = 0; - virtual void resetEventFlags() = 0; virtual QString getStatusString() const = 0; - const ContactId& getContactId() const {return contactId;}; + const ContactId& getContactId() const { return contactId; }; virtual bool eventFilter(QObject*, QEvent*) final override; - void setName(const QString& name); void setStatusMsg(const QString& status); QString getStatusMsg() const; @@ -56,7 +52,6 @@ public slots: void activate(); void compactChange(bool compact); - signals: void chatroomWidgetClicked(GenericChatroomWidget* widget); void newWindowOpened(GenericChatroomWidget* widget); @@ -67,17 +62,13 @@ public slots: void enterEvent(QEvent* e) override; void leaveEvent(QEvent* e) override; - protected: - QPoint dragStartPos; QColor lastColor; QHBoxLayout* mainLayout = nullptr; QVBoxLayout* textLayout = nullptr; - - ContactId contactId; }; -#endif // GENERICCHATROOMWIDGET_H +#endif // GENERICCHATROOMWIDGET_H diff --git a/src/modules/im/src/widget/groupwidget.cpp b/src/modules/im/src/widget/groupwidget.cpp index 2b6edbea..0524b17e 100644 --- a/src/modules/im/src/widget/groupwidget.cpp +++ b/src/modules/im/src/widget/groupwidget.cpp @@ -11,6 +11,13 @@ */ #include "groupwidget.h" +#include +#include +#include +#include +#include +#include +#include #include "contentdialogmanager.h" #include "contentlayout.h" #include "form/groupchatform.h" @@ -25,180 +32,161 @@ #include "src/widget/friendwidget.h" #include "src/widget/widget.h" #include "tool/croppinglabel.h" -#include -#include -#include -#include -#include -#include -#include -GroupWidget::GroupWidget(ContentLayout *layout, QString groupnumber, - const GroupId &groupId, const QString &groupName, - bool compact) - : GenericChatroomWidget(ChatType::GroupChat, groupId), - contentLayout{layout}, - quitGroup{nullptr}, - destroyGrpAct{nullptr}, - about{nullptr} -{ +GroupWidget::GroupWidget(ContentLayout* layout, QString groupnumber, const GroupId& groupId, + const QString& groupName, bool compact) + : GenericChatroomWidget(ChatType::GroupChat, groupId) + , contentLayout{layout} + , quitGroup{nullptr} + , destroyGrpAct{nullptr} + , about{nullptr} { + setAcceptDrops(true); + connect(this, &GroupWidget::removeGroup, this, &GroupWidget::do_removeGroup); + connect(this, &GroupWidget::destroyGroup, this, &GroupWidget::do_destroyGroup); - setAcceptDrops(true); - - connect(this, &GroupWidget::removeGroup, this, &GroupWidget::do_removeGroup); - connect(this, &GroupWidget::destroyGroup, this, &GroupWidget::do_destroyGroup); - - auto core = Core::getInstance(); - auto &settings = Settings::getInstance(); + auto core = Core::getInstance(); + auto& settings = Settings::getInstance(); - group = GroupList::addGroup( - groupId, groupName, true, core->getUsername() - ); + group = GroupList::addGroup(groupId, groupName, true, core->getUsername()); - auto dialogManager = ContentDialogManager::getInstance(); + auto dialogManager = ContentDialogManager::getInstance(); - nameLabel->setText(group->getDisplayedName()); + nameLabel->setText(group->getDisplayedName()); - updateUserCount(group->getPeersCount()); - connect(group, &Group::subjectChanged, this, &GroupWidget::updateTitle); - connect(group, &Group::peerCountChanged, this, &GroupWidget::updateUserCount); - connect(group, &Group::descChanged, this, &GroupWidget::updateDesc); - connect(group, &Group::privilegesChanged, this, &GroupWidget::do_privilegesChanged); + updateUserCount(group->getPeersCount()); + connect(group, &Group::subjectChanged, this, &GroupWidget::updateTitle); + connect(group, &Group::peerCountChanged, this, &GroupWidget::updateUserCount); + connect(group, &Group::descChanged, this, &GroupWidget::updateDesc); + connect(group, &Group::privilegesChanged, this, &GroupWidget::do_privilegesChanged); -// connect(nameLabel, &CroppingLabel::editFinished, group, &Group::setName); - connect(group, &Group::displayedNameChanged, - [&](auto& newName) { - setName(newName); - }); + // connect(nameLabel, &CroppingLabel::editFinished, group, &Group::setName); + connect(group, &Group::displayedNameChanged, [&](auto& newName) { setName(newName); }); - connect(this, &GroupWidget::chatroomWidgetClicked, [this]() { - this->do_widgetClicked(this); - emit groupWidgetClicked(this); - }); + connect(this, &GroupWidget::chatroomWidgetClicked, [this]() { + this->do_widgetClicked(this); + emit groupWidgetClicked(this); + }); - settings::Translator::registerHandler([this] { retranslateUi(); }, this); - retranslateUi(); + settings::Translator::registerHandler([this] { retranslateUi(); }, this); + retranslateUi(); - init(); + init(); - emit Widget::getInstance()->groupAdded(group); + emit Widget::getInstance() -> groupAdded(group); -// groupAlertConnections.insert(groupId, notifyReceivedConnection); + // groupAlertConnections.insert(groupId, notifyReceivedConnection); } GroupWidget::~GroupWidget() { qDebug() << __func__; - emit Widget::getInstance()->groupRemoved(group); + emit Widget::getInstance() -> groupRemoved(group); settings::Translator::unregister(this); } -void GroupWidget::init() -{ +void GroupWidget::init() { menu = new QMenu(this); - // QAction *openChatWindow = nullptr; - // if (chatroom->possibleToOpenInNewWindow()) { - // openChatWindow = menu.addAction(tr("Open chat in new window")); - // } + // QAction *openChatWindow = nullptr; + // if (chatroom->possibleToOpenInNewWindow()) { + // openChatWindow = menu.addAction(tr("Open chat in new window")); + // } - // QAction *removeChatWindow = nullptr; - // if (chatroom->canBeRemovedFromWindow()) { - // removeChatWindow = menu.addAction(tr("Remove chat from this window")); - // } + // QAction *removeChatWindow = nullptr; + // if (chatroom->canBeRemovedFromWindow()) { + // removeChatWindow = menu.addAction(tr("Remove chat from this window")); + // } -// menu.addSeparator(); + // menu.addSeparator(); - // QAction *setSubject = menu.addAction(tr("Set title...")); + // QAction *setSubject = menu.addAction(tr("Set title...")); quitGroup = menu->addAction(tr("Quit group", "Menu to quit a groupchat")); - } -ContentDialog *GroupWidget::addGroupDialog(Group *group) { - - auto &settings = Settings::getInstance(); - - auto &groupId = group->getPersistentId(); - - ContentDialog *dialog = - ContentDialogManager::getInstance()->getGroupDialog(GroupId(groupId)); -// bool separated = settings.getSeparateWindow(); -// if (!dialog) { -// dialog = createContentDialog(); -// } - - // GroupWidget *widget = groupWidgets[groupId]; - // bool isCurrentWindow = activeChatroomWidget == widget; - // if (!groupDialog && !separated && isCurrentWindow) { - // onAddClicked(); - // } - - // auto chatForm = groupChatForms[groupId].data(); - // auto chatroom = groupChatrooms[groupId]; -// ContentDialogManager::getInstance()->addGroupToDialog( -// groupId, dialog, chatroom.get(), chatform.get()); - // - // #if (QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)) - // auto removeGroup = QOverload::of(&Widget::removeGroup); - // auto destroyGroup = QOverload::of(&Widget::destroyGroup); - // #else - // auto removeGroup = - // static_cast(&Widget::destroyGroup); - // auto destroyGroup = - // static_cast(&Widget::destroyGroup); - // #endif - - // connect(groupWidget, &GroupWidget::chatroomWidgetClicked, chatForm, - // &GroupChatForm::focusInput); - // connect(groupWidget, &GroupWidget::middleMouseClicked, dialog, - // [this]() { dialog->removeGroup(groupId); }); - // connect(groupWidget, &GroupWidget::chatroomWidgetClicked, chatForm, - // &ChatForm::focusInput); - // connect(groupWidget, &GroupWidget::newWindowOpened, this, - // &Widget::openNewDialog); - // - // // Signal transmission from the created `groupWidget` (which shown in - // // ContentDialog) to the `widget` (which shown in main widget) - // // FIXME: emit should be removed - // connect(groupWidget, &GroupWidget::chatroomWidgetClicked, - // [this](GenericChatroomWidget *w) { - // Q_UNUSED(w); - // emit widget->chatroomWidgetClicked(widget); - // }); - // - // connect(groupWidget, &GroupWidget::newWindowOpened, - // [this](GenericChatroomWidget *w) { - // Q_UNUSED(w); - // emit widget->newWindowOpened(widget); - // }); - // - // // FIXME: emit should be removed - // emit widget->chatroomWidgetClicked(widget); - - return dialog; +ContentDialog* GroupWidget::addGroupDialog(Group* group) { + auto& settings = Settings::getInstance(); + + auto& groupId = group->getPersistentId(); + + ContentDialog* dialog = ContentDialogManager::getInstance()->getGroupDialog(GroupId(groupId)); + // bool separated = settings.getSeparateWindow(); + // if (!dialog) { + // dialog = createContentDialog(); + // } + + // GroupWidget *widget = groupWidgets[groupId]; + // bool isCurrentWindow = activeChatroomWidget == widget; + // if (!groupDialog && !separated && isCurrentWindow) { + // onAddClicked(); + // } + + // auto chatForm = groupChatForms[groupId].data(); + // auto chatroom = groupChatrooms[groupId]; + // ContentDialogManager::getInstance()->addGroupToDialog( + // groupId, dialog, chatroom.get(), chatform.get()); + // + // #if (QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)) + // auto removeGroup = QOverload::of(&Widget::removeGroup); + // auto destroyGroup = QOverload::of(&Widget::destroyGroup); + // #else + // auto removeGroup = + // static_cast(&Widget::destroyGroup); + // auto destroyGroup = + // static_cast(&Widget::destroyGroup); + // #endif + + // connect(groupWidget, &GroupWidget::chatroomWidgetClicked, chatForm, + // &GroupChatForm::focusInput); + // connect(groupWidget, &GroupWidget::middleMouseClicked, dialog, + // [this]() { dialog->removeGroup(groupId); }); + // connect(groupWidget, &GroupWidget::chatroomWidgetClicked, chatForm, + // &ChatForm::focusInput); + // connect(groupWidget, &GroupWidget::newWindowOpened, this, + // &Widget::openNewDialog); + // + // // Signal transmission from the created `groupWidget` (which shown in + // // ContentDialog) to the `widget` (which shown in main widget) + // // FIXME: emit should be removed + // connect(groupWidget, &GroupWidget::chatroomWidgetClicked, + // [this](GenericChatroomWidget *w) { + // Q_UNUSED(w); + // emit widget->chatroomWidgetClicked(widget); + // }); + // + // connect(groupWidget, &GroupWidget::newWindowOpened, + // [this](GenericChatroomWidget *w) { + // Q_UNUSED(w); + // emit widget->newWindowOpened(widget); + // }); + // + // // FIXME: emit should be removed + // emit widget->chatroomWidgetClicked(widget); + + return dialog; } -ContentDialog *GroupWidget::createContentDialog() const { - qDebug() << __func__; +ContentDialog* GroupWidget::createContentDialog() const { + qDebug() << __func__; - ContentDialog *contentDialog = new ContentDialog(); - // connect(contentDialog, &ContentDialog::friendDialogShown, this, - // &Widget::onFriendDialogShown); - // connect(contentDialog, &ContentDialog::groupDialogShown, this, - // &Widget::onGroupDialogShown); + ContentDialog* contentDialog = new ContentDialog(); + // connect(contentDialog, &ContentDialog::friendDialogShown, this, + // &Widget::onFriendDialogShown); + // connect(contentDialog, &ContentDialog::groupDialogShown, this, + // &Widget::onGroupDialogShown); - auto core = Core::getInstance(); + auto core = Core::getInstance(); - connect(core, &Core::usernameSet, contentDialog, &ContentDialog::setUsername); + connect(core, &Core::usernameSet, contentDialog, &ContentDialog::setUsername); + + // connect(&settings, &Settings::groupchatPositionChanged, &contentDialog, + // &ContentDialog::reorderLayouts); + // connect(&contentDialog, &ContentDialog::addFriendDialog, this, + // &Widget::addFriendDialog); + // connect(&contentDialog, &ContentDialog::addGroupDialog, this, + // &Widget::addGroupDialog); + // connect(&contentDialog, &ContentDialog::connectFriendWidget, this, + // &Widget::connectFriendWidget); - // connect(&settings, &Settings::groupchatPositionChanged, &contentDialog, - // &ContentDialog::reorderLayouts); - // connect(&contentDialog, &ContentDialog::addFriendDialog, this, - // &Widget::addFriendDialog); - // connect(&contentDialog, &ContentDialog::addGroupDialog, this, - // &Widget::addGroupDialog); - // connect(&contentDialog, &ContentDialog::connectFriendWidget, this, - // &Widget::connectFriendWidget); // #ifdef Q_OS_MAC // Nexus &n = Nexus::getInstance(); @@ -211,117 +199,106 @@ ContentDialog *GroupWidget::createContentDialog() const { // n.updateWindows(); // #endif - ContentDialogManager::getInstance()->addContentDialog(*contentDialog); - return contentDialog; + + ContentDialogManager::getInstance()->addContentDialog(*contentDialog); + return contentDialog; } -void GroupWidget::updateTitle(const QString &author, const QString &newName) { - Q_UNUSED(author); +void GroupWidget::updateTitle(const QString& author, const QString& newName) { Q_UNUSED(author); } -} +void GroupWidget::contextMenuEvent(QContextMenuEvent* event) { + if (!active) { + setBackgroundRole(QPalette::Highlight); + } -void GroupWidget::contextMenuEvent(QContextMenuEvent *event) { - if (!active) { - setBackgroundRole(QPalette::Highlight); - } - - // Disable leave event. - installEventFilter(this); - QAction *selectedItem = menu->exec(event->globalPos()); - removeEventFilter(this); - - if (!active) { - setBackgroundRole(QPalette::Window); - } - - if (!selectedItem) { - return; - } - - if (selectedItem == quitGroup) { - const bool retYes = GUI::askQuestion(tr("Confirmation"), - tr("Are you sure to quit %1 chat group?").arg(getName()), - /* defaultAns = */ false, - /* warning = */ true, - /* yesno = */ true); - if (!retYes) { - return; - } - emit removeGroup(group->getPersistentId()); - } else if (selectedItem == destroyGrpAct) { - emit destroyGroup(group->getPersistentId()); - } - /*else if (selectedItem == openChatWindow) { - emit newWindowOpened(this); - } else if (selectedItem == removeChatWindow) { - chatroom->removeGroupFromDialogs(); - } else if (selectedItem == setSubject) { - editName(); - }*/ -} + // Disable leave event. + installEventFilter(this); + QAction* selectedItem = menu->exec(event->globalPos()); + removeEventFilter(this); -void GroupWidget::mousePressEvent(QMouseEvent *ev) { - if (ev->button() == Qt::LeftButton) { - dragStartPos = ev->pos(); - } + if (!active) { + setBackgroundRole(QPalette::Window); + } - GenericChatroomWidget::mousePressEvent(ev); -} + if (!selectedItem) { + return; + } -void GroupWidget::mouseMoveEvent(QMouseEvent *ev) { - if (!(ev->buttons() & Qt::LeftButton)) { - return; - } - - if ((dragStartPos - ev->pos()).manhattanLength() > - QApplication::startDragDistance()) { - QMimeData *mdata = new QMimeData; - const Group *group = getGroup(); - mdata->setText(group->getName()); - mdata->setData("groupId", group->getPersistentId().getByteArray()); - - QDrag *drag = new QDrag(this); - drag->setMimeData(mdata); - drag->setPixmap(avatar->getPixmap()); - drag->exec(Qt::CopyAction | Qt::MoveAction); - } + if (selectedItem == quitGroup) { + const bool retYes = + GUI::askQuestion(tr("Confirmation"), + tr("Are you sure to quit %1 chat group?").arg(getName()), + /* defaultAns = */ false, + /* warning = */ true, + /* yesno = */ true); + if (!retYes) { + return; + } + emit removeGroup(group->getPersistentId()); + } else if (selectedItem == destroyGrpAct) { + emit destroyGroup(group->getPersistentId()); + } + /*else if (selectedItem == openChatWindow) { + emit newWindowOpened(this); + } else if (selectedItem == removeChatWindow) { + chatroom->removeGroupFromDialogs(); + } else if (selectedItem == setSubject) { + editName(); + }*/ } -void GroupWidget::do_widgetClicked(GenericChatroomWidget *w) { - showDetails(); +void GroupWidget::mousePressEvent(QMouseEvent* ev) { + if (ev->button() == Qt::LeftButton) { + dragStartPos = ev->pos(); + } + + GenericChatroomWidget::mousePressEvent(ev); } -void GroupWidget::updateDesc(const QString &) -{ +void GroupWidget::mouseMoveEvent(QMouseEvent* ev) { + if (!(ev->buttons() & Qt::LeftButton)) { + return; + } + + if ((dragStartPos - ev->pos()).manhattanLength() > QApplication::startDragDistance()) { + QMimeData* mdata = new QMimeData; + const Group* group = getGroup(); + mdata->setText(group->getName()); + mdata->setData("groupId", group->getPersistentId().getByteArray()); + QDrag* drag = new QDrag(this); + drag->setMimeData(mdata); + drag->setPixmap(avatar->getPixmap()); + drag->exec(Qt::CopyAction | Qt::MoveAction); + } } -void GroupWidget::do_removeGroup(const GroupId &groupId) -{ - qDebug()<<__func__<leaveGroup(groupId.toString()); } -void GroupWidget::do_destroyGroup(const GroupId &groupId) -{ - -} +void GroupWidget::do_destroyGroup(const GroupId& groupId) {} -void GroupWidget::do_privilegesChanged(const Group::Role &role, const Group::Affiliation &aff, const QList codes) -{ - if(aff == Group::Affiliation::Owner){ - if(!destroyGrpAct){ +void GroupWidget::do_privilegesChanged(const Group::Role& role, const Group::Affiliation& aff, + const QList codes) { + if (aff == Group::Affiliation::Owner) { + if (!destroyGrpAct) { destroyGrpAct = menu->addAction(tr("Destroy group", "Destroy the groupchat")); } - }else{ + } else { menu->removeAction(destroyGrpAct); destroyGrpAct = nullptr; } } -void GroupWidget::showDetails(){ - if(!about){ +void GroupWidget::showDetails() { + if (!about) { about = new AboutGroupForm(group->getPersistentId(), this); contentLayout->addWidget(about); } @@ -329,13 +306,13 @@ void GroupWidget::showDetails(){ } void GroupWidget::updateUserCount(int numPeers) { - // qDebug()<<"updateUserCount group:" << getGroup()->getId() << numPeers; - // statusMessageLabel->setText(tr("%n user(s) in chat", "Number of users in - // chat", numPeers)); -// const auto group = chatroom->getGroup(); -// if(about){ -// about->set -// } + // qDebug()<<"updateUserCount group:" << getGroup()->getId() << numPeers; + // statusMessageLabel->setText(tr("%n user(s) in chat", "Number of users in + // chat", numPeers)); + // const auto group = chatroom->getGroup(); + // if(about){ + // about->set + // } } void GroupWidget::setAsActiveChatroom() { setActive(true); } @@ -343,76 +320,71 @@ void GroupWidget::setAsActiveChatroom() { setActive(true); } void GroupWidget::setAsInactiveChatroom() { setActive(false); } void GroupWidget::onActiveSet(bool active) { -// const auto uri = active ? ":img/group_dark.svg" : ":img/group.svg"; -// avatar->setPixmap(Style::scaleSvgImage(uri, avatar->width(), avatar->height())); + // const auto uri = active ? ":img/group_dark.svg" : ":img/group.svg"; + // avatar->setPixmap(Style::scaleSvgImage(uri, avatar->width(), avatar->height())); } void GroupWidget::updateStatusLight(Status::Status status, bool event) { -// const Group *g = chatroom->getGroup(); -// if(statusPic){ -// statusPic->setPixmap(QPixmap(Status::getIconPath(status, event))); -// statusPic->setMargin(event ? 1 : 3); -// } + // const Group *g = chatroom->getGroup(); + // if(statusPic){ + // statusPic->setPixmap(QPixmap(Status::getIconPath(status, event))); + // statusPic->setMargin(event ? 1 : 3); + // } } QString GroupWidget::getStatusString() const { -// if (chatroom->hasNewMessage()) { -// return tr("New Message"); -// } else { -// return tr("Online"); -// } + // if (chatroom->hasNewMessage()) { + // return tr("New Message"); + // } else { + // return tr("Online"); + // } return {}; } void GroupWidget::editName() { nameLabel->editBegin(); } +void GroupWidget::resetEventFlags() {} -void GroupWidget::resetEventFlags() { } +void GroupWidget::dragEnterEvent(QDragEnterEvent* ev) { + // if (!ev->mimeData()->hasFormat("toxPk")) { + // return; + // } + // const ToxPk pk{ev->mimeData()->data("toxPk")}; + // if (chatroom->friendExists(pk)) { + // ev->acceptProposedAction(); + // } -void GroupWidget::dragEnterEvent(QDragEnterEvent *ev) { -// if (!ev->mimeData()->hasFormat("toxPk")) { -// return; -// } -// const ToxPk pk{ev->mimeData()->data("toxPk")}; -// if (chatroom->friendExists(pk)) { -// ev->acceptProposedAction(); -// } - -// if (!active) { -// setBackgroundRole(QPalette::Highlight); -// } + // if (!active) { + // setBackgroundRole(QPalette::Highlight); + // } } -void GroupWidget::dragLeaveEvent(QDragLeaveEvent *) { - if (!active) { - setBackgroundRole(QPalette::Window); - } +void GroupWidget::dragLeaveEvent(QDragLeaveEvent*) { + if (!active) { + setBackgroundRole(QPalette::Window); + } } -void GroupWidget::dropEvent(QDropEvent *ev) { -// if (!ev->mimeData()->hasFormat("toxPk")) { -// return; -// } -// const ToxPk pk{ev->mimeData()->data("toxPk")}; -// if (!chatroom->friendExists(pk)) { -// return; -// } +void GroupWidget::dropEvent(QDropEvent* ev) { + // if (!ev->mimeData()->hasFormat("toxPk")) { + // return; + // } + // const ToxPk pk{ev->mimeData()->data("toxPk")}; + // if (!chatroom->friendExists(pk)) { + // return; + // } -// chatroom->inviteFriend(pk); + // chatroom->inviteFriend(pk); -// if (!active) { -// setBackgroundRole(QPalette::Window); -// } + // if (!active) { + // setBackgroundRole(QPalette::Window); + // } } -void GroupWidget::retranslateUi() { - updateUserCount(group->getPeersCount()); -} - - +void GroupWidget::retranslateUi() { updateUserCount(group->getPeersCount()); } void GroupWidget::reloadTheme() { - if(about){ - //TODO about->reloadTheme(); + if (about) { + // TODO about->reloadTheme(); } } diff --git a/src/modules/im/src/widget/groupwidget.h b/src/modules/im/src/widget/groupwidget.h index 059cea32..a17759c6 100644 --- a/src/modules/im/src/widget/groupwidget.h +++ b/src/modules/im/src/widget/groupwidget.h @@ -19,76 +19,75 @@ #include "src/model/chatroom/groupchatroom.h" #include "src/model/message.h" +#include +#include #include "ContentWidget.h" #include "contentdialog.h" #include "form/groupchatform.h" #include "src/model/groupmessagedispatcher.h" #include "src/model/sessionchatlog.h" -#include -#include class GroupWidget final : public GenericChatroomWidget { - Q_OBJECT + Q_OBJECT public: - GroupWidget(ContentLayout *layout, - QString groupnumber, - const GroupId &groupId, - const QString &groupName, - bool compact); + GroupWidget(ContentLayout* layout, + QString groupnumber, + const GroupId& groupId, + const QString& groupName, + bool compact); - ~GroupWidget(); - void init(); + ~GroupWidget(); + void init(); - void setAsInactiveChatroom() final override; - void setAsActiveChatroom() final override; - void updateStatusLight(Status::Status status, bool event) final override; - void resetEventFlags() final override; - QString getStatusString() const final override; - const Group *getGroup() const {return group;}; + void setAsInactiveChatroom() final override; + void setAsActiveChatroom() final override; + void updateStatusLight(Status::Status status, bool event) final override; + void resetEventFlags() final override; + QString getStatusString() const final override; + const Group* getGroup() const { return group; }; - void editName(); - ContentDialog * addGroupDialog(Group *group); - ContentDialog * createContentDialog()const ; + void editName(); + ContentDialog* addGroupDialog(Group* group); + ContentDialog* createContentDialog() const; - void showDetails(); - void reloadTheme() ; + void showDetails(); + void reloadTheme(); signals: - void groupWidgetClicked(GroupWidget *widget); - void removeGroup(const GroupId &groupId); - void destroyGroup(const GroupId &groupId); + void groupWidgetClicked(GroupWidget* widget); + void removeGroup(const GroupId& groupId); + void destroyGroup(const GroupId& groupId); protected: - void contextMenuEvent(QContextMenuEvent *event) final override; - void mousePressEvent(QMouseEvent *event) final override; - void mouseMoveEvent(QMouseEvent *event) final override; - void dragEnterEvent(QDragEnterEvent *ev) override; - void dragLeaveEvent(QDragLeaveEvent *ev) override; - void dropEvent(QDropEvent *ev) override; - void onActiveSet(bool active) override; + void contextMenuEvent(QContextMenuEvent* event) final override; + void mousePressEvent(QMouseEvent* event) final override; + void mouseMoveEvent(QMouseEvent* event) final override; + void dragEnterEvent(QDragEnterEvent* ev) override; + void dragLeaveEvent(QDragLeaveEvent* ev) override; + void dropEvent(QDropEvent* ev) override; + void onActiveSet(bool active) override; private slots: - void retranslateUi(); - void updateTitle(const QString &author, const QString &newName); - void updateUserCount(int numPeers); - void do_widgetClicked(GenericChatroomWidget *w); - void updateDesc(const QString &); - void do_removeGroup(const GroupId &groupId); - void do_destroyGroup(const GroupId &groupId); - void do_privilegesChanged(const Group::Role &role, - const Group::Affiliation &aff, - const QList codes); + void retranslateUi(); + void updateTitle(const QString& author, const QString& newName); + void updateUserCount(int numPeers); + void do_widgetClicked(GenericChatroomWidget* w); + void updateDesc(const QString&); + void do_removeGroup(const GroupId& groupId); + void do_destroyGroup(const GroupId& groupId); + void do_privilegesChanged( + const Group::Role& role, const Group::Affiliation& aff, const QList codes); private: - Group *group; + Group* group; - ContentLayout* contentLayout; - AboutGroupForm* about; + ContentLayout* contentLayout; + AboutGroupForm* about; - QMenu *menu; - QAction *destroyGrpAct; - QAction *quitGroup; + QMenu* menu; + QAction* destroyGrpAct; + QAction* quitGroup; }; -#endif // GROUPWIDGET_H +#endif // GROUPWIDGET_H diff --git a/src/modules/im/src/widget/gui.cpp b/src/modules/im/src/widget/gui.cpp index 043afa27..67888583 100644 --- a/src/modules/im/src/widget/gui.cpp +++ b/src/modules/im/src/widget/gui.cpp @@ -10,10 +10,8 @@ * See the Mulan PubL v2 for more details. */ - #include "gui.h" -#include "widget.h" -#include "src/nexus.h" +#include #include #include #include @@ -23,7 +21,8 @@ #include #include #include -#include +#include "src/nexus.h" +#include "widget.h" /** * @class GUI @@ -36,9 +35,7 @@ * @brief Emitted when the GUI is resized on supported platforms. */ -GUI::GUI(QObject* parent) - : QObject(parent) -{ +GUI::GUI(QObject* parent) : QObject(parent) { assert(QThread::currentThread() == qApp->thread()); assert(Nexus::getDesktopGUI()); } @@ -46,8 +43,7 @@ GUI::GUI(QObject* parent) /** * @brief Returns the singleton instance. */ -GUI& GUI::getInstance() -{ +GUI& GUI::getInstance() { static GUI gui; return gui; } @@ -59,8 +55,7 @@ GUI& GUI::getInstance() * @note A disabled GUI can't be interacted with by the user. * @param state Enable/disable GUI. */ -void GUI::setEnabled(bool state) -{ +void GUI::setEnabled(bool state) { if (QThread::currentThread() == qApp->thread()) { getInstance()._setEnabled(state); } else { @@ -75,8 +70,7 @@ void GUI::setEnabled(bool state) * * This is usually always visible to the user. */ -void GUI::setWindowTitle(const QString& title) -{ +void GUI::setWindowTitle(const QString& title) { if (QThread::currentThread() == qApp->thread()) { getInstance()._setWindowTitle(title); } else { @@ -88,8 +82,7 @@ void GUI::setWindowTitle(const QString& title) /** * @brief Reloads the application theme and redraw the window. */ -void GUI::reloadTheme() -{ +void GUI::reloadTheme() { if (QThread::currentThread() == qApp->thread()) { getInstance()._reloadTheme(); emit getInstance().themeApplyRequest(); @@ -103,8 +96,7 @@ void GUI::reloadTheme() * @param title Title of information window. * @param msg Text in information window. */ -void GUI::showInfo(const QString& title, const QString& msg) -{ +void GUI::showInfo(const QString& title, const QString& msg) { if (QThread::currentThread() == qApp->thread()) { getInstance()._showInfo(title, msg); } else { @@ -118,8 +110,7 @@ void GUI::showInfo(const QString& title, const QString& msg) * @param title Title of warning window. * @param msg Text in warning window. */ -void GUI::showWarning(const QString& title, const QString& msg) -{ +void GUI::showWarning(const QString& title, const QString& msg) { if (QThread::currentThread() == qApp->thread()) { getInstance()._showWarning(title, msg); } else { @@ -133,8 +124,7 @@ void GUI::showWarning(const QString& title, const QString& msg) * @param title Title of error window. * @param msg Text in error window. */ -void GUI::showError(const QString& title, const QString& msg) -{ +void GUI::showError(const QString& title, const QString& msg) { if (QThread::currentThread() == qApp->thread()) { // If the GUI hasn't started yet and we're on the main thread, // we still want to be able to show error messages @@ -157,8 +147,8 @@ void GUI::showError(const QString& title, const QString& msg) * @param yesno Show "Yes" and "No" buttons. * @return True if the answer is positive, false otherwise. */ -bool GUI::askQuestion(const QString& title, const QString& msg, bool defaultAns, bool warning, bool yesno) -{ +bool GUI::askQuestion(const QString& title, const QString& msg, bool defaultAns, bool warning, + bool yesno) { if (QThread::currentThread() == qApp->thread()) { return getInstance()._askQuestion(title, msg, defaultAns, warning, yesno); } else { @@ -184,8 +174,7 @@ bool GUI::askQuestion(const QString& title, const QString& msg, bool defaultAns, * @return True if the answer is positive, false otherwise. */ bool GUI::askQuestion(const QString& title, const QString& msg, const QString& button1, - const QString& button2, bool defaultAns, bool warning) -{ + const QString& button2, bool defaultAns, bool warning) { if (QThread::currentThread() == qApp->thread()) { return getInstance()._askQuestion(title, msg, button1, button2, defaultAns, warning); } else { @@ -200,55 +189,45 @@ bool GUI::askQuestion(const QString& title, const QString& msg, const QString& b // Private implementations -void GUI::_setEnabled(bool state) -{ +void GUI::_setEnabled(bool state) { Widget* w = Nexus::getDesktopGUI(); - if (w) - w->setEnabled(state); + if (w) w->setEnabled(state); } -void GUI::_setWindowTitle(const QString& title) -{ +void GUI::_setWindowTitle(const QString& title) { QWidget* w = getMainWidget(); - if (!w) - return; + if (!w) return; if (title.isEmpty()) w->setWindowTitle("qTox"); else w->setWindowTitle("qTox - " + title); } -void GUI::_reloadTheme() -{ +void GUI::_reloadTheme() { Widget* w = Nexus::getDesktopGUI(); - if (w) - w->reloadTheme(); + if (w) w->reloadTheme(); } -void GUI::_showInfo(const QString& title, const QString& msg) -{ +void GUI::_showInfo(const QString& title, const QString& msg) { QMessageBox messageBox(QMessageBox::Information, title, msg, QMessageBox::Ok, getMainWidget()); messageBox.setButtonText(QMessageBox::Ok, QApplication::tr("Ok")); messageBox.exec(); } -void GUI::_showWarning(const QString& title, const QString& msg) -{ +void GUI::_showWarning(const QString& title, const QString& msg) { QMessageBox messageBox(QMessageBox::Warning, title, msg, QMessageBox::Ok, getMainWidget()); messageBox.setButtonText(QMessageBox::Ok, QApplication::tr("Ok")); messageBox.exec(); } -void GUI::_showError(const QString& title, const QString& msg) -{ +void GUI::_showError(const QString& title, const QString& msg) { QMessageBox messageBox(QMessageBox::Critical, title, msg, QMessageBox::Ok, getMainWidget()); messageBox.setButtonText(QMessageBox::Ok, QApplication::tr("Ok")); messageBox.exec(); } bool GUI::_askQuestion(const QString& title, const QString& msg, bool defaultAns, bool warning, - bool yesno) -{ + bool yesno) { QString positiveButton = yesno ? QApplication::tr("Yes") : QApplication::tr("Ok"); QString negativeButton = yesno ? QApplication::tr("No") : QApplication::tr("Cancel"); @@ -256,8 +235,7 @@ bool GUI::_askQuestion(const QString& title, const QString& msg, bool defaultAns } bool GUI::_askQuestion(const QString& title, const QString& msg, const QString& button1, - const QString& button2, bool defaultAns, bool warning) -{ + const QString& button2, bool defaultAns, bool warning) { QMessageBox::Icon icon = warning ? QMessageBox::Warning : QMessageBox::Question; QMessageBox box(icon, title, msg, QMessageBox::NoButton, getMainWidget()); QPushButton* pushButton1 = box.addButton(button1, QMessageBox::AcceptRole); @@ -275,8 +253,7 @@ bool GUI::_askQuestion(const QString& title, const QString& msg, const QString& * @brief Get the main widget. * @return The main QWidget* of the application */ -QWidget* GUI::getMainWidget() -{ +QWidget* GUI::getMainWidget() { QWidget* maingui{nullptr}; maingui = Nexus::getDesktopGUI(); return maingui; diff --git a/src/modules/im/src/widget/gui.h b/src/modules/im/src/widget/gui.h index db714124..4885cdb7 100644 --- a/src/modules/im/src/widget/gui.h +++ b/src/modules/im/src/widget/gui.h @@ -10,7 +10,6 @@ * See the Mulan PubL v2 for more details. */ - #ifndef GUI_H #define GUI_H @@ -18,8 +17,7 @@ class QWidget; -class GUI : public QObject -{ +class GUI : public QObject { Q_OBJECT public: static GUI& getInstance(); @@ -39,7 +37,7 @@ class GUI : public QObject signals: void themeApplyRequest(); - private: +private: explicit GUI(QObject* parent = nullptr); private slots: @@ -56,4 +54,4 @@ private slots: const QString& button2, bool defaultAns = false, bool warning = true); }; -#endif // GUI_H +#endif // GUI_H diff --git a/src/modules/im/src/widget/loginscreen.cpp b/src/modules/im/src/widget/loginscreen.cpp index 419afcf2..fee8bf52 100644 --- a/src/modules/im/src/widget/loginscreen.cpp +++ b/src/modules/im/src/widget/loginscreen.cpp @@ -11,6 +11,10 @@ */ #include "loginscreen.h" +#include +#include +#include +#include #include "lib/settings/translator.h" #include "src/lib/settings/style.h" #include "src/persistence/profile.h" @@ -19,16 +23,11 @@ #include "src/widget/form/setpassworddialog.h" #include "src/widget/tool/profileimporter.h" #include "ui_loginscreen.h" -#include -#include -#include -#include LoginScreen::LoginScreen(const QString& initialProfileName, QWidget* parent) - : QDialog(parent) - , ui(new Ui::LoginScreen) - , quitShortcut{QKeySequence(Qt::CTRL + Qt::Key_Q), this} -{ + : QDialog(parent) + , ui(new Ui::LoginScreen) + , quitShortcut{QKeySequence(Qt::CTRL + Qt::Key_Q), this} { ui->setupUi(this); // permanently disables maximize button https://github.com/qTox/qTox/issues/1973 @@ -36,7 +35,8 @@ LoginScreen::LoginScreen(const QString& initialProfileName, QWidget* parent) this->setFixedSize(this->size()); connect(&quitShortcut, &QShortcut::activated, this, &LoginScreen::close); - connect(ui->newProfilePgbtn, &QPushButton::clicked, this, &LoginScreen::onNewProfilePageClicked); + connect(ui->newProfilePgbtn, &QPushButton::clicked, this, + &LoginScreen::onNewProfilePageClicked); connect(ui->loginPgbtn, &QPushButton::clicked, this, &LoginScreen::onLoginPageClicked); connect(ui->createAccountButton, &QPushButton::clicked, this, &LoginScreen::onCreateNewProfile); connect(ui->newUsername, &QLineEdit::returnPressed, this, &LoginScreen::onCreateNewProfile); @@ -48,7 +48,8 @@ LoginScreen::LoginScreen(const QString& initialProfileName, QWidget* parent) connect(ui->loginPassword, &QLineEdit::returnPressed, this, &LoginScreen::onLogin); connect(ui->newPass, &QLineEdit::textChanged, this, &LoginScreen::onPasswordEdited); connect(ui->newPassConfirm, &QLineEdit::textChanged, this, &LoginScreen::onPasswordEdited); - connect(ui->autoLoginCB, &QCheckBox::stateChanged, this, &LoginScreen::onAutoLoginCheckboxChanged); + connect(ui->autoLoginCB, &QCheckBox::stateChanged, this, + &LoginScreen::onAutoLoginCheckboxChanged); connect(ui->importButton, &QPushButton::clicked, this, &LoginScreen::onImportProfile); reset(initialProfileName); @@ -58,8 +59,7 @@ LoginScreen::LoginScreen(const QString& initialProfileName, QWidget* parent) settings::Translator::registerHandler(std::bind(&LoginScreen::retranslateUi, this), this); } -LoginScreen::~LoginScreen() -{ +LoginScreen::~LoginScreen() { settings::Translator::unregister(this); delete ui; } @@ -67,8 +67,7 @@ LoginScreen::~LoginScreen() /** * @brief Resets the UI, clears all fields. */ -void LoginScreen::reset(const QString& initialProfileName) -{ +void LoginScreen::reset(const QString& initialProfileName) { ui->newUsername->clear(); ui->newPass->clear(); ui->newPassConfirm->clear(); @@ -91,51 +90,36 @@ void LoginScreen::reset(const QString& initialProfileName) } } -void LoginScreen::onProfileLoaded() -{ - done(QDialog::Accepted); -} +void LoginScreen::onProfileLoaded() { done(QDialog::Accepted); } -void LoginScreen::onProfileLoadFailed() -{ +void LoginScreen::onProfileLoadFailed() { QMessageBox::critical(this, tr("Couldn't load this profile"), tr("Wrong password.")); ui->loginPassword->setFocus(); ui->loginPassword->selectAll(); } -void LoginScreen::onAutoLoginChanged(bool state) -{ - ui->autoLoginCB->setChecked(state); -} +void LoginScreen::onAutoLoginChanged(bool state) { ui->autoLoginCB->setChecked(state); } -bool LoginScreen::event(QEvent* event) -{ +bool LoginScreen::event(QEvent* event) { switch (event->type()) { #ifdef Q_OS_MAC - case QEvent::WindowActivate: - case QEvent::WindowStateChange: - emit windowStateChanged(windowState()); - break; + case QEvent::WindowActivate: + case QEvent::WindowStateChange: + emit windowStateChanged(windowState()); + break; #endif - default: - break; + default: + break; } return QWidget::event(event); } -void LoginScreen::onNewProfilePageClicked() -{ - ui->stackedWidget->setCurrentIndex(0); -} +void LoginScreen::onNewProfilePageClicked() { ui->stackedWidget->setCurrentIndex(0); } -void LoginScreen::onLoginPageClicked() -{ - ui->stackedWidget->setCurrentIndex(1); -} +void LoginScreen::onLoginPageClicked() { ui->stackedWidget->setCurrentIndex(1); } -void LoginScreen::onCreateNewProfile() -{ +void LoginScreen::onCreateNewProfile() { QString name = ui->newUsername->text(); QString pass = ui->newPass->text(); @@ -167,10 +151,8 @@ void LoginScreen::onCreateNewProfile() emit createNewProfile(name, pass); } -void LoginScreen::onLoginUsernameSelected(const QString& name) -{ - if (name.isEmpty()) - return; +void LoginScreen::onLoginUsernameSelected(const QString& name) { + if (name.isEmpty()) return; ui->loginPassword->clear(); if (Profile::isEncrypted(name)) { @@ -185,12 +167,11 @@ void LoginScreen::onLoginUsernameSelected(const QString& name) ui->loginPassword->hide(); ui->autoLoginCB->show(); ui->autoLoginCB->setToolTip( - tr("Password protected profiles can't be automatically loaded.")); + tr("Password protected profiles can't be automatically loaded.")); } } -void LoginScreen::onLogin() -{ +void LoginScreen::onLogin() { QString name = ui->loginUsernames->currentText(); QString pass = ui->loginPassword->text(); @@ -211,24 +192,18 @@ void LoginScreen::onLogin() emit loadProfile(name, pass); } -void LoginScreen::onPasswordEdited() -{ +void LoginScreen::onPasswordEdited() { ui->passStrengthMeter->setValue(SetPasswordDialog::getPasswordStrength(ui->newPass->text())); } -void LoginScreen::onAutoLoginCheckboxChanged(int state) -{ +void LoginScreen::onAutoLoginCheckboxChanged(int state) { auto cstate = static_cast(state); emit autoLoginChanged(cstate == Qt::CheckState::Checked); } -void LoginScreen::retranslateUi() -{ - ui->retranslateUi(this); -} +void LoginScreen::retranslateUi() { ui->retranslateUi(this); } -void LoginScreen::onImportProfile() -{ +void LoginScreen::onImportProfile() { ProfileImporter pi(this); if (pi.importProfile()) { reset(); diff --git a/src/modules/im/src/widget/loginscreen.h b/src/modules/im/src/widget/loginscreen.h index 5259ab7d..2feddbea 100644 --- a/src/modules/im/src/widget/loginscreen.h +++ b/src/modules/im/src/widget/loginscreen.h @@ -10,7 +10,6 @@ * See the Mulan PubL v2 for more details. */ - #ifndef LOGINSCREEN_H #define LOGINSCREEN_H @@ -24,8 +23,7 @@ namespace Ui { class LoginScreen; } -class LoginScreen : public QDialog -{ +class LoginScreen : public QDialog { Q_OBJECT public: @@ -69,4 +67,4 @@ private slots: QShortcut quitShortcut; }; -#endif // LOGINSCREEN_H +#endif // LOGINSCREEN_H diff --git a/src/modules/im/src/widget/maskablepixmapwidget.cpp b/src/modules/im/src/widget/maskablepixmapwidget.cpp index 5149dbff..8286b8cc 100644 --- a/src/modules/im/src/widget/maskablepixmapwidget.cpp +++ b/src/modules/im/src/widget/maskablepixmapwidget.cpp @@ -20,21 +20,13 @@ */ MaskablePixmapWidget::MaskablePixmapWidget(QWidget* parent, QSize size, QString maskName) - : QLabel("", parent) - , renderTarget(nullptr) - , maskName(maskName) - , clickable(false) -{ + : QLabel("", parent), renderTarget(nullptr), maskName(maskName), clickable(false) { setSize(size); } -MaskablePixmapWidget::~MaskablePixmapWidget() -{ - delete renderTarget; -} +MaskablePixmapWidget::~MaskablePixmapWidget() { delete renderTarget; } -void MaskablePixmapWidget::setClickable(bool clickable) -{ +void MaskablePixmapWidget::setClickable(bool clickable) { this->clickable = clickable; if (clickable) { @@ -44,27 +36,21 @@ void MaskablePixmapWidget::setClickable(bool clickable) } } -void MaskablePixmapWidget::setPixmap(const QPixmap& pmap) -{ +void MaskablePixmapWidget::setPixmap(const QPixmap& pmap) { if (pmap.isNull()) { return; } unscaled = pmap; - pixmap = pmap.scaled(size() * devicePixelRatioF(), - Qt::KeepAspectRatio, - Qt::SmoothTransformation); + pixmap = pmap.scaled( + size() * devicePixelRatioF(), Qt::KeepAspectRatio, Qt::SmoothTransformation); updatePixmap(); update(); } -QPixmap MaskablePixmapWidget::getPixmap() const -{ - return *renderTarget; -} +QPixmap MaskablePixmapWidget::getPixmap() const { return *renderTarget; } -void MaskablePixmapWidget::setSize(QSize size) -{ +void MaskablePixmapWidget::setSize(QSize size) { setFixedSize(size); delete renderTarget; @@ -73,34 +59,29 @@ void MaskablePixmapWidget::setSize(QSize size) QPixmap pmapMask = QPixmap(maskName); if (!pmapMask.isNull()) { - mask = pmapMask.scaled(targetSize, - Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + mask = pmapMask.scaled(targetSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); } if (!unscaled.isNull()) { - pixmap = unscaled.scaled(targetSize, - Qt::KeepAspectRatio, - Qt::SmoothTransformation); + pixmap = unscaled.scaled(targetSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); updatePixmap(); update(); } } -void MaskablePixmapWidget::mousePressEvent(QMouseEvent*) -{ +void MaskablePixmapWidget::mousePressEvent(QMouseEvent*) { if (clickable) { emit clicked(); } } -void MaskablePixmapWidget::updatePixmap() -{ +void MaskablePixmapWidget::updatePixmap() { renderTarget->fill(Qt::transparent); renderTarget->setDevicePixelRatio(1.0); QSize actualSize = size() * devicePixelRatioF(); QPoint offset((actualSize.width() - pixmap.size().width()) / 2, - (actualSize.height() - pixmap.size().height()) / 2); // centering the pixmap + (actualSize.height() - pixmap.size().height()) / 2); // centering the pixmap QPainter painter(renderTarget); painter.setCompositionMode(QPainter::CompositionMode_SourceOver); diff --git a/src/modules/im/src/widget/maskablepixmapwidget.h b/src/modules/im/src/widget/maskablepixmapwidget.h index e1a397ee..77b2fd18 100644 --- a/src/modules/im/src/widget/maskablepixmapwidget.h +++ b/src/modules/im/src/widget/maskablepixmapwidget.h @@ -15,8 +15,7 @@ #include -class MaskablePixmapWidget final : public QLabel -{ +class MaskablePixmapWidget final : public QLabel { Q_OBJECT public: MaskablePixmapWidget(QWidget* parent, QSize size, QString maskName = QString()); @@ -43,4 +42,4 @@ class MaskablePixmapWidget final : public QLabel bool clickable; }; -#endif // MASKABLEPIXMAPWIDGET_H +#endif // MASKABLEPIXMAPWIDGET_H diff --git a/src/modules/im/src/widget/notificationedgewidget.cpp b/src/modules/im/src/widget/notificationedgewidget.cpp index 954904d7..1c095586 100644 --- a/src/modules/im/src/widget/notificationedgewidget.cpp +++ b/src/modules/im/src/widget/notificationedgewidget.cpp @@ -11,22 +11,21 @@ */ #include "notificationedgewidget.h" -#include "src/lib/settings/style.h" #include #include +#include "src/lib/settings/style.h" #include NotificationEdgeWidget::NotificationEdgeWidget(Position position, QWidget* parent) - : QWidget(parent) -{ - setAttribute(Qt::WA_StyledBackground); // Show background. + : QWidget(parent) { + setAttribute(Qt::WA_StyledBackground); // Show background. setStyleSheet(Style::getStylesheet("notificationEdge/notificationEdge.css")); QHBoxLayout* layout = new QHBoxLayout(this); layout->addStretch(); textLabel = new QLabel(this); - textLabel->setMinimumHeight(textLabel->sizeHint().height()); // Prevent cut-off text. + textLabel->setMinimumHeight(textLabel->sizeHint().height()); // Prevent cut-off text. layout->addWidget(textLabel); QLabel* arrowLabel = new QLabel(this); @@ -42,13 +41,11 @@ NotificationEdgeWidget::NotificationEdgeWidget(Position position, QWidget* paren setCursor(Qt::PointingHandCursor); } -void NotificationEdgeWidget::updateNotificationCount(int count) -{ +void NotificationEdgeWidget::updateNotificationCount(int count) { textLabel->setText(tr("Unread message(s)", "", count)); } -void NotificationEdgeWidget::mouseReleaseEvent(QMouseEvent* event) -{ +void NotificationEdgeWidget::mouseReleaseEvent(QMouseEvent* event) { emit clicked(); QWidget::mousePressEvent(event); } diff --git a/src/modules/im/src/widget/notificationedgewidget.h b/src/modules/im/src/widget/notificationedgewidget.h index ab7204fd..2d52cb5b 100644 --- a/src/modules/im/src/widget/notificationedgewidget.h +++ b/src/modules/im/src/widget/notificationedgewidget.h @@ -17,15 +17,10 @@ class QLabel; -class NotificationEdgeWidget final : public QWidget -{ +class NotificationEdgeWidget final : public QWidget { Q_OBJECT public: - enum Position : uint8_t - { - Top, - Bottom - }; + enum Position : uint8_t { Top, Bottom }; explicit NotificationEdgeWidget(Position position, QWidget* parent = nullptr); void updateNotificationCount(int count); @@ -40,4 +35,4 @@ class NotificationEdgeWidget final : public QWidget QLabel* textLabel; }; -#endif // NOTIFICATIONEDGEWIDGET_H +#endif // NOTIFICATIONEDGEWIDGET_H diff --git a/src/modules/im/src/widget/notificationscrollarea.cpp b/src/modules/im/src/widget/notificationscrollarea.cpp index d25da828..f8b54107 100644 --- a/src/modules/im/src/widget/notificationscrollarea.cpp +++ b/src/modules/im/src/widget/notificationscrollarea.cpp @@ -10,24 +10,20 @@ * See the Mulan PubL v2 for more details. */ #include "notificationscrollarea.h" -#include "genericchatroomwidget.h" -#include "notificationedgewidget.h" #include #include +#include "genericchatroomwidget.h" +#include "notificationedgewidget.h" -NotificationScrollArea::NotificationScrollArea(QWidget* parent) - : AdjustingScrollArea(parent) -{ +NotificationScrollArea::NotificationScrollArea(QWidget* parent) : AdjustingScrollArea(parent) { connect(verticalScrollBar(), &QAbstractSlider::valueChanged, this, &NotificationScrollArea::updateVisualTracking); connect(verticalScrollBar(), &QAbstractSlider::rangeChanged, this, &NotificationScrollArea::updateVisualTracking); } -void NotificationScrollArea::trackWidget(GenericChatroomWidget* widget) -{ - if (trackedWidgets.find(widget) != trackedWidgets.end()) - return; +void NotificationScrollArea::trackWidget(GenericChatroomWidget* widget) { + if (trackedWidgets.find(widget) != trackedWidgets.end()) return; Visibility visibility = widgetVisible(widget); if (visibility != Visible) { @@ -60,17 +56,13 @@ void NotificationScrollArea::trackWidget(GenericChatroomWidget* widget) /** * @brief Delete notification bar from visible elements on scroll area */ -void NotificationScrollArea::updateVisualTracking() -{ - updateTracking(nullptr); -} +void NotificationScrollArea::updateVisualTracking() { updateTracking(nullptr); } /** * @brief Delete notification bar from visible elements and widget on scroll area * @param widget Chatroom widget to remove from tracked widgets */ -void NotificationScrollArea::updateTracking(GenericChatroomWidget* widget) -{ +void NotificationScrollArea::updateTracking(GenericChatroomWidget* widget) { QHash::iterator i = trackedWidgets.begin(); while (i != trackedWidgets.end()) { if (i.key() == widget || widgetVisible(i.key()) == Visible) { @@ -96,18 +88,14 @@ void NotificationScrollArea::updateTracking(GenericChatroomWidget* widget) } } -void NotificationScrollArea::resizeEvent(QResizeEvent* event) -{ - if (topEdge != nullptr) - recalculateTopEdge(); - if (bottomEdge != nullptr) - recalculateBottomEdge(); +void NotificationScrollArea::resizeEvent(QResizeEvent* event) { + if (topEdge != nullptr) recalculateTopEdge(); + if (bottomEdge != nullptr) recalculateBottomEdge(); AdjustingScrollArea::resizeEvent(event); } -void NotificationScrollArea::findNextWidget() -{ +void NotificationScrollArea::findNextWidget() { int value = 0; GenericChatroomWidget* next = nullptr; QHash::iterator i = trackedWidgets.begin(); @@ -136,8 +124,7 @@ void NotificationScrollArea::findNextWidget() ensureWidgetVisible(next, 0, referencesBelow != 1 ? bottomEdge->height() : 0); } -void NotificationScrollArea::findPreviousWidget() -{ +void NotificationScrollArea::findPreviousWidget() { int value = 0; GenericChatroomWidget* next = nullptr; QHash::iterator i = trackedWidgets.begin(); @@ -162,12 +149,10 @@ void NotificationScrollArea::findPreviousWidget() } } - if (next != nullptr) - ensureWidgetVisible(next, 0, referencesAbove != 1 ? topEdge->height() : 0); + if (next != nullptr) ensureWidgetVisible(next, 0, referencesAbove != 1 ? topEdge->height() : 0); } -NotificationScrollArea::Visibility NotificationScrollArea::widgetVisible(QWidget* widget) const -{ +NotificationScrollArea::Visibility NotificationScrollArea::widgetVisible(QWidget* widget) const { int y = widget->mapTo(viewport(), QPoint()).y(); if (y < 0) @@ -178,14 +163,12 @@ NotificationScrollArea::Visibility NotificationScrollArea::widgetVisible(QWidget return Visible; } -void NotificationScrollArea::recalculateTopEdge() -{ +void NotificationScrollArea::recalculateTopEdge() { topEdge->move(viewport()->pos()); topEdge->resize(viewport()->width(), topEdge->height()); } -void NotificationScrollArea::recalculateBottomEdge() -{ +void NotificationScrollArea::recalculateBottomEdge() { QPoint position = viewport()->pos(); position.setY(position.y() + viewport()->height() - bottomEdge->height()); bottomEdge->move(position); diff --git a/src/modules/im/src/widget/notificationscrollarea.h b/src/modules/im/src/widget/notificationscrollarea.h index 4a4c9f6f..882f1aa4 100644 --- a/src/modules/im/src/widget/notificationscrollarea.h +++ b/src/modules/im/src/widget/notificationscrollarea.h @@ -13,14 +13,13 @@ #ifndef NOTIFICATIONSCROLLAREA_H #define NOTIFICATIONSCROLLAREA_H -#include "tool/adjustingscrollarea.h" #include +#include "tool/adjustingscrollarea.h" class GenericChatroomWidget; class NotificationEdgeWidget; -class NotificationScrollArea final : public AdjustingScrollArea -{ +class NotificationScrollArea final : public AdjustingScrollArea { public: explicit NotificationScrollArea(QWidget* parent = nullptr); @@ -37,12 +36,7 @@ private slots: void findPreviousWidget(); private: - enum Visibility : uint8_t - { - Visible, - Above, - Below - }; + enum Visibility : uint8_t { Visible, Above, Below }; Visibility widgetVisible(QWidget* widget) const; void recalculateTopEdge(); void recalculateBottomEdge(); @@ -54,4 +48,4 @@ private slots: size_t referencesBelow = 0; }; -#endif // NOTIFICATIONSCROLLAREA_H +#endif // NOTIFICATIONSCROLLAREA_H diff --git a/src/modules/im/src/widget/passwordedit.cpp b/src/modules/im/src/widget/passwordedit.cpp index a5a8b2fc..3cdb8554 100644 --- a/src/modules/im/src/widget/passwordedit.cpp +++ b/src/modules/im/src/widget/passwordedit.cpp @@ -23,10 +23,7 @@ PasswordEdit::EventHandler* PasswordEdit::eventHandler{nullptr}; -PasswordEdit::PasswordEdit(QWidget* parent) - : QLineEdit(parent) - , action(new QAction(this)) -{ +PasswordEdit::PasswordEdit(QWidget* parent) : QLineEdit(parent), action(new QAction(this)) { setEchoMode(QLineEdit::Password); #ifdef ENABLE_CAPSLOCK_INDICATOR @@ -36,23 +33,16 @@ PasswordEdit::PasswordEdit(QWidget* parent) #endif } -PasswordEdit::~PasswordEdit() -{ - unregisterHandler(); -} +PasswordEdit::~PasswordEdit() { unregisterHandler(); } -void PasswordEdit::registerHandler() -{ +void PasswordEdit::registerHandler() { #ifdef ENABLE_CAPSLOCK_INDICATOR - if (!eventHandler) - eventHandler = new EventHandler(); - if (!eventHandler->actions.contains(action)) - eventHandler->actions.append(action); + if (!eventHandler) eventHandler = new EventHandler(); + if (!eventHandler->actions.contains(action)) eventHandler->actions.append(action); #endif } -void PasswordEdit::unregisterHandler() -{ +void PasswordEdit::unregisterHandler() { #ifdef ENABLE_CAPSLOCK_INDICATOR int idx; @@ -66,49 +56,40 @@ void PasswordEdit::unregisterHandler() #endif } -void PasswordEdit::showEvent(QShowEvent*) -{ +void PasswordEdit::showEvent(QShowEvent*) { #ifdef ENABLE_CAPSLOCK_INDICATOR action->setVisible(Platform::capsLockEnabled()); #endif registerHandler(); } -void PasswordEdit::hideEvent(QHideEvent*) -{ - unregisterHandler(); -} +void PasswordEdit::hideEvent(QHideEvent*) { unregisterHandler(); } #ifdef ENABLE_CAPSLOCK_INDICATOR -PasswordEdit::EventHandler::EventHandler() -{ +PasswordEdit::EventHandler::EventHandler() { QCoreApplication::instance()->installEventFilter(this); } -PasswordEdit::EventHandler::~EventHandler() -{ +PasswordEdit::EventHandler::~EventHandler() { QCoreApplication::instance()->removeEventFilter(this); } -void PasswordEdit::EventHandler::updateActions() -{ +void PasswordEdit::EventHandler::updateActions() { bool caps = Platform::capsLockEnabled(); - for (QAction* action : actions) - action->setVisible(caps); + for (QAction* action : actions) action->setVisible(caps); } -bool PasswordEdit::EventHandler::eventFilter(QObject* obj, QEvent* event) -{ +bool PasswordEdit::EventHandler::eventFilter(QObject* obj, QEvent* event) { switch (event->type()) { - case QEvent::WindowActivate: - case QEvent::KeyRelease: - updateActions(); - break; - default: - break; + case QEvent::WindowActivate: + case QEvent::KeyRelease: + updateActions(); + break; + default: + break; } return QObject::eventFilter(obj, event); } -#endif // ENABLE_CAPSLOCK_INDICATOR +#endif // ENABLE_CAPSLOCK_INDICATOR diff --git a/src/modules/im/src/widget/passwordedit.h b/src/modules/im/src/widget/passwordedit.h index 4a239c64..e88d5f10 100644 --- a/src/modules/im/src/widget/passwordedit.h +++ b/src/modules/im/src/widget/passwordedit.h @@ -16,8 +16,7 @@ #include #include -class PasswordEdit : public QLineEdit -{ +class PasswordEdit : public QLineEdit { Q_OBJECT public: explicit PasswordEdit(QWidget* parent); @@ -28,8 +27,7 @@ class PasswordEdit : public QLineEdit virtual void hideEvent(QHideEvent* event); private: - class EventHandler : QObject - { + class EventHandler : QObject { public: QVector actions; @@ -47,4 +45,4 @@ class PasswordEdit : public QLineEdit static EventHandler* eventHandler; }; -#endif // PASSWORDEDIT_H +#endif // PASSWORDEDIT_H diff --git a/src/modules/im/src/widget/qrwidget.cpp b/src/modules/im/src/widget/qrwidget.cpp index 5949e83c..c765244b 100644 --- a/src/modules/im/src/widget/qrwidget.cpp +++ b/src/modules/im/src/widget/qrwidget.cpp @@ -10,13 +10,12 @@ * See the Mulan PubL v2 for more details. */ - #include "qrwidget.h" +#include #include #include #include #include -#include #ifdef Q_OS_WIN32 #include @@ -30,8 +29,8 @@ */ QRWidget::QRWidget(QWidget* parent) - : QWidget(parent) - , data("0") + : QWidget(parent) + , data("0") // Note: The encoding fails with empty string so I just default to something else. // Use the setQRData() call to change this. { @@ -41,36 +40,27 @@ QRWidget::QRWidget(QWidget* parent) image = new QImage(size, QImage::Format_RGB32); } -QRWidget::~QRWidget() -{ - delete image; -} +QRWidget::~QRWidget() { delete image; } -void QRWidget::setQRData(const QString& data) -{ +void QRWidget::setQRData(const QString& data) { this->data = data; paintImage(); } -QImage* QRWidget::getImage() -{ - return image; -} +QImage* QRWidget::getImage() { return image; } /** * @brief QRWidget::saveImage * @param path Full path to the file with extension. * @return indicate if saving was successful. */ -bool QRWidget::saveImage(QString path) -{ +bool QRWidget::saveImage(QString path) { // 0 - image format same as file extension, 75-quality, png file is ~6.3kb return image->save(path, nullptr, 75); } // http://stackoverflow.com/questions/21400254/how-to-draw-a-qr-code-with-qt-in-native-c-c -void QRWidget::paintImage() -{ +void QRWidget::paintImage() { QPainter painter(image); // NOTE: I have hardcoded some parameters here that would make more sense as variables. // ECLEVEL_M is much faster recognizable by barcodescanner any any other type diff --git a/src/modules/im/src/widget/qrwidget.h b/src/modules/im/src/widget/qrwidget.h index a62e6353..0221cfab 100644 --- a/src/modules/im/src/widget/qrwidget.h +++ b/src/modules/im/src/widget/qrwidget.h @@ -10,14 +10,12 @@ * See the Mulan PubL v2 for more details. */ - #ifndef QRWIDGET_H #define QRWIDGET_H #include -class QRWidget : public QWidget -{ +class QRWidget : public QWidget { Q_OBJECT public: @@ -34,4 +32,4 @@ class QRWidget : public QWidget QSize size; }; -#endif // QRWIDGET_H +#endif // QRWIDGET_H diff --git a/src/modules/im/src/widget/searchform.cpp b/src/modules/im/src/widget/searchform.cpp index 3f1bbfba..af9d4ffd 100644 --- a/src/modules/im/src/widget/searchform.cpp +++ b/src/modules/im/src/widget/searchform.cpp @@ -14,29 +14,27 @@ #include "form/searchsettingsform.h" #include "src/lib/settings/style.h" -#include #include -#include -#include #include +#include +#include +#include #include static std::array STATE_NAME = { - QString{}, - QStringLiteral("green"), - QStringLiteral("red"), + QString{}, + QStringLiteral("green"), + QStringLiteral("red"), }; - -SearchForm::SearchForm(QWidget* parent) : QWidget(parent) -{ +SearchForm::SearchForm(QWidget* parent) : QWidget(parent) { using namespace SearchFormUI; QVBoxLayout* layout = new QVBoxLayout(); QHBoxLayout* layoutNavigation = new QHBoxLayout(); QHBoxLayout* layoutMessage = new QHBoxLayout(); - QSpacerItem *lSpacer = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Ignored); - QSpacerItem *rSpacer = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Ignored); + QSpacerItem* lSpacer = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Ignored); + QSpacerItem* rSpacer = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Ignored); searchLine = new SearchFormUI::LineEdit(); settings = new SearchSettingsForm(); messageLabel = new QLabel(); @@ -88,33 +86,17 @@ SearchForm::SearchForm(QWidget* parent) : QWidget(parent) connect(settings, &SearchSettingsForm::updateSettings, this, &SearchForm::changedState); } -void SearchForm::removeSearchPhrase() -{ - searchLine->setText(""); -} +void SearchForm::removeSearchPhrase() { searchLine->setText(""); } -QString SearchForm::getSearchPhrase() const -{ - return searchPhrase; -} +QString SearchForm::getSearchPhrase() const { return searchPhrase; } -ParameterSearch SearchForm::getParameterSearch() -{ - return parameter; -} +ParameterSearch SearchForm::getParameterSearch() { return parameter; } -void SearchForm::setFocusEditor() -{ - searchLine->setFocus(); -} +void SearchForm::setFocusEditor() { searchLine->setFocus(); } -void SearchForm::insertEditor(const QString &text) -{ - searchLine->insert(text); -} +void SearchForm::insertEditor(const QString& text) { searchLine->insert(text); } -void SearchForm::reloadTheme() -{ +void SearchForm::reloadTheme() { settingsButton->setStyleSheet(Style::getStylesheet(QStringLiteral("chatForm/buttons.css"))); upButton->setStyleSheet(Style::getStylesheet(QStringLiteral("chatForm/buttons.css"))); downButton->setStyleSheet(Style::getStylesheet(QStringLiteral("chatForm/buttons.css"))); @@ -124,14 +106,12 @@ void SearchForm::reloadTheme() settings->reloadTheme(); } -void SearchForm::showEvent(QShowEvent* event) -{ +void SearchForm::showEvent(QShowEvent* event) { QWidget::showEvent(event); emit visibleChanged(); } -QPushButton *SearchForm::createButton(const QString& name, const QString& state) -{ +QPushButton* SearchForm::createButton(const QString& name, const QString& state) { QPushButton* btn = new QPushButton(); btn->setAttribute(Qt::WA_LayoutUsesWidgetRect); btn->setObjectName(name); @@ -141,8 +121,7 @@ QPushButton *SearchForm::createButton(const QString& name, const QString& state) return btn; } -ParameterSearch SearchForm::getAndCheckParametrSearch() -{ +ParameterSearch SearchForm::getAndCheckParametrSearch() { if (isActiveSettings) { auto sendParam = settings->getParameterSearch(); if (!isChangedPhrase && !sendParam.isUpdate) { @@ -158,24 +137,21 @@ ParameterSearch SearchForm::getAndCheckParametrSearch() return ParameterSearch(); } -void SearchForm::setStateName(QPushButton *btn, ToolButtonState state) -{ +void SearchForm::setStateName(QPushButton* btn, ToolButtonState state) { const auto index = static_cast(state); btn->setProperty("state", STATE_NAME[index]); btn->setStyleSheet(Style::getStylesheet(QStringLiteral("chatForm/buttons.css"))); btn->setEnabled(index != 0); } -void SearchForm::useBeginState() -{ +void SearchForm::useBeginState() { setStateName(upButton, ToolButtonState::Common); setStateName(downButton, ToolButtonState::Common); messageLabel->setVisible(false); isPrevSearch = false; } -void SearchForm::changedSearchPhrase(const QString& text) -{ +void SearchForm::changedSearchPhrase(const QString& text) { useBeginState(); if (searchPhrase == text) { @@ -200,8 +176,7 @@ void SearchForm::changedSearchPhrase(const QString& text) } } -void SearchForm::clickedUp() -{ +void SearchForm::clickedUp() { if (downButton->isEnabled()) { isPrevSearch = false; } else { @@ -218,8 +193,7 @@ void SearchForm::clickedUp() } } -void SearchForm::clickedDown() -{ +void SearchForm::clickedDown() { if (upButton->isEnabled()) { isPrevSearch = false; } else { @@ -236,21 +210,18 @@ void SearchForm::clickedDown() } } -void SearchForm::clickedHide() -{ +void SearchForm::clickedHide() { hide(); emit visibleChanged(); } -void SearchForm::clickedStart() -{ +void SearchForm::clickedStart() { changedState(false); isSearchInBegin = true; emit searchInBegin(searchPhrase, getAndCheckParametrSearch()); } -void SearchForm::clickedSearch() -{ +void SearchForm::clickedSearch() { isActiveSettings = !isActiveSettings; settings->setVisible(isActiveSettings); useBeginState(); @@ -263,8 +234,7 @@ void SearchForm::clickedSearch() } } -void SearchForm::changedState(bool isUpdate) -{ +void SearchForm::changedState(bool isUpdate) { if (isUpdate) { startButton->setHidden(false); upButton->setHidden(true); @@ -278,8 +248,7 @@ void SearchForm::changedState(bool isUpdate) useBeginState(); } -void SearchForm::showMessageNotFound(SearchDirection direction) -{ +void SearchForm::showMessageNotFound(SearchDirection direction) { if (isSearchInBegin) { if (parameter.period == PeriodSearch::AfterDate) { setStateName(downButton, ToolButtonState::Disabled); @@ -302,12 +271,9 @@ void SearchForm::showMessageNotFound(SearchDirection direction) using namespace SearchFormUI; -LineEdit::LineEdit(QWidget* parent) : QLineEdit(parent) -{ -} +LineEdit::LineEdit(QWidget* parent) : QLineEdit(parent) {} -void LineEdit::keyPressEvent(QKeyEvent* event) -{ +void LineEdit::keyPressEvent(QKeyEvent* event) { int key = event->key(); if ((key == Qt::Key_Enter || key == Qt::Key_Return)) { @@ -322,5 +288,3 @@ void LineEdit::keyPressEvent(QKeyEvent* event) QLineEdit::keyPressEvent(event); } - - diff --git a/src/modules/im/src/widget/searchform.h b/src/modules/im/src/widget/searchform.h index 74d095a6..16f28c0a 100644 --- a/src/modules/im/src/widget/searchform.h +++ b/src/modules/im/src/widget/searchform.h @@ -13,26 +13,24 @@ #ifndef SEARCHFORM_H #define SEARCHFORM_H -#include #include +#include #include "searchtypes.h" class QPushButton; class QLabel; class SearchSettingsForm; -namespace SearchFormUI -{ - class LineEdit; +namespace SearchFormUI { +class LineEdit; } -class SearchForm final : public QWidget -{ +class SearchForm final : public QWidget { Q_OBJECT public: enum class ToolButtonState { - Disabled = 0, // Grey - Common = 1, // Green - Active = 2, // Red + Disabled = 0, // Grey + Common = 1, // Green + Active = 2, // Red }; explicit SearchForm(QWidget* parent = nullptr); @@ -40,7 +38,7 @@ class SearchForm final : public QWidget QString getSearchPhrase() const; ParameterSearch getParameterSearch(); void setFocusEditor(); - void insertEditor(const QString &text); + void insertEditor(const QString& text); void reloadTheme(); protected: @@ -58,7 +56,7 @@ class SearchForm final : public QWidget QPushButton* downButton; QPushButton* hideButton; QPushButton* startButton; - SearchFormUI::LineEdit *searchLine; + SearchFormUI::LineEdit* searchLine; SearchSettingsForm* settings; QLabel* messageLabel; @@ -89,23 +87,21 @@ public slots: void visibleChanged(); }; -namespace SearchFormUI -{ +namespace SearchFormUI { class LineEdit : public QLineEdit { Q_OBJECT - public: - LineEdit(QWidget *parent = nullptr); +public: + LineEdit(QWidget* parent = nullptr); - protected: - virtual void keyPressEvent(QKeyEvent *event) final override; +protected: + virtual void keyPressEvent(QKeyEvent* event) final override; - signals: +signals: void clickEnter(); void clickShiftEnter(); void clickEsc(); }; -} - +} // namespace SearchFormUI -#endif // SEARCHFORM_H +#endif // SEARCHFORM_H diff --git a/src/modules/im/src/widget/searchtypes.h b/src/modules/im/src/widget/searchtypes.h index 8e922eb0..e1870483 100644 --- a/src/modules/im/src/widget/searchtypes.h +++ b/src/modules/im/src/widget/searchtypes.h @@ -25,18 +25,9 @@ enum class FilterSearch { RegisterAndRegular }; -enum class PeriodSearch { - None, - WithTheEnd, - WithTheFirst, - AfterDate, - BeforeDate -}; +enum class PeriodSearch { None, WithTheEnd, WithTheFirst, AfterDate, BeforeDate }; -enum class SearchDirection { - Up, - Down -}; +enum class SearchDirection { Up, Down }; struct ParameterSearch { FilterSearch filter{FilterSearch::None}; @@ -44,26 +35,22 @@ struct ParameterSearch { QDate date; bool isUpdate{false}; - bool operator ==(const ParameterSearch& other) { - return filter == other.filter && - period == other.period && - date == other.date; + bool operator==(const ParameterSearch& other) { + return filter == other.filter && period == other.period && date == other.date; } - bool operator !=(const ParameterSearch& other) { - return !(*this == other); - } + bool operator!=(const ParameterSearch& other) { return !(*this == other); } }; class SearchExtraFunctions { public: /** - * @brief generateFilterWordsOnly generate string for filter "Whole words only" for correct search phrase - * containing symbols "\[]/^$.|?*+(){}" + * @brief generateFilterWordsOnly generate string for filter "Whole words only" for correct + * search phrase containing symbols "\[]/^$.|?*+(){}" * @param phrase for search * @return new phrase for search */ - static QString generateFilterWordsOnly(const QString &phrase) { + static QString generateFilterWordsOnly(const QString& phrase) { QString filter = QRegularExpression::escape(phrase); const QString symbols = QStringLiteral("\\[]/^$.|?*+(){}"); @@ -87,4 +74,4 @@ class SearchExtraFunctions { } }; -#endif //SEARCHTYPES_H +#endif // SEARCHTYPES_H diff --git a/src/modules/im/src/widget/splitterrestorer.cpp b/src/modules/im/src/widget/splitterrestorer.cpp index c58f9f2b..a479c1f4 100644 --- a/src/modules/im/src/widget/splitterrestorer.cpp +++ b/src/modules/im/src/widget/splitterrestorer.cpp @@ -31,9 +31,7 @@ static int defaultWidth = 0; */ const static int leftWidthPercent = 33; -SplitterRestorer::SplitterRestorer(QSplitter* splitter) - : splitter{splitter} -{ +SplitterRestorer::SplitterRestorer(QSplitter* splitter) : splitter{splitter} { if (defaultWidth == 0) { defaultWidth = QSplitter().handleWidth(); } @@ -45,10 +43,10 @@ SplitterRestorer::SplitterRestorer(QSplitter* splitter) * @param state State saved by QSplitter::saveState() * @param windowSize Widnow size (used to calculate splitter size) */ -void SplitterRestorer::restore(const QByteArray& state, const QSize& windowSize) -{ - bool brokenSplitter = !splitter->restoreState(state) || splitter->orientation() != Qt::Horizontal - || splitter->handleWidth() > defaultWidth; +void SplitterRestorer::restore(const QByteArray& state, const QSize& windowSize) { + bool brokenSplitter = !splitter->restoreState(state) || + splitter->orientation() != Qt::Horizontal || + splitter->handleWidth() > defaultWidth; if (splitter->count() == 2 && brokenSplitter) { splitter->setOrientation(Qt::Horizontal); diff --git a/src/modules/im/src/widget/splitterrestorer.h b/src/modules/im/src/widget/splitterrestorer.h index c604bc0b..28fbfa67 100644 --- a/src/modules/im/src/widget/splitterrestorer.h +++ b/src/modules/im/src/widget/splitterrestorer.h @@ -17,8 +17,7 @@ class QSize; class QSplitter; class QByteArray; -class SplitterRestorer -{ +class SplitterRestorer { public: explicit SplitterRestorer(QSplitter* splitter); void restore(const QByteArray& state, const QSize& windowSize); @@ -27,4 +26,4 @@ class SplitterRestorer QSplitter* splitter; }; -#endif // SPLITTERRESTORER_H +#endif // SPLITTERRESTORER_H diff --git a/src/modules/im/src/widget/tool/activatedialog.cpp b/src/modules/im/src/widget/tool/activatedialog.cpp index 4e007ae0..70444eca 100644 --- a/src/modules/im/src/widget/tool/activatedialog.cpp +++ b/src/modules/im/src/widget/tool/activatedialog.cpp @@ -10,17 +10,12 @@ * See the Mulan PubL v2 for more details. */ - #include "activatedialog.h" #include -ActivateDialog::ActivateDialog(QWidget* parent, Qt::WindowFlags f) - : QDialog(parent, f) -{ -} +ActivateDialog::ActivateDialog(QWidget* parent, Qt::WindowFlags f) : QDialog(parent, f) {} -bool ActivateDialog::event(QEvent* event) -{ +bool ActivateDialog::event(QEvent* event) { if (event->type() == QEvent::WindowActivate || event->type() == QEvent::WindowStateChange) emit windowStateChanged(windowState()); diff --git a/src/modules/im/src/widget/tool/activatedialog.h b/src/modules/im/src/widget/tool/activatedialog.h index ec315516..0c4a6f12 100644 --- a/src/modules/im/src/widget/tool/activatedialog.h +++ b/src/modules/im/src/widget/tool/activatedialog.h @@ -15,8 +15,7 @@ #include -class ActivateDialog : public QDialog -{ +class ActivateDialog : public QDialog { Q_OBJECT public: #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) @@ -30,4 +29,4 @@ class ActivateDialog : public QDialog void windowStateChanged(Qt::WindowStates state); }; -#endif // ACTIVATEDIALOG_H +#endif // ACTIVATEDIALOG_H diff --git a/src/modules/im/src/widget/tool/adjustingscrollarea.cpp b/src/modules/im/src/widget/tool/adjustingscrollarea.cpp index 4ac4ba8c..6a26efe2 100644 --- a/src/modules/im/src/widget/tool/adjustingscrollarea.cpp +++ b/src/modules/im/src/widget/tool/adjustingscrollarea.cpp @@ -17,25 +17,19 @@ #include #include -AdjustingScrollArea::AdjustingScrollArea(QWidget* parent) - : QScrollArea(parent) -{ -} +AdjustingScrollArea::AdjustingScrollArea(QWidget* parent) : QScrollArea(parent) {} -void AdjustingScrollArea::resizeEvent(QResizeEvent* ev) -{ +void AdjustingScrollArea::resizeEvent(QResizeEvent* ev) { int scrollBarWidth = - verticalScrollBar()->isVisible() ? verticalScrollBar()->sizeHint().width() : 0; + verticalScrollBar()->isVisible() ? verticalScrollBar()->sizeHint().width() : 0; - if (layoutDirection() == Qt::RightToLeft) - setViewportMargins(-scrollBarWidth, 0, 0, 0); + if (layoutDirection() == Qt::RightToLeft) setViewportMargins(-scrollBarWidth, 0, 0, 0); updateGeometry(); QScrollArea::resizeEvent(ev); } -QSize AdjustingScrollArea::sizeHint() const -{ +QSize AdjustingScrollArea::sizeHint() const { if (widget()) { int scrollbarWidth = verticalScrollBar()->isVisible() ? verticalScrollBar()->width() : 0; return widget()->sizeHint() + QSize(scrollbarWidth, 0); diff --git a/src/modules/im/src/widget/tool/adjustingscrollarea.h b/src/modules/im/src/widget/tool/adjustingscrollarea.h index 787edb58..19f5a038 100644 --- a/src/modules/im/src/widget/tool/adjustingscrollarea.h +++ b/src/modules/im/src/widget/tool/adjustingscrollarea.h @@ -15,8 +15,7 @@ #include -class AdjustingScrollArea : public QScrollArea -{ +class AdjustingScrollArea : public QScrollArea { Q_OBJECT public: explicit AdjustingScrollArea(QWidget* parent = nullptr); @@ -27,4 +26,4 @@ class AdjustingScrollArea : public QScrollArea virtual QSize sizeHint() const final override; }; -#endif // ADJUSTINGSCROLLAREA_H +#endif // ADJUSTINGSCROLLAREA_H diff --git a/src/modules/im/src/widget/tool/callconfirmwidget.cpp b/src/modules/im/src/widget/tool/callconfirmwidget.cpp index 832748af..a62a48c8 100644 --- a/src/modules/im/src/widget/tool/callconfirmwidget.cpp +++ b/src/modules/im/src/widget/tool/callconfirmwidget.cpp @@ -11,8 +11,7 @@ */ #include "callconfirmwidget.h" -#include "src/lib/settings/style.h" -#include "src/widget/widget.h" +#include #include #include #include @@ -24,7 +23,8 @@ #include #include #include -#include +#include "src/lib/settings/style.h" +#include "src/widget/widget.h" /** * @class CallConfirmWidget @@ -44,15 +44,14 @@ */ CallConfirmWidget::CallConfirmWidget(const QWidget* anchor) - : QWidget() - , anchor(anchor) - , rectW{120} - , rectH{85} - , spikeW{30} - , spikeH{15} - , roundedFactor{20} - , rectRatio(static_cast(rectH) / static_cast(rectW)) -{ + : QWidget() + , anchor(anchor) + , rectW{120} + , rectH{85} + , spikeW{30} + , spikeH{15} + , roundedFactor{20} + , rectRatio(static_cast(rectH) / static_cast(rectW)) { setWindowFlags(Qt::SubWindow); setAttribute(Qt::WA_DeleteOnClose); @@ -69,12 +68,13 @@ CallConfirmWidget::CallConfirmWidget(const QWidget* anchor) // Note: At the moment this may not work properly. For languages written // from right to left, there is no translation for the phrase "Incoming call...". // In this situation, the phrase "Incoming call..." looks as "...oming call..." - Qt::TextElideMode elideMode = - (QGuiApplication::layoutDirection() == Qt::LeftToRight) ? Qt::ElideRight : Qt::ElideLeft; + Qt::TextElideMode elideMode = (QGuiApplication::layoutDirection() == Qt::LeftToRight) + ? Qt::ElideRight + : Qt::ElideLeft; int marginSize = 12; QFontMetrics fontMetrics(callLabel->font()); QString elidedText = - fontMetrics.elidedText(callLabel->text(), elideMode, rectW - marginSize * 2 - 4); + fontMetrics.elidedText(callLabel->text(), elideMode, rectW - marginSize * 2 - 4); callLabel->setText(elidedText); QDialogButtonBox* buttonBox = new QDialogButtonBox(Qt::Horizontal, this); @@ -106,22 +106,19 @@ CallConfirmWidget::CallConfirmWidget(const QWidget* anchor) /** * @brief Recalculate our positions to track the anchor */ -void CallConfirmWidget::reposition() -{ - if (parentWidget()) - parentWidget()->removeEventFilter(this); +void CallConfirmWidget::reposition() { + if (parentWidget()) parentWidget()->removeEventFilter(this); setParent(anchor->window()); parentWidget()->installEventFilter(this); QWidget* w = anchor->window(); - QPoint pos = anchor->mapToGlobal({(anchor->width() - rectW) / 2, anchor->height()}) - - w->mapToGlobal({0, 0}); + 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 int xOverflow = 0; - if (pos.x() + rectW > w->width()) - xOverflow = pos.x() + rectW - w->width(); + if (pos.x() + rectW > w->width()) xOverflow = pos.x() + rectW - w->width(); pos.rx() -= xOverflow; mainRect = {0, spikeH, rectW, rectH}; @@ -134,8 +131,7 @@ void CallConfirmWidget::reposition() update(); } -void CallConfirmWidget::paintEvent(QPaintEvent*) -{ +void CallConfirmWidget::paintEvent(QPaintEvent*) { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); painter.setBrush(brush); @@ -145,8 +141,7 @@ void CallConfirmWidget::paintEvent(QPaintEvent*) painter.drawPolygon(spikePoly); } -void CallConfirmWidget::showEvent(QShowEvent*) -{ +void CallConfirmWidget::showEvent(QShowEvent*) { // Kriby: Legacy comment, is this still true? // If someone does show() from Widget or lower, the event will reach us // because it's our parent, and we could show up in the wrong form. @@ -156,18 +151,14 @@ void CallConfirmWidget::showEvent(QShowEvent*) update(); } -void CallConfirmWidget::hideEvent(QHideEvent*) -{ - if (parentWidget()) - parentWidget()->removeEventFilter(this); +void CallConfirmWidget::hideEvent(QHideEvent*) { + if (parentWidget()) parentWidget()->removeEventFilter(this); setParent(nullptr); } -bool CallConfirmWidget::eventFilter(QObject*, QEvent* event) -{ - if (event->type() == QEvent::Resize) - reposition(); +bool CallConfirmWidget::eventFilter(QObject*, QEvent* event) { + if (event->type() == QEvent::Resize) reposition(); return false; } diff --git a/src/modules/im/src/widget/tool/callconfirmwidget.h b/src/modules/im/src/widget/tool/callconfirmwidget.h index 206cbf91..b651d682 100644 --- a/src/modules/im/src/widget/tool/callconfirmwidget.h +++ b/src/modules/im/src/widget/tool/callconfirmwidget.h @@ -10,7 +10,6 @@ * See the Mulan PubL v2 for more details. */ - #ifndef CALLCONFIRMWIDGET_H #define CALLCONFIRMWIDGET_H @@ -22,8 +21,7 @@ class QPaintEvent; class QShowEvent; -class CallConfirmWidget final : public QWidget -{ +class CallConfirmWidget final : public QWidget { Q_OBJECT public: explicit CallConfirmWidget(const QWidget* anchor); @@ -54,4 +52,4 @@ public slots: const qreal rectRatio; }; -#endif // CALLCONFIRMWIDGET_H +#endif // CALLCONFIRMWIDGET_H diff --git a/src/modules/im/src/widget/tool/chattextedit.cpp b/src/modules/im/src/widget/tool/chattextedit.cpp index 932ba4db..a72fcf12 100644 --- a/src/modules/im/src/widget/tool/chattextedit.cpp +++ b/src/modules/im/src/widget/tool/chattextedit.cpp @@ -19,28 +19,21 @@ #include #include -ChatTextEdit::ChatTextEdit(QWidget* parent) - : QTextEdit(parent) -{ - +ChatTextEdit::ChatTextEdit(QWidget* parent) : QTextEdit(parent) { setAcceptRichText(false); setAcceptDrops(false); - setAttribute(Qt::WA_InputMethodEnabled,true); - + setAttribute(Qt::WA_InputMethodEnabled, true); settings::Translator::registerHandler([this] { retranslateUi(); }, this); retranslateUi(); } -ChatTextEdit::~ChatTextEdit() -{ - settings::Translator::unregister(this); -} +ChatTextEdit::~ChatTextEdit() { settings::Translator::unregister(this); } -void ChatTextEdit::keyPressEvent(QKeyEvent* event) -{ +void ChatTextEdit::keyPressEvent(QKeyEvent* event) { int key = event->key(); - if ((key == Qt::Key_Enter || key == Qt::Key_Return) && !(event->modifiers() & Qt::ShiftModifier)) { + if ((key == Qt::Key_Enter || key == Qt::Key_Return) && + !(event->modifiers() & Qt::ShiftModifier)) { emit enterPressed(); return; } @@ -66,23 +59,13 @@ void ChatTextEdit::keyPressEvent(QKeyEvent* event) QTextEdit::keyPressEvent(event); } -void ChatTextEdit::setLastMessage(QString lm) -{ - lastMessage = lm; -} +void ChatTextEdit::setLastMessage(QString lm) { lastMessage = lm; } -void ChatTextEdit::retranslateUi() -{ - setPlaceholderText(tr("Type your message here...")); -} +void ChatTextEdit::retranslateUi() { setPlaceholderText(tr("Type your message here...")); } -void ChatTextEdit::sendKeyEvent(QKeyEvent* event) -{ - emit keyPressEvent(event); -} +void ChatTextEdit::sendKeyEvent(QKeyEvent* event) { emit keyPressEvent(event); } -bool ChatTextEdit::pasteIfImage(QKeyEvent* event) -{ +bool ChatTextEdit::pasteIfImage(QKeyEvent* event) { const QClipboard* const clipboard = QApplication::clipboard(); if (!clipboard) { return false; @@ -101,4 +84,3 @@ bool ChatTextEdit::pasteIfImage(QKeyEvent* event) emit pasteImage(pixmap); return true; } - diff --git a/src/modules/im/src/widget/tool/chattextedit.h b/src/modules/im/src/widget/tool/chattextedit.h index b9d40568..5970389c 100644 --- a/src/modules/im/src/widget/tool/chattextedit.h +++ b/src/modules/im/src/widget/tool/chattextedit.h @@ -15,8 +15,7 @@ #include -class ChatTextEdit final : public QTextEdit -{ +class ChatTextEdit final : public QTextEdit { Q_OBJECT public: explicit ChatTextEdit(QWidget* parent = nullptr); @@ -41,4 +40,4 @@ class ChatTextEdit final : public QTextEdit QString lastMessage; }; -#endif // CHATTEXTEDIT_H +#endif // CHATTEXTEDIT_H diff --git a/src/modules/im/src/widget/tool/croppinglabel.cpp b/src/modules/im/src/widget/tool/croppinglabel.cpp index bf236387..4113581f 100644 --- a/src/modules/im/src/widget/tool/croppinglabel.cpp +++ b/src/modules/im/src/widget/tool/croppinglabel.cpp @@ -21,124 +21,126 @@ class LineEdit : public QLineEdit { public: - explicit LineEdit(QWidget *parent = nullptr) : QLineEdit(parent) {} + explicit LineEdit(QWidget* parent = nullptr) : QLineEdit(parent) {} protected: - void keyPressEvent(QKeyEvent *event) override { - if (event->key() == Qt::Key_Escape) { - undo(); - clearFocus(); - } + void keyPressEvent(QKeyEvent* event) override { + if (event->key() == Qt::Key_Escape) { + undo(); + clearFocus(); + } - QLineEdit::keyPressEvent(event); - } + QLineEdit::keyPressEvent(event); + } }; -CroppingLabel::CroppingLabel(QWidget *parent) : QLabel(parent), - blockPaintEvents(false), - editable(false), - elideMode(Qt::ElideRight) // +CroppingLabel::CroppingLabel(QWidget* parent) + : QLabel(parent) + , blockPaintEvents(false) + , editable(false) + , elideMode(Qt::ElideRight) // { - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - textEdit = new LineEdit(this); - textEdit->hide(); - textEdit->setInputMethodHints(Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText | Qt::ImhPreferLatin); + textEdit = new LineEdit(this); + textEdit->hide(); + textEdit->setInputMethodHints(Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText | + Qt::ImhPreferLatin); - connect(textEdit, &QLineEdit::editingFinished, this, &CroppingLabel::editingFinished); + connect(textEdit, &QLineEdit::editingFinished, this, &CroppingLabel::editingFinished); } void CroppingLabel::editBegin() { - showTextEdit(); - textEdit->selectAll(); + showTextEdit(); + textEdit->selectAll(); } void CroppingLabel::setEditable(bool editable) { - this->editable = editable; + this->editable = editable; - if (editable) - setCursor(Qt::PointingHandCursor); - else - unsetCursor(); + if (editable) + setCursor(Qt::PointingHandCursor); + else + unsetCursor(); } void CroppingLabel::setElideMode(Qt::TextElideMode elide) { elideMode = elide; } -void CroppingLabel::setText(const QString &text) { - origText = text.trimmed(); - setElidedText(); +void CroppingLabel::setText(const QString& text) { + origText = text.trimmed(); + setElidedText(); } -void CroppingLabel::setPlaceholderText(const QString &text) { - textEdit->setPlaceholderText(text); - setElidedText(); +void CroppingLabel::setPlaceholderText(const QString& text) { + textEdit->setPlaceholderText(text); + setElidedText(); } -void CroppingLabel::resizeEvent(QResizeEvent *ev) { - setElidedText(); - textEdit->resize(ev->size()); +void CroppingLabel::resizeEvent(QResizeEvent* ev) { + setElidedText(); + textEdit->resize(ev->size()); - QLabel::resizeEvent(ev); + QLabel::resizeEvent(ev); } QSize CroppingLabel::sizeHint() const { return QSize(0, QLabel::sizeHint().height()); } QSize CroppingLabel::minimumSizeHint() const { #if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)) - QSize s(fontMetrics().horizontalAdvance("..."), QLabel::minimumSizeHint().height()); + QSize s(fontMetrics().horizontalAdvance("..."), QLabel::minimumSizeHint().height()); #else - QSize s(fontMetrics().width("..."), QLabel::minimumSizeHint().height()); + QSize s(fontMetrics().width("..."), QLabel::minimumSizeHint().height()); #endif - const int v_margin = 2; // from Qt - const int h_margin = 4; // from Qt - s += QSize(h_margin, v_margin); - QStyleOptionFrame opt; - initStyleOption(&opt); - return (style()->sizeFromContents(QStyle::CT_LineEdit, &opt, s.expandedTo(QApplication::globalStrut()), this)); + const int v_margin = 2; // from Qt + const int h_margin = 4; // from Qt + s += QSize(h_margin, v_margin); + QStyleOptionFrame opt; + initStyleOption(&opt); + return (style()->sizeFromContents(QStyle::CT_LineEdit, &opt, + s.expandedTo(QApplication::globalStrut()), this)); } -void CroppingLabel::mouseReleaseEvent(QMouseEvent *e) { - if (editable) - showTextEdit(); +void CroppingLabel::mouseReleaseEvent(QMouseEvent* e) { + if (editable) showTextEdit(); - emit clicked(); + emit clicked(); - QLabel::mouseReleaseEvent(e); + QLabel::mouseReleaseEvent(e); } -void CroppingLabel::paintEvent(QPaintEvent *paintEvent) { - if (blockPaintEvents) { - paintEvent->ignore(); - return; - } - QLabel::paintEvent(paintEvent); +void CroppingLabel::paintEvent(QPaintEvent* paintEvent) { + if (blockPaintEvents) { + paintEvent->ignore(); + return; + } + QLabel::paintEvent(paintEvent); } void CroppingLabel::setElidedText() { - QString elidedText = fontMetrics().elidedText(origText, elideMode, width()); - if (elidedText != origText) - setToolTip(Qt::convertFromPlainText(origText, Qt::WhiteSpaceNormal)); - else - setToolTip(QString()); - if (!elidedText.isEmpty()) { - QLabel::setText(elidedText); - } else { - // NOTE: it would be nice if the label had custom styling when it was default - QLabel::setText(textEdit->placeholderText()); - } + QString elidedText = fontMetrics().elidedText(origText, elideMode, width()); + if (elidedText != origText) + setToolTip(Qt::convertFromPlainText(origText, Qt::WhiteSpaceNormal)); + else + setToolTip(QString()); + if (!elidedText.isEmpty()) { + QLabel::setText(elidedText); + } else { + // NOTE: it would be nice if the label had custom styling when it was default + QLabel::setText(textEdit->placeholderText()); + } } void CroppingLabel::hideTextEdit() { - textEdit->hide(); - blockPaintEvents = false; + textEdit->hide(); + blockPaintEvents = false; } void CroppingLabel::showTextEdit() { - blockPaintEvents = true; - textEdit->show(); - textEdit->setFocus(); - textEdit->setText(origText); - textEdit->setFocusPolicy(Qt::ClickFocus); + blockPaintEvents = true; + textEdit->show(); + textEdit->setFocus(); + textEdit->setText(origText); + textEdit->setFocusPolicy(Qt::ClickFocus); } /** @@ -148,21 +150,23 @@ void CroppingLabel::showTextEdit() { QString CroppingLabel::fullText() { return origText; } void CroppingLabel::minimizeMaximumWidth() { - // This function chooses the smallest possible maximum width. - // Text width + padding. Without padding, we'll have elipses. + // This function chooses the smallest possible maximum width. + // Text width + padding. Without padding, we'll have elipses. #if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)) - setMaximumWidth(fontMetrics().horizontalAdvance(origText) + fontMetrics().horizontalAdvance("...")); + setMaximumWidth(fontMetrics().horizontalAdvance(origText) + + fontMetrics().horizontalAdvance("...")); #else - setMaximumWidth(fontMetrics().width(origText) + fontMetrics().width("...")); + setMaximumWidth(fontMetrics().width(origText) + fontMetrics().width("...")); #endif } void CroppingLabel::editingFinished() { - hideTextEdit(); - QString newText = textEdit->text().trimmed().remove(QRegExp("[\\t\\n\\v\\f\\r\\x0000]")); + hideTextEdit(); - if (origText != newText) - emit editFinished(textEdit->text()); - - emit editRemoved(); + QString newText = textEdit->text(); + if (origText != newText) { + setText(newText); + emit editFinished(newText); + } + emit editRemoved(); } diff --git a/src/modules/im/src/widget/tool/croppinglabel.h b/src/modules/im/src/widget/tool/croppinglabel.h index bffdb475..2bb369ba 100644 --- a/src/modules/im/src/widget/tool/croppinglabel.h +++ b/src/modules/im/src/widget/tool/croppinglabel.h @@ -17,8 +17,7 @@ class QLineEdit; -class CroppingLabel : public QLabel -{ +class CroppingLabel : public QLabel { Q_OBJECT public: explicit CroppingLabel(QWidget* parent = nullptr); @@ -61,4 +60,4 @@ private slots: Qt::TextElideMode elideMode; }; -#endif // CROPPINGLABEL_H +#endif // CROPPINGLABEL_H diff --git a/src/modules/im/src/widget/tool/flyoutoverlaywidget.cpp b/src/modules/im/src/widget/tool/flyoutoverlaywidget.cpp index bf80fe67..7111c3d6 100644 --- a/src/modules/im/src/widget/tool/flyoutoverlaywidget.cpp +++ b/src/modules/im/src/widget/tool/flyoutoverlaywidget.cpp @@ -18,9 +18,7 @@ #include #include -FlyoutOverlayWidget::FlyoutOverlayWidget(QWidget* parent) - : QWidget(parent) -{ +FlyoutOverlayWidget::FlyoutOverlayWidget(QWidget* parent) : QWidget(parent) { setContentsMargins(0, 0, 0, 0); animation = new QPropertyAnimation(this, QByteArrayLiteral("flyoutPercent"), this); @@ -28,32 +26,21 @@ FlyoutOverlayWidget::FlyoutOverlayWidget(QWidget* parent) animation->setKeyValueAt(1, 1.0f); animation->setDuration(200); - connect(animation, &QAbstractAnimation::finished, this, &FlyoutOverlayWidget::finishedAnimation); + connect(animation, &QAbstractAnimation::finished, this, + &FlyoutOverlayWidget::finishedAnimation); setFlyoutPercent(0); hide(); } -FlyoutOverlayWidget::~FlyoutOverlayWidget() -{ -} +FlyoutOverlayWidget::~FlyoutOverlayWidget() {} -int FlyoutOverlayWidget::animationDuration() const -{ - return animation->duration(); -} +int FlyoutOverlayWidget::animationDuration() const { return animation->duration(); } -void FlyoutOverlayWidget::setAnimationDuration(int timeMs) -{ - animation->setDuration(timeMs); -} +void FlyoutOverlayWidget::setAnimationDuration(int timeMs) { animation->setDuration(timeMs); } -qreal FlyoutOverlayWidget::flyoutPercent() const -{ - return percent; -} +qreal FlyoutOverlayWidget::flyoutPercent() const { return percent; } -void FlyoutOverlayWidget::setFlyoutPercent(qreal progress) -{ +void FlyoutOverlayWidget::setFlyoutPercent(qreal progress) { percent = progress; QSize self = size(); @@ -62,51 +49,38 @@ void FlyoutOverlayWidget::setFlyoutPercent(qreal progress) setVisible(progress != 0); } -bool FlyoutOverlayWidget::isShown() const -{ - return (percent == 1); -} +bool FlyoutOverlayWidget::isShown() const { return (percent == 1); } -bool FlyoutOverlayWidget::isBeingAnimated() const -{ +bool FlyoutOverlayWidget::isBeingAnimated() const { return (animation->state() == QAbstractAnimation::Running); } -bool FlyoutOverlayWidget::isBeingShown() const -{ +bool FlyoutOverlayWidget::isBeingShown() const { return (isBeingAnimated() && animation->direction() == QAbstractAnimation::Forward); } -void FlyoutOverlayWidget::animateShow() -{ - if (percent == 1.0f) - return; +void FlyoutOverlayWidget::animateShow() { + if (percent == 1.0f) return; - if (animation->state() != QAbstractAnimation::Running) - this->startPos = pos(); + if (animation->state() != QAbstractAnimation::Running) this->startPos = pos(); startAnimation(true); } -void FlyoutOverlayWidget::animateHide() -{ - if (animation->state() != QAbstractAnimation::Running) - this->startPos = pos(); +void FlyoutOverlayWidget::animateHide() { + if (animation->state() != QAbstractAnimation::Running) this->startPos = pos(); startAnimation(false); } -void FlyoutOverlayWidget::finishedAnimation() -{ +void FlyoutOverlayWidget::finishedAnimation() { bool hide = (animation->direction() == QAbstractAnimation::Backward); // Delay it by a few frames to let the system catch up on rendering - if (hide) - QTimer::singleShot(50, this, SIGNAL(hidden())); + if (hide) QTimer::singleShot(50, this, SIGNAL(hidden())); } -void FlyoutOverlayWidget::startAnimation(bool forward) -{ +void FlyoutOverlayWidget::startAnimation(bool forward) { setAttribute(Qt::WA_TransparentForMouseEvents, !forward); animation->setDirection(forward ? QAbstractAnimation::Forward : QAbstractAnimation::Backward); animation->start(); diff --git a/src/modules/im/src/widget/tool/flyoutoverlaywidget.h b/src/modules/im/src/widget/tool/flyoutoverlaywidget.h index ae41d3c4..b6846559 100644 --- a/src/modules/im/src/widget/tool/flyoutoverlaywidget.h +++ b/src/modules/im/src/widget/tool/flyoutoverlaywidget.h @@ -17,8 +17,7 @@ class QPropertyAnimation; -class FlyoutOverlayWidget : public QWidget -{ +class FlyoutOverlayWidget : public QWidget { Q_OBJECT Q_PROPERTY(qreal flyoutPercent READ flyoutPercent WRITE setFlyoutPercent) public: @@ -52,4 +51,4 @@ class FlyoutOverlayWidget : public QWidget QPoint startPos; }; -#endif // FLYOUTOVERLAYWIDGET_HPP +#endif // FLYOUTOVERLAYWIDGET_HPP diff --git a/src/modules/im/src/widget/tool/friendrequestdialog.cpp b/src/modules/im/src/widget/tool/friendrequestdialog.cpp index 6fe7a78a..37ea9775 100644 --- a/src/modules/im/src/widget/tool/friendrequestdialog.cpp +++ b/src/modules/im/src/widget/tool/friendrequestdialog.cpp @@ -19,9 +19,9 @@ #include #include -FriendRequestDialog::FriendRequestDialog(QWidget* parent, const QString& userId, const QString& message) - : QDialog(parent) -{ +FriendRequestDialog::FriendRequestDialog(QWidget* parent, const QString& userId, + const QString& message) + : QDialog(parent) { setAttribute(Qt::WA_QuitOnClose, false); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); setWindowTitle(tr("IMFriend request", "Title of the window to aceept/deny a friend request")); @@ -35,7 +35,6 @@ FriendRequestDialog::FriendRequestDialog(QWidget* parent, const QString& userId, QPlainTextEdit* messageEdit = new QPlainTextEdit(message, this); messageEdit->setReadOnly(true); - QDialogButtonBox* buttonBox = new QDialogButtonBox(Qt::Horizontal, this); buttonBox->addButton(tr("Accept", "Accept a friend request"), QDialogButtonBox::AcceptRole); diff --git a/src/modules/im/src/widget/tool/friendrequestdialog.h b/src/modules/im/src/widget/tool/friendrequestdialog.h index 228aaee0..22024369 100644 --- a/src/modules/im/src/widget/tool/friendrequestdialog.h +++ b/src/modules/im/src/widget/tool/friendrequestdialog.h @@ -15,11 +15,10 @@ #include -class FriendRequestDialog : public QDialog -{ +class FriendRequestDialog : public QDialog { Q_OBJECT public: explicit FriendRequestDialog(QWidget* parent, const QString& userId, const QString& message); }; -#endif // FRIENDREQUESTDIALOG_HPP +#endif // FRIENDREQUESTDIALOG_HPP diff --git a/src/modules/im/src/widget/tool/identicon.cpp b/src/modules/im/src/widget/tool/identicon.cpp index 44a8c32b..4b5f23d3 100644 --- a/src/modules/im/src/widget/tool/identicon.cpp +++ b/src/modules/im/src/widget/tool/identicon.cpp @@ -53,8 +53,7 @@ * @brief Creates an Identicon, that visualizes a hash in graphical form. * @param data Data to visualize */ -Identicon::Identicon(const QByteArray& data) -{ +Identicon::Identicon(const QByteArray& data) { static_assert(Identicon::COLORS == 2, "Only two colors are implemented"); // hash with sha256 QByteArray hash = QCryptographicHash::hash(data, QCryptographicHash::Sha256); @@ -85,8 +84,7 @@ Identicon::Identicon(const QByteArray& data) * @param bytes Bytes to convert to a color * @return Value in the range of 0.0..1.0 */ -float Identicon::bytesToColor(QByteArray bytes) -{ +float Identicon::bytesToColor(QByteArray bytes) { static_assert(IDENTICON_COLOR_BYTES <= 8, "IDENTICON_COLOR max value is 8"); const uint8_t* const bytesChr = reinterpret_cast(bytes.constData()); assert(bytes.length() == IDENTICON_COLOR_BYTES); @@ -101,8 +99,8 @@ float Identicon::bytesToColor(QByteArray bytes) } // normalize to 0.0 ... 1.0 - return (static_cast(hue)) - / (static_cast(((static_cast(1)) << (8 * IDENTICON_COLOR_BYTES)) - 1)); + return (static_cast(hue)) / + (static_cast(((static_cast(1)) << (8 * IDENTICON_COLOR_BYTES)) - 1)); } /** @@ -111,8 +109,7 @@ float Identicon::bytesToColor(QByteArray bytes) * must be >= 1 * @return a QImage with the identicon */ -QImage Identicon::toImage(int scaleFactor) -{ +QImage Identicon::toImage(int scaleFactor) { if (scaleFactor < 1) { qDebug() << "Can't scale with values <1, clamping to 1"; scaleFactor = 1; diff --git a/src/modules/im/src/widget/tool/identicon.h b/src/modules/im/src/widget/tool/identicon.h index 06cbb7ec..f86cd553 100644 --- a/src/modules/im/src/widget/tool/identicon.h +++ b/src/modules/im/src/widget/tool/identicon.h @@ -16,8 +16,7 @@ #include #include -class Identicon -{ +class Identicon { public: Identicon(const QByteArray& data); QImage toImage(int scaleFactor = 1); @@ -32,11 +31,11 @@ class Identicon static constexpr int COLORS = 2; static constexpr int ACTIVE_COLS = (IDENTICON_ROWS + 1) / 2; static constexpr int IDENTICON_COLOR_BYTES = 6; - static constexpr int HASH_MIN_LEN = ACTIVE_COLS * IDENTICON_ROWS - + COLORS * IDENTICON_COLOR_BYTES; + static constexpr int HASH_MIN_LEN = + ACTIVE_COLS * IDENTICON_ROWS + COLORS * IDENTICON_COLOR_BYTES; uint8_t identiconColors[IDENTICON_ROWS][ACTIVE_COLS]; QColor colors[COLORS]; }; -#endif // IDENTICON_H +#endif // IDENTICON_H diff --git a/src/modules/im/src/widget/tool/movablewidget.cpp b/src/modules/im/src/widget/tool/movablewidget.cpp index a403014c..399151f8 100644 --- a/src/modules/im/src/widget/tool/movablewidget.cpp +++ b/src/modules/im/src/widget/tool/movablewidget.cpp @@ -15,9 +15,7 @@ #include #include -MovableWidget::MovableWidget(QWidget* parent) - : QWidget(parent) -{ +MovableWidget::MovableWidget(QWidget* parent) : QWidget(parent) { setMinimumHeight(64); setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored)); actualSize = minimumSize(); @@ -27,8 +25,7 @@ MovableWidget::MovableWidget(QWidget* parent) actualPos = QPoint(0, 0); } -void MovableWidget::resetBoundary(QRect newBoundary) -{ +void MovableWidget::resetBoundary(QRect newBoundary) { boundaryRect = newBoundary; resize(QSize(round(actualSize.width()), round(actualSize.height()))); @@ -38,8 +35,7 @@ void MovableWidget::resetBoundary(QRect newBoundary) actualPos = moveTo; } -void MovableWidget::setBoundary(QRect newBoundary) -{ +void MovableWidget::setBoundary(QRect newBoundary) { if (boundaryRect.isNull()) { boundaryRect = newBoundary; return; @@ -48,18 +44,17 @@ void MovableWidget::setBoundary(QRect newBoundary) float changeX = newBoundary.width() / static_cast(boundaryRect.width()); float changeY = newBoundary.height() / static_cast(boundaryRect.height()); - float percentageX = (x() - boundaryRect.x()) / static_cast(boundaryRect.width() - width()); + float percentageX = + (x() - boundaryRect.x()) / static_cast(boundaryRect.width() - width()); float percentageY = - (y() - boundaryRect.y()) / static_cast(boundaryRect.height() - height()); + (y() - boundaryRect.y()) / static_cast(boundaryRect.height() - height()); actualSize.setWidth(actualSize.width() * changeX); actualSize.setHeight(actualSize.height() * changeY); - if (actualSize.width() == 0) - actualSize.setWidth(1); + if (actualSize.width() == 0) actualSize.setWidth(1); - if (actualSize.height() == 0) - actualSize.setHeight(1); + if (actualSize.height() == 0) actualSize.setHeight(1); resize(QSize(round(actualSize.width()), round(actualSize.height()))); @@ -73,13 +68,9 @@ void MovableWidget::setBoundary(QRect newBoundary) boundaryRect = newBoundary; } -float MovableWidget::getRatio() const -{ - return ratio; -} +float MovableWidget::getRatio() const { return ratio; } -void MovableWidget::setRatio(float r) -{ +void MovableWidget::setRatio(float r) { ratio = r; resize(width(), width() / ratio); QPoint position = QPoint(actualPos.x(), actualPos.y()); @@ -90,18 +81,15 @@ void MovableWidget::setRatio(float r) actualSize = size(); } -void MovableWidget::mousePressEvent(QMouseEvent* event) -{ +void MovableWidget::mousePressEvent(QMouseEvent* event) { if (event->buttons() & Qt::LeftButton) { - if (!(mode & Resize)) - mode |= Moving; + if (!(mode & Resize)) mode |= Moving; lastPoint = event->globalPos(); } } -void MovableWidget::mouseMoveEvent(QMouseEvent* event) -{ +void MovableWidget::mouseMoveEvent(QMouseEvent* event) { if (mode & Moving) { QPoint moveTo = pos() - (lastPoint - event->globalPos()); checkBoundary(moveTo); @@ -139,9 +127,11 @@ void MovableWidget::mouseMoveEvent(QMouseEvent* event) const Modes ResizeDownRight = ResizeDown | ResizeRight; const Modes ResizeDownLeft = ResizeDown | ResizeLeft; - if ((mode & ResizeUpRight) == ResizeUpRight || (mode & ResizeDownLeft) == ResizeDownLeft) + if ((mode & ResizeUpRight) == ResizeUpRight || + (mode & ResizeDownLeft) == ResizeDownLeft) setCursor(Qt::SizeBDiagCursor); - else if ((mode & ResizeUpLeft) == ResizeUpLeft || (mode & ResizeDownRight) == ResizeDownRight) + else if ((mode & ResizeUpLeft) == ResizeUpLeft || + (mode & ResizeDownRight) == ResizeDownRight) setCursor(Qt::SizeFDiagCursor); else if (mode & (ResizeLeft | ResizeRight)) setCursor(Qt::SizeHorCursor); @@ -153,13 +143,12 @@ void MovableWidget::mouseMoveEvent(QMouseEvent* event) QPoint displacement = lastPoint - event->globalPos(); QSize lastSize = size(); - if (mode & ResizeUp) { lastSize.setHeight(height() + displacement.y()); if (lastSize.height() > maximumHeight()) - lastPosition.setY(y() - displacement.y() - + (lastSize.height() - maximumHeight())); + lastPosition.setY(y() - displacement.y() + + (lastSize.height() - maximumHeight())); else lastPosition.setY(y() - displacement.y()); } @@ -167,22 +156,19 @@ void MovableWidget::mouseMoveEvent(QMouseEvent* event) if (mode & ResizeLeft) { lastSize.setWidth(width() + displacement.x()); if (lastSize.width() > maximumWidth()) - lastPosition.setX(x() - displacement.x() + (lastSize.width() - maximumWidth())); + lastPosition.setX(x() - displacement.x() + + (lastSize.width() - maximumWidth())); else lastPosition.setX(x() - displacement.x()); } - if (mode & ResizeRight) - lastSize.setWidth(width() - displacement.x()); + if (mode & ResizeRight) lastSize.setWidth(width() - displacement.x()); - if (mode & ResizeDown) - lastSize.setHeight(height() - displacement.y()); + if (mode & ResizeDown) lastSize.setHeight(height() - displacement.y()); - if (lastSize.height() > maximumHeight()) - lastSize.setHeight(maximumHeight()); + if (lastSize.height() > maximumHeight()) lastSize.setHeight(maximumHeight()); - if (lastSize.width() > maximumWidth()) - lastSize.setWidth(maximumWidth()); + if (lastSize.width() > maximumWidth()) lastSize.setWidth(maximumWidth()); if (mode & (ResizeLeft | ResizeRight)) { if (mode & (ResizeUp | ResizeDown)) { @@ -193,11 +179,9 @@ void MovableWidget::mouseMoveEvent(QMouseEvent* event) resize(lastSize.width(), height); - if (lastSize.width() < minimumWidth()) - lastPosition.setX(pos().x()); + if (lastSize.width() < minimumWidth()) lastPosition.setX(pos().x()); - if (height < minimumHeight()) - lastPosition.setY(pos().y()); + if (height < minimumHeight()) lastPosition.setY(pos().y()); } else { resize(lastSize.width(), lastSize.width() / getRatio()); } @@ -221,16 +205,12 @@ void MovableWidget::mouseMoveEvent(QMouseEvent* event) } } -void MovableWidget::mouseReleaseEvent(QMouseEvent* event) -{ - if (!(event->buttons() & Qt::LeftButton)) - mode = 0; +void MovableWidget::mouseReleaseEvent(QMouseEvent* event) { + if (!(event->buttons() & Qt::LeftButton)) mode = 0; } -void MovableWidget::mouseDoubleClickEvent(QMouseEvent* event) -{ - if (!(event->buttons() & Qt::LeftButton)) - return; +void MovableWidget::mouseDoubleClickEvent(QMouseEvent* event) { + if (!(event->buttons() & Qt::LeftButton)) return; if (!graphicsEffect()) { QGraphicsOpacityEffect* opacityEffect = new QGraphicsOpacityEffect(this); @@ -241,16 +221,13 @@ void MovableWidget::mouseDoubleClickEvent(QMouseEvent* event) } } -void MovableWidget::checkBoundary(QPoint& point) const -{ +void MovableWidget::checkBoundary(QPoint& point) const { int x1, y1, x2, y2; boundaryRect.getCoords(&x1, &y1, &x2, &y2); - if (point.x() < boundaryRect.left()) - point.setX(boundaryRect.left()); + if (point.x() < boundaryRect.left()) point.setX(boundaryRect.left()); - if (point.y() < boundaryRect.top()) - point.setY(boundaryRect.top()); + if (point.y() < boundaryRect.top()) point.setY(boundaryRect.top()); if (point.x() + width() > boundaryRect.right() + 1) point.setX(boundaryRect.right() - width() + 1); diff --git a/src/modules/im/src/widget/tool/movablewidget.h b/src/modules/im/src/widget/tool/movablewidget.h index b1222fbb..501383b5 100644 --- a/src/modules/im/src/widget/tool/movablewidget.h +++ b/src/modules/im/src/widget/tool/movablewidget.h @@ -15,8 +15,7 @@ #include -class MovableWidget : public QWidget -{ +class MovableWidget : public QWidget { public: explicit MovableWidget(QWidget* parent); void resetBoundary(QRect newBoundary); @@ -36,8 +35,7 @@ class MovableWidget : public QWidget typedef uint8_t Modes; - enum Mode : Modes - { + enum Mode : Modes { Moving = 0x01, ResizeLeft = 0x02, ResizeRight = 0x04, @@ -54,4 +52,4 @@ class MovableWidget : public QWidget float ratio; }; -#endif // MOVABLEWIDGET_H +#endif // MOVABLEWIDGET_H diff --git a/src/modules/im/src/widget/tool/profileimporter.cpp b/src/modules/im/src/widget/tool/profileimporter.cpp index 4427d0e6..3a47248b 100644 --- a/src/modules/im/src/widget/tool/profileimporter.cpp +++ b/src/modules/im/src/widget/tool/profileimporter.cpp @@ -28,17 +28,13 @@ * to create dialog forms. */ -ProfileImporter::ProfileImporter(QWidget* parent) - : QWidget(parent) -{ -} +ProfileImporter::ProfileImporter(QWidget* parent) : QWidget(parent) {} /** * @brief Show a file dialog. Selected file will be imported as Tox profile. * @return True, if the import was succesful. False otherwise. */ -bool ProfileImporter::importProfile() -{ +bool ProfileImporter::importProfile() { QString title = tr("Import profile", "import dialog title"); QString filter = tr("Tox save file (*.tox)", "import dialog filter"); QString dir = QDir::homePath(); @@ -57,8 +53,7 @@ bool ProfileImporter::importProfile() * @param message Text in question window. * @return True if the answer is positive, false otherwise. */ -bool ProfileImporter::askQuestion(QString title, QString message) -{ +bool ProfileImporter::askQuestion(QString title, QString message) { QMessageBox::Icon icon = QMessageBox::Warning; QMessageBox box(icon, title, message, QMessageBox::NoButton, this); QPushButton* pushButton1 = box.addButton(QApplication::tr("Yes"), QMessageBox::AcceptRole); @@ -75,10 +70,8 @@ bool ProfileImporter::askQuestion(QString title, QString message) * @param path Path to Tox profile. * @return True, if the import was succesful. False otherwise. */ -bool ProfileImporter::importProfile(const QString& path) -{ - if (path.isEmpty()) - return false; +bool ProfileImporter::importProfile(const QString& path) { + if (path.isEmpty()) return false; QFileInfo info(path); if (!info.exists()) { @@ -95,7 +88,7 @@ bool ProfileImporter::importProfile(const QString& path) "Tox save file; ignoring.", "popup text"), QMessageBox::Ok); - return false; // ingore importing non-tox file + return false; // ingore importing non-tox file } QString settingsPath = Settings::getInstance().getSettingsDirPath(); @@ -106,11 +99,10 @@ bool ProfileImporter::importProfile(const QString& path) QString message = tr("A profile named \"%1\" already exists. " "Do you want to erase it?", "import confirm text") - .arg(profile); + .arg(profile); bool erase = askQuestion(title, message); - if (!erase) - return false; // import canelled + if (!erase) return false; // import canelled QFile(profilePath).remove(); } @@ -121,5 +113,5 @@ bool ProfileImporter::importProfile(const QString& path) QMessageBox::information(this, tr("Profile imported"), tr("%1.tox was successfully imported").arg(profile), QMessageBox::Ok); - return true; // import successfull + return true; // import successfull } diff --git a/src/modules/im/src/widget/tool/profileimporter.h b/src/modules/im/src/widget/tool/profileimporter.h index 72cef7d3..40f96e27 100644 --- a/src/modules/im/src/widget/tool/profileimporter.h +++ b/src/modules/im/src/widget/tool/profileimporter.h @@ -15,8 +15,7 @@ #include -class ProfileImporter : public QWidget -{ +class ProfileImporter : public QWidget { Q_OBJECT public: @@ -28,4 +27,4 @@ class ProfileImporter : public QWidget bool askQuestion(QString title, QString message); }; -#endif // PROFILEIMPORTER_H +#endif // PROFILEIMPORTER_H diff --git a/src/modules/im/src/widget/tool/removefrienddialog.cpp b/src/modules/im/src/widget/tool/removefrienddialog.cpp index 914c1cdc..8f1f004b 100644 --- a/src/modules/im/src/widget/tool/removefrienddialog.cpp +++ b/src/modules/im/src/widget/tool/removefrienddialog.cpp @@ -13,16 +13,13 @@ #include "removefrienddialog.h" #include - -RemoveFriendDialog::RemoveFriendDialog(QWidget* parent, const Friend* f) - : QDialog(parent) -{ +RemoveFriendDialog::RemoveFriendDialog(QWidget* parent, const Friend* f) : QDialog(parent) { setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); setAttribute(Qt::WA_QuitOnClose, false); ui.setupUi(this); QString name = f->getDisplayedName().toHtmlEscaped(); QString text = tr("Are you sure you want to remove %1 from your contacts list?") - .arg(QString("%1").arg(name)); + .arg(QString("%1").arg(name)); ui.label->setText(text); auto removeButton = ui.buttonBox->button(QDialogButtonBox::Ok); @@ -35,8 +32,7 @@ RemoveFriendDialog::RemoveFriendDialog(QWidget* parent, const Friend* f) setFocus(); } -void RemoveFriendDialog::onAccepted() -{ +void RemoveFriendDialog::onAccepted() { _accepted = true; close(); } diff --git a/src/modules/im/src/widget/tool/removefrienddialog.h b/src/modules/im/src/widget/tool/removefrienddialog.h index 6cdb58f2..b601e18a 100644 --- a/src/modules/im/src/widget/tool/removefrienddialog.h +++ b/src/modules/im/src/widget/tool/removefrienddialog.h @@ -13,27 +13,18 @@ #ifndef DELETEFRIENDDIALOG_H #define DELETEFRIENDDIALOG_H - -#include "ui_removefrienddialog.h" -#include "src/model/friend.h" #include +#include "src/model/friend.h" +#include "ui_removefrienddialog.h" - -class RemoveFriendDialog : public QDialog -{ +class RemoveFriendDialog : public QDialog { Q_OBJECT public: explicit RemoveFriendDialog(QWidget* parent, const Friend* f); - inline bool removeHistory() - { - return ui.removeHistory->isChecked(); - } + inline bool removeHistory() { return ui.removeHistory->isChecked(); } - inline bool accepted() - { - return _accepted; - } + inline bool accepted() { return _accepted; } public slots: void onAccepted(); @@ -43,4 +34,4 @@ public slots: bool _accepted = false; }; -#endif // DELETEFRIENDDIALOG_H +#endif // DELETEFRIENDDIALOG_H diff --git a/src/modules/im/src/widget/tool/roundedmaskcontainer.cpp b/src/modules/im/src/widget/tool/roundedmaskcontainer.cpp index 2349ea06..5474a4ae 100644 --- a/src/modules/im/src/widget/tool/roundedmaskcontainer.cpp +++ b/src/modules/im/src/widget/tool/roundedmaskcontainer.cpp @@ -6,33 +6,27 @@ #include class RoundMaskGraphicsEffect : public QGraphicsEffect { - public: - RoundMaskGraphicsEffect(QWidget *target) : QGraphicsEffect(target), _target(target) - { - } +public: + RoundMaskGraphicsEffect(QWidget* target) : QGraphicsEffect(target), _target(target) {} - QRectF boundingRectFor(const QRectF &rect) const { - return rect.adjusted(-1, -1, 1, 1); - } - void setRadius(int r) - { + QRectF boundingRectFor(const QRectF& rect) const { return rect.adjusted(-1, -1, 1, 1); } + void setRadius(int r) { radius = r; update(); } - protected: - void draw(QPainter *painter) - { - if (radius <= 0) - { + +protected: + void draw(QPainter* painter) { + if (radius <= 0) { drawSource(painter); return; } QPoint offset; - Qt::CoordinateSystem system = sourceIsPixmap() ? Qt::LogicalCoordinates : Qt::DeviceCoordinates; + Qt::CoordinateSystem system = + sourceIsPixmap() ? Qt::LogicalCoordinates : Qt::DeviceCoordinates; QPixmap pixmap = sourcePixmap(system, &offset, QGraphicsEffect::NoPad); - if (pixmap.isNull()) - return; + if (pixmap.isNull()) return; painter->save(); QPainter pixmapPainter(&pixmap); @@ -59,23 +53,19 @@ class RoundMaskGraphicsEffect : public QGraphicsEffect { painter->restore(); } - private: +private: QPointer _target; int radius = 0; }; - -RoundedMaskContainer::RoundedMaskContainer(QWidget *parent) : QFrame(parent) -{ +RoundedMaskContainer::RoundedMaskContainer(QWidget* parent) : QFrame(parent) { setAttribute(Qt::WA_OpaquePaintEvent, false); effect = new RoundMaskGraphicsEffect(this); setGraphicsEffect(effect); } -void RoundedMaskContainer::setRoundRadius(int radius) -{ - if (_radius != radius) - { +void RoundedMaskContainer::setRoundRadius(int radius) { + if (_radius != radius) { _radius = radius; effect->setRadius(radius); } diff --git a/src/modules/im/src/widget/tool/roundedmaskcontainer.h b/src/modules/im/src/widget/tool/roundedmaskcontainer.h index 1746026e..d9cada8c 100644 --- a/src/modules/im/src/widget/tool/roundedmaskcontainer.h +++ b/src/modules/im/src/widget/tool/roundedmaskcontainer.h @@ -8,15 +8,13 @@ class RoundMaskGraphicsEffect; class RoundedMaskContainer : public QFrame { Q_OBJECT Q_PROPERTY(int radius READ roundRadius WRITE setRoundRadius) - public: - RoundedMaskContainer(QWidget *parent); +public: + RoundedMaskContainer(QWidget* parent); Q_INVOKABLE void setRoundRadius(int radius); - Q_INVOKABLE int roundRadius() const { - return _radius; - } + Q_INVOKABLE int roundRadius() const { return _radius; } - private: +private: int _radius = 0; - RoundMaskGraphicsEffect *effect = nullptr; + RoundMaskGraphicsEffect* effect = nullptr; }; -#endif // !ROUNDEDMASKCONTAINER_H +#endif // !ROUNDEDMASKCONTAINER_H diff --git a/src/modules/im/src/widget/tool/screengrabberchooserrectitem.cpp b/src/modules/im/src/widget/tool/screengrabberchooserrectitem.cpp index dcaf00df..84f20793 100644 --- a/src/modules/im/src/widget/tool/screengrabberchooserrectitem.cpp +++ b/src/modules/im/src/widget/tool/screengrabberchooserrectitem.cpp @@ -17,14 +17,12 @@ #include #include -enum -{ +enum { HandleSize = 10, MinRectSize = 2, }; -ScreenGrabberChooserRectItem::ScreenGrabberChooserRectItem(QGraphicsScene* scene) -{ +ScreenGrabberChooserRectItem::ScreenGrabberChooserRectItem(QGraphicsScene* scene) { scene->addItem(this); setCursor(QCursor(Qt::OpenHandCursor)); @@ -51,18 +49,14 @@ ScreenGrabberChooserRectItem::ScreenGrabberChooserRectItem(QGraphicsScene* scene hideHandles(); } -ScreenGrabberChooserRectItem::~ScreenGrabberChooserRectItem() -{ -} +ScreenGrabberChooserRectItem::~ScreenGrabberChooserRectItem() {} -QRectF ScreenGrabberChooserRectItem::boundingRect() const -{ +QRectF ScreenGrabberChooserRectItem::boundingRect() const { return QRectF(-HandleSize - 1, -HandleSize - 1, rectWidth + HandleSize + 1, rectHeight + HandleSize + 1); } -void ScreenGrabberChooserRectItem::beginResize(QPointF mousePos) -{ +void ScreenGrabberChooserRectItem::beginResize(QPointF mousePos) { rectWidth = this->rectHeight = 0; mainRect->setRect(QRect()); state = Resizing; @@ -73,8 +67,7 @@ void ScreenGrabberChooserRectItem::beginResize(QPointF mousePos) mainRect->grabMouse(); } -QRect ScreenGrabberChooserRectItem::chosenRect() const -{ +QRect ScreenGrabberChooserRectItem::chosenRect() const { QRect rect(x(), y(), rectWidth, rectHeight); if (rectWidth < 0) { rect.setX(rect.x() + rectWidth); @@ -89,8 +82,7 @@ QRect ScreenGrabberChooserRectItem::chosenRect() const return rect; } -void ScreenGrabberChooserRectItem::showHandles() -{ +void ScreenGrabberChooserRectItem::showHandles() { this->topLeft->show(); this->topCenter->show(); this->topRight->show(); @@ -101,8 +93,7 @@ void ScreenGrabberChooserRectItem::showHandles() this->leftCenter->show(); } -void ScreenGrabberChooserRectItem::hideHandles() -{ +void ScreenGrabberChooserRectItem::hideHandles() { this->topLeft->hide(); this->topCenter->hide(); this->topRight->hide(); @@ -113,16 +104,14 @@ void ScreenGrabberChooserRectItem::hideHandles() this->leftCenter->hide(); } -void ScreenGrabberChooserRectItem::mousePress(QGraphicsSceneMouseEvent* event) -{ +void ScreenGrabberChooserRectItem::mousePress(QGraphicsSceneMouseEvent* event) { if (event->button() == Qt::LeftButton) { this->state = Moving; setCursor(QCursor(Qt::ClosedHandCursor)); } } -void ScreenGrabberChooserRectItem::mouseMove(QGraphicsSceneMouseEvent* event) -{ +void ScreenGrabberChooserRectItem::mouseMove(QGraphicsSceneMouseEvent* event) { if (this->state == Moving) { QPointF delta = event->scenePos() - event->lastScenePos(); moveBy(delta.x(), delta.y()); @@ -141,8 +130,7 @@ void ScreenGrabberChooserRectItem::mouseMove(QGraphicsSceneMouseEvent* event) emit regionChosen(chosenRect()); } -void ScreenGrabberChooserRectItem::mouseRelease(QGraphicsSceneMouseEvent* event) -{ +void ScreenGrabberChooserRectItem::mouseRelease(QGraphicsSceneMouseEvent* event) { if (event->button() == Qt::LeftButton) { setCursor(QCursor(Qt::OpenHandCursor)); @@ -168,25 +156,20 @@ void ScreenGrabberChooserRectItem::mouseRelease(QGraphicsSceneMouseEvent* event) } } -void ScreenGrabberChooserRectItem::mouseDoubleClick(QGraphicsSceneMouseEvent* event) -{ +void ScreenGrabberChooserRectItem::mouseDoubleClick(QGraphicsSceneMouseEvent* event) { Q_UNUSED(event); emit doubleClicked(); } -void ScreenGrabberChooserRectItem::mousePressHandle(int x, int y, QGraphicsSceneMouseEvent* event) -{ +void ScreenGrabberChooserRectItem::mousePressHandle(int x, int y, QGraphicsSceneMouseEvent* event) { Q_UNUSED(x); Q_UNUSED(y); - if (event->button() == Qt::LeftButton) - this->state = HandleResizing; + if (event->button() == Qt::LeftButton) this->state = HandleResizing; } -void ScreenGrabberChooserRectItem::mouseMoveHandle(int x, int y, QGraphicsSceneMouseEvent* event) -{ - if (this->state != HandleResizing) - return; +void ScreenGrabberChooserRectItem::mouseMoveHandle(int x, int y, QGraphicsSceneMouseEvent* event) { + if (this->state != HandleResizing) return; QPointF delta = event->scenePos() - event->lastScenePos(); delta.rx() *= qAbs(x); @@ -214,46 +197,35 @@ void ScreenGrabberChooserRectItem::mouseMoveHandle(int x, int y, QGraphicsSceneM emit regionChosen(chosenRect()); } -void ScreenGrabberChooserRectItem::mouseReleaseHandle(int x, int y, QGraphicsSceneMouseEvent* event) -{ +void ScreenGrabberChooserRectItem::mouseReleaseHandle(int x, int y, + QGraphicsSceneMouseEvent* event) { Q_UNUSED(x); Q_UNUSED(y); - if (event->button() == Qt::LeftButton) - this->state = None; + if (event->button() == Qt::LeftButton) this->state = None; } -QPoint ScreenGrabberChooserRectItem::getHandleMultiplier(QGraphicsItem* handle) -{ - if (handle == this->topLeft) - return QPoint(-1, -1); +QPoint ScreenGrabberChooserRectItem::getHandleMultiplier(QGraphicsItem* handle) { + if (handle == this->topLeft) return QPoint(-1, -1); - if (handle == this->topCenter) - return QPoint(0, -1); + if (handle == this->topCenter) return QPoint(0, -1); - if (handle == this->topRight) - return QPoint(1, -1); + if (handle == this->topRight) return QPoint(1, -1); - if (handle == this->rightCenter) - return QPoint(1, 0); + if (handle == this->rightCenter) return QPoint(1, 0); - if (handle == this->bottomRight) - return QPoint(1, 1); + if (handle == this->bottomRight) return QPoint(1, 1); - if (handle == this->bottomCenter) - return QPoint(0, 1); + if (handle == this->bottomCenter) return QPoint(0, 1); - if (handle == this->bottomLeft) - return QPoint(-1, 1); + if (handle == this->bottomLeft) return QPoint(-1, 1); - if (handle == this->leftCenter) - return QPoint(-1, 0); + if (handle == this->leftCenter) return QPoint(-1, 0); return QPoint(); } -void ScreenGrabberChooserRectItem::updateHandlePositions() -{ +void ScreenGrabberChooserRectItem::updateHandlePositions() { this->topLeft->setPos(-HandleSize, -HandleSize); this->topCenter->setPos((this->rectWidth - HandleSize) / 2, -HandleSize); this->topRight->setPos(this->rectWidth, -HandleSize); @@ -264,8 +236,7 @@ void ScreenGrabberChooserRectItem::updateHandlePositions() this->leftCenter->setPos(-HandleSize, (this->rectHeight - HandleSize) / 2); } -QGraphicsRectItem* ScreenGrabberChooserRectItem::createHandleItem(QGraphicsScene* scene) -{ +QGraphicsRectItem* ScreenGrabberChooserRectItem::createHandleItem(QGraphicsScene* scene) { QGraphicsRectItem* handle = new QGraphicsRectItem(0, 0, HandleSize, HandleSize); handle->setPen(QPen(Qt::blue)); handle->setBrush(Qt::NoBrush); @@ -277,8 +248,7 @@ QGraphicsRectItem* ScreenGrabberChooserRectItem::createHandleItem(QGraphicsScene return handle; } -bool ScreenGrabberChooserRectItem::sceneEventFilter(QGraphicsItem* watched, QEvent* event) -{ +bool ScreenGrabberChooserRectItem::sceneEventFilter(QGraphicsItem* watched, QEvent* event) { if (watched == this->mainRect) forwardMainRectEvent(event); else @@ -287,40 +257,37 @@ bool ScreenGrabberChooserRectItem::sceneEventFilter(QGraphicsItem* watched, QEve return true; } -void ScreenGrabberChooserRectItem::forwardMainRectEvent(QEvent* event) -{ +void ScreenGrabberChooserRectItem::forwardMainRectEvent(QEvent* event) { QGraphicsSceneMouseEvent* mouseEvent = static_cast(event); switch (event->type()) { - case QEvent::GraphicsSceneMousePress: - return mousePress(mouseEvent); - case QEvent::GraphicsSceneMouseMove: - return mouseMove(mouseEvent); - case QEvent::GraphicsSceneMouseRelease: - return mouseRelease(mouseEvent); - case QEvent::GraphicsSceneMouseDoubleClick: - return mouseDoubleClick(mouseEvent); - default: - return; + case QEvent::GraphicsSceneMousePress: + return mousePress(mouseEvent); + case QEvent::GraphicsSceneMouseMove: + return mouseMove(mouseEvent); + case QEvent::GraphicsSceneMouseRelease: + return mouseRelease(mouseEvent); + case QEvent::GraphicsSceneMouseDoubleClick: + return mouseDoubleClick(mouseEvent); + default: + return; } } -void ScreenGrabberChooserRectItem::forwardHandleEvent(QGraphicsItem* watched, QEvent* event) -{ +void ScreenGrabberChooserRectItem::forwardHandleEvent(QGraphicsItem* watched, QEvent* event) { QGraphicsSceneMouseEvent* mouseEvent = static_cast(event); QPoint multiplier = getHandleMultiplier(watched); - if (multiplier.isNull()) - return; + if (multiplier.isNull()) return; switch (event->type()) { - case QEvent::GraphicsSceneMousePress: - return mousePressHandle(multiplier.x(), multiplier.y(), mouseEvent); - case QEvent::GraphicsSceneMouseMove: - return mouseMoveHandle(multiplier.x(), multiplier.y(), mouseEvent); - case QEvent::GraphicsSceneMouseRelease: - return mouseReleaseHandle(multiplier.x(), multiplier.y(), mouseEvent); - default: - return; + case QEvent::GraphicsSceneMousePress: + return mousePressHandle(multiplier.x(), multiplier.y(), mouseEvent); + case QEvent::GraphicsSceneMouseMove: + return mouseMoveHandle(multiplier.x(), multiplier.y(), mouseEvent); + case QEvent::GraphicsSceneMouseRelease: + return mouseReleaseHandle(multiplier.x(), multiplier.y(), mouseEvent); + default: + return; } } diff --git a/src/modules/im/src/widget/tool/screengrabberchooserrectitem.h b/src/modules/im/src/widget/tool/screengrabberchooserrectitem.h index 5ef97b11..c20ab47e 100644 --- a/src/modules/im/src/widget/tool/screengrabberchooserrectitem.h +++ b/src/modules/im/src/widget/tool/screengrabberchooserrectitem.h @@ -15,8 +15,7 @@ #include -class ScreenGrabberChooserRectItem final : public QObject, public QGraphicsItemGroup -{ +class ScreenGrabberChooserRectItem final : public QObject, public QGraphicsItemGroup { Q_OBJECT public: explicit ScreenGrabberChooserRectItem(QGraphicsScene* scene); @@ -39,8 +38,7 @@ class ScreenGrabberChooserRectItem final : public QObject, public QGraphicsItemG virtual bool sceneEventFilter(QGraphicsItem* watched, QEvent* event) final override; private: - enum State - { + enum State { None, Resizing, HandleResizing, @@ -80,5 +78,4 @@ class ScreenGrabberChooserRectItem final : public QObject, public QGraphicsItemG QGraphicsRectItem* leftCenter; }; - -#endif // SCREENGRABBERCHOOSERRECTITEM_HPP +#endif // SCREENGRABBERCHOOSERRECTITEM_HPP diff --git a/src/modules/im/src/widget/tool/screengrabberoverlayitem.cpp b/src/modules/im/src/widget/tool/screengrabberoverlayitem.cpp index 8c4b6593..3fddfc2e 100644 --- a/src/modules/im/src/widget/tool/screengrabberoverlayitem.cpp +++ b/src/modules/im/src/widget/tool/screengrabberoverlayitem.cpp @@ -20,35 +20,27 @@ #include "screenshotgrabber.h" ScreenGrabberOverlayItem::ScreenGrabberOverlayItem(ScreenshotGrabber* grabber) - : screnshootGrabber(grabber) -{ - - QBrush overlayBrush(QColor(0x00, 0x00, 0x00, 0x70)); // Translucent black + : screnshootGrabber(grabber) { + QBrush overlayBrush(QColor(0x00, 0x00, 0x00, 0x70)); // Translucent black setCursor(QCursor(Qt::CrossCursor)); setBrush(overlayBrush); setPen(QPen(Qt::NoPen)); } -ScreenGrabberOverlayItem::~ScreenGrabberOverlayItem() -{ -} +ScreenGrabberOverlayItem::~ScreenGrabberOverlayItem() {} -void ScreenGrabberOverlayItem::setChosenRect(QRect rect) -{ +void ScreenGrabberOverlayItem::setChosenRect(QRect rect) { QRect oldRect = chosenRect; chosenRect = rect; update(oldRect.united(rect)); } -void ScreenGrabberOverlayItem::mousePressEvent(QGraphicsSceneMouseEvent* event) -{ - if (event->button() == Qt::LeftButton) - this->screnshootGrabber->beginRectChooser(event); +void ScreenGrabberOverlayItem::mousePressEvent(QGraphicsSceneMouseEvent* event) { + if (event->button() == Qt::LeftButton) this->screnshootGrabber->beginRectChooser(event); } -void ScreenGrabberOverlayItem::paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*) -{ +void ScreenGrabberOverlayItem::paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*) { painter->setBrush(brush()); painter->setPen(pen()); @@ -58,9 +50,9 @@ void ScreenGrabberOverlayItem::paint(QPainter* painter, const QStyleOptionGraphi qreal topY = chosenRect.y(); qreal bottomY = chosenRect.y() + chosenRect.height(); - painter->drawRect(0, 0, leftX, self.height()); // Left of chosen - painter->drawRect(rightX, 0, self.width() - rightX, self.height()); // Right of chosen - painter->drawRect(leftX, 0, chosenRect.width(), topY); // Top of chosen + painter->drawRect(0, 0, leftX, self.height()); // Left of chosen + painter->drawRect(rightX, 0, self.width() - rightX, self.height()); // Right of chosen + painter->drawRect(leftX, 0, chosenRect.width(), topY); // Top of chosen painter->drawRect(leftX, bottomY, chosenRect.width(), - self.height() - bottomY); // Bottom of chosen + self.height() - bottomY); // Bottom of chosen } diff --git a/src/modules/im/src/widget/tool/screengrabberoverlayitem.h b/src/modules/im/src/widget/tool/screengrabberoverlayitem.h index 959be73e..a54b8e38 100644 --- a/src/modules/im/src/widget/tool/screengrabberoverlayitem.h +++ b/src/modules/im/src/widget/tool/screengrabberoverlayitem.h @@ -17,8 +17,7 @@ class ScreenshotGrabber; -class ScreenGrabberOverlayItem final : public QObject, public QGraphicsRectItem -{ +class ScreenGrabberOverlayItem final : public QObject, public QGraphicsRectItem { Q_OBJECT public: explicit ScreenGrabberOverlayItem(ScreenshotGrabber* grabber); @@ -37,4 +36,4 @@ class ScreenGrabberOverlayItem final : public QObject, public QGraphicsRectItem QRect chosenRect; }; -#endif // SCREENGRABBEROVERLAYITEM_HPP +#endif // SCREENGRABBEROVERLAYITEM_HPP diff --git a/src/modules/im/src/widget/tool/screenshotgrabber.cpp b/src/modules/im/src/widget/tool/screenshotgrabber.cpp index 0f45f65f..5a5db50f 100644 --- a/src/modules/im/src/widget/tool/screenshotgrabber.cpp +++ b/src/modules/im/src/widget/tool/screenshotgrabber.cpp @@ -25,16 +25,12 @@ #include "screengrabberchooserrectitem.h" #include "screengrabberoverlayitem.h" -#include "toolboxgraphicsitem.h" #include "src/widget/widget.h" +#include "toolboxgraphicsitem.h" ScreenshotGrabber::ScreenshotGrabber() - : QObject() - , mKeysBlocked(false) - , scene(nullptr) - , mQToxVisible(true) -{ - window = new QGraphicsView(scene); // Top-level widget + : QObject(), mKeysBlocked(false), scene(nullptr), mQToxVisible(true) { + window = new QGraphicsView(scene); // Top-level widget window->setWindowFlags(Qt::FramelessWindowHint | Qt::BypassWindowManagerHint); window->setContentsMargins(0, 0, 0, 0); window->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); @@ -46,30 +42,25 @@ ScreenshotGrabber::ScreenshotGrabber() setupScene(); } -void ScreenshotGrabber::reInit() -{ +void ScreenshotGrabber::reInit() { window->resetCachedContent(); setupScene(); showGrabber(); mKeysBlocked = false; } -ScreenshotGrabber::~ScreenshotGrabber() -{ +ScreenshotGrabber::~ScreenshotGrabber() { delete scene; delete window; } -bool ScreenshotGrabber::eventFilter(QObject* object, QEvent* event) -{ - if (event->type() == QEvent::KeyPress) - return handleKeyPress(static_cast(event)); +bool ScreenshotGrabber::eventFilter(QObject* object, QEvent* event) { + if (event->type() == QEvent::KeyPress) return handleKeyPress(static_cast(event)); return QObject::eventFilter(object, event); } -void ScreenshotGrabber::showGrabber() -{ +void ScreenshotGrabber::showGrabber() { this->screenGrab = grabScreen(); this->screenGrabDisplay->setPixmap(this->screenGrab); this->window->show(); @@ -86,10 +77,8 @@ void ScreenshotGrabber::showGrabber() adjustTooltipPosition(); } -bool ScreenshotGrabber::handleKeyPress(QKeyEvent* event) -{ - if (mKeysBlocked) - return false; +bool ScreenshotGrabber::handleKeyPress(QKeyEvent* event) { + if (mKeysBlocked) return false; if (event->key() == Qt::Key_Escape) reject(); @@ -111,11 +100,9 @@ bool ScreenshotGrabber::handleKeyPress(QKeyEvent* event) return true; } -void ScreenshotGrabber::acceptRegion() -{ +void ScreenshotGrabber::acceptRegion() { QRect rect = this->chooserRect->chosenRect(); - if (rect.width() < 1 || rect.height() < 1) - return; + if (rect.width() < 1 || rect.height() < 1) return; // Scale the accepted region from DIPs to actual pixels rect.setRect(rect.x() * pixRatio, rect.y() * pixRatio, rect.width() * pixRatio, @@ -130,8 +117,7 @@ void ScreenshotGrabber::acceptRegion() deleteLater(); } -void ScreenshotGrabber::setupScene() -{ +void ScreenshotGrabber::setupScene() { delete scene; scene = new QGraphicsScene; window->setScene(scene); @@ -158,31 +144,28 @@ void ScreenshotGrabber::setupScene() &ScreenGrabberOverlayItem::setChosenRect); } -void ScreenshotGrabber::useNothingSelectedTooltip() -{ +void ScreenshotGrabber::useNothingSelectedTooltip() { helperTooltip->setHtml( - tr("Click and drag to select a region. Press %1 to " - "hide/show qTox window, or %2 to cancel.", - "Help text shown when no region has been selected yet") - .arg(QString("%1").arg(tr("Space", "[Space] key on the keyboard")), - QString("%1").arg(tr("Escape", "[Escape] key on the keyboard")))); + tr("Click and drag to select a region. Press %1 to " + "hide/show qTox window, or %2 to cancel.", + "Help text shown when no region has been selected yet") + .arg(QString("%1").arg(tr("Space", "[Space] key on the keyboard")), + QString("%1").arg(tr("Escape", "[Escape] key on the keyboard")))); adjustTooltipPosition(); } -void ScreenshotGrabber::useRegionSelectedTooltip() -{ +void ScreenshotGrabber::useRegionSelectedTooltip() { helperTooltip->setHtml( - tr("Press %1 to send a screenshot of the selection, " - "%2 to hide/show qTox window, or %3 to cancel.", - "Help text shown when a region has been selected") - .arg(QString("%1").arg(tr("Enter", "[Enter] key on the keyboard")), - QString("%1").arg(tr("Space", "[Space] key on the keyboard")), - QString("%1").arg(tr("Escape", "[Escape] key on the keyboard")))); + tr("Press %1 to send a screenshot of the selection, " + "%2 to hide/show qTox window, or %3 to cancel.", + "Help text shown when a region has been selected") + .arg(QString("%1").arg(tr("Enter", "[Enter] key on the keyboard")), + QString("%1").arg(tr("Space", "[Space] key on the keyboard")), + QString("%1").arg(tr("Escape", "[Escape] key on the keyboard")))); adjustTooltipPosition(); } -void ScreenshotGrabber::chooseHelperTooltipText(QRect rect) -{ +void ScreenshotGrabber::chooseHelperTooltipText(QRect rect) { if (rect.size().isNull()) useNothingSelectedTooltip(); else @@ -193,8 +176,7 @@ void ScreenshotGrabber::chooseHelperTooltipText(QRect rect) * @internal * @brief Align the tooltip centered at top of screen with the mouse cursor. */ -void ScreenshotGrabber::adjustTooltipPosition() -{ +void ScreenshotGrabber::adjustTooltipPosition() { QRect recGL = QGuiApplication::primaryScreen()->virtualGeometry(); #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) const auto rec = QGuiApplication::screenAt(QCursor::pos())->geometry(); @@ -209,14 +191,12 @@ void ScreenshotGrabber::adjustTooltipPosition() helperToolbox->setY(y); } -void ScreenshotGrabber::reject() -{ +void ScreenshotGrabber::reject() { restoreHiddenWindows(); deleteLater(); } -QPixmap ScreenshotGrabber::grabScreen() -{ +QPixmap ScreenshotGrabber::grabScreen() { QScreen* screen = QGuiApplication::primaryScreen(); QRect rec = screen->virtualGeometry(); @@ -225,8 +205,7 @@ QPixmap ScreenshotGrabber::grabScreen() rec.y() * pixRatio, rec.width() * pixRatio, rec.height() * pixRatio); } -void ScreenshotGrabber::hideVisibleWindows() -{ +void ScreenshotGrabber::hideVisibleWindows() { foreach (QWidget* w, qApp->topLevelWidgets()) { if (w != window && w->isVisible()) { mHiddenWindows << w; @@ -237,19 +216,16 @@ void ScreenshotGrabber::hideVisibleWindows() mQToxVisible = false; } -void ScreenshotGrabber::restoreHiddenWindows() -{ +void ScreenshotGrabber::restoreHiddenWindows() { foreach (QWidget* w, mHiddenWindows) { - if (w) - w->setVisible(true); + if (w) w->setVisible(true); } mHiddenWindows.clear(); mQToxVisible = true; } -void ScreenshotGrabber::beginRectChooser(QGraphicsSceneMouseEvent* event) -{ +void ScreenshotGrabber::beginRectChooser(QGraphicsSceneMouseEvent* event) { QPointF pos = event->scenePos(); this->chooserRect->setX(pos.x()); this->chooserRect->setY(pos.y()); diff --git a/src/modules/im/src/widget/tool/screenshotgrabber.h b/src/modules/im/src/widget/tool/screenshotgrabber.h index ecd38e65..3e5ad9cb 100644 --- a/src/modules/im/src/widget/tool/screenshotgrabber.h +++ b/src/modules/im/src/widget/tool/screenshotgrabber.h @@ -27,8 +27,7 @@ class ScreenGrabberChooserRectItem; class ScreenGrabberOverlayItem; class ToolBoxGraphicsItem; -class ScreenshotGrabber : public QObject -{ +class ScreenshotGrabber : public QObject { Q_OBJECT public: ScreenshotGrabber(); @@ -84,5 +83,4 @@ public slots: QVector> mHiddenWindows; }; - -#endif // SCREENSHOTGRABBER_H +#endif // SCREENSHOTGRABBER_H diff --git a/src/modules/im/src/widget/tool/toolboxgraphicsitem.cpp b/src/modules/im/src/widget/tool/toolboxgraphicsitem.cpp index 6619527e..a6105c16 100644 --- a/src/modules/im/src/widget/tool/toolboxgraphicsitem.cpp +++ b/src/modules/im/src/widget/tool/toolboxgraphicsitem.cpp @@ -14,8 +14,7 @@ #include -ToolBoxGraphicsItem::ToolBoxGraphicsItem() -{ +ToolBoxGraphicsItem::ToolBoxGraphicsItem() { this->opacityAnimation = new QPropertyAnimation(this, QByteArrayLiteral("opacity"), this); this->opacityAnimation->setKeyValueAt(0, this->idleOpacity); @@ -25,31 +24,25 @@ ToolBoxGraphicsItem::ToolBoxGraphicsItem() setOpacity(this->activeOpacity); } -ToolBoxGraphicsItem::~ToolBoxGraphicsItem() -{ -} +ToolBoxGraphicsItem::~ToolBoxGraphicsItem() {} -void ToolBoxGraphicsItem::hoverEnterEvent(QGraphicsSceneHoverEvent* event) -{ +void ToolBoxGraphicsItem::hoverEnterEvent(QGraphicsSceneHoverEvent* event) { startAnimation(QAbstractAnimation::Backward); QGraphicsItemGroup::hoverEnterEvent(event); } -void ToolBoxGraphicsItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* event) -{ +void ToolBoxGraphicsItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* event) { startAnimation(QAbstractAnimation::Forward); QGraphicsItemGroup::hoverLeaveEvent(event); } -void ToolBoxGraphicsItem::startAnimation(QAbstractAnimation::Direction direction) -{ +void ToolBoxGraphicsItem::startAnimation(QAbstractAnimation::Direction direction) { this->opacityAnimation->setDirection(direction); this->opacityAnimation->start(); } void ToolBoxGraphicsItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, - QWidget* widget) -{ + QWidget* widget) { painter->save(); painter->setPen(Qt::NoPen); painter->setBrush(QBrush(QColor(0xFF, 0xE2, 0x82))); diff --git a/src/modules/im/src/widget/tool/toolboxgraphicsitem.h b/src/modules/im/src/widget/tool/toolboxgraphicsitem.h index 087cf8c2..baaa2e64 100644 --- a/src/modules/im/src/widget/tool/toolboxgraphicsitem.h +++ b/src/modules/im/src/widget/tool/toolboxgraphicsitem.h @@ -17,8 +17,7 @@ #include #include -class ToolBoxGraphicsItem final : public QObject, public QGraphicsItemGroup -{ +class ToolBoxGraphicsItem final : public QObject, public QGraphicsItemGroup { Q_OBJECT Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity) public: @@ -41,4 +40,4 @@ class ToolBoxGraphicsItem final : public QObject, public QGraphicsItemGroup int fadeTimeMs = 300; }; -#endif // TOOLBOXGRAPHICSITEM_HPP +#endif // TOOLBOXGRAPHICSITEM_HPP diff --git a/src/modules/im/src/widget/widget.cpp b/src/modules/im/src/widget/widget.cpp index 9e386476..7d5461d0 100644 --- a/src/modules/im/src/widget/widget.cpp +++ b/src/modules/im/src/widget/widget.cpp @@ -24,8 +24,8 @@ #include #include #include -#include #include +#include #ifdef Q_OS_MAC #include @@ -33,7 +33,9 @@ #include #endif +#include "Bus.h" #include "ChatWidget.h" +#include "application.h" #include "base/OkSettings.h" #include "base/Page.h" #include "base/SvgUtils.h" @@ -75,70 +77,71 @@ #include "src/widget/gui.h" #include "tool/removefrienddialog.h" #include "ui_mainwindow.h" -#include "application.h" -#include "Bus.h" -bool toxActivateEventHandler(const QByteArray &) { - Widget *widget = Nexus::getDesktopGUI(); - if (!widget) { - return true; - } +bool toxActivateEventHandler(const QByteArray&) { + Widget* widget = Nexus::getDesktopGUI(); + if (!widget) { + return true; + } - qDebug() << "Handling [activate] event from other instance"; - widget->forceShow(); + qDebug() << "Handling [activate] event from other instance"; + widget->forceShow(); - return true; + return true; } +static Widget* instance = nullptr; -static Widget *instance = nullptr; - -Widget *Widget::getInstance(){ +Widget* Widget::getInstance() { assert(instance); return instance; }; -Widget::Widget(IAudioControl &audio, QWidget *parent)// - : QFrame(parent), icon{nullptr}, trayMenu{nullptr},// - ui(new Ui::IMMainWindow), eventFlag(false),// - eventIcon(false), audio(audio), // - settings(Settings::getInstance()), // - delayCaller(std::make_unique()) // +Widget::Widget(IAudioControl& audio, QWidget* parent) // + : QFrame(parent) + , icon{nullptr} + , trayMenu{nullptr} + , ui(new Ui::IMMainWindow) + , eventFlag(false) + , eventIcon(false) + , audio(audio) + , settings(Settings::getInstance()) + , delayCaller(std::make_unique()) // { - instance = this; + instance = this; - ui->setupUi(this); - layout()->setSpacing(0); - setObjectName(qsl("Page:%1").arg(static_cast(UI::PageMenu::chat))); + ui->setupUi(this); + layout()->setSpacing(0); - ui->tabWidget->setObjectName("mainTab"); + ui->tabWidget->setObjectName("mainTab"); - chatWidget = new ChatWidget(this); - ui->tabWidget->addTab(chatWidget, tr("Chat")); + chatWidget = new ChatWidget(this); + ui->tabWidget->addTab(chatWidget, tr("Chat")); - contactWidget = new ContactWidget(this); - ui->tabWidget->addTab(contactWidget, tr("Contact")); + contactWidget = new ContactWidget(this); + ui->tabWidget->addTab(contactWidget, tr("Contact")); - settingsWidget = new SettingsWidget(this); - ui->tabWidget->addTab(settingsWidget, tr("Settings")); + settingsWidget = new SettingsWidget(this); + ui->tabWidget->addTab(settingsWidget, tr("Settings")); - installEventFilter(this); + installEventFilter(this); - QString locale = settings.getTranslation(); - settings::Translator::translate(OK_IM_MODULE, locale); - connect(ok::Application::Instance()->bus(), &ok::Bus::languageChanged, [](QString locale0){ - settings::Translator::translate(OK_IM_MODULE, locale0); - }); + QString locale = settings.getTranslation(); + settings::Translator::translate(OK_IM_MODULE, locale); + connect(ok::Application::Instance()->bus(), &ok::Bus::languageChanged, + [](QString locale0) { settings::Translator::translate(OK_IM_MODULE, locale0); }); - - qRegisterMetaType("ToxFile"); + qRegisterMetaType("ToxFile"); QIcon themeIcon = QIcon::fromTheme("qtox"); if (!themeIcon.isNull()) { - setWindowIcon(themeIcon); + setWindowIcon(themeIcon); } timer = new QTimer(); + connect(timer, &QTimer::timeout, this, &Widget::onUserAwayCheck); + connect(timer, &QTimer::timeout, this, &Widget::onEventIconTick); + connect(timer, &QTimer::timeout, this, &Widget::onTryCreateTrayIcon); timer->start(1000); icon_size = 15; @@ -149,34 +152,34 @@ Widget::Widget(IAudioControl &audio, QWidget *parent)// // Preparing icons and set their size statusOnline = new QAction(this); statusOnline->setIcon(SvgUtils::prepareIcon(Status::getIconPath(Status::Status::Online), - icon_size, icon_size)); + icon_size, icon_size)); connect(statusOnline, &QAction::triggered, this, &Widget::setStatusOnline); statusAway = new QAction(this); - statusAway->setIcon(SvgUtils::prepareIcon(Status::getIconPath(Status::Status::Away), - icon_size, icon_size)); + statusAway->setIcon( + SvgUtils::prepareIcon(Status::getIconPath(Status::Status::Away), icon_size, icon_size)); connect(statusAway, &QAction::triggered, this, &Widget::setStatusAway); statusBusy = new QAction(this); - statusBusy->setIcon(SvgUtils::prepareIcon(Status::getIconPath(Status::Status::Busy), - icon_size, icon_size)); + statusBusy->setIcon( + SvgUtils::prepareIcon(Status::getIconPath(Status::Status::Busy), icon_size, icon_size)); connect(statusBusy, &QAction::triggered, this, &Widget::setStatusBusy); actionLogout = new QAction(this); - actionLogout->setIcon(SvgUtils:: - prepareIcon(":/img/others/logout-icon.svg", icon_size, icon_size)); + actionLogout->setIcon( + SvgUtils::prepareIcon(":/img/others/logout-icon.svg", icon_size, icon_size)); actionQuit = new QAction(this); - #ifndef Q_OS_OSX +#ifndef Q_OS_OSX actionQuit->setMenuRole(QAction::QuitRole); - #endif +#endif - actionQuit->setIcon(SvgUtils::prepareIcon( - Style::getImagePath("rejectCall/rejectCall.svg"), icon_size, icon_size)); + actionQuit->setIcon(SvgUtils::prepareIcon(Style::getImagePath("rejectCall/rejectCall.svg"), + icon_size, icon_size)); connect(actionQuit, &QAction::triggered, qApp, &QApplication::quit); // layout()->setContentsMargins(0, 0, 0, 0); - setAttribute(Qt::WA_LayoutOnEntireRect, false); // style sheet will make content margins + setAttribute(Qt::WA_LayoutOnEntireRect, false); // style sheet will make content margins // setContentsMargins(0,0,0,0); // setAutoFillBackground(true); @@ -190,15 +193,11 @@ Widget::Widget(IAudioControl &audio, QWidget *parent)// // ui->myProfile->insertSpacing(1, 7); // } - - // ui->friendList->setWidget(contactListWidget); // ui->friendList->setLayoutDirection(Qt::RightToLeft); // ui->friendList->setContextMenuPolicy(Qt::CustomContextMenu); // ui->statusLabel->setEditable(true); - - // disable proportional scaling // ui->mainSplitter->setStretchFactor(0, 0); // ui->mainSplitter->setStretchFactor(1, 1); @@ -217,101 +216,14 @@ Widget::Widget(IAudioControl &audio, QWidget *parent)// // keyboard shortcuts new QShortcut(QKeySequence(Qt::CTRL, Qt::Key_Q), this, SLOT(close())); - new QShortcut(QKeySequence(Qt::CTRL, Qt::SHIFT , Qt::Key_Tab), this, - SLOT(previousContact())); + new QShortcut(QKeySequence(Qt::CTRL, Qt::SHIFT, Qt::Key_Tab), this, SLOT(previousContact())); new QShortcut(QKeySequence(Qt::CTRL, Qt::Key_Tab), this, SLOT(nextContact())); - new QShortcut(QKeySequence(Qt::CTRL , Qt::Key_PageUp), this, SLOT(previousContact())); - new QShortcut(QKeySequence(Qt::CTRL , Qt::Key_PageDown), this, SLOT(nextContact())); + new QShortcut(QKeySequence(Qt::CTRL, Qt::Key_PageUp), this, SLOT(previousContact())); + new QShortcut(QKeySequence(Qt::CTRL, Qt::Key_PageDown), this, SLOT(nextContact())); new QShortcut(Qt::Key_F11, this, SLOT(toggleFullscreen())); -// #ifdef Q_OS_MAC -// QMenuBar *globalMenu = Nexus::getInstance().globalMenuBar; -// QAction *windowMenu = Nexus::getInstance().windowMenu->menuAction(); -// QAction *viewMenu = Nexus::getInstance().viewMenu->menuAction(); -// QAction *frontAction = Nexus::getInstance().frontAction; - -// fileMenu = globalMenu->insertMenu(viewMenu, new QMenu(this)); - -// editProfileAction = fileMenu->menu()->addAction(QString()); -// connect(editProfileAction, &QAction::triggered, this, &Widget::showProfile); - -// changeStatusMenu = fileMenu->menu()->addMenu(QString()); -// fileMenu->menu()->addAction(changeStatusMenu->menuAction()); -// changeStatusMenu->addAction(statusOnline); -// changeStatusMenu->addSeparator(); -// changeStatusMenu->addAction(statusAway); -// changeStatusMenu->addAction(statusBusy); - -// fileMenu->menu()->addSeparator(); -// logoutAction = fileMenu->menu()->addAction(QString()); -// connect(logoutAction, &QAction::triggered, -// [this]() { Nexus::getInstance().showLogin(); }); - -// editMenu = globalMenu->insertMenu(viewMenu, new QMenu(this)); -// editMenu->menu()->addSeparator(); - -// viewMenu->menu()->insertMenu(Nexus::getInstance().fullscreenAction, -// filterMenu); - -// viewMenu->menu()->insertSeparator(Nexus::getInstance().fullscreenAction); - -// contactMenu = globalMenu->insertMenu(windowMenu, new QMenu(this)); - -// addContactAction = contactMenu->menu()->addAction(QString()); -// connect(addContactAction, &QAction::triggered, this, &Widget::onAddClicked); - -// nextConversationAction = new QAction(this); -// Nexus::getInstance().windowMenu->insertAction(frontAction, -// nextConversationAction); -// nextConversationAction->setShortcut(QKeySequence::SelectNextPage); -// connect(nextConversationAction, &QAction::triggered, [this]() { -// if (ContentDialogManager::getInstance()->current() == -// QApplication::activeWindow()) -// ContentDialogManager::getInstance()->current()->cycleContacts(true); -// else if (QApplication::activeWindow() == this) -// cycleContacts(true); -// }); - -// previousConversationAction = new QAction(this); -// Nexus::getInstance().windowMenu->insertAction(frontAction, -// previousConversationAction); -// previousConversationAction->setShortcut(QKeySequence::SelectPreviousPage); -// connect(previousConversationAction, &QAction::triggered, [this] { -// if (ContentDialogManager::getInstance()->current() == -// QApplication::activeWindow()) -// ContentDialogManager::getInstance()->current()->cycleContacts(false); -// else if (QApplication::activeWindow() == this) -// cycleContacts(false); -// }); - -// windowMenu->menu()->insertSeparator(frontAction); - -// QAction *preferencesAction = viewMenu->menu()->addAction(QString()); -// preferencesAction->setMenuRole(QAction::PreferencesRole); -// connect(preferencesAction, &QAction::triggered, this, -// &Widget::onShowSettings); - -// QAction *aboutAction = viewMenu->menu()->addAction(QString()); -// aboutAction->setMenuRole(QAction::AboutRole); -// connect(aboutAction, &QAction::triggered, [this]() { -// onShowSettings(); -// settingsWidget->showAbout(); -// }); - -// QMenu *dockChangeStatusMenu = new QMenu(tr("Status"), this); -// dockChangeStatusMenu->addAction(statusOnline); -// statusOnline->setIconVisibleInMenu(true); -// dockChangeStatusMenu->addSeparator(); -// dockChangeStatusMenu->addAction(statusAway); -// dockChangeStatusMenu->addAction(statusBusy); -// Nexus::getInstance().dockMenu->addAction(dockChangeStatusMenu->menuAction()); - -// connect(this, &Widget::windowStateChanged, &Nexus::getInstance(), -// &Nexus::onWindowStateChanged); -// #endif - -// onSeparateWindowChanged(settings.getSeparateWindow(), false); + // onSeparateWindowChanged(settings.getSeparateWindow(), false); // ui->addButton->setCheckable(true); // ui->groupButton->setCheckable(true); @@ -328,472 +240,437 @@ Widget::Widget(IAudioControl &audio, QWidget *parent)// // SplitterRestorer restorer(ui->mainSplitter); // restorer.restore(settings.getSplitterState(), size()); -// friendRequestsButton = nullptr; -// groupInvitesButton = nullptr; -// unreadGroupInvites = 0; -// -// connect(groupInviteForm, &GroupInviteForm::groupInvitesSeen, this, -// &Widget::groupInvitesClear); -// connect(groupInviteForm, &GroupInviteForm::groupInviteAccepted, this, -// &Widget::onGroupInviteAccepted); - - + // friendRequestsButton = nullptr; + // groupInvitesButton = nullptr; + // unreadGroupInvites = 0; + // + // connect(groupInviteForm, &GroupInviteForm::groupInvitesSeen, this, + // &Widget::groupInvitesClear); + // connect(groupInviteForm, &GroupInviteForm::groupInviteAccepted, this, + // &Widget::onGroupInviteAccepted); reloadTheme(); updateIcons(); retranslateUi(); - settings::Translator::registerHandler(std::bind(&Widget::retranslateUi, this), - this); + settings::Translator::registerHandler(std::bind(&Widget::retranslateUi, this), this); // settings - auto &okSettings = ok::base::OkSettings::getInstance(); + auto& okSettings = ok::base::OkSettings::getInstance(); connect(&okSettings, &ok::base::OkSettings::showSystemTrayChanged, this, &Widget::onSetShowSystemTray); if (!okSettings.getShowSystemTray()) { - show(); + show(); } - - connect(&settings, &Settings::separateWindowChanged, this, - &Widget::onSeparateWindowClicked); + connect(&settings, &Settings::separateWindowChanged, this, &Widget::onSeparateWindowClicked); #ifdef Q_OS_MAC Nexus::getInstance().updateWindows(); #endif - init(); + init(); } void Widget::init() { - profile = Nexus::getProfile(); + // profile = Nexus::getProfile(); - connect(this, &Widget::toSendMessage, [&](){ - ui->tabWidget->setCurrentIndex(0); - }); + connect(this, &Widget::toSendMessage, [&]() { ui->tabWidget->setCurrentIndex(0); }); - connect(this, &Widget::toShowDetails, [&](){ - ui->tabWidget->setCurrentIndex(1); - }); + connect(this, &Widget::toShowDetails, [&]() { ui->tabWidget->setCurrentIndex(1); }); #if UPDATE_CHECK_ENABLED - updateCheck = std::unique_ptr(new UpdateCheck(settings)); - connect(updateCheck.get(), &UpdateCheck::updateAvailable, this, - &Widget::onUpdateAvailable); + updateCheck = std::unique_ptr(new UpdateCheck(settings)); + connect(updateCheck.get(), &UpdateCheck::updateAvailable, this, &Widget::onUpdateAvailable); #endif #if UPDATE_CHECK_ENABLED - updateCheck->checkForUpdate(); + updateCheck->checkForUpdate(); #endif - - - } -bool Widget::eventFilter(QObject *obj, QEvent *event) { - QWindowStateChangeEvent *ce = nullptr; - Qt::WindowStates state = windowState(); - - switch (event->type()) { - case QEvent::Close: - // It's needed if user enable `Close to tray` - wasMaximized = state.testFlag(Qt::WindowMaximized); - break; - case QEvent::WindowStateChange: - ce = static_cast(event); - if (state.testFlag(Qt::WindowMinimized) && obj) { - wasMaximized = ce->oldState().testFlag(Qt::WindowMaximized); - } +bool Widget::eventFilter(QObject* obj, QEvent* event) { + QWindowStateChangeEvent* ce = nullptr; + Qt::WindowStates state = windowState(); + + switch (event->type()) { + case QEvent::Close: + // It's needed if user enable `Close to tray` + wasMaximized = state.testFlag(Qt::WindowMaximized); + break; + case QEvent::WindowStateChange: + ce = static_cast(event); + if (state.testFlag(Qt::WindowMinimized) && obj) { + wasMaximized = ce->oldState().testFlag(Qt::WindowMaximized); + } #ifdef Q_OS_MAC - emit windowStateChanged(windowState()); + emit windowStateChanged(windowState()); #endif - break; - default: - break; - } + break; + default: + break; + } - return false; + return false; } void Widget::updateIcons() { - if (!icon) { - return; - } - - - // Some builds of Qt appear to have a bug in icon loading: - // QIcon::hasThemeIcon is sometimes unaware that the icon returned - // from QIcon::fromTheme was a fallback icon, causing hasThemeIcon to - // incorrectly return true. - // - // In qTox this leads to the tray and window icons using the static qTox logo - // icon instead of an icon based on the current presence status. - // - // This workaround checks for an icon that definitely does not exist to - // determine if hasThemeIcon can be trusted. - // - // On systems with the Qt bug, this workaround will always use our included - // icons but user themes will be unable to override them. - static bool checkedHasThemeIcon = false; - static bool hasThemeIconBug = false; - - if (!checkedHasThemeIcon) { - hasThemeIconBug = QIcon::hasThemeIcon("qtox-asjkdfhawjkeghdfjgh"); - checkedHasThemeIcon = true; - - if (hasThemeIconBug) { - qDebug() << "Detected buggy QIcon::hasThemeIcon. Icon overrides from " - "theme will be ignored."; + if (!icon) { + return; } - } - -// QIcon ico; -// if (!hasThemeIconBug && QIcon::hasThemeIcon("qtox-" + assetSuffix)) { -// ico = QIcon::fromTheme("qtox-" + assetSuffix); -// } else { -// QString color = settings.getLightTrayIcon() ? "light" : "dark"; -// QString path = -// ":/img/taskbar/" + color + "/taskbar_" + assetSuffix + ".svg"; -// QSvgRenderer renderer(path); -// -// // Prepare a QImage with desired characteritisc -// QImage image = QImage(250, 250, QImage::Format_ARGB32); -// image.fill(Qt::transparent); -// QPainter painter(&image); -// renderer.render(&painter); -// ico = QIcon(QPixmap::fromImage(image)); -// } -// setWindowIcon(ico); -// if (icon) { -// icon->setIcon(ico); -// } + // Some builds of Qt appear to have a bug in icon loading: + // QIcon::hasThemeIcon is sometimes unaware that the icon returned + // from QIcon::fromTheme was a fallback icon, causing hasThemeIcon to + // incorrectly return true. + // + // In qTox this leads to the tray and window icons using the static qTox logo + // icon instead of an icon based on the current presence status. + // + // This workaround checks for an icon that definitely does not exist to + // determine if hasThemeIcon can be trusted. + // + // On systems with the Qt bug, this workaround will always use our included + // icons but user themes will be unable to override them. + static bool checkedHasThemeIcon = false; + static bool hasThemeIconBug = false; + + if (!checkedHasThemeIcon) { + hasThemeIconBug = QIcon::hasThemeIcon("qtox-asjkdfhawjkeghdfjgh"); + checkedHasThemeIcon = true; + + if (hasThemeIconBug) { + qDebug() << "Detected buggy QIcon::hasThemeIcon. Icon overrides from " + "theme will be ignored."; + } + } + + // QIcon ico; + // if (!hasThemeIconBug && QIcon::hasThemeIcon("qtox-" + assetSuffix)) { + // ico = QIcon::fromTheme("qtox-" + assetSuffix); + // } else { + // QString color = settings.getLightTrayIcon() ? "light" : "dark"; + // QString path = + // ":/img/taskbar/" + color + "/taskbar_" + assetSuffix + ".svg"; + // QSvgRenderer renderer(path); + // + // // Prepare a QImage with desired characteritisc + // QImage image = QImage(250, 250, QImage::Format_ARGB32); + // image.fill(Qt::transparent); + // QPainter painter(&image); + // renderer.render(&painter); + // ico = QIcon(QPixmap::fromImage(image)); + // } + + // setWindowIcon(ico); + // if (icon) { + // icon->setIcon(ico); + // } } Widget::~Widget() { - qDebug() << __func__; + qDebug() << __func__; - settings::Translator::unregister(this); - if (icon) { - icon->hide(); - } + settings::Translator::unregister(this); + if (icon) { + icon->hide(); + } - delete timer; - delete trayMenu; - delete ui; + delete timer; + delete trayMenu; + delete ui; } /** * @brief Switches to the About settings page. */ void Widget::showUpdateDownloadProgress() { - onShowSettings(); - settingsWidget->showAbout(); + onShowSettings(); + settingsWidget->showAbout(); } -void Widget::moveEvent(QMoveEvent *event) { - if (event->type() == QEvent::Move) { - saveWindowGeometry(); - saveSplitterGeometry(); - } - - QWidget::moveEvent(event); -} +void Widget::moveEvent(QMoveEvent* event) { + if (event->type() == QEvent::Move) { + saveWindowGeometry(); + saveSplitterGeometry(); + } -void Widget::closeEvent(QCloseEvent *event) { - // if (settings.getShowSystemTray() && settings.getCloseToTray()) { - QWidget::closeEvent(event); - // } else { - // if (autoAwayActive) { - // emit statusSet(Status::Status::Online); - // autoAwayActive = false; - // } - // saveWindowGeometry(); - // saveSplitterGeometry(); - // QWidget::closeEvent(event); - // qApp->quit(); - // } + QWidget::moveEvent(event); +} + +void Widget::closeEvent(QCloseEvent* event) { + // if (settings.getShowSystemTray() && settings.getCloseToTray()) { + QWidget::closeEvent(event); + // } else { + // if (autoAwayActive) { + // emit statusSet(Status::Status::Online); + // autoAwayActive = false; + // } + // saveWindowGeometry(); + // saveSplitterGeometry(); + // QWidget::closeEvent(event); + // qApp->quit(); + // } } -void Widget::changeEvent(QEvent *event) { - // if (event->type() == QEvent::WindowStateChange) { - // if (isMinimized() && settings.getShowSystemTray() && - // settings.getMinimizeToTray()) { - // this->hide(); - // } - // } +void Widget::changeEvent(QEvent* event) { + // if (event->type() == QEvent::WindowStateChange) { + // if (isMinimized() && settings.getShowSystemTray() && + // settings.getMinimizeToTray()) { + // this->hide(); + // } + // } } -void Widget::resizeEvent(QResizeEvent *event) { - saveWindowGeometry(); - QWidget::resizeEvent(event); +void Widget::resizeEvent(QResizeEvent* event) { + saveWindowGeometry(); + QWidget::resizeEvent(event); } -QString Widget::getUsername() { return core->getUsername(); } - -void Widget::onSelfAvatarLoaded(const QPixmap &pic) { +QString Widget::getUsername() { return Nexus::getProfile()->getCore()->getUsername(); } - if(pic.size().isEmpty()){ - qWarning()<<__func__<<"pic is empty."; - return; - } -// profilePicture->setPixmap(pic); +void Widget::onSelfAvatarLoaded(const QPixmap& pic) { + if (pic.size().isEmpty()) { + qWarning() << __func__ << "pic is empty."; + return; + } + // profilePicture->setPixmap(pic); } -void Widget::onCoreChanged(Core &coreRef) { - core = &coreRef; - connectToCore(coreRef); +void Widget::onCoreChanged(Core& coreRef) { + core = &coreRef; + connectToCore(coreRef); } -void Widget::connectToCore(Core &core) { - connect(&core, &Core::connected, this, &Widget::onConnected); - connect(&core, &Core::disconnected, this, &Widget::onDisconnected); - connect(&core, &Core::statusSet, this, &Widget::onStatusSet); - connect(&core, &Core::usernameSet, this, &Widget::setUsername); - connect(&core, &Core::avatarSet, this, &Widget::setAvatar); - connect(&core, &Core::failedToAddFriend, this, &Widget::addFriendFailed); - - connect(this, &Widget::statusSet, &core, &Core::setStatus); - connect(this, &Widget::changeGroupTitle, &core, &Core::setGroupName); - - connect(timer, &QTimer::timeout, this, &Widget::onUserAwayCheck); - connect(timer, &QTimer::timeout, this, &Widget::onEventIconTick); - connect(timer, &QTimer::timeout, this, &Widget::onTryCreateTrayIcon); - +void Widget::connectToCore(Core& core) { + connect(&core, &Core::connected, this, &Widget::onConnected); + connect(&core, &Core::disconnected, this, &Widget::onDisconnected); + connect(&core, &Core::statusSet, this, &Widget::onStatusSet); + connect(&core, &Core::usernameSet, this, &Widget::setUsername); + connect(&core, &Core::avatarSet, this, &Widget::setAvatar); + connect(&core, &Core::failedToAddFriend, this, &Widget::addFriendFailed); - - core.setUIStarted(); + connect(this, &Widget::statusSet, &core, &Core::setStatus); + connect(this, &Widget::changeGroupTitle, &core, &Core::setGroupName); } void Widget::onConnected() { -// ui->statusButton->setEnabled(true); -// emit core->statusSet(core->getStatus()); + // ui->statusButton->setEnabled(true); + // emit core->statusSet(core->getStatus()); } void Widget::onDisconnected() { -// ui->statusButton->setEnabled(false); -// emit core->statusSet(Status::Status::Offline); + // ui->statusButton->setEnabled(false); + // emit core->statusSet(Status::Status::Offline); } void Widget::onFailedToStartCore() { - QMessageBox critical(this); - critical.setText(tr("toxcore failed to start, the application will terminate " - "after you close this message.")); - critical.setIcon(QMessageBox::Critical); - critical.exec(); - qApp->exit(EXIT_FAILURE); + QMessageBox critical(this); + critical.setText( + tr("toxcore failed to start, the application will terminate " + "after you close this message.")); + critical.setIcon(QMessageBox::Critical); + critical.exec(); + qApp->exit(EXIT_FAILURE); } void Widget::onBadProxyCore() { - settings.setProxyType(Settings::ProxyType::ptNone); - QMessageBox critical(this); - critical.setText(tr("toxcore failed to start with your proxy settings. " - "qTox cannot run; please modify your " - "settings and restart.", - "popup text")); - critical.setIcon(QMessageBox::Critical); - critical.exec(); - onShowSettings(); + settings.setProxyType(Settings::ProxyType::ptNone); + QMessageBox critical(this); + critical.setText( + tr("toxcore failed to start with your proxy settings. " + "qTox cannot run; please modify your " + "settings and restart.", + "popup text")); + critical.setIcon(QMessageBox::Critical); + critical.exec(); + onShowSettings(); } void Widget::onStatusSet(Status::Status status) { -// ui->statusButton->setProperty("status", static_cast(status)); -// ui->statusButton->setIcon( -// prepareIcon(getIconPath(status), icon_size, icon_size)); -// updateIcons(); + // ui->statusButton->setProperty("status", static_cast(status)); + // ui->statusButton->setIcon( + // prepareIcon(getIconPath(status), icon_size, icon_size)); + // updateIcons(); } -void Widget::onSeparateWindowClicked(bool separate) { - onSeparateWindowChanged(separate, true); -} +void Widget::onSeparateWindowClicked(bool separate) { onSeparateWindowChanged(separate, true); } void Widget::onSeparateWindowChanged(bool separate, bool clicked) { - if (!separate) { - QWindowList windowList = QGuiApplication::topLevelWindows(); + if (!separate) { + QWindowList windowList = QGuiApplication::topLevelWindows(); - for (QWindow *window : windowList) { - if (window->objectName() == "detachedWindow") { - window->close(); - } - } + for (QWindow* window : windowList) { + if (window->objectName() == "detachedWindow") { + window->close(); + } + } + // SplitterRestorer restorer(ui->mainSplitter); + // restorer.restore(settings.getSplitterState(), size()); -// SplitterRestorer restorer(ui->mainSplitter); -// restorer.restore(settings.getSplitterState(), size()); + onShowSettings(); + } else { + // int width = ui->friendList->size().width(); + QSize size; + QPoint pos; + + // if (contentLayout) { + // pos = mapToGlobal(ui->mainSplitter->widget(1)->pos()); + // size = ui->mainSplitter->widget(1)->size(); + // } + + // if (contentLayout) { + // contentLayout->clear(); + // contentLayout->parentWidget()->setParent( + // nullptr); // Remove from splitter. + // contentLayout->parentWidget()->hide(); + // contentLayout->parentWidget()->deleteLater(); + // contentLayout->deleteLater(); + // contentLayout = nullptr; + // } + + // setMinimumWidth(ui->tooliconsZone->sizeHint().width()); + + if (clicked) { + showNormal(); + // resize(width, height()); + + if (settingsWidget) { + ContentLayout* contentLayout = createContentDialog((DialogType::SettingDialog)); + contentLayout->parentWidget()->resize(size); + contentLayout->parentWidget()->move(pos); + settingsWidget->show(contentLayout); + } + } - onShowSettings(); - } else { -// int width = ui->friendList->size().width(); - QSize size; - QPoint pos; - -// if (contentLayout) { -// pos = mapToGlobal(ui->mainSplitter->widget(1)->pos()); -// size = ui->mainSplitter->widget(1)->size(); -// } - -// if (contentLayout) { -// contentLayout->clear(); -// contentLayout->parentWidget()->setParent( -// nullptr); // Remove from splitter. -// contentLayout->parentWidget()->hide(); -// contentLayout->parentWidget()->deleteLater(); -// contentLayout->deleteLater(); -// contentLayout = nullptr; -// } - -// setMinimumWidth(ui->tooliconsZone->sizeHint().width()); - - if (clicked) { - showNormal(); -// resize(width, height()); - - if (settingsWidget) { - ContentLayout *contentLayout = - createContentDialog((DialogType::SettingDialog)); - contentLayout->parentWidget()->resize(size); - contentLayout->parentWidget()->move(pos); - settingsWidget->show(contentLayout); - } + setWindowTitle(QString()); } - - setWindowTitle(QString()); - } } -void Widget::setWindowTitle(const QString &title) { - // if (title.isEmpty()) { - // setWindowTitle(QApplication::applicationName()); - // } else { - // QString tmp = title; - // /// <[^>]*> Regexp to remove HTML tags, in case someone used them in - // title setWindowTitle(QApplication::applicationName() + - // QStringLiteral(" - ") + - // tmp.remove(QRegExp("<[^>]*>"))); - // } +void Widget::setWindowTitle(const QString& title) { + // if (title.isEmpty()) { + // setWindowTitle(QApplication::applicationName()); + // } else { + // QString tmp = title; + // /// <[^>]*> Regexp to remove HTML tags, in case someone used them in + // title setWindowTitle(QApplication::applicationName() + + // QStringLiteral(" - ") + + // tmp.remove(QRegExp("<[^>]*>"))); + // } } void Widget::forceShow() { - hide(); - // Workaround to force minimized window to be restored - show(); - activateWindow(); + hide(); + // Workaround to force minimized window to be restored + show(); + activateWindow(); } void Widget::onTransferClicked() { -// if (settings.getSeparateWindow()) { -// if (!filesForm->isShown()) { -// filesForm->show(createContentDialog(DialogType::TransferDialog)); -// } - -// setActiveToolMenuButton(ActiveToolMenuButton::None); -// } else { -// hideMainForms(nullptr); -//// filesForm->show(contentLayout); -// setWindowTitle(fromDialogType(DialogType::TransferDialog)); -// setActiveToolMenuButton(ActiveToolMenuButton::TransferButton); -// } + // if (settings.getSeparateWindow()) { + // if (!filesForm->isShown()) { + // filesForm->show(createContentDialog(DialogType::TransferDialog)); + // } + + // setActiveToolMenuButton(ActiveToolMenuButton::None); + // } else { + // hideMainForms(nullptr); + //// filesForm->show(contentLayout); + // setWindowTitle(fromDialogType(DialogType::TransferDialog)); + // setActiveToolMenuButton(ActiveToolMenuButton::TransferButton); + // } } -void Widget::confirmExecutableOpen(const QFileInfo &file) { - static const QStringList dangerousExtensions = { - "app", "bat", "com", "cpl", "dmg", "exe", "hta", "jar", - "js", "jse", "lnk", "msc", "msh", "msh1", "msh1xml", "msh2", - "msh2xml", "mshxml", "msi", "msp", "pif", "ps1", "ps1xml", "ps2", - "ps2xml", "psc1", "psc2", "py", "reg", "scf", "sh", "src", - "vb", "vbe", "vbs", "ws", "wsc", "wsf", "wsh"}; - - if (dangerousExtensions.contains(file.suffix())) { - bool answer = GUI::askQuestion( - tr("Executable file", "popup title"), - tr("You have asked qTox to open an executable file. " - "Executable files can potentially damage your computer. " - "Are you sure want to open this file?", - "popup text"), - false, true); - if (!answer) { - return; - } +void Widget::confirmExecutableOpen(const QFileInfo& file) { + static const QStringList dangerousExtensions = { + "app", "bat", "com", "cpl", "dmg", "exe", "hta", "jar", "js", "jse", + "lnk", "msc", "msh", "msh1", "msh1xml", "msh2", "msh2xml", "mshxml", "msi", "msp", + "pif", "ps1", "ps1xml", "ps2", "ps2xml", "psc1", "psc2", "py", "reg", "scf", + "sh", "src", "vb", "vbe", "vbs", "ws", "wsc", "wsf", "wsh"}; + + if (dangerousExtensions.contains(file.suffix())) { + bool answer = GUI::askQuestion(tr("Executable file", "popup title"), + tr("You have asked qTox to open an executable file. " + "Executable files can potentially damage your computer. " + "Are you sure want to open this file?", + "popup text"), + false, true); + if (!answer) { + return; + } - // The user wants to run this file, so make it executable and run it - QFile(file.filePath()) - .setPermissions(file.permissions() | QFile::ExeOwner | QFile::ExeUser | - QFile::ExeGroup | QFile::ExeOther); - } + // The user wants to run this file, so make it executable and run it + QFile(file.filePath()) + .setPermissions(file.permissions() | QFile::ExeOwner | QFile::ExeUser | + QFile::ExeGroup | QFile::ExeOther); + } - QDesktopServices::openUrl(QUrl::fromLocalFile(file.filePath())); + QDesktopServices::openUrl(QUrl::fromLocalFile(file.filePath())); } void Widget::onIconClick(QSystemTrayIcon::ActivationReason reason) { - if (reason == QSystemTrayIcon::Trigger) { - if (isHidden() || isMinimized()) { - if (wasMaximized) { - showMaximized(); - } else { - showNormal(); - } - - activateWindow(); - } else if (!isActiveWindow()) { - activateWindow(); - } else { - wasMaximized = isMaximized(); - hide(); - } - } else if (reason == QSystemTrayIcon::Unknown) { - if (isHidden()) { - forceShow(); + if (reason == QSystemTrayIcon::Trigger) { + if (isHidden() || isMinimized()) { + if (wasMaximized) { + showMaximized(); + } else { + showNormal(); + } + + activateWindow(); + } else if (!isActiveWindow()) { + activateWindow(); + } else { + wasMaximized = isMaximized(); + hide(); + } + } else if (reason == QSystemTrayIcon::Unknown) { + if (isHidden()) { + forceShow(); + } } - } } void Widget::onShowSettings() { - if (settings.getSeparateWindow()) { - if (!settingsWidget->isShown()) { - settingsWidget->show(createContentDialog(DialogType::SettingDialog)); - } - -// setActiveToolMenuButton(ActiveToolMenuButton::None); - } else { - hideMainForms(nullptr); -// settingsWidget->show(contentLayout); - // setWindowTitle(fromDialogType(DialogType::SettingDialog)); -// setActiveToolMenuButton(ActiveToolMenuButton::SettingButton); - } -} - - -void Widget::hideMainForms(GenericChatroomWidget *chatroomWidget) { + if (settings.getSeparateWindow()) { + if (!settingsWidget->isShown()) { + settingsWidget->show(createContentDialog(DialogType::SettingDialog)); + } + // setActiveToolMenuButton(ActiveToolMenuButton::None); + } else { + hideMainForms(nullptr); + // settingsWidget->show(contentLayout); + // setWindowTitle(fromDialogType(DialogType::SettingDialog)); + // setActiveToolMenuButton(ActiveToolMenuButton::SettingButton); + } } -void Widget::setUsername(const QString &username) { +void Widget::hideMainForms(GenericChatroomWidget* chatroomWidget) {} -} +void Widget::setUsername(const QString& username) {} -void Widget::onStatusMessageChanged(const QString &newStatusMessage) { - // Keep old status message until Core tells us to set it. - core->setStatusMessage(newStatusMessage); +void Widget::onStatusMessageChanged(const QString& newStatusMessage) { + // Keep old status message until Core tells us to set it. + core->setStatusMessage(newStatusMessage); } -void Widget::setAvatar( QByteArray avatar) { - if (avatar.isEmpty()) - { - qWarning() << __func__ <<"avatar is empty!"; +void Widget::setAvatar(QByteArray avatar) { + if (avatar.isEmpty()) { + qWarning() << __func__ << "avatar is empty!"; return; } QPixmap pixmap; - if(!base::Images::putToPixmap(avatar, pixmap)) - { - qWarning()<<"loadFromData failed."; - return; - } - - emit avatarSet(pixmap); + if (!base::Images::putToPixmap(avatar, pixmap)) { + qWarning() << "loadFromData failed."; + return; + } -// profilePicture->setPixmap(pixmap); -// profileInfo->setAvatar(pixmap); + emit avatarSet(pixmap); + // profilePicture->setPixmap(pixmap); + // profileInfo->setAvatar(pixmap); } /** @@ -802,42 +679,41 @@ void Widget::setAvatar( QByteArray avatar) { * @param loop if true, loop the sound until onStopNotification() is called */ void Widget::playNotificationSound(IAudioSink::Sound sound, bool loop) { - if (!settings.getAudioOutDevEnabled()) { - // don't try to play sounds if audio is disabled - return; - } + if (!settings.getAudioOutDevEnabled()) { + // don't try to play sounds if audio is disabled + return; + } - if (audioNotification == nullptr) { - audioNotification = std::unique_ptr(audio.makeSink()); if (audioNotification == nullptr) { - qDebug() << "Failed to allocate AudioSink"; - return; + audioNotification = std::unique_ptr(audio.makeSink()); + if (audioNotification == nullptr) { + qDebug() << "Failed to allocate AudioSink"; + return; + } } - } - audioNotification->connectTo_finishedPlaying( - this, [this]() { cleanupNotificationSound(); }); + audioNotification->connectTo_finishedPlaying(this, [this]() { cleanupNotificationSound(); }); - audioNotification->playMono16Sound(sound); + audioNotification->playMono16Sound(sound); - if (loop) { - audioNotification->startLoop(); - } + if (loop) { + audioNotification->startLoop(); + } } void Widget::cleanupNotificationSound() { audioNotification.reset(); } void Widget::incomingNotification(QString friendnumber) { - const auto &friendId = FriendId(friendnumber); - newFriendMessageAlert(friendId, {}, false); + const auto& friendId = FriendId(friendnumber); + newFriendMessageAlert(friendId, {}, false); - // loop until call answered or rejected - playNotificationSound(IAudioSink::Sound::IncomingCall, true); + // loop until call answered or rejected + playNotificationSound(IAudioSink::Sound::IncomingCall, true); } void Widget::outgoingNotification() { - // loop until call answered or rejected - playNotificationSound(IAudioSink::Sound::OutgoingCall, true); + // loop until call answered or rejected + playNotificationSound(IAudioSink::Sound::OutgoingCall, true); } /** @@ -845,613 +721,587 @@ void Widget::outgoingNotification() { */ void Widget::onStopNotification() { audioNotification.reset(); } +void Widget::addFriendFailed(const FriendId&, const QString& errorInfo) { + QString info = QString(tr("Couldn't request friendship")); + if (!errorInfo.isEmpty()) { + info = info + QStringLiteral(": ") + errorInfo; + } -void Widget::addFriendFailed(const FriendId &, const QString &errorInfo) { - QString info = QString(tr("Couldn't request friendship")); - if (!errorInfo.isEmpty()) { - info = info + QStringLiteral(": ") + errorInfo; - } - - QMessageBox::critical(nullptr, "Error", info); + QMessageBox::critical(nullptr, "Error", info); } - -void Widget::onChatroomWidgetClicked(GenericChatroomWidget *widget) { - openDialog(widget, /* newWindow = */ false); +void Widget::onChatroomWidgetClicked(GenericChatroomWidget* widget) { + openDialog(widget, /* newWindow = */ false); } -void Widget::openNewDialog(GenericChatroomWidget *widget) { - openDialog(widget, /* newWindow = */ true); +void Widget::openNewDialog(GenericChatroomWidget* widget) { + openDialog(widget, /* newWindow = */ true); } -void Widget::openDialog(GenericChatroomWidget *widget, bool newWindow) { - widget->resetEventFlags(); -// widget->updateStatusLight(); +void Widget::openDialog(GenericChatroomWidget* widget, bool newWindow) { + widget->resetEventFlags(); + // widget->updateStatusLight(); -// GenericChatForm *form; -// GroupId id; -//// const IMFriend *frnd = widget->getFriend(); -//// const Group *group = widget->getGroup(); -//// if (frnd) { -//// form = chatForms[frnd->getPublicKey()]; -//// } else if (group) { -//// id = group->getPersistentId(); -//// form = groupChatForms[id].data(); -//// } -// bool chatFormIsSet; -// ContentDialogManager::getInstance()->focusContact(id); -// chatFormIsSet = ContentDialogManager::getInstance()->contactWidgetExists(id); - -// if ((chatFormIsSet || form->isVisible()) && !newWindow) { -// return; -// } + // GenericChatForm *form; + // GroupId id; + //// const IMFriend *frnd = widget->getFriend(); + //// const Group *group = widget->getGroup(); + //// if (frnd) { + //// form = chatForms[frnd->getPublicKey()]; + //// } else if (group) { + //// id = group->getPersistentId(); + //// form = groupChatForms[id].data(); + //// } + // bool chatFormIsSet; + // ContentDialogManager::getInstance()->focusContact(id); + // chatFormIsSet = ContentDialogManager::getInstance()->contactWidgetExists(id); -// if (settings.getSeparateWindow() || newWindow) { -// ContentDialog *dialog = nullptr; - -// if (!settings.getDontGroupWindows() && !newWindow) { -// dialog = ContentDialogManager::getInstance()->current(); -// } - -// if (dialog == nullptr) { -// dialog = createContentDialog(); -// } - -// dialog->show(); - -// if (frnd) { -// addFriendDialog(frnd, dialog); -// } else { -// auto group = widget->getGroup(); -// addGroupDialog(group, dialog); -// } - -// dialog->raise(); -// dialog->activateWindow(); -// } else { -// hideMainForms(widget); -// if (frnd) { -//// chatForms[frnd->getPublicKey()]->show(contentLayout); -//// } else { -//// groupChatForms[group->getPersistentId()]->show(contentLayout); -// } -// widget->setAsActiveChatroom(); -// setWindowTitle(widget->getSubject()); -// } + // if ((chatFormIsSet || form->isVisible()) && !newWindow) { + // return; + // } + + // if (settings.getSeparateWindow() || newWindow) { + // ContentDialog *dialog = nullptr; + + // if (!settings.getDontGroupWindows() && !newWindow) { + // dialog = ContentDialogManager::getInstance()->current(); + // } + + // if (dialog == nullptr) { + // dialog = createContentDialog(); + // } + + // dialog->show(); + + // if (frnd) { + // addFriendDialog(frnd, dialog); + // } else { + // auto group = widget->getGroup(); + // addGroupDialog(group, dialog); + // } + + // dialog->raise(); + // dialog->activateWindow(); + // } else { + // hideMainForms(widget); + // if (frnd) { + //// chatForms[frnd->getPublicKey()]->show(contentLayout); + //// } else { + //// groupChatForms[group->getPersistentId()]->show(contentLayout); + // } + // widget->setAsActiveChatroom(); + // setWindowTitle(widget->getSubject()); + // } } -bool Widget::newFriendMessageAlert(const FriendId &friendId, const QString &text, - bool sound, bool file) { - bool hasActive; - QWidget *currentWindow; - ContentDialog *contentDialog = - ContentDialogManager::getInstance()->getFriendDialog(friendId); - Friend *f = FriendList::findFriend(friendId); - - if (contentDialog != nullptr) { - currentWindow = contentDialog->window(); - hasActive = ContentDialogManager::getInstance()->isContactActive(friendId); - } else { - if (settings.getSeparateWindow() && settings.getShowWindow()) { - if (settings.getDontGroupWindows()) { - contentDialog = createContentDialog(); - } else { - contentDialog = ContentDialogManager::getInstance()->current(); - if (!contentDialog) { - contentDialog = createContentDialog(); - } - } +bool Widget::newFriendMessageAlert(const FriendId& friendId, const QString& text, bool sound, + bool file) { + bool hasActive; + QWidget* currentWindow; + ContentDialog* contentDialog = ContentDialogManager::getInstance()->getFriendDialog(friendId); + Friend* f = FriendList::findFriend(friendId); - currentWindow = contentDialog->window(); - hasActive = - ContentDialogManager::getInstance()->isContactActive(friendId); + if (contentDialog != nullptr) { + currentWindow = contentDialog->window(); + hasActive = ContentDialogManager::getInstance()->isContactActive(friendId); } else { - currentWindow = window(); - } - } + if (settings.getSeparateWindow() && settings.getShowWindow()) { + if (settings.getDontGroupWindows()) { + contentDialog = createContentDialog(); + } else { + contentDialog = ContentDialogManager::getInstance()->current(); + if (!contentDialog) { + contentDialog = createContentDialog(); + } + } + + currentWindow = contentDialog->window(); + hasActive = ContentDialogManager::getInstance()->isContactActive(friendId); + } else { + currentWindow = window(); + } + } - if (newMessageAlert(currentWindow, hasActive, sound)) { + if (newMessageAlert(currentWindow, hasActive, sound)) { #if DESKTOP_NOTIFICATIONS - if (settings.getNotifyHide()) { - notifier.notifyMessageSimple(file - ? DesktopNotify::MessageType::FRIEND_FILE - : DesktopNotify::MessageType::FRIEND); - } else { - QString title = f->getDisplayedName(); - if (file) { - title += " - " + tr("File sent"); - } - notifier.notifyMessagePixmap( - title, text, Nexus::getProfile()->loadAvatar(f->getPublicKey())); - } + if (settings.getNotifyHide()) { + notifier.notifyMessageSimple(file ? DesktopNotify::MessageType::FRIEND_FILE + : DesktopNotify::MessageType::FRIEND); + } else { + QString title = f->getDisplayedName(); + if (file) { + title += " - " + tr("File sent"); + } + notifier.notifyMessagePixmap(title, text, + Nexus::getProfile()->loadAvatar(f->getPublicKey())); + } #endif - if (contentDialog == nullptr) { - if (hasActive) { -// setWindowTitle(widget->getSubject()); - } - } else { - ContentDialogManager::getInstance()->updateFriendStatus(friendId); - } + if (contentDialog == nullptr) { + if (hasActive) { + // setWindowTitle(widget->getSubject()); + } + } else { + ContentDialogManager::getInstance()->updateFriendStatus(friendId); + } - return true; - } + return true; + } - return false; + return false; } -bool Widget::newGroupMessageAlert(const GroupId &groupId, const FriendId &authorPk, - const QString &message, bool notify) { - - qDebug() << __func__ <<"groupId" << groupId.toString()<< "message"<< message; +bool Widget::newGroupMessageAlert(const GroupId& groupId, const FriendId& authorPk, + const QString& message, bool notify) { + qDebug() << __func__ << "groupId" << groupId.toString() << "message" << message; bool hasActive = false; - QWidget *currentWindow = - currentWindow = window(); - + QWidget* currentWindow = currentWindow = window(); - if (!newMessageAlert(currentWindow, hasActive, true, notify)) { - return false; - } + if (!newMessageAlert(currentWindow, hasActive, true, notify)) { + return false; + } // g->setEventFlag(true); // widget->updateStatusLight(); #if DESKTOP_NOTIFICATIONS - if (settings.getNotifyHide()) { - notifier.notifyMessageSimple(DesktopNotify::MessageType::GROUP); - } else { - IMFriend *f = FriendList::findFriend(authorPk); - QString title = - g->getPeerList().value(authorPk) + " (" + g->getDisplayedName() + ")"; - if (!f) { - notifier.notifyMessage(title, message); + if (settings.getNotifyHide()) { + notifier.notifyMessageSimple(DesktopNotify::MessageType::GROUP); } else { - notifier.notifyMessagePixmap( - title, message, Nexus::getProfile()->loadAvatar(f->getPublicKey())); + IMFriend* f = FriendList::findFriend(authorPk); + QString title = g->getPeerList().value(authorPk) + " (" + g->getDisplayedName() + ")"; + if (!f) { + notifier.notifyMessage(title, message); + } else { + notifier.notifyMessagePixmap(title, message, + Nexus::getProfile()->loadAvatar(f->getPublicKey())); + } } - } #endif -// if (contentDialog == nullptr) { -// if (hasActive) { -// setWindowTitle(widget->getSubject()); -// } -// } else { -// ContentDialogManager::getInstance()->updateGroupStatus(groupId); -// } + // if (contentDialog == nullptr) { + // if (hasActive) { + // setWindowTitle(widget->getSubject()); + // } + // } else { + // ContentDialogManager::getInstance()->updateGroupStatus(groupId); + // } - return true; + return true; } QString Widget::fromDialogType(DialogType type) { - switch (type) { - case DialogType::AddDialog: - return tr("Add friend", "title of the window"); - case DialogType::GroupDialog: - return tr("Group invites", "title of the window"); - case DialogType::TransferDialog: - return tr("File transfers", "title of the window"); - case DialogType::SettingDialog: - return tr("Settings", "title of the window"); - case DialogType::ProfileDialog: - return tr("My profile", "title of the window"); - } - assert(false); - return QString(); -} - -bool Widget::newMessageAlert(QWidget *currentWindow, bool isActive, bool sound, - bool notify) { - bool inactiveWindow = isMinimized() || !currentWindow->isActiveWindow(); - - if (!inactiveWindow && isActive) { - return false; - } + switch (type) { + case DialogType::AddDialog: + return tr("Add friend", "title of the window"); + case DialogType::GroupDialog: + return tr("Group invites", "title of the window"); + case DialogType::TransferDialog: + return tr("File transfers", "title of the window"); + case DialogType::SettingDialog: + return tr("Settings", "title of the window"); + case DialogType::ProfileDialog: + return tr("My profile", "title of the window"); + } + assert(false); + return QString(); +} - if (notify) { - auto &settings = Settings::getInstance(); +bool Widget::newMessageAlert(QWidget* currentWindow, bool isActive, bool sound, bool notify) { + bool inactiveWindow = isMinimized() || !currentWindow->isActiveWindow(); - if (settings.getShowWindow()) { - currentWindow->show(); + if (!inactiveWindow && isActive) { + return false; } - if (settings.getNotify()) { - if (inactiveWindow) { -#if DESKTOP_NOTIFICATIONS - if (!settings.getDesktopNotify()) { - QApplication::alert(currentWindow); + if (notify) { + auto& settings = Settings::getInstance(); + + if (settings.getShowWindow()) { + currentWindow->show(); } + + if (settings.getNotify()) { + if (inactiveWindow) { +#if DESKTOP_NOTIFICATIONS + if (!settings.getDesktopNotify()) { + QApplication::alert(currentWindow); + } #else - QApplication::alert(currentWindow); + QApplication::alert(currentWindow); #endif - eventFlag = true; - } - bool isBusy = core->getStatus() == Status::Status::Busy; - bool busySound = settings.getBusySound(); - bool notifySound = settings.getNotifySound(); - - if (notifySound && sound && (!isBusy || busySound)) { - playNotificationSound(IAudioSink::Sound::NewMessage); - } + eventFlag = true; + } + + bool isBusy = Nexus::getCore()->getStatus() == Status::Status::Busy; + bool busySound = settings.getBusySound(); + bool notifySound = settings.getNotifySound(); + + if (notifySound && sound && (!isBusy || busySound)) { + playNotificationSound(IAudioSink::Sound::NewMessage); + } + } } - } - return true; + return true; } -void Widget::friendRequestedTo(const ToxId &friendAddress, const QString &nick, const QString &message){ - qDebug()<<"friendRequestedTo"<resetEventFlags(); -// widget->updateStatusLight(); +void Widget::onDialogShown(GenericChatroomWidget* widget) { + widget->resetEventFlags(); + // widget->updateStatusLight(); -// ui->friendList->updateTracking(widget); - resetIcon(); + // ui->friendList->updateTracking(widget); + resetIcon(); } -void Widget::onFriendDialogShown(const Friend *f) { -// onDialogShown(contactListWidget->getFriend(f->getPublicKey())); +void Widget::onFriendDialogShown(const Friend* f) { + // onDialogShown(contactListWidget->getFriend(f->getPublicKey())); } -void Widget::onGroupDialogShown(const Group *g) { - const GroupId &groupId = g->getPersistentId(); -// onDialogShown(groupWidgets[groupId]); +void Widget::onGroupDialogShown(const Group* g) { + const GroupId& groupId = g->getPersistentId(); + // onDialogShown(groupWidgets[groupId]); } void Widget::toggleFullscreen() { - if (windowState().testFlag(Qt::WindowFullScreen)) { - setWindowState(windowState() & ~Qt::WindowFullScreen); - } else { - setWindowState(windowState() | Qt::WindowFullScreen); - } + if (windowState().testFlag(Qt::WindowFullScreen)) { + setWindowState(windowState() & ~Qt::WindowFullScreen); + } else { + setWindowState(windowState() | Qt::WindowFullScreen); + } } void Widget::onUpdateAvailable() { -// ui->settingsButton->setProperty("update-available", true); -// ui->settingsButton->style()->unpolish(ui->settingsButton); -// ui->settingsButton->style()->polish(ui->settingsButton); + // ui->settingsButton->setProperty("update-available", true); + // ui->settingsButton->style()->unpolish(ui->settingsButton); + // ui->settingsButton->style()->polish(ui->settingsButton); } -ContentDialog *Widget::createContentDialog() const { - ContentDialog *contentDialog = new ContentDialog(); +ContentDialog* Widget::createContentDialog() const { + ContentDialog* contentDialog = new ContentDialog(); - registerContentDialog(*contentDialog); - return contentDialog; + registerContentDialog(*contentDialog); + return contentDialog; } -void Widget::registerContentDialog(ContentDialog &contentDialog) const { - ContentDialogManager::getInstance()->addContentDialog(contentDialog); - connect(&contentDialog, &ContentDialog::friendDialogShown, this, - &Widget::onFriendDialogShown); - connect(&contentDialog, &ContentDialog::groupDialogShown, this, - &Widget::onGroupDialogShown); - connect(core, &Core::usernameSet, &contentDialog, - &ContentDialog::setUsername); - connect(&settings, &Settings::groupchatPositionChanged, &contentDialog, - &ContentDialog::reorderLayouts); +void Widget::registerContentDialog(ContentDialog& contentDialog) const { + ContentDialogManager::getInstance()->addContentDialog(contentDialog); + connect(&contentDialog, &ContentDialog::friendDialogShown, this, &Widget::onFriendDialogShown); + connect(&contentDialog, &ContentDialog::groupDialogShown, this, &Widget::onGroupDialogShown); + connect(core, &Core::usernameSet, &contentDialog, &ContentDialog::setUsername); + connect(&settings, &Settings::groupchatPositionChanged, &contentDialog, + &ContentDialog::reorderLayouts); #ifdef Q_OS_MAC - Nexus &n = Nexus::getInstance(); - connect(&contentDialog, &ContentDialog::destroyed, &n, - &Nexus::updateWindowsClosed); - connect(&contentDialog, &ContentDialog::windowStateChanged, &n, - &Nexus::onWindowStateChanged); - connect(contentDialog.windowHandle(), &QWindow::windowTitleChanged, &n, - &Nexus::updateWindows); - n.updateWindows(); + Nexus& n = Nexus::getInstance(); + connect(&contentDialog, &ContentDialog::destroyed, &n, &Nexus::updateWindowsClosed); + connect(&contentDialog, &ContentDialog::windowStateChanged, &n, &Nexus::onWindowStateChanged); + connect(contentDialog.windowHandle(), &QWindow::windowTitleChanged, &n, &Nexus::updateWindows); + n.updateWindows(); #endif } -ContentLayout *Widget::createContentDialog(DialogType type) const { - class Dialog : public ActivateDialog { - public: - explicit Dialog(DialogType type, Settings &settings, Core *core) - : ActivateDialog(nullptr, Qt::Window), type(type), settings(settings), - core{core} { - restoreGeometry(settings.getDialogSettingsGeometry()); - settings::Translator::registerHandler( - std::bind(&Dialog::retranslateUi, this), this); - retranslateUi(); - setWindowIcon(QIcon(":/img/icons/qtox.svg")); - setStyleSheet(Style::getStylesheet("window/general.css")); - - connect(core, &Core::usernameSet, this, &Dialog::retranslateUi); - } +ContentLayout* Widget::createContentDialog(DialogType type) const { + class Dialog : public ActivateDialog { + public: + explicit Dialog(DialogType type, Settings& settings, Core* core) + : ActivateDialog(nullptr, Qt::Window), type(type), settings(settings), core{core} { + restoreGeometry(settings.getDialogSettingsGeometry()); + settings::Translator::registerHandler(std::bind(&Dialog::retranslateUi, this), this); + retranslateUi(); + setWindowIcon(QIcon(":/img/icons/qtox.svg")); + setStyleSheet(Style::getStylesheet("window/general.css")); - ~Dialog() { settings::Translator::unregister(this); } + connect(core, &Core::usernameSet, this, &Dialog::retranslateUi); + } - public slots: + ~Dialog() { settings::Translator::unregister(this); } - void retranslateUi() { - setWindowTitle(core->getUsername() + QStringLiteral(" - ") + - Widget::fromDialogType(type)); - } + public slots: - protected: - void resizeEvent(QResizeEvent *event) override { - settings.setDialogSettingsGeometry(saveGeometry()); - QDialog::resizeEvent(event); - } + void retranslateUi() { + setWindowTitle(core->getUsername() + QStringLiteral(" - ") + + Widget::fromDialogType(type)); + } - void moveEvent(QMoveEvent *event) override { - settings.setDialogSettingsGeometry(saveGeometry()); - QDialog::moveEvent(event); - } + protected: + void resizeEvent(QResizeEvent* event) override { + settings.setDialogSettingsGeometry(saveGeometry()); + QDialog::resizeEvent(event); + } - private: - DialogType type; - Settings &settings; - Core *core; - }; + void moveEvent(QMoveEvent* event) override { + settings.setDialogSettingsGeometry(saveGeometry()); + QDialog::moveEvent(event); + } + + private: + DialogType type; + Settings& settings; + Core* core; + }; - Dialog *dialog = new Dialog(type, settings, core); - dialog->setAttribute(Qt::WA_DeleteOnClose); - ContentLayout *contentLayoutDialog = new ContentLayout(dialog); + Dialog* dialog = new Dialog(type, settings, core); + dialog->setAttribute(Qt::WA_DeleteOnClose); + ContentLayout* contentLayoutDialog = new ContentLayout(dialog); - dialog->setObjectName("detached"); - dialog->setLayout(contentLayoutDialog); - dialog->layout()->setMargin(0); - dialog->layout()->setSpacing(0); - dialog->setMinimumSize(720, 400); - dialog->setAttribute(Qt::WA_DeleteOnClose); - dialog->show(); + dialog->setObjectName("detached"); + dialog->setLayout(contentLayoutDialog); + dialog->layout()->setMargin(0); + dialog->layout()->setSpacing(0); + dialog->setMinimumSize(720, 400); + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->show(); #ifdef Q_OS_MAC - connect(dialog, &Dialog::destroyed, &Nexus::getInstance(), - &Nexus::updateWindowsClosed); - connect(dialog, &ActivateDialog::windowStateChanged, &Nexus::getInstance(), - &Nexus::updateWindowsStates); - connect(dialog->windowHandle(), &QWindow::windowTitleChanged, - &Nexus::getInstance(), &Nexus::updateWindows); - Nexus::getInstance().updateWindows(); + connect(dialog, &Dialog::destroyed, &Nexus::getInstance(), &Nexus::updateWindowsClosed); + connect(dialog, &ActivateDialog::windowStateChanged, &Nexus::getInstance(), + &Nexus::updateWindowsStates); + connect(dialog->windowHandle(), &QWindow::windowTitleChanged, &Nexus::getInstance(), + &Nexus::updateWindows); + Nexus::getInstance().updateWindows(); #endif - return contentLayoutDialog; + return contentLayoutDialog; } -void Widget::copyFriendIdToClipboard(const FriendId &friendId) { - Friend *f = FriendList::findFriend(friendId); - if (f != nullptr) { - QClipboard *clipboard = QApplication::clipboard(); - clipboard->setText(friendId.toString(), QClipboard::Clipboard); - } +void Widget::copyFriendIdToClipboard(const FriendId& friendId) { + Friend* f = FriendList::findFriend(friendId); + if (f != nullptr) { + QClipboard* clipboard = QApplication::clipboard(); + clipboard->setText(friendId.toString(), QClipboard::Clipboard); + } } - - -void Widget::titleChangedByUser(const QString &title) { - const auto *group = qobject_cast(sender()); - assert(group != nullptr); - emit changeGroupTitle(group->getId(), title); +void Widget::titleChangedByUser(const QString& title) { + const auto* group = qobject_cast(sender()); + assert(group != nullptr); + emit changeGroupTitle(group->getId(), title); } void Widget::onGroupPeerAudioPlaying(QString groupnumber, FriendId peerPk) { - const GroupId &groupId = GroupId(groupnumber); - Group *g = GroupList::findGroup(groupId); - if (!g) { - qWarning() << "Can not find the group named:" << groupnumber; - return; - } - -// auto form = groupChatForms[groupId].data(); -// form->peerAudioPlaying(peerPk); -} - -void Widget::removeGroup(Group *g, bool fake) { -// const auto &groupId = g->getPersistentId(); -// const auto groupnumber = g->getId(); -// auto groupWidgetIt = groupWidgets.find(groupId); -// if (groupWidgetIt == groupWidgets.end()) { -// qWarning() << "Tried to remove group" << groupnumber -// << "but GroupWidget doesn't exist"; -// return; -// } -// auto widget = groupWidgetIt.value(); -// widget->setAsInactiveChatroom(); -// if (static_cast(widget) == activeChatroomWidget) { -// activeChatroomWidget = nullptr; -// onAddClicked(); -// } -// -// GroupList::removeGroup(groupId, fake); -// ContentDialog *contentDialog = -// ContentDialogManager::getInstance()->getGroupDialog(groupId); -// if (contentDialog != nullptr) { -// contentDialog->removeGroup(groupId); -// } -// -// if (!fake) { -// core->destroyGroup(groupnumber); -// }else{ -// core->leaveGroup(groupnumber); -// } -// -// contactListWidget->removeGroupWidget(widget); // deletes widget -// -// groupWidgets.remove(groupId); -// auto groupChatFormIt = groupChatForms.find(groupId); -// if (groupChatFormIt == groupChatForms.end()) { -// qWarning() << "Tried to remove group" << groupnumber -// << "but GroupChatForm doesn't exist"; -// return; -// } -// groupChatForms.erase(groupChatFormIt); -// delete g; -//// if (contentLayout && contentLayout->mainHead->layout()->isEmpty()) { -//// onAddClicked(); -//// } -// -// groupAlertConnections.remove(groupId); -// -// contactListWidget->reDraw(); + const GroupId& groupId = GroupId(groupnumber); + Group* g = GroupList::findGroup(groupId); + if (!g) { + qWarning() << "Can not find the group named:" << groupnumber; + return; + } + + // auto form = groupChatForms[groupId].data(); + // form->peerAudioPlaying(peerPk); } -void Widget::removeGroup(const GroupId &groupId) { - removeGroup(GroupList::findGroup(groupId)); +void Widget::removeGroup(Group* g, bool fake) { + // const auto &groupId = g->getPersistentId(); + // const auto groupnumber = g->getId(); + // auto groupWidgetIt = groupWidgets.find(groupId); + // if (groupWidgetIt == groupWidgets.end()) { + // qWarning() << "Tried to remove group" << groupnumber + // << "but GroupWidget doesn't exist"; + // return; + // } + // auto widget = groupWidgetIt.value(); + // widget->setAsInactiveChatroom(); + // if (static_cast(widget) == activeChatroomWidget) { + // activeChatroomWidget = nullptr; + // onAddClicked(); + // } + // + // GroupList::removeGroup(groupId, fake); + // ContentDialog *contentDialog = + // ContentDialogManager::getInstance()->getGroupDialog(groupId); + // if (contentDialog != nullptr) { + // contentDialog->removeGroup(groupId); + // } + // + // if (!fake) { + // core->destroyGroup(groupnumber); + // }else{ + // core->leaveGroup(groupnumber); + // } + // + // contactListWidget->removeGroupWidget(widget); // deletes widget + // + // groupWidgets.remove(groupId); + // auto groupChatFormIt = groupChatForms.find(groupId); + // if (groupChatFormIt == groupChatForms.end()) { + // qWarning() << "Tried to remove group" << groupnumber + // << "but GroupChatForm doesn't exist"; + // return; + // } + // groupChatForms.erase(groupChatFormIt); + // delete g; + //// if (contentLayout && contentLayout->mainHead->layout()->isEmpty()) { + //// onAddClicked(); + //// } + // + // groupAlertConnections.remove(groupId); + // + // contactListWidget->reDraw(); } -void Widget::destroyGroup(const GroupId &groupId) { - removeGroup(GroupList::findGroup(groupId), false); +void Widget::removeGroup(const GroupId& groupId) { removeGroup(GroupList::findGroup(groupId)); } + +void Widget::destroyGroup(const GroupId& groupId) { + removeGroup(GroupList::findGroup(groupId), false); } -GroupWidget *Widget::createGroup(QString groupnumber, - const GroupId &groupId, - const QString& groupName) { +GroupWidget* Widget::createGroup(QString groupnumber, + const GroupId& groupId, + const QString& groupName) { + // auto newgroup = contactListWidget->addGroup(groupnumber, groupId, groupName); + // qDebug() << "createGroup" << groupnumber + // << groupName; + // + // Group *g = GroupList::findGroup(groupId); + // if (g) { + // qWarning() << "Group already exists" << groupnumber << "=>group:" << g; + // return g; + // } + // + // const bool enabled = core->getGroupAvEnabled(groupnumber); + // Group *newgroup = GroupList::addGroup(groupnumber, groupId, groupName, + // enabled, core->getUsername()); + // + // auto dialogManager = ContentDialogManager::getInstance(); + // auto rawChatroom = new GroupChatroom(newgroup, dialogManager); + // std::shared_ptr chatroom(rawChatroom); + // + // const auto compact = settings.getCompactLayout(); + // auto widget = new GroupWidget(chatroom, compact); + // auto messageProcessor = MessageProcessor(sharedMessageProcessorParams); + // auto messageDispatcher = std::make_shared( + // *newgroup, std::move(messageProcessor), *core, *core, + // Settings::getInstance()); + // auto groupChatLog = std::make_shared(*core); + // + // connect(messageDispatcher.get(), &IMessageDispatcher::messageReceived, + // groupChatLog.get(), &SessionChatLog::onMessageReceived); + // connect(messageDispatcher.get(), &IMessageDispatcher::messageSent, + // groupChatLog.get(), &SessionChatLog::onMessageSent); + // connect(messageDispatcher.get(), &IMessageDispatcher::messageComplete, + // groupChatLog.get(), &SessionChatLog::onMessageComplete); + // + // auto notifyReceivedCallback = [this, groupId](const ToxPk &author, + // const Message &message) { + // auto isTargeted = + // std::any_of(message.metadata.begin(), message.metadata.end(), + // [](MessageMetadata metadata) { + // return metadata.type == MessageMetadataType::selfMention; + // }); + // newGroupMessageAlert(groupId, author, message.content, + // isTargeted || settings.getGroupAlwaysNotify()); + // }; + // + // auto notifyReceivedConnection = + // connect(messageDispatcher.get(), &IMessageDispatcher::messageReceived, + // notifyReceivedCallback); + // groupAlertConnections.insert(groupId, notifyReceivedConnection); + // + // auto form = + // new GroupChatForm(newgroup, *groupChatLog, *messageDispatcher, settings); + // connect(&settings, &Settings::nameColorsChanged, form, + // &GenericChatForm::setColorizedNames); + // form->setColorizedNames(settings.getEnableGroupChatsColor()); + // groupMessageDispatchers[groupId] = messageDispatcher; + // groupChatLogs[groupId] = groupChatLog; + // groupWidgets[groupId] = widget; + // groupChatrooms[groupId] = chatroom; + // groupChatForms[groupId] = QSharedPointer(form); + // + // contactListWidget->addGroupWidget(widget); + // + // widget->updateStatusLight(); + // contactListWidget->activateWindow(); + // + // connect(widget, &GroupWidget::chatroomWidgetClicked, this, + // &Widget::onChatroomWidgetClicked); + // connect(widget, &GroupWidget::newWindowOpened, this, &Widget::openNewDialog); + // #if (QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)) + // auto widgetRemoveGroup = QOverload::of(&Widget::removeGroup); + // auto widgetDestroyGroup = QOverload::of(&Widget::destroyGroup); + // #else + // auto widgetRemoveGroup = + // static_cast(&Widget::removeGroup); + // auto widgetDestroyGroup = + // static_cast(&Widget::destroyGroup); + // #endif + // connect(widget, &GroupWidget::removeGroup, this, widgetRemoveGroup); + // connect(widget, &GroupWidget::destroyGroup, this, widgetDestroyGroup); + //// connect(widget, &GroupWidget::middleMouseClicked, this, + //// [this]() { removeGroup(groupId); }); + // connect(widget, &GroupWidget::chatroomWidgetClicked, form, + // &ChatForm::focusInput); + // connect(newgroup, &Group::titleChangedByUser, this, + // &Widget::titleChangedByUser); + // connect(core, &Core::usernameSet, newgroup, &Group::setSelfName); + // + // FilterCriteria filter = getFilterCriteria(); + // widget->searchName(ui->searchContactText->text(), filterGroups(filter)); + // return newgroup; -// auto newgroup = contactListWidget->addGroup(groupnumber, groupId, groupName); -// qDebug() << "createGroup" << groupnumber -// << groupName; -// -// Group *g = GroupList::findGroup(groupId); -// if (g) { -// qWarning() << "Group already exists" << groupnumber << "=>group:" << g; -// return g; -// } -// -// const bool enabled = core->getGroupAvEnabled(groupnumber); -// Group *newgroup = GroupList::addGroup(groupnumber, groupId, groupName, -// enabled, core->getUsername()); -// -// auto dialogManager = ContentDialogManager::getInstance(); -// auto rawChatroom = new GroupChatroom(newgroup, dialogManager); -// std::shared_ptr chatroom(rawChatroom); -// -// const auto compact = settings.getCompactLayout(); -// auto widget = new GroupWidget(chatroom, compact); -// auto messageProcessor = MessageProcessor(sharedMessageProcessorParams); -// auto messageDispatcher = std::make_shared( -// *newgroup, std::move(messageProcessor), *core, *core, -// Settings::getInstance()); -// auto groupChatLog = std::make_shared(*core); -// -// connect(messageDispatcher.get(), &IMessageDispatcher::messageReceived, -// groupChatLog.get(), &SessionChatLog::onMessageReceived); -// connect(messageDispatcher.get(), &IMessageDispatcher::messageSent, -// groupChatLog.get(), &SessionChatLog::onMessageSent); -// connect(messageDispatcher.get(), &IMessageDispatcher::messageComplete, -// groupChatLog.get(), &SessionChatLog::onMessageComplete); -// -// auto notifyReceivedCallback = [this, groupId](const ToxPk &author, -// const Message &message) { -// auto isTargeted = -// std::any_of(message.metadata.begin(), message.metadata.end(), -// [](MessageMetadata metadata) { -// return metadata.type == MessageMetadataType::selfMention; -// }); -// newGroupMessageAlert(groupId, author, message.content, -// isTargeted || settings.getGroupAlwaysNotify()); -// }; -// -// auto notifyReceivedConnection = -// connect(messageDispatcher.get(), &IMessageDispatcher::messageReceived, -// notifyReceivedCallback); -// groupAlertConnections.insert(groupId, notifyReceivedConnection); -// -// auto form = -// new GroupChatForm(newgroup, *groupChatLog, *messageDispatcher, settings); -// connect(&settings, &Settings::nameColorsChanged, form, -// &GenericChatForm::setColorizedNames); -// form->setColorizedNames(settings.getEnableGroupChatsColor()); -// groupMessageDispatchers[groupId] = messageDispatcher; -// groupChatLogs[groupId] = groupChatLog; -// groupWidgets[groupId] = widget; -// groupChatrooms[groupId] = chatroom; -// groupChatForms[groupId] = QSharedPointer(form); -// -// contactListWidget->addGroupWidget(widget); -// -// widget->updateStatusLight(); -// contactListWidget->activateWindow(); -// -// connect(widget, &GroupWidget::chatroomWidgetClicked, this, -// &Widget::onChatroomWidgetClicked); -// connect(widget, &GroupWidget::newWindowOpened, this, &Widget::openNewDialog); -//#if (QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)) -// auto widgetRemoveGroup = QOverload::of(&Widget::removeGroup); -// auto widgetDestroyGroup = QOverload::of(&Widget::destroyGroup); -//#else -// auto widgetRemoveGroup = -// static_cast(&Widget::removeGroup); -// auto widgetDestroyGroup = -// static_cast(&Widget::destroyGroup); -//#endif -// connect(widget, &GroupWidget::removeGroup, this, widgetRemoveGroup); -// connect(widget, &GroupWidget::destroyGroup, this, widgetDestroyGroup); -//// connect(widget, &GroupWidget::middleMouseClicked, this, -//// [this]() { removeGroup(groupId); }); -// connect(widget, &GroupWidget::chatroomWidgetClicked, form, -// &ChatForm::focusInput); -// connect(newgroup, &Group::titleChangedByUser, this, -// &Widget::titleChangedByUser); -// connect(core, &Core::usernameSet, newgroup, &Group::setSelfName); -// -// FilterCriteria filter = getFilterCriteria(); -// widget->searchName(ui->searchContactText->text(), filterGroups(filter)); - -// return newgroup; - -return nullptr; + return nullptr; } /** * @brief Used to reset the blinking icon. */ void Widget::resetIcon() { - eventIcon = false; - eventFlag = false; - updateIcons(); -} - -bool Widget::event(QEvent *e) { - switch (e->type()) { - case QEvent::MouseButtonPress: - case QEvent::MouseButtonDblClick: -// focusChatInput(); - break; - case QEvent::Paint: -// ui->friendList->updateVisualTracking(); - break; - case QEvent::WindowActivate: + eventIcon = false; + eventFlag = false; + updateIcons(); +} - if (eventFlag) { - resetIcon(); - } +bool Widget::event(QEvent* e) { + switch (e->type()) { + case QEvent::MouseButtonPress: + case QEvent::MouseButtonDblClick: + // focusChatInput(); + break; + case QEvent::Paint: + // ui->friendList->updateVisualTracking(); + break; + case QEvent::WindowActivate: + + if (eventFlag) { + resetIcon(); + } #ifdef Q_OS_MAC - emit windowStateChanged(windowState()); + emit windowStateChanged(windowState()); - case QEvent::WindowStateChange: - Nexus::getInstance().updateWindowsStates(); + case QEvent::WindowStateChange: + Nexus::getInstance().updateWindowsStates(); #endif - break; - default: - break; - } + break; + default: + break; + } - return QWidget::event(e); + return QWidget::event(e); } void Widget::onUserAwayCheck() { #ifdef QTOX_PLATFORM_EXT - uint32_t autoAwayTime = settings.getAutoAwayTime() * 60 * 1000; + uint32_t autoAwayTime = settings.getAutoAwayTime() * 60 * 1000; // bool online = static_cast( // ui->statusButton->property("status").toInt()) == // Status::Status::Online; @@ -1470,127 +1320,122 @@ void Widget::onUserAwayCheck() { } void Widget::onEventIconTick() { - if (eventFlag) { - eventIcon ^= true; - updateIcons(); - } + if (eventFlag) { + eventIcon ^= true; + updateIcons(); + } } void Widget::onTryCreateTrayIcon() { - static int32_t tries = 15; - if (!icon && tries--) { - if (QSystemTrayIcon::isSystemTrayAvailable()) { - icon = std::unique_ptr(new QSystemTrayIcon); - updateIcons(); - trayMenu = new QMenu(this); - - // adding activate to the top, avoids accidentally clicking quit - trayMenu->addAction(actionShow); - trayMenu->addSeparator(); - trayMenu->addAction(statusOnline); - trayMenu->addAction(statusAway); - trayMenu->addAction(statusBusy); - trayMenu->addSeparator(); - trayMenu->addAction(actionLogout); - trayMenu->addAction(actionQuit); - icon->setContextMenu(trayMenu); - - connect(icon.get(), &QSystemTrayIcon::activated, this, - &Widget::onIconClick); - - auto &okSettings = ok::base::OkSettings::getInstance(); - if (okSettings.getShowSystemTray()) { - icon->show(); - setHidden(okSettings.getAutostartInTray()); - } else { - show(); - } + static int32_t tries = 15; + if (!icon && tries--) { + if (QSystemTrayIcon::isSystemTrayAvailable()) { + icon = std::unique_ptr(new QSystemTrayIcon); + updateIcons(); + trayMenu = new QMenu(this); + + // adding activate to the top, avoids accidentally clicking quit + trayMenu->addAction(actionShow); + trayMenu->addSeparator(); + trayMenu->addAction(statusOnline); + trayMenu->addAction(statusAway); + trayMenu->addAction(statusBusy); + trayMenu->addSeparator(); + trayMenu->addAction(actionLogout); + trayMenu->addAction(actionQuit); + icon->setContextMenu(trayMenu); + + connect(icon.get(), &QSystemTrayIcon::activated, this, &Widget::onIconClick); + + auto& okSettings = ok::base::OkSettings::getInstance(); + if (okSettings.getShowSystemTray()) { + icon->show(); + setHidden(okSettings.getAutostartInTray()); + } else { + show(); + } #ifdef Q_OS_MAC - Nexus::getInstance().dockMenu->setAsDockMenu(); + Nexus::getInstance().dockMenu->setAsDockMenu(); #endif - } else if (!isVisible()) { - show(); - } - } else { - disconnect(timer, &QTimer::timeout, this, &Widget::onTryCreateTrayIcon); - if (!icon) { - qWarning() << "No system tray detected!"; - show(); + } else if (!isVisible()) { + show(); + } + } else { + disconnect(timer, &QTimer::timeout, this, &Widget::onTryCreateTrayIcon); + if (!icon) { + qWarning() << "No system tray detected!"; + show(); + } } - } } void Widget::setStatusOnline() { -// if (!ui->statusButton->isEnabled()) { -// return; -// } + // if (!ui->statusButton->isEnabled()) { + // return; + // } - core->setStatus(Status::Status::Online); + core->setStatus(Status::Status::Online); } void Widget::setStatusAway() { -// if (!ui->statusButton->isEnabled()) { -// return; -// } + // if (!ui->statusButton->isEnabled()) { + // return; + // } - core->setStatus(Status::Status::Away); + core->setStatus(Status::Status::Away); } void Widget::setStatusBusy() { -// if (!ui->statusButton->isEnabled()) { -// return; -// } + // if (!ui->statusButton->isEnabled()) { + // return; + // } - core->setStatus(Status::Status::Busy); + core->setStatus(Status::Status::Busy); } - - void Widget::onSetShowSystemTray(bool newValue) { - if (icon) { - icon->setVisible(newValue); - } + if (icon) { + icon->setVisible(newValue); + } } void Widget::saveWindowGeometry() { - settings.setWindowGeometry(saveGeometry()); - // settings.setWindowState(saveState()); + settings.setWindowGeometry(saveGeometry()); + // settings.setWindowState(saveState()); } void Widget::saveSplitterGeometry() { - if (!settings.getSeparateWindow()) { -// settings.setSplitterState(ui->mainSplitter->saveState()); - } + if (!settings.getSeparateWindow()) { + // settings.setSplitterState(ui->mainSplitter->saveState()); + } } void Widget::onSplitterMoved(int pos, int index) { - Q_UNUSED(pos); - Q_UNUSED(index); - saveSplitterGeometry(); + Q_UNUSED(pos); + Q_UNUSED(index); + saveSplitterGeometry(); } void Widget::cycleContacts(bool forward) { -// contactListWidget->cycleContacts(activeChatroomWidget, forward); + // contactListWidget->cycleContacts(activeChatroomWidget, forward); } - -void Widget::clearAllReceipts() { - chatWidget->clearAllReceipts(); -} +void Widget::clearAllReceipts() { chatWidget->clearAllReceipts(); } void Widget::reloadTheme() { - auto& style = Style::getStylesheet("window/general.css"); - this->setStyleSheet(style); - chatWidget->reloadTheme(); - contactWidget->reloadTheme(); + auto& style = Style::getStylesheet("window/general.css"); + this->setStyleSheet(style); + chatWidget->reloadTheme(); + contactWidget->reloadTheme(); } void Widget::retranslateUi() { - ui->retranslateUi(this); - ui->tabWidget->setTabText(0, tr("Chat")); - ui->tabWidget->setTabText(1, tr("Contact")); - ui->tabWidget->setTabText(2, tr("Settings")); + ui->retranslateUi(this); + ui->tabWidget->setTabText(0, tr("Chat")); + ui->tabWidget->setTabText(1, tr("Contact")); + ui->tabWidget->setTabText(2, tr("Settings")); + // #ifdef Q_OS_MAC // Nexus::getInstance().retranslateUi(); @@ -1607,4 +1452,7 @@ void Widget::retranslateUi() { // nextConversationAction->setText(tr("Next Conversation")); // previousConversationAction->setText(tr("Previous Conversation")); // #endif + } + +void Widget::showEvent(QShowEvent* e) { QWidget::showEvent(e); } diff --git a/src/modules/im/src/widget/widget.h b/src/modules/im/src/widget/widget.h index e0c1421d..087b43f4 100644 --- a/src/modules/im/src/widget/widget.h +++ b/src/modules/im/src/widget/widget.h @@ -36,7 +36,6 @@ #include "src/platform/desktop_notifications/desktopnotify.h" #endif - #define PIXELS_TO_ACT 7 namespace Ui { @@ -55,7 +54,7 @@ class FilesForm; class Friend; class FriendChatroom; class FriendListWidget; -//class FriendWidget; +// class FriendWidget; class GenericChatroomWidget; class Group; class GroupChatForm; @@ -81,277 +80,255 @@ class ChatHistory; class ChatWidget; class ContactWidget; - - -enum class DialogType { - AddDialog, - TransferDialog, - SettingDialog, - ProfileDialog, - GroupDialog -}; +enum class DialogType { AddDialog, TransferDialog, SettingDialog, ProfileDialog, GroupDialog }; enum class ActiveToolMenuButton { - AddButton, - GroupButton, - TransferButton, - SettingButton, - None, + AddButton, + GroupButton, + TransferButton, + SettingButton, + None, }; - - class Widget final : public QFrame { - Q_OBJECT + Q_OBJECT private: - - public: - explicit Widget(IAudioControl &audio, QWidget *parent = nullptr); - ~Widget() override; - - static Widget *getInstance(); - bool newMessageAlert(QWidget *currentWindow, bool isActive, bool sound = true, - bool notify = true); - - void init(); - void setCentralWidget(QWidget *widget, const QString &widgetName); - QString getUsername(); - Camera *getCamera(); + explicit Widget(IAudioControl& audio, QWidget* parent = nullptr); + ~Widget() override; - void showUpdateDownloadProgress(); + static Widget* getInstance(); + bool newMessageAlert(QWidget* currentWindow, bool isActive, bool sound = true, + bool notify = true); - bool newFriendMessageAlert(const FriendId &friendId, const QString &text, - bool sound = true, bool file = false); - bool newGroupMessageAlert(const GroupId &groupId, const FriendId &authorPk, - const QString &message, bool notify); - bool getIsWindowMinimized(); - void updateIcons(); + void init(); + void setCentralWidget(QWidget* widget, const QString& widgetName); + QString getUsername(); + Camera* getCamera(); - static QString fromDialogType(DialogType type); - ContentDialog *createContentDialog() const; - ContentLayout *createContentDialog(DialogType type) const; + void showUpdateDownloadProgress(); - static void confirmExecutableOpen(const QFileInfo &file); + bool newFriendMessageAlert(const FriendId& friendId, const QString& text, bool sound = true, + bool file = false); + bool newGroupMessageAlert(const GroupId& groupId, const FriendId& authorPk, + const QString& message, bool notify); + bool getIsWindowMinimized(); + void updateIcons(); - void clearAllReceipts(); + static QString fromDialogType(DialogType type); + ContentDialog* createContentDialog() const; + ContentLayout* createContentDialog(DialogType type) const; - void reloadTheme(); + static void confirmExecutableOpen(const QFileInfo& file); + void clearAllReceipts(); - void resetIcon(); - -// [[nodiscard]] ContentLayout *getContentLayout() const { -// return contentLayout; -// } + void reloadTheme(); + void resetIcon(); + // [[nodiscard]] ContentLayout *getContentLayout() const { + // return contentLayout; + // } public slots: - void onShowSettings(); - void onSeparateWindowClicked(bool separate); - void onSeparateWindowChanged(bool separate, bool clicked); - void setWindowTitle(const QString &title); - void forceShow(); - void onConnected(); - void onDisconnected(); - void onStatusSet(Status::Status status); - void onFailedToStartCore(); - void onBadProxyCore(); - void onSelfAvatarLoaded(const QPixmap &pic); - - void setUsername(const QString &username); - - void setAvatar( QByteArray avatar); - - void addFriendFailed(const FriendId &userId, const QString &errorInfo = QString()); - - - void onFileReceiveRequested(const ToxFile &file); - - void titleChangedByUser(const QString &title); - void onGroupPeerAudioPlaying(QString groupnumber, FriendId peerPk); - - - void onFriendDialogShown(const Friend *f); - void onGroupDialogShown(const Group *g); - void toggleFullscreen(); - void onUpdateAvailable(); - void onCoreChanged(Core &core); - void incomingNotification(QString friendId); - void onStopNotification(); - void outgoingNotification(); + void onShowSettings(); + void onSeparateWindowClicked(bool separate); + void onSeparateWindowChanged(bool separate, bool clicked); + void setWindowTitle(const QString& title); + void forceShow(); + void onConnected(); + void onDisconnected(); + void onStatusSet(Status::Status status); + void onFailedToStartCore(); + void onBadProxyCore(); + void onSelfAvatarLoaded(const QPixmap& pic); + + void setUsername(const QString& username); + + void setAvatar(QByteArray avatar); + + void addFriendFailed(const FriendId& userId, const QString& errorInfo = QString()); + + void onFileReceiveRequested(const ToxFile& file); + + void titleChangedByUser(const QString& title); + void onGroupPeerAudioPlaying(QString groupnumber, FriendId peerPk); + + void onFriendDialogShown(const Friend* f); + void onGroupDialogShown(const Group* g); + void toggleFullscreen(); + void onUpdateAvailable(); + void onCoreChanged(Core& core); + void incomingNotification(QString friendId); + void onStopNotification(); + void outgoingNotification(); signals: - void friendAdded(const Friend* f); - void friendRemoved(const Friend* f); - void friendRequestAccepted(const FriendId &friendPk); - void friendRequestRejected(const FriendId &friendPk); - void friendRequested(const ToxId &friendAddress, const QString &nick, const QString &message); - - void groupAdded(const Group* g); - void groupRemoved(const Group* g); - - void statusSet(Status::Status status); - void statusSelected(Status::Status status); - void usernameChanged(const QString &username); - void avatarSet(const QPixmap &avt); - - void changeGroupTitle(QString groupnumber, const QString &title); - void statusMessageChanged(const QString &statusMessage); - void resized(); - void windowStateChanged(Qt::WindowStates states); - void toSendMessage(const QString &to, bool isGroup = false); - void toShowDetails(const ContactId &to); - void toDeleteChat(const QString &to); - void toClearHistory(const QString &to); + void friendAdded(const Friend* f); + void friendRemoved(const Friend* f); + void friendRequestAccepted(const FriendId& friendPk); + void friendRequestRejected(const FriendId& friendPk); + void friendRequested(const ToxId& friendAddress, const QString& nick, const QString& message); + + void groupAdded(const Group* g); + void groupRemoved(const Group* g); + + void statusSet(Status::Status status); + void statusSelected(Status::Status status); + void usernameChanged(const QString& username); + void avatarSet(const QPixmap& avt); + + void changeGroupTitle(QString groupnumber, const QString& title); + void statusMessageChanged(const QString& statusMessage); + void resized(); + void windowStateChanged(Qt::WindowStates states); + void toSendMessage(const QString& to, bool isGroup = false); + void toShowDetails(const ContactId& to); + void toDeleteChat(const QString& to); + void toClearHistory(const QString& to); + +protected: + void showEvent(QShowEvent* e) override; private slots: - void onTransferClicked(); + void onTransferClicked(); - void openNewDialog(GenericChatroomWidget *widget); - void onChatroomWidgetClicked(GenericChatroomWidget *widget); - void onStatusMessageChanged(const QString &newStatusMessage); + void openNewDialog(GenericChatroomWidget* widget); + void onChatroomWidgetClicked(GenericChatroomWidget* widget); + void onStatusMessageChanged(const QString& newStatusMessage); - void copyFriendIdToClipboard(const FriendId &friendId); - void removeGroup(const GroupId &groupId); - void destroyGroup(const GroupId &groupId); + void copyFriendIdToClipboard(const FriendId& friendId); + void removeGroup(const GroupId& groupId); + void destroyGroup(const GroupId& groupId); - void onIconClick(QSystemTrayIcon::ActivationReason); - void onUserAwayCheck(); - void onEventIconTick(); - void onTryCreateTrayIcon(); - void onSetShowSystemTray(bool newValue); - void onSplitterMoved(int pos, int index); + void onIconClick(QSystemTrayIcon::ActivationReason); + void onUserAwayCheck(); + void onEventIconTick(); + void onTryCreateTrayIcon(); + void onSetShowSystemTray(bool newValue); + void onSplitterMoved(int pos, int index); - void onDialogShown(GenericChatroomWidget *widget); + void onDialogShown(GenericChatroomWidget* widget); + void registerContentDialog(ContentDialog& contentDialog) const; + void friendRequestedTo(const ToxId& friendAddress, const QString& nick, const QString& message); - void registerContentDialog(ContentDialog &contentDialog) const; - void friendRequestedTo(const ToxId &friendAddress, const QString &nick, const QString &message); - -private: - // QMainWindow overrides - bool eventFilter(QObject *obj, QEvent *event) final override; - bool event(QEvent *e) final override; - void closeEvent(QCloseEvent *event) final override; - void changeEvent(QEvent *event) final override; - void resizeEvent(QResizeEvent *event) final override; - void moveEvent(QMoveEvent *event) final override; - - -// void setActiveToolMenuButton(ActiveToolMenuButton newActiveButton); - void hideMainForms(GenericChatroomWidget *chatroomWidget); - GroupWidget *createGroup(QString groupnumber, const GroupId &groupId, const QString& name); - void removeFriend(Friend *f, bool fake = false); - void removeGroup(Group *g, bool fake = false); - void saveWindowGeometry(); - void saveSplitterGeometry(); - void cycleContacts(bool forward); - - void retranslateUi(); - - void openDialog(GenericChatroomWidget *widget, bool newWindow); - void playNotificationSound(IAudioSink::Sound sound, bool loop = false); - void cleanupNotificationSound(); -void connectToCore(Core&core); private: + // QMainWindow overrides + bool eventFilter(QObject* obj, QEvent* event) final override; + bool event(QEvent* e) final override; + void closeEvent(QCloseEvent* event) final override; + void changeEvent(QEvent* event) final override; + void resizeEvent(QResizeEvent* event) final override; + void moveEvent(QMoveEvent* event) final override; + + // void setActiveToolMenuButton(ActiveToolMenuButton newActiveButton); + void hideMainForms(GenericChatroomWidget* chatroomWidget); + GroupWidget* createGroup(QString groupnumber, const GroupId& groupId, const QString& name); + void removeFriend(Friend* f, bool fake = false); + void removeGroup(Group* g, bool fake = false); + void saveWindowGeometry(); + void saveSplitterGeometry(); + void cycleContacts(bool forward); + + void retranslateUi(); + + void openDialog(GenericChatroomWidget* widget, bool newWindow); + void playNotificationSound(IAudioSink::Sound sound, bool loop = false); + void cleanupNotificationSound(); + void connectToCore(Core& core); - std::unique_ptr icon; - QMenu *trayMenu; - QAction *statusOnline; - QAction *statusAway; - QAction *statusBusy; - QAction *actionLogout; - QAction *actionQuit; - QAction *actionShow; - void setStatusOnline(); - void setStatusAway(); - void setStatusBusy(); - - Ui::IMMainWindow *ui; - QSplitter *centralLayout; - QPoint dragPosition; - - - - ChatWidget * chatWidget; - ContactWidget* contactWidget; - SettingsWidget* settingsWidget; - - - - Core *core; - Profile *profile; - -// FilesForm *filesForm; - -// GenericChatroomWidget *activeChatroomWidget; -// FriendListWidget *contactListWidget; -// MaskablePixmapWidget *profilePicture; - bool notify(QObject *receiver, QEvent *event); - bool autoAwayActive = false; - QTimer *timer; - bool eventFlag; - bool eventIcon; - bool wasMaximized = false; - - int icon_size; - - IAudioControl &audio; - std::unique_ptr audioNotification = nullptr; - Settings &settings; - -// QMap friendWidgets; -// FriendListWidget* friendListWidget; - // Shared pointer because qmap copies stuff all over the place -// QMap> -// friendMessageDispatchers; - // Stop gap method of linking our friend messages back to a group id. - // Eventual goal is to have a notification manager that works on - // Messages hooked up to message dispatchers but we aren't there - // yet -// QMap friendAlertConnections; -// QMap> friendChatLogs; -// QMap> friendChatrooms; - -// QMap groupWidgets; -// QMap> -// groupMessageDispatchers; - - // Stop gap method of linking our group messages back to a group id. - // Eventual goal is to have a notification manager that works on - // Messages hooked up to message dispatchers but we aren't there - // yet -// QMap groupAlertConnections; -// QMap> groupChatLogs; -// QMap> groupChatrooms; -// QMap> groupChatForms; - - +private: + std::unique_ptr icon; + QMenu* trayMenu; + QAction* statusOnline; + QAction* statusAway; + QAction* statusBusy; + QAction* actionLogout; + QAction* actionQuit; + QAction* actionShow; + void setStatusOnline(); + void setStatusAway(); + void setStatusBusy(); + + Ui::IMMainWindow* ui; + QSplitter* centralLayout; + QPoint dragPosition; + + ChatWidget* chatWidget; + ContactWidget* contactWidget; + SettingsWidget* settingsWidget; + + Core* core; + // Profile *profile; + + // FilesForm *filesForm; + + // GenericChatroomWidget *activeChatroomWidget; + // FriendListWidget *contactListWidget; + // MaskablePixmapWidget *profilePicture; + bool notify(QObject* receiver, QEvent* event); + bool autoAwayActive = false; + QTimer* timer; + bool eventFlag; + bool eventIcon; + bool wasMaximized = false; + + int icon_size; + + IAudioControl& audio; + std::unique_ptr audioNotification = nullptr; + Settings& settings; + + // QMap friendWidgets; + // FriendListWidget* friendListWidget; + // Shared pointer because qmap copies stuff all over the place + // QMap> + // friendMessageDispatchers; + // Stop gap method of linking our friend messages back to a group id. + // Eventual goal is to have a notification manager that works on + // Messages hooked up to message dispatchers but we aren't there + // yet + // QMap friendAlertConnections; + // QMap> friendChatLogs; + // QMap> friendChatrooms; + + // QMap groupWidgets; + // QMap> + // groupMessageDispatchers; + + // Stop gap method of linking our group messages back to a group id. + // Eventual goal is to have a notification manager that works on + // Messages hooked up to message dispatchers but we aren't there + // yet + // QMap groupAlertConnections; + // QMap> groupChatLogs; + // QMap> groupChatrooms; + // QMap> groupChatForms; #if DESKTOP_NOTIFICATIONS - DesktopNotify notifier; + DesktopNotify notifier; #endif #ifdef Q_OS_MAC - QAction *fileMenu; - QAction *editMenu; - QAction *contactMenu; - QMenu *changeStatusMenu; - QAction *editProfileAction; - QAction *logoutAction; - QAction *addContactAction; - QAction *nextConversationAction; - QAction *previousConversationAction; + QAction* fileMenu; + QAction* editMenu; + QAction* contactMenu; + QMenu* changeStatusMenu; + QAction* editProfileAction; + QAction* logoutAction; + QAction* addContactAction; + QAction* nextConversationAction; + QAction* previousConversationAction; #endif - std::shared_ptr<::base::DelayedCallTimer> delayCaller; + std::shared_ptr<::base::DelayedCallTimer> delayCaller; }; -bool toxActivateEventHandler(const QByteArray &data); +bool toxActivateEventHandler(const QByteArray& data); -#endif // WIDGET_H +#endif // WIDGET_H diff --git a/src/modules/im/src/worker/SendWorker.cpp b/src/modules/im/src/worker/SendWorker.cpp index 15366d6e..5d65770e 100644 --- a/src/modules/im/src/worker/SendWorker.cpp +++ b/src/modules/im/src/worker/SendWorker.cpp @@ -26,95 +26,111 @@ #include #include -SendWorker::SendWorker(const FriendId &friendId) : contactId{friendId} { - qDebug() << __func__ << "friend:" << friendId.toString(); +SendWorker::SendWorker(const FriendId& friendId) : contactId{friendId} { + qDebug() << __func__ << "friend:" << friendId.toString(); - auto core = Core::getInstance(); - auto &settings = Settings::getInstance(); - auto profile = Nexus::getProfile(); - auto history = profile->getHistory(); + auto core = Core::getInstance(); + auto& settings = Settings::getInstance(); + auto profile = Nexus::getProfile(); + auto history = profile->getHistory(); - initChatHeader(friendId); + initChatHeader(friendId); - messageDispatcher = std::make_unique(friendId, sharedParams, *core, *core); + messageDispatcher = + std::make_unique(friendId, sharedParams, *core, *core); - chatHistory = std::make_unique(friendId, history, *core, settings, *messageDispatcher.get()); + chatHistory = std::make_unique(friendId, history, *core, settings, + *messageDispatcher.get()); - chatForm = std::make_unique(&friendId, *chatHistory.get(), *messageDispatcher.get()); + chatForm = std::make_unique(&friendId, *chatHistory.get(), *messageDispatcher.get()); - chatRoom = std::make_unique(&friendId, ContentDialogManager::getInstance()); + chatRoom = std::make_unique(&friendId, ContentDialogManager::getInstance()); } -SendWorker::SendWorker(const GroupId &groupId) : contactId{groupId} { - qDebug() << __func__ << "group:" << groupId.toString(); +SendWorker::SendWorker(const GroupId& groupId) : contactId{groupId} { + qDebug() << __func__ << "group:" << groupId.toString(); - auto profile = Nexus::getProfile(); - auto core = Core::getInstance(); - auto &settings = Settings::getInstance(); - auto history = profile->getHistory(); + auto profile = Nexus::getProfile(); + auto core = Core::getInstance(); + auto& settings = Settings::getInstance(); + auto history = profile->getHistory(); - initChatHeader(groupId); + initChatHeader(groupId); - messageDispatcher = std::make_unique(groupId, sharedParams, *core, *core, Settings::getInstance()); + messageDispatcher = std::make_unique(groupId, sharedParams, *core, + *core, Settings::getInstance()); - chatLog = std::make_unique(*core); - connect(messageDispatcher.get(), &IMessageDispatcher::messageSent, chatLog.get(), &SessionChatLog::onMessageSent); - connect(messageDispatcher.get(), &IMessageDispatcher::messageComplete, chatLog.get(), &SessionChatLog::onMessageComplete); - connect(messageDispatcher.get(), &IMessageDispatcher::messageReceived, chatLog.get(), &SessionChatLog::onMessageReceived); + chatLog = std::make_unique(*core); + connect(messageDispatcher.get(), &IMessageDispatcher::messageSent, chatLog.get(), + &SessionChatLog::onMessageSent); + connect(messageDispatcher.get(), &IMessageDispatcher::messageComplete, chatLog.get(), + &SessionChatLog::onMessageComplete); + connect(messageDispatcher.get(), &IMessageDispatcher::messageReceived, chatLog.get(), + &SessionChatLog::onMessageReceived); - chatForm = std::make_unique(&groupId, *chatLog.get(), *messageDispatcher.get(), settings); + chatForm = std::make_unique(&groupId, *chatLog.get(), *messageDispatcher.get(), + settings); - chatRoom = std::make_unique(&groupId, ContentDialogManager::getInstance()); + chatRoom = std::make_unique(&groupId, ContentDialogManager::getInstance()); } SendWorker::~SendWorker() { qDebug() << __func__; } void SendWorker::clearHistory() { - auto profile = Nexus::getProfile(); - auto history = profile->getHistory(); - history->removeFriendHistory(contactId.toString()); + auto profile = Nexus::getProfile(); + auto history = profile->getHistory(); + history->removeFriendHistory(contactId.toString()); } -std::unique_ptr SendWorker::forFriend(const FriendId &friend_) { return std::make_unique(friend_); } +std::unique_ptr SendWorker::forFriend(const FriendId& friend_) { + return std::make_unique(friend_); +} -std::unique_ptr SendWorker::forGroup(const GroupId &group) { return std::make_unique(group); } +std::unique_ptr SendWorker::forGroup(const GroupId& group) { + return std::make_unique(group); +} -void SendWorker::initChatHeader(const ContactId &contactId) { - headWidget = std::make_unique(contactId); +void SendWorker::initChatHeader(const ContactId& contactId) { + headWidget = std::make_unique(contactId); - connect(headWidget.get(), &ChatFormHeader::callAccepted, this, [this](const ToxPeer &p) { emit acceptCall(p, lastCallIsVideo); }); + connect(headWidget.get(), &ChatFormHeader::callAccepted, this, + [this](const ToxPeer& p) { emit acceptCall(p, lastCallIsVideo); }); - connect(headWidget.get(), &ChatFormHeader::callRejected, this, [this](const ToxPeer &p) { emit rejectCall(p); }); + connect(headWidget.get(), &ChatFormHeader::callRejected, this, + [this](const ToxPeer& p) { emit rejectCall(p); }); - connect(headWidget.get(), &ChatFormHeader::callTriggered, this, &SendWorker::onCallTriggered); + connect(headWidget.get(), &ChatFormHeader::callTriggered, this, &SendWorker::onCallTriggered); - connect(headWidget.get(), &ChatFormHeader::videoCallTriggered, this, &SendWorker::onVideoCallTriggered); + connect(headWidget.get(), &ChatFormHeader::videoCallTriggered, this, + &SendWorker::onVideoCallTriggered); } void SendWorker::startCounter(bool video) { - qDebug() << __func__; - - if (!callDuration) { - callDuration = std::make_unique(); - callDuration->setContact(headWidget->getContact()); - - connect(callDuration.get(), &CallDurationForm::endCall, [&]() { emit endCall(); }); - connect(callDuration.get(), &CallDurationForm::muteSpeaker, [&](bool mute) { emit muteSpeaker(mute); }); - connect(callDuration.get(), &CallDurationForm::muteMicrophone, [&](bool mute) { emit muteMicrophone(mute); }); - } - - callDuration->show(); - if(video){ - callDuration->showNetcam(); - }else{ - callDuration->showAvatar(); - } + qDebug() << __func__; + + if (!callDuration) { + callDuration = std::make_unique(); + callDuration->setContact(headWidget->getContact()); + + connect(callDuration.get(), &CallDurationForm::endCall, [&]() { emit endCall(); }); + connect(callDuration.get(), &CallDurationForm::muteSpeaker, + [&](bool mute) { emit muteSpeaker(mute); }); + connect(callDuration.get(), &CallDurationForm::muteMicrophone, + [&](bool mute) { emit muteMicrophone(mute); }); + } + + callDuration->show(); + if (video) { + callDuration->showNetcam(); + } else { + callDuration->showAvatar(); + } } void SendWorker::stopCounter(bool error) { - qDebug() << __func__; - if (!callDuration) { - return; - } - callDuration.reset(); + qDebug() << __func__; + if (!callDuration) { + return; + } + callDuration.reset(); } diff --git a/src/modules/im/src/worker/SendWorker.h b/src/modules/im/src/worker/SendWorker.h index 38bccc55..f14db445 100644 --- a/src/modules/im/src/worker/SendWorker.h +++ b/src/modules/im/src/worker/SendWorker.h @@ -17,14 +17,14 @@ #ifndef OKMSG_PROJECT_SENDWORKER_H #define OKMSG_PROJECT_SENDWORKER_H -#include -#include "src/model/message.h" #include #include #include #include +#include +#include "src/model/message.h" -class SendWorker : public QObject{ +class SendWorker : public QObject { Q_OBJECT public: SendWorker(const FriendId& m_friend); @@ -33,38 +33,25 @@ class SendWorker : public QObject{ void clearHistory(); - static std::unique_ptr forFriend(const FriendId& m_friend); - static std::unique_ptr forGroup(const GroupId& m_group); - + static std::unique_ptr forFriend(const FriendId& m_friend); + static std::unique_ptr forGroup(const GroupId& m_group); -ChatFormHeader* getHeader()const{ - return headWidget.get(); -} + ChatFormHeader* getHeader() const { return headWidget.get(); } - GenericChatForm* getChatForm() const { - return chatForm.get(); - }; + GenericChatForm* getChatForm() const { return chatForm.get(); }; - Chatroom* getChatroom() const { - return chatRoom.get(); - } + Chatroom* getChatroom() const { return chatRoom.get(); } - IMessageDispatcher* dispacher(){ - return messageDispatcher.get(); - } + IMessageDispatcher* dispacher() { return messageDispatcher.get(); } - QList getLastTextMessage(){ - return chatHistory->getLastTextMessage(1); - } + QList getLastTextMessage() { return chatHistory->getLastTextMessage(1); } - IChatLog* getChatLog()const{ - return chatHistory.get(); - } + IChatLog* getChatLog() const { return chatHistory.get(); } void startCounter(bool video = false); void stopCounter(bool error = false); private: - void initChatHeader(const ContactId &contactId); + void initChatHeader(const ContactId& contactId); MessageProcessor::SharedParams sharedParams; @@ -88,7 +75,6 @@ ChatFormHeader* getHeader()const{ void endCall(); void muteSpeaker(bool mute); void muteMicrophone(bool mute); - }; -#endif // OKMSG_PROJECT_SENDWORKER_H +#endif // OKMSG_PROJECT_SENDWORKER_H diff --git a/src/modules/module.h b/src/modules/module.h index 4a4c3831..93175102 100644 --- a/src/modules/module.h +++ b/src/modules/module.h @@ -12,45 +12,41 @@ #pragma once -#include "lib/session/AuthSession.h" #include #include #include +#include "lib/session/AuthSession.h" class Profile; class QWidget; class IAudioControl; typedef struct { - QByteArray windowGeometry; + QByteArray windowGeometry; } SavedInfo; typedef enum { - MM_Avatar // 头像 + MM_Avatar // 头像 } PayloadType; typedef struct { - PayloadType type; - QByteArray payload; + PayloadType type; + QByteArray payload; } ModuleMessage; class Module { - public: - static QString Name(); - static Module *Create(); - - virtual ~Module(){}; - virtual void init(Profile *p) = 0; - virtual QString name() = 0; - virtual QWidget *widget() = 0; - virtual void start(ok::session::SignInInfo &signInInfo) = 0; - virtual bool isStarted() = 0; - virtual void hide() = 0; - virtual void onSave(SavedInfo &) = 0; - virtual void cleanup() = 0; - virtual void destroy() = 0; - - + static QString Name(); + static Module* Create(); + + virtual ~Module(){}; + virtual void init(Profile* p) = 0; + virtual QString name() = 0; + virtual QWidget* widget() = 0; + virtual void start(std::shared_ptr session) = 0; + virtual bool isStarted() = 0; + virtual void hide() = 0; + virtual void onSave(SavedInfo&) = 0; + virtual void cleanup() = 0; + virtual void destroy() = 0; }; - diff --git a/src/modules/platform/CMakeLists.txt b/src/modules/platform/CMakeLists.txt index d8121392..ae1bed04 100644 --- a/src/modules/platform/CMakeLists.txt +++ b/src/modules/platform/CMakeLists.txt @@ -1,16 +1,82 @@ project(Platform) +add_definitions(-DOK_${PROJECT_NAME}_MODULE="${PROJECT_NAME}") + +file(GLOB_RECURSE ${PROJECT_NAME}_SOURCES src/*.h src/*.cpp) +file(GLOB_RECURSE ${PROJECT_NAME}_RESOURCES res/*.html res/*.js) +file(GLOB_RECURSE ${PROJECT_NAME}_UIS src/*.ui) + +file(GLOB ${PROJECT_NAME}_TSS + ts/*.ts + ts/*.xml +) +qt5_add_translation( + ${PROJECT_NAME}_QM_FILES + ${${PROJECT_NAME}_TSS} +) + +set(RESOURCE_NAME "${PROJECT_BINARY_DIR}/${PROJECT_NAME}.qrc.in") + +file(WRITE "${RESOURCE_NAME}" + " + + +") +# ts +file(APPEND "${RESOURCE_NAME}" " +") #换行 +foreach (qm ${${PROJECT_NAME}_QM_FILES}) + get_filename_component(qm_name ${qm} NAME) + file(APPEND "${RESOURCE_NAME}" + #留出格式空间 + " ${qm}\n") +endforeach (qm) +file(APPEND "${RESOURCE_NAME}" + "") + +file(APPEND "${RESOURCE_NAME}" " + +") #换行 + +foreach (f ${${PROJECT_NAME}_RESOURCES}) + get_filename_component(f_name ${f} NAME) + file(APPEND "${RESOURCE_NAME}" + " ${f}\n") +endforeach (f) + +file(APPEND "${RESOURCE_NAME}" + " + +") + +execute_process( + COMMAND + ${CMAKE_COMMAND} -E copy_if_different + ${RESOURCE_NAME} + ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.qrc) + +qt5_add_resources( + ${PROJECT_NAME}_RESOURCES + ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.qrc +) + +qt5_wrap_ui(${PROJECT_NAME}_FORMS + ${${PROJECT_NAME}_UIS} +) -file(GLOB ${PROJECT_NAME}_SOURCES src/*.h src/*.cpp) add_library(${PROJECT_NAME} STATIC ${${PROJECT_NAME}_SOURCES} + ${${PROJECT_NAME}_RESOURCES} + ${${PROJECT_NAME}_FORMS} ) -find_package(Qt5 COMPONENTS Core Widgets WebEngine WebEngineWidgets REQUIRED) +find_package(Qt5 COMPONENTS Core Widgets WebChannel WebSockets WebEngine WebEngineWidgets REQUIRED) target_link_libraries(${PROJECT_NAME} + PRIVATE ${Qt5WebChannel_LIBRARIES} + PRIVATE ${Qt5WebSockets_LIBRARIES} PRIVATE ${Qt5WebEngineWidgets_LIBRARIES} PRIVATE ${Qt5WebEngine_LIBRARIES} PRIVATE ${Qt5Widgets_LIBRARIES} PRIVATE ${Qt5Core_LIBRARIES} -) \ No newline at end of file +) diff --git a/src/modules/platform/res/html/platform.html b/src/modules/platform/res/html/platform.html new file mode 100644 index 00000000..d2e5b9ff --- /dev/null +++ b/src/modules/platform/res/html/platform.html @@ -0,0 +1,76 @@ + + + + + + + Work platform + + + + + + + + + +
    + +
+ + + \ No newline at end of file diff --git a/src/modules/platform/res/html/platform.js b/src/modules/platform/res/html/platform.js new file mode 100644 index 00000000..e5683b1d --- /dev/null +++ b/src/modules/platform/res/html/platform.js @@ -0,0 +1,35 @@ +/** + * ~ Copyright (c) 2022 船山信息 chuanshaninfo.com + * ~ The project is licensed under Mulan PubL v2. + * ~ You can use this software according to the terms and conditions of the Mulan + * ~ PubL v2. You may obtain a copy of Mulan PubL v2 at: + * ~ http://license.coscl.org.cn/MulanPubL-2.0 + * ~ THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * ~ EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * ~ MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * ~ See the Mulan PubL v2 for more details. + */ +var wsUri = "ws://localhost:65500"; +window.loggedin = false; +window.onload = function () { + var appList = $("#app-list"); + var socket = new WebSocket(wsUri); + + socket.onclose = function () { + console.error("web channel closed"); + }; + + socket.onerror = function (error) { + console.error("web channel error: " + error); + }; + + socket.onmessage = function (event) { + console.log('Message from server', event.data); + const app = JSON.parse(event.data); + appList.append("
  • " + app.name + "
  • "); + }; + + socket.onopen = function () { + + } +} diff --git a/src/modules/platform/res/html/qwebchannel.js b/src/modules/platform/res/html/qwebchannel.js new file mode 100644 index 00000000..32ad51eb --- /dev/null +++ b/src/modules/platform/res/html/qwebchannel.js @@ -0,0 +1,448 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebChannel module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +"use strict"; + +var QWebChannelMessageTypes = { + signal: 1, + propertyUpdate: 2, + init: 3, + idle: 4, + debug: 5, + invokeMethod: 6, + connectToSignal: 7, + disconnectFromSignal: 8, + setProperty: 9, + response: 10, +}; + +var QWebChannel = function(transport, initCallback) +{ + if (typeof transport !== "object" || typeof transport.send !== "function") { + console.error("The QWebChannel expects a transport object with a send function and onmessage callback property." + + " Given is: transport: " + typeof(transport) + ", transport.send: " + typeof(transport.send)); + return; + } + + var channel = this; + this.transport = transport; + + this.send = function(data) + { + if (typeof(data) !== "string") { + data = JSON.stringify(data); + } + channel.transport.send(data); + } + + this.transport.onmessage = function(message) + { + var data = message.data; + if (typeof data === "string") { + data = JSON.parse(data); + } + switch (data.type) { + case QWebChannelMessageTypes.signal: + channel.handleSignal(data); + break; + case QWebChannelMessageTypes.response: + channel.handleResponse(data); + break; + case QWebChannelMessageTypes.propertyUpdate: + channel.handlePropertyUpdate(data); + break; + default: + console.error("invalid message received:", message.data); + break; + } + } + + this.execCallbacks = {}; + this.execId = 0; + this.exec = function(data, callback) + { + if (!callback) { + // if no callback is given, send directly + channel.send(data); + return; + } + if (channel.execId === Number.MAX_VALUE) { + // wrap + channel.execId = Number.MIN_VALUE; + } + if (data.hasOwnProperty("id")) { + console.error("Cannot exec message with property id: " + JSON.stringify(data)); + return; + } + data.id = channel.execId++; + channel.execCallbacks[data.id] = callback; + channel.send(data); + }; + + this.objects = {}; + + this.handleSignal = function(message) + { + var object = channel.objects[message.object]; + if (object) { + object.signalEmitted(message.signal, message.args); + } else { + console.warn("Unhandled signal: " + message.object + "::" + message.signal); + } + } + + this.handleResponse = function(message) + { + if (!message.hasOwnProperty("id")) { + console.error("Invalid response message received: ", JSON.stringify(message)); + return; + } + channel.execCallbacks[message.id](message.data); + delete channel.execCallbacks[message.id]; + } + + this.handlePropertyUpdate = function(message) + { + message.data.forEach(data => { + var object = channel.objects[data.object]; + if (object) { + object.propertyUpdate(data.signals, data.properties); + } else { + console.warn("Unhandled property update: " + data.object + "::" + data.signal); + } + }); + channel.exec({type: QWebChannelMessageTypes.idle}); + } + + this.debug = function(message) + { + channel.send({type: QWebChannelMessageTypes.debug, data: message}); + }; + + channel.exec({type: QWebChannelMessageTypes.init}, function(data) { + for (const objectName of Object.keys(data)) { + new QObject(objectName, data[objectName], channel); + } + + // now unwrap properties, which might reference other registered objects + for (const objectName of Object.keys(channel.objects)) { + channel.objects[objectName].unwrapProperties(); + } + + if (initCallback) { + initCallback(channel); + } + channel.exec({type: QWebChannelMessageTypes.idle}); + }); +}; + +function QObject(name, data, webChannel) +{ + this.__id__ = name; + webChannel.objects[name] = this; + + // List of callbacks that get invoked upon signal emission + this.__objectSignals__ = {}; + + // Cache of all properties, updated when a notify signal is emitted + this.__propertyCache__ = {}; + + var object = this; + + // ---------------------------------------------------------------------- + + this.unwrapQObject = function(response) + { + if (response instanceof Array) { + // support list of objects + return response.map(qobj => object.unwrapQObject(qobj)) + } + if (!(response instanceof Object)) + return response; + + if (!response["__QObject*__"] || response.id === undefined) { + var jObj = {}; + for (const propName of Object.keys(response)) { + jObj[propName] = object.unwrapQObject(response[propName]); + } + return jObj; + } + + var objectId = response.id; + if (webChannel.objects[objectId]) + return webChannel.objects[objectId]; + + if (!response.data) { + console.error("Cannot unwrap unknown QObject " + objectId + " without data."); + return; + } + + var qObject = new QObject( objectId, response.data, webChannel ); + qObject.destroyed.connect(function() { + if (webChannel.objects[objectId] === qObject) { + delete webChannel.objects[objectId]; + // reset the now deleted QObject to an empty {} object + // just assigning {} though would not have the desired effect, but the + // below also ensures all external references will see the empty map + // NOTE: this detour is necessary to workaround QTBUG-40021 + Object.keys(qObject).forEach(name => delete qObject[name]); + } + }); + // here we are already initialized, and thus must directly unwrap the properties + qObject.unwrapProperties(); + return qObject; + } + + this.unwrapProperties = function() + { + for (const propertyIdx of Object.keys(object.__propertyCache__)) { + object.__propertyCache__[propertyIdx] = object.unwrapQObject(object.__propertyCache__[propertyIdx]); + } + } + + function addSignal(signalData, isPropertyNotifySignal) + { + var signalName = signalData[0]; + var signalIndex = signalData[1]; + object[signalName] = { + connect: function(callback) { + if (typeof(callback) !== "function") { + console.error("Bad callback given to connect to signal " + signalName); + return; + } + + object.__objectSignals__[signalIndex] = object.__objectSignals__[signalIndex] || []; + object.__objectSignals__[signalIndex].push(callback); + + // only required for "pure" signals, handled separately for properties in propertyUpdate + if (isPropertyNotifySignal) + return; + + // also note that we always get notified about the destroyed signal + if (signalName === "destroyed" || signalName === "destroyed()" || signalName === "destroyed(QObject*)") + return; + + // and otherwise we only need to be connected only once + if (object.__objectSignals__[signalIndex].length == 1) { + webChannel.exec({ + type: QWebChannelMessageTypes.connectToSignal, + object: object.__id__, + signal: signalIndex + }); + } + }, + disconnect: function(callback) { + if (typeof(callback) !== "function") { + console.error("Bad callback given to disconnect from signal " + signalName); + return; + } + object.__objectSignals__[signalIndex] = object.__objectSignals__[signalIndex] || []; + var idx = object.__objectSignals__[signalIndex].indexOf(callback); + if (idx === -1) { + console.error("Cannot find connection of signal " + signalName + " to " + callback.name); + return; + } + object.__objectSignals__[signalIndex].splice(idx, 1); + if (!isPropertyNotifySignal && object.__objectSignals__[signalIndex].length === 0) { + // only required for "pure" signals, handled separately for properties in propertyUpdate + webChannel.exec({ + type: QWebChannelMessageTypes.disconnectFromSignal, + object: object.__id__, + signal: signalIndex + }); + } + } + }; + } + + /** + * Invokes all callbacks for the given signalname. Also works for property notify callbacks. + */ + function invokeSignalCallbacks(signalName, signalArgs) + { + var connections = object.__objectSignals__[signalName]; + if (connections) { + connections.forEach(function(callback) { + callback.apply(callback, signalArgs); + }); + } + } + + this.propertyUpdate = function(signals, propertyMap) + { + // update property cache + for (const propertyIndex of Object.keys(propertyMap)) { + var propertyValue = propertyMap[propertyIndex]; + object.__propertyCache__[propertyIndex] = this.unwrapQObject(propertyValue); + } + + for (const signalName of Object.keys(signals)) { + // Invoke all callbacks, as signalEmitted() does not. This ensures the + // property cache is updated before the callbacks are invoked. + invokeSignalCallbacks(signalName, signals[signalName]); + } + } + + this.signalEmitted = function(signalName, signalArgs) + { + invokeSignalCallbacks(signalName, this.unwrapQObject(signalArgs)); + } + + function addMethod(methodData) + { + var methodName = methodData[0]; + var methodIdx = methodData[1]; + + // Fully specified methods are invoked by id, others by name for host-side overload resolution + var invokedMethod = methodName[methodName.length - 1] === ')' ? methodIdx : methodName + + object[methodName] = function() { + var args = []; + var callback; + var errCallback; + for (var i = 0; i < arguments.length; ++i) { + var argument = arguments[i]; + if (typeof argument === "function") + callback = argument; + else if (argument instanceof QObject && webChannel.objects[argument.__id__] !== undefined) + args.push({ + "id": argument.__id__ + }); + else + args.push(argument); + } + + var result; + // during test, webChannel.exec synchronously calls the callback + // therefore, the promise must be constucted before calling + // webChannel.exec to ensure the callback is set up + if (!callback && (typeof(Promise) === 'function')) { + result = new Promise(function(resolve, reject) { + callback = resolve; + errCallback = reject; + }); + } + + webChannel.exec({ + "type": QWebChannelMessageTypes.invokeMethod, + "object": object.__id__, + "method": invokedMethod, + "args": args + }, function(response) { + if (response !== undefined) { + var result = object.unwrapQObject(response); + if (callback) { + (callback)(result); + } + } else if (errCallback) { + (errCallback)(); + } + }); + + return result; + }; + } + + function bindGetterSetter(propertyInfo) + { + var propertyIndex = propertyInfo[0]; + var propertyName = propertyInfo[1]; + var notifySignalData = propertyInfo[2]; + // initialize property cache with current value + // NOTE: if this is an object, it is not directly unwrapped as it might + // reference other QObject that we do not know yet + object.__propertyCache__[propertyIndex] = propertyInfo[3]; + + if (notifySignalData) { + if (notifySignalData[0] === 1) { + // signal name is optimized away, reconstruct the actual name + notifySignalData[0] = propertyName + "Changed"; + } + addSignal(notifySignalData, true); + } + + Object.defineProperty(object, propertyName, { + configurable: true, + get: function () { + var propertyValue = object.__propertyCache__[propertyIndex]; + if (propertyValue === undefined) { + // This shouldn't happen + console.warn("Undefined value in property cache for property \"" + propertyName + "\" in object " + object.__id__); + } + + return propertyValue; + }, + set: function(value) { + if (value === undefined) { + console.warn("Property setter for " + propertyName + " called with undefined value!"); + return; + } + object.__propertyCache__[propertyIndex] = value; + var valueToSend = value; + if (valueToSend instanceof QObject && webChannel.objects[valueToSend.__id__] !== undefined) + valueToSend = { "id": valueToSend.__id__ }; + webChannel.exec({ + "type": QWebChannelMessageTypes.setProperty, + "object": object.__id__, + "property": propertyIndex, + "value": valueToSend + }); + } + }); + + } + + // ---------------------------------------------------------------------- + + data.methods.forEach(addMethod); + + data.properties.forEach(bindGetterSetter); + + data.signals.forEach(function(signal) { addSignal(signal, false); }); + + Object.assign(object, data.enums); +} + +//required for use with nodejs +if (typeof module === 'object') { + module.exports = { + QWebChannel: QWebChannel + }; +} diff --git a/src/modules/platform/src/AccessToken.cpp b/src/modules/platform/src/AccessToken.cpp new file mode 100644 index 00000000..6a45903c --- /dev/null +++ b/src/modules/platform/src/AccessToken.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022 船山信息 chuanshaninfo.com + * The project is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan + * PubL v2. You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +// +// Created by gaojie on 24-8-3. +// + +#include "AccessToken.h" +#include "lib/backend/PassportService.h" + +namespace ok::platform { + +AccessToken::AccessToken() : expiresIn{0}, refreshExpiresIn{0} {} + +AccessToken::AccessToken(backend::SysToken& sysToken) + : username(sysToken.username) + , tokenType(sysToken.tokenType) + , accessToken(sysToken.accessToken) + , expiresIn(sysToken.expiresIn) + , refreshToken(sysToken.accessToken) + , refreshExpiresIn(sysToken.refreshExpiresIn) + , session_state(sysToken.session_state) {} +AccessToken::~AccessToken() = default; +} // namespace ok::platform \ No newline at end of file diff --git a/src/modules/platform/src/AccessToken.h b/src/modules/platform/src/AccessToken.h new file mode 100644 index 00000000..2bee90b8 --- /dev/null +++ b/src/modules/platform/src/AccessToken.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2022 船山信息 chuanshaninfo.com + * The project is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan + * PubL v2. You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +// +// Created by gaojie on 24-8-3. +// + +#pragma once +#include +namespace ok { +namespace backend { +class SysToken; +} +} // namespace ok +namespace ok::platform { + +class AccessToken : public QObject { + Q_OBJECT +public: + AccessToken(); + AccessToken(backend::SysToken& sysToken); + ~AccessToken(); + + QString username; + QString tokenType; + QString accessToken; + quint64 expiresIn; + QString refreshToken; + quint64 refreshExpiresIn; + QString session_state; +}; + +} // namespace ok::platform diff --git a/src/modules/platform/src/AppCenterWidget.cpp b/src/modules/platform/src/AppCenterWidget.cpp new file mode 100644 index 00000000..6292b149 --- /dev/null +++ b/src/modules/platform/src/AppCenterWidget.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2022 船山信息 chuanshaninfo.com + * The project is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan + * PubL v2. You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +// +// Created by gaojie on 24-8-4. +// + +#include "AppCenterWidget.h" +#include +#include +#include +#include +#include + +#include "Backend.h" +#include "application.h" +#include "websocketclientwrapper.h" +#include "websockettransport.h" + +namespace ok::platform { + +AppCenterWidget::AppCenterWidget(QWidget* parent) : UI::OWidget(parent) { + setLayout(new QGridLayout); +} + +void AppCenterWidget::startWebEngine() { + QString htmlContent; + QFile file(":/res/Platform/platform.html"); + if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { + QTextStream in(&file); + htmlContent = in.readAll(); + file.close(); + } + + webView = new QWebEngineView(this); + webView->setContent(htmlContent.toUtf8(), "text/html", QUrl("file:///")); + + // auto page = webView->page(); + // webChannel = new QWebChannel(page); + // webChannel->registerObject(QStringLiteral("accessToken"), &accessToken); + // page->setWebChannel(webChannel); + + layout()->addWidget(webView); +} + +void AppCenterWidget::startWsServer() { + wss = new QWebSocketServer(QStringLiteral("OkStar Websocket Server"), + QWebSocketServer::NonSecureMode); + + if (!wss->listen(QHostAddress::LocalHost, 65500)) { + qWarning() << "Failed to open web socket server."; + return; + } + + // wrap WebSocket clients in QWebChannelAbstractTransport objects + clientWrapper = new WebSocketClientWrapper(wss); + + // setup the channel + // connect(clientWrapper, + // &WebSocketClientWrapper::clientConnected, + // webChannel, + // &QWebChannel::connectTo); + connect(clientWrapper, + &WebSocketClientWrapper::clientConnected, + this, + &AppCenterWidget::clientConnected); +} + +void AppCenterWidget::clientConnected(WebSocketTransport* transport) { + auto session = ok::Application::Instance()->getSession(); + auto token = session->getToken(); + + auto backend = new Backend(session->getSignInInfo().stackUrl); + backend->setHeader("Authorization", token.tokenType + " " + token.accessToken); + backend->getAppList([=](QByteArray body, QString name) { + auto arr = Jsons::toJSON(body).object().value("data").toObject().value("list").toArray(); + for (auto app : arr) { + auto a = app.toObject(); + // qDebug() <sendMessage(a); + } + }); +} +void AppCenterWidget::start() { + startWebEngine(); + startWsServer(); +} + +} // namespace ok::platform diff --git a/src/modules/platform/src/AppCenterWidget.h b/src/modules/platform/src/AppCenterWidget.h new file mode 100644 index 00000000..952dcde3 --- /dev/null +++ b/src/modules/platform/src/AppCenterWidget.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022 船山信息 chuanshaninfo.com + * The project is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan + * PubL v2. You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +// +// Created by gaojie on 24-8-4. +// + +#pragma once + +#include "UI/widget/OWidget.h" + +class QWebEngineView; +class QWebChannel; +class QThread; +class QWebSocketServer; +class WebSocketClientWrapper; +class WebSocketTransport; + +namespace ok::platform { +class AppCenterWidget : public UI::OWidget { + Q_OBJECT +public: + AppCenterWidget(QWidget* parent = nullptr); + void start(); + +private: + std::unique_ptr thread; + + QWebEngineView* webView; + QWebChannel* webChannel; + QWebSocketServer* wss; + WebSocketClientWrapper* clientWrapper; + + void startWsServer(); + void startWebEngine(); + +public slots: + void clientConnected(WebSocketTransport* transport); +}; +} // namespace ok::platform diff --git a/src/modules/platform/src/Backend.cpp b/src/modules/platform/src/Backend.cpp new file mode 100644 index 00000000..566e13ed --- /dev/null +++ b/src/modules/platform/src/Backend.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2022 船山信息 chuanshaninfo.com + * The project is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan + * PubL v2. You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +// +// Created by gaojie on 24-8-3. +// + +#include "Backend.h" +namespace ok::platform { + +Backend::Backend(const QString& baseUrl, QObject* parent) + : ok::backend::BaseService(baseUrl, parent) {} + +bool Backend::getAppList(const network::HttpBodyFn& fn, int pageIndex, int pageSize) { + QString url = _baseUrl + "/api/sys/work/app/page"; + + QJsonDocument doc; + QJsonObject obj; + obj.insert("pageIndex", pageIndex); + obj.insert("pageSize", pageSize); + doc.setObject(obj); + headers.insert("Origin", _baseUrl); + http->setHeaders(headers); + return http->postJson(QUrl(url), doc, fn, nullptr, nullptr, nullptr); +} + +} // namespace ok::platform diff --git a/src/modules/platform/src/Backend.h b/src/modules/platform/src/Backend.h new file mode 100644 index 00000000..e738f788 --- /dev/null +++ b/src/modules/platform/src/Backend.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2022 船山信息 chuanshaninfo.com + * The project is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan + * PubL v2. You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +// +// Created by gaojie on 24-8-3. +// +#pragma once + +#include +#include +#include "lib/backend/BaseService.h" + +namespace ok::platform { + +struct App { + /** + * {"id":51, + * "key":"企业IM", + * "name":"OkMSG商业套装", + * "avatar":"https://s3.okstar.org.cn/okcloud/fdc636f5-955c-47a8-bca1-253cfbeb35c6.png", + * "descr":"OkMSG +是由OkStar社区维护的跨平台的企业通讯协同工具,支持独立私有化部署的集即时消息、语音和视频通话、发送文件、会议等多种功能于一身的开源项目。同时非常注重数据安全与保护, + 让您的企业更加有效开启协作、有效沟通,控制成本,开拓新业务,并帮助您加速发展业务。", +"author":null, +"mail":null, +"homePage":null, +"providerId":1, +"introduceId":null}, + */ + + int64 id; + QString key; + QString name; + QString avatar; + QString descr; + QString author; + QString mail; + QString homePage; + QString type; + + App(const QJsonObject& data) { + id = data.value("id").toInt(); // + mail = data.value("mail").toString(); // + name = data.value("name").toString(); // + descr = data.value("descr").toString(); // + author = data.value("author").toString(); // + homePage = data.value("homePage").toString(); // + type = data.value("type").toString(); // + } + + QJsonObject toJson() { + QJsonObject jo; + jo.insert("id", id); + jo.insert("key", key); + jo.insert("name", name); + jo.insert("author", author); + return jo; + } + + QString toJsonString() { return QString(QJsonDocument(toJson()).toJson()); } +}; + +class Backend : public ok::backend::BaseService { + Q_OBJECT +public: + Backend(const QString& baseUrl, QObject* parent = nullptr); + + bool getAppList(const network::HttpBodyFn& fn, int res = 0, int pageSize = 50); +}; + +} // namespace ok::platform diff --git a/src/modules/platform/src/Platform.cpp b/src/modules/platform/src/Platform.cpp index 844aa109..af8d636c 100644 --- a/src/modules/platform/src/Platform.cpp +++ b/src/modules/platform/src/Platform.cpp @@ -16,22 +16,20 @@ #include "Platform.h" -namespace platform { +namespace ok::platform { -Platform::Platform(): m_widget{nullptr} { - m_widget = new Widget(); -} +Platform::Platform() : m_widget{nullptr} { m_widget = std::make_unique(); } -Platform::~Platform() { +Platform::~Platform() {} -} +void Platform::init(Profile* p) {} +QString Platform::name() { return {"Platform"}; } + +void Platform::start(std::shared_ptr session) { m_widget->start(); } -void Platform::init(Profile *p) {} -QString Platform::name() { return QString(); } -void Platform::start(ok::session::SignInInfo &signInInfo) {} bool Platform::isStarted() { return false; } -void Platform::onSave(SavedInfo &) {} +void Platform::onSave(SavedInfo&) {} void Platform::cleanup() {} void Platform::destroy() {} void Platform::hide() {} -} // namespace platform +} // namespace ok::platform diff --git a/src/modules/platform/src/Platform.h b/src/modules/platform/src/Platform.h index 4b4f728f..33540b5a 100644 --- a/src/modules/platform/src/Platform.h +++ b/src/modules/platform/src/Platform.h @@ -19,28 +19,25 @@ #include "Widget.h" #include "modules/module.h" -namespace platform{ +namespace ok::platform { class Platform : public QObject, public Module { -Q_OBJECT + Q_OBJECT public: - Platform(); - ~Platform(); - void init(Profile *p) override; - QString name() override; - void start(ok::session::SignInInfo &signInInfo) override; - bool isStarted() override; - void onSave(SavedInfo &) override; - void cleanup() override; - void destroy() override; + Platform(); + ~Platform(); + void init(Profile* p) override; + QString name() override; + void start(std::shared_ptr session) override; + bool isStarted() override; + void onSave(SavedInfo&) override; + void cleanup() override; + void destroy() override; + + QWidget* widget() override{ return m_widget.get(); } + void hide() override; - QWidget * widget() override { - return m_widget; - } - void hide() override; private: - - Widget* m_widget; + std::unique_ptr m_widget; }; -} - +} // namespace ok::platform diff --git a/src/modules/platform/src/Widget.cpp b/src/modules/platform/src/Widget.cpp index 32ce217e..43c6661d 100644 --- a/src/modules/platform/src/Widget.cpp +++ b/src/modules/platform/src/Widget.cpp @@ -15,20 +15,50 @@ // #include "Widget.h" +#include "ui_Widget.h" -#include -#include -#include +#include "AppCenterWidget.h" +#include "Bus.h" +#include "application.h" +#include "base/OkSettings.h" +#include "lib/settings/translator.h" -namespace platform { +namespace ok::platform { -Widget::Widget(QWidget *parent): UI::OMenuWidget(parent) { - setLayout(new QGridLayout()); +Widget::Widget(QWidget* parent) : UI::OMenuWidget(parent), ui(new Ui::WorkPlatform) { + OK_RESOURCE_INIT(Platform); + ui->setupUi(this); + ui->tabWidget->setObjectName("mainTab"); + QString locale = ok::base::OkSettings::getInstance().getTranslation(); + settings::Translator::translate(OK_Platform_MODULE, locale); + settings::Translator::registerHandler([this] { retranslateUi(); }, this); + retranslateUi(); + connect(ok::Application::Instance()->bus(), &ok::Bus::languageChanged, + [](QString locale0) { settings::Translator::translate(OK_Platform_MODULE, locale0); }); - webView = new QWebEngineView(this); - webView->load(QUrl("https://stack.okstar.org.cn")); // 加载网页 + centerWidget = new AppCenterWidget(this); + ui->tabWidget->addTab(centerWidget, tr("App center")); - layout()->addWidget(webView); + // thread = (std::make_unique()); + // thread->setObjectName("WorkPlatform"); + // connect(thread.get(), &QThread::started, this, &Widget::doStart); + // moveToThread(thread.get()); + // } -} // namespace platform \ No newline at end of file + +Widget::~Widget() { + settings::Translator::unregister(this); + delete ui; +} + +void Widget::start() { centerWidget->start(); } + +void Widget::doStart() {} + +void Widget::retranslateUi() { + ui->retranslateUi(this); + ui->tabWidget->setTabText(0, tr("App center")); +} + +} // namespace ok::platform diff --git a/src/modules/platform/src/Widget.h b/src/modules/platform/src/Widget.h index dab0de62..cca05530 100644 --- a/src/modules/platform/src/Widget.h +++ b/src/modules/platform/src/Widget.h @@ -16,21 +16,38 @@ #pragma once -#include "UI/widget/OMenuWidget.h" #include +#include "UI/widget/OMenuWidget.h" +#include "base/resources.h" + +OK_RESOURCE_LOADER(Platform) + +namespace Ui { +class WorkPlatform; +} -class QWebEngineView; +namespace ok::platform { -namespace platform{ +class AppCenterWidget; -class Widget : public UI::OMenuWidget{ -Q_OBJECT +class Widget : public UI::OMenuWidget { + Q_OBJECT public: - Widget(QWidget *parent= nullptr); + Widget(QWidget* parent = nullptr); + ~Widget() override; + void start(); + +protected: + void retranslateUi(); private: - QWebEngineView *webView; -}; -} + OK_RESOURCE_PTR(Platform); + Ui::WorkPlatform* ui; + // tab + AppCenterWidget* centerWidget; +public slots: + void doStart(); +}; +} // namespace ok::platform diff --git a/src/modules/platform/src/Widget.ui b/src/modules/platform/src/Widget.ui new file mode 100644 index 00000000..a000597f --- /dev/null +++ b/src/modules/platform/src/Widget.ui @@ -0,0 +1,34 @@ + + + + + WorkPlatform + + + + 0 + 0 + 400 + 300 + + + + + + + + + + + + diff --git a/src/modules/platform/src/websocketclientwrapper.cpp b/src/modules/platform/src/websocketclientwrapper.cpp new file mode 100644 index 00000000..2992e030 --- /dev/null +++ b/src/modules/platform/src/websocketclientwrapper.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2022 船山信息 chuanshaninfo.com + * The project is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan + * PubL v2. You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#include "websocketclientwrapper.h" +#include "websockettransport.h" + +#include + +/*! + \brief Wraps connected QWebSockets clients in WebSocketTransport objects. + + This code is all that is required to connect incoming WebSockets to the WebChannel. Any kind + of remote JavaScript client that supports WebSockets can thus receive messages and access the + published objects. +*/ + +/*! + Construct the client wrapper with the given parent. + + All clients connecting to the QWebSocketServer will be automatically wrapped + in WebSocketTransport objects. +*/ +WebSocketClientWrapper::WebSocketClientWrapper(QWebSocketServer* server, QObject* parent) + : QObject(parent), m_server(server) { + connect(server, &QWebSocketServer::newConnection, this, + &WebSocketClientWrapper::handleNewConnection); +} + +/*! + Wrap an incoming WebSocket connection in a WebSocketTransport object. +*/ +void WebSocketClientWrapper::handleNewConnection() { + emit clientConnected(new WebSocketTransport(m_server->nextPendingConnection())); +} diff --git a/src/modules/platform/src/websocketclientwrapper.h b/src/modules/platform/src/websocketclientwrapper.h new file mode 100644 index 00000000..553497f8 --- /dev/null +++ b/src/modules/platform/src/websocketclientwrapper.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022 船山信息 chuanshaninfo.com + * The project is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan + * PubL v2. You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#ifndef WEBSOCKETCLIENTWRAPPER_H +#define WEBSOCKETCLIENTWRAPPER_H + +#include + +class WebSocketTransport; + +QT_BEGIN_NAMESPACE +class QWebSocketServer; +QT_END_NAMESPACE + +class WebSocketClientWrapper : public QObject { + Q_OBJECT + +public: + WebSocketClientWrapper(QWebSocketServer* server, QObject* parent = nullptr); + +signals: + void clientConnected(WebSocketTransport* client); + +private slots: + void handleNewConnection(); + +private: + QWebSocketServer* m_server; +}; + +#endif // WEBSOCKETCLIENTWRAPPER_H diff --git a/src/modules/platform/src/websockettransport.cpp b/src/modules/platform/src/websockettransport.cpp new file mode 100644 index 00000000..5efb88a5 --- /dev/null +++ b/src/modules/platform/src/websockettransport.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2022 船山信息 chuanshaninfo.com + * The project is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan + * PubL v2. You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#include "websockettransport.h" + +#include +#include +#include +#include + +WebSocketTransport::WebSocketTransport(QWebSocket* socket) + : QWebChannelAbstractTransport(socket), m_socket(socket) { + connect(socket, &QWebSocket::textMessageReceived, this, + &WebSocketTransport::textMessageReceived); + + connect(socket, &QWebSocket::disconnected, this, &WebSocketTransport::deleteLater); +} + +/*! + Destroys the WebSocketTransport. +*/ +WebSocketTransport::~WebSocketTransport() { m_socket->deleteLater(); } + +/*! + Serialize the JSON message and send it as a text message via the WebSocket to the client. +*/ +void WebSocketTransport::sendMessage(const QJsonObject& message) { + QJsonDocument doc(message); + sendMessage(QString::fromUtf8(doc.toJson(QJsonDocument::Compact))); +} + +void WebSocketTransport::sendMessage(const QString& json) { m_socket->sendTextMessage(json); } + +/*! + Deserialize the stringified JSON messageData and emit messageReceived. +*/ +void WebSocketTransport::textMessageReceived(const QString& messageData) { + qDebug() << __func__ << ":" << messageData; + QJsonParseError error; + QJsonDocument message = QJsonDocument::fromJson(messageData.toUtf8(), &error); + if (error.error) { + qWarning() << "Failed to parse text message as JSON object:" << messageData + << "Error is:" << error.errorString(); + return; + } else if (!message.isObject()) { + qWarning() << "Received JSON message that is not an object: " << messageData; + return; + } + emit messageReceived(message.object(), this); +} diff --git a/src/modules/platform/src/websockettransport.h b/src/modules/platform/src/websockettransport.h new file mode 100644 index 00000000..dccedeaa --- /dev/null +++ b/src/modules/platform/src/websockettransport.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2022 船山信息 chuanshaninfo.com + * The project is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan + * PubL v2. You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#ifndef WEBSOCKETTRANSPORT_H +#define WEBSOCKETTRANSPORT_H + +#include + +QT_BEGIN_NAMESPACE +class QWebSocket; +QT_END_NAMESPACE + +class WebSocketTransport : public QWebChannelAbstractTransport { + Q_OBJECT +public: + explicit WebSocketTransport(QWebSocket* socket); + virtual ~WebSocketTransport(); + + void sendMessage(const QJsonObject& message) override; + void sendMessage(const QString& json); + +private slots: + void textMessageReceived(const QString& message); + +private: + QWebSocket* m_socket; +}; + +#endif // WEBSOCKETTRANSPORT_H diff --git a/src/modules/platform/ts/en.xml b/src/modules/platform/ts/en.xml new file mode 100644 index 00000000..e2807cd1 --- /dev/null +++ b/src/modules/platform/ts/en.xml @@ -0,0 +1,23 @@ + + + + + + + ok::platform::Widget + + App center + App Center + + + diff --git a/src/modules/platform/ts/zh_CN.xml b/src/modules/platform/ts/zh_CN.xml new file mode 100644 index 00000000..5d5872a9 --- /dev/null +++ b/src/modules/platform/ts/zh_CN.xml @@ -0,0 +1,23 @@ + + + + + + + ok::platform::Widget + + App center + 应用中心 + + + diff --git a/src/modules/platform/ts/zh_TW.xml b/src/modules/platform/ts/zh_TW.xml new file mode 100644 index 00000000..f67bc30a --- /dev/null +++ b/src/modules/platform/ts/zh_TW.xml @@ -0,0 +1,23 @@ + + + + + + + ok::platform::Widget + + App center + 應用中心 + + + diff --git a/src/profilelocker.cpp b/src/profilelocker.cpp index c8670fc6..fb9b5e7f 100644 --- a/src/profilelocker.cpp +++ b/src/profilelocker.cpp @@ -10,11 +10,10 @@ * See the Mulan PubL v2 for more details. */ - #include "profilelocker.h" -#include "persistence/im/settings.h" #include #include +#include "persistence/im/settings.h" /** * @class ProfileLocker @@ -29,8 +28,7 @@ using namespace std; unique_ptr ProfileLocker::lockfile; QString ProfileLocker::curLockName; -QString ProfileLocker::lockPathFromName(const QString& name) -{ +QString ProfileLocker::lockPathFromName(const QString& name) { return Settings::getInstance().getSettingsDirPath() + '/' + name + ".lock"; } @@ -42,11 +40,9 @@ QString ProfileLocker::lockPathFromName(const QString& name) * @param profile Profile name to check. * @return True, if profile locked, false otherwise. */ -bool ProfileLocker::isLockable(QString profile) -{ +bool ProfileLocker::isLockable(QString profile) { // If we already have the lock, it's definitely lockable - if (lockfile && curLockName == profile) - return true; + if (lockfile && curLockName == profile) return true; QLockFile newLock(lockPathFromName(profile)); return newLock.tryLock(); @@ -57,10 +53,8 @@ bool ProfileLocker::isLockable(QString profile) * @param profile Profile to lock. * @return Returns true if we already own the lock. */ -bool ProfileLocker::lock(QString profile) -{ - if (lockfile && curLockName == profile) - return true; +bool ProfileLocker::lock(QString profile) { + if (lockfile && curLockName == profile) return true; QLockFile* newLock = new QLockFile(lockPathFromName(profile)); newLock->setStaleLockTime(0); @@ -78,10 +72,8 @@ bool ProfileLocker::lock(QString profile) /** * @brief Releases the lock on the current profile. */ -void ProfileLocker::unlock() -{ - if (!lockfile) - return; +void ProfileLocker::unlock() { + if (!lockfile) return; lockfile->unlock(); lockfile.reset(); @@ -94,8 +86,7 @@ void ProfileLocker::unlock() * If we can't get a lock, exit qTox immediately. * If we never had a lock in the first place, exit immediately. */ -void ProfileLocker::assertLock() -{ +void ProfileLocker::assertLock() { if (!lockfile) { qCritical() << "assertLock: We don't seem to own any lock!"; deathByBrokenLock(); @@ -116,8 +107,7 @@ void ProfileLocker::assertLock() /** * @brief Print an error then exit immediately. */ -void ProfileLocker::deathByBrokenLock() -{ +void ProfileLocker::deathByBrokenLock() { qCritical() << "Lock is *BROKEN*, exiting immediately"; abort(); } @@ -126,17 +116,13 @@ void ProfileLocker::deathByBrokenLock() * @brief Chacks, that profile locked. * @return Returns true if we're currently holding a lock. */ -bool ProfileLocker::hasLock() -{ - return lockfile.operator bool(); -} +bool ProfileLocker::hasLock() { return lockfile.operator bool(); } /** * @brief Get current locked profile name. * @return Return the name of the currently loaded profile, a null string if there is none. */ -QString ProfileLocker::getCurLockName() -{ +QString ProfileLocker::getCurLockName() { if (lockfile) return curLockName; else diff --git a/src/profilelocker.h b/src/profilelocker.h index fe5d2305..dc053e5b 100644 --- a/src/profilelocker.h +++ b/src/profilelocker.h @@ -10,15 +10,13 @@ * See the Mulan PubL v2 for more details. */ - #ifndef PROFILELOCKER_H #define PROFILELOCKER_H #include #include -class ProfileLocker -{ +class ProfileLocker { private: ProfileLocker() = delete; @@ -39,4 +37,4 @@ class ProfileLocker static QString curLockName; }; -#endif // PROFILELOCKER_H +#endif // PROFILELOCKER_H