diff --git a/tests/imgs/led_absent.svg b/tests/imgs/led_absent.svg new file mode 100644 index 000000000..0cbbd5b8b --- /dev/null +++ b/tests/imgs/led_absent.svg @@ -0,0 +1,18 @@ + + + + led_inprogress + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/imgs/led_connected.svg b/tests/imgs/led_connected.svg new file mode 100644 index 000000000..5c13ec21b --- /dev/null +++ b/tests/imgs/led_connected.svg @@ -0,0 +1,18 @@ + + + + led_connected + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/imgs/led_disconnected.svg b/tests/imgs/led_disconnected.svg new file mode 100644 index 000000000..f9bae679f --- /dev/null +++ b/tests/imgs/led_disconnected.svg @@ -0,0 +1,18 @@ + + + + led_disconnected + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/imgs/led_do_not_disturb.svg b/tests/imgs/led_do_not_disturb.svg new file mode 100644 index 000000000..91a4459bc --- /dev/null +++ b/tests/imgs/led_do_not_disturb.svg @@ -0,0 +1,18 @@ + + + + led_error + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/imgs/valid.svg b/tests/imgs/valid.svg new file mode 100644 index 000000000..f06fd960f --- /dev/null +++ b/tests/imgs/valid.svg @@ -0,0 +1,17 @@ + + + + valid + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/languages/en.ts b/tests/languages/en.ts index a00601d8c..96cb25eeb 100644 --- a/tests/languages/en.ts +++ b/tests/languages/en.ts @@ -8,4 +8,59 @@ Search contact, start call, start chat... + + manage_accounts + + manageAccountsTitle + Presence and accounts + + + manageAccountsDescription + Select your active account and choose all necessary presence status. + + + awayPresence + Away + + + beRightBackPresence + Be right back + + + busyPresence + Busy + + + doNotDisturbPresence + Away + + + movedPresence + Moved + + + offlinePresence + Disconnected + + + onThePhonePresence + On the phone + + + onlinePresence + Connected + + + outToLunchPresence + Out to lunch + + + usingAnotherMessagingServicePresence + Using another messaging service + + + validate + VALIDATE + + diff --git a/tests/languages/fr.ts b/tests/languages/fr.ts index 5036bc10a..88b9c797d 100644 --- a/tests/languages/fr.ts +++ b/tests/languages/fr.ts @@ -8,4 +8,59 @@ Chercher contact, commencer appel ou chat... + + manage_accounts + + manageAccountsTitle + Présence et comptes + + + manageAccountsDescription + Sélectionner votre compte actif ainsi que vos status de présence. + + + awayPresence + Absent + + + beRightBackPresence + De retour + + + busyPresence + Occupé + + + doNotDisturbPresence + Ne pas déranger + + + movedPresence + Parti + + + offlinePresence + Déconnecté + + + onThePhonePresence + Au téléphone + + + onlinePresence + Disponible + + + outToLunchPresence + A table + + + usingAnotherMessagingServicePresence + Utilisation d'un autre service de messagerie + + + validate + VALIDER + + diff --git a/tests/linphone.pro b/tests/linphone.pro index 1a413f72e..68f5e30dc 100644 --- a/tests/linphone.pro +++ b/tests/linphone.pro @@ -6,11 +6,13 @@ TEMPLATE = app SOURCES = \ src/app.cpp \ src/main.cpp \ - src/views/main_window.cpp + src/models/settings/AccountSettingsModel.cpp \ + src/models/settings/SettingsModel.cpp HEADERS = \ src/app.hpp \ - src/views/main_window.hpp + src/models/settings/AccountSettingsModel.hpp \ + src/models/settings/SettingsModel.hpp TRANSLATIONS = \ languages/en.ts \ @@ -19,7 +21,7 @@ TRANSLATIONS = \ lupdate_only{ # Each component folder must be added explicitly. SOURCES = \ - ui/components/Form/*.qml \ + ui/components/form/*.qml \ ui/views/*.qml } diff --git a/tests/resources.qrc b/tests/resources.qrc index dbbd8d67d..9348ccd14 100644 --- a/tests/resources.qrc +++ b/tests/resources.qrc @@ -5,13 +5,21 @@ languages/fr.qm - ui/components/Form/Collapse.qml - ui/components/Form/RoundButton.qml - ui/components/Form/ToolBarButton.qml + ui/components/form/Collapse.qml + ui/components/form/DialogButton.qml + ui/components/form/DialogComboBox.qml + ui/components/form/RoundButton.qml + ui/components/form/ToolBarButton.qml ui/views/main_window.qml + ui/views/manage_accounts.qml imgs/collapse.svg + imgs/led_absent.svg + imgs/led_connected.svg + imgs/led_disconnected.svg + imgs/led_do_not_disturb.svg imgs/start_conference.svg + imgs/valid.svg diff --git a/tests/src/app.cpp b/tests/src/app.cpp index 275c45ff0..e05a0ab99 100644 --- a/tests/src/app.cpp +++ b/tests/src/app.cpp @@ -4,7 +4,6 @@ #include "app.hpp" -#define APPLICATION_NAME "Linphone" #define LANGUAGES_PATH ":/languages/" // =================================================================== @@ -17,7 +16,4 @@ App::App(int &argc, char **argv) : QGuiApplication(argc, argv) { } else { qWarning() << "No translation found."; } - - // Set application name. - QCoreApplication::setApplicationName(APPLICATION_NAME); } diff --git a/tests/src/models/settings/AccountSettingsListModel.cpp b/tests/src/models/settings/AccountSettingsListModel.cpp new file mode 100644 index 000000000..182d2cfab --- /dev/null +++ b/tests/src/models/settings/AccountSettingsListModel.cpp @@ -0,0 +1,16 @@ +#include "AccountSettingsListModel.hpp" + +// =================================================================== + +AccountSettingsListModel::AccountSettingsListModel (QObject *parent) : + QObject(parent) { +} + +int AccountSettingsListModel::getDefaultAccount () const { + return 1; +} + +void AccountSettingsListModel::setDefaultAccount (int index) { + // NOTHING TODO. + (void)index; +} diff --git a/tests/src/models/settings/AccountSettingsListModel.hpp b/tests/src/models/settings/AccountSettingsListModel.hpp new file mode 100644 index 000000000..9532b9e7c --- /dev/null +++ b/tests/src/models/settings/AccountSettingsListModel.hpp @@ -0,0 +1,23 @@ +#ifndef ACCOUNT_SETTINGS_LIST_MODEL_H_ +#define ACCOUNT_SETTINGS_LIST_MODEL_H_ + +#include + +// =================================================================== + +class AccountSettingsListModel : public QObject { + Q_OBJECT; + + Q_PROPERTY(int index + READ getDefaultAccount + WRITE setDefaultAccount); + +public: + AccountSettingsListModel (QObject *parent = Q_NULLPTR); + +private: + int getDefaultAccount () const; + void setDefaultAccount (int index); +}; + +#endif diff --git a/tests/src/models/settings/AccountSettingsModel.cpp b/tests/src/models/settings/AccountSettingsModel.cpp new file mode 100644 index 000000000..545321b44 --- /dev/null +++ b/tests/src/models/settings/AccountSettingsModel.cpp @@ -0,0 +1,28 @@ +#include "AccountSettingsModel.hpp" + +typedef AccountSettingsModel::Presence Presence; + +// =================================================================== + +AccountSettingsModel::AccountSettingsModel (QObject *parent) : + QObject(parent) { +} + +QString AccountSettingsModel::getUsername () const { + return "Toto"; +} + +void AccountSettingsModel::setUsername (const QString &username) { + // NOTHING TODO. + (void)username; +} + + +Presence AccountSettingsModel::getPresence () const { + return Presence::Away; +} + +void AccountSettingsModel::setPresence (Presence presence) { + // NOTHING TODO. + (void)presence; +} diff --git a/tests/src/models/settings/AccountSettingsModel.hpp b/tests/src/models/settings/AccountSettingsModel.hpp new file mode 100644 index 000000000..20804d42a --- /dev/null +++ b/tests/src/models/settings/AccountSettingsModel.hpp @@ -0,0 +1,45 @@ +#ifndef ACCOUNT_SETTINGS_MODEL_H_ +#define ACCOUNT_SETTINGS_MODEL_H_ + +#include + +// =================================================================== + +class AccountSettingsModel : public QObject { + Q_OBJECT; + + Q_PROPERTY(QString username + READ getUsername + WRITE setUsername); + + Q_PROPERTY(Presence presence + READ getPresence + WRITE setPresence); + +public: + // See: https://tools.ietf.org/html/rfc4480#section-3.2 + // Activities, section 3.2 of RFC 4480 + enum Presence { + Away, + BeRightBack, + Busy, + DoNotDisturb, + Moved, + Offline, + OnThePhone, + Online, + OutToLunch, + UsingAnotherMessagingService + }; + + AccountSettingsModel (QObject *parent = Q_NULLPTR); + +private: + QString getUsername () const; + void setUsername (const QString &username); + + Presence getPresence () const; + void setPresence (Presence presence); +}; + +#endif // ACCOUNT_SETTINGS_MODEL_H_ diff --git a/tests/src/models/settings/SettingsModel.cpp b/tests/src/models/settings/SettingsModel.cpp new file mode 100644 index 000000000..4552d7b28 --- /dev/null +++ b/tests/src/models/settings/SettingsModel.cpp @@ -0,0 +1,7 @@ +#include "SettingsModel.hpp" + +// =================================================================== + +SettingsModel::SettingsModel (QObject *parent) : + QObject(parent) { +} diff --git a/tests/src/models/settings/SettingsModel.hpp b/tests/src/models/settings/SettingsModel.hpp new file mode 100644 index 000000000..fbb9f722a --- /dev/null +++ b/tests/src/models/settings/SettingsModel.hpp @@ -0,0 +1,20 @@ +#ifndef SETTINGS_MODEL_H_ +#define SETTINGS_MODEL_H_ + +#include + +#include "AccountSettingsModel.hpp" + +// =================================================================== + +class SettingsModel : public QObject { + Q_OBJECT; + +public: + SettingsModel (QObject *parent = Q_NULLPTR); + +private: + QList accountsSettings; +}; + +#endif // SETTINGS_MODEL_H_ diff --git a/tests/src/views/main_window.cpp b/tests/src/views/main_window.cpp deleted file mode 100644 index 18f6aa6e5..000000000 --- a/tests/src/views/main_window.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "main_window.hpp" diff --git a/tests/src/views/main_window.hpp b/tests/src/views/main_window.hpp deleted file mode 100644 index cdbae4e47..000000000 --- a/tests/src/views/main_window.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef MAIN_WINDOW_H_ -#define MAIN_WINDOW_H_ - -class MainWindow { - // TODO. -}; - -#endif // MAIN_WINDOW_ diff --git a/tests/ui/components/Form/Collapse.qml b/tests/ui/components/form/Collapse.qml similarity index 100% rename from tests/ui/components/Form/Collapse.qml rename to tests/ui/components/form/Collapse.qml diff --git a/tests/ui/components/form/DialogButton.qml b/tests/ui/components/form/DialogButton.qml new file mode 100644 index 000000000..945fe4e85 --- /dev/null +++ b/tests/ui/components/form/DialogButton.qml @@ -0,0 +1,18 @@ +import QtQuick 2.7 +import QtQuick.Controls 2.0 + +Button { + background: Rectangle { + color: button.down ? '#FE5E00' : '#434343' + implicitWidth: 120 + implicitHeight: 30 + radius: 4 + } + contentItem: Text { + color: '#FFFFFF' + text: button.text + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + id: button +} diff --git a/tests/ui/components/form/DialogComboBox.qml b/tests/ui/components/form/DialogComboBox.qml new file mode 100644 index 000000000..4094ffa06 --- /dev/null +++ b/tests/ui/components/form/DialogComboBox.qml @@ -0,0 +1,9 @@ +import QtQuick 2.7 +import QtQuick.Controls 2.0 + +ComboBox { + background: Rectangle { + color: 'transparent' + } + id: comboBox +} diff --git a/tests/ui/components/Form/RoundButton.qml b/tests/ui/components/form/RoundButton.qml similarity index 81% rename from tests/ui/components/Form/RoundButton.qml rename to tests/ui/components/form/RoundButton.qml index 47db8b234..b42d3909d 100644 --- a/tests/ui/components/Form/RoundButton.qml +++ b/tests/ui/components/form/RoundButton.qml @@ -7,5 +7,6 @@ Button { Image { anchors.fill: parent id: backgroundImage + fillMode: Image.PreserveAspectFit } } diff --git a/tests/ui/components/Form/ToolBarButton.qml b/tests/ui/components/form/ToolBarButton.qml similarity index 100% rename from tests/ui/components/Form/ToolBarButton.qml rename to tests/ui/components/form/ToolBarButton.qml diff --git a/tests/ui/views/main_window.qml b/tests/ui/views/main_window.qml index 176bf68ce..e00852b4f 100644 --- a/tests/ui/views/main_window.qml +++ b/tests/ui/views/main_window.qml @@ -1,8 +1,8 @@ -import QtQuick 2.5 +import QtQuick 2.7 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.3 -import 'qrc:/ui/components/Form' +import 'qrc:/ui/components/form' ApplicationWindow { header: ToolBar { @@ -17,7 +17,7 @@ ApplicationWindow { // Collapse. Collapse { - image: '/imgs/collapse.svg' + image: 'qrc:/imgs/collapse.svg' onCollapsed: { mainWindow.height = collapsed ? 480 : 70 } @@ -26,6 +26,15 @@ ApplicationWindow { // User info. // TODO + // User actions. + ToolBarButton { + onClicked: { + var component = Qt.createComponent("qrc:/ui/views/manage_accounts.qml"); + var win = component.createObject(mainWindow); + win.show(); + } + } + // Search. TextField { signal searchTextChanged (string text) @@ -42,12 +51,13 @@ ApplicationWindow { // Start conference. ToolBarButton { - image: '/imgs/start_conference.svg' + image: 'qrc:/imgs/start_conference.svg' } } } id: mainWindow minimumHeight: 70 minimumWidth: 640 + title: 'Linphone' visible: true } diff --git a/tests/ui/views/manage_accounts.qml b/tests/ui/views/manage_accounts.qml new file mode 100644 index 000000000..c19bbacff --- /dev/null +++ b/tests/ui/views/manage_accounts.qml @@ -0,0 +1,195 @@ +import QtQuick 2.7 +import QtQuick.Controls 2.0 +import QtQuick.Layouts 1.3 +import QtQuick.Window 2.2 + +import 'qrc:/ui/components/form' + +Window { + id: window + minimumHeight: 328 + minimumWidth: 480 + modality: Qt.WindowModal + title: qsTr('manageAccountsTitle') + + ColumnLayout { + anchors.fill: parent + spacing: 0 + + // Window description. + Item { + Layout.alignment : Qt.AlignTop + Layout.fillWidth: true + height: 90 + + Text { + anchors.fill: parent + anchors.leftMargin: 50 + anchors.rightMargin: 50 + font.pointSize: 12 + text: qsTr('manageAccountsDescription') + verticalAlignment: Text.AlignVCenter + wrapMode: Text.WordWrap + } + } + + // Accounts list. + Item { + Layout.alignment: Qt.AlignTop + Layout.fillHeight: true + Layout.fillWidth: true + id: listViewContainer + + ListView { + anchors.fill: parent + boundsBehavior: Flickable.StopAtBounds + clip: true + highlightRangeMode: ListView.ApplyRange + id: accountsList + spacing: 0 + horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOn + // TODO: Remove, use C++ model instead. + model: ListModel { + ListElement { + presence: 'connected' + sipAddress: 'jim.williams.zzzz.yyyy.kkkk.sip.linphone.org' + isDefault: false + } + ListElement { + presence: 'connected' + sipAddress: 'toto.lala.sip.linphone.org' + isDefault: false + } + ListElement { + presence: 'disconnected' + sipAddress: 'machin.truc.sip.linphone.org' + isDefault: true + } + ListElement { + presence: 'absent' + sipAddress: 'hey.listen.sip.linphone.org' + isDefault: false + } + ListElement { + presence: 'do_not_disturb' + sipAddress: 'valentin.cognito.sip.linphone.org' + isDefault: false + } + ListElement { + presence: 'do_not_disturb' + sipAddress: 'charles.henri.sip.linphone.org' + isDefault: false + } + ListElement { + presence: 'disconnected' + sipAddress: 'yesyes.nono.sip.linphone.org' + isDefault: false + } + ListElement { + presence: 'connected' + sipAddress: 'nsa.sip.linphone.org' + isDefault: false + } + } + delegate: Item { + height: 34 + width: parent.width + + Rectangle { + anchors.fill: parent + color: isDefault ? '#EAEAEA' : 'transparent' + id: accountLine + + RowLayout { + anchors.fill: parent + spacing: 15 + anchors.leftMargin: 15 + anchors.rightMargin: 15 + + // Default account. + Item { + Layout.fillHeight: parent.height + Layout.preferredWidth: 20 + + Image { + anchors.fill: parent + fillMode: Image.PreserveAspectFit + source: isDefault ? 'qrc:/imgs/valid.svg' : '' + } + } + + // Sip account. + Item { + Layout.fillHeight: parent.height + Layout.fillWidth: true + + Text { + anchors.fill: parent + clip: true + color: '#59575A' + text: sipAddress; + verticalAlignment: Text.AlignVCenter + + MouseArea { + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + } + } + } + + // Presence. + Item { + Layout.fillHeight: parent.height + Layout.preferredWidth: 20 + + Image { + anchors.fill: parent + fillMode: Image.PreserveAspectFit + source: 'qrc:/imgs/led_' + presence + '.svg' + } + } + + // Update presence. + Item { + Layout.fillHeight: parent.height + Layout.preferredWidth: 160 + + DialogComboBox { + anchors.fill: parent + model: ListModel { + ListElement { key: qsTr('onlinePresence'); value: 1 } + ListElement { key: qsTr('busyPresence'); value: 2 } + ListElement { key: qsTr('beRightBackPresence'); value: 3 } + ListElement { key: qsTr('awayPresence'); value: 4 } + ListElement { key: qsTr('onThePhonePresence'); value: 5 } + ListElement { key: qsTr('outToLunchPresence'); value: 6 } + ListElement { key: qsTr('doNotDisturbPresence'); value: 7 } + ListElement { key: qsTr('movedPresence'); value: 8 } + ListElement { key: qsTr('usingAnotherMessagingServicePresence'); value: 9 } + ListElement { key: qsTr('offlinePresence'); value: 10 } + } + textRole: 'key' + } + } + } + } + } + } + } + + // Validate + Rectangle { + Layout.alignment: Qt.AlignTop + Layout.fillWidth: true + height: 100 + + DialogButton { + anchors.bottom: parent.bottom + anchors.bottomMargin: 30 + anchors.left: parent.left + anchors.leftMargin: 54 + text: qsTr('validate') + } + } + } +}