diff --git a/assets/languages/en.ts b/assets/languages/en.ts index 0103776dc..c9eff363d 100644 --- a/assets/languages/en.ts +++ b/assets/languages/en.ts @@ -997,6 +997,10 @@ your friend's SIP address or username. cleanLogs CLEAN LOGS + + cleanLogsDescription + Are you sure you want to remove all logs? + SettingsAudio diff --git a/assets/languages/fr.ts b/assets/languages/fr.ts index 510a938c9..b45e46870 100644 --- a/assets/languages/fr.ts +++ b/assets/languages/fr.ts @@ -985,7 +985,7 @@ Cliquez ici : <a href="%1">%1</a> logsUploadFailed - L'envoi des logs a échoué.> + L'envoi des logs a échoué. logsEnabledLabel @@ -995,6 +995,10 @@ Cliquez ici : <a href="%1">%1</a> cleanLogs SUPPRIMER LOGS + + cleanLogsDescription + Voulez-vous vraiment supprimer tous les logs ? + SettingsAudio diff --git a/resources.qrc b/resources.qrc index 022fcb318..b2cc787bd 100644 --- a/resources.qrc +++ b/resources.qrc @@ -296,6 +296,8 @@ ui/modules/Common/Window/VirtualWindow.qml ui/modules/Common/Window/Window.js ui/modules/Common/Window/Window.qml + ui/modules/Konami/Konami.qml + ui/modules/Konami/qmldir ui/modules/Linphone/Account/AccountStatus.qml ui/modules/Linphone/Blocks/CardBlock.qml ui/modules/Linphone/Blocks/RequestBlock.qml @@ -403,6 +405,7 @@ ui/views/App/Main/MainWindow.js ui/views/App/Main/MainWindowMenuBar.qml ui/views/App/Main/MainWindow.qml + ui/views/App/Settings/SettingsAdvanced.js ui/views/App/Settings/SettingsAdvanced.qml ui/views/App/Settings/SettingsAudio.qml ui/views/App/Settings/SettingsCallsChat.qml @@ -441,6 +444,7 @@ ui/views/App/Styles/Main/InviteFriendsStyle.qml ui/views/App/Styles/Main/MainWindowStyle.qml ui/views/App/Styles/qmldir + ui/views/App/Styles/Settings/SettingsAdvancedStyle.qml ui/views/App/Styles/Settings/SettingsAudioStyle.qml ui/views/App/Styles/Settings/SettingsSipAccountsEditStyle.qml ui/views/App/Styles/Settings/SettingsVideoPreviewStyle.qml diff --git a/src/app/App.cpp b/src/app/App.cpp index 7b9c07afe..8c1756530 100644 --- a/src/app/App.cpp +++ b/src/app/App.cpp @@ -86,7 +86,7 @@ App::App (int &argc, char *argv[]) : SingleApplication(argc, argv, true, Mode::U // Initialize logger. shared_ptr config = ::getConfigIfExists(*mParser); - Logger::init(SettingsModel::getLogsFolder(config), SettingsModel::getLogsEnabled(config)); + Logger::init(config); if (mParser->isSet("verbose")) Logger::getInstance()->setVerbose(true); diff --git a/src/app/logger/Logger.cpp b/src/app/logger/Logger.cpp index 979e44086..98e41b2ac 100644 --- a/src/app/logger/Logger.cpp +++ b/src/app/logger/Logger.cpp @@ -25,6 +25,7 @@ #include #include +#include "../../components/settings/SettingsModel.hpp" #include "../../utils/Utils.hpp" #include "../paths/Paths.hpp" @@ -159,11 +160,13 @@ void Logger::enable (bool status) { linphone_core_enable_log_collection(status ? LinphoneLogCollectionEnabled : LinphoneLogCollectionDisabled); } -void Logger::init (const QString &folder, bool enabled) { - Q_ASSERT(!folder.isEmpty()); - +void Logger::init (const std::shared_ptr &config) { if (mInstance) return; + + const QString folder = SettingsModel::getLogsFolder(config); + Q_ASSERT(!folder.isEmpty()); + mInstance = new Logger(); qInstallMessageHandler(Logger::log); @@ -177,5 +180,5 @@ void Logger::init (const QString &folder, bool enabled) { linphone_core_set_log_collection_path(::Utils::appStringToCoreString(folder).c_str()); linphone_core_set_log_collection_max_file_size(MAX_LOGS_COLLECTION_SIZE); - mInstance->enable(enabled); + mInstance->enable(SettingsModel::getLogsEnabled(config)); } diff --git a/src/app/logger/Logger.hpp b/src/app/logger/Logger.hpp index f676c9f93..2a7bb5090 100644 --- a/src/app/logger/Logger.hpp +++ b/src/app/logger/Logger.hpp @@ -23,6 +23,7 @@ #ifndef LOGGER_H_ #define LOGGER_H_ +#include #include // ============================================================================= @@ -41,7 +42,7 @@ public: void enable (bool status); - static void init (const QString &folder, bool enabled); + static void init (const std::shared_ptr &config); static Logger *getInstance () { return mInstance; diff --git a/src/components/core/CoreHandlers.cpp b/src/components/core/CoreHandlers.cpp index dd2c3cdea..d866417a7 100644 --- a/src/components/core/CoreHandlers.cpp +++ b/src/components/core/CoreHandlers.cpp @@ -69,11 +69,10 @@ void CoreHandlers::handleCoreCreated () { void CoreHandlers::notifyCoreStarted () { if (mCoreCreated && mCoreStarted) - scheduleFunctionInApp( - [this]() { - qInfo() << QStringLiteral("Core started."); - emit coreStarted(); - }); + scheduleFunctionInApp([this] { + qInfo() << QStringLiteral("Core started."); + emit coreStarted(); + }); } // ----------------------------------------------------------------------------- @@ -125,9 +124,9 @@ void CoreHandlers::onGlobalStateChanged ( void CoreHandlers::onLogCollectionUploadStateChanged ( const shared_ptr &, linphone::CoreLogCollectionUploadState state, - const string & + const string &info ) { - emit logsUploadStateChanged(state); + emit logsUploadStateChanged(state, info); } void CoreHandlers::onLogCollectionUploadProgressIndication ( diff --git a/src/components/core/CoreHandlers.hpp b/src/components/core/CoreHandlers.hpp index 59587cfc2..5011cb8db 100644 --- a/src/components/core/CoreHandlers.hpp +++ b/src/components/core/CoreHandlers.hpp @@ -46,7 +46,7 @@ signals: void callTransferFailed (const std::shared_ptr &call); void callTransferSucceeded (const std::shared_ptr &call); void coreStarted (); - void logsUploadStateChanged (linphone::CoreLogCollectionUploadState state); + void logsUploadStateChanged (linphone::CoreLogCollectionUploadState state, const std::string &info); void messageReceived (const std::shared_ptr &message); void presenceReceived (const QString &sipAddress, const std::shared_ptr &presenceModel); void registrationStateChanged (const std::shared_ptr &proxyConfig, linphone::RegistrationState state); diff --git a/src/components/core/CoreManager.cpp b/src/components/core/CoreManager.cpp index 02f9348c2..540e243d2 100644 --- a/src/components/core/CoreManager.cpp +++ b/src/components/core/CoreManager.cpp @@ -107,6 +107,8 @@ void CoreManager::forceRefreshRegisters () { mCore->refreshRegisters(); } +// ----------------------------------------------------------------------------- + void CoreManager::sendLogs () const { Q_CHECK_PTR(mCore); @@ -115,6 +117,12 @@ void CoreManager::sendLogs () const { mCore->uploadLogCollection(); } +void CoreManager::cleanLogs () const { + Q_CHECK_PTR(mCore); + + mCore->resetLogCollection(); +} + // ----------------------------------------------------------------------------- #define SET_DATABASE_PATH(DATABASE, PATH) \ @@ -198,15 +206,14 @@ void CoreManager::iterate () { // ----------------------------------------------------------------------------- -void CoreManager::handleLogsUploadStateChanged (linphone::CoreLogCollectionUploadState state) { +void CoreManager::handleLogsUploadStateChanged (linphone::CoreLogCollectionUploadState state, const string &info) { switch (state) { case linphone::CoreLogCollectionUploadStateInProgress: break; + case linphone::CoreLogCollectionUploadStateDelivered: - emit logsUploaded(true); - break; case linphone::CoreLogCollectionUploadStateNotDelivered: - emit logsUploaded(false); + emit logsUploaded(::Utils::coreStringToAppString(info)); break; } } diff --git a/src/components/core/CoreManager.hpp b/src/components/core/CoreManager.hpp index 9116f807e..8672f7bac 100644 --- a/src/components/core/CoreManager.hpp +++ b/src/components/core/CoreManager.hpp @@ -120,12 +120,13 @@ public: Q_INVOKABLE void forceRefreshRegisters (); Q_INVOKABLE void sendLogs () const; + Q_INVOKABLE void cleanLogs () const; signals: void coreCreated (); void coreStarted (); - void logsUploaded (bool success); + void logsUploaded (const QString &url); private: CoreManager (QObject *parent, const QString &configPath); @@ -140,7 +141,7 @@ private: void iterate (); - void handleLogsUploadStateChanged (linphone::CoreLogCollectionUploadState state); + void handleLogsUploadStateChanged (linphone::CoreLogCollectionUploadState state, const std::string &info); static QString getDownloadUrl (); diff --git a/src/components/other/colors/Colors.cpp b/src/components/other/colors/Colors.cpp index 23e15dbce..4c2d457e7 100644 --- a/src/components/other/colors/Colors.cpp +++ b/src/components/other/colors/Colors.cpp @@ -20,7 +20,6 @@ * Author: Ronan Abhamon */ -#include #include #include "../../../utils/Utils.hpp" @@ -29,10 +28,6 @@ #define COLORS_SECTION "ui_colors" -#ifndef LINPHONE_FRIDAY -#define LINPHONE_FRIDAY 1 -#endif // ifndef LINPHONE_FRIDAY - #if LINPHONE_FRIDAY #include #endif // if LINPHONE_FRIDAY @@ -43,24 +38,29 @@ using namespace std; #if LINPHONE_FRIDAY - static void setLinphoneFridayColors (Colors &colors) { - colors.setProperty("i", QColor("#F48D8D")); - colors.setProperty("s", QColor("#F58585")); - colors.setProperty("t", QColor("#FFC5C5")); + inline bool isLinphoneFriday () { + return QDate::currentDate().dayOfWeek() == 5; } #endif // if LINPHONE_FRIDAY Colors::Colors (QObject *parent) : QObject(parent) { #if LINPHONE_FRIDAY - if (QDate::currentDate().dayOfWeek() == 5) - ::setLinphoneFridayColors(*this); - + if (isLinphoneFriday()) { + setProperty("i", QColor("#F48D8D")); + setProperty("s", QColor("#F58585")); + setProperty("t", QColor("#FFC5C5")); + } #endif // if LINPHONE_FRIDAY } void Colors::useConfig (const std::shared_ptr &config) { - overrideColors(config); + #if LINPHONE_FRIDAY + if (!isLinphoneFriday()) + overrideColors(config); + #else + overrideColors(config); + #endif // if LINPHONE_FRIDAY } // ----------------------------------------------------------------------------- diff --git a/src/components/other/colors/Colors.hpp b/src/components/other/colors/Colors.hpp index e2aadc138..761d10696 100644 --- a/src/components/other/colors/Colors.hpp +++ b/src/components/other/colors/Colors.hpp @@ -23,6 +23,7 @@ #ifndef COLORS_H_ #define COLORS_H_ +#include #include #include @@ -48,7 +49,7 @@ // ----------------------------------------------------------------------------- namespace linphone { - class Config; +class Config; } class Colors : public QObject { diff --git a/ui/modules/Konami/Konami.qml b/ui/modules/Konami/Konami.qml new file mode 100644 index 000000000..b90fa7241 --- /dev/null +++ b/ui/modules/Konami/Konami.qml @@ -0,0 +1,92 @@ +/* + * Konami.qml + * Copyright 2017 Ronan Abhamon (https://github.com/Wescoeur) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +import QtQuick 2.7 + +// ============================================================================= + +Item { + id: konami + + property var code: [ + Qt.Key_Up, + Qt.Key_Up, + Qt.Key_Down, + Qt.Key_Down, + Qt.Key_Left, + Qt.Key_Right, + Qt.Key_Left, + Qt.Key_Right, + Qt.Key_B, + Qt.Key_A + ] + + property int delay: 2000 + + signal triggered + + // --------------------------------------------------------------------------- + + Keys.forwardTo: core + + Timer { + id: timer + + interval: konami.delay + + onTriggered: core.index = 0 + } + + Item { + id: core + + property int index: 0 + + anchors.fill: parent + + Keys.onPressed: { + timer.stop() + + var code = konami.code + if (event.key === code[index]) { + // 1. Code OK. + if (++index === code.length) { + index = 0 + + konami.triggered() + return + } + + // 2. Actual key OK. + if (delay > 0) { + timer.start() + } + + return + } + + // 3. Wrong key. + index = 0 + } + } +} diff --git a/ui/modules/Konami/qmldir b/ui/modules/Konami/qmldir new file mode 100644 index 000000000..09952a541 --- /dev/null +++ b/ui/modules/Konami/qmldir @@ -0,0 +1,5 @@ +module Konami + +// ============================================================================= + +Konami 1.0 Konami.qml diff --git a/ui/views/App/Main/Dialogs/About.qml b/ui/views/App/Main/Dialogs/About.qml index 38b594203..c6ee71ed9 100644 --- a/ui/views/App/Main/Dialogs/About.qml +++ b/ui/views/App/Main/Dialogs/About.qml @@ -2,6 +2,7 @@ import QtQuick 2.7 import QtQuick.Layouts 1.3 import Common 1.0 +import Konami 1.0 import Linphone 1.0 import App.Styles 1.0 @@ -40,6 +41,16 @@ DialogPlus { Icon { icon: 'linphone_logo' iconSize: parent.height + + Konami { + anchors.fill: parent + onTriggered: console.log('TODO') + + MouseArea { + anchors.fill: parent + onClicked: parent.focus = true + } + } } Column { diff --git a/ui/views/App/Settings/SettingsAdvanced.js b/ui/views/App/Settings/SettingsAdvanced.js new file mode 100644 index 000000000..0e27312dd --- /dev/null +++ b/ui/views/App/Settings/SettingsAdvanced.js @@ -0,0 +1,31 @@ +// ============================================================================= +// `SettingsAdvanced.qml` Logic. +// ============================================================================= + +.import Linphone 1.0 as Linphone + +.import 'qrc:/ui/scripts/Utils/utils.js' as Utils + +// ============================================================================= + +function cleanLogs () { + window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), { + descriptionText: qsTr('cleanLogsDescription'), + }, function (status) { + if (status) { + Linphone.CoreManager.cleanLogs() + } + }) +} + +function handleLogsUploaded (url) { + if (url.length) { + sendLogsBlock.stop('') + Qt.openUrlExternally( + 'mailto:?subject=' + encodeURIComponent('Desktop Linphone Log') + + '&body=' + encodeURIComponent(url) + ) + } else { + sendLogsBlock.stop(qsTr('logsUploadFailed')) + } +} diff --git a/ui/views/App/Settings/SettingsAdvanced.qml b/ui/views/App/Settings/SettingsAdvanced.qml index 2831bbd9e..da7c31b06 100644 --- a/ui/views/App/Settings/SettingsAdvanced.qml +++ b/ui/views/App/Settings/SettingsAdvanced.qml @@ -5,6 +5,8 @@ import Linphone 1.0 import App.Styles 1.0 +import 'SettingsAdvanced.js' as Logic + // ============================================================================= TabContainer { @@ -63,12 +65,12 @@ TabContainer { Row { anchors.right: parent.right - spacing: 5 + spacing: SettingsAdvancedStyle.buttons.spacing TextButtonB { text: qsTr('cleanLogs') - onClicked: CoreManager.cleanLogs() + onClicked: Logic.cleanLogs() } TextButtonB { @@ -88,7 +90,7 @@ TabContainer { Connections { target: CoreManager - onLogsUploaded: sendLogsBlock.stop(success ? '' : qsTr('logsUploadFailed')) + onLogsUploaded: Logic.handleLogsUploaded(url) } } diff --git a/ui/views/App/Styles/Settings/SettingsAdvancedStyle.qml b/ui/views/App/Styles/Settings/SettingsAdvancedStyle.qml new file mode 100644 index 000000000..357fd0bbc --- /dev/null +++ b/ui/views/App/Styles/Settings/SettingsAdvancedStyle.qml @@ -0,0 +1,10 @@ +pragma Singleton +import QtQml 2.2 + +// ============================================================================= + +QtObject { + property QtObject buttons: QtObject { + property int spacing: 10 + } +} diff --git a/ui/views/App/Styles/qmldir b/ui/views/App/Styles/qmldir index 986011f59..5f66e91fa 100644 --- a/ui/views/App/Styles/qmldir +++ b/ui/views/App/Styles/qmldir @@ -31,6 +31,7 @@ singleton AboutStyle 1.0 Main/Dialogs/AboutS singleton AuthenticationRequestStyle 1.0 Main/Dialogs/AuthenticationRequestStyle.qml singleton ManageAccountsStyle 1.0 Main/Dialogs/ManageAccountsStyle.qml +singleton SettingsAdvancedStyle 1.0 Settings/SettingsAdvancedStyle.qml singleton SettingsAudioStyle 1.0 Settings/SettingsAudioStyle.qml singleton SettingsSipAccountsEditStyle 1.0 Settings/SettingsSipAccountsEditStyle.qml singleton SettingsVideoPreviewStyle 1.0 Settings/SettingsVideoPreviewStyle.qml