From a9a78cb4bfd6732ebd9e78c56c07ac6ddd704085 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20J=C3=B6rgensen?= Date: Mon, 22 Sep 2025 10:58:55 +0200 Subject: [PATCH] Accessibility and code improvments: * Normalize and correct linphone color * Add border when user focus using keyboard navigation * Correct some keyboard navigation * Add accessibility screen reading to interactive elements except chat and meeting --- Linphone/core/App.cpp | 8 + Linphone/core/account/AccountCore.cpp | 13 +- Linphone/core/notifier/Notifier.cpp | 10 + Linphone/data/languages/de.ts | 1208 +++++++++++----- Linphone/data/languages/en.ts | 1215 ++++++++++++----- Linphone/data/languages/fr_FR.ts | 1208 +++++++++++----- Linphone/tool/CMakeLists.txt | 3 + Linphone/tool/Utils.cpp | 6 +- .../accessibility/AccessibilityHelper.cpp | 36 + .../accessibility/AccessibilityHelper.hpp | 41 + Linphone/tool/accessibility/FocusHelper.cpp | 54 + Linphone/tool/accessibility/FocusHelper.hpp | 66 + Linphone/view/CMakeLists.txt | 4 +- Linphone/view/Control/Button/Button.qml | 78 +- .../view/Control/Button/CheckableButton.qml | 16 +- Linphone/view/Control/Button/ComboBox.qml | 487 +++---- .../Button/CountryIndicatorCombobox.qml | 11 +- .../Control/Button/HelpIconLabelButton.qml | 2 +- Linphone/view/Control/Button/IconButton.qml | 2 +- Linphone/view/Control/Button/LabelButton.qml | 1 + Linphone/view/Control/Button/PopupButton.qml | 165 ++- .../Control/Button/Settings/ComboSetting.qml | 2 +- .../Control/Button/Settings/SwitchSetting.qml | 3 + Linphone/view/Control/Button/Slider.qml | 28 +- Linphone/view/Control/Button/Switch.qml | 93 +- .../Container/Contact/PresenceNoteLayout.qml | 2 +- .../Control/Container/CreationFormLayout.qml | 31 +- .../view/Control/Container/FormItemLayout.qml | 3 +- .../Container/GroupCreationFormLayout.qml | 30 +- Linphone/view/Control/Container/TabBar.qml | 24 +- .../view/Control/Container/VerticalTabBar.qml | 54 +- .../Display/Call/CallHistoryListView.qml | 34 +- .../Control/Display/Call/CallListView.qml | 19 +- .../Control/Display/Chat/ChatListView.qml | 4 +- .../view/Control/Display/Chat/ChatMessage.qml | 12 +- .../Chat/ChatMessageInvitationBubble.qml | 12 +- Linphone/view/Control/Display/Chat/Event.qml | 4 +- .../view/Control/Display/Chat/FileView.qml | 2 +- .../view/Control/Display/Contact/Avatar.qml | 2 +- .../view/Control/Display/Contact/Contact.qml | 213 ++- .../Display/Contact/ContactListItem.qml | 7 +- .../Display/Contact/ContactListView.qml | 13 +- .../Display/Contact/ContactStatusPopup.qml | 98 ++ .../view/Control/Display/Contact/Presence.qml | 51 +- .../Contact/PresenceSetCustomStatus.qml | 2 +- .../Display/Contact/PresenceStatusItem.qml | 59 +- .../Control/Display/Contact/Voicemail.qml | 4 +- Linphone/view/Control/Display/EffectImage.qml | 4 +- .../view/Control/Display/HorizontalBar.qml | 11 + .../view/Control/Display/MediaProgressBar.qml | 2 +- .../Display/Meeting/MeetingListView.qml | 6 +- .../Display/Settings/SettingsMenuItem.qml | 41 +- Linphone/view/Control/Display/Sticker.qml | 2 +- .../view/Control/Display/TemporaryText.qml | 2 +- .../Control/Form/Call/ChangeLayoutForm.qml | 4 +- .../view/Control/Form/Login/LoginForm.qml | 30 +- .../Form/Settings/MultimediaSettings.qml | 86 +- .../Form/Settings/ScreencastSettings.qml | 2 +- .../Input/Chat/ChatDroppableTextArea.qml | 8 +- .../view/Control/Input/DecoratedTextField.qml | 1 + Linphone/view/Control/Input/DigitInput.qml | 4 +- .../view/Control/Input/PhoneNumberInput.qml | 12 +- Linphone/view/Control/Input/SearchBar.qml | 37 +- Linphone/view/Control/Input/TextArea.qml | 1 + Linphone/view/Control/Input/TextField.qml | 41 +- .../Popup/Dialog/ZrtpAuthenticationDialog.qml | 6 +- .../view/Control/Popup/InformationPopup.qml | 12 +- Linphone/view/Control/Popup/Popup.qml | 2 + Linphone/view/Control/Tool/Helper/utils.js | 53 + .../view/Page/Form/Chat/SelectedChatView.qml | 2 +- .../view/Page/Form/Contact/ContactEdition.qml | 123 +- Linphone/view/Page/Form/Login/LoginPage.qml | 49 +- .../view/Page/Form/Login/SIPLoginPage.qml | 23 +- .../Page/Form/Meeting/AddParticipantsForm.qml | 325 +++-- .../view/Page/Form/Meeting/MeetingForm.qml | 1 + .../view/Page/Form/Register/RegisterPage.qml | 103 +- .../Form/Settings/AbstractSettingsMenu.qml | 16 +- .../Page/Layout/Chat/ConversationInfos.qml | 6 +- .../Layout/Chat/GroupChatInfoParticipants.qml | 2 +- .../view/Page/Layout/Login/LoginLayout.qml | 25 +- Linphone/view/Page/Layout/Main/MainLayout.qml | 519 ++++--- .../Settings/AbstractSettingsLayout.qml | 62 +- .../Settings/AccountSettingsGeneralLayout.qml | 4 +- .../Settings/AdvancedSettingsLayout.qml | 3 + .../Layout/Settings/CallSettingsLayout.qml | 2 + .../Settings/ContactsSettingsLayout.qml | 8 + .../ContactsSettingsProviderLayout.qml | 22 +- .../Layout/Settings/LdapSettingsLayout.qml | 19 +- .../Page/Main/Account/AccountListView.qml | 145 +- Linphone/view/Page/Main/Call/CallPage.qml | 182 +-- .../view/Page/Main/Call/CallSettingsPanel.qml | 8 +- .../view/Page/Main/Contact/ContactPage.qml | 37 +- .../view/Page/Main/Meeting/MeetingPage.qml | 2 +- Linphone/view/Page/Window/AbstractWindow.qml | 2 +- .../view/Page/Window/Call/CallsWindow.qml | 206 ++- Linphone/view/Page/Window/Main/MainWindow.qml | 1 + Linphone/view/Style/DefaultStyle.qml | 8 +- Linphone/view/Style/buttonStyle.js | 100 +- README.md | 24 + 99 files changed, 5011 insertions(+), 2825 deletions(-) create mode 100644 Linphone/tool/accessibility/AccessibilityHelper.cpp create mode 100644 Linphone/tool/accessibility/AccessibilityHelper.hpp create mode 100644 Linphone/tool/accessibility/FocusHelper.cpp create mode 100644 Linphone/tool/accessibility/FocusHelper.hpp create mode 100644 Linphone/view/Control/Display/Contact/ContactStatusPopup.qml create mode 100644 Linphone/view/Control/Display/HorizontalBar.qml diff --git a/Linphone/core/App.cpp b/Linphone/core/App.cpp index 374fa7a56..58cd6b346 100644 --- a/Linphone/core/App.cpp +++ b/Linphone/core/App.cpp @@ -98,6 +98,8 @@ #include "tool/Constants.hpp" #include "tool/EnumsToString.hpp" #include "tool/Utils.hpp" +#include "tool/accessibility/AccessibilityHelper.hpp" +#include "tool/accessibility/FocusHelper.hpp" #include "tool/native/DesktopTools.hpp" #include "tool/providers/AvatarProvider.hpp" #include "tool/providers/EmojiProvider.hpp" @@ -725,6 +727,12 @@ void App::initCppInterfaces() { "SettingsCpp", 1, 0, "SettingsCpp", [this](QQmlEngine *engine, QJSEngine *) -> QObject * { return mSettings.get(); }); + qmlRegisterSingletonType( + "AccessibilityHelperCpp", 1, 0, "AccessibilityHelperCpp", + [](QQmlEngine *engine, QJSEngine *) -> QObject * { return new AccessibilityHelper(engine); }); + + qmlRegisterType("CustomControls", 1, 0, "FocusHelper"); + qmlRegisterType(Constants::MainQmlUri, 1, 0, "DashRectangle"); qmlRegisterType(Constants::MainQmlUri, 1, 0, "PhoneNumberProxy"); qmlRegisterType(Constants::MainQmlUri, 1, 0, "VariantObject"); diff --git a/Linphone/core/account/AccountCore.cpp b/Linphone/core/account/AccountCore.cpp index efe6f74be..a008480b9 100644 --- a/Linphone/core/account/AccountCore.cpp +++ b/Linphone/core/account/AccountCore.cpp @@ -60,10 +60,7 @@ AccountCore::AccountCore(const std::shared_ptr &account) : QO mRegisterEnabled = params->registerEnabled(); mMwiServerAddress = params->getMwiServerAddress() ? Utils::coreStringToAppString(params->getMwiServerAddress()->asString()) : ""; - mTransports << "UDP" - << "TCP" - << "TLS" - << "DTLS"; + mTransports << "UDP" << "TCP" << "TLS" << "DTLS"; mTransport = LinphoneEnums::toString(LinphoneEnums::fromLinphone(params->getTransport())); mRegistrarUri = params->getServerAddress() ? Utils::coreStringToAppString(params->getServerAddress()->asString()) : ""; @@ -458,13 +455,13 @@ QColor AccountCore::getRegistrationColor() const { mustBeInMainThread(log().arg(Q_FUNC_INFO)); switch (mRegistrationState) { case LinphoneEnums::RegistrationState::Ok: - return Utils::getDefaultStyleColor("success_500main"); + return Utils::getDefaultStyleColor("success_500_main"); case LinphoneEnums::RegistrationState::Refreshing: - return Utils::getDefaultStyleColor("main2_500main"); + return Utils::getDefaultStyleColor("main2_500_main"); case LinphoneEnums::RegistrationState::Progress: - return Utils::getDefaultStyleColor("main2_500main"); + return Utils::getDefaultStyleColor("main2_500_main"); case LinphoneEnums::RegistrationState::Failed: - return Utils::getDefaultStyleColor("danger_500main"); + return Utils::getDefaultStyleColor("danger_500_main"); case LinphoneEnums::RegistrationState::None: case LinphoneEnums::RegistrationState::Cleared: return Utils::getDefaultStyleColor("warning_600"); diff --git a/Linphone/core/notifier/Notifier.cpp b/Linphone/core/notifier/Notifier.cpp index 5a7af61e1..8556ebc63 100644 --- a/Linphone/core/notifier/Notifier.cpp +++ b/Linphone/core/notifier/Notifier.cpp @@ -36,6 +36,7 @@ #include "core/chat/ChatGui.hpp" #include "model/tool/ToolModel.hpp" #include "tool/LinphoneEnums.hpp" +#include "tool/accessibility/AccessibilityHelper.hpp" #include "tool/providers/AvatarProvider.hpp" #include "tool/providers/ImageProvider.hpp" @@ -302,6 +303,11 @@ void Notifier::notifyReceivedCall(const shared_ptr &call) { QString displayName = call->getCallLog() && call->getCallLog()->getConferenceInfo() ? Utils::coreStringToAppString(call->getCallLog()->getConferenceInfo()->getSubject()) : Utils::coreStringToAppString(call->getRemoteAddress()->getDisplayName()); + + // Accessibility alert + //: New call from %1 + AccessibilityHelper::announceMessage(tr("new_call_alert_accessible_name").arg(displayName)); + App::postCoreAsync([this, gui, displayName]() { mustBeInMainThread(getClassName()); QVariantMap map; @@ -381,6 +387,10 @@ void Notifier::notifyReceivedMessages(const std::shared_ptr auto chatCore = ChatCore::create(room); + // Accessibility alert + //: New message on chatroom %1 + AccessibilityHelper::announceMessage(tr("new_message_alert_accessible_name").arg(chatCore->getTitle())); + App::postCoreAsync([this, txt, chatCore, remoteAddress]() { mustBeInMainThread(getClassName()); QVariantMap map; diff --git a/Linphone/data/languages/de.ts b/Linphone/data/languages/de.ts index 8a56a8e15..56edbee33 100644 --- a/Linphone/data/languages/de.ts +++ b/Linphone/data/languages/de.ts @@ -4,11 +4,23 @@ AbstractSettingsLayout - + + return_accessible_name + Return + + + + save "Enregistrer" Speichern + + + save_settings_accessible_name + Save %1 settings + + AbstractWindow @@ -27,45 +39,45 @@ AccountCore - + drawer_menu_account_connection_status_connected "Connecté" Verbunden - + drawer_menu_account_connection_status_refreshing Aktualisiere… - + drawer_menu_account_connection_status_progress Verbinde… - + drawer_menu_account_connection_status_failed Fehler - + drawer_menu_account_connection_status_cleared Deaktiviert - + manage_account_status_connected_summary "Vous êtes en ligne et joignable." Sie sind online und erreichbar. - + manage_account_status_failed_summary "Erreur de connexion, vérifiez vos paramètres." Verbindungsfehler, überprüfen Sie Ihre Einstellungen. - + manage_account_status_cleared_summary "Compte désactivé, vous ne recevrez ni appel ni message." Konto deaktiviert, Sie erhalten keine Anrufe oder Nachrichten. @@ -80,6 +92,15 @@ Fehler beim Abrufen der Geräte + + AccountListView + + + add_an_account + Add an account + + + AccountManager @@ -464,13 +485,13 @@ AddParticipantsForm - + search_bar_search_contacts_placeholder "Rechercher des contacts" Kontakte finden - + add_participant_selected_count 0 "%n participant(s) sélectionné(s)" @@ -480,13 +501,19 @@ - + + remove_participant_accessible_name + Remove participant %1 + + + + list_filter_no_result_found "Aucun contact" Kein Ergebnis gefunden… - + contact_list_empty Zurzeit keine Kontakte @@ -553,25 +580,32 @@ Ungültiges URL-Format - + + download_apply_remote_provisioning_accessible_name + "Download and apply remote provisioning" + + + + + settings_advanced_media_encryption_title Media encryption Medienverschlüsselung - + settings_advanced_media_encryption_mandatory_title Media encryption mandatory Pflicht zur Medienverschlüsselung - + settings_advanced_create_endtoend_encrypted_meetings_title Create end to end encrypted meetings and group calls - + settings_advanced_hide_fps_title FPS ausblenden @@ -600,94 +634,94 @@ App - + remote_provisioning_dialog Voulez-vous télécharger et appliquer la configuration depuis cette adresse ? Möchten Sie die Remote-Konfiguration von dieser Adresse herunterladen und anwenden? - - + + info_popup_error_title Error - - + + info_popup_configuration_failed_message Remote provisioning failed : %1 - + configuration_error_detail not reachable - + application_description "A free and open source SIP video-phone." Ein kostenloses Open-Source SIP Video-Telefon. - + command_line_arg_order "Send an order to the application towards a command line" Kommandozeilen-Befehl an die Anwendung schicken - + command_line_option_show_help Zeige Hilfe - + command_line_option_show_app_version Zeige App-Version - + command_line_option_config_to_fetch "Specify the linphone configuration file to be fetched. It will be merged with the current configuration." Abzurufende Linphone-Konfigurationsdatei angeben. Sie wird mit der aktuellen Konfiguration zusammengeführt. - + command_line_option_config_to_fetch_arg "URL, path or file" URL, Pfad oder Datei - + command_line_option_minimized - + command_line_option_log_to_stdout Debug-Informationen auf der Standardausgabe ausgeben - + command_line_option_print_app_logs_only "Print only logs from the application" Nur Anwendungs-Logs ausgeben - + hide_action "Cacher" "Afficher" Ausblenden - + show_action Zeigen - + quit_action "Quitter" Beenden @@ -930,6 +964,15 @@ Videoanruf + + CallHistoryListView + + + call_name_accessible_button + Call %1 + + + CallLayout @@ -977,29 +1020,53 @@ CallListView - + meeting "Réunion Besprechung - + call "Appel" Anruf - + paused_call_or_meeting "%1 en pause" %1 pausiert - + ongoing_call_or_meeting "%1 en cours" %1 laufend + + + transfer_call_name_accessible_name + Transfer call %1 + + + + + resume_call_name_accessible_name + Resume %1 call + + + + + pause_call_name_accessible_name + Pause %1 call + + + + + end_call_name_accessible_name + End %1 call + + CallModel @@ -1115,48 +1182,71 @@ Anrufe - - + + call_history_options_accessible_name + + + + + menu_delete_history "Supprimer l'historique" Verlauf löschen - + + call_history_list_options_accessible_name + Call history options + + + + + create_new_call_accessible_name + Create new call + + + + call_search_in_history "Rechercher un appel" Anruf suchen - + call_forward_to_address_info - + call_forward_to_address_info_voicemail - + list_filter_no_result_found "Aucun résultat…" Kein Ergebnis gefunden… - + history_list_empty_history "Aucun appel dans votre historique" Anrufverlauf leer - + + return_to_call_history_accessible_name + Return to call history + + + + call_action_start_new_call "Nouvel appel" Neuer Anruf - + call_start_group_call_title "Appel de groupe" Gruppenanruf @@ -1170,7 +1260,7 @@ - + call_action_start_group_call "Lancer" Starten @@ -1186,74 +1276,74 @@ Erforderlich - - - + + + information_popup_error_title Fehler - + group_call_error_must_have_name "Un nom doit être donné à l'appel de groupe Es muss ein Name für den Anruf angegeben werden - + group_call_error_not_connected "Vous n'etes pas connecté" Sie sind nicht verbunden - + menu_see_existing_contact "Show contact" Kontakt anzeigen - + menu_add_address_to_contacts "Add to contacts" Zu Kontakten hinzufügen - + menu_copy_sip_address "Copier l'adresse SIP" SIP-Adresse kopieren - + sip_address_copied_to_clipboard_toast Adresse copiée SIP-Adresse kopiert - + sip_address_copied_to_clipboard_message L'adresse a été copié dans le presse_papiers Die Adresse wurde in die Zwischenablage kopiert - + sip_address_copy_to_clipboard_error "Erreur lors de la copie de l'adresse" Fehler beim Kopieren der Adresse - + notification_missed_call_title "Appel manqué" Verpasster Anruf - + call_outgoing "Appel sortant" Ausgehender Anruf - + call_audio_incoming "Appel entrant" Eingehender Anruf @@ -1332,6 +1422,21 @@ Current ringtone : + + + choose_ringtone_file_accessible_name + Choose ringtone file + + + + + CallSettingsPanel + + + close_name_panel_accessible_button + Close %1 panel + + CallStatistics @@ -1351,236 +1456,236 @@ CallsWindow - + call_transfer_in_progress_toast "Transfert en cours, veuillez patienter" Weiterleitung läuft, bitte warten - - + + information_popup_error_title Fehler - + call_transfer_failed_toast "Le transfert d'appel a échoué" Weiterleitung fehlgeschlagen - + conference_error_empty_uri "La conférence n'a pas pu démarrer en raison d'une erreur d'uri." Die Besprechung konnte aufgrund eines URI-Fehlers nicht gestartet werden. - + call_close_window_dialog_title "Terminer tous les appels en cours ?" Alle laufenden Anrufe beenden? - + call_close_window_dialog_message "La fenêtre est sur le point d'être fermée. Cela terminera tous les appels en cours." Das Fenster wird gleich geschlossen. Dies beendet alle laufenden Anrufe. - + call_can_be_trusted_toast "Appareil authentifié" Gerät vertrauenswürdig - + call_dir %1 Anruf - + call_ended Appel terminé Anruf beendet - + conference_paused Meeting paused Besprechung pausiert - + call_paused Call paused Anruf pausiert - - + + call_srtp_point_to_point_encrypted Appel chiffré de point à point Punkt-zu-Punkt verschlüsselter Anruf - + call_zrtp_sas_validation_required Vérification nécessaire Validierung erforderlich - + call_zrtp_end_to_end_encrypted Appel chiffré de bout en bout Ende-zu-Ende verschlüsselter Anruf - + call_not_encrypted "Appel non chiffré" Unverschlüsselter Anruf - - + + call_waiting_for_encryption_info Waiting for encryption Warten auf Verschlüsselung - + call_paused_by_remote Call paused by remote - + conference_user_is_recording "You are recording the meeting" Sie nehmen die Besprechung auf - + call_user_is_recording "You are recording the call" Sie nehmen den Anruf auf - + conference_remote_is_recording "Someone is recording the meeting" Jemand nimmt die Besprechung auf - + call_remote_recording "%1 is recording the call" %1 nimmt den Anruf auf - + call_stop_recording "Stop recording" Aufnahme stoppen - + add Hinzufügen - + call_transfer_current_call_title "Transférer %1 à…" %1 weiterleiten an… - - + + call_transfer_confirm_dialog_tittle "Confirmer le transfert" Weiterleitung bestätigen - - + + call_transfer_confirm_dialog_message "Vous allez transférer %1 à %2." Sie werden %1 an %2 weiterleiten. - + call_action_start_new_call "Nouvel appel" Neuen Anruf starten - - + + call_action_show_dialer "Pavé numérique" Wähltastatur - + call_action_change_layout "Modifier la disposition" Layout ändern - + call_action_go_to_calls_list "Liste d'appel" Anrufliste - + Merger tous les appels call_action_merge_calls Alle Anrufe zusammenführen - - + + call_action_go_to_settings "Paramètres" Einstellungen - + conference_action_screen_sharing "Partage de votre écran" Bildschirm teilen - + conference_share_link_title Partager le lien de la réunion Besprechungs-Link teilen - + copied Copié Kopiert - + information_popup_meeting_address_copied_to_clipboard Le lien de la réunion a été copié dans le presse-papier Der Besprechungs-Link wurde in die Zwischenablage kopiert - - - + + + conference_participants_list_title "Participants (%1)" Teilnehmer (%1) - - + + group_call_participant_selected 1 ausgewählter Teilnehmer @@ -1588,161 +1693,194 @@ - + meeting_schedule_add_participants_title Teilnehmer hinzufügen - + call_encryption_title Chiffrement Verschlüsselung - + + open_statistic_panel_accessible_name + + + + conference_user_is_sharing_screen "You are sharing your screen" - + call_stop_screen_sharing "Stop sharing" - + + stop_recording_accessible_name + Stop recording + + + + + stop_screen_sharing_accessible_name + "Stop screen sharing" + + + + call_stats_title Statistiques Statistiken - + + call_action_end_call "Terminer l'appel" Anruf beenden - + + call_action_resume_call "Reprendre l'appel" Anruf fortsetzen - + + call_action_pause_call "Mettre l'appel en pause" Anruf pausieren - + + call_action_transfer_call "Transférer l'appel" Anruf weiterleiten - + + call_action_start_new_call_hint "Initier un nouvel appel" Neuen Anruf starten - + + call_display_call_list_hint "Afficher la liste d'appels" Anrufliste anzeigen - + + call_deactivate_video_hint "Désactiver la vidéo" "Activer la vidéo" Video deaktivieren - + + call_activate_video_hint Video aktivieren - + + call_activate_microphone "Activer le micro" Mikrofon aktivieren - + + call_deactivate_microphone "Désactiver le micro" Mikrofon stummschalten - + + call_share_screen_hint Partager l'écran… Bildschirm teilen… - + + call_open_chat_hint Open chat… - + + call_rise_hand_hint "Lever la main" Hand heben - + + call_send_reaction_hint "Envoyer une réaction" Reaktion senden - + + call_manage_participants_hint "Gérer les participants" Teilnehmer verwalten - + + call_more_options_hint "Plus d'options…" Weitere Optionen… - + call_action_change_conference_layout "Modifier la disposition" Layout ändern - + call_action_full_screen "Mode Plein écran" Vollbildmodus - + call_action_stop_recording "Terminer l'enregistrement" Aufnahme beenden - + call_action_record "Enregistrer l'appel" Anruf aufnehmen - + call_activate_speaker_hint "Activer le son" Lautsprecher aktivieren - + call_deactivate_speaker_hint "Désactiver le son" Lautsprecher stummschalten @@ -1894,7 +2032,7 @@ - + cannot_record_while_in_call_tooltip Cannot record a message while a call is ongoing @@ -1970,25 +2108,25 @@ ChatMessage - + chat_message_copy_selection "Copy selection" - + chat_message_copy "Copy" - + chat_message_copied_to_clipboard_title Copied - + chat_message_copied_to_clipboard_toast "to clipboard" @@ -2024,25 +2162,25 @@ - + chat_message_reception_info "Reception info" - + chat_message_reply Reply - + chat_message_forward Forward - + chat_message_delete "Delete" @@ -2451,35 +2589,41 @@ Error Fehler - + information_popup_error_title Erreur Fehler - + information_popup_voicemail_address_undefined_message L'URI de messagerie vocale n'est pas définie. Die Voicemail-URI ist nicht definiert. + + + account_settings_name_accessible_name + Account settings of %1 + + ContactEdition - + contact_editor_title "Modifier contact" Kontakt bearbeiten - + save "Enregistrer Speichern - - + + contact_editor_dialog_cancel_change_message "Les changements seront annulés. Souhaitez-vous continuer ?" Änderungen werden verworfen. Möchten Sie fortfahren? @@ -2490,68 +2634,126 @@ Error Bitte geben Sie einen Vornamen ein - + + close_accessible_name + Close %n + + + + contact_editor_mandatory_first_name_or_company_not_filled "Veuillez saisir un prénom ou un nom d'entreprise" - + contact_editor_mandatory_address_or_number_not_filled "Veuillez saisir une adresse ou un numéro de téléphone" Bitte geben Sie eine SIP-Adresse oder Telefonnummer ein - + contact_editor_add_image_label "Ajouter une image" Bild hinzufügen - + contact_details_edit "Modifier" Bearbeiten - + + edit_contact_image_accessible_name + "Edit contact image" + + + + contact_details_delete "Supprimer" Löschen - + + delete_contact_image_accessible_name + "Delete contact image" + + + + + contact_editor_first_name "Prénom" Vorname - + + contact_editor_last_name "Nom" Nachname - + + contact_editor_company "Entreprise" Unternehmen - + + contact_editor_job_title "Fonction" Beruf - - + + sip_address SIP-Adresse - - + + sip_address_number_accessible_name + "SIP address number %1" + + + + + remove_sip_address_accessible_name + "Remove SIP address %1" + + + + + new_sip_address_accessible_name + "New SIP address" + + + + + phone_number_number_accessible_name + "Phone number number %1" + + + + + remove_phone_number_accessible_name + Remove phone number %1 + + + + + new_phone_number_accessible_name + "New phone number" + + + + + phone "Téléphone" Telefon @@ -2560,58 +2762,73 @@ Error ContactListItem - + contact_details_remove_from_favourites "Enlever des favoris" Aus Favoriten entfernen - + contact_details_add_to_favourites "Ajouter aux favoris" Zu Favoriten hinzufügen - + Partager Teilen - + information_popup_error_title Fehler - + information_popup_vcard_creation_error La création du fichier vcard a échoué VCard-Erstellung fehlgeschlagen - + information_popup_vcard_creation_title VCard créée VCard erstellt - + information_popup_vcard_creation_success "VCard du contact enregistrée dans %1" VCard in %1 gespeichert - + contact_sharing_email_title Partage de contact Kontakt teilen - + contact_details_delete "Supprimer" Löschen + + ContactListView + + + shrink_accessible_name + Shrink %1 + + + + + expand_accessible_name + Expand %1 + + + ContactPage @@ -2726,26 +2943,50 @@ Error Kontakte - + + create_contact_accessible_name + Create new contact + + + + search_bar_look_for_contact_text Rechercher un contact Kontakt suchen - + list_filter_no_result_found Aucun résultat… Kein Ergebnis… - + contact_list_empty Aucun contact pour le moment Zurzeit keine Kontakte - - + + more_info_accessible_name + More info %1 + + + + + expand_accessible_name + Expand %1 + + + + + shrink_accessible_name + Shrink %1 + + + + + contact_details_edit Edit ---------- @@ -2753,19 +2994,19 @@ Error Bearbeiten - + contact_call_action "Appel" Anrufen - + contact_message_action "Message" Nachricht - + contact_video_call_action "Appel vidéo" Videoanruf @@ -2791,120 +3032,133 @@ Error Offline - + contact_details_numbers_and_addresses_title "Coordonnées" Kontaktinformationen - + + call_adress_accessible_name + Call address %1 + + + + contact_details_company_name "Société :" Unternehmen : - + contact_details_job_title "Poste :" Beruf : - + contact_details_medias_title "Medias" Medien - + + contact_details_medias_subtitle "Afficher les medias partagés" Geteilte Medien anzeigen - + contact_details_trust_title "Confiance" Vertrauen - + contact_dialog_devices_trust_title "Niveau de confiance - Appareils vérifiés" Vertrauenslevel - Verifizierte Geräte - + contact_details_no_device_found "Aucun appareil" Kein Gerät - + contact_device_without_name "Appareil inconnu" Unbekanntes Gerät - + contact_make_call_check_device_trust "Vérifier" Überprüfen - + + verify_device_accessible_name + Verify %1 device + + + + contact_details_actions_title "Autres actions" Weitere Aktionen - + contact_details_remove_from_favourites "Retirer des favoris" Aus Favoriten entfernen - + contact_details_add_to_favourites "Ajouter aux favoris" Zu Favoriten hinzufügen - + contact_details_share "Partager" Teilen - + information_popup_error_title Fehler - + contact_details_share_error_mesage "La création du fichier vcard a échoué" VCard-Erstellung fehlgeschlagen - + contact_details_share_success_title "VCard créée" VCard erstellt - + contact_details_share_success_mesage "VCard du contact enregistrée dans %1" VCard wurde in %1 gespeichert - + contact_details_share_email_title "Partage de contact" Kontakt teilen - + contact_details_delete "Supprimer ce contact" Kontakt löschen @@ -2947,33 +3201,57 @@ Error LDAP-Server bearbeiten - + + edit_ldap_server_accessible_name + "Editer le serveur LDAP %1" + + + + + use_ldap_server_accessible_name + "Utiliser le serveur LDAP %1" + + + + settings_contacts_add_carddav_server_title "Ajouter un carnet d'adresse CardDAV" CardDAV-Adressbuch hinzufügen - + settings_contacts_edit_carddav_server_title "Modifier un carnet d'adresse CardDAV" CardDAV-Adressbuch bearbeiten + + + edit_cardav_server_accessible_name + "Editer le carnet d'adresses CardDAV %1" + + + + + use_cardav_server_accessible_name + "Utiliser le d'adresses CardDAV %1" + + ContactsSettingsProviderLayout - + information_popup_success_title Erfolg - + information_popup_changes_saved "Les changements ont été sauvegardés" Änderungen wurden gespeichert - + add "Ajouter" Hinzufügen @@ -3127,7 +3405,7 @@ Error CreationFormLayout - + search_bar_look_for_contact_text "Rechercher un contact" Kontakt suchen @@ -3508,13 +3786,20 @@ Error Gruppenname - + + return_accessible_name + Return + + + + + group_start_dialog_subject_hint "Nom du groupe" - + required "Requis" Erforderlich @@ -3575,123 +3860,129 @@ Error LdapSettingsLayout - + settings_contacts_ldap_title LDAP-Server - + settings_contacts_ldap_subtitle LDAP-Server hinzufügen, um in der magischen Suchleiste suchen zu können. - + information_popup_success_title Erfolg - + settings_contacts_ldap_success_toast "L'annuaire LDAP a été sauvegardé" LDAP-Server wurde gespeichert - + settings_contacts_ldap_error_toast "Une erreur s'est produite, la configuration LDAP n'a pas été sauvegardée !" Ein Fehler ist aufgetreten, die LDAP-Konfiguration wurde nicht gespeichert! - + information_popup_error_title Fehler - + settings_contacts_ldap_delete_confirmation_message "Supprimer l'annuaire LDAP ?" LDAP-Server löschen? - + + delete_ldap_server_accessible_name + Delete LDAP server + + + + settings_contacts_ldap_server_url_title "URL du serveur (ne peut être vide)" Server-URL (darf nicht leer sein) - + settings_contacts_ldap_bind_dn_title "Bind DN" DN binden - + settings_contacts_ldap_password_title "Mot de passe" Passwort - + settings_contacts_ldap_use_tls_title "Utiliser TLS" TLS verwenden - + settings_contacts_ldap_search_base_title "Base de recherche (ne peut être vide)" Suchbasis (darf nicht leer sein) - + settings_contacts_ldap_search_filter_title "Filtre" Filter - + settings_contacts_ldap_max_results_title "Nombre maximum de résultats" Maximale Ergebnisse - + settings_contacts_ldap_request_delay_title "Délai entre 2 requêtes (en millisecondes)" Zeitverzögerung zwischen zwei Anfragen (in Millisekunden) - + settings_contacts_ldap_request_timeout_title "Durée maximun (en secondes)" Zeitüberschreitung (in Sekunden) - + settings_contacts_ldap_min_characters_title "Nombre minimum de caractères pour la requête" Mindestanzahl an Zeichen für die Anfrage - + settings_contacts_ldap_name_attributes_title "Attributs de nom" Namenattribute - + settings_contacts_ldap_sip_attributes_title "Attributs SIP" SIP-Attribute - + settings_contacts_ldap_sip_domain_title "Domaine SIP" SIP-Domäne - + settings_contacts_ldap_debug_title "Débogage" Debug @@ -3708,37 +3999,46 @@ Error LoginForm - + + username Nom d'utilisateur : username Benutzername - + + password Mot de passe Passwort - + + mandatory_field_accessible_name + "%1 mandatory" + + + + + assistant_account_login "Connexion" Anmelden - + assistant_account_login_missing_username "Veuillez saisir un nom d'utilisateur" Bitte Benutzernamen eingeben - + assistant_account_login_missing_password "Veuillez saisir un mot de passe" Bitte Passwort eingeben - + assistant_forgotten_password "Mot de passe oublié ?" Passwort vergessen? @@ -3747,44 +4047,44 @@ Error LoginLayout - - + + help_about_title À propos de %1 Über %1 - + help_about_privacy_policy_title "Politique de confidentialité" Datenschutzrichtlinie - + help_about_privacy_policy_link "Visiter notre potilique de confidentialité" Unsere Datenschutzrichtlinie besuchen - + help_about_version_title "Version" Version - + help_about_licence_title "Licence" Lizenz - + help_about_copyright_title "Copyright Urheberrecht - + close "Fermer" Schließen @@ -3793,60 +4093,66 @@ Error LoginPage - + + return_accessible_name + Return + + + + assistant_account_login Connexion Anmelden - + assistant_no_account_yet "Pas encore de compte ?" Noch kein Konto? - + assistant_account_register "S'inscrire" Registrieren - + assistant_login_third_party_sip_account_title "Compte SIP tiers" Drittanbieter-SIP-Konto - + assistant_login_remote_provisioning "Configuration distante" Remote-Konfiguration - + assistant_login_download_remote_config "Télécharger une configuration distante" Remote-Konfiguration herunterladen - + assistant_login_remote_provisioning_url 'Veuillez entrer le lien de configuration qui vous a été fourni :' Bitte geben Sie den bereitgestellten Konfigurationslink ein: - + cancel Abbrechen - + validate "Valider" Bestätigen - + settings_advanced_remote_provisioning_url 'Lien de configuration distante' Link zur Remote-Konfiguration @@ -3868,102 +4174,144 @@ Error MainLayout - + bottom_navigation_calls_label "Appels" Anrufe - + + open_calls_page_accessible_name + "Open calls page" + + + + bottom_navigation_contacts_label "Contacts" Kontakte - + + open_contacts_page_accessible_name + "Open contacts page" + + + + bottom_navigation_conversations_label "Conversations" Konversationen + open_conversations_page_accessible_name + "Open conversations page" + + + + bottom_navigation_meetings_label "Réunions" Besprechungen - + + open_contact_page_accessible_name + "Open meetings page" + + + + searchbar_placeholder_text "Rechercher un contact, appeler %1" Kontakt suchen, %1 anrufen - + searchbar_placeholder_text_chat_feature_enabled "ou envoyer un message …" oder eine Nachricht senden … - - + + do_not_disturb_accessible_name + "Do not disturb" + + + + + contact_presence_status_disable_do_not_disturb "Désactiver ne pas déranger" Nicht stören deaktivieren - + information_popup_error_title Fehler - + no_voicemail_uri_error_message "L'URI de messagerie vocale n'est pas définie." Die Voicemail-URI ist nicht definiert. - + + account_list_accessible_name + "Account list" + + + + + application_options_accessible_name + "Application options" + + + + drawer_menu_manage_account Mon compte Mein Konto - + contact_presence_status_enable_do_not_disturb "Activer ne pas déranger" Nicht stören aktivieren - + settings_title Einstellungen - + recordings_title "Enregistrements" Aufnahmen - + help_title "Aide" Hilfe - + help_quit_title "Quitter l'application" App beenden - + quit_app_question "Quitter %1 ?" %1 beenden? - + drawer_menu_add_account "Ajouter un compte" Konto hinzufügen @@ -4002,48 +4350,48 @@ Error Ihr Gesprächspartner wurde an den ausgewählten Kontakt weitergeleitet - + information_popup_success_title Gespeichert - + information_popup_changes_saved "Les changements ont été sauvegardés" Änderungen wurden gespeichert - + captcha_validation_loading_message "Veuillez valider le captcha sur la page web" Bitte das Captcha auf der Webseite bestätigen - + assistant_register_error_title "Erreur lors de la création" Fehler bei der Erstellung - + assistant_register_success_title "Compte créé" Konto erstellt - + assistant_register_success_message "Le compte a été créé. Vous pouvez maintenant vous connecter" Das Konto wurde erstellt. Sie können sich jetzt anmelden. - + assistant_register_error_code "Erreur dans le code de validation" Fehler im Bestätigungscode - + information_popup_error_title Fehler @@ -4083,13 +4431,13 @@ Error Beschreibung hinzufügen - + meeting_schedule_add_participants_title "Ajouter des participants" Teilnehmer hinzufügen - + meeting_schedule_send_invitations_title "Envoyer une invitation aux participants" Einladung an Teilnehmer senden @@ -4387,25 +4735,47 @@ Error MultimediaSettings - + + multimedia_settings_ringer_title Ringtone - Incoming calls Klingelton - Eingehende Anrufe - + + + + + choose_something_accessible_name + Choose %1 + + + + + + multimedia_settings_speaker_title "Haut-parleurs" Lautsprecher - + + + device_volume_accessible_name + %1 volume + + + + + + multimedia_settings_microphone_title "Microphone" Mikrofon - + + multimedia_settings_camera_title "Caméra" Kamera @@ -4479,28 +4849,40 @@ Error Notifier - + + new_call_alert_accessible_name + New call from %1 + + + + new_voice_message 'Voice message received!' : message to warn the user in a notofication for voice messages. - + new_file_message - + new_conference_invitation 'Conference invitation received!' : Notification about receiving an invitation to a conference. - + new_chat_room_messages 'New messages received!' Notification that warn the user of new messages. + + + new_message_alert_accessible_name + New message on chatroom %1 + + OIDCModel @@ -4632,30 +5014,60 @@ Error Teilnehmer hinzufügen + + PhoneNumberInput + + + prefix_phone_number_accessible_name + %1 prefix + + + + + number_phone_number_accessible_name + %1 number + + + + + PopupButton + + + close_popup_panel_accessible_name + "Close %1 popup" + + + + + open_popup_panel_accessible_name + "Open %1" popup + + + Presence - + contact_presence_reset_status - + contact_presence_custom_status - + contact_presence_button_set_custom_status - + contact_presence_button_edit_custom_status - + contact_presence_button_delete_custom_status @@ -4849,109 +5261,135 @@ Error RegisterPage - + + return_accessible_name + Return + + + + assistant_account_register "Inscription Registrieren - + assistant_already_have_an_account Haben Sie bereits ein Konto? - + assistant_account_login Anmelden - + assistant_account_register_with_phone_number Mit Telefonnummer registrieren - + assistant_account_register_with_email Mit E-Mail registrieren - + + username Benutzername - - + + + + + + mandatory_field_accessible_name + "%1 mandatory" + + + + + domain + + + + + + phone_number "Numéro de téléphone" Telefonnummer - + + email Email - + + password Passwort - + + assistant_account_register_password_confirmation "Confirmation mot de passe" Passwort bestätigen - + assistant_dialog_cgu_and_privacy_policy_message "J'accepte les %1 et la %2" Ich akzeptiere %1 und %2 - + assistant_dialog_general_terms_label "conditions d'utilisation" Allgemeine Geschäftsbedingungen - + assistant_dialog_privacy_policy_label "politique de confidentialité" Datenschutzrichtlinie - + assistant_account_create "Créer" Erstellen - + assistant_account_create_missing_username_error "Veuillez entrer un nom d'utilisateur" Bitte Benutzernamen eingeben - + assistant_account_create_missing_password_error "Veuillez entrer un mot de passe" Bitte Passwort eingeben - + assistant_account_create_confirm_password_error "Les mots de passe sont différents" Die Passwörter stimmen nicht überein - + assistant_account_create_missing_number_error "Veuillez entrer un numéro de téléphone" Bitte Telefonnummer eingeben - + assistant_account_create_missing_email_error "Veuillez entrer un email" Bitte E-Mail eingeben @@ -4960,25 +5398,31 @@ Error SIPLoginPage - + + return_accessible_name + Return + + + + assistant_login_third_party_sip_account_title Compte SIP tiers Drittanbieter-SIP-Konto - + assistant_no_account_yet Pas encore de compte ? Noch kein Konto? - + assistant_account_register S'inscrire Registrieren - + Certaines fonctionnalités telles que les conversations de groupe, les vidéo-conférences, etc… nécessitent un compte %1. Ces fonctionnalités seront masquées si vous utilisez un compte SIP tiers. @@ -4991,93 +5435,108 @@ Pour les activer dans un projet commercial, merci de nous contacter. Um sie in einem kommerziellen Projekt zu aktivieren, kontaktieren Sie uns bitte. - + assistant_third_party_sip_account_create_linphone_account "Créer un compte linphone" Linphone-Konto erstellen - + assistant_third_party_sip_account_warning_ok "Je comprends" Verstanden - + + username "Nom d'utilisateur" Benutzername - + + + mandatory_field_accessible_name + "%1 mandatory" + + + + + password Passwort - + + sip_address_domain "Domaine" Domäne - + + sip_address_display_name Nom d'affichage Anzeigename - + + transport "Transport" Transport - + + assistant_account_login Anmelden - + assistant_account_login_missing_username Bitte Benutzernamen eingeben - + assistant_account_login_missing_password Bitte Passwort eingeben - + assistant_account_login_missing_domain "Veuillez saisir un nom de domaine Bitte Domäne eingeben - + login_advanced_parameters_label Advanced parameters - + + login_proxy_server_url "Outbound SIP Proxy URI" - + login_proxy_server_url_tooltip "If this field is filled, the outbound proxy will be enabled automatically. Leave it empty to disable it." - + login_registrar_uri "Registrar URI" - + + login_id "Authentication ID (if different)" @@ -5122,6 +5581,21 @@ Pour les activer dans un projet commercial, merci de nous contacter. Teilen + + SearchBar + + + open_dialer_acccessibility_label + "Open dialer" + + + + + clear_text_input_acccessibility_label + "Clear text input" + + + SecurityModePage @@ -5220,6 +5694,15 @@ Pour les activer dans un projet commercial, merci de nous contacter. + + SettingsMenuItem + + + setting_tab_accessible_name + %1 settings + + + SettingsPage @@ -5315,6 +5798,21 @@ Pour les activer dans un projet commercial, merci de nous contacter. Pausiert + + TextField + + + show_accessible_name + Show %1 + + + + + hide_accessible_name + Hide %1 + + + ToolModel @@ -6885,7 +7383,7 @@ Failed to create 1-1 conversation with %1 ! utils - + formatYears '%1 year' @@ -6894,7 +7392,7 @@ Failed to create 1-1 conversation with %1 ! - + formatMonths '%1 month' @@ -6903,7 +7401,7 @@ Failed to create 1-1 conversation with %1 ! - + formatWeeks '%1 week' @@ -6912,7 +7410,7 @@ Failed to create 1-1 conversation with %1 ! - + formatDays '%1 day' @@ -6921,7 +7419,7 @@ Failed to create 1-1 conversation with %1 ! - + formatHours '%1 hour' @@ -6930,7 +7428,7 @@ Failed to create 1-1 conversation with %1 ! - + formatMinutes '%1 minute' @@ -6939,7 +7437,7 @@ Failed to create 1-1 conversation with %1 ! - + formatSeconds '%1 second' @@ -6948,62 +7446,62 @@ Failed to create 1-1 conversation with %1 ! - + codec_install "Installation de codec" Codec-Installation - + download_codec "Télécharger le codec %1 (%2) ?" Codec %1 (%2) herunterladen? - + information_popup_success_title "Succès" Erfolg - + information_popup_codec_install_success_text "Le codec a été installé avec succès." Der Codec wurde erfolgreich installiert. - - - + + + information_popup_error_title Fehler - + information_popup_codec_install_error_text "Le codec n'a pas pu être installé." Der Codec konnte nicht installiert werden. - + information_popup_codec_save_error_text "Le codec n'a pas pu être sauvegardé." Der Codec konnte nicht gespeichert werden. - + information_popup_codec_download_error_text "Le codec n'a pas pu être téléchargé." Der Codec konnte nicht heruntergeladen werden. - + loading_popup_codec_install_progress "Téléchargement en cours …" Download läuft … - + okButton Ok diff --git a/Linphone/data/languages/en.ts b/Linphone/data/languages/en.ts index cb51ba5da..302d5989a 100644 --- a/Linphone/data/languages/en.ts +++ b/Linphone/data/languages/en.ts @@ -4,11 +4,23 @@ AbstractSettingsLayout - + + return_accessible_name + Return + Return + + + save "Enregistrer" Save + + + save_settings_accessible_name + Save %1 settings + Save %1 settings + AbstractWindow @@ -27,45 +39,45 @@ AccountCore - + drawer_menu_account_connection_status_connected "Connecté" Connected - + drawer_menu_account_connection_status_refreshing Refreshing… - + drawer_menu_account_connection_status_progress Connecting… - + drawer_menu_account_connection_status_failed Error - + drawer_menu_account_connection_status_cleared Disabled - + manage_account_status_connected_summary "Vous êtes en ligne et joignable." You are online and reachable. - + manage_account_status_failed_summary "Erreur de connexion, vérifiez vos paramètres." Connection error, check your settings. - + manage_account_status_cleared_summary "Compte désactivé, vous ne recevrez ni appel ni message." Account disabled, you will not receive calls or messages. @@ -80,6 +92,15 @@ Error retrieving devices + + AccountListView + + + add_an_account + Add an account + Add an account + + AccountManager @@ -464,13 +485,13 @@ AddParticipantsForm - + search_bar_search_contacts_placeholder "Rechercher des contacts" Find contacts - + add_participant_selected_count 0 "%n participant(s) sélectionné(s)" @@ -480,13 +501,19 @@ - + + remove_participant_accessible_name + Remove participant %1 + Remove participant %1 + + + list_filter_no_result_found "Aucun contact" No result found… - + contact_list_empty No contact for the moment @@ -553,25 +580,32 @@ Invalid url format - + + download_apply_remote_provisioning_accessible_name + "Download and apply remote provisioning" + Download and apply remote provisioning + + + + settings_advanced_media_encryption_title Media encryption Media encryption - + settings_advanced_media_encryption_mandatory_title Media encryption mandatory Mandatory media encryption - + settings_advanced_create_endtoend_encrypted_meetings_title Create end to end encrypted meetings and group calls Create end to end encrypted meetings and group calls - + settings_advanced_hide_fps_title Hide FPS @@ -600,94 +634,94 @@ App - + remote_provisioning_dialog Voulez-vous télécharger et appliquer la configuration depuis cette adresse ? Do you want to download and apply remote provisioning from this address ? - - + + info_popup_error_title Error Error - - + + info_popup_configuration_failed_message Remote provisioning failed : %1 Remote provisioning failed : %1 - + configuration_error_detail not reachable not reachable - + application_description "A free and open source SIP video-phone." A free and open source SIP video-phone. - + command_line_arg_order "Send an order to the application towards a command line" Send an order to the application towards a command line - + command_line_option_show_help Show this help - + command_line_option_show_app_version Show app version - + command_line_option_config_to_fetch "Specify the linphone configuration file to be fetched. It will be merged with the current configuration." Specify the linphone configuration file to be fetched. It will be merged with the current configuration. - + command_line_option_config_to_fetch_arg "URL, path or file" URL, path or file - + command_line_option_minimized Minimize - + command_line_option_log_to_stdout Log to stdout some debug information while running - + command_line_option_print_app_logs_only "Print only logs from the application" Print only logs from the application - + hide_action "Cacher" "Afficher" Hide - + show_action Show - + quit_action "Quitter" Quit @@ -910,6 +944,15 @@ Video call + + CallHistoryListView + + + call_name_accessible_button + Call %1 + Call %1 + + CallLayout @@ -957,29 +1000,53 @@ CallListView - + meeting "Réunion Meeting - + call "Appel" Call - + paused_call_or_meeting "%1 en pause" %1 paused - + ongoing_call_or_meeting "%1 en cours" Ongoing %1 + + + transfer_call_name_accessible_name + Transfer call %1 + Transfer call %1 + + + + resume_call_name_accessible_name + Resume %1 call + Resume %1 call + + + + pause_call_name_accessible_name + Pause %1 call + Pause %1 call + + + + end_call_name_accessible_name + End %1 call + End %1 call + CallModel @@ -1053,12 +1120,12 @@ CallPage - + call_forward_to_address_info Forward calls to: - + call_forward_to_address_info_voicemail Voicemail @@ -1105,117 +1172,140 @@ Calls - - + + call_history_options_accessible_name + Call history options + + + + menu_delete_history "Supprimer l'historique" Delete history - + + call_history_list_options_accessible_name + Call history options + Call history options + + + + create_new_call_accessible_name + Create new call + Create new call + + + call_search_in_history "Rechercher un appel" Find call - + list_filter_no_result_found "Aucun résultat…" No result found… - + history_list_empty_history "Aucun appel dans votre historique" No call in history - + + return_to_call_history_accessible_name + Return to call history + Return to call history + + + call_action_start_new_call "Nouvel appel" New call - + call_start_group_call_title "Appel de groupe" Group call - + call_action_start_group_call "Lancer" Start - - - + + + information_popup_error_title Error - + group_call_error_must_have_name "Un nom doit être donné à l'appel de groupe A name must be provided for the call - + group_call_error_not_connected "Vous n'etes pas connecté" You are not connected - + menu_see_existing_contact "Show contact" Show contact - + menu_add_address_to_contacts "Add to contacts" Add to contacts - + menu_copy_sip_address "Copier l'adresse SIP" Copy SIP address - + sip_address_copied_to_clipboard_toast Adresse copiée SIP address copied - + sip_address_copied_to_clipboard_message L'adresse a été copié dans le presse_papiers The address has been copied to the clipboard - + sip_address_copy_to_clipboard_error "Erreur lors de la copie de l'adresse" Error copying address - + notification_missed_call_title "Appel manqué" Missed call - + call_outgoing "Appel sortant" Outgoing call - + call_audio_incoming "Appel entrant" Incoming call @@ -1294,6 +1384,21 @@ Current ringtone : Current ringtone : + + + choose_ringtone_file_accessible_name + Choose ringtone file + Choose ringtone file + + + + CallSettingsPanel + + + close_name_panel_accessible_button + Close %1 panel + Close %1 panel + CallStatistics @@ -1313,236 +1418,236 @@ CallsWindow - + call_transfer_in_progress_toast "Transfert en cours, veuillez patienter" Transfer in progress, please wait - - + + information_popup_error_title Error - + call_transfer_failed_toast "Le transfert d'appel a échoué" Transfer failed - + conference_error_empty_uri "La conférence n'a pas pu démarrer en raison d'une erreur d'uri." Meeting could start due to URI error. - + call_close_window_dialog_title "Terminer tous les appels en cours ?" End all current calls ? - + call_close_window_dialog_message "La fenêtre est sur le point d'être fermée. Cela terminera tous les appels en cours." The window is about to be closed. This will end all current calls. - + call_can_be_trusted_toast "Appareil authentifié" Device trusted - + call_dir %1 call - + call_ended Appel terminé Call ended - + conference_paused Meeting paused Meeting paused - + call_paused Call paused Call paused - - + + call_srtp_point_to_point_encrypted Appel chiffré de point à point Point-to-point encrypted call - + call_zrtp_sas_validation_required Vérification nécessaire Validation required - + call_zrtp_end_to_end_encrypted Appel chiffré de bout en bout End-to-end encrypted call - + call_not_encrypted "Appel non chiffré" Unencrypted call - - + + call_waiting_for_encryption_info Waiting for encryption Waiting for encryption - + call_paused_by_remote Call paused by remote Call paused by remote - + conference_user_is_recording "You are recording the meeting" You are recording the meeting - + call_user_is_recording "You are recording the call" You are recording the call - + conference_remote_is_recording "Someone is recording the meeting" Someone is recording the meeting - + call_remote_recording "%1 is recording the call" %1 records the call - + call_stop_recording "Stop recording" Stop recording - + add Add - + call_transfer_current_call_title "Transférer %1 à…" Transfer %1 to… - - + + call_transfer_confirm_dialog_tittle "Confirmer le transfert" Confirm transfer - - + + call_transfer_confirm_dialog_message "Vous allez transférer %1 à %2." You are going to transfer %1 to %2. - + call_action_start_new_call "Nouvel appel" New call - - + + call_action_show_dialer "Pavé numérique" Dialer - + call_action_change_layout "Modifier la disposition" Change layout - + call_action_go_to_calls_list "Liste d'appel" Call list - + Merger tous les appels call_action_merge_calls Merge all calls - - + + call_action_go_to_settings "Paramètres" Settings - + conference_action_screen_sharing "Partage de votre écran" Share your screen - + conference_share_link_title Partager le lien de la réunion Share meeting link - + copied Copié Copied - + information_popup_meeting_address_copied_to_clipboard Le lien de la réunion a été copié dans le presse-papier Meeting link has been copied to the clipboard - - - + + + conference_participants_list_title "Participants (%1)" Participants (%1) - - + + group_call_participant_selected %1 selected participant @@ -1550,161 +1655,194 @@ - + meeting_schedule_add_participants_title Add participants - + call_encryption_title Chiffrement Encryption - + + open_statistic_panel_accessible_name + Open statistic panel + + + conference_user_is_sharing_screen "You are sharing your screen" You are sharing your screen - + call_stop_screen_sharing "Stop sharing" Stop - + + stop_recording_accessible_name + Stop recording + Stop recording + + + + stop_screen_sharing_accessible_name + "Stop screen sharing" + Stop screen sharing + + + call_stats_title Statistiques Statistics - + + call_action_end_call "Terminer l'appel" End call - + + call_action_resume_call "Reprendre l'appel" Resume call - + + call_action_pause_call "Mettre l'appel en pause" Pause call - + + call_action_transfer_call "Transférer l'appel" Transfer call - + + call_action_start_new_call_hint "Initier un nouvel appel" Start new call - + + call_display_call_list_hint "Afficher la liste d'appels" View call list - + + call_deactivate_video_hint "Désactiver la vidéo" "Activer la vidéo" Turn off video - + + call_activate_video_hint Enable video - + + call_activate_microphone "Activer le micro" Activate microphone - + + call_deactivate_microphone "Désactiver le micro" Mute microphone - + + call_share_screen_hint Partager l'écran… Share screen… - + + call_open_chat_hint Open chat… Open conversation… - + + call_rise_hand_hint "Lever la main" Rise hand - + + call_send_reaction_hint "Envoyer une réaction" Send reaction - + + call_manage_participants_hint "Gérer les participants" Manage participants - + + call_more_options_hint "Plus d'options…" More options… - + call_action_change_conference_layout "Modifier la disposition" Change layout - + call_action_full_screen "Mode Plein écran" Full screen mode - + call_action_stop_recording "Terminer l'enregistrement" End recording - + call_action_record "Enregistrer l'appel" Record call - + call_activate_speaker_hint "Activer le son" Activate speaker - + call_deactivate_speaker_hint "Désactiver le son" Mute speaker @@ -1856,7 +1994,7 @@ Say something… - + cannot_record_while_in_call_tooltip Cannot record a message while a call is ongoing Cannot record a message while a call is ongoing @@ -1932,25 +2070,25 @@ ChatMessage - + chat_message_copy_selection "Copy selection" Copy selection - + chat_message_copy "Copy" Copy - + chat_message_copied_to_clipboard_title Copied Copied - + chat_message_copied_to_clipboard_toast "to clipboard" in clipboard @@ -1986,25 +2124,25 @@ You replied - + chat_message_reception_info "Reception info" Reception info - + chat_message_reply Reply Reply - + chat_message_forward Forward Forward - + chat_message_delete "Delete" Delete @@ -2298,11 +2436,6 @@ Only your correspondent can decrypt them. "La création a échoué" Creation failed - - information_popup_codec_install_error_text - "La création a échoué" - The codec could not be installed. - group_chat_error_must_have_name @@ -2394,102 +2527,166 @@ Only your correspondent can decrypt them. Contact - + information_popup_error_title Erreur Error - + information_popup_voicemail_address_undefined_message L'URI de messagerie vocale n'est pas définie. The voicemail URI is not defined. + + + account_settings_name_accessible_name + Account settings of %1 + Account settings of %1 + ContactEdition - + contact_editor_title "Modifier contact" Edit contact - + save "Enregistrer Save - - + + contact_editor_dialog_cancel_change_message "Les changements seront annulés. Souhaitez-vous continuer ?" Changes will be discarded. Do you wish to continue? - + + close_accessible_name + Close %n + Close %1 + + + contact_editor_mandatory_first_name_or_company_not_filled "Veuillez saisir un prénom ou un nom d'entreprise" Please enter a first name or a company name - + contact_editor_mandatory_address_or_number_not_filled "Veuillez saisir une adresse ou un numéro de téléphone" Please enter a SIP address or phone number - + contact_editor_add_image_label "Ajouter une image" Add an image - + contact_details_edit "Modifier" Edit - + + edit_contact_image_accessible_name + "Edit contact image" + Edit contact image + + + contact_details_delete "Supprimer" Delete - + + delete_contact_image_accessible_name + "Delete contact image" + Delete contact image + + + + contact_editor_first_name "Prénom" First name - + + contact_editor_last_name "Nom" Last name - + + contact_editor_company "Entreprise" Company - + + contact_editor_job_title "Fonction" Job - - + + sip_address SIP address - - + + sip_address_number_accessible_name + "SIP address number %1" + SIP address number %1 + + + + remove_sip_address_accessible_name + "Remove SIP address %1" + Remove SIP address %1 + + + + new_sip_address_accessible_name + "New SIP address" + New SIP address + + + + phone_number_number_accessible_name + "Phone number number %1" + Phone number number %1 + + + + remove_phone_number_accessible_name + Remove phone number %1 + Remove phone number %1 + + + + new_phone_number_accessible_name + "New phone number" + New phone number + + + + phone "Téléphone" Phone @@ -2498,58 +2695,73 @@ Only your correspondent can decrypt them. ContactListItem - + contact_details_remove_from_favourites "Enlever des favoris" Remove from favorites - + contact_details_add_to_favourites "Ajouter aux favoris" Add to favorites - + Partager Share - + information_popup_error_title Error - + information_popup_vcard_creation_error La création du fichier vcard a échoué VCard creation failed - + information_popup_vcard_creation_title VCard créée VCard created - + information_popup_vcard_creation_success "VCard du contact enregistrée dans %1" VCard has been saved in %1 - + contact_sharing_email_title Partage de contact Share contact - + contact_details_delete "Supprimer" Delete + + ContactListView + + + shrink_accessible_name + Shrink %1 + Shrink %1 + + + + expand_accessible_name + Expand %1 + Expand %1 + + ContactPage @@ -2664,26 +2876,50 @@ Only your correspondent can decrypt them. Contacts - + search_bar_look_for_contact_text Rechercher un contact Find contact - + list_filter_no_result_found Aucun résultat… No result… - + contact_list_empty Aucun contact pour le moment No contact at the moment - - + + expand_accessible_name + Expand %1 + Expand %1 + + + + shrink_accessible_name + Shrink %1 + Shrink %1 + + + + create_contact_accessible_name + Create new contact + Create new contact + + + + more_info_accessible_name + More info %1 + More info %1 + + + + contact_details_edit Edit ---------- @@ -2691,138 +2927,151 @@ Only your correspondent can decrypt them. Edit - + contact_call_action "Appel" Call - + contact_message_action "Message" Message - + contact_video_call_action "Appel vidéo" Video call - + contact_details_numbers_and_addresses_title "Coordonnées" Contact details - + + call_adress_accessible_name + Call address %1 + Call address %1 + + + contact_details_company_name "Société :" Company : - + contact_details_job_title "Poste :" Job : - + contact_details_medias_title "Medias" Medias - + + contact_details_medias_subtitle "Afficher les medias partagés" Show shared media - + contact_details_trust_title "Confiance" Trust - + contact_dialog_devices_trust_title "Niveau de confiance - Appareils vérifiés" Trust Level - Verified Devices - + contact_details_no_device_found "Aucun appareil" No device - + contact_device_without_name "Appareil inconnu" Unknown device - + contact_make_call_check_device_trust "Vérifier" Verify - + + verify_device_accessible_name + Verify %1 device + Verify %1 device + + + contact_details_actions_title "Autres actions" Other actions - + contact_details_remove_from_favourites "Retirer des favoris" Remove from favorites - + contact_details_add_to_favourites "Ajouter aux favoris" Add to favorites - + contact_details_share "Partager" Share - + information_popup_error_title Error - + contact_details_share_error_mesage "La création du fichier vcard a échoué" VCard creation failed - + contact_details_share_success_title "VCard créée" VCard created - + contact_details_share_success_mesage "VCard du contact enregistrée dans %1" VCard has been saved in %1 - + contact_details_share_email_title "Partage de contact" Share contact - + contact_details_delete "Supprimer ce contact" Delete contact @@ -2865,33 +3114,57 @@ Only your correspondent can decrypt them. Edit a LDAP server - + + edit_ldap_server_accessible_name + "Editer le serveur LDAP %1" + Edit the LDAP server %1 + + + + use_ldap_server_accessible_name + "Utiliser le serveur LDAP %1" + Use the LDAP server %1 + + + settings_contacts_add_carddav_server_title "Ajouter un carnet d'adresse CardDAV" Add a CardDAV address book - + settings_contacts_edit_carddav_server_title "Modifier un carnet d'adresse CardDAV" Edit a CardDAV address book + + + edit_cardav_server_accessible_name + "Editer le carnet d'adresses CardDAV %1" + Edit the CardDAV address book %1 + + + + use_cardav_server_accessible_name + "Utiliser le d'adresses CardDAV %1" + Use the CardDAV address book %1 + ContactsSettingsProviderLayout - + information_popup_success_title Success - + information_popup_changes_saved "Les changements ont été sauvegardés" Changes have been saved - + add "Ajouter" Add @@ -3040,7 +3313,7 @@ Only your correspondent can decrypt them. CreationFormLayout - + search_bar_look_for_contact_text "Rechercher un contact" Find contact @@ -3418,13 +3691,20 @@ Expiration : %1 GroupCreationFormLayout - + + return_accessible_name + Return + Return + + + + group_start_dialog_subject_hint "Nom du groupe" Group name - + required "Requis" Required @@ -3485,123 +3765,129 @@ Expiration : %1 LdapSettingsLayout - + settings_contacts_ldap_title LDAP servers - + settings_contacts_ldap_subtitle Add your LDAP servers to be able to search in the magic search bar. - + information_popup_success_title Success - + settings_contacts_ldap_success_toast "L'annuaire LDAP a été sauvegardé" LDAP server has been saved - + settings_contacts_ldap_error_toast "Une erreur s'est produite, la configuration LDAP n'a pas été sauvegardée !" An error occurred, the LDAP configuration was not saved! - + information_popup_error_title Error - + settings_contacts_ldap_delete_confirmation_message "Supprimer l'annuaire LDAP ?" Delete LDAP server ? - + + delete_ldap_server_accessible_name + Delete LDAP server + Delete LDAP server + + + settings_contacts_ldap_server_url_title "URL du serveur (ne peut être vide)" Server URL (can not be empty) - + settings_contacts_ldap_bind_dn_title "Bind DN" Bind DN - + settings_contacts_ldap_password_title "Mot de passe" Password - + settings_contacts_ldap_use_tls_title "Utiliser TLS" Use TLS - + settings_contacts_ldap_search_base_title "Base de recherche (ne peut être vide)" Research base (can not be empty) - + settings_contacts_ldap_search_filter_title "Filtre" Filter - + settings_contacts_ldap_max_results_title "Nombre maximum de résultats" Max results - + settings_contacts_ldap_request_delay_title "Délai entre 2 requêtes (en millisecondes)" Delay between two queries (in milliseconds) - + settings_contacts_ldap_request_timeout_title "Durée maximun (en secondes)" Timeout (in seconds) - + settings_contacts_ldap_min_characters_title "Nombre minimum de caractères pour la requête" Minimum number of characters for the query - + settings_contacts_ldap_name_attributes_title "Attributs de nom" Name attributes - + settings_contacts_ldap_sip_attributes_title "Attributs SIP" SIP attributes - + settings_contacts_ldap_sip_domain_title "Domaine SIP" SIP domain - + settings_contacts_ldap_debug_title "Débogage" Debug @@ -3618,37 +3904,46 @@ Expiration : %1 LoginForm - + + username Nom d'utilisateur : username Username - + + password Mot de passe Password - + + mandatory_field_accessible_name + "%1 mandatory" + %1 mandatory + + + + assistant_account_login "Connexion" Connection - + assistant_account_login_missing_username "Veuillez saisir un nom d'utilisateur" Please enter a username - + assistant_account_login_missing_password "Veuillez saisir un mot de passe" Please enter a password - + assistant_forgotten_password "Mot de passe oublié ?" Forgotten password ? @@ -3657,44 +3952,44 @@ Expiration : %1 LoginLayout - - + + help_about_title À propos de %1 About %1 - + help_about_privacy_policy_title "Politique de confidentialité" Privacy Policy - + help_about_privacy_policy_link "Visiter notre potilique de confidentialité" Visit our privacy policy - + help_about_version_title "Version" Version - + help_about_licence_title "Licence" Licence - + help_about_copyright_title "Copyright Copyright - + close "Fermer" Close @@ -3703,60 +3998,66 @@ Expiration : %1 LoginPage - + + return_accessible_name + Return + Return + + + assistant_account_login Connexion Connection - + assistant_no_account_yet "Pas encore de compte ?" No account yet ? - + assistant_account_register "S'inscrire" Register - + assistant_login_third_party_sip_account_title "Compte SIP tiers" Third-party SIP account - + assistant_login_remote_provisioning "Configuration distante" Remote provisioning - + assistant_login_download_remote_config "Télécharger une configuration distante" Download a remote configuration - + assistant_login_remote_provisioning_url 'Veuillez entrer le lien de configuration qui vous a été fourni :' Please enter the setup link provided to you : - + cancel Cancel - + validate "Valider" Confirm - + settings_advanced_remote_provisioning_url 'Lien de configuration distante' Remote provisioning link @@ -3778,102 +4079,144 @@ Expiration : %1 MainLayout - + bottom_navigation_calls_label "Appels" Calls - + + open_calls_page_accessible_name + "Open calls page" + Open calls pages + + + bottom_navigation_contacts_label "Contacts" Contacts - + + open_contacts_page_accessible_name + "Open contacts page" + Open contacts page + + + bottom_navigation_conversations_label "Conversations" Conversations + open_conversations_page_accessible_name + "Open conversations page" + Open conversations page + + + bottom_navigation_meetings_label "Réunions" Meetings - + + open_contact_page_accessible_name + "Open meetings page" + Open meetings page + + + searchbar_placeholder_text "Rechercher un contact, appeler %1" Find contact, call %1 - + searchbar_placeholder_text_chat_feature_enabled "ou envoyer un message …" or send message … - - + + do_not_disturb_accessible_name + "Do not disturb" + Do not disturb + + + + contact_presence_status_disable_do_not_disturb "Désactiver ne pas déranger" Disable do not disturb - + information_popup_error_title Error - + no_voicemail_uri_error_message "L'URI de messagerie vocale n'est pas définie." The voicemail URI is not defined. - + + account_list_accessible_name + "Account list" + account list + + + + application_options_accessible_name + "Application options" + Application options + + + drawer_menu_manage_account Mon compte My account - + contact_presence_status_enable_do_not_disturb "Activer ne pas déranger" Enable do not disturb - + settings_title Settings - + recordings_title "Enregistrements" Records - + help_title "Aide" Help - + help_quit_title "Quitter l'application" Quit the app - + quit_app_question "Quitter %1 ?" Quit %1 ? - + drawer_menu_add_account "Ajouter un compte" Add an account @@ -3912,48 +4255,48 @@ Expiration : %1 Your correspondent has been transferred to the selected contact - + information_popup_success_title Saved - + information_popup_changes_saved "Les changements ont été sauvegardés" Changes have been saved - + captcha_validation_loading_message "Veuillez valider le captcha sur la page web" Please validate the captcha on the web page - + assistant_register_error_title "Erreur lors de la création" Error while creating - + assistant_register_success_title "Compte créé" Account created - + assistant_register_success_message "Le compte a été créé. Vous pouvez maintenant vous connecter" The account has been created. You can now log in. - + assistant_register_error_code "Erreur dans le code de validation" Error in validation code - + information_popup_error_title Error @@ -3993,13 +4336,13 @@ Expiration : %1 Add a description - + meeting_schedule_add_participants_title "Ajouter des participants" Add participants - + meeting_schedule_send_invitations_title "Envoyer une invitation aux participants" Send an invitation to participants @@ -4293,25 +4636,47 @@ Expiration : %1 MultimediaSettings - + + multimedia_settings_ringer_title Ringtone - Incoming calls Ringtone - Incoming calls - + + + + + choose_something_accessible_name + Choose %1 + Choose %1 + + + + + multimedia_settings_speaker_title "Haut-parleurs" Speakers - + + + device_volume_accessible_name + %1 volume + %1 volume + + + + + multimedia_settings_microphone_title "Microphone" Microphone - + + multimedia_settings_camera_title "Caméra" Camera @@ -4380,28 +4745,40 @@ Expiration : %1 Notifier - + + new_call_alert_accessible_name + New call from %1 + New call from %1 + + + new_voice_message 'Voice message received!' : message to warn the user in a notofication for voice messages. Voice message received! - + new_file_message File received! - + new_conference_invitation 'Conference invitation received!' : Notification about receiving an invitation to a conference. Conference invitation received ! - + new_chat_room_messages 'New messages received!' Notification that warn the user of new messages. New messages received ! + + + new_message_alert_accessible_name + New message on chatroom %1 + New message on chatroom %1 + OIDCModel @@ -4533,30 +4910,60 @@ Expiration : %1 Add participants + + PhoneNumberInput + + + prefix_phone_number_accessible_name + %1 prefix + %1 prefix + + + + number_phone_number_accessible_name + %1 number + %1 number + + + + PopupButton + + + close_popup_panel_accessible_name + "Close %1 popup" + Close %1 popup + + + + open_popup_panel_accessible_name + "Open %1" popup + Open %1 popup + + Presence - + contact_presence_reset_status Reset status - + contact_presence_button_set_custom_status Set - + contact_presence_button_edit_custom_status Edit - + contact_presence_button_delete_custom_status Delete - + contact_presence_custom_status Custom status @@ -4738,109 +5145,135 @@ Expiration : %1 RegisterPage - + + return_accessible_name + Return + Return + + + assistant_account_register "Inscription Register - + assistant_already_have_an_account Already have an account ? - + assistant_account_login Connection - + assistant_account_register_with_phone_number Register with a phone number - + assistant_account_register_with_email Register with email - + + username Username - - + + + + + + mandatory_field_accessible_name + "%1 mandatory" + %1 mandatory + + + + domain + Domain + + + + + phone_number "Numéro de téléphone" Phone number - + + email Email - + + password Password - + + assistant_account_register_password_confirmation "Confirmation mot de passe" Password confirmation - + assistant_dialog_cgu_and_privacy_policy_message "J'accepte les %1 et la %2" I accept the %1 and the %2 - + assistant_dialog_general_terms_label "conditions d'utilisation" terms of use - + assistant_dialog_privacy_policy_label "politique de confidentialité" privacy policy - + assistant_account_create "Créer" Create - + assistant_account_create_missing_username_error "Veuillez entrer un nom d'utilisateur" Please enter a username - + assistant_account_create_missing_password_error "Veuillez entrer un mot de passe" Please enter a password - + assistant_account_create_confirm_password_error "Les mots de passe sont différents" Passwords do not match - + assistant_account_create_missing_number_error "Veuillez entrer un numéro de téléphone" Please enter a phone number - + assistant_account_create_missing_email_error "Veuillez entrer un email" Please enter an email @@ -4849,25 +5282,31 @@ Expiration : %1 SIPLoginPage - + + return_accessible_name + Return + Return + + + assistant_login_third_party_sip_account_title Compte SIP tiers Third-party SIP account - + assistant_no_account_yet Pas encore de compte ? No account yet ? - + assistant_account_register S'inscrire Register - + Certaines fonctionnalités telles que les conversations de groupe, les vidéo-conférences, etc… nécessitent un compte %1. Ces fonctionnalités seront masquées si vous utilisez un compte SIP tiers. @@ -4880,93 +5319,108 @@ These features will be hidden if you use a third-party SIP account. To enable them in a commercial project, please contact us. - + assistant_third_party_sip_account_create_linphone_account "Créer un compte linphone" Create a linphone account - + assistant_third_party_sip_account_warning_ok "Je comprends" I understand - + + username "Nom d'utilisateur" Username - + + + mandatory_field_accessible_name + "%1 mandatory" + %1 mandatory + + + + password Password - + + sip_address_domain "Domaine" Domain - + + sip_address_display_name Nom d'affichage Display name - + + transport "Transport" Transport - + + assistant_account_login Connection - + assistant_account_login_missing_username Please enter a username - + assistant_account_login_missing_password Please enter a password - + assistant_account_login_missing_domain "Veuillez saisir un nom de domaine Please enter a domain - + login_advanced_parameters_label Advanced parameters Advanced parameters - + + login_proxy_server_url "Outbound SIP Proxy URI" Outbound SIP Proxy URI - + login_proxy_server_url_tooltip "If this field is filled, the outbound proxy will be enabled automatically. Leave it empty to disable it." If this field is filled, the outbound proxy will be enabled automatically. Leave it empty to disable it. - + login_registrar_uri "Registrar URI" Registrar URI - + + login_id "Authentication ID (if different)" Authentication ID (if different) @@ -5011,6 +5465,21 @@ To enable them in a commercial project, please contact us. Share + + SearchBar + + + open_dialer_acccessibility_label + "Open dialer" + Open dialer + + + + clear_text_input_acccessibility_label + "Clear text input" + Clear text input + + SecurityModePage @@ -5068,7 +5537,7 @@ To enable them in a commercial project, please contact us. settings_security_enable_vfs_subtitle "Attention, vous ne pourrez pas revenir en arrière !" - Warning: once enabled it can\'t be disabled! + Warning: once enabled it can't be disabled! @@ -5109,6 +5578,15 @@ To enable them in a commercial project, please contact us. Conversations + + SettingsMenuItem + + + setting_tab_accessible_name + %1 settings + %1 settings + + SettingsPage @@ -5204,6 +5682,21 @@ To enable them in a commercial project, please contact us. Paused + + TextField + + + show_accessible_name + Show %1 + Show %1 + + + + hide_accessible_name + Hide %1 + Hide %1 + + ToolModel @@ -6774,7 +7267,7 @@ Failed to create 1-1 conversation with %1 ! utils - + formatYears '%1 year' @@ -6783,7 +7276,7 @@ Failed to create 1-1 conversation with %1 ! - + formatMonths '%1 month' @@ -6792,7 +7285,7 @@ Failed to create 1-1 conversation with %1 ! - + formatWeeks '%1 week' @@ -6801,7 +7294,7 @@ Failed to create 1-1 conversation with %1 ! - + formatDays '%1 day' @@ -6810,7 +7303,7 @@ Failed to create 1-1 conversation with %1 ! - + formatHours '%1 hour' @@ -6819,7 +7312,7 @@ Failed to create 1-1 conversation with %1 ! - + formatMinutes '%1 minute' @@ -6828,7 +7321,7 @@ Failed to create 1-1 conversation with %1 ! - + formatSeconds '%1 second' @@ -6837,62 +7330,62 @@ Failed to create 1-1 conversation with %1 ! - + codec_install "Installation de codec" Codec installation - + download_codec "Télécharger le codec %1 (%2) ?" Download codec %1 (%2) ? - + information_popup_success_title "Succès" Success - + information_popup_codec_install_success_text "Le codec a été installé avec succès." The codec has been successfully installed. - - - + + + information_popup_error_title Error - + information_popup_codec_install_error_text "Le codec n'a pas pu être installé." The codec could not be installed. - + information_popup_codec_save_error_text "Le codec n'a pas pu être sauvegardé." The codec could not be saved. - + information_popup_codec_download_error_text "Le codec n'a pas pu être téléchargé." The codec could not be downloaded. - + loading_popup_codec_install_progress "Téléchargement en cours …" Download in progress… - + okButton Ok diff --git a/Linphone/data/languages/fr_FR.ts b/Linphone/data/languages/fr_FR.ts index 95d5324b0..ec07833d7 100644 --- a/Linphone/data/languages/fr_FR.ts +++ b/Linphone/data/languages/fr_FR.ts @@ -4,11 +4,23 @@ AbstractSettingsLayout - + + return_accessible_name + Return + Retour + + + save "Enregistrer" Enregistrer + + + save_settings_accessible_name + Save %1 settings + Sauvegarder les paramètres %1 + AbstractWindow @@ -27,45 +39,45 @@ AccountCore - + drawer_menu_account_connection_status_connected "Connecté" Connecté - + drawer_menu_account_connection_status_refreshing En cours de rafraîchissement… - + drawer_menu_account_connection_status_progress Connexion… - + drawer_menu_account_connection_status_failed Erreur - + drawer_menu_account_connection_status_cleared Désactivé - + manage_account_status_connected_summary "Vous êtes en ligne et joignable." Vous êtes en ligne et joignable. - + manage_account_status_failed_summary "Erreur de connexion, vérifiez vos paramètres." Erreur de connexion, vérifiez vos paramètres. - + manage_account_status_cleared_summary "Compte désactivé, vous ne recevrez ni appel ni message." Compte désactivé, vous ne recevrez ni appel ni message. @@ -80,6 +92,15 @@ Erreur lors de la récupération des appareils + + AccountListView + + + add_an_account + Add an account + Ajouter un compte + + AccountManager @@ -464,13 +485,13 @@ AddParticipantsForm - + search_bar_search_contacts_placeholder "Rechercher des contacts" Rechercher des contacts - + add_participant_selected_count 0 "%n participant(s) sélectionné(s)" @@ -480,13 +501,19 @@ - + + remove_participant_accessible_name + Remove participant %1 + Retirer le participant %1 + + + list_filter_no_result_found "Aucun contact" Aucun résultat… - + contact_list_empty Aucun contact @@ -553,25 +580,32 @@ Format d'url invalide - + + download_apply_remote_provisioning_accessible_name + "Download and apply remote provisioning" + Télécharger et appliquer la configuration distante + + + + settings_advanced_media_encryption_title Media encryption Chiffrement du média - + settings_advanced_media_encryption_mandatory_title Media encryption mandatory Chiffrement du média obligatoire - + settings_advanced_create_endtoend_encrypted_meetings_title Create end to end encrypted meetings and group calls Créer des appels de groupe et conférences chiffré(e)s de bout en bout - + settings_advanced_hide_fps_title Cacher les FPS @@ -600,94 +634,94 @@ App - + remote_provisioning_dialog Voulez-vous télécharger et appliquer la configuration depuis cette adresse ? Voulez-vous télécharger et appliquer la configuration depuis cette adresse ? - - + + info_popup_error_title Error Erreur - - + + info_popup_configuration_failed_message Remote provisioning failed : %1 La configuration distante a échoué : %1 - + configuration_error_detail not reachable indisponible - + application_description "A free and open source SIP video-phone." A free and open source SIP video-phone. - + command_line_arg_order "Send an order to the application towards a command line" Send an order to the application towards a command line - + command_line_option_show_help Show this help - + command_line_option_show_app_version Afficher la version de l'application - + command_line_option_config_to_fetch "Specify the linphone configuration file to be fetched. It will be merged with the current configuration." Specify the linphone configuration file to be fetched. It will be merged with the current configuration. - + command_line_option_config_to_fetch_arg "URL, path or file" URL, path or file - + command_line_option_minimized Minimiser - + command_line_option_log_to_stdout Log to stdout some debug information while running - + command_line_option_print_app_logs_only "Print only logs from the application" Print only logs from the application - + hide_action "Cacher" "Afficher" Cacher - + show_action Afficher - + quit_action "Quitter" Quitter @@ -910,6 +944,15 @@ Appel Vidéo + + CallHistoryListView + + + call_name_accessible_button + Call %1 + Appeler %1 + + CallLayout @@ -957,29 +1000,53 @@ CallListView - + meeting "Réunion Réunion - + call "Appel" Appel - + paused_call_or_meeting "%1 en pause" %1 en pause - + ongoing_call_or_meeting "%1 en cours" %1 en cours + + + transfer_call_name_accessible_name + Transfer call %1 + Transférer l'appel %1 + + + + resume_call_name_accessible_name + Resume %1 call + Reprendre l'appel %1 + + + + pause_call_name_accessible_name + Pause %1 call + Mettre l'appel %1 en pause + + + + end_call_name_accessible_name + End %1 call + Terminer l'appel %1 + CallModel @@ -1095,127 +1162,150 @@ Appels - - + + call_history_options_accessible_name + Options de l' + + + + menu_delete_history "Supprimer l'historique" Supprimer l'historique - + + call_history_list_options_accessible_name + Call history options + Options de la liste de l'historique d'appel + + + + create_new_call_accessible_name + Create new call + Créer un nouvel appel + + + call_search_in_history "Rechercher un appel" Rechercher un appel - + call_forward_to_address_info Transférer l'appel à : - + call_forward_to_address_info_voicemail Boîte vocale - + list_filter_no_result_found "Aucun résultat…" Aucun résultat… - + history_list_empty_history "Aucun appel dans votre historique" Aucun appel dans votre historique - + + return_to_call_history_accessible_name + Return to call history + Retourner à l'historique d'appels + + + call_action_start_new_call "Nouvel appel" Nouvel appel - + call_start_group_call_title "Appel de groupe" Appel de groupe - + call_action_start_group_call "Lancer" Lancer - - - + + + information_popup_error_title Erreur - + group_call_error_must_have_name "Un nom doit être donné à l'appel de groupe Un nom doit être donné à l'appel de groupe - + group_call_error_not_connected "Vous n'etes pas connecté" Vous n'etes pas connecté - + menu_see_existing_contact "Show contact" Voir le contact - + menu_add_address_to_contacts "Add to contacts" Ajouter aux contacts - + menu_copy_sip_address "Copier l'adresse SIP" Copier l'adresse SIP - + sip_address_copied_to_clipboard_toast Adresse copiée Adresse copiée - + sip_address_copied_to_clipboard_message L'adresse a été copié dans le presse_papiers L'adresse a été copié dans le presse-papiers - + sip_address_copy_to_clipboard_error "Erreur lors de la copie de l'adresse" Erreur lors de la copie de l'adresse - + notification_missed_call_title "Appel manqué" Appel manqué - + call_outgoing "Appel sortant" Appel sortant - + call_audio_incoming "Appel entrant" Appel entrant @@ -1294,6 +1384,21 @@ Current ringtone : Sonnerie actuelle : + + + choose_ringtone_file_accessible_name + Choose ringtone file + Choisir le ficher de sonnerie + + + + CallSettingsPanel + + + close_name_panel_accessible_button + Close %1 panel + Fermer le panneau %1 + CallStatistics @@ -1313,236 +1418,236 @@ CallsWindow - + call_transfer_in_progress_toast "Transfert en cours, veuillez patienter" Transfert en cours, veuillez patienter - - + + information_popup_error_title Erreur - + call_transfer_failed_toast "Le transfert d'appel a échoué" Le transfert d'appel a échoué - + conference_error_empty_uri "La conférence n'a pas pu démarrer en raison d'une erreur d'uri." La conférence n'a pas pu démarrer en raison d'une erreur d'uri. - + call_close_window_dialog_title "Terminer tous les appels en cours ?" Terminer tous les appels en cours ? - + call_close_window_dialog_message "La fenêtre est sur le point d'être fermée. Cela terminera tous les appels en cours." La fenêtre est sur le point d'être fermée. Cela terminera tous les appels en cours. - + call_can_be_trusted_toast "Appareil authentifié" Appareil authentifié - + call_dir Appel %1 - + call_ended Appel terminé Appel terminé - + conference_paused Meeting paused Réunion mise en pause - + call_paused Call paused Appel mis en pause - - + + call_srtp_point_to_point_encrypted Appel chiffré de point à point Appel chiffré de point à point - + call_zrtp_sas_validation_required Vérification nécessaire Vérification nécessaire - + call_zrtp_end_to_end_encrypted Appel chiffré de bout en bout Appel chiffré de bout en bout - + call_not_encrypted "Appel non chiffré" Appel non chiffré - - + + call_waiting_for_encryption_info Waiting for encryption En attente de chiffrement - + call_paused_by_remote Call paused by remote Appel mis en pause par votre correspondant - + conference_user_is_recording "You are recording the meeting" Vous enregistrez la réunion - + call_user_is_recording "You are recording the call" Vous enregistrez l'appel - + conference_remote_is_recording "Someone is recording the meeting" Un participant enregistre la réunion - + call_remote_recording "%1 is recording the call" %1 enregistre l'appel - + call_stop_recording "Stop recording" Arrêter l'enregistrement - + add Ajouter - + call_transfer_current_call_title "Transférer %1 à…" Transférer %1 à… - - + + call_transfer_confirm_dialog_tittle "Confirmer le transfert" Confirmer le transfert - - + + call_transfer_confirm_dialog_message "Vous allez transférer %1 à %2." Vous allez transférer %1 à %2. - + call_action_start_new_call "Nouvel appel" Nouvel appel - - + + call_action_show_dialer "Pavé numérique" Pavé numérique - + call_action_change_layout "Modifier la disposition" Modifier la disposition - + call_action_go_to_calls_list "Liste d'appel" Liste d'appel - + Merger tous les appels call_action_merge_calls Merger tous les appels - - + + call_action_go_to_settings "Paramètres" Paramètres - + conference_action_screen_sharing "Partage de votre écran" Partage de votre écran - + conference_share_link_title Partager le lien de la réunion Partager le lien de la réunion - + copied Copié Copié - + information_popup_meeting_address_copied_to_clipboard Le lien de la réunion a été copié dans le presse-papier Le lien de la réunion a été copié dans le presse-papier - - - + + + conference_participants_list_title "Participants (%1)" Participants (%1) - - + + group_call_participant_selected %1 participant sélectionné @@ -1550,161 +1655,194 @@ - + meeting_schedule_add_participants_title Ajouter des participants - + call_encryption_title Chiffrement Chiffrement - + + open_statistic_panel_accessible_name + Ouvrir le panneau de statistiques + + + conference_user_is_sharing_screen "You are sharing your screen" Vous partagez votre écran - + call_stop_screen_sharing "Stop sharing" Arrêter le partage - + + stop_recording_accessible_name + Stop recording + Arrêter l'enregistrement + + + + stop_screen_sharing_accessible_name + "Stop screen sharing" + Arrêter le partage d'écran + + + call_stats_title Statistiques Statistiques - + + call_action_end_call "Terminer l'appel" Terminer l'appel - + + call_action_resume_call "Reprendre l'appel" Reprendre l'appel - + + call_action_pause_call "Mettre l'appel en pause" Mettre l'appel en pause - + + call_action_transfer_call "Transférer l'appel" Transférer l'appel - + + call_action_start_new_call_hint "Initier un nouvel appel" Initier un nouvel appel - + + call_display_call_list_hint "Afficher la liste d'appels" Afficher la liste d'appels - + + call_deactivate_video_hint "Désactiver la vidéo" "Activer la vidéo" Désactiver la vidéo - + + call_activate_video_hint Activer la vidéo - + + call_activate_microphone "Activer le micro" Activer le micro - + + call_deactivate_microphone "Désactiver le micro" Désactiver le micro - + + call_share_screen_hint Partager l'écran… Partager l'écran… - + + call_open_chat_hint Open chat… Ouvrir le chat… - + + call_rise_hand_hint "Lever la main" Lever la main - + + call_send_reaction_hint "Envoyer une réaction" Envoyer une réaction - + + call_manage_participants_hint "Gérer les participants" Gérer les participants - + + call_more_options_hint "Plus d'options…" Plus d'options… - + call_action_change_conference_layout "Modifier la disposition" Modifier la disposition - + call_action_full_screen "Mode Plein écran" Mode Plein écran - + call_action_stop_recording "Terminer l'enregistrement" Terminer l'enregistrement - + call_action_record "Enregistrer l'appel" Enregistrer l'appel - + call_activate_speaker_hint "Activer le son" Activer le son - + call_deactivate_speaker_hint "Désactiver le son" Désactiver le son @@ -1856,7 +1994,7 @@ Dites quelque chose… - + cannot_record_while_in_call_tooltip Cannot record a message while a call is ongoing Impossible d'enregistrer un message vocal pendant un appel @@ -1932,25 +2070,25 @@ ChatMessage - + chat_message_copy_selection "Copy selection" Copier la sélection - + chat_message_copy "Copy" Copier - + chat_message_copied_to_clipboard_title Copied Copié - + chat_message_copied_to_clipboard_toast "to clipboard" dans le presse-papiers @@ -1986,25 +2124,25 @@ Vous avez répondu - + chat_message_reception_info "Reception info" Info de réception - + chat_message_reply Reply Répondre - + chat_message_forward Forward Transférer - + chat_message_delete "Delete" Supprimer @@ -2389,102 +2527,166 @@ en bout. Seul votre correspondant peut les déchiffrer. Contact - + information_popup_error_title Erreur Erreur - + information_popup_voicemail_address_undefined_message L'URI de messagerie vocale n'est pas définie. L'URI de messagerie vocale n'est pas définie. + + + account_settings_name_accessible_name + Account settings of %1 + Paramaètres de compte de %1 + ContactEdition - + contact_editor_title "Modifier contact" Modifier contact - + save "Enregistrer Enregistrer - - + + contact_editor_dialog_cancel_change_message "Les changements seront annulés. Souhaitez-vous continuer ?" Les changements seront annulés. Souhaitez-vous continuer ? - + + close_accessible_name + Close %n + Fermer %n + + + contact_editor_mandatory_first_name_or_company_not_filled "Veuillez saisir un prénom ou un nom d'entreprise" Veuillez saisir un prénom ou un nom d'entreprise - + contact_editor_mandatory_address_or_number_not_filled "Veuillez saisir une adresse ou un numéro de téléphone" Veuillez saisir une adresse ou un numéro de téléphone - + contact_editor_add_image_label "Ajouter une image" Ajouter une image - + contact_details_edit "Modifier" Modifier - + + edit_contact_image_accessible_name + "Edit contact image" + + + + contact_details_delete "Supprimer" Supprimer - + + delete_contact_image_accessible_name + "Delete contact image" + Supprimer l'image du contact + + + + contact_editor_first_name "Prénom" Prénom - + + contact_editor_last_name "Nom" Nom - + + contact_editor_company "Entreprise" Entreprise - + + contact_editor_job_title "Fonction" Fonction - - + + sip_address Adresse SIP - - + + sip_address_number_accessible_name + "SIP address number %1" + Adresse SIP numéro + + + + remove_sip_address_accessible_name + "Remove SIP address %1" + Retirer l'adresse SIP + + + + new_sip_address_accessible_name + "New SIP address" + Nouvelle adresse SIP + + + + phone_number_number_accessible_name + "Phone number number %1" + Numéro de téléphone numéro + + + + remove_phone_number_accessible_name + Remove phone number %1 + Retirer le numéro de téléphone + + + + new_phone_number_accessible_name + "New phone number" + Nouveau numéro de téléphone + + + + phone "Téléphone" Téléphone @@ -2493,58 +2695,73 @@ en bout. Seul votre correspondant peut les déchiffrer. ContactListItem - + contact_details_remove_from_favourites "Enlever des favoris" Enlever des favoris - + contact_details_add_to_favourites "Ajouter aux favoris" Ajouter aux favoris - + Partager Partager - + information_popup_error_title Erreur - + information_popup_vcard_creation_error La création du fichier vcard a échoué La création du fichier vcard a échoué - + information_popup_vcard_creation_title VCard créée VCard créée - + information_popup_vcard_creation_success "VCard du contact enregistrée dans %1" VCard du contact enregistrée dans %1 - + contact_sharing_email_title Partage de contact Partage de contact - + contact_details_delete "Supprimer" Supprimer + + ContactListView + + + shrink_accessible_name + Shrink %1 + Réduire %1 + + + + expand_accessible_name + Expand %1 + Étendre %1 + + ContactPage @@ -2659,26 +2876,50 @@ en bout. Seul votre correspondant peut les déchiffrer. Contacts - + search_bar_look_for_contact_text Rechercher un contact Rechercher un contact - + list_filter_no_result_found Aucun résultat… Aucun résultat… - + contact_list_empty Aucun contact pour le moment Aucun contact pour le moment - - + + expand_accessible_name + Expand %1 + Étendre %1 + + + + shrink_accessible_name + Shrink %1 + Réduire + + + + create_contact_accessible_name + Create new contact + Créer un nouveau contact + + + + more_info_accessible_name + More info %1 + Plus d'information + + + + contact_details_edit Edit ---------- @@ -2686,138 +2927,151 @@ en bout. Seul votre correspondant peut les déchiffrer. Éditer - + contact_call_action "Appel" Appel - + contact_message_action "Message" Message - + contact_video_call_action "Appel vidéo" Appel vidéo - + contact_details_numbers_and_addresses_title "Coordonnées" Coordonnées - + + call_adress_accessible_name + Call address %1 + Appeller l'adresse %1 + + + contact_details_company_name "Société :" Société : - + contact_details_job_title "Poste :" Poste : - + contact_details_medias_title "Medias" Medias - + + contact_details_medias_subtitle "Afficher les medias partagés" Afficher les medias partagés - + contact_details_trust_title "Confiance" Confiance - + contact_dialog_devices_trust_title "Niveau de confiance - Appareils vérifiés" Niveau de confiance - Appareils vérifiés - + contact_details_no_device_found "Aucun appareil" Aucun appareil - + contact_device_without_name "Appareil inconnu" Appareil inconnu - + contact_make_call_check_device_trust "Vérifier" Vérifier - + + verify_device_accessible_name + Verify %1 device + Vérifier l'appareil %1 + + + contact_details_actions_title "Autres actions" Autres actions - + contact_details_remove_from_favourites "Retirer des favoris" Retirer des favoris - + contact_details_add_to_favourites "Ajouter aux favoris" Ajouter aux favoris - + contact_details_share "Partager" Partager - + information_popup_error_title Erreur - + contact_details_share_error_mesage "La création du fichier vcard a échoué" La création du fichier vcard a échoué - + contact_details_share_success_title "VCard créée" VCard créée - + contact_details_share_success_mesage "VCard du contact enregistrée dans %1" VCard du contact enregistrée dans %1 - + contact_details_share_email_title "Partage de contact" Partage de contact - + contact_details_delete "Supprimer ce contact" Supprimer ce contact @@ -2860,33 +3114,57 @@ en bout. Seul votre correspondant peut les déchiffrer. Modifier un annuaire LDAP - + + edit_ldap_server_accessible_name + "Editer le serveur LDAP %1" + Editer le serveur LDAP %1 + + + + use_ldap_server_accessible_name + "Utiliser le serveur LDAP %1" + Utiliser le serveur LDAP %1 + + + settings_contacts_add_carddav_server_title "Ajouter un carnet d'adresse CardDAV" Ajouter un carnet d'adresse CardDAV - + settings_contacts_edit_carddav_server_title "Modifier un carnet d'adresse CardDAV" Modifier un carnet d'adresse CardDAV + + + edit_cardav_server_accessible_name + "Editer le carnet d'adresses CardDAV %1" + Editer le carnet dl'adresses CardDAV %1 + + + + use_cardav_server_accessible_name + "Utiliser le d'adresses CardDAV %1" + Utiliser le carnet dl'adresses CardDAV %1 + ContactsSettingsProviderLayout - + information_popup_success_title Succès - + information_popup_changes_saved "Les changements ont été sauvegardés" Les changements ont été sauvegardés - + add "Ajouter" Ajouter @@ -3035,7 +3313,7 @@ en bout. Seul votre correspondant peut les déchiffrer. CreationFormLayout - + search_bar_look_for_contact_text "Rechercher un contact" Rechercher un contact @@ -3413,13 +3691,20 @@ Expiration : %1 GroupCreationFormLayout - + + return_accessible_name + Return + Retour + + + + group_start_dialog_subject_hint "Nom du groupe" Nom du groupe - + required "Requis" Requis @@ -3480,123 +3765,129 @@ Expiration : %1 LdapSettingsLayout - + settings_contacts_ldap_title Annuaires LDAP - + settings_contacts_ldap_subtitle Ajouter vos annuaires LDAP pour pouvoir effectuer des recherches dans la magic search bar. - + information_popup_success_title Succès - + settings_contacts_ldap_success_toast "L'annuaire LDAP a été sauvegardé" L'annuaire LDAP a été sauvegardé - + settings_contacts_ldap_error_toast "Une erreur s'est produite, la configuration LDAP n'a pas été sauvegardée !" Erreur - + information_popup_error_title Une erreur s'est produite, la configuration LDAP n'a pas été sauvegardée ! - + settings_contacts_ldap_delete_confirmation_message "Supprimer l'annuaire LDAP ?" Supprimer l'annuaire LDAP ? - + + delete_ldap_server_accessible_name + Delete LDAP server + Supprimer le serveur LDAP + + + settings_contacts_ldap_server_url_title "URL du serveur (ne peut être vide)" URL du serveur (ne peut être vide) - + settings_contacts_ldap_bind_dn_title "Bind DN" Bind DN - + settings_contacts_ldap_password_title "Mot de passe" Mot de passe - + settings_contacts_ldap_use_tls_title "Utiliser TLS" Utiliser TLS - + settings_contacts_ldap_search_base_title "Base de recherche (ne peut être vide)" Base de recherche (ne peut être vide) - + settings_contacts_ldap_search_filter_title "Filtre" Filtre - + settings_contacts_ldap_max_results_title "Nombre maximum de résultats" Nombre maximum de résultats - + settings_contacts_ldap_request_delay_title "Délai entre 2 requêtes (en millisecondes)" Délai entre 2 requêtes (en millisecondes) - + settings_contacts_ldap_request_timeout_title "Durée maximun (en secondes)" Durée maximun (en secondes) - + settings_contacts_ldap_min_characters_title "Nombre minimum de caractères pour la requête" Nombre minimum de caractères pour la requête - + settings_contacts_ldap_name_attributes_title "Attributs de nom" Attributs de nom - + settings_contacts_ldap_sip_attributes_title "Attributs SIP" Attributs SIP - + settings_contacts_ldap_sip_domain_title "Domaine SIP" Domaine SIP - + settings_contacts_ldap_debug_title "Débogage" Débogage @@ -3613,37 +3904,46 @@ Expiration : %1 LoginForm - + + username Nom d'utilisateur : username Nom d'utilisateur - + + password Mot de passe Mot de passe - + + mandatory_field_accessible_name + "%1 mandatory" + %1 requit + + + + assistant_account_login "Connexion" Connexion - + assistant_account_login_missing_username "Veuillez saisir un nom d'utilisateur" Veuillez saisir un nom d'utilisateur - + assistant_account_login_missing_password "Veuillez saisir un mot de passe" Veuillez saisir un mot de passe - + assistant_forgotten_password "Mot de passe oublié ?" Mot de passe oublié ? @@ -3652,44 +3952,44 @@ Expiration : %1 LoginLayout - - + + help_about_title À propos de %1 À propos de %1 - + help_about_privacy_policy_title "Politique de confidentialité" Politique de confidentialité - + help_about_privacy_policy_link "Visiter notre potilique de confidentialité" Visiter notre potilique de confidentialité - + help_about_version_title "Version" Version - + help_about_licence_title "Licence" Licence - + help_about_copyright_title "Copyright Copyright - + close "Fermer" Fermer @@ -3698,60 +3998,66 @@ Expiration : %1 LoginPage - + + return_accessible_name + Return + Retour + + + assistant_account_login Connexion Connexion - + assistant_no_account_yet "Pas encore de compte ?" Pas encore de compte ? - + assistant_account_register "S'inscrire" S'inscrire - + assistant_login_third_party_sip_account_title "Compte SIP tiers" Compte SIP tiers - + assistant_login_remote_provisioning "Configuration distante" Configuration distante - + assistant_login_download_remote_config "Télécharger une configuration distante" Télécharger une configuration distante - + assistant_login_remote_provisioning_url 'Veuillez entrer le lien de configuration qui vous a été fourni :' Veuillez entrer le lien de configuration qui vous a été fourni : - + cancel Annuler - + validate "Valider" Valider - + settings_advanced_remote_provisioning_url 'Lien de configuration distante' Lien de configuration distante @@ -3773,102 +4079,144 @@ Expiration : %1 MainLayout - + bottom_navigation_calls_label "Appels" Appels - + + open_calls_page_accessible_name + "Open calls page" + Ouvrir la page des appels + + + bottom_navigation_contacts_label "Contacts" Contacts - + + open_contacts_page_accessible_name + "Open contacts page" + Ouvrir la page des contacts + + + bottom_navigation_conversations_label "Conversations" Conversations + open_conversations_page_accessible_name + "Open conversations page" + Ouvrir la page des conversations + + + bottom_navigation_meetings_label "Réunions" Réunions - + + open_contact_page_accessible_name + "Open meetings page" + Ouvrir la page des réunions + + + searchbar_placeholder_text "Rechercher un contact, appeler %1" Rechercher un contact, appeler %1 - + searchbar_placeholder_text_chat_feature_enabled "ou envoyer un message …" ou envoyer un message … - - + + do_not_disturb_accessible_name + "Do not disturb" + Ne pas déranger + + + + contact_presence_status_disable_do_not_disturb "Désactiver ne pas déranger" Désactiver ne pas déranger - + information_popup_error_title Erreur - + no_voicemail_uri_error_message "L'URI de messagerie vocale n'est pas définie." L'URI de messagerie vocale n'est pas définie. - + + account_list_accessible_name + "Account list" + liste des comptes + + + + application_options_accessible_name + "Application options" + Options de l'application + + + drawer_menu_manage_account Mon compte Mon compte - + contact_presence_status_enable_do_not_disturb "Activer ne pas déranger" Activer ne pas déranger - + settings_title Paramètres - + recordings_title "Enregistrements" Enregistrements - + help_title "Aide" Aide - + help_quit_title "Quitter l'application" Quitter l'application - + quit_app_question "Quitter %1 ?" Quitter %1 ? - + drawer_menu_add_account "Ajouter un compte" Ajouter un compte @@ -3907,48 +4255,48 @@ Expiration : %1 Votre correspondant a été transféré au contact sélectionné - + information_popup_success_title Enregistré - + information_popup_changes_saved "Les changements ont été sauvegardés" Les changements ont été sauvegardés - + captcha_validation_loading_message "Veuillez valider le captcha sur la page web" Veuillez valider le captcha sur la page web - + assistant_register_error_title "Erreur lors de la création" Erreur lors de la création - + assistant_register_success_title "Compte créé" Compte créé - + assistant_register_success_message "Le compte a été créé. Vous pouvez maintenant vous connecter" Le compte a été créé. Vous pouvez maintenant vous connecter - + assistant_register_error_code "Erreur dans le code de validation" Erreur dans le code de validation - + information_popup_error_title Erreur @@ -3988,13 +4336,13 @@ Expiration : %1 Ajouter une description - + meeting_schedule_add_participants_title "Ajouter des participants" Ajouter des participants - + meeting_schedule_send_invitations_title "Envoyer une invitation aux participants" Envoyer une invitation aux participants @@ -4288,25 +4636,47 @@ Expiration : %1 MultimediaSettings - + + multimedia_settings_ringer_title Ringtone - Incoming calls Sonnerie - Appels entrants - + + + + + choose_something_accessible_name + Choose %1 + Sélection + + + + + multimedia_settings_speaker_title "Haut-parleurs" Haut-parleurs - + + + device_volume_accessible_name + %1 volume + %1 volume + + + + + multimedia_settings_microphone_title "Microphone" Microphone - + + multimedia_settings_camera_title "Caméra" Caméra @@ -4375,28 +4745,40 @@ Expiration : %1 Notifier - + + new_call_alert_accessible_name + New call from %1 + Nouvel appel de %1 + + + new_voice_message 'Voice message received!' : message to warn the user in a notofication for voice messages. Message vocal reçu ! - + new_file_message Fichier reçu ! - + new_conference_invitation 'Conference invitation received!' : Notification about receiving an invitation to a conference. Nouvelle invitation à une conférence ! - + new_chat_room_messages 'New messages received!' Notification that warn the user of new messages. Nouveaux messages reçus ! + + + new_message_alert_accessible_name + New message on chatroom %1 + Nouveau message sur la conversation %1 + OIDCModel @@ -4528,30 +4910,60 @@ Expiration : %1 Ajouter des participants + + PhoneNumberInput + + + prefix_phone_number_accessible_name + %1 prefix + + + + + number_phone_number_accessible_name + %1 number + %1 indicatif téléphonique + + + + PopupButton + + + close_popup_panel_accessible_name + "Close %1 popup" + Femer la %1 popup + + + + open_popup_panel_accessible_name + "Open %1" popup + Ouvrir la %1 popup + + Presence - + contact_presence_reset_status Réinitialiser le statut - + contact_presence_custom_status Statut personnalisé - + contact_presence_button_set_custom_status Définir - + contact_presence_button_edit_custom_status Editer - + contact_presence_button_delete_custom_status Supprimer @@ -4733,109 +5145,135 @@ Expiration : %1 RegisterPage - + + return_accessible_name + Return + Retour + + + assistant_account_register "Inscription Inscription - + assistant_already_have_an_account Déjà un compte ? - + assistant_account_login Connexion - + assistant_account_register_with_phone_number S'inscrire avec un numéro de téléphone - + assistant_account_register_with_email S'inscrire avec un email - + + username Nom d'utilisateur - - + + + + + + mandatory_field_accessible_name + "%1 mandatory" + %1 requit + + + + domain + Domaine + + + + + phone_number "Numéro de téléphone" Numéro de téléphone - + + email Email - + + password Mot de passe - + + assistant_account_register_password_confirmation "Confirmation mot de passe" Confirmation mot de passe - + assistant_dialog_cgu_and_privacy_policy_message "J'accepte les %1 et la %2" J'accepte les %1 et la %2 - + assistant_dialog_general_terms_label "conditions d'utilisation" conditions d'utilisation - + assistant_dialog_privacy_policy_label "politique de confidentialité" politique de confidentialité - + assistant_account_create "Créer" Créer - + assistant_account_create_missing_username_error "Veuillez entrer un nom d'utilisateur" Veuillez entrer un nom d'utilisateur - + assistant_account_create_missing_password_error "Veuillez entrer un mot de passe" Veuillez entrer un mot de passe - + assistant_account_create_confirm_password_error "Les mots de passe sont différents" Les mots de passe sont différents - + assistant_account_create_missing_number_error "Veuillez entrer un numéro de téléphone" Veuillez entrer un numéro de téléphone - + assistant_account_create_missing_email_error "Veuillez entrer un email" Veuillez entrer un email @@ -4844,25 +5282,31 @@ Expiration : %1 SIPLoginPage - + + return_accessible_name + Return + Retour + + + assistant_login_third_party_sip_account_title Compte SIP tiers Compte SIP tiers - + assistant_no_account_yet Pas encore de compte ? Pas encore de compte ? - + assistant_account_register S'inscrire S'inscrire - + Certaines fonctionnalités telles que les conversations de groupe, les vidéo-conférences, etc… nécessitent un compte %1. Ces fonctionnalités seront masquées si vous utilisez un compte SIP tiers. @@ -4875,93 +5319,108 @@ Ces fonctionnalités seront masquées si vous utilisez un compte SIP tiers. Pour les activer dans un projet commercial, merci de nous contacter. - + assistant_third_party_sip_account_create_linphone_account "Créer un compte linphone" Créer un compte linphone - + assistant_third_party_sip_account_warning_ok "Je comprends" Je comprends - + + username "Nom d'utilisateur" Nom d'utilisateur - + + + mandatory_field_accessible_name + "%1 mandatory" + %1 requit + + + + password Mot de passe - + + sip_address_domain "Domaine" Domaine - + + sip_address_display_name Nom d'affichage Nom d'affichage - + + transport "Transport" Transport - + + assistant_account_login Connexion - + assistant_account_login_missing_username Veuillez saisir un nom d'utilisateur - + assistant_account_login_missing_password Veuillez saisir un mot de passe - + assistant_account_login_missing_domain "Veuillez saisir un nom de domaine Veuillez saisir un nom de domaine - + login_advanced_parameters_label Advanced parameters Paramètres avancés - + + login_proxy_server_url "Outbound SIP Proxy URI" URI du proxy SIP sortant - + login_proxy_server_url_tooltip "If this field is filled, the outbound proxy will be enabled automatically. Leave it empty to disable it." Si ce champ est rempli, l’outbound proxy sera activé automatiquement. Laissez-le vide pour le désactiver. - + login_registrar_uri "Registrar URI" Registrar URI - + + login_id "Authentication ID (if different)" Identifiant de connexion (si différent) @@ -5006,6 +5465,21 @@ Pour les activer dans un projet commercial, merci de nous contacter.Partager + + SearchBar + + + open_dialer_acccessibility_label + "Open dialer" + Ouvrir le numéroteur + + + + clear_text_input_acccessibility_label + "Clear text input" + Supprimer le texte saisi + + SecurityModePage @@ -5104,6 +5578,15 @@ Pour les activer dans un projet commercial, merci de nous contacter.Conversations + + SettingsMenuItem + + + setting_tab_accessible_name + %1 settings + %1 paramètres + + SettingsPage @@ -5199,6 +5682,21 @@ Pour les activer dans un projet commercial, merci de nous contacter.En pause + + TextField + + + show_accessible_name + Show %1 + Afficher %1 + + + + hide_accessible_name + Hide %1 + Cacher %1 + + ToolModel @@ -6769,7 +7267,7 @@ Failed to create 1-1 conversation with %1 ! utils - + formatYears '%1 year' @@ -6778,7 +7276,7 @@ Failed to create 1-1 conversation with %1 ! - + formatMonths '%1 month' @@ -6787,7 +7285,7 @@ Failed to create 1-1 conversation with %1 ! - + formatWeeks '%1 week' @@ -6796,7 +7294,7 @@ Failed to create 1-1 conversation with %1 ! - + formatDays '%1 day' @@ -6805,7 +7303,7 @@ Failed to create 1-1 conversation with %1 ! - + formatHours '%1 hour' @@ -6814,7 +7312,7 @@ Failed to create 1-1 conversation with %1 ! - + formatMinutes '%1 minute' @@ -6823,7 +7321,7 @@ Failed to create 1-1 conversation with %1 ! - + formatSeconds '%1 second' @@ -6832,62 +7330,62 @@ Failed to create 1-1 conversation with %1 ! - + codec_install "Installation de codec" Installation de codec - + download_codec "Télécharger le codec %1 (%2) ?" Télécharger le codec %1 (%2) ? - + information_popup_success_title "Succès" Succès - + information_popup_codec_install_success_text "Le codec a été installé avec succès." Le codec a été installé avec succès. - - - + + + information_popup_error_title Erreur - + information_popup_codec_install_error_text "Le codec n'a pas pu être installé." Le codec n'a pas pu être installé. - + information_popup_codec_save_error_text "Le codec n'a pas pu être sauvegardé." Le codec n'a pas pu être sauvegardé. - + information_popup_codec_download_error_text "Le codec n'a pas pu être téléchargé." Le codec n'a pas pu être téléchargé. - + loading_popup_codec_install_progress "Téléchargement en cours …" Téléchargement en cours… - + okButton Ok diff --git a/Linphone/tool/CMakeLists.txt b/Linphone/tool/CMakeLists.txt index 254fb63a7..8a9f58ca9 100644 --- a/Linphone/tool/CMakeLists.txt +++ b/Linphone/tool/CMakeLists.txt @@ -28,6 +28,9 @@ list(APPEND _LINPHONEAPP_SOURCES tool/ui/DashRectangle.cpp + tool/accessibility/FocusHelper.cpp + tool/accessibility/AccessibilityHelper.cpp + ) if (APPLE) diff --git a/Linphone/tool/Utils.cpp b/Linphone/tool/Utils.cpp index eb4f16efa..2cf23f10f 100644 --- a/Linphone/tool/Utils.cpp +++ b/Linphone/tool/Utils.cpp @@ -1765,16 +1765,16 @@ QColor Utils::getPresenceColor(LinphoneEnums::Presence presence) { QColor presenceColor = QColorConstants::Transparent; switch (presence) { case LinphoneEnums::Presence::Online: - presenceColor = Utils::getDefaultStyleColor("success_500main"); + presenceColor = Utils::getDefaultStyleColor("success_500_main"); break; case LinphoneEnums::Presence::Away: presenceColor = Utils::getDefaultStyleColor("warning_500_main"); break; case LinphoneEnums::Presence::Busy: - presenceColor = Utils::getDefaultStyleColor("danger_500main"); + presenceColor = Utils::getDefaultStyleColor("danger_500_main"); break; case LinphoneEnums::Presence::DoNotDisturb: - presenceColor = Utils::getDefaultStyleColor("danger_500main"); + presenceColor = Utils::getDefaultStyleColor("danger_500_main"); break; case LinphoneEnums::Presence::Offline: presenceColor = Utils::getDefaultStyleColor("main2_600"); diff --git a/Linphone/tool/accessibility/AccessibilityHelper.cpp b/Linphone/tool/accessibility/AccessibilityHelper.cpp new file mode 100644 index 000000000..170e49724 --- /dev/null +++ b/Linphone/tool/accessibility/AccessibilityHelper.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2010-2025 Belledonne Communications SARL. + * + * This file is part of linphone-desktop + * (see https://www.linphone.org). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "AccessibilityHelper.hpp" +#include "tool/Utils.hpp" +#include +#include +#include + +DEFINE_ABSTRACT_OBJECT(AccessibilityHelper) + +void AccessibilityHelper::announceMessage(const QString &message, QObject *context, bool assertive) { + QObject *target = context ? context : static_cast(Utils::getMainWindow()); + QAccessibleAnnouncementEvent event(target, message); + event.setPoliteness(assertive ? QAccessible::AnnouncementPoliteness::Assertive + : QAccessible::AnnouncementPoliteness::Polite); + + QAccessible::updateAccessibility(&event); +} diff --git a/Linphone/tool/accessibility/AccessibilityHelper.hpp b/Linphone/tool/accessibility/AccessibilityHelper.hpp new file mode 100644 index 000000000..303655a0f --- /dev/null +++ b/Linphone/tool/accessibility/AccessibilityHelper.hpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2010-2025 Belledonne Communications SARL. + * + * This file is part of linphone-desktop + * (see https://www.linphone.org). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef ACCESSIBILITY_HELPER_H +#define ACCESSIBILITY_HELPER_H + +#include +#include + +#include "tool/AbstractObject.hpp" + +class AccessibilityHelper : public QObject, public AbstractObject { + Q_OBJECT +public: + AccessibilityHelper(QObject *parent = nullptr) : QObject(parent) { + } + + Q_INVOKABLE static void announceMessage(const QString &message, QObject *context = nullptr, bool assertive = false); + +private: + DECLARE_ABSTRACT_OBJECT +}; + +#endif // ACCESSIBILITY_HELPER_H \ No newline at end of file diff --git a/Linphone/tool/accessibility/FocusHelper.cpp b/Linphone/tool/accessibility/FocusHelper.cpp new file mode 100644 index 000000000..392673ce4 --- /dev/null +++ b/Linphone/tool/accessibility/FocusHelper.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2010-2025 Belledonne Communications SARL. + * + * This file is part of linphone-desktop + * (see https://www.linphone.org). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "FocusHelper.hpp" +#include + +FocusHelperAttached::FocusHelperAttached(QObject *parent) : QObject(parent) { + if (auto item = qobject_cast(parent)) { + m_item = item; + m_item->installEventFilter(this); + } +} + +bool FocusHelperAttached::eventFilter(QObject *watched, QEvent *event) { + if (watched == m_item) { + if (event->type() == QEvent::FocusIn) { + auto fe = static_cast(event); + if (fe) { + int focusReason = fe->reason(); + m_keyboardFocus = (focusReason == Qt::TabFocusReason || focusReason == Qt::BacktabFocusReason); + m_otherFocus = focusReason == Qt::OtherFocusReason; + emit keyboardFocusChanged(); + emit otherFocusChanged(); + } + } else if (event->type() == QEvent::FocusOut) { + m_keyboardFocus = false; + m_otherFocus = false; + emit keyboardFocusChanged(); + emit otherFocusChanged(); + } + } + return QObject::eventFilter(watched, event); +} + +FocusHelperAttached *FocusHelper::qmlAttachedProperties(QObject *obj) { + return new FocusHelperAttached(obj); +} diff --git a/Linphone/tool/accessibility/FocusHelper.hpp b/Linphone/tool/accessibility/FocusHelper.hpp new file mode 100644 index 000000000..dc5d8c73e --- /dev/null +++ b/Linphone/tool/accessibility/FocusHelper.hpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2010-2025 Belledonne Communications SARL. + * + * This file is part of linphone-desktop + * (see https://www.linphone.org). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include +#include +#include +#include + +class FocusHelperAttached : public QObject { + Q_OBJECT + Q_PROPERTY(bool keyboardFocus READ keyboardFocus NOTIFY keyboardFocusChanged) + Q_PROPERTY(bool otherFocus READ otherFocus NOTIFY otherFocusChanged) + +public: + explicit FocusHelperAttached(QObject *parent = nullptr); + + bool keyboardFocus() const { + return m_keyboardFocus; + } + bool otherFocus() const { + return m_otherFocus; + } + +signals: + void keyboardFocusChanged(); + void otherFocusChanged(); + +protected: + bool eventFilter(QObject *watched, QEvent *event) override; + +private: + QPointer m_item; + bool m_keyboardFocus = false; + bool m_otherFocus = false; + + friend class FocusHelper; +}; + +class FocusHelper : public QObject { + Q_OBJECT +public: + using QObject::QObject; + + static FocusHelperAttached *qmlAttachedProperties(QObject *obj); +}; + +QML_DECLARE_TYPEINFO(FocusHelper, QML_HAS_ATTACHED_PROPERTIES) diff --git a/Linphone/view/CMakeLists.txt b/Linphone/view/CMakeLists.txt index 48d6cfed7..af4931e7f 100644 --- a/Linphone/view/CMakeLists.txt +++ b/Linphone/view/CMakeLists.txt @@ -45,12 +45,13 @@ list(APPEND _LINPHONEAPP_QML_FILES view/Control/Display/EffectImage.qml view/Control/Display/Flickable.qml view/Control/Display/GradientRectangle.qml - view/Control/Display/TemporaryText.qml + view/Control/Display/HorizontalBar.qml view/Control/Display/MediaProgressBar.qml view/Control/Display/ProgressBar.qml view/Control/Display/RoundedPane.qml view/Control/Display/RoundProgressBar.qml view/Control/Display/Sticker.qml + view/Control/Display/TemporaryText.qml view/Control/Display/Text.qml view/Control/Display/ToolTip.qml view/Control/Display/Call/CallListView.qml @@ -72,6 +73,7 @@ list(APPEND _LINPHONEAPP_QML_FILES view/Control/Display/Chat/VideoFileView.qml view/Control/Display/Contact/Avatar.qml view/Control/Display/Contact/Contact.qml + view/Control/Display/Contact/ContactStatusPopup.qml view/Control/Display/Contact/Presence.qml view/Control/Display/Contact/PresenceStatusItem.qml view/Control/Display/Contact/PresenceSetCustomStatus.qml diff --git a/Linphone/view/Control/Button/Button.qml b/Linphone/view/Control/Button/Button.qml index c2cb4f954..429844552 100644 --- a/Linphone/view/Control/Button/Button.qml +++ b/Linphone/view/Control/Button/Button.qml @@ -4,42 +4,63 @@ import QtQuick.Effects import QtQuick.Layouts import QtQml import Linphone +import CustomControls 1.0 +import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle Control.Button { id: mainItem - property int capitalization property var style + property bool asynchronous: false + hoverEnabled: enabled + activeFocusOnTab: true + property color disabledFilterColor: color.hslLightness > 0.5 + ? DefaultStyle.grey_0 + : DefaultStyle.grey_400 + property bool hasNavigationFocus: enabled && (activeFocus || hovered) + property bool keyboardFocus: FocusHelper.keyboardFocus + // Background properties property color color: style?.color?.normal || DefaultStyle.main1_500_main property color hoveredColor: style?.color?.hovered || Qt.darker(color, 1.05) property color pressedColor: style?.color?.pressed || Qt.darker(color, 1.1) property color checkedColor: style?.color?.checked || style?.color?.pressed || Qt.darker(color, 1.1) + property bool shadowEnabled: false + property int capitalization + property color backgroundColor: mainItem.checkable && mainItem.checked + ? mainItem.checkedColor || mainItem.pressedColor + : mainItem.pressed + ? mainItem.pressedColor + : mainItem.hovered + ? mainItem.hoveredColor + : mainItem.color + // Text properties + property bool underline: false + property real textSize: Utils.getSizeWithScreenRatio(18) + property real textWeight: Typography.b1.weight property color textColor: style?.text?.normal || DefaultStyle.grey_0 property color hoveredTextColor: style?.text?.hovered || Qt.darker(textColor, 1.05) property color pressedTextColor: style?.text?.pressed || Qt.darker(textColor, 1.1) - property color borderColor: style?.borderColor || "transparent" + property var textFormat: Text.AutoText + property var textHAlignment: Text.AlignHCenter + // Tooltip properties ToolTip.visible: hovered && ToolTip.text != "" ToolTip.delay: 500 - property color disabledFilterColor: color.hslLightness > 0.5 - ? DefaultStyle.grey_0 - : DefaultStyle.grey_400 - property real textSize: Math.round(18 * DefaultStyle.dp) - property real textWeight: Typography.b1.weight - property var textHAlignment: Text.AlignHCenter - property real radius: Math.round(48 * DefaultStyle.dp) - property bool underline: false - property bool hasNavigationFocus: enabled && (activeFocus || hovered) - property bool shadowEnabled: false + // Border properties + property color borderColor: style?.borderColor?.normal || "transparent" + property color keyboardFocusedBorderColor: style?.borderColor?.keybaordFocused || DefaultStyle.main2_900 + property real borderWidth: Utils.getSizeWithScreenRatio(1) + property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3) + // Image properties property var contentImageColor: style?.image?.normal || DefaultStyle.main2_600 property var hoveredImageColor: style?.image?.pressed || Qt.darker(contentImageColor, 1.05) property var checkedImageColor: style?.image?.checked || Qt.darker(contentImageColor, 1.1) property var pressedImageColor: style?.image?.pressed || Qt.darker(contentImageColor, 1.1) - property bool asynchronous: false - property var textFormat: Text.AutoText - spacing: Math.round(5 * DefaultStyle.dp) - hoverEnabled: enabled - activeFocusOnTab: true icon.source: style?.iconSource || "" + property color colorizationColor: mainItem.checkable && mainItem.checked ? mainItem.checkedImageColor || mainItem.checkedColor || mainItem.pressedColor : mainItem.pressed ? mainItem.pressedImageColor : mainItem.hovered ? mainItem.hoveredImageColor : mainItem.contentImageColor + // Size properties + spacing: Utils.getSizeWithScreenRatio(5) + property real radius: Math.ceil(height / 2) + MouseArea { id: mouseArea z: stacklayout.z + 1 @@ -54,18 +75,15 @@ Control.Button { anchors.fill: parent sourceComponent: Item { + width: mainItem.width + height: mainItem.height Rectangle { id: buttonBackground anchors.fill: parent - color: mainItem.checkable && mainItem.checked - ? mainItem.checkedColor || mainItem.pressedColor - : mainItem.pressed - ? mainItem.pressedColor - : mainItem.hovered || mainItem.hasNavigationFocus - ? mainItem.hoveredColor - : mainItem.color + color: mainItem.backgroundColor radius: mainItem.radius - border.color: mainItem.borderColor + border.color: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.borderColor + border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth } MultiEffect { enabled: mainItem.shadowEnabled @@ -115,7 +133,7 @@ Control.Button { family: DefaultStyle.defaultFont capitalization: mainItem.capitalization underline: mainItem.underline - bold: mainItem.style === ButtonStyle.noBackground && (mainItem.hovered || mainItem.pressed) + bold: (mainItem.style === ButtonStyle.noBackground || mainItem.style === ButtonStyle.noBackgroundRed) && (mainItem.hovered || mainItem.pressed) } TextMetrics { id: textMetrics @@ -129,13 +147,7 @@ Control.Button { imageSource: mainItem.icon.source imageWidth: mainItem.icon.width imageHeight: mainItem.icon.height - colorizationColor: mainItem.checkable && mainItem.checked - ? mainItem.checkedImageColor || mainItem.checkedColor || mainItem.pressedColor - : mainItem.pressed - ? mainItem.pressedImageColor - : mainItem.hovered - ? mainItem.hoveredImageColor - : mainItem.contentImageColor + colorizationColor: mainItem.colorizationColor } contentItem: Control.StackView{ diff --git a/Linphone/view/Control/Button/CheckableButton.qml b/Linphone/view/Control/Button/CheckableButton.qml index ead8c7065..5f14658ee 100644 --- a/Linphone/view/Control/Button/CheckableButton.qml +++ b/Linphone/view/Control/Button/CheckableButton.qml @@ -20,19 +20,9 @@ Button { ? pressedColor : color checkable: true - background: Rectangle { - anchors.fill: parent - color: mainItem.backgroundColor - radius: mainItem.width /2 - Rectangle { - anchors.fill: parent - visible: !mainItem.enabled - opacity: 0.2 - color: DefaultStyle.grey_600 - } - } + Accessible.role: Accessible.Button icon.source: checkedIconUrl && mainItem.checked ? checkedIconUrl : iconUrl - icon.width: width * 0.58 - icon.height: width * 0.58 + icon.width: Math.round(width * 0.58) + icon.height: Math.round(width * 0.58) contentImageColor: style?.image?.normal || DefaultStyle.grey_0 } diff --git a/Linphone/view/Control/Button/ComboBox.qml b/Linphone/view/Control/Button/ComboBox.qml index 47604ed96..d5db5b300 100644 --- a/Linphone/view/Control/Button/ComboBox.qml +++ b/Linphone/view/Control/Button/ComboBox.qml @@ -3,267 +3,268 @@ import QtQuick.Controls.Basic as Control import QtQuick.Layouts import QtQuick.Effects import Linphone - +import CustomControls 1.0 +import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils + Control.ComboBox { - id: mainItem - // Usage : each item of the model list must be {text: …, img: …} - // If string list, only text part of the delegate will be filled - // readonly property string currentText: selectedItemText.text - property alias listView: listView - property string constantImageSource + id: mainItem + // Usage : each item of the model list must be {text: …, img: …} + // If string list, only text part of the delegate will be filled + // readonly property string currentText: selectedItemText.text + property alias listView: listView + property string constantImageSource property real pixelSize: Typography.p1.pixelSize property real weight: Typography.p1.weight - property real leftMargin: Math.round(10 * DefaultStyle.dp) - property bool oneLine: false - property bool shadowEnabled: mainItem.activeFocus || mainItem.hovered - property string flagRole// Specific case if flag is shown (special font) - property var indicatorColor: DefaultStyle.main2_600 - property int indicatorRightMargin: Math.round(20 * DefaultStyle.dp) - leftPadding: Math.round(10 * DefaultStyle.dp) - rightPadding: indicImage.width + indicatorRightMargin + property real leftMargin: Utils.getSizeWithScreenRatio(10) + property bool oneLine: false + property bool shadowEnabled: mainItem.activeFocus || mainItem.hovered + property string flagRole // Specific case if flag is shown (special font) + property var indicatorColor: DefaultStyle.main2_600 + property int indicatorRightMargin: Utils.getSizeWithScreenRatio(20) + leftPadding: Utils.getSizeWithScreenRatio(10) + rightPadding: indicImage.width + indicatorRightMargin + property bool keyboardFocus: FocusHelper.keyboardFocus + // Text properties + property color textColor: DefaultStyle.main2_600 + property color disabledTextColor: DefaultStyle.grey_400 + // Border properties + property color borderColor: DefaultStyle.grey_200 + property color disabledBorderColor: DefaultStyle.grey_400 + property color activeFocusedBorderColor: DefaultStyle.main1_500_main + property color keyboardFocusedBorderColor: DefaultStyle.main2_900 + property real borderWidth: Utils.getSizeWithScreenRatio(1) + property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3) + // Background properties + property color color: DefaultStyle.grey_100 + property color disabledColor: DefaultStyle.grey_200 - onConstantImageSourceChanged: if (constantImageSource) selectedItemImg.imageSource = constantImageSource - onCurrentIndexChanged: { - var item = model[currentIndex] - if (!item) item = model.getAt(currentIndex) - if (!item) return - selectedItemText.text = mainItem.textRole - ? item[mainItem.textRole] - : item.text - ? item.text - : item - ? item - : "" - if(mainItem.flagRole) selectedItemFlag.text = item[mainItem.flagRole] - selectedItemImg.imageSource = constantImageSource - ? constantImageSource - : item.img - ? item.img - : "" - } - - Keys.onPressed: (event)=>{ - if(!mainItem.contentItem.activeFocus && (event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return)){ - mainItem.popup.open() - event.accepted = true - } - } + onConstantImageSourceChanged: if (constantImageSource) + selectedItemImg.imageSource = constantImageSource + onCurrentIndexChanged: { + var item = model[currentIndex]; + if (!item) + item = model.getAt(currentIndex); + if (!item) + return; + selectedItemText.text = mainItem.textRole ? item[mainItem.textRole] : item.text ? item.text : item ? item : ""; + if (mainItem.flagRole) + selectedItemFlag.text = item[mainItem.flagRole]; + selectedItemImg.imageSource = constantImageSource ? constantImageSource : item.img ? item.img : ""; + } - background: Item{ - Rectangle { - id: buttonBackground - anchors.fill: parent - radius: Math.round(63 * DefaultStyle.dp) - color: mainItem.enabled ? DefaultStyle.grey_100 : DefaultStyle.grey_200 - border.color: mainItem.enabled - ? mainItem.activeFocus - ? DefaultStyle.main1_500_main - : DefaultStyle.grey_200 - : DefaultStyle.grey_400 - } - MultiEffect { - enabled: mainItem.shadowEnabled - anchors.fill: buttonBackground - source: buttonBackground - visible: mainItem.shadowEnabled - // Crash : https://bugreports.qt.io/browse/QTBUG-124730 - shadowEnabled: true //mainItem.shadowEnabled - shadowColor: DefaultStyle.grey_1000 - shadowBlur: 0.5 - shadowOpacity: mainItem.shadowEnabled ? 0.1 : 0.0 - } - } - contentItem: RowLayout { - spacing: Math.round(5 * DefaultStyle.dp) - EffectImage { - id: selectedItemImg - Layout.preferredWidth: visible ? Math.round(24 * DefaultStyle.dp) : 0 - Layout.preferredHeight: visible ? Math.round(24 * DefaultStyle.dp) : 0 - Layout.leftMargin: mainItem.leftMargin - imageSource: mainItem.constantImageSource ? mainItem.constantImageSource : "" - colorizationColor: DefaultStyle.main2_600 - visible: imageSource != "" - fillMode: Image.PreserveAspectFit - } - Text { - id: selectedItemFlag - Layout.preferredWidth: implicitWidth - Layout.leftMargin: selectedItemImg.visible ? 0 : Math.round(5 * DefaultStyle.dp) - Layout.alignment: Qt.AlignCenter - color: mainItem.enabled ? DefaultStyle.main2_600 : DefaultStyle.grey_400 - font { - family: DefaultStyle.flagFont - pixelSize: mainItem.pixelSize - weight: mainItem.weight - } - } - Text { - id: selectedItemText - Layout.fillWidth: true - Layout.leftMargin: selectedItemImg.visible ? 0 : Math.round(5 * DefaultStyle.dp) - Layout.rightMargin: Math.round(20 * DefaultStyle.dp) - Layout.alignment: Qt.AlignCenter - color: mainItem.enabled ? DefaultStyle.main2_600 : DefaultStyle.grey_400 - elide: Text.ElideRight - maximumLineCount: oneLine ? 1 : 2 - wrapMode: Text.WrapAnywhere - font { - family: DefaultStyle.defaultFont - pixelSize: mainItem.pixelSize - weight: mainItem.weight - } - } - } + Keys.onPressed: event => { + if (!mainItem.contentItem.activeFocus && (event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return)) { + mainItem.popup.open(); + event.accepted = true; + } + } + background: Item { + Rectangle { + id: buttonBackground + anchors.fill: parent + radius: Math.round(mainItem.height / 2) + color: mainItem.enabled ? mainItem.color : mainItem.disabledColor + border.color: !mainItem.enabled ? mainItem.disabledBorderColor : mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.activeFocus || mainItem.popup.opened ? mainItem.activeFocusedBorderColor : mainItem.borderColor + border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth + } + MultiEffect { + enabled: mainItem.shadowEnabled + anchors.fill: buttonBackground + source: buttonBackground + visible: mainItem.shadowEnabled + // Crash : https://bugreports.qt.io/browse/QTBUG-124730 + shadowEnabled: true //mainItem.shadowEnabled + shadowColor: DefaultStyle.grey_1000 + shadowBlur: 0.5 + shadowOpacity: mainItem.shadowEnabled ? 0.1 : 0.0 + } + } + contentItem: RowLayout { + spacing: Utils.getSizeWithScreenRatio(5) + EffectImage { + id: selectedItemImg + Layout.preferredWidth: visible ? Utils.getSizeWithScreenRatio(24) : 0 + Layout.preferredHeight: visible ? Utils.getSizeWithScreenRatio(24) : 0 + Layout.leftMargin: mainItem.leftMargin + imageSource: mainItem.constantImageSource ? mainItem.constantImageSource : "" + colorizationColor: mainItem.enabled ? mainItem.textColor : mainItem.disabledTextColor + visible: imageSource != "" + fillMode: Image.PreserveAspectFit + } + Text { + id: selectedItemFlag + Layout.preferredWidth: implicitWidth + Layout.leftMargin: selectedItemImg.visible ? 0 : Utils.getSizeWithScreenRatio(5) + Layout.alignment: Qt.AlignCenter + color: mainItem.enabled ? mainItem.textColor : mainItem.disabledTextColor + font { + family: DefaultStyle.flagFont + pixelSize: mainItem.pixelSize + weight: mainItem.weight + } + } + Text { + id: selectedItemText + Layout.fillWidth: true + Layout.leftMargin: selectedItemImg.visible ? 0 : Utils.getSizeWithScreenRatio(5) + Layout.rightMargin: Utils.getSizeWithScreenRatio(20) + Layout.alignment: Qt.AlignCenter + color: mainItem.enabled ? mainItem.textColor : mainItem.disabledTextColor + elide: Text.ElideRight + maximumLineCount: oneLine ? 1 : 2 + wrapMode: Text.WrapAnywhere + font { + family: DefaultStyle.defaultFont + pixelSize: mainItem.pixelSize + weight: mainItem.weight + } + } + } - indicator: EffectImage { - id: indicImage - z: 1 - anchors.right: parent.right - anchors.rightMargin: mainItem.indicatorRightMargin - anchors.verticalCenter: parent.verticalCenter - imageSource: AppIcons.downArrow - width: Math.round(15 * DefaultStyle.dp) - height: Math.round(15 * DefaultStyle.dp) - fillMode: Image.PreserveAspectFit - colorizationColor: mainItem.indicatorColor - } + indicator: EffectImage { + id: indicImage + z: 1 + anchors.right: parent.right + anchors.rightMargin: mainItem.indicatorRightMargin + anchors.verticalCenter: parent.verticalCenter + imageSource: AppIcons.downArrow + width: Utils.getSizeWithScreenRatio(15) + height: Utils.getSizeWithScreenRatio(15) + fillMode: Image.PreserveAspectFit + colorizationColor: mainItem.indicatorColor + // Rotate when popup open/close + transformOrigin: Item.Center + rotation: mainItem.popup.opened ? 180 : 0 + Behavior on rotation { + NumberAnimation { + duration: 200 + easing.type: Easing.InOutQuad + } + } + } - popup: Control.Popup { - id: popup - y: mainItem.height - 1 - width: mainItem.width - implicitHeight: Math.min(contentItem.implicitHeight, mainWindow.height) + popup: Control.Popup { + id: popup + y: mainItem.height - 1 + width: mainItem.width + implicitHeight: Math.min(contentItem.implicitHeight, mainWindow.height) padding: Math.max(Math.round(1 * DefaultStyle.dp), 1) - onOpened: { - listView.positionViewAtIndex(listView.currentIndex, ListView.Center) - listView.forceActiveFocus() - } - contentItem: ListView { - id: listView - clip: true - implicitHeight: contentHeight - height: popup.height - model: visible? mainItem.model : [] - currentIndex: mainItem.highlightedIndex >= 0 ? mainItem.highlightedIndex : 0 - highlightFollowsCurrentItem: true - highlightMoveDuration: -1 - highlightMoveVelocity: -1 - highlight: Rectangle { - width: listView.width - color: DefaultStyle.main2_200 + onOpened: { + listView.positionViewAtIndex(listView.currentIndex, ListView.Center); + listView.forceActiveFocus(); + } + contentItem: ListView { + id: listView + clip: true + implicitHeight: contentHeight + height: popup.height + model: visible ? mainItem.model : [] + currentIndex: mainItem.highlightedIndex >= 0 ? mainItem.highlightedIndex : 0 + highlightFollowsCurrentItem: true + highlightMoveDuration: -1 + highlightMoveVelocity: -1 + highlight: Rectangle { + width: listView.width + color: DefaultStyle.main2_200 radius: Math.round(15 * DefaultStyle.dp) - y: listView.currentItem? listView.currentItem.y : 0 - } - - Keys.onPressed: (event)=>{ - if(event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return){ - event.accepted = true - mainItem.currentIndex = listView.currentIndex - popup.close() - } - } + y: listView.currentItem ? listView.currentItem.y : 0 + } - delegate: Item { - width:mainItem.width - height: mainItem.height - // anchors.left: listView.left - // anchors.right: listView.right - RowLayout{ - anchors.fill: parent - EffectImage { - id: delegateImg + Keys.onPressed: event => { + if (event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return) { + event.accepted = true; + mainItem.currentIndex = listView.currentIndex; + popup.close(); + } + } + + delegate: Item { + width: mainItem.width + height: mainItem.height + // anchors.left: listView.left + // anchors.right: listView.right + Accessible.name: typeof (modelData) != "undefined" ? mainItem.textRole ? modelData[mainItem.textRole] : modelData.text ? modelData.text : modelData : $modelData ? mainItem.textRole ? $modelData[mainItem.textRole] : $modelData : "" + RowLayout { + anchors.fill: parent + EffectImage { + id: delegateImg Layout.preferredWidth: visible ? Math.round(20 * DefaultStyle.dp) : 0 Layout.leftMargin: Math.round(10 * DefaultStyle.dp) - visible: imageSource != "" + visible: imageSource != "" imageWidth: Math.round(20 * DefaultStyle.dp) - imageSource: typeof(modelData) != "undefined" && modelData.img ? modelData.img : "" - fillMode: Image.PreserveAspectFit - } - - Text { - Layout.preferredWidth: implicitWidth - Layout.leftMargin: delegateImg.visible ? 0 : Math.round(5 * DefaultStyle.dp) - Layout.alignment: Qt.AlignCenter - visible: mainItem.flagRole - font { - family: DefaultStyle.flagFont - pixelSize: mainItem.pixelSize - weight: mainItem.weight - } - text: mainItem.flagRole - ? typeof(modelData) != "undefined" - ? modelData[mainItem.flagRole] - : $modelData[mainItem.flagRole] - : "" - } - Text { - Layout.fillWidth: true + imageSource: typeof (modelData) != "undefined" && modelData.img ? modelData.img : "" + fillMode: Image.PreserveAspectFit + } + + Text { + id: flagItem + Layout.preferredWidth: implicitWidth Layout.leftMargin: delegateImg.visible ? 0 : Math.round(5 * DefaultStyle.dp) + Layout.alignment: Qt.AlignCenter + visible: mainItem.flagRole + font { + family: DefaultStyle.flagFont + pixelSize: mainItem.pixelSize + weight: mainItem.weight + } + text: mainItem.flagRole ? typeof (modelData) != "undefined" ? modelData[mainItem.flagRole] : $modelData[mainItem.flagRole] : "" + } + Text { + Layout.fillWidth: true + Layout.leftMargin: delegateImg.visible ? 0 : flagItem.visble ? Utils.getSizeWithScreenRatio(5) : Utils.getSizeWithScreenRatio(25) Layout.rightMargin: Math.round(20 * DefaultStyle.dp) - Layout.alignment: Qt.AlignCenter - text: typeof(modelData) != "undefined" - ? mainItem.textRole - ? modelData[mainItem.textRole] - : modelData.text - ? modelData.text - : modelData - : $modelData - ? mainItem.textRole - ? $modelData[mainItem.textRole] - : $modelData - : "" - elide: Text.ElideRight - maximumLineCount: 1 - wrapMode: Text.WrapAnywhere - font { - family: DefaultStyle.defaultFont - pixelSize: Math.round(14 * DefaultStyle.dp) - weight: Math.min(Math.round(400 * DefaultStyle.dp), 1000) - } - } - } + Layout.alignment: Qt.AlignCenter + text: typeof (modelData) != "undefined" ? mainItem.textRole ? modelData[mainItem.textRole] : modelData.text ? modelData.text : modelData : $modelData ? mainItem.textRole ? $modelData[mainItem.textRole] : $modelData : "" + elide: Text.ElideRight + maximumLineCount: 1 + wrapMode: Text.WrapAnywhere + font { + family: DefaultStyle.defaultFont + pixelSize: Utils.getSizeWithScreenRatio(15) + weight: Math.min(Utils.getSizeWithScreenRatio(400), 1000) + } + } + } - MouseArea { - id: mouseArea - anchors.fill: parent - hoverEnabled: true - Rectangle { - anchors.fill: parent - opacity: 0.1 - radius: Math.round(15 * DefaultStyle.dp) - color: DefaultStyle.main2_500main - visible: parent.containsMouse - } - onClicked: { - mainItem.currentIndex = index - popup.close() - } - } - } + MouseArea { + id: mouseArea + anchors.fill: parent + hoverEnabled: true + Rectangle { + anchors.fill: parent + opacity: 0.1 + radius: Utils.getSizeWithScreenRatio(15) + color: DefaultStyle.main2_500_main + visible: parent.containsMouse + } + onClicked: { + mainItem.currentIndex = index; + popup.close(); + } + } + } - Control.ScrollIndicator.vertical: Control.ScrollIndicator { } - } + Control.ScrollIndicator.vertical: Control.ScrollIndicator {} + } - - - background: Item { - implicitWidth: mainItem.width - implicitHeight: Math.round(30 * DefaultStyle.dp) - Rectangle { - id: cboxBg - anchors.fill: parent - radius: Math.round(15 * DefaultStyle.dp) - } - MultiEffect { - anchors.fill: cboxBg - source: cboxBg - shadowEnabled: true - shadowColor: DefaultStyle.grey_1000 - shadowBlur: 0.1 - shadowOpacity: 0.1 - } - } - } + background: Item { + implicitWidth: mainItem.width + implicitHeight: Utils.getSizeWithScreenRatio(30) + Rectangle { + id: cboxBg + anchors.fill: parent + radius: Utils.getSizeWithScreenRatio(15) + } + MultiEffect { + anchors.fill: cboxBg + source: cboxBg + shadowEnabled: true + shadowColor: DefaultStyle.grey_1000 + shadowBlur: 0.1 + shadowOpacity: 0.1 + } + } + } } diff --git a/Linphone/view/Control/Button/CountryIndicatorCombobox.qml b/Linphone/view/Control/Button/CountryIndicatorCombobox.qml index 79ba6a8ef..dbb685f45 100644 --- a/Linphone/view/Control/Button/CountryIndicatorCombobox.qml +++ b/Linphone/view/Control/Button/CountryIndicatorCombobox.qml @@ -26,6 +26,7 @@ ColumnLayout { Control.ComboBox { id: combobox currentIndex: phoneNumberModel.count > 0 ? Math.max(0, phoneNumberModel.findIndexByCountryCallingCode(defaultCallingCode)) : -1 + Accessible.name: mainItem.Accessible.name model: PhoneNumberProxy { id: phoneNumberModel } @@ -36,7 +37,7 @@ ColumnLayout { color: mainItem.enableBackgroundColor ? DefaultStyle.grey_100 : "transparent" border.color: mainItem.enableBackgroundColors ? (mainItem.errorMessage.length > 0 - ? DefaultStyle.danger_500main + ? DefaultStyle.danger_500_main : textField.activeFocus ? DefaultStyle.main1_500_main : DefaultStyle.grey_200) @@ -140,7 +141,7 @@ ColumnLayout { id: countryText text: $modelData.country elide: Text.ElideRight - color: DefaultStyle.main2_500main + color: DefaultStyle.main2_500_main font { pixelSize: Typography.p1.pixelSize weight: Typography.p1.weight @@ -151,13 +152,13 @@ ColumnLayout { id: separator width: Math.max(Math.round(1 * DefaultStyle.dp), 1) height: combobox.height / 2 - color: DefaultStyle.main2_500main + color: DefaultStyle.main2_500_main } Text { text: "+" + $modelData.countryCallingCode elide: Text.ElideRight - color: DefaultStyle.main2_500main + color: DefaultStyle.main2_500_main font { pixelSize: Typography.p1.pixelSize weight: Typography.p1.weight @@ -174,7 +175,7 @@ ColumnLayout { anchors.fill: parent opacity: 0.1 radius: Math.round(15 * DefaultStyle.dp) - color: DefaultStyle.main2_500main + color: DefaultStyle.main2_500_main visible: parent.containsMouse } onClicked: { diff --git a/Linphone/view/Control/Button/HelpIconLabelButton.qml b/Linphone/view/Control/Button/HelpIconLabelButton.qml index 7e12b0cdc..60161db3e 100644 --- a/Linphone/view/Control/Button/HelpIconLabelButton.qml +++ b/Linphone/view/Control/Button/HelpIconLabelButton.qml @@ -50,7 +50,7 @@ MouseArea { verticalAlignment: Text.AlignTop Layout.fillWidth: true text: mainItem.subTitle - color: DefaultStyle.main2_500main + color: DefaultStyle.main2_500_main visible: subTitle.length > 0 font: Typography.p1 } diff --git a/Linphone/view/Control/Button/IconButton.qml b/Linphone/view/Control/Button/IconButton.qml index c397fa531..80a146714 100644 --- a/Linphone/view/Control/Button/IconButton.qml +++ b/Linphone/view/Control/Button/IconButton.qml @@ -22,7 +22,7 @@ Button { : mainItem.hovered || mainItem.hasNavigationFocus ? mainItem.hoveredColor : mainItem.color - border.color: mainItem.borderColor + border.color: mainItem.hovered ? mainItem.focusedBorderColor : mainItem.borderColor } contentItem: EffectImage { diff --git a/Linphone/view/Control/Button/LabelButton.qml b/Linphone/view/Control/Button/LabelButton.qml index 544303662..a3a5a807e 100644 --- a/Linphone/view/Control/Button/LabelButton.qml +++ b/Linphone/view/Control/Button/LabelButton.qml @@ -24,6 +24,7 @@ ColumnLayout { contentImageColor: DefaultStyle.main2_600 radius: Math.round(40 * DefaultStyle.dp) style: ButtonStyle.grey + Accessible.name: labelButton.label } Text { id: text diff --git a/Linphone/view/Control/Button/PopupButton.qml b/Linphone/view/Control/Button/PopupButton.qml index ce0d53cbf..fb42a3641 100644 --- a/Linphone/view/Control/Button/PopupButton.qml +++ b/Linphone/view/Control/Button/PopupButton.qml @@ -2,94 +2,100 @@ import QtQuick import QtQuick.Controls.Basic as Control import QtQuick.Effects import Linphone +import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle Button { id: mainItem property alias popup: popup - property bool shadowEnabled: mainItem.activeFocus || hovered + property bool shadowEnabled: mainItem.activeFocus && !keyboardFocus || hovered property alias popupBackgroundColor: popupBackground.color - property color backgroundColor: checked ? pressedColor : hovered ? hoveredColor : color + property color backgroundColor: checked ? pressedColor : hovered || mainItem.activeFocus ? hoveredColor : color + property string popUpTitle: "" + Accessible.name: popup.visible ? + //: "Close %1 popup" + qsTr("close_popup_panel_accessible_name").arg(popUpTitle) : + //: "Open %1" popup + qsTr("open_popup_panel_accessible_name").arg(popUpTitle) style: ButtonStyle.popupButton checked: popup.visible - implicitWidth: Math.round(24 * DefaultStyle.dp) - implicitHeight: Math.round(24 * DefaultStyle.dp) - width: Math.round(24 * DefaultStyle.dp) - height: Math.round(24 * DefaultStyle.dp) leftPadding: 0 rightPadding: 0 topPadding: 0 bottomPadding: 0 icon.source: AppIcons.verticalDots - icon.width: width - icon.height: width + icon.width: Utils.getSizeWithScreenRatio(24) + icon.height: Utils.getSizeWithScreenRatio(24) + implicitWidth: Utils.getSizeWithScreenRatio(30) + implicitHeight: Utils.getSizeWithScreenRatio(30) function close() { - popup.close() + popup.close(); } function open() { - popup.open() + popup.open(); } function isFocusable(item) { - return item.activeFocusOnTab + return item.activeFocusOnTab; } + + /** + * Check if an element has at least one child that is focusable + */ + function hasFocusableChild(content) { + return content.children.some(child => isFocusable(child)); + } + function getPreviousItem(index) { - return _getPreviousItem( - popup.contentItem - instanceof FocusScope ? popup.contentItem.children[0] : popup.contentItem, - index) + return _getPreviousItem(popup.contentItem instanceof FocusScope ? popup.contentItem.children[0] : popup.contentItem, index); } + function getNextItem(index) { - return _getNextItem( - popup.contentItem - instanceof FocusScope ? popup.contentItem.children[0] : popup.contentItem, - index) + return _getNextItem(popup.contentItem instanceof FocusScope ? popup.contentItem.children[0] : popup.contentItem, index); } function _getPreviousItem(content, index) { - if (content.visibleChildren.length == 0) - return null - --index + if (content.visibleChildren.length == 0 || !hasFocusableChild(content)) + return null; + --index; while (index >= 0) { - if (isFocusable(content.children[index]) - && content.children[index].visible) - return content.children[index] - --index + if (isFocusable(content.children[index]) && content.children[index].visible) + return content.children[index]; + --index; } - return _getPreviousItem(content, content.children.length) + return _getPreviousItem(content, content.visibleChildren.length); } + function _getNextItem(content, index) { - ++index + if (content.visibleChildren.length == 0 || !hasFocusableChild(content)) + return null; + ++index; while (index < content.children.length) { - if (isFocusable(content.children[index]) - && content.children[index].visible) - return content.children[index] - ++index + if (isFocusable(content.children[index]) && content.children[index].visible) + return content.children[index]; + ++index; } - return _getNextItem(content, -1) + return _getNextItem(content, -1); } Keys.onPressed: event => { - if (mainItem.checked) { - if (event.key == Qt.Key_Escape - || event.key == Qt.Key_Left - || event.key == Qt.Key_Space) { - mainItem.close() - mainItem.forceActiveFocus() - event.accepted = true - } else if (event.key == Qt.Key_Up) { - getPreviousItem(0).forceActiveFocus() - event.accepted = true - } else if (event.key == Qt.Key_Tab - || event.key == Qt.Key_Down) { - getNextItem(-1).forceActiveFocus() - event.accepted = true - } - } else if (event.key == Qt.Key_Space) { - mainItem.open() - event.accepted = true - } - } + if (mainItem.checked) { + if (event.key == Qt.Key_Escape || event.key == Qt.Key_Left || event.key == Qt.Key_Space) { + mainItem.close(); + mainItem.forceActiveFocus(Qt.TabFocusReason); + event.accepted = true; + } else if (event.key == Qt.Key_Up) { + getPreviousItem(0).forceActiveFocus(Qt.TabFocusReason); + event.accepted = true; + } else if (event.key == Qt.Key_Tab || event.key == Qt.Key_Down) { + getNextItem(-1).forceActiveFocus(Qt.BacktabFocusReason); + event.accepted = true; + } + } else if (event.key == Qt.Key_Space) { + mainItem.open(); + event.accepted = true; + } + } background: Item { anchors.fill: mainItem @@ -97,7 +103,9 @@ Button { id: buttonBackground anchors.fill: parent color: mainItem.backgroundColor - radius: Math.round(40 * DefaultStyle.dp) + radius: Utils.getSizeWithScreenRatio(40) + border.color: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.borderColor + border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth } MultiEffect { enabled: mainItem.shadowEnabled @@ -119,45 +127,37 @@ Button { } onPressed: { if (popup.visible) - popup.close() + popup.close(); else - popup.open() + popup.open(); } Control.Popup { id: popup x: 0 y: mainItem.height visible: false - closePolicy: Popup.CloseOnPressOutsideParent | Popup.CloseOnPressOutside - | Popup.CloseOnEscape - padding: Math.round(10 * DefaultStyle.dp) + closePolicy: Popup.CloseOnPressOutsideParent | Popup.CloseOnPressOutside | Popup.CloseOnEscape + padding: Utils.getSizeWithScreenRatio(10) parent: mainItem // Explicit define for coordinates references. function updatePosition() { if (!visible) - return - var popupHeight = popup.height + popup.padding - var popupWidth = popup.width + popup.padding - var winPosition = mainItem.Window.contentItem ? mainItem.Window.contentItem.mapToItem( - mainItem, 0, - 0) : { - "x": 0, - "y": 0 - } + return; + var popupHeight = popup.height + popup.padding; + var popupWidth = popup.width + popup.padding; + var winPosition = mainItem.Window.contentItem ? mainItem.Window.contentItem.mapToItem(mainItem, 0, 0) : { + "x": 0, + "y": 0 + }; // Stay inside main window - y = Math.max(Math.min( - winPosition.y + mainItem.Window.height - popupHeight, - mainItem.height), winPosition.y) - x = Math.max( - Math.min( - winPosition.x + mainItem.Window.width - popupWidth, - 0), winPosition.x) + y = Math.max(Math.min(winPosition.y + mainItem.Window.height - popupHeight, mainItem.height), winPosition.y); + x = Math.max(Math.min(winPosition.x + mainItem.Window.width - popupWidth, 0), winPosition.x); // Avoid overlapping with popup button by going to the right (todo: check if left is better?) if (y < mainItem.height && y + popupHeight > 0) { - x += mainItem.width + x += mainItem.width; } - var globalPos = mapToItem(mainItem.Window.contentItem, x, y) + var globalPos = mapToItem(mainItem.Window.contentItem, x, y); if (globalPos.x + popupWidth >= mainItem.Window.width) { - x = -popupWidth + x = -popupWidth; } } @@ -168,21 +168,20 @@ Button { Connections { target: mainItem.Window function onHeightChanged() { - Qt.callLater(popup.updatePosition) + Qt.callLater(popup.updatePosition); } function onWidthChanged() { - Qt.callLater(popup.updatePosition) + Qt.callLater(popup.updatePosition); } } - background: Item { anchors.fill: parent Rectangle { id: popupBackground anchors.fill: parent color: DefaultStyle.grey_0 - radius: Math.round(16 * DefaultStyle.dp) + radius: Utils.getSizeWithScreenRatio(16) } MultiEffect { source: popupBackground @@ -192,7 +191,7 @@ Button { shadowColor: DefaultStyle.grey_1000 shadowOpacity: 0.4 } - MouseArea{ + MouseArea { anchors.fill: parent } } diff --git a/Linphone/view/Control/Button/Settings/ComboSetting.qml b/Linphone/view/Control/Button/Settings/ComboSetting.qml index a2b30c608..ee82d025e 100644 --- a/Linphone/view/Control/Button/Settings/ComboSetting.qml +++ b/Linphone/view/Control/Button/Settings/ComboSetting.qml @@ -6,7 +6,7 @@ import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils ComboBox { id: mainItem - Layout.preferredHeight: Math.round(49 * DefaultStyle.dp) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(49) property string propertyName property var propertyOwner diff --git a/Linphone/view/Control/Button/Settings/SwitchSetting.qml b/Linphone/view/Control/Button/Settings/SwitchSetting.qml index 7ade3718d..103831c9e 100644 --- a/Linphone/view/Control/Button/Settings/SwitchSetting.qml +++ b/Linphone/view/Control/Button/Settings/SwitchSetting.qml @@ -2,6 +2,7 @@ import QtQuick import QtQuick.Controls.Basic import QtQuick.Layouts import Linphone +import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils RowLayout { id:mainItem @@ -45,6 +46,8 @@ RowLayout { enabled: mainItem.enabled onCheckedChanged: mainItem.checkedChanged(checked) onToggled: binding.when = true + implicitHeight: Utils.getSizeWithScreenRatio(30) + Accessible.name: "%1 %2".arg(mainItem.titleText).arg(mainItem.subTitleText) } Binding { id: binding diff --git a/Linphone/view/Control/Button/Slider.qml b/Linphone/view/Control/Button/Slider.qml index 4fa26a020..3335dca77 100644 --- a/Linphone/view/Control/Button/Slider.qml +++ b/Linphone/view/Control/Button/Slider.qml @@ -3,22 +3,30 @@ import QtQuick.Effects import QtQuick.Layouts import QtQuick.Controls.Basic as Control import Linphone +import CustomControls 1.0 +import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils Control.Slider { id: mainItem - property bool shadowEnabled: mainItem.hovered || mainItem.activeFocus + property bool keyboardFocus: FocusHelper.keyboardFocus + property bool shadowEnabled: mainItem.hovered || mainItem.activeFocus && !keyboardFocus hoverEnabled: true + // Border properties + property color borderColor: "transparent" + property color keyboardFocusedBorderColor: DefaultStyle.main2_900 + property real borderWidth: 0 + property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3) background: Item{ x: mainItem.leftPadding y: mainItem.topPadding + mainItem.availableHeight / 2 - height / 2 - implicitWidth: Math.round(200 * DefaultStyle.dp) - implicitHeight: Math.round(4 * DefaultStyle.dp) + implicitWidth: Utils.getSizeWithScreenRatio(200) + implicitHeight: Utils.getSizeWithScreenRatio(4) width: mainItem.availableWidth height: implicitHeight Rectangle { id: sliderBackground anchors.fill: parent - radius: Math.round(30 * DefaultStyle.dp) + radius: Math.round(height / 2) // TODO : change the colors when mockup indicates their names color: DefaultStyle.grey_850 @@ -30,7 +38,7 @@ Control.Slider { GradientStop { position: 0.0; color: DefaultStyle.main1_300 } GradientStop { position: 1.0; color: DefaultStyle.main1_500_main } } - radius: Math.round(40 * DefaultStyle.dp) + radius: Math.round(height / 2) } } MultiEffect { @@ -49,13 +57,15 @@ Control.Slider { handle: Item { x: mainItem.leftPadding + mainItem.visualPosition * (mainItem.availableWidth - width) y: mainItem.topPadding + mainItem.availableHeight / 2 - height / 2 - implicitWidth: Math.round(16 * DefaultStyle.dp) - implicitHeight: Math.round(16 * DefaultStyle.dp) + implicitWidth: Utils.getSizeWithScreenRatio(16) + implicitHeight: Utils.getSizeWithScreenRatio(16) Rectangle { id: handleRect anchors.fill: parent - radius: Math.round(30 * DefaultStyle.dp) + radius: Math.round(height / 2) color: DefaultStyle.grey_0 + border.color: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.borderColor + border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth } MultiEffect { source: handleRect @@ -63,7 +73,7 @@ Control.Slider { shadowEnabled: true shadowColor: DefaultStyle.grey_1000 shadowBlur: 0.1 - shadowOpacity: 0.1 + shadowOpacity: 0.5 } } } diff --git a/Linphone/view/Control/Button/Switch.qml b/Linphone/view/Control/Button/Switch.qml index 135ce8f82..91ef394c4 100644 --- a/Linphone/view/Control/Button/Switch.qml +++ b/Linphone/view/Control/Button/Switch.qml @@ -1,52 +1,69 @@ import QtQuick import QtQuick.Controls.Basic as Control import QtQuick.Effects - import Linphone +import CustomControls 1.0 +import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils Control.Switch { id: mainItem - property bool shadowEnabled: mainItem.hovered || mainItem.activeFocus hoverEnabled: true - font { + property bool keyboardFocus: FocusHelper.keyboardFocus + property bool shadowEnabled: mainItem.hovered || mainItem.activeFocus && !keyboardFocus + // Text properties + font { pixelSize: Typography.p1.pixelSize weight: Typography.p1.weight - } - indicator: Item{ - implicitWidth: Math.round(32 * DefaultStyle.dp) - implicitHeight: Math.round(20 * DefaultStyle.dp) - x: mainItem.leftPadding - y: parent.height / 2 - height / 2 - Rectangle { - id: indicatorBackground - anchors.fill: parent - radius: Math.round(10 * DefaultStyle.dp) - color: mainItem.checked? DefaultStyle.success_500main : DefaultStyle.main2_400 - - Rectangle { - anchors.verticalCenter: parent.verticalCenter - property real margin: Math.round(4 * DefaultStyle.dp) - x: mainItem.checked ? parent.width - width - margin : margin - width: Math.round(12 * DefaultStyle.dp) - height: Math.round(12 * DefaultStyle.dp) - radius: Math.round(10 * DefaultStyle.dp) - color: DefaultStyle.grey_0 - Behavior on x { - NumberAnimation{duration: 100} - } - } - } + } + // Size properties + implicitHeight: Utils.getSizeWithScreenRatio(20) + implicitWidth: Math.round(implicitHeight * 1.6) + // Border properties + property color borderColor: "transparent" + property color keyboardFocusedBorderColor: DefaultStyle.main2_900 + property real borderWidth: 0 + property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3) + + indicator: Item { + id: indicatorItem + x: mainItem.leftPadding + y: parent.height / 2 - height / 2 + height: mainItem.height + width: mainItem.width + Rectangle { + id: indicatorBackground + anchors.fill: parent + radius: Math.round(indicatorItem.height / 2) + color: mainItem.checked ? DefaultStyle.success_500_main : DefaultStyle.main2_400 + border.color: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.borderColor + border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth + + Rectangle { + anchors.verticalCenter: parent.verticalCenter + height: Math.round(indicatorItem.height * 0.6) + width: height + property real margin: Math.round((indicatorItem.height - height) / 2) + radius: Math.round(height / 2) + x: mainItem.checked ? parent.width - width - margin : margin + color: DefaultStyle.grey_0 + Behavior on x { + NumberAnimation { + duration: 100 + } + } + } + } MultiEffect { - enabled: mainItem.shadowEnabled - anchors.fill: indicatorBackground - source: indicatorBackground - visible: mainItem.shadowEnabled - // Crash : https://bugreports.qt.io/browse/QTBUG-124730 - shadowEnabled: true //mainItem.shadowEnabled - shadowColor: DefaultStyle.grey_1000 - shadowBlur: 0.1 - shadowOpacity: mainItem.shadowEnabled ? 0.5 : 0.0 - } + enabled: mainItem.shadowEnabled + anchors.fill: indicatorBackground + source: indicatorBackground + visible: mainItem.shadowEnabled + // Crash : https://bugreports.qt.io/browse/QTBUG-124730 + shadowEnabled: true //mainItem.shadowEnabled + shadowColor: DefaultStyle.grey_1000 + shadowBlur: 0.1 + shadowOpacity: mainItem.shadowEnabled ? 0.5 : 0.0 + } } contentItem: Text { diff --git a/Linphone/view/Control/Container/Contact/PresenceNoteLayout.qml b/Linphone/view/Control/Container/Contact/PresenceNoteLayout.qml index a0155a77f..4e995b2cd 100644 --- a/Linphone/view/Control/Container/Contact/PresenceNoteLayout.qml +++ b/Linphone/view/Control/Container/Contact/PresenceNoteLayout.qml @@ -43,7 +43,7 @@ Rectangle { Text { font: Typography.p3 - color: DefaultStyle.main2_500main + color: DefaultStyle.main2_500_main text: mainItem.friendCore?.presenceNote || "" wrapMode: Text.Wrap Layout.fillWidth: true diff --git a/Linphone/view/Control/Container/CreationFormLayout.qml b/Linphone/view/Control/Container/CreationFormLayout.qml index c2998bf23..59501ba4f 100644 --- a/Linphone/view/Control/Container/CreationFormLayout.qml +++ b/Linphone/view/Control/Container/CreationFormLayout.qml @@ -6,6 +6,7 @@ import QtQuick.Effects import Linphone import UtilsCpp import SettingsCpp +import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils FocusScope { id: mainItem @@ -19,20 +20,20 @@ FocusScope { clip: true property alias topContent: topLayout.data property bool topLayoutVisible: topLayout.children.length > 0 - property int searchBarRightMaring: Math.round(39 * DefaultStyle.dp) + property int searchBarRightMaring: Utils.getSizeWithScreenRatio(39) ColumnLayout { anchors.fill: parent - spacing: Math.round(22 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(22) ColumnLayout { id: topLayout visible: mainItem.topLayoutVisible - spacing: Math.round(18 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(18) } ColumnLayout { onVisibleChanged: if (!visible && mainItem.numPadPopup) mainItem.numPadPopup.close() - spacing: Math.round(38 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(38) SearchBar { id: searchBar Layout.alignment: Qt.AlignTop @@ -44,28 +45,32 @@ FocusScope { //: "Rechercher un contact" placeholderText: qsTr("search_bar_look_for_contact_text") numericPadPopup: mainItem.numPadPopup - KeyNavigation.down: grouCreationButton + KeyNavigation.down: groupCreationButton } ColumnLayout { id: content - spacing: Math.round(32 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(32) Button { - id: grouCreationButton - Layout.preferredWidth: Math.round(320 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(44 * DefaultStyle.dp) + id: groupCreationButton + Layout.preferredWidth: Utils.getSizeWithScreenRatio(320) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(44) padding: 0 KeyNavigation.up: searchBar KeyNavigation.down: contactList onClicked: mainItem.groupCreationRequested() background: Rectangle { anchors.fill: parent - radius: Math.round(50 * DefaultStyle.dp) + radius: height / 2 gradient: Gradient { orientation: Gradient.Horizontal GradientStop { position: 0.0; color: DefaultStyle.main2_100} GradientStop { position: 1.0; color: DefaultStyle.grey_0} } + // Black border for keyboard navigation + border.color: DefaultStyle.main2_900 + border.width: groupCreationButton.keyboardFocus ? Utils.getSizeWithScreenRatio(3) : 0 } + Accessible.name: mainItem.startGroupButtonText contentItem: RowLayout { spacing: Math.round(16 * DefaultStyle.dp) anchors.verticalCenter: parent.verticalCenter @@ -96,9 +101,9 @@ FocusScope { } EffectImage { imageSource: AppIcons.rightArrow - Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) - colorizationColor: DefaultStyle.main2_500main + Layout.preferredWidth: Utils.getSizeWithScreenRatio(24) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(24) + colorizationColor: DefaultStyle.main2_500_main } } } diff --git a/Linphone/view/Control/Container/FormItemLayout.qml b/Linphone/view/Control/Container/FormItemLayout.qml index ff20e3623..9c8f932bd 100644 --- a/Linphone/view/Control/Container/FormItemLayout.qml +++ b/Linphone/view/Control/Container/FormItemLayout.qml @@ -67,6 +67,7 @@ FocusScope{ Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) style: ButtonStyle.noBackground icon.source: AppIcons.info + popUpTitle: mainItem.label popup.contentItem: Text { text: mainItem.tooltip } @@ -85,7 +86,7 @@ FocusScope{ TemporaryText { id: errorText anchors.top: contentItem.bottom - color: DefaultStyle.danger_500main + color: DefaultStyle.danger_500_main } } diff --git a/Linphone/view/Control/Container/GroupCreationFormLayout.qml b/Linphone/view/Control/Container/GroupCreationFormLayout.qml index 1948d9563..bd01db9c8 100644 --- a/Linphone/view/Control/Container/GroupCreationFormLayout.qml +++ b/Linphone/view/Control/Container/GroupCreationFormLayout.qml @@ -6,6 +6,7 @@ import QtQuick.Effects import Linphone import UtilsCpp import SettingsCpp +import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle FocusScope { @@ -22,16 +23,20 @@ FocusScope { spacing: 0 anchors.fill: parent RowLayout { - spacing: Math.round(10 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(10) Button { id: backGroupCallButton style: ButtonStyle.noBackgroundOrange icon.source: AppIcons.leftArrow - Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(30) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(30) + icon.width: Utils.getSizeWithScreenRatio(24) + icon.height: Utils.getSizeWithScreenRatio(24) KeyNavigation.down: groupName KeyNavigation.right: groupCallButton KeyNavigation.left: groupCallButton + //: Return + Accessible.name: qsTr("return_accessible_name") onClicked: { mainItem.returnRequested() } @@ -41,7 +46,7 @@ FocusScope { color: DefaultStyle.main1_500_main maximumLineCount: 1 font { - pixelSize: Math.round(18 * DefaultStyle.dp) + pixelSize: Utils.getSizeWithScreenRatio(18) weight: Typography.h4.weight } Layout.fillWidth: true @@ -49,7 +54,7 @@ FocusScope { SmallButton { id: groupCallButton enabled: mainItem.selectedParticipantsCount.length != 0 - Layout.rightMargin: Math.round(21 * DefaultStyle.dp) + Layout.rightMargin: Utils.getSizeWithScreenRatio(21) text: mainItem.createGroupButtonText style: ButtonStyle.main KeyNavigation.down: addParticipantsLayout @@ -62,8 +67,8 @@ FocusScope { } RowLayout { spacing: 0 - Layout.topMargin: Math.round(18 * DefaultStyle.dp) - Layout.rightMargin: Math.round(38 * DefaultStyle.dp) + Layout.topMargin: Utils.getSizeWithScreenRatio(18) + Layout.rightMargin: Utils.getSizeWithScreenRatio(38) Text { font.pixelSize: Typography.p2.pixelSize font.weight: Typography.p2.weight @@ -74,8 +79,8 @@ FocusScope { Layout.fillWidth: true } Text { - font.pixelSize: Math.round(12 * DefaultStyle.dp) - font.weight: Math.round(300 * DefaultStyle.dp) + font.pixelSize: Utils.getSizeWithScreenRatio(12) + font.weight: Utils.getSizeWithScreenRatio(300) //: "Requis" text: qsTr("required") } @@ -83,16 +88,17 @@ FocusScope { TextField { id: groupName Layout.fillWidth: true - Layout.rightMargin: Math.round(38 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(49 * DefaultStyle.dp) + Layout.rightMargin: Utils.getSizeWithScreenRatio(38) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(49) focus: true KeyNavigation.down: addParticipantsLayout //participantList.count > 0 ? participantList : searchbar + Accessible.name: qsTr("group_start_dialog_subject_hint") } AddParticipantsForm { id: addParticipantsLayout Layout.fillWidth: true Layout.fillHeight: true - Layout.topMargin: Math.round(15 * DefaultStyle.dp) + Layout.topMargin: Utils.getSizeWithScreenRatio(15) onSelectedParticipantsCountChanged: mainItem.selectedParticipantsCount = selectedParticipantsCount focus: true diff --git a/Linphone/view/Control/Container/TabBar.qml b/Linphone/view/Control/Container/TabBar.qml index 005b79f18..26d70c3b9 100644 --- a/Linphone/view/Control/Container/TabBar.qml +++ b/Linphone/view/Control/Container/TabBar.qml @@ -3,6 +3,8 @@ import QtQuick.Layouts import QtQuick.Controls.Basic as Control import QtQuick.Effects import Linphone +import CustomControls 1.0 +import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils Control.TabBar { id: mainItem @@ -20,7 +22,7 @@ Control.TabBar { Rectangle { id: barBG - height: Math.round(4 * DefaultStyle.dp) + height: Utils.getSizeWithScreenRatio(4) color: DefaultStyle.grey_200 anchors.bottom: parent.bottom width: parent.width @@ -49,9 +51,11 @@ Control.TabBar { required property string modelData required property int index property bool shadowEnabled: activeFocus || hovered + property bool keyboardFocus: FocusHelper.keyboardFocus width: implicitWidth activeFocusOnTab: true hoverEnabled: true + Accessible.name: modelData ToolTip { visible: tabText.truncated && hovered delay: 1000 @@ -65,27 +69,35 @@ Control.TabBar { background: Item { anchors.fill: parent - visible: mainItem.currentIndex === index || tabButton.hovered - Rectangle { id: tabBackground - height: Math.round(5 * DefaultStyle.dp) + visible: mainItem.currentIndex === index || tabButton.hovered + height: Utils.getSizeWithScreenRatio(5) color: mainItem.currentIndex === index ? DefaultStyle.main1_500_main : DefaultStyle.main2_400 anchors.bottom: parent.bottom anchors.left: parent.left anchors.right: parent.right } MultiEffect { + visible: (mainItem.currentIndex === index || tabButton.hovered) && tabButton.shadowEnabled enabled: tabButton.shadowEnabled anchors.fill: tabBackground source: tabBackground - visible: tabButton.shadowEnabled // Crash : https://bugreports.qt.io/browse/QTBUG-124730 shadowEnabled: true //mainItem.shadowEnabled shadowColor: DefaultStyle.grey_1000 shadowBlur: 0.1 shadowOpacity: tabButton.shadowEnabled ? 0.5 : 0.0 } + Rectangle{ + id: borderBackground + visible: tabButton.keyboardFocus + height: tabButton.height + width: tabButton.width + color: "transparent" + border.color: "black" + border.width: 3 + } } contentItem: Text { @@ -100,7 +112,7 @@ Control.TabBar { elide: Text.ElideRight maximumLineCount: 1 text: modelData - bottomPadding: Math.round(5 * DefaultStyle.dp) + bottomPadding: Utils.getSizeWithScreenRatio(5) } } } diff --git a/Linphone/view/Control/Container/VerticalTabBar.qml b/Linphone/view/Control/Container/VerticalTabBar.qml index c6c33b773..e28c89bc1 100644 --- a/Linphone/view/Control/Container/VerticalTabBar.qml +++ b/Linphone/view/Control/Container/VerticalTabBar.qml @@ -2,14 +2,15 @@ import QtQuick import QtQuick.Layouts import QtQuick.Controls.Basic as Control import QtQuick.Effects - import Linphone import SettingsCpp +import CustomControls 1.0 +import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils Control.TabBar { id: mainItem - //spacing: Math.round(32 * DefaultStyle.dp) - topPadding: Math.round(36 * DefaultStyle.dp) + //spacing: Utils.getSizeWithScreenRatio(32) + topPadding: Utils.getSizeWithScreenRatio(36) property var model readonly property alias cornerRadius: bottomLeftCorner.radius @@ -38,10 +39,10 @@ Control.TabBar { component UnreadNotification: Rectangle { property int unread: 0 visible: unread > 0 - width: Math.round(15 * DefaultStyle.dp) - height: Math.round(15 * DefaultStyle.dp) + width: Utils.getSizeWithScreenRatio(15) + height: Utils.getSizeWithScreenRatio(15) radius: width/2 - color: DefaultStyle.danger_500main + color: DefaultStyle.danger_500_main Text{ id: unreadCount anchors.fill: parent @@ -77,7 +78,7 @@ Control.TabBar { id: bottomLeftCorner anchors.fill: parent color: DefaultStyle.main1_500_main - radius: Math.round(25 * DefaultStyle.dp) + radius: Utils.getSizeWithScreenRatio(25) } Rectangle { color: DefaultStyle.main1_500_main @@ -100,10 +101,12 @@ Control.TabBar { id: tabButton width: mainItem.width height: visible && buttonIcon.isImageReady ? undefined : 0 - bottomInset: Math.round(32 * DefaultStyle.dp) - topInset: Math.round(32 * DefaultStyle.dp) + bottomInset: Utils.getSizeWithScreenRatio(32) + topInset: Utils.getSizeWithScreenRatio(32) hoverEnabled: true visible: modelData?.visible != undefined ? modelData.visible : true + text: modelData.accessibilityLabel + property bool keyboardFocus: FocusHelper.keyboardFocus UnreadNotification { unread: !defaultAccount ? -1 @@ -113,18 +116,27 @@ Control.TabBar { ? defaultAccount.core?.unreadMessageNotifications || -1 : 0 anchors.right: parent.right - anchors.rightMargin: Math.round(15 * DefaultStyle.dp) + anchors.rightMargin: Utils.getSizeWithScreenRatio(15) anchors.top: parent.top } MouseArea { anchors.fill: tabButton cursorShape: tabButton.hovered ? Qt.PointingHandCursor : Qt.ArrowCursor - acceptedButtons: Qt.NoButton + acceptedButtons: Qt.NoButton + } + background: Rectangle{ + // Black border for keyboard navigation + visible: tabButton.keyboardFocus + color: "transparent" + border.color: DefaultStyle.main2_900 + border.width: Utils.getSizeWithScreenRatio(3) + radius: Utils.getSizeWithScreenRatio(5) + anchors.fill: tabButton } contentItem: ColumnLayout { EffectImage { id: buttonIcon - property real buttonSize: mainItem.currentIndex !== index && tabButton.hovered ? Math.round(26 * DefaultStyle.dp) : Math.round(24 * DefaultStyle.dp) + property real buttonSize: mainItem.currentIndex !== index && tabButton.hovered ? Utils.getSizeWithScreenRatio(26) : Utils.getSizeWithScreenRatio(24) imageSource: mainItem.currentIndex === index ? modelData.selectedIcon : modelData.icon Layout.preferredWidth: buttonSize Layout.preferredHeight: buttonSize @@ -138,20 +150,20 @@ Control.TabBar { visible: buttonIcon.isImageReady text: modelData.label font { - weight: mainItem.currentIndex === index - ? Math.round(800 * DefaultStyle.dp) + weight: mainItem.currentIndex === index + ? Utils.getSizeWithScreenRatio(800) : tabButton.hovered - ? Math.round(600 * DefaultStyle.dp) - : Math.round(400 * DefaultStyle.dp) - pixelSize: Math.round(11 * DefaultStyle.dp) + ? Utils.getSizeWithScreenRatio(600) + : Utils.getSizeWithScreenRatio(400) + pixelSize: Utils.getSizeWithScreenRatio(11) } color: DefaultStyle.grey_0 Layout.fillWidth: true Layout.preferredHeight: txtMeter.height Layout.alignment: Qt.AlignHCenter horizontalAlignment: Text.AlignHCenter - leftPadding: Math.round(3 * DefaultStyle.dp) - rightPadding: Math.round(3 * DefaultStyle.dp) + leftPadding: Utils.getSizeWithScreenRatio(3) + rightPadding: Utils.getSizeWithScreenRatio(3) } } TextMetrics { @@ -159,15 +171,13 @@ Control.TabBar { text: modelData.label font: buttonText.font Component.onCompleted: { - font.weight = Math.round(800 * DefaultStyle.dp) + font.weight = Utils.getSizeWithScreenRatio(800) mainItem.implicitWidth = Math.max(mainItem.implicitWidth, advanceWidth + buttonIcon.buttonSize) } } onClicked: { mainItem.setCurrentIndex(TabBar.index) } - - background: Item {} } } } diff --git a/Linphone/view/Control/Display/Call/CallHistoryListView.qml b/Linphone/view/Control/Display/Call/CallHistoryListView.qml index 0fb216edc..6aca4aac5 100644 --- a/Linphone/view/Control/Display/Call/CallHistoryListView.qml +++ b/Linphone/view/Control/Display/Call/CallHistoryListView.qml @@ -15,7 +15,7 @@ ListView { property SearchBar searchBar property bool loading: false property string searchText: searchBar?.text - property real busyIndicatorSize: Math.round(60 * DefaultStyle.dp) + property real busyIndicatorSize: Utils.getSizeWithScreenRatio(60) signal resultsReceived @@ -34,14 +34,14 @@ ListView { onFilterTextChanged: maxDisplayItems = initialDisplayItems initialDisplayItems: Math.max( 20, - 2 * mainItem.height / (Math.round(56 * DefaultStyle.dp))) + 2 * mainItem.height / (Utils.getSizeWithScreenRatio(56))) displayItemsStep: 3 * initialDisplayItems / 2 onModelReset: { mainItem.resultsReceived() } } flickDeceleration: 10000 - spacing: Math.round(10 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(10) Keys.onPressed: event => { if (event.key == Qt.Key_Escape) { @@ -122,20 +122,20 @@ ListView { property int lastMouseContainsIndex: -1 delegate: FocusScope { width: mainItem.width - height: Math.round(56 * DefaultStyle.dp) + height: Utils.getSizeWithScreenRatio(56) RowLayout { z: 1 anchors.fill: parent - anchors.leftMargin: Math.round(10 * DefaultStyle.dp) - spacing: Math.round(10 * DefaultStyle.dp) + anchors.leftMargin: Utils.getSizeWithScreenRatio(10) + spacing: Utils.getSizeWithScreenRatio(10) Avatar { id: historyAvatar property var contactObj: UtilsCpp.findFriendByAddress(modelData.core.remoteAddress) contact: contactObj?.value || null displayNameVal: modelData.core.displayName secured: securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified - width: Math.round(45 * DefaultStyle.dp) - height: Math.round(45 * DefaultStyle.dp) + width: Utils.getSizeWithScreenRatio(45) + height: Utils.getSizeWithScreenRatio(45) isConference: modelData.core.isConference shadowEnabled: false asynchronous: false @@ -143,7 +143,7 @@ ListView { ColumnLayout { Layout.fillHeight: true Layout.fillWidth: true - spacing: Math.round(5 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(5) Text { Layout.fillWidth: true maximumLineCount: 1 @@ -154,7 +154,7 @@ ListView { } } RowLayout { - spacing: Math.round(6 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(6) EffectImage { id: statusIcon imageSource: modelData.core.status === LinphoneEnums.CallStatus.Declined @@ -170,9 +170,9 @@ ListView { === LinphoneEnums.CallStatus.Aborted || modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted - || modelData.core.status === LinphoneEnums.CallStatus.Missed ? DefaultStyle.danger_500main : modelData.core.isOutgoing ? DefaultStyle.info_500_main : DefaultStyle.success_500main - Layout.preferredWidth: Math.round(12 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(12 * DefaultStyle.dp) + || modelData.core.status === LinphoneEnums.CallStatus.Missed ? DefaultStyle.danger_500_main : modelData.core.isOutgoing ? DefaultStyle.info_500_main : DefaultStyle.success_500_main + Layout.preferredWidth: Utils.getSizeWithScreenRatio(12) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(12) transform: Rotation { angle: modelData.core.isOutgoing && (modelData.core.status === LinphoneEnums.CallStatus.Declined @@ -191,8 +191,8 @@ ListView { // text: modelData.core.date text: UtilsCpp.formatDate(modelData.core.date) font { - pixelSize: Math.round(12 * DefaultStyle.dp) - weight: Math.round(300 * DefaultStyle.dp) + pixelSize: Utils.getSizeWithScreenRatio(12) + weight: Utils.getSizeWithScreenRatio(300) } } } @@ -203,6 +203,8 @@ ListView { focus: true activeFocusOnTab: false asynchronous: false + //: Call %1 + Accessible.name: qsTr("call_name_accessible_button").arg(historyAvatar.displayNameVal) onClicked: { if (modelData.core.isConference) { var callsWindow = UtilsCpp.getCallsWindow() @@ -228,7 +230,7 @@ ListView { Rectangle { anchors.fill: parent opacity: 0.7 - radius: Math.round(8 * DefaultStyle.dp) + radius: Utils.getSizeWithScreenRatio(8) color: mainItem.currentIndex === index ? DefaultStyle.main2_200 : DefaultStyle.main2_100 visible: mainItem.lastMouseContainsIndex === index diff --git a/Linphone/view/Control/Display/Call/CallListView.qml b/Linphone/view/Control/Display/Call/CallListView.qml index 73bb0a2b4..ffacb2915 100644 --- a/Linphone/view/Control/Display/Call/CallListView.qml +++ b/Linphone/view/Control/Display/Call/CallListView.qml @@ -24,9 +24,12 @@ ListView { property string currentRemoteAddress: AppCpp.calls.currentCall ? AppCpp.calls.currentCall.core.remoteAddress : "" delegate: RowLayout { + id: callInformationItem spacing: Math.round(8 * DefaultStyle.dp) width: mainItem.width height: Math.round(45 * DefaultStyle.dp) + property var remoteNameObj: UtilsCpp.getDisplayName(modelData.core.remoteAddress) + property var callName : modelData.core.isConference ? modelData.core.conference.core.subject : remoteNameObj ? remoteNameObj.value : "" Avatar { id: delegateAvatar Layout.preferredWidth: Math.round(45 * DefaultStyle.dp) @@ -41,9 +44,7 @@ ListView { Text { id: delegateName property var remoteNameObj: UtilsCpp.getDisplayName(modelData.core.remoteAddress) - text: modelData.core.isConference - ? modelData.core.conference.core.subject - : remoteNameObj ? remoteNameObj.value : "" + text: callInformationItem.callName font.pixelSize: Math.round(14 * DefaultStyle.dp) Layout.fillWidth: true maximumLineCount: 1 @@ -79,6 +80,8 @@ ListView { onClicked: { mainItem.transferCallToAnotherRequested(modelData) } + //: Transfer call %1 + Accessible.name: qsTr("transfer_call_name_accessible_name").arg(callInformationItem.callName) } Button { id: pausingButton @@ -91,7 +94,7 @@ ListView { topPadding: Math.round(5 * DefaultStyle.dp) bottomPadding: Math.round(5 * DefaultStyle.dp) property bool pausedByUser: modelData.core.state === LinphoneEnums.CallState.Paused - color: pausedByUser ? DefaultStyle.success_500main : DefaultStyle.grey_500 + color: pausedByUser ? DefaultStyle.success_500_main : DefaultStyle.grey_500 contentImageColor: DefaultStyle.grey_0 KeyNavigation.right: endCallButton KeyNavigation.left: endCallButton @@ -104,6 +107,12 @@ ListView { text: pausingButton.text font.bold: true } + Accessible.name: (pausedByUser ? + //: Resume %1 call + qsTr("resume_call_name_accessible_name") : + //: Pause %1 call + qsTr("pause_call_name_accessible_name") + ).arg(callInformationItem.callName) } SmallButton { id: endCallButton @@ -124,6 +133,8 @@ ListView { text: endCallButton.text font.bold: true } + //: End %1 call + Accessible.name: qsTr("end_call_name_accessible_name").arg(callInformationItem.callName) } } } diff --git a/Linphone/view/Control/Display/Chat/ChatListView.qml b/Linphone/view/Control/Display/Chat/ChatListView.qml index d80d40be1..df0b9960c 100644 --- a/Linphone/view/Control/Display/Chat/ChatListView.qml +++ b/Linphone/view/Control/Display/Chat/ChatListView.qml @@ -141,7 +141,7 @@ ListView { id: background anchors.fill: parent radius: width/2 - color: DefaultStyle.danger_500main + color: DefaultStyle.danger_500_main Text{ anchors.fill: parent verticalAlignment: Text.AlignVCenter @@ -295,7 +295,7 @@ ListView { RowLayout { Item{Layout.fillWidth: true} Text { - color: DefaultStyle.main2_500main + color: DefaultStyle.main2_500_main text: modelData ? UtilsCpp.formatDate(modelData.core.lastUpdatedTime, true, false) : "" font { pixelSize: Typography.p3.pixelSize diff --git a/Linphone/view/Control/Display/Chat/ChatMessage.qml b/Linphone/view/Control/Display/Chat/ChatMessage.qml index 8f5bd1faf..93cd2ec8f 100644 --- a/Linphone/view/Control/Display/Chat/ChatMessage.qml +++ b/Linphone/view/Control/Display/Chat/ChatMessage.qml @@ -73,7 +73,7 @@ Control.Control { width: implicitWidth x: mapToItem(this, chatBubble.x, chatBubble.y).x text: mainItem.chatMessage.core.fromName - color: DefaultStyle.main2_500main + color: DefaultStyle.main2_500_main font { pixelSize: Typography.p4.pixelSize weight: Typography.p4.weight @@ -87,7 +87,7 @@ Control.Control { Layout.alignment: mainItem.isRemoteMessage ? Qt.AlignLeft: Qt.AlignRight EffectImage { imageSource: AppIcons.forward - colorizationColor: DefaultStyle.main2_500main + colorizationColor: DefaultStyle.main2_500_main Layout.preferredWidth: Math.round(12 * DefaultStyle.dp) Layout.preferredHeight: Math.round(12 * DefaultStyle.dp) } @@ -115,7 +115,7 @@ Control.Control { Layout.alignment: mainItem.isRemoteMessage ? Qt.AlignLeft : Qt.AlignRight EffectImage { imageSource: AppIcons.reply - colorizationColor: DefaultStyle.main2_500main + colorizationColor: DefaultStyle.main2_500_main Layout.preferredWidth: Math.round(12 * DefaultStyle.dp) Layout.preferredHeight: Math.round(12 * DefaultStyle.dp) } @@ -270,7 +270,7 @@ Control.Control { Text { id: ephemeralTime visible: mainItem.chatMessage.core.isEphemeral - color: DefaultStyle.main2_500main + color: DefaultStyle.main2_500_main text: UtilsCpp.formatDuration(mainItem.chatMessage.core.ephemeralDuration * 1000) font { pixelSize: Typography.p3.pixelSize @@ -280,7 +280,7 @@ Control.Control { EffectImage { visible: mainItem.chatMessage.core.isEphemeral imageSource: AppIcons.clockCountDown - colorizationColor: DefaultStyle.main2_500main + colorizationColor: DefaultStyle.main2_500_main Layout.preferredWidth: visible ? 14 * DefaultStyle.dp : 0 Layout.preferredHeight: visible ? 14 * DefaultStyle.dp : 0 } @@ -292,7 +292,7 @@ Control.Control { Text { Layout.alignment: Qt.AlignVCenter text: UtilsCpp.formatDate(mainItem.chatMessage.core.timestamp, true, false, "dd/MM") - color: DefaultStyle.main2_500main + color: DefaultStyle.main2_500_main font { pixelSize: Typography.p3.pixelSize weight: Typography.p3.weight diff --git a/Linphone/view/Control/Display/Chat/ChatMessageInvitationBubble.qml b/Linphone/view/Control/Display/Chat/ChatMessageInvitationBubble.qml index 8f24f8aee..73b6420f8 100644 --- a/Linphone/view/Control/Display/Chat/ChatMessageInvitationBubble.qml +++ b/Linphone/view/Control/Display/Chat/ChatMessageInvitationBubble.qml @@ -71,7 +71,7 @@ ColumnLayout { conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Updated ? DefaultStyle.warning_600 : conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Cancelled ? - DefaultStyle.danger_500main : + DefaultStyle.danger_500_main : DefaultStyle.main2_600 } @@ -109,7 +109,7 @@ ColumnLayout { Layout.fillWidth: true // Layout.preferredWidth: advancedWidth text: conferenceInfo.dateTime.toLocaleString(Qt.locale(), "ddd") - color: DefaultStyle.main2_500main + color: DefaultStyle.main2_500_main font { pixelSize: Typography.p4.pixelSize weight: Typography.p4.weight @@ -161,7 +161,7 @@ ColumnLayout { Text { text: conferenceInfo.dateTime.toLocaleString(Qt.locale(), "dddd d MMMM yyyy") font: Typography.p4 - color: DefaultStyle.main2_500main + color: DefaultStyle.main2_500_main } Text { //: from %1 to %2 (UTC%3) @@ -171,14 +171,14 @@ ColumnLayout { text: qsTr("").arg( conferenceInfo.dateTime.toLocaleString(Qt.locale(), "hh:mm")).arg( conferenceInfo.endDateTime.toLocaleString(Qt.locale(), "hh:mm")).arg(offsetFromUtc) - color: DefaultStyle.main2_500main + color: DefaultStyle.main2_500_main font: Typography.p4 } Text { text: timeRangeText font: Typography.p4 - color: DefaultStyle.main2_500main + color: DefaultStyle.main2_500_main } } } @@ -244,7 +244,7 @@ ColumnLayout { wrapMode: Text.WordWrap textFormat: Text.RichText font: Typography.p4 - color: DefaultStyle.main2_500main + color: DefaultStyle.main2_500_main maximumLineCount: 3 elide: Text.ElideRight visible: conferenceInfo.description.length > 0 diff --git a/Linphone/view/Control/Display/Chat/Event.qml b/Linphone/view/Control/Display/Chat/Event.qml index 7fd098567..801f37a4f 100644 --- a/Linphone/view/Control/Display/Chat/Event.qml +++ b/Linphone/view/Control/Display/Chat/Event.qml @@ -25,7 +25,7 @@ RowLayout { id: message text: eventLogCore.eventDetails font: Typography.p3 - color: eventLogCore.important ? DefaultStyle.danger_500main : DefaultStyle.main2_500main + color: eventLogCore.important ? DefaultStyle.danger_500_main : DefaultStyle.main2_500_main horizontalAlignment: Text.AlignHCenter Layout.alignment: Qt.AlignHCenter } @@ -33,7 +33,7 @@ RowLayout { id: date text: UtilsCpp.toDateTimeString(eventLogCore.timestamp) font: Typography.p3 - color: DefaultStyle.main2_500main + color: DefaultStyle.main2_500_main horizontalAlignment: Text.AlignHCenter Layout.alignment: Qt.AlignHCenter } diff --git a/Linphone/view/Control/Display/Chat/FileView.qml b/Linphone/view/Control/Display/Chat/FileView.qml index 1db5ed529..a88b37f78 100644 --- a/Linphone/view/Control/Display/Chat/FileView.qml +++ b/Linphone/view/Control/Display/Chat/FileView.qml @@ -119,7 +119,7 @@ Item { width: Math.round(24 * DefaultStyle.dp) height: Math.round(24 * DefaultStyle.dp) imageSource: AppIcons.playFill - colorizationColor: DefaultStyle.main2_0 + colorizationColor: DefaultStyle.main2_000 } Text { z: parent.z + 1 diff --git a/Linphone/view/Control/Display/Contact/Avatar.qml b/Linphone/view/Control/Display/Contact/Avatar.qml index 7e0f91ff7..303a60c5b 100644 --- a/Linphone/view/Control/Display/Contact/Avatar.qml +++ b/Linphone/view/Control/Display/Contact/Avatar.qml @@ -94,7 +94,7 @@ Loader{ color: "transparent" border { width: Math.round(2 * DefaultStyle.dp) - color: mainItem.secured ? DefaultStyle.info_500_main : DefaultStyle.danger_500main + color: mainItem.secured ? DefaultStyle.info_500_main : DefaultStyle.danger_500_main } EffectImage { x: parent.width / 7 diff --git a/Linphone/view/Control/Display/Contact/Contact.qml b/Linphone/view/Control/Display/Contact/Contact.qml index 38e4d0083..21e36cba8 100644 --- a/Linphone/view/Control/Display/Contact/Contact.qml +++ b/Linphone/view/Control/Display/Contact/Contact.qml @@ -8,24 +8,44 @@ import QtQuick.Controls.Basic as Control import Linphone import UtilsCpp import SettingsCpp +import CustomControls 1.0 import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle Control.Control{ id: mainItem - padding: Math.round(10 * DefaultStyle.dp) + activeFocusOnTab: true + padding: Utils.getSizeWithScreenRatio(10) property AccountGui account - property color backgroundColor: DefaultStyle.grey_0 - leftPadding: Math.round(8 * DefaultStyle.dp) - rightPadding: Math.round(8 * DefaultStyle.dp) + leftPadding: Utils.getSizeWithScreenRatio(8) + rightPadding: Utils.getSizeWithScreenRatio(8) + property var style + + property bool isSelected + property bool keyboardFocus: FocusHelper.keyboardFocus + + // Background properties + readonly property color defaultBackgroundColor: style?.color?.normal ?? DefaultStyle.grey_0 + readonly property color hoveredBackgroundColor: style?.color?.hovered ?? defaultBackgroundColor + readonly property color selectedBackgroundColor: style?.color?.selected ?? defaultBackgroundColor + readonly property color focusedBackgroundColor: style?.color?.keybaordFocused ?? defaultBackgroundColor + // Border properties + readonly property color defaultBorderColor: style?.borderColor?.normal ?? "transparent" + readonly property color hoveredBorderColor: style?.borderColor?.hovered ?? defaultBorderColor + readonly property color selectedBorderColor: style?.borderColor?.selected ?? defaultBorderColor + readonly property color keyboardFocusedBorderColor: style?.borderColor?.keybaordFocused || DefaultStyle.main2_900 + property real borderWidth: Utils.getSizeWithScreenRatio(1) + property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3) signal avatarClicked() signal backgroundClicked() signal edit() background: Rectangle { - radius: Math.round(10 * DefaultStyle.dp) - color: mainItem.backgroundColor + radius: Utils.getSizeWithScreenRatio(10) + color: mainItem.isSelected ? mainItem.selectedBackgroundColor : hovered ? mainItem.hoveredBackgroundColor : mainItem.defaultBackgroundColor + border.color: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.isSelected ? mainItem.selectedBorderColor : hovered ? mainItem.hoveredBorderColor : mainItem.defaultBorderColor + border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth MouseArea{ id: mouseArea anchors.fill: parent @@ -35,21 +55,39 @@ Control.Control{ contentItem: RowLayout{ spacing: 0 RowLayout { - spacing: Math.round(10 * DefaultStyle.dp) - Avatar{ - id: avatar - Layout.preferredWidth: Math.round(45 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(45 * DefaultStyle.dp) - account: mainItem.account - MouseArea{ + spacing: Utils.getSizeWithScreenRatio(10) + Button { + id: avatarButton + onClicked: mainItem.avatarClicked() + Layout.preferredWidth: Utils.getSizeWithScreenRatio(45) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(45) + color: "transparent" + contentItem: Item{ anchors.fill: parent - onClicked: mainItem.avatarClicked() - } + width: avatarButton.width + height: avatarButton.height + Avatar{ + id: avatar + height: avatarButton.height + width: avatarButton.width + account: mainItem.account + } + Rectangle{ + // Black border for keyboard navigation + visible: avatarButton.keyboardFocus + width: avatarButton.width + height: avatarButton.height + color: "transparent" + border.color: DefaultStyle.main2_900 + border.width: Utils.getSizeWithScreenRatio(3) + radius: width / 2 + } + } } Item { - Layout.preferredWidth: Math.round(200 * DefaultStyle.dp) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(200) Layout.fillHeight: true - Layout.rightMargin: Math.round(10 * DefaultStyle.dp) + Layout.rightMargin: Utils.getSizeWithScreenRatio(10) ContactDescription{ id: description anchors.fill: parent @@ -57,118 +95,26 @@ Control.Control{ } } } - PopupButton { - id: presenceAndRegistrationItem - Layout.minimumWidth: Math.round(86 * DefaultStyle.dp) - Layout.maximumWidth: Math.round(150 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) - Layout.preferredWidth: presenceOrRegistrationText.implicitWidth + Math.round(50 * DefaultStyle.dp) - enabled: mainItem.account && mainItem.account.core.registrationState === LinphoneEnums.RegistrationState.Ok - onEnabledChanged: if(!enabled) close() - contentItem: Rectangle { - id: presenceBar - property bool isRegistered: mainItem.account?.core.registrationState === LinphoneEnums.RegistrationState.Ok - color: DefaultStyle.main2_200 - radius: Math.round(15 * DefaultStyle.dp) - RowLayout { - anchors.fill: parent - Image { - id: registrationImage - sourceSize.width: Math.round(11 * DefaultStyle.dp) - sourceSize.height: Math.round(11 * DefaultStyle.dp) - smooth: false - Layout.preferredWidth: Math.round(11 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(11 * DefaultStyle.dp) - source: presenceBar.isRegistered - ? mainItem.account.core.presenceIcon - : mainItem.account?.core.registrationIcon || "" - Layout.leftMargin: Math.round(8 * DefaultStyle.dp) - RotationAnimator on rotation { - running: mainItem.account && mainItem.account.core.registrationState === LinphoneEnums.RegistrationState.Progress - direction: RotationAnimator.Clockwise - from: 0 - to: 360 - loops: Animation.Infinite - duration: 10000 - } - } - Text { - id: presenceOrRegistrationText - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - visible: mainItem.account - // Test texts - // Timer{ - // running: true - // interval: 1000 - // repeat: true - // onTriggered: text.mode = (++text.mode) % 4 - // } - font.weight: Math.round(300 * DefaultStyle.dp) - font.pixelSize: Math.round(12 * DefaultStyle.dp) - color: presenceBar.isRegistered ? mainItem.account.core.presenceColor : mainItem.account?.core.registrationColor - text: presenceBar.isRegistered ? mainItem.account.core.presenceStatus : mainItem.account?.core.humaneReadableRegistrationState - } - EffectImage { - fillMode: Image.PreserveAspectFit - imageSource: AppIcons.downArrow - colorizationColor: DefaultStyle.main2_600 - Layout.preferredHeight: Math.round(14 * DefaultStyle.dp) - Layout.preferredWidth: Math.round(14 * DefaultStyle.dp) - Layout.rightMargin: 8 * DefaultStyle.dp - } - } - } - popup.contentItem: Rectangle { - implicitWidth: 280 * DefaultStyle.dp - implicitHeight: 20 * DefaultStyle.dp + (setCustomStatus.visible ? 240 * DefaultStyle.dp : setPresence.implicitHeight) - Presence { - id: setPresence - anchors.fill: parent - anchors.margins: 20 * DefaultStyle.dp - accountCore: mainItem.account.core - onSetCustomStatusClicked: { - setPresence.visible = false - setCustomStatus.visible = true - } - onIsSet: presenceAndRegistrationItem.popup.close() - } - PresenceSetCustomStatus { - id: setCustomStatus - visible: false - anchors.fill: parent - anchors.margins: 20 * DefaultStyle.dp - accountCore: mainItem.account.core - onVisibleChanged: { - if (!visible) { - setPresence.visible = true - setCustomStatus.visible = false - } - } - onIsSet: presenceAndRegistrationItem.popup.close() - } - } - } - + ContactStatusPopup{} Item{ - Layout.preferredWidth: Math.round(26 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(26 * DefaultStyle.dp) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(26) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(26) Layout.fillHeight: true - Layout.leftMargin: Math.round(40 * DefaultStyle.dp) + Layout.leftMargin: Utils.getSizeWithScreenRatio(40) visible: mainItem.account.core.unreadNotifications > 0 Rectangle{ id: unreadNotifications anchors.verticalCenter: parent.verticalCenter - width: Math.round(26 * DefaultStyle.dp) - height: Math.round(26 * DefaultStyle.dp) + width: Utils.getSizeWithScreenRatio(26) + height: Utils.getSizeWithScreenRatio(26) radius: width/2 - color: DefaultStyle.danger_500main + color: DefaultStyle.danger_500_main border.color: DefaultStyle.grey_0 - border.width: Math.round(2 * DefaultStyle.dp) + border.width: Utils.getSizeWithScreenRatio(2) Text{ id: unreadCount anchors.fill: parent - anchors.margins: Math.round(2 * DefaultStyle.dp) + anchors.margins: Utils.getSizeWithScreenRatio(2) verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter color: DefaultStyle.grey_0 @@ -188,10 +134,10 @@ Control.Control{ } } Voicemail { - Layout.leftMargin: Math.round(18 * DefaultStyle.dp) - Layout.rightMargin: Math.round(20 * DefaultStyle.dp) - Layout.preferredWidth: Math.round(30 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(26 * DefaultStyle.dp) + Layout.leftMargin: Utils.getSizeWithScreenRatio(18) + Layout.rightMargin: Utils.getSizeWithScreenRatio(20) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(30) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(26) scaleFactor: 0.7 showMwi: mainItem.account.core.showMwi visible: mainItem.account.core.voicemailAddress.length > 0 || mainItem.account.core.showMwi @@ -207,20 +153,19 @@ Control.Control{ } } Item{Layout.fillWidth: true} - EffectImage { + Button { id: manageAccount - imageSource: AppIcons.manageProfile - Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) - Layout.alignment: Qt.AlignHCenter + style: ButtonStyle.noBackground + icon.source: AppIcons.manageProfile + Layout.preferredWidth: Utils.getSizeWithScreenRatio(30) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(30) + icon.width: Utils.getSizeWithScreenRatio(24) + icon.height: Utils.getSizeWithScreenRatio(24) visible: !SettingsCpp.hideAccountSettings - width: Math.round(24 * DefaultStyle.dp) - fillMode: Image.PreserveAspectFit - colorizationColor: DefaultStyle.main2_500main - MouseArea{ - anchors.fill: parent - onClicked: mainItem.edit() - cursorShape: Qt.PointingHandCursor + //: Account settings of %1 + Accessible.name: qsTr("account_settings_name_accessible_name") + onClicked: { + mainItem.edit() } } } diff --git a/Linphone/view/Control/Display/Contact/ContactListItem.qml b/Linphone/view/Control/Display/Contact/ContactListItem.qml index c9cf550bc..3e39f6730 100644 --- a/Linphone/view/Control/Display/Contact/ContactListItem.qml +++ b/Linphone/view/Control/Display/Contact/ContactListItem.qml @@ -40,6 +40,7 @@ FocusScope { signal clicked(var mouse) signal contactDeletionRequested(FriendGui contact) signal containsMouseChanged(bool containsMouse) + Accessible.name: displayName MouseArea { Text { @@ -200,9 +201,9 @@ FocusScope { : qsTr("contact_details_add_to_favourites") icon.source: searchResultItem.core.starred ? AppIcons.heartFill : AppIcons.heart spacing: Math.round(10 * DefaultStyle.dp) - textColor: DefaultStyle.main2_500main + textColor: DefaultStyle.main2_500_main hoveredImageColor: searchResultItem.core.starred ? DefaultStyle.main1_700 : DefaultStyle.danger_700 - contentImageColor: searchResultItem.core.starred ? DefaultStyle.danger_500main : DefaultStyle.main2_600 + contentImageColor: searchResultItem.core.starred ? DefaultStyle.danger_500_main : DefaultStyle.main2_600 onClicked: { searchResultItem.core.lSetStarred( !searchResultItem.core.starred) @@ -215,7 +216,7 @@ FocusScope { Layout.fillWidth: true icon.source: AppIcons.shareNetwork spacing: Math.round(10 * DefaultStyle.dp) - textColor: DefaultStyle.main2_500main + textColor: DefaultStyle.main2_500_main onClicked: { var vcard = searchResultItem.core.getVCard() var username = searchResultItem.core.givenName diff --git a/Linphone/view/Control/Display/Contact/ContactListView.qml b/Linphone/view/Control/Display/Contact/ContactListView.qml index ad7f0b155..3b9c213f8 100644 --- a/Linphone/view/Control/Display/Contact/ContactListView.qml +++ b/Linphone/view/Control/Display/Contact/ContactListView.qml @@ -40,9 +40,9 @@ ListView { property bool haveContacts: count > 0 property real sectionsPixelSize: Typography.h4.pixelSize property real sectionsWeight: Typography.h4.weight - property real sectionsSpacing: Math.round(18 * DefaultStyle.dp) + property real sectionsSpacing: Utils.getSizeWithScreenRatio(18) - property real itemsRightMargin: Math.round(39 * DefaultStyle.dp) + property real itemsRightMargin: Utils.getSizeWithScreenRatio(39) property bool expanded: true property real headerHeight: headerItem?.height @@ -56,7 +56,7 @@ ListView { highlightFollowsCurrentItem: false cacheBuffer: 400 implicitHeight: contentHeight - spacing: expanded ? Math.round(4 * DefaultStyle.dp) : 0 + spacing: expanded ? Utils.getSizeWithScreenRatio(4) : 0 onVisibleChanged: if (visible && !expanded) expanded = true @@ -150,7 +150,7 @@ ListView { Item{// Do not use directly RowLayout : there is an issue where the layout doesn't update on visible Layout.fillWidth: true Layout.preferredHeight: mainItem.count > 0 ? headerTitleLayout.implicitHeight : 0 - Layout.bottomMargin: Math.round(4 * DefaultStyle.dp) + Layout.bottomMargin: Utils.getSizeWithScreenRatio(4) RowLayout { id: headerTitleLayout anchors.fill: parent @@ -174,6 +174,11 @@ ListView { Layout.rightMargin: mainItem.itemsRightMargin focus: true onClicked: mainItem.expanded = !mainItem.expanded + Accessible.name: (mainItem.expanded ? + //: Shrink %1 + qsTr("shrink_accessible_name") : + //: Expand %1 + qsTr("expand_accessible_name")).arg(mainItem.title) } } } diff --git a/Linphone/view/Control/Display/Contact/ContactStatusPopup.qml b/Linphone/view/Control/Display/Contact/ContactStatusPopup.qml new file mode 100644 index 000000000..bf640f654 --- /dev/null +++ b/Linphone/view/Control/Display/Contact/ContactStatusPopup.qml @@ -0,0 +1,98 @@ +import QtQuick +import QtQuick.Effects + +import QtQuick.Layouts +import QtQuick.Controls.Basic as Control + + +import Linphone +import UtilsCpp +import SettingsCpp +import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils +import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle + +PopupButton { + id: presenceAndRegistrationItem + Layout.minimumWidth: Utils.getSizeWithScreenRatio(86) + Layout.maximumWidth: Utils.getSizeWithScreenRatio(150) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(24) + Layout.preferredWidth: presenceOrRegistrationText.implicitWidth + Utils.getSizeWithScreenRatio(50) + enabled: mainItem.account && mainItem.account.core.registrationState === LinphoneEnums.RegistrationState.Ok + onEnabledChanged: if(!enabled) close() + property bool editCustomStatus : false + contentItem: Rectangle { + id: presenceBar + property bool isRegistered: mainItem.account?.core.registrationState === LinphoneEnums.RegistrationState.Ok + color: DefaultStyle.main2_200 + radius: Utils.getSizeWithScreenRatio(15) + RowLayout { + anchors.fill: parent + Image { + id: registrationImage + sourceSize.width: Utils.getSizeWithScreenRatio(11) + sourceSize.height: Utils.getSizeWithScreenRatio(11) + smooth: false + Layout.preferredWidth: Utils.getSizeWithScreenRatio(11) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(11) + source: presenceBar.isRegistered + ? mainItem.account.core.presenceIcon + : mainItem.account?.core.registrationIcon || "" + Layout.leftMargin: Utils.getSizeWithScreenRatio(8) + RotationAnimator on rotation { + running: mainItem.account && mainItem.account.core.registrationState === LinphoneEnums.RegistrationState.Progress + direction: RotationAnimator.Clockwise + from: 0 + to: 360 + loops: Animation.Infinite + duration: 10000 + } + } + Text { + id: presenceOrRegistrationText + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + visible: mainItem.account + font.weight: Utils.getSizeWithScreenRatio(300) + font.pixelSize: Utils.getSizeWithScreenRatio(12) + color: presenceBar.isRegistered ? mainItem.account.core.presenceColor : mainItem.account?.core.registrationColor + text: presenceBar.isRegistered ? mainItem.account.core.presenceStatus : mainItem.account?.core.humaneReadableRegistrationState + } + EffectImage { + fillMode: Image.PreserveAspectFit + imageSource: AppIcons.downArrow + colorizationColor: DefaultStyle.main2_600 + Layout.preferredHeight: Utils.getSizeWithScreenRatio(14) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(14) + Layout.rightMargin: 8 * DefaultStyle.dp + } + } + } + popup.contentItem: Rectangle { + implicitWidth: Utils.getSizeWithScreenRatio(280) + implicitHeight: 20 * DefaultStyle.dp + (setCustomStatus.visible ? 240 * DefaultStyle.dp : setPresence.implicitHeight) + Presence { + id: setPresence + visible: !presenceAndRegistrationItem.editCustomStatus + anchors.fill: parent + anchors.margins: 20 * DefaultStyle.dp + accountCore: mainItem.account.core + onSetCustomStatusClicked: { + presenceAndRegistrationItem.editCustomStatus = true + } + onIsSet: presenceAndRegistrationItem.popup.close() + } + PresenceSetCustomStatus { + id: setCustomStatus + visible: presenceAndRegistrationItem.editCustomStatus + anchors.fill: parent + anchors.margins: 20 * DefaultStyle.dp + accountCore: mainItem.account.core + onVisibleChanged: { + if (!visible) { + presenceAndRegistrationItem.editCustomStatus = false + } + } + onIsSet: presenceAndRegistrationItem.popup.close() + } + } +} \ No newline at end of file diff --git a/Linphone/view/Control/Display/Contact/Presence.qml b/Linphone/view/Control/Display/Contact/Presence.qml index a685f9248..9ce75ef86 100644 --- a/Linphone/view/Control/Display/Contact/Presence.qml +++ b/Linphone/view/Control/Display/Contact/Presence.qml @@ -2,6 +2,7 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts import Linphone +import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle ColumnLayout { @@ -11,7 +12,7 @@ ColumnLayout { signal setCustomStatusClicked signal isSet - spacing: 8 * DefaultStyle.dp + spacing: Utils.getSizeWithScreenRatio(8) PresenceStatusItem { presence: LinphoneEnums.Presence.Online; accountCore: mainItem.accountCore; onClick: mainItem.isSet()} PresenceStatusItem { presence: LinphoneEnums.Presence.Away; accountCore: mainItem.accountCore; onClick: mainItem.isSet()} PresenceStatusItem { presence: LinphoneEnums.Presence.Busy; accountCore: mainItem.accountCore; onClick: mainItem.isSet()} @@ -22,8 +23,8 @@ ColumnLayout { spacing: 0 visible: accountCore.explicitPresence != LinphoneEnums.Presence.Undefined Layout.alignment: Qt.AlignLeft - Layout.topMargin: Math.round(3 * DefaultStyle.dp) - Layout.bottomMargin: Math.round(3 * DefaultStyle.dp) + Layout.topMargin: Utils.getSizeWithScreenRatio(3) + Layout.bottomMargin: Utils.getSizeWithScreenRatio(3) Label { font: Typography.p1 text: qsTr("contact_presence_reset_status") @@ -32,46 +33,30 @@ ColumnLayout { Item { Layout.fillWidth: true } - Item { - width: Math.round(17 * DefaultStyle.dp) - height: Math.round(17 * DefaultStyle.dp) - - MouseArea { - id: hoverArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: { - accountCore.resetToAutomaticPresence() - } - } - - EffectImage { - fillMode: Image.PreserveAspectFit - imageSource: AppIcons.reloadArrow - colorizationColor: hoverArea.containsMouse ? DefaultStyle.main2_800 : DefaultStyle.main2_600 - anchors.fill: parent - } + Button { + id: resetStatusItem + style: ButtonStyle.noBackground + icon.width: Utils.getSizeWithScreenRatio(17) + icon.height: Utils.getSizeWithScreenRatio(17) + icon.source: AppIcons.reloadArrow + onClicked: accountCore.resetToAutomaticPresence() } } - Rectangle { - height: 1 - width: parent.width - color: DefaultStyle.main2_500main - Layout.topMargin: 8 * DefaultStyle.dp + HorizontalBar { + Layout.topMargin: Utils.getSizeWithScreenRatio(8) } ColumnLayout { - spacing: 19 * DefaultStyle.dp + spacing: Utils.getSizeWithScreenRatio(19) RowLayout { - spacing: 10 * DefaultStyle.dp - Layout.topMargin: Math.round(3 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(10) + Layout.topMargin: Utils.getSizeWithScreenRatio(3) Layout.alignment: Qt.AlignLeft Text { font: Typography.p1 text: accountCore.presenceNote.length > 0 ? accountCore.presenceNote : qsTr("contact_presence_custom_status") color: DefaultStyle.main2_600 wrapMode: Text.WordWrap - Layout.preferredWidth: (accountCore.presenceNote.length == 0 ? 175 : 230) * DefaultStyle.dp + Layout.preferredWidth: Utils.getSizeWithScreenRatio(accountCore.presenceNote.length == 0 ? 175 : 230) } Item { Layout.fillWidth: true @@ -87,7 +72,7 @@ ColumnLayout { } RowLayout { visible: accountCore.presenceNote.length > 0 - spacing: 10 * DefaultStyle.dp + spacing: Utils.getSizeWithScreenRatio(10) Item { Layout.fillWidth: true } diff --git a/Linphone/view/Control/Display/Contact/PresenceSetCustomStatus.qml b/Linphone/view/Control/Display/Contact/PresenceSetCustomStatus.qml index 0d822ce19..8b7cfa851 100644 --- a/Linphone/view/Control/Display/Contact/PresenceSetCustomStatus.qml +++ b/Linphone/view/Control/Display/Contact/PresenceSetCustomStatus.qml @@ -34,7 +34,7 @@ Column { id: statusMessage wrapMode: TextEdit.Wrap font: Typography.p1 - color: DefaultStyle.main2_500main + color: DefaultStyle.main2_500_main Layout.fillHeight: true Layout.fillWidth: true property string previoustext: "" diff --git a/Linphone/view/Control/Display/Contact/PresenceStatusItem.qml b/Linphone/view/Control/Display/Contact/PresenceStatusItem.qml index ca325f397..8eed0010d 100644 --- a/Linphone/view/Control/Display/Contact/PresenceStatusItem.qml +++ b/Linphone/view/Control/Display/Contact/PresenceStatusItem.qml @@ -3,51 +3,34 @@ import QtQuick.Controls import QtQuick.Layouts import Linphone import UtilsCpp +import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils +import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle -Rectangle { +IconLabelButton { id: mainItem - + property var accountCore property var presence signal click() - color: mouseArea.containsMouse ? DefaultStyle.main2_100 : "transparent" - width: 236 * DefaultStyle.dp - height: 22 * DefaultStyle.dp - radius: 5 * DefaultStyle.dp + style: ButtonStyle.hoveredBackgroundBis + height: Utils.getSizeWithScreenRatio(22) + radius: Utils.getSizeWithScreenRatio(5) + text: UtilsCpp.getPresenceStatus(presence) + textSize: Typography.p1.pixelSize + textColor: UtilsCpp.getPresenceColor(mainItem.presence) + textWeight: Typography.p1.weight + icon.width: Utils.getSizeWithScreenRatio(11) + icon.height: Utils.getSizeWithScreenRatio(11) + icon.source: UtilsCpp.getPresenceIcon(mainItem.presence) + Layout.fillWidth: true + shadowEnabled: false + contentImageColor: undefined + padding: 0 - RowLayout { - anchors.fill: parent - spacing: 10 * DefaultStyle.dp - Layout.alignment: Qt.AlignLeft - - Image { - sourceSize.width: 11 * DefaultStyle.dp - sourceSize.height: 11 * DefaultStyle.dp - smooth: false - Layout.preferredWidth: 11 * DefaultStyle.dp - Layout.preferredHeight: 11 * DefaultStyle.dp - source: UtilsCpp.getPresenceIcon(mainItem.presence) - } - - Text { - text: UtilsCpp.getPresenceStatus(mainItem.presence) - font: Typography.p1 - horizontalAlignment: Text.AlignLeft - Layout.alignment: Qt.AlignLeft - Layout.fillWidth: true - color: UtilsCpp.getPresenceColor(mainItem.presence) - } + onClicked: { + mainItem.accountCore.presence = mainItem.presence + mainItem.click() } - MouseArea { - id: mouseArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: { - mainItem.accountCore.presence = mainItem.presence - mainItem.click() - } - } } diff --git a/Linphone/view/Control/Display/Contact/Voicemail.qml b/Linphone/view/Control/Display/Contact/Voicemail.qml index adfb39fda..df30c7be1 100644 --- a/Linphone/view/Control/Display/Contact/Voicemail.qml +++ b/Linphone/view/Control/Display/Contact/Voicemail.qml @@ -40,7 +40,7 @@ Rectangle{ horizontalAlignment: Text.AlignHCenter font.weight: Typography.p2.weight font.pixelSize: Typography.p2.pixelSize * scaleFactor - color: DefaultStyle.danger_500main + color: DefaultStyle.danger_500_main text: voicemailCount >= 100 ? '99+' : voicemailCount visible: showMwi && voicemailCount > 0 maximumLineCount: 1 @@ -49,7 +49,7 @@ Rectangle{ Rectangle { anchors.top: parent.top anchors.right: parent.right - color: DefaultStyle.danger_500main + color: DefaultStyle.danger_500_main visible: showMwi && voicemailCount == 0 width: Math.round(14 * DefaultStyle.dp) * scaleFactor height: width diff --git a/Linphone/view/Control/Display/EffectImage.qml b/Linphone/view/Control/Display/EffectImage.qml index ce11f7357..d285b93a4 100644 --- a/Linphone/view/Control/Display/EffectImage.qml +++ b/Linphone/view/Control/Display/EffectImage.qml @@ -10,7 +10,7 @@ import Linphone Loader { id: mainItem active: visible - property var imageSource + property url imageSource: "" property var fillMode: Image.PreserveAspectFit property var colorizationColor property real imageWidth: width @@ -23,7 +23,7 @@ Loader { Image { id: image visible: !effect2.effectEnabled - source: mainItem.imageSource ? mainItem.imageSource : "" + source: mainItem.imageSource fillMode: mainItem.fillMode sourceSize.width: width sourceSize.height: height diff --git a/Linphone/view/Control/Display/HorizontalBar.qml b/Linphone/view/Control/Display/HorizontalBar.qml new file mode 100644 index 000000000..8637823ae --- /dev/null +++ b/Linphone/view/Control/Display/HorizontalBar.qml @@ -0,0 +1,11 @@ +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Linphone +import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils + +Rectangle{ + height: 1 + Layout.fillWidth: true + color: DefaultStyle.main2_500_main +} \ No newline at end of file diff --git a/Linphone/view/Control/Display/MediaProgressBar.qml b/Linphone/view/Control/Display/MediaProgressBar.qml index 6850b16cc..852821e05 100644 --- a/Linphone/view/Control/Display/MediaProgressBar.qml +++ b/Linphone/view/Control/Display/MediaProgressBar.qml @@ -146,7 +146,7 @@ ProgressBar { spacing: mainItem.recording ? Math.round(5 * DefaultStyle.dp) : 0 EffectImage { visible: mainItem.recording - colorizationColor: DefaultStyle.danger_500main + colorizationColor: DefaultStyle.danger_500_main imageSource: AppIcons.recordFill Layout.preferredWidth: Math.round(14 * DefaultStyle.dp) Layout.preferredHeight: Math.round(14 * DefaultStyle.dp) diff --git a/Linphone/view/Control/Display/Meeting/MeetingListView.qml b/Linphone/view/Control/Display/Meeting/MeetingListView.qml index c8922310b..7f320884a 100644 --- a/Linphone/view/Control/Display/Meeting/MeetingListView.qml +++ b/Linphone/view/Control/Display/Meeting/MeetingListView.qml @@ -200,7 +200,7 @@ ListView { Layout.preferredHeight: Math.round(19 * DefaultStyle.dp) Layout.alignment: Qt.AlignCenter text: day.substring(0,3) + '.' - color: DefaultStyle.main2_500main + color: DefaultStyle.main2_500_main wrapMode: Text.NoWrap elide: Text.ElideNone font { @@ -224,7 +224,7 @@ ListView { verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter text: UtilsCpp.toDateDayString(dateTime) - color: dayNum.isCurrentDay ? DefaultStyle.grey_0 : DefaultStyle.main2_500main + color: dayNum.isCurrentDay ? DefaultStyle.grey_0 : DefaultStyle.main2_500_main wrapMode: Text.NoWrap font { pixelSize: Math.round(20 * DefaultStyle.dp) @@ -275,7 +275,7 @@ ListView { Text { //: "Réunion annulée" text: itemDelegate.isCanceled ? qsTr("meeting_info_cancelled") : UtilsCpp.toDateHourString(dateTime) + " - " + UtilsCpp.toDateHourString(endDateTime) - color: itemDelegate.isCanceled ? DefaultStyle.danger_500main : DefaultStyle.main2_500main + color: itemDelegate.isCanceled ? DefaultStyle.danger_500_main : DefaultStyle.main2_500_main font { pixelSize: Typography.p1.pixelSize weight: Typography.p1.weight diff --git a/Linphone/view/Control/Display/Settings/SettingsMenuItem.qml b/Linphone/view/Control/Display/Settings/SettingsMenuItem.qml index 524745d9d..2792a8d91 100644 --- a/Linphone/view/Control/Display/Settings/SettingsMenuItem.qml +++ b/Linphone/view/Control/Display/Settings/SettingsMenuItem.qml @@ -3,19 +3,23 @@ import QtQuick.Controls.Basic as Control import QtQuick.Layouts import QtQuick.Effects import Linphone +import CustomControls 1.0 +import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils Item { id: mainItem - - height: visible ? Math.round(50 * DefaultStyle.dp) : 0 + height: visible ? Utils.getSizeWithScreenRatio(50) : 0 anchors.right: parent.right anchors.left: parent.left + property bool keyboardOtherFocus: FocusHelper.keyboardFocus || FocusHelper.otherFocus property string titleText property bool isSelected: false - property bool shadowEnabled: mainItem.activeFocus || mouseArea.containsMouse signal selected() + + //: %1 settings + Accessible.name: qsTr("setting_tab_accessible_name").arg(titleText) Keys.onPressed: (event)=>{ if(event.key == Qt.Key_Space || event.key == Qt.Key_Return || event.key == Qt.Key_Enter){ @@ -29,29 +33,14 @@ Item { Rectangle { id: background anchors.fill: parent - color: DefaultStyle.main2_200 - radius: Math.round(35 * DefaultStyle.dp) - visible: parent.containsMouse || isSelected || mainItem.shadowEnabled + color: mainItem.isSelected ? DefaultStyle.main2_200 : parent.containsMouse ? DefaultStyle.main2_100 : "transparent" + radius: mainItem.height / 2 + bottomRightRadius: 0 + topRightRadius: 0 + visible: parent.containsMouse || mainItem.isSelected || mainItem.keyboardOtherFocus + border.color: DefaultStyle.main2_900 + border.width: mainItem.keyboardOtherFocus ? Utils.getSizeWithScreenRatio(3) : 0 } - Rectangle { - id: backgroundRightFiller - anchors.right: parent.right - color: DefaultStyle.main2_200 - width: Math.round(35 * DefaultStyle.dp) - height: Math.round(50 * DefaultStyle.dp) - visible: parent.containsMouse || isSelected - } - // MultiEffect { - // enabled: mainItem.shadowEnabled - // anchors.fill: background - // source: background - // visible: mainItem.shadowEnabled - // // Crash : https://bugreports.qt.io/browse/QTBUG-124730 - // shadowEnabled: true //mainItem.shadowEnabled - // shadowColor: DefaultStyle.grey_1000 - // shadowBlur: 0.1 - // shadowOpacity: mainItem.shadowEnabled ? 0.5 : 0.0 - // } onClicked: { mainItem.selected() } @@ -61,7 +50,7 @@ Item { anchors.left: parent.left anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter - text: titleText + text: mainItem.titleText font: Typography.h4 } diff --git a/Linphone/view/Control/Display/Sticker.qml b/Linphone/view/Control/Display/Sticker.qml index 61a1ca797..9d955f8db 100644 --- a/Linphone/view/Control/Display/Sticker.qml +++ b/Linphone/view/Control/Display/Sticker.qml @@ -303,7 +303,7 @@ Item { imageWidth: Math.min(mainItem.width / 16, Math.round(20 * DefaultStyle.dp)) imageHeight: Math.min(mainItem.width / 16, Math.round(20 * DefaultStyle.dp)) imageSource: AppIcons.microphoneSlash - colorizationColor: DefaultStyle.main2_500main + colorizationColor: DefaultStyle.main2_500_main } } } diff --git a/Linphone/view/Control/Display/TemporaryText.qml b/Linphone/view/Control/Display/TemporaryText.qml index f555bfc05..f93ecf8b5 100644 --- a/Linphone/view/Control/Display/TemporaryText.qml +++ b/Linphone/view/Control/Display/TemporaryText.qml @@ -6,7 +6,7 @@ import Linphone Text { id: mainItem - color: DefaultStyle.danger_500main + color: DefaultStyle.danger_500_main property bool isVisible: text.length > 0 function clear() { autoHideErrorMessage.stop() diff --git a/Linphone/view/Control/Form/Call/ChangeLayoutForm.qml b/Linphone/view/Control/Form/Call/ChangeLayoutForm.qml index a028a5b17..ea847f625 100644 --- a/Linphone/view/Control/Form/Call/ChangeLayoutForm.qml +++ b/Linphone/view/Control/Form/Call/ChangeLayoutForm.qml @@ -50,11 +50,11 @@ FocusScope { Layout.preferredWidth: Math.round(32 * DefaultStyle.dp) Layout.preferredHeight: Math.round(32 * DefaultStyle.dp) imageSource: modelData.imgUrl - colorizationColor: DefaultStyle.main2_500main + colorizationColor: DefaultStyle.main2_500_main } Text { text: modelData.text - color: DefaultStyle.main2_500main + color: DefaultStyle.main2_500_main verticalAlignment: Text.AlignVCenter font.pixelSize: Math.round(14 * DefaultStyle.dp) Layout.fillWidth: true diff --git a/Linphone/view/Control/Form/Login/LoginForm.qml b/Linphone/view/Control/Form/Login/LoginForm.qml index 874c75c46..b5ae8194d 100644 --- a/Linphone/view/Control/Form/Login/LoginForm.qml +++ b/Linphone/view/Control/Form/Login/LoginForm.qml @@ -3,41 +3,47 @@ import QtQuick.Layouts import QtQuick.Controls.Basic as Control import Linphone import ConstantsCpp 1.0 +import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle ColumnLayout { id: mainItem - spacing: Math.round(8 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(8) FormItemLayout { id: username - Layout.preferredWidth: Math.round(346 * DefaultStyle.dp) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(346) //: Nom d'utilisateur : username label: qsTr("username") mandatory: true enableErrorText: true contentItem: TextField { id: usernameEdit - Layout.preferredWidth: Math.round(360 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(49 * DefaultStyle.dp) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(360) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(49) isError: username.errorTextVisible || (errorText.isVisible && text.length > 0) + onAccepted: passwordEdit.forceActiveFocus() + //: "%1 mandatory" + Accessible.name: qsTr("mandatory_field_accessible_name").arg(qsTr("username")) } } Item { Layout.preferredHeight: password.implicitHeight FormItemLayout { id: password - width: Math.round(346 * DefaultStyle.dp) + width: Utils.getSizeWithScreenRatio(346) //: Mot de passe label: qsTr("password") mandatory: true enableErrorText: true contentItem: TextField { id: passwordEdit - Layout.preferredWidth: Math.round(360 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(49 * DefaultStyle.dp) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(360) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(49) isError: password.errorTextVisible || (errorText.isVisible && text.length > 0) hidden: true + onAccepted: connectionButton.trigger() + Accessible.name: qsTr("password") } TemporaryText { id: errorText @@ -55,11 +61,12 @@ ColumnLayout { } RowLayout { - Layout.topMargin: Math.round(7 * DefaultStyle.dp) - spacing: Math.round(29 * DefaultStyle.dp) + Layout.topMargin: Utils.getSizeWithScreenRatio(7) + spacing: Utils.getSizeWithScreenRatio(29) BigButton { id: connectionButton style: ButtonStyle.main + Accessible.name: qsTr("assistant_account_login") contentItem: StackLayout { id: connectionButtonContent currentIndex: 0 @@ -115,11 +122,6 @@ ColumnLayout { connectionButtonContent.currentIndex = 1 } - Shortcut { - sequences: ["Return", "Enter"] - onActivated: if(passwordEdit.activeFocus) connectionButton.trigger() - else if( usernameEdit.activeFocus) passwordEdit.forceActiveFocus() - } onPressed: connectionButton.trigger() } SmallButton { diff --git a/Linphone/view/Control/Form/Settings/MultimediaSettings.qml b/Linphone/view/Control/Form/Settings/MultimediaSettings.qml index c2483a89e..e81d9d2c5 100644 --- a/Linphone/view/Control/Form/Settings/MultimediaSettings.qml +++ b/Linphone/view/Control/Form/Settings/MultimediaSettings.qml @@ -3,6 +3,7 @@ import QtQuick.Controls.Basic as Control import QtQuick.Layouts import Linphone import SettingsCpp +import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils ColumnLayout { id: mainItem @@ -13,31 +14,31 @@ ColumnLayout { property string microDevice: inputAudioDeviceCBox.currentText property bool ringerDevicesVisible: false property bool backgroundVisible: true - spacing: Math.round(40 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(40) RoundedPane { background.visible: mainItem.backgroundVisible Layout.alignment: Qt.AlignHCenter height: contentItem.implicitHeight + topPadding + bottomPadding Layout.fillWidth: true - topPadding: background.visible ? Math.round(25 * DefaultStyle.dp) : 0 - bottomPadding: background.visible ? Math.round(25 * DefaultStyle.dp) : 0 - leftPadding: background.visible ? Math.round(25 * DefaultStyle.dp) : 0 - rightPadding: background.visible ? Math.round(25 * DefaultStyle.dp) : 0 + topPadding: background.visible ? Utils.getSizeWithScreenRatio(25) : 0 + bottomPadding: background.visible ? Utils.getSizeWithScreenRatio(25) : 0 + leftPadding: background.visible ? Utils.getSizeWithScreenRatio(25) : 0 + rightPadding: background.visible ? Utils.getSizeWithScreenRatio(25) : 0 contentItem: ColumnLayout { spacing: mainItem.spacing ColumnLayout { - spacing: Math.round(12 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(12) visible: mainItem.ringerDevicesVisible RowLayout { - spacing: Math.round(8 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(8) EffectImage { imageSource: AppIcons.bellRinger colorizationColor: DefaultStyle.main1_500_main - Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) - imageWidth: Math.round(24 * DefaultStyle.dp) - imageHeight: Math.round(24 * DefaultStyle.dp) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(24) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(24) + imageWidth: Utils.getSizeWithScreenRatio(24) + imageHeight: Utils.getSizeWithScreenRatio(24) } Text { //: Ringtone - Incoming calls @@ -49,28 +50,30 @@ ColumnLayout { } ComboSetting { Layout.fillWidth: true - Layout.topMargin: Math.round(12 * DefaultStyle.dp) + Layout.topMargin: Utils.getSizeWithScreenRatio(12) Layout.preferredWidth: parent.width entries: SettingsCpp.ringerDevices propertyName: "ringerDevice" propertyOwner: SettingsCpp textRole: 'display_name' + //: Choose %1 + Accessible.name: qsTr("choose_something_accessible_name").arg(qsTr("multimedia_settings_ringer_title")) } Item { Layout.fillHeight: true } } ColumnLayout { - spacing: Math.round(12 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(12) RowLayout { - spacing: Math.round(8 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(8) EffectImage { imageSource: AppIcons.speaker colorizationColor: DefaultStyle.main1_500_main - Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) - imageWidth: Math.round(24 * DefaultStyle.dp) - imageHeight: Math.round(24 * DefaultStyle.dp) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(24) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(24) + imageWidth: Utils.getSizeWithScreenRatio(24) + imageHeight: Utils.getSizeWithScreenRatio(24) } Text { //: "Haut-parleurs" @@ -83,7 +86,7 @@ ColumnLayout { id: outputAudioDeviceCBox Layout.fillWidth: true Layout.preferredWidth: parent.width - Layout.preferredHeight: Math.round(49 * DefaultStyle.dp) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(49) entries: SettingsCpp.playbackDevices propertyName: "playbackDevice" propertyOwner: SettingsCpp @@ -95,6 +98,7 @@ ColumnLayout { SettingsCpp.lSetPlaybackDevice(outputAudioDeviceCBox.currentValue) } } + Accessible.name: qsTr("choose_something_accessible_name").arg(qsTr("multimedia_settings_speaker_title")) } Slider { id: speakerVolume @@ -106,19 +110,21 @@ ColumnLayout { if (mainItem.call) SettingsCpp.lSetPlaybackGain(value) else SettingsCpp.playbackGain = value } + //: %1 volume + Accessible.name: qsTr("device_volume_accessible_name").arg(qsTr("multimedia_settings_speaker_title")) } } ColumnLayout { - spacing: Math.round(12 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(12) RowLayout { - spacing: Math.round(8 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(8) EffectImage { imageSource: AppIcons.microphone colorizationColor: DefaultStyle.main1_500_main - Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) - imageWidth: Math.round(24 * DefaultStyle.dp) - imageHeight: Math.round(24 * DefaultStyle.dp) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(24) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(24) + imageWidth: Utils.getSizeWithScreenRatio(24) + imageHeight: Utils.getSizeWithScreenRatio(24) } Text { //: "Microphone" @@ -131,7 +137,7 @@ ColumnLayout { id: inputAudioDeviceCBox Layout.fillWidth: true Layout.preferredWidth: parent.width - Layout.preferredHeight: Math.round(49 * DefaultStyle.dp) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(49) entries: SettingsCpp.captureDevices propertyName: "captureDevice" propertyOwner: SettingsCpp @@ -143,6 +149,7 @@ ColumnLayout { SettingsCpp.lSetCaptureDevice(inputAudioDeviceCBox.currentValue) } } + Accessible.name: qsTr("choose_something_accessible_name").arg(qsTr("multimedia_settings_microphone_title")) } Slider { id: microVolume @@ -154,6 +161,8 @@ ColumnLayout { if (mainItem.call) SettingsCpp.lSetCaptureGain(value) else SettingsCpp.captureGain = value } + //: %1 volume + Accessible.name: qsTr("device_volume_accessible_name").arg(qsTr("multimedia_settings_microphone_title")) } Timer { id: audioTestSliderTimer @@ -168,16 +177,16 @@ ColumnLayout { id: audioTestSlider Layout.fillWidth: true enabled: false - Layout.preferredHeight: Math.round(10 * DefaultStyle.dp) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(10) background: Rectangle { x: audioTestSlider.leftPadding y: audioTestSlider.topPadding + audioTestSlider.availableHeight / 2 - height / 2 - implicitWidth: Math.round(200 * DefaultStyle.dp) - implicitHeight: Math.round(10 * DefaultStyle.dp) + implicitWidth: Utils.getSizeWithScreenRatio(200) + implicitHeight: Utils.getSizeWithScreenRatio(10) width: audioTestSlider.availableWidth height: implicitHeight - radius: Math.round(2 * DefaultStyle.dp) + radius: Utils.getSizeWithScreenRatio(2) color: DefaultStyle.grey_850 Rectangle { @@ -188,24 +197,24 @@ ColumnLayout { GradientStop { position: 0.0; color: DefaultStyle.vue_meter_light_green } GradientStop { position: 1.0; color: DefaultStyle.vue_meter_dark_green} } - radius: Math.round(2 * DefaultStyle.dp) + radius: Utils.getSizeWithScreenRatio(2) } } handle: Item {visible: false} } } ColumnLayout { - spacing: Math.round(12 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(12) visible: SettingsCpp.videoEnabled RowLayout { - spacing: Math.round(8 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(8) EffectImage { imageSource: AppIcons.videoCamera colorizationColor: DefaultStyle.main1_500_main - Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) - imageWidth: Math.round(24 * DefaultStyle.dp) - imageHeight: Math.round(24 * DefaultStyle.dp) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(24) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(24) + imageWidth: Utils.getSizeWithScreenRatio(24) + imageHeight: Utils.getSizeWithScreenRatio(24) } Text { //: "Caméra" @@ -218,7 +227,7 @@ ColumnLayout { id: videoDevicesCbox Layout.fillWidth: true Layout.preferredWidth: parent.width - Layout.preferredHeight: Math.round(49 * DefaultStyle.dp) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(49) entries: SettingsCpp.videoDevices propertyName: "videoDevice" propertyOwner: SettingsCpp @@ -229,6 +238,7 @@ ColumnLayout { SettingsCpp.lSetVideoDevice(videoDevicesCbox.currentValue) } } + Accessible.name: qsTr("choose_something_accessible_name").arg(qsTr("multimedia_settings_camera_title")) } } Connections { diff --git a/Linphone/view/Control/Form/Settings/ScreencastSettings.qml b/Linphone/view/Control/Form/Settings/ScreencastSettings.qml index 2f0270c16..bdf6f28f0 100644 --- a/Linphone/view/Control/Form/Settings/ScreencastSettings.qml +++ b/Linphone/view/Control/Form/Settings/ScreencastSettings.qml @@ -22,7 +22,7 @@ ColumnLayout { //: "Veuillez choisir l’écran ou la fenêtre que vous souihaitez partager au autres participants" text: qsTr("screencast_settings_choose_window_text") font.pixelSize: Math.round(14 * DefaultStyle.dp) - color: DefaultStyle.main2_500main + color: DefaultStyle.main2_500_main } TabBar { Layout.fillWidth: true diff --git a/Linphone/view/Control/Input/Chat/ChatDroppableTextArea.qml b/Linphone/view/Control/Input/Chat/ChatDroppableTextArea.qml index c7581e5d9..7534b8dcd 100644 --- a/Linphone/view/Control/Input/Chat/ChatDroppableTextArea.qml +++ b/Linphone/view/Control/Input/Chat/ChatDroppableTextArea.qml @@ -158,6 +158,7 @@ Control.Control { } onCursorRectangleChanged: sendingAreaFlickable.ensureVisible(cursorRectangle) wrapMode: TextEdit.WordWrap + KeyNavigation.tab: recordButton.visible ? recordButton : sendMessageButton Keys.onPressed: (event) => { if ((event.key == Qt.Key_Enter || event.key == Qt.Key_Return)) if(!(event.modifiers & Qt.ShiftModifier)) { @@ -194,6 +195,7 @@ Control.Control { } } BigButton { + id: sendMessageButton visible: sendingTextArea.text.length !== 0 || mainItem.selectedFilesCount > 0 style: ButtonStyle.noBackgroundOrange icon.source: AppIcons.paperPlaneRight @@ -275,7 +277,7 @@ Control.Control { Rectangle { id: hoverContent anchors.fill: parent - color: DefaultStyle.main2_0 + color: DefaultStyle.main2_000 visible: false radius: Math.round(20 * DefaultStyle.dp) @@ -284,14 +286,14 @@ Control.Control { imageSource: AppIcons.filePlus width: Math.round(37 * DefaultStyle.dp) height: Math.round(37 * DefaultStyle.dp) - colorizationColor: DefaultStyle.main2_500main + colorizationColor: DefaultStyle.main2_500_main } DashRectangle { x: parent.x y: parent.y radius: hoverContent.radius - color: DefaultStyle.main2_500main + color: DefaultStyle.main2_500_main width: parent.width height: parent.height } diff --git a/Linphone/view/Control/Input/DecoratedTextField.qml b/Linphone/view/Control/Input/DecoratedTextField.qml index 8b923348d..100b62e99 100644 --- a/Linphone/view/Control/Input/DecoratedTextField.qml +++ b/Linphone/view/Control/Input/DecoratedTextField.qml @@ -60,6 +60,7 @@ FormItemLayout { } } onTextChanged: mainItem.clearErrorText() + Accessible.name: mainItem.title } } diff --git a/Linphone/view/Control/Input/DigitInput.qml b/Linphone/view/Control/Input/DigitInput.qml index 027b7f755..53d90dfa6 100644 --- a/Linphone/view/Control/Input/DigitInput.qml +++ b/Linphone/view/Control/Input/DigitInput.qml @@ -5,7 +5,7 @@ import Linphone Control.TextField { id: mainItem property real inputSize: Math.round(100 * DefaultStyle.dp) - color: activeFocus ? DefaultStyle.main1_500_main : DefaultStyle.main2_500main + color: activeFocus ? DefaultStyle.main1_500_main : DefaultStyle.main2_500_main validator: IntValidator{bottom: 0; top: 9} width: inputSize * 0.9 @@ -33,7 +33,7 @@ Control.TextField { Rectangle { id: background border.width: Math.round(Math.max(DefaultStyle.dp), 1) - border.color: mainItem.activeFocus ? DefaultStyle.main1_500_main : DefaultStyle.main2_500main + border.color: mainItem.activeFocus ? DefaultStyle.main1_500_main : DefaultStyle.main2_500_main radius: mainItem.inputSize * 0.15 width: mainItem.inputSize * 0.9 height: mainItem.inputSize diff --git a/Linphone/view/Control/Input/PhoneNumberInput.qml b/Linphone/view/Control/Input/PhoneNumberInput.qml index 32795d218..f45567c6b 100644 --- a/Linphone/view/Control/Input/PhoneNumberInput.qml +++ b/Linphone/view/Control/Input/PhoneNumberInput.qml @@ -2,6 +2,7 @@ import QtQuick import QtQuick.Controls.Basic import QtQuick.Layouts import Linphone +import CustomControls 1.0 ColumnLayout { id: mainItem @@ -16,6 +17,7 @@ ColumnLayout { readonly property string phoneNumber: textField.text readonly property string countryCode: combobox.currentText property string defaultCallingCode + property bool keyboardFocus: FocusHelper.keyboardFocus Text { visible: label.length > 0 @@ -38,7 +40,7 @@ ColumnLayout { radius: Math.round(63 * DefaultStyle.dp) color: DefaultStyle.grey_100 border.color: mainItem.errorMessage.length > 0 - ? DefaultStyle.danger_500main + ? DefaultStyle.danger_500_main : (textField.hasActiveFocus || combobox.hasActiveFocus) ? DefaultStyle.main1_500_main : DefaultStyle.grey_200 @@ -48,6 +50,9 @@ ColumnLayout { id: combobox implicitWidth: Math.round(110 * DefaultStyle.dp) defaultCallingCode: mainItem.defaultCallingCode + property bool keyboardFocus: FocusHelper.keyboardFocus + //: %1 prefix + Accessible.name: qsTr("prefix_phone_number_accessible_name").arg(mainItem.Accessible.name) } Rectangle { Layout.preferredWidth: Math.max(Math.round(1 * DefaultStyle.dp), 1) @@ -63,6 +68,9 @@ ColumnLayout { background: Item{} initialText: initialPhoneNumber validator: RegularExpressionValidator{ regularExpression: /[0-9]+/} + property bool keyboardFocus: FocusHelper.keyboardFocus + //: %1 number + Accessible.name: qsTr("number_phone_number_accessible_name").arg(mainItem.Accessible.name) } } } @@ -71,7 +79,7 @@ ColumnLayout { anchors.top: contentBackground.bottom // visible: mainItem.enableErrorText text: mainItem.errorMessage - color: DefaultStyle.danger_500main + color: DefaultStyle.danger_500_main verticalAlignment: Text.AlignVCenter elide: Text.ElideRight wrapMode: Text.Wrap diff --git a/Linphone/view/Control/Input/SearchBar.qml b/Linphone/view/Control/Input/SearchBar.qml index 6e397f52c..8fe35a7b0 100644 --- a/Linphone/view/Control/Input/SearchBar.qml +++ b/Linphone/view/Control/Input/SearchBar.qml @@ -2,16 +2,12 @@ import QtQuick import QtQuick.Controls.Basic as Control import QtQuick.Layouts import Linphone +import CustomControls 1.0 +import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle FocusScope { id: mainItem - property string placeholderText: "" - property color placeholderTextColor: DefaultStyle.main2_400 - property real textInputWidth: Math.round(350 * DefaultStyle.dp) - property color borderColor: "transparent" - property color focusedBorderColor: DefaultStyle.main2_500main - property string text: textField.searchText property bool magnifierVisible: true property var validator: RegularExpressionValidator{} property var numericPadPopup @@ -20,6 +16,17 @@ FocusScope { property alias color: backgroundItem.color property bool delaySearch: true // Wait some idle time after typing to start searching property bool handleNumericPadPopupButtonsPressed: true + // Border properties + property color borderColor: "transparent" + property color focusedBorderColor: DefaultStyle.main2_500_main + property color keyboardFocusedBorderColor: DefaultStyle.main2_900 + property real borderWidth: Utils.getSizeWithScreenRatio(1) + property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3) + // Text properties + property string placeholderText: "" + property color placeholderTextColor: DefaultStyle.main2_400 + property real textInputWidth: Math.round(350 * DefaultStyle.dp) + property string text: textField.searchText signal openNumericPadRequested()// Useful for redirection before displaying numeric pad. @@ -45,12 +52,13 @@ FocusScope { anchors.fill: parent radius: Math.round(28 * DefaultStyle.dp) color: DefaultStyle.grey_100 - border.color: textField.activeFocus ? mainItem.focusedBorderColor : mainItem.borderColor + border.color: textField.keyboardFocus ? mainItem.keyboardFocusedBorderColor : textField.activeFocus ? mainItem.focusedBorderColor : mainItem.borderColor + border.width: textField.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth } EffectImage { id: magnifier visible: mainItem.magnifierVisible - colorizationColor: DefaultStyle.main2_500main + colorizationColor: DefaultStyle.main2_500_main anchors.left: parent.left anchors.verticalCenter: parent.verticalCenter anchors.leftMargin: Math.round(10 * DefaultStyle.dp) @@ -64,6 +72,7 @@ FocusScope { anchors.leftMargin: magnifier.visible ? 0 : Math.round(10 * DefaultStyle.dp) anchors.right: clearTextButton.left anchors.verticalCenter: parent.verticalCenter + property bool keyboardFocus: FocusHelper.keyboardFocus property string searchText @@ -86,7 +95,7 @@ FocusScope { } cursorDelegate: Rectangle { visible: textField.cursorVisible - color: DefaultStyle.main2_500main + color: DefaultStyle.main2_500_main width: Math.max(Math.round(1 * DefaultStyle.dp), 1) } Timer{ @@ -104,11 +113,15 @@ FocusScope { icon.source: AppIcons.dialer contentImageColor: checked ? DefaultStyle.main1_500_main : DefaultStyle.main2_600 hoveredImageColor: contentImageColor - width: Math.round(24 * DefaultStyle.dp) - height: Math.round(24 * DefaultStyle.dp) + width: Math.round(30 * DefaultStyle.dp) + height: Math.round(30* DefaultStyle.dp) + icon.width: Utils.getSizeWithScreenRatio(24) + icon.height: Utils.getSizeWithScreenRatio(24) anchors.verticalCenter: parent.verticalCenter anchors.right: parent.right anchors.rightMargin: Math.round(20 * DefaultStyle.dp) + //: "Open dialer" + Accessible.name: qsTr("open_dialer_acccessibility_label") onClicked: { if(!checked){ mainItem.openNumericPadRequested() @@ -127,6 +140,8 @@ FocusScope { anchors.bottom: parent.bottom anchors.right: parent.right anchors.rightMargin: Math.round(20 * DefaultStyle.dp) + //: "Clear text input" + Accessible.name: qsTr("clear_text_input_acccessibility_label") onClicked: { textField.clear() } diff --git a/Linphone/view/Control/Input/TextArea.qml b/Linphone/view/Control/Input/TextArea.qml index 44521a0c9..35434bdb3 100644 --- a/Linphone/view/Control/Input/TextArea.qml +++ b/Linphone/view/Control/Input/TextArea.qml @@ -17,6 +17,7 @@ TextEdit { topPadding: Math.round(5 * DefaultStyle.dp) bottomPadding: Math.round(5 * DefaultStyle.dp) activeFocusOnTab: true + KeyNavigation.priority: KeyNavigation.BeforeItem property bool displayAsRichText: false property var encodeTextObj: UtilsCpp.encodeTextToQmlRichFormat(text) diff --git a/Linphone/view/Control/Input/TextField.qml b/Linphone/view/Control/Input/TextField.qml index 89d3288ae..cebe5c836 100644 --- a/Linphone/view/Control/Input/TextField.qml +++ b/Linphone/view/Control/Input/TextField.qml @@ -2,17 +2,19 @@ import QtQuick import QtQuick.Controls.Basic as Control import QtQuick.Layouts import Linphone +import CustomControls 1.0 +import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle Control.TextField { id: mainItem property var customWidth width: Math.round((customWidth ? customWidth - 1 : 360) * DefaultStyle.dp) - height: Math.round(49 * DefaultStyle.dp) - leftPadding: Math.round(15 * DefaultStyle.dp) + height: Utils.getSizeWithScreenRatio(49) + leftPadding: Utils.getSizeWithScreenRatio(15) rightPadding: eyeButton.visible - ? Math.round(5 * DefaultStyle.dp) + eyeButton.width + eyeButton.rightMargin - : Math.round(15 * DefaultStyle.dp) + ? Utils.getSizeWithScreenRatio(5) + eyeButton.width + eyeButton.rightMargin + : Utils.getSizeWithScreenRatio(15) echoMode: (hidden && !eyeButton.checked) ? TextInput.Password : TextInput.Normal // Workaround for Windows slowness when first typing a password @@ -23,7 +25,7 @@ Control.TextField { } verticalAlignment: TextInput.AlignVCenter - color: isError ? DefaultStyle.danger_500main : DefaultStyle.main2_600 + color: isError ? DefaultStyle.danger_500_main : DefaultStyle.main2_600 placeholderTextColor: DefaultStyle.placeholders font { family: DefaultStyle.defaultFont @@ -38,10 +40,19 @@ Control.TextField { property bool controlIsDown: false property bool hidden: false property bool isError: false + property bool keyboardFocus: FocusHelper.keyboardFocus + // Background properties property bool backgroundVisible: true property color backgroundColor: DefaultStyle.grey_100 property color disabledBackgroundColor: DefaultStyle.grey_200 + // Border properties property color backgroundBorderColor: DefaultStyle.grey_200 + property color activeBorderColor: DefaultStyle.main1_500_main + property color keyboardFocusedBorderColor: DefaultStyle.main2_900 + property color errorBorderColor: DefaultStyle.danger_500_main + property real borderWidth: Utils.getSizeWithScreenRatio(1) + property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3) + // Text properties property string initialText property real pixelSize: Typography.p1.pixelSize property real weight: Typography.p1.weight @@ -116,15 +127,16 @@ Control.TextField { id: inputBackground visible: mainItem.backgroundVisible anchors.fill: parent - radius: Math.round(79 * DefaultStyle.dp) + radius: Utils.getSizeWithScreenRatio(79) color: mainItem.enabled ? mainItem.backgroundColor : mainItem.disabledBackgroundColor - border.color: mainItem.isError ? DefaultStyle.danger_500main : mainItem.activeFocus ? DefaultStyle.main1_500_main : mainItem.backgroundBorderColor + border.color: mainItem.isError ? mainItem.errorBorderColor : mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.activeFocus ? mainItem.activeBorderColor : mainItem.backgroundBorderColor + border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth } cursorDelegate: Rectangle { id: cursor color: DefaultStyle.main1_500_main - width: Math.max(Math.round(1 * DefaultStyle.dp), 1) + width: Math.max(Utils.getSizeWithScreenRatio(1), 1) anchors.verticalCenter: mainItem.verticalCenter SequentialAnimation { @@ -175,18 +187,25 @@ Control.TextField { Button { id: eyeButton KeyNavigation.left: mainItem - property real rightMargin: Math.round(15 * DefaultStyle.dp) + property real rightMargin: Utils.getSizeWithScreenRatio(15) z: 1 visible: mainItem.hidden checkable: true style: ButtonStyle.noBackground icon.source: eyeButton.checked ? AppIcons.eyeShow : AppIcons.eyeHide - width: Math.round(20 * DefaultStyle.dp) - height: Math.round(20 * DefaultStyle.dp) + width: Utils.getSizeWithScreenRatio(20) + height: Utils.getSizeWithScreenRatio(20) icon.width: width icon.height: height anchors.verticalCenter: parent.verticalCenter anchors.right: parent.right anchors.rightMargin: rightMargin + + Accessible.name: (eyeButton.checked ? + //: Hide %1 + qsTr("hide_accessible_name") : + //: Show %1 + qsTr("show_accessible_name") + ).arg(mainItem.Accessible.name) } } diff --git a/Linphone/view/Control/Popup/Dialog/ZrtpAuthenticationDialog.qml b/Linphone/view/Control/Popup/Dialog/ZrtpAuthenticationDialog.qml index 81b886253..22984da62 100644 --- a/Linphone/view/Control/Popup/Dialog/ZrtpAuthenticationDialog.qml +++ b/Linphone/view/Control/Popup/Dialog/ZrtpAuthenticationDialog.qml @@ -32,7 +32,7 @@ Dialog { width: mainItem.width height: mainItem.implicitHeight color: mainItem.securityError - ? DefaultStyle.danger_500main + ? DefaultStyle.danger_500_main : mainItem.isCaseMismatch ? DefaultStyle.warning_600 : DefaultStyle.info_500_main @@ -244,8 +244,8 @@ Dialog { //: "Aucune correspondance" text: qsTr("call_dialog_zrtp_validate_trust_letters_do_not_match") color: DefaultStyle.grey_0 - borderColor: DefaultStyle.danger_500main - textColor: DefaultStyle.danger_500main + borderColor: DefaultStyle.danger_500_main + textColor: DefaultStyle.danger_500_main visible: !mainItem.securityError onClicked: { if(mainItem.call) mainItem.call.core.lCheckAuthenticationTokenSelected(" ") diff --git a/Linphone/view/Control/Popup/InformationPopup.qml b/Linphone/view/Control/Popup/InformationPopup.qml index 29251c668..72ec9986b 100644 --- a/Linphone/view/Control/Popup/InformationPopup.qml +++ b/Linphone/view/Control/Popup/InformationPopup.qml @@ -21,8 +21,10 @@ Popup { rightMargin: Math.round(20 * DefaultStyle.dp) bottomMargin: Math.round(20 * DefaultStyle.dp) padding: Math.round(20 * DefaultStyle.dp) - underlineColor: mainItem.isSuccess ? DefaultStyle.success_500main : DefaultStyle.danger_500main + underlineColor: mainItem.isSuccess ? DefaultStyle.success_500_main : DefaultStyle.danger_500_main radius: 0 + focus: true + onHoveredChanged: { if (hovered) autoClosePopup.stop() else autoClosePopup.restart() @@ -36,9 +38,11 @@ Popup { } contentItem: RowLayout { spacing: Math.round(24 * DefaultStyle.dp) + Accessible.role: Accessible.AlertMessage + Accessible.name: "%1, %2".arg(mainItem.title).arg(mainItem.description) EffectImage { imageSource: mainItem.isSuccess ? AppIcons.smiley : AppIcons.smileySad - colorizationColor: mainItem.isSuccess ? DefaultStyle.success_500main : DefaultStyle.danger_500main + colorizationColor: mainItem.isSuccess ? DefaultStyle.success_500_main : DefaultStyle.danger_500_main Layout.preferredWidth: Math.round(32 * DefaultStyle.dp) Layout.preferredHeight: Math.round(32 * DefaultStyle.dp) width: Math.round(32 * DefaultStyle.dp) @@ -56,7 +60,7 @@ Popup { Text { Layout.fillWidth: true text: mainItem.title - color: mainItem.isSuccess ? DefaultStyle.success_500main : DefaultStyle.danger_500main + color: mainItem.isSuccess ? DefaultStyle.success_500_main : DefaultStyle.danger_500_main font { pixelSize: Typography.h4.pixelSize weight: Typography.h4.weight @@ -80,7 +84,7 @@ Popup { Layout.maximumWidth: Math.round(300 * DefaultStyle.dp) text: mainItem.description wrapMode: Text.WordWrap - color: DefaultStyle.main2_500main + color: DefaultStyle.main2_500_main font { pixelSize: Math.round(12 * DefaultStyle.dp) weight: Math.round(300 * DefaultStyle.dp) diff --git a/Linphone/view/Control/Popup/Popup.qml b/Linphone/view/Control/Popup/Popup.qml index 5736093c4..658f3ff45 100644 --- a/Linphone/view/Control/Popup/Popup.qml +++ b/Linphone/view/Control/Popup/Popup.qml @@ -2,6 +2,7 @@ import QtQuick import QtQuick.Controls.Basic as Control import QtQuick.Effects import Linphone +import CustomControls 1.0 Control.Popup{ id: mainItem @@ -9,6 +10,7 @@ Control.Popup{ property color underlineColor : DefaultStyle.main1_500_main property real radius: Math.round(16 * DefaultStyle.dp) property bool hovered: mouseArea.containsMouse + property bool keyboardFocus: FocusHelper.keyboardFocus background: Item{ Rectangle { diff --git a/Linphone/view/Control/Tool/Helper/utils.js b/Linphone/view/Control/Tool/Helper/utils.js index ee4b9c5af..bf5a4066d 100644 --- a/Linphone/view/Control/Tool/Helper/utils.js +++ b/Linphone/view/Control/Tool/Helper/utils.js @@ -138,6 +138,49 @@ function getTopParent (object, useFakeParent) { return parent } + +// ----------------------------------------------------------------------------- + +// Check that an item is descendant of another one +function isDescendant(child, parent) { + console.debug("---") + console.debug(child) + var current = child.parent + while (current) { + console.debug(current) + if (current === parent) + return true + current = current.parent + } + return false +} + +// ----------------------------------------------------------------------------- + +// Retrieve first focussable item of an Item. If no item found, return undefined +function getFirstFocussableItemInItem(item) { + var next = item.nextItemInFocusChain(); + if (next && isDescendant(next, item)){ + return next; + } + return undefined; +} + +// Retrieve last focussable item of an Item. If no item found, return undefined +function getLastFocussableItemInItem(item) { + var next = item.nextItemInFocusChain(); + if(next && !isDescendant(next, item)){ + return undefined; + } + var current + do{ + current = next; + next = current.nextItemInFocusChain(); + } while(isDescendant(next, item) && next.visible) + console.log("find last content", current) + return current; +} + // ----------------------------------------------------------------------------- // Load by default a window in the ui/views folder. @@ -826,4 +869,14 @@ function codepointFromFilename(filename) { let codePoints = parts.map(hex => parseInt(hex, 16)); var unicode = String.fromCodePoint(...codePoints); return unicode; +} + + +// ----------------------------------------------------------------------------- + +function getSizeWithScreenRatio(size){ + if (size == 0) { + return size; + } + return Math.max(Math.round(size * Linphone.DefaultStyle.dp), 1); } \ No newline at end of file diff --git a/Linphone/view/Page/Form/Chat/SelectedChatView.qml b/Linphone/view/Page/Form/Chat/SelectedChatView.qml index d90fc3611..2762490f9 100644 --- a/Linphone/view/Page/Form/Chat/SelectedChatView.qml +++ b/Linphone/view/Page/Form/Chat/SelectedChatView.qml @@ -425,7 +425,7 @@ FocusScope { Layout.fillWidth: true //: Reply to %1 text: mainItem.chatMessage ? qsTr("reply_to_label").arg(UtilsCpp.boldTextPart(mainItem.chatMessage.core.fromName, mainItem.chatMessage.core.fromName)) : "" - color: DefaultStyle.main2_500main + color: DefaultStyle.main2_500_main font { pixelSize: Typography.p3.pixelSize weight: Typography.p3.weight diff --git a/Linphone/view/Page/Form/Contact/ContactEdition.qml b/Linphone/view/Page/Form/Contact/ContactEdition.qml index b5d12b181..bc529b4c1 100644 --- a/Linphone/view/Page/Form/Contact/ContactEdition.qml +++ b/Linphone/view/Page/Form/Contact/ContactEdition.qml @@ -7,6 +7,7 @@ import QtQuick.Layouts import Linphone import UtilsCpp import SettingsCpp +import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle MainRightPanel { @@ -36,7 +37,7 @@ MainRightPanel { mainItem.contact.core.undo() mainItem.closeEdition('') } - width: Math.round(278 * DefaultStyle.dp) + width: Utils.getSizeWithScreenRatio(278) //: "Les changements seront annulés. Souhaitez-vous continuer ?" text: qsTr("contact_editor_dialog_cancel_change_message") } @@ -45,18 +46,20 @@ MainRightPanel { Text { text: mainItem.title font { - pixelSize: Math.round(20 * DefaultStyle.dp) + pixelSize: Utils.getSizeWithScreenRatio(20) weight: Typography.h4.weight } } Item{Layout.fillWidth: true} Button { style: ButtonStyle.noBackground - width: Math.round(24 * DefaultStyle.dp) - height: Math.round(24 * DefaultStyle.dp) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(30) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(30) icon.source: AppIcons.closeX - icon.width: Math.round(24 * DefaultStyle.dp) - icon.height: Math.round(24 * DefaultStyle.dp) + icon.width: Utils.getSizeWithScreenRatio(24) + icon.height: Utils.getSizeWithScreenRatio(24) + //: Close %n + Accessible.name: qsTr("close_accessible_name").arg(mainItem.title) onClicked: { if (contact.core.isSaved) mainItem.closeEdition('') else showConfirmationLambdaPopup("", qsTr("contact_editor_dialog_cancel_change_message"), "", function(confirmed) { @@ -70,9 +73,16 @@ MainRightPanel { } content: ContactLayout { + id: contactLayoutItem anchors.fill: parent contact: mainItem.contact button.text: mainItem.saveButtonText + button.Keys.onPressed: (event) => { + if(event.key == Qt.Key_Up){ + phoneNumberInput.forceActiveFocus(Qt.BacktabFocusReason) + event.accepted = true + } + } // Let some time to GUI to set fields on losing focus. Timer{ @@ -114,7 +124,7 @@ MainRightPanel { RowLayout { visible: mainItem.contact && mainItem.contact.core.pictureUri.length != 0 Layout.alignment: Qt.AlignHCenter - spacing: Math.round(32 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(32) IconLabelButton { id: editButton Layout.preferredWidth: width @@ -128,6 +138,8 @@ MainRightPanel { textWeight: Typography.h4.weight KeyNavigation.right: removeButton onClicked: fileDialog.open() + //: "Edit contact image" + Accessible.name: qsTr("edit_contact_image_accessible_name") } FileDialog { id: fileDialog @@ -153,6 +165,8 @@ MainRightPanel { textWeight: Typography.h4.weight KeyNavigation.left: editButton onClicked: mainItem.contact.core.pictureUri = "" + //: "Delete contact image" + Accessible.name: qsTr("delete_contact_image_accessible_name") } }, Item{Layout.fillWidth: true} @@ -195,7 +209,7 @@ MainRightPanel { ScrollBar.horizontal: Control.ScrollBar { } ColumnLayout { - spacing: Math.round(20 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(20) anchors.left: parent.left anchors.right: parent.right @@ -207,15 +221,16 @@ MainRightPanel { label: qsTr("contact_editor_first_name") contentItem: TextField { id: givenNameEdit - Layout.preferredHeight: Math.round(49 * DefaultStyle.dp) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(49) initialText: contact.core.givenName onTextEdited: { contact.core.givenName = givenNameEdit.text } backgroundColor: DefaultStyle.grey_0 - backgroundBorderColor: givenName.errorTextVisible ? DefaultStyle.danger_500main : DefaultStyle.grey_200 + backgroundBorderColor: givenName.errorTextVisible ? DefaultStyle.danger_500_main : DefaultStyle.grey_200 KeyNavigation.up: editButton.visible ? editButton : addPictureButton KeyNavigation.down: nameTextField + Accessible.name: qsTr("contact_editor_first_name") } } FormItemLayout { @@ -229,6 +244,7 @@ MainRightPanel { backgroundColor: DefaultStyle.grey_0 KeyNavigation.up: givenNameEdit KeyNavigation.down: companyTextField + Accessible.name: qsTr("contact_editor_last_name") } } FormItemLayout { @@ -242,6 +258,7 @@ MainRightPanel { backgroundColor: DefaultStyle.grey_0 KeyNavigation.up: nameTextField KeyNavigation.down: jobTextField + Accessible.name: qsTr("contact_editor_company") } } FormItemLayout { @@ -256,13 +273,11 @@ MainRightPanel { KeyNavigation.up: companyTextField Keys.onPressed: (event) => { if(event.key == Qt.Key_Down){ - if(addressesList.count > 0) - addressesList.itemAt(0).forceActiveFocus() - else - newAddressTextField.forceActiveFocus() + (addressesList.count > 0 ? addressesList.itemAt(0) : newAddressTextField).forceActiveFocus(Qt.TabFocusReason) event.accepted = true } } + Accessible.name: qsTr("contact_editor_job_title") } } Repeater { @@ -275,25 +290,23 @@ MainRightPanel { label: modelData.label contentItem: RowLayout { id: addressLayout - spacing: Math.round(10 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(10) function updateFocus(event){ if(event.key == Qt.Key_Up){ - if(index - 1 >=0 ) - addressesList.itemAt(index - 1).forceActiveFocus() - else - jobTextField.forceActiveFocus() + (index - 1 >=0 ? addressesList.itemAt(index - 1) : jobTextField).forceActiveFocus(Qt.BacktabFocusReason) event.accepted = true }else if(event.key == Qt.Key_Down){ - if(index + 1 < addressesList.count) - addressesList.itemAt(index+1).forceActiveFocus() - else - newAddressTextField.forceActiveFocus() + (index + 1 < addressesList.count ? addressesList.itemAt(index+1) : newAddressTextField).forceActiveFocus(Qt.TabFocusReason) event.accepted = true + }else if(event.key == Qt.Key_Right && addressTextField.activeFocus){ + removeAddressButton.forceActiveFocus(Qt.TabFocusReason) + }else if(event.key == Qt.Key_Left && removeAddressButton.activeFocus){ + addressTextField.forceActiveFocus(Qt.BacktabFocusReason) } } TextField { id: addressTextField - Layout.preferredWidth: Math.round(421 * DefaultStyle.dp) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(421) Layout.preferredHeight: height onEditingFinished: { var label = qsTr("sip_address") @@ -305,19 +318,23 @@ MainRightPanel { focus: true KeyNavigation.right: removeAddressButton Keys.onPressed: (event) => addressLayout.updateFocus(event) + //: "SIP address number %1" + Accessible.name: qsTr("sip_address_number_accessible_name").arg(index+1) } Button { id: removeAddressButton - Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(30) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(30) Layout.alignment: Qt.AlignVCenter icon.source: AppIcons.closeX - icon.width: Math.round(24 * DefaultStyle.dp) - icon.height: Math.round(24 * DefaultStyle.dp) + icon.width: Utils.getSizeWithScreenRatio(24) + icon.height: Utils.getSizeWithScreenRatio(24) style: ButtonStyle.noBackground KeyNavigation.left: addressTextField Keys.onPressed: (event) => addressLayout.updateFocus(event) onClicked: mainItem.contact.core.removeAddress(index) + //: "Remove SIP address %1" + Accessible.name: qsTr("remove_sip_address_accessible_name").arg(addressTextField.text) } } } @@ -334,16 +351,10 @@ MainRightPanel { backgroundColor: DefaultStyle.grey_0 Keys.onPressed: (event) => { if(event.key == Qt.Key_Up){ - if(addressesList.count > 0 ) - addressesList.itemAt(addressesList.count - 1).forceActiveFocus() - else - jobTextField.forceActiveFocus() + (addressesList.count > 0 ? addressesList.itemAt(addressesList.count - 1) : jobTextField).forceActiveFocus(Qt.BacktabFocusReason) event.accepted = true }else if(event.key == Qt.Key_Down){ - if(phoneNumberList.count > 0) - phoneNumberList.itemAt(0).forceActiveFocus() - else - phoneNumberInputTextField.forceActiveFocus() + (phoneNumberList.count > 0 ? phoneNumberList.itemAt(0) : phoneNumberInputTextField).forceActiveFocus(Qt.TabFocusReason) event.accepted = true } } @@ -352,6 +363,8 @@ MainRightPanel { newAddressTextField.clear() editionLayout.connectOnce(editionLayout.ensureVisibleRequested, editionLayout.ensureVisible) } + //: "New SIP address" + Accessible.name: qsTr("new_sip_address_accessible_name") } } Repeater { @@ -363,25 +376,19 @@ MainRightPanel { label: modelData.label contentItem: RowLayout { id: phoneNumberLayout - spacing: Math.round(10 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(10) function updateFocus(event){ if(event.key == Qt.Key_Up){ - if(index - 1 >=0 ) - phoneNumberList.itemAt(index - 1).forceActiveFocus() - else - newAddressTextField.forceActiveFocus() + (index - 1 >=0 ? phoneNumberList.itemAt(index - 1): newAddressTextField).forceActiveFocus(Qt.BacktabFocusReason) event.accepted = true }else if(event.key == Qt.Key_Down){ - if(index + 1 < phoneNumberList.count) - phoneNumberList.itemAt(index+1).forceActiveFocus() - else - phoneNumberInputTextField.forceActiveFocus() + (index + 1 < phoneNumberList.count ? phoneNumberList.itemAt(index+1) : phoneNumberInputTextField).forceActiveFocus(Qt.TabFocusReason) event.accepted = true } } TextField { id: phoneTextField - Layout.preferredWidth: Math.round(421 * DefaultStyle.dp) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(421) Layout.preferredHeight: height initialText: modelData.address backgroundColor: DefaultStyle.grey_0 @@ -392,19 +399,23 @@ MainRightPanel { //: "Téléphone" if (text.length != 0) mainItem.contact.core.setPhoneNumberAt(index, qsTr("phone"), text) } + //: "Phone number number %1" + Accessible.name: qsTr("phone_number_number_accessible_name").arg(index+1) } Button { id: removePhoneButton - Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(30) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(30) Layout.alignment: Qt.AlignVCenter style: ButtonStyle.noBackground icon.source: AppIcons.closeX - icon.width: Math.round(24 * DefaultStyle.dp) - icon.height: Math.round(24 * DefaultStyle.dp) + icon.width: Utils.getSizeWithScreenRatio(24) + icon.height: Utils.getSizeWithScreenRatio(24) KeyNavigation.left: phoneTextField Keys.onPressed: (event) => phoneNumberLayout.updateFocus(event) onClicked: mainItem.contact.core.removePhoneNumber(index) + //: Remove phone number %1 + Accessible.name: qsTr("remove_phone_number_accessible_name").arg(phoneTextField.text) } } } @@ -421,16 +432,10 @@ MainRightPanel { backgroundColor: DefaultStyle.grey_0 Keys.onPressed: (event) => { if(event.key == Qt.Key_Up){ - if(phoneNumberList.count > 0 ) - phoneNumberList.itemAt(phoneNumberList.count - 1).forceActiveFocus() - else - newAddressTextField.forceActiveFocus() + (phoneNumberList.count > 0 ? phoneNumberList.itemAt(phoneNumberList.count - 1) : newAddressTextField).forceActiveFocus(Qt.BacktabFocusReason) event.accepted = true }else if(event.key == Qt.Key_Down){ - if(saveButton.enabled) - saveButton.forceActiveFocus() - else - givenNameEdit.forceActiveFocus() + (contactLayoutItem.button.enabled ? contactLayoutItem.button : givenNameEdit).forceActiveFocus(Qt.TabFocusReason) event.accepted = true } } @@ -439,6 +444,8 @@ MainRightPanel { phoneNumberInputTextField.clear() editionLayout.connectOnce(editionLayout.ensureVisibleRequested, editionLayout.ensureVisible) } + //: "New phone number" + Accessible.name: qsTr("new_phone_number_accessible_name") } } TemporaryText { diff --git a/Linphone/view/Page/Form/Login/LoginPage.qml b/Linphone/view/Page/Form/Login/LoginPage.qml index 4755f7c05..e5eb9ec69 100644 --- a/Linphone/view/Page/Form/Login/LoginPage.qml +++ b/Linphone/view/Page/Form/Login/LoginPage.qml @@ -5,6 +5,7 @@ import QtQuick.Controls.Basic as Control import Linphone import UtilsCpp import SettingsCpp +import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle LoginLayout { @@ -19,23 +20,25 @@ LoginLayout { BigButton { enabled: mainItem.showBackButton opacity: mainItem.showBackButton ? 1.0 : 0 - Layout.leftMargin: Math.round(79 * DefaultStyle.dp) + Layout.leftMargin: Utils.getSizeWithScreenRatio(79) icon.source: AppIcons.leftArrow style: ButtonStyle.noBackground onClicked: { console.debug("[LoginLayout] User: return") mainItem.goBack() } + //: Return + Accessible.name: qsTr("return_accessible_name") }, RowLayout { - spacing: Math.round(15 * DefaultStyle.dp) - Layout.leftMargin: Math.round(21 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(15) + Layout.leftMargin: Utils.getSizeWithScreenRatio(21) EffectImage { fillMode: Image.PreserveAspectFit imageSource: AppIcons.profile colorizationColor: DefaultStyle.main2_600 - Layout.preferredHeight: Math.round(34 * DefaultStyle.dp) - Layout.preferredWidth: Math.round(34 * DefaultStyle.dp) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(34) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(34) } Text { //: Connexion @@ -51,11 +54,11 @@ LoginLayout { }, RowLayout { visible: !SettingsCpp.assistantHideCreateAccount - spacing: Math.round(20 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(20) Layout.rightMargin: Math.round(Math.max(10 * DefaultStyle.dp, (51 - ((51/(DefaultStyle.defaultWidth - mainWindow.minimumWidth))*(DefaultStyle.defaultWidth-mainWindow.width))) * DefaultStyle.dp)) Text { - Layout.rightMargin: Math.round(15 * DefaultStyle.dp) + Layout.rightMargin: Utils.getSizeWithScreenRatio(15) //: "Pas encore de compte ?" text: qsTr("assistant_no_account_yet") font.pixelSize: Typography.p1.pixelSize @@ -77,7 +80,7 @@ LoginLayout { Flickable { anchors.left: parent.left anchors.top: parent.top - anchors.leftMargin: Math.round(127 * DefaultStyle.dp) + anchors.leftMargin: Utils.getSizeWithScreenRatio(127) anchors.bottom: parent.bottom ColumnLayout { id: content @@ -87,8 +90,8 @@ LoginLayout { } BigButton { Layout.preferredWidth: loginForm.width - Layout.preferredHeight: Math.round(47 * DefaultStyle.dp) - Layout.topMargin: Math.round(39 * DefaultStyle.dp) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(47) + Layout.topMargin: Utils.getSizeWithScreenRatio(39) visible: !SettingsCpp.assistantHideThirdPartyAccount //: "Compte SIP tiers" text: qsTr("assistant_login_third_party_sip_account_title") @@ -97,8 +100,8 @@ LoginLayout { } BigButton { Layout.preferredWidth: loginForm.width - Layout.preferredHeight: Math.round(47 * DefaultStyle.dp) - Layout.topMargin: Math.round(25 * DefaultStyle.dp) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(47) + Layout.topMargin: Utils.getSizeWithScreenRatio(25) //: "Configuration distante" text: qsTr("assistant_login_remote_provisioning") style: ButtonStyle.secondary @@ -110,22 +113,22 @@ LoginLayout { z: -1 anchors.top: parent.top anchors.right: parent.right - anchors.topMargin: Math.round(129 * DefaultStyle.dp) - anchors.rightMargin: Math.round(127 * DefaultStyle.dp) - width: Math.round(395 * DefaultStyle.dp) - height: Math.round(350 * DefaultStyle.dp) + anchors.topMargin: Utils.getSizeWithScreenRatio(129) + anchors.rightMargin: Utils.getSizeWithScreenRatio(127) + width: Utils.getSizeWithScreenRatio(395) + height: Utils.getSizeWithScreenRatio(350) fillMode: Image.PreserveAspectFit source: AppIcons.loginImage } ] Dialog{ id: fetchConfigDialog - height: Math.round(315 * DefaultStyle.dp) - width: Math.round(637 * DefaultStyle.dp) - leftPadding: Math.round(33 * DefaultStyle.dp) - rightPadding: Math.round(33 * DefaultStyle.dp) - topPadding: Math.round(41 * DefaultStyle.dp) - bottomPadding: Math.round(29 * DefaultStyle.dp) + height: Utils.getSizeWithScreenRatio(315) + width: Utils.getSizeWithScreenRatio(637) + leftPadding: Utils.getSizeWithScreenRatio(33) + rightPadding: Utils.getSizeWithScreenRatio(33) + topPadding: Utils.getSizeWithScreenRatio(41) + bottomPadding: Utils.getSizeWithScreenRatio(29) radius: 0 //: "Télécharger une configuration distante" title: qsTr('assistant_login_download_remote_config') @@ -147,7 +150,7 @@ LoginLayout { TextField{ id: configUrl Layout.fillWidth: true - Layout.preferredHeight: Math.round(49 * DefaultStyle.dp) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(49) //: 'Lien de configuration distante' placeholderText: qsTr("settings_advanced_remote_provisioning_url") } diff --git a/Linphone/view/Page/Form/Login/SIPLoginPage.qml b/Linphone/view/Page/Form/Login/SIPLoginPage.qml index f93a1b9e7..ebae25dc3 100644 --- a/Linphone/view/Page/Form/Login/SIPLoginPage.qml +++ b/Linphone/view/Page/Form/Login/SIPLoginPage.qml @@ -29,6 +29,8 @@ LoginLayout { console.debug("[SIPLoginPage] User: return") mainItem.goBack() } + //: Return + Accessible.name: qsTr("return_accessible_name") } EffectImage { fillMode: Image.PreserveAspectFit @@ -194,6 +196,8 @@ LoginLayout { isError: username.errorTextVisible || (LoginPageCpp.badIds && errorText.isVisible) Layout.preferredWidth: Math.round(360 * DefaultStyle.dp) KeyNavigation.down: passwordEdit + //: "%1 mandatory" + Accessible.name: qsTr("mandatory_field_accessible_name").arg(qsTr("username")) } } FormItemLayout { @@ -209,6 +213,7 @@ LoginLayout { Layout.preferredWidth: Math.round(360 * DefaultStyle.dp) KeyNavigation.up: usernameEdit KeyNavigation.down: domainEdit + Accessible.name: qsTr("password") } } FormItemLayout { @@ -225,6 +230,8 @@ LoginLayout { Layout.preferredWidth: Math.round(360 * DefaultStyle.dp) KeyNavigation.up: passwordEdit KeyNavigation.down: displayName + //: "%1 mandatory" + Accessible.name: qsTr("mandatory_field_accessible_name").arg(qsTr("sip_address_domain")) } Connections { target: SettingsCpp @@ -242,6 +249,7 @@ LoginLayout { Layout.preferredWidth: Math.round(360 * DefaultStyle.dp) KeyNavigation.up: domainEdit KeyNavigation.down: transportCbox + Accessible.name: qsTr("sip_address_display_name") } } FormItemLayout { @@ -263,6 +271,9 @@ LoginLayout { currentIndex: Utils.findIndex(model, function (entry) { return entry.text === SettingsCpp.assistantThirdPartySipAccountTransport.toUpperCase() }) + KeyNavigation.up: displayName + KeyNavigation.down: outboundProxyUriEdit + Accessible.name: qsTr("transport") } } } @@ -283,6 +294,8 @@ LoginLayout { id: connectionButton Layout.topMargin: Math.round(15 * DefaultStyle.dp) style: ButtonStyle.main + property Item tabTarget + Accessible.name: qsTr("assistant_account_login") contentItem: StackLayout { id: connectionButtonContent currentIndex: 0 @@ -330,7 +343,8 @@ LoginLayout { loginDelay.restart() } onPressed: trigger() - KeyNavigation.up: transportCbox + KeyNavigation.up: connectionId + KeyNavigation.tab: tabTarget Timer{ id: loginDelay interval: 200 @@ -347,12 +361,13 @@ LoginLayout { } console.debug("[SIPLoginPage] User: Log in") LoginPageCpp.login(usernameEdit.text, passwordEdit.text, displayName.text, domainEdit.text, - transportCbox.currentValue, registrarUriEdit.text, outboundProxyUriEdit.text, connectionIdEdit.text); + transportCbox.currentValue, serverAddressEdit.text, connectionIdEdit.text); connectionButton.enabled = false connectionButtonContent.currentIndex = 1 } } } + Item { Layout.fillHeight: true } @@ -379,6 +394,8 @@ LoginLayout { contentItem: TextField { id: outboundProxyUriEdit Layout.preferredWidth: Math.round(360 * DefaultStyle.dp) + Accessible.name: qsTr("login_proxy_server_url") + KeyNavigation.up: transportCbox KeyNavigation.down: registrarUriEdit } } @@ -390,6 +407,7 @@ LoginLayout { contentItem: TextField { id: registrarUriEdit Layout.preferredWidth: Math.round(360 * DefaultStyle.dp) + Accessible.name: qsTr("login_registrar_uri") KeyNavigation.up: outboundProxyUriEdit KeyNavigation.down: connectionIdEdit } @@ -403,6 +421,7 @@ LoginLayout { id: connectionIdEdit Layout.preferredWidth: Math.round(360 * DefaultStyle.dp) KeyNavigation.up: registrarUriEdit + Accessible.name: qsTr("login_id") } } } diff --git a/Linphone/view/Page/Form/Meeting/AddParticipantsForm.qml b/Linphone/view/Page/Form/Meeting/AddParticipantsForm.qml index aec7191e0..9f1e495dd 100644 --- a/Linphone/view/Page/Form/Meeting/AddParticipantsForm.qml +++ b/Linphone/view/Page/Form/Meeting/AddParticipantsForm.qml @@ -5,182 +5,173 @@ import QtQuick.Controls.Basic as Control import Linphone import UtilsCpp import SettingsCpp -import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle +import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils +import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle -FocusScope{ - id: mainItem +FocusScope { + id: mainItem //: "Rechercher des contacts" property string placeHolderText: qsTr("search_bar_search_contacts_placeholder") - property list selectedParticipants - property int selectedParticipantsCount: selectedParticipants.length - property ConferenceInfoGui conferenceInfoGui - property color searchBarColor: DefaultStyle.grey_100 - property color searchBarBorderColor: "transparent" - property int participantscSrollBarRightMargin: Math.round(8 * DefaultStyle.dp) + property list selectedParticipants + property int selectedParticipantsCount: selectedParticipants.length + property ConferenceInfoGui conferenceInfoGui + property color searchBarColor: DefaultStyle.grey_100 + property color searchBarBorderColor: "transparent" + property int participantscSrollBarRightMargin: Utils.getSizeWithScreenRatio(8) - function clearSelectedParticipants() { - // TODO - //contactList.selectedContacts.clear() - } + function clearSelectedParticipants() { + // TODO + //contactList.selectedContacts.clear() + } - ColumnLayout { - anchors.fill: parent - spacing: Math.round(15 * DefaultStyle.dp) - GridView { - id: participantList - Layout.fillWidth: true - visible: contentHeight > 0 - Layout.preferredHeight: contentHeight - Layout.maximumHeight: mainItem.height / 3 - width: mainItem.width - cellWidth: Math.round((50 + 18) * DefaultStyle.dp) - cellHeight: Math.round(80 * DefaultStyle.dp) - // columnCount: Math.floor(width/cellWidth) - model: mainItem.selectedParticipants - clip: true - // columnSpacing: Math.round(18 * DefaultStyle.dp) - // rowSpacing: Math.round(9 * DefaultStyle.dp) - Keys.onPressed: (event) => { - if(currentIndex <=0 && event.key == Qt.Key_Up){ - nextItemInFocusChain(false).forceActiveFocus() - } - } - header: ColumnLayout { - Layout.fillWidth: true - Text { - Layout.fillWidth: true - horizontalAlignment: Text.AlignLeft - visible: mainItem.selectedParticipantsCount > 0 - //: "%n participant(s) sélectionné(s)" - text: qsTr("add_participant_selected_count", '0', mainItem.selectedParticipantsCount).arg(mainItem.selectedParticipantsCount) - maximumLineCount: 1 - color: DefaultStyle.grey_1000 - font { - pixelSize: Math.round(12 * DefaultStyle.dp) - weight: Math.round(300 * DefaultStyle.dp) - } - } - Item { - Layout.preferredHeight: Math.round(10 * DefaultStyle.dp) - } - } - delegate: FocusScope { - ColumnLayout { - anchors.fill: parent - spacing: Math.round(4 * DefaultStyle.dp) - width: Math.round(50 * DefaultStyle.dp) - Item { - Layout.alignment: Qt.AlignHCenter - Layout.preferredWidth: Math.round(50 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(50 * DefaultStyle.dp) - Avatar { - anchors.fill: parent - _address: modelData - shadowEnabled: false - secured: friendSecurityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified - } - Button { - Layout.preferredWidth: Math.round(17 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(17 * DefaultStyle.dp) - icon.width: Math.round(12 * DefaultStyle.dp) - icon.height: Math.round(12 * DefaultStyle.dp) - icon.source: AppIcons.closeX - anchors.top: parent.top - anchors.right: parent.right - background: Item { - Rectangle { - id: backgroundRect - color: DefaultStyle.grey_0 - anchors.fill: parent - radius: Math.round(50 * DefaultStyle.dp) - } - MultiEffect { - anchors.fill: backgroundRect - source: backgroundRect - shadowEnabled: true - shadowColor: DefaultStyle.grey_1000 - shadowBlur: 0.1 - shadowOpacity: 0.5 - } - } - onClicked: contactList.removeSelectedContactByAddress(modelData) - } - } - Text { - Layout.alignment: Qt.AlignHCenter - Layout.preferredWidth: width - width: Math.round(50 * DefaultStyle.dp) - maximumLineCount: 1 - clip: true - property var nameObj: UtilsCpp.getDisplayName(modelData) - text: nameObj ? nameObj.value : "" - color: DefaultStyle.main2_700 - wrapMode: Text.WrapAnywhere + ColumnLayout { + anchors.fill: parent + spacing: Utils.getSizeWithScreenRatio(15) + GridView { + id: participantList + Layout.fillWidth: true + visible: contentHeight > 0 + Layout.preferredHeight: contentHeight + Layout.maximumHeight: mainItem.height / 3 + width: mainItem.width + cellWidth: Math.round((50 + 18) * DefaultStyle.dp) + cellHeight: Utils.getSizeWithScreenRatio(80) + // columnCount: Math.floor(width/cellWidth) + model: mainItem.selectedParticipants + clip: true + // columnSpacing: Utils.getSizeWithScreenRatio(18) + // rowSpacing: Utils.getSizeWithScreenRatio(9) + Keys.onPressed: event => { + if (currentIndex <= 0 && event.key == Qt.Key_Up) { + nextItemInFocusChain(false).forceActiveFocus(); + } + } + header: ColumnLayout { + Layout.fillWidth: true + Text { + Layout.fillWidth: true + horizontalAlignment: Text.AlignLeft + visible: mainItem.selectedParticipantsCount > 0 + //: "%n participant(s) sélectionné(s)" + text: qsTr("add_participant_selected_count", '0', mainItem.selectedParticipantsCount).arg(mainItem.selectedParticipantsCount) + maximumLineCount: 1 + color: DefaultStyle.grey_1000 + font { + pixelSize: Utils.getSizeWithScreenRatio(12) + weight: Utils.getSizeWithScreenRatio(300) + } + } + Item { + Layout.preferredHeight: Utils.getSizeWithScreenRatio(10) + } + } + delegate: FocusScope { + ColumnLayout { + anchors.fill: parent + spacing: Utils.getSizeWithScreenRatio(4) + width: Utils.getSizeWithScreenRatio(50) + Item { + id: participantItem + property var nameObj: UtilsCpp.getDisplayName(modelData) + property string displayName: nameObj ? nameObj.value : "" + Layout.alignment: Qt.AlignHCenter + Layout.preferredWidth: Utils.getSizeWithScreenRatio(50) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(50) + Avatar { + anchors.fill: parent + _address: modelData + shadowEnabled: false + secured: friendSecurityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified + } + Button { + width: Utils.getSizeWithScreenRatio(17) + height: Utils.getSizeWithScreenRatio(17) + icon.width: Utils.getSizeWithScreenRatio(12) + icon.height: Utils.getSizeWithScreenRatio(12) + icon.source: AppIcons.closeX + anchors.top: parent.top + anchors.right: parent.right + //: Remove participant %1 + Accessible.name: qsTr("remove_participant_accessible_name").arg(participantItem.displayName) + style: ButtonStyle.whiteSelected + shadowEnabled: true + onClicked: contactList.removeSelectedContactByAddress(modelData) + } + } + Text { + Layout.alignment: Qt.AlignHCenter + Layout.preferredWidth: width + width: Utils.getSizeWithScreenRatio(50) + maximumLineCount: 1 + clip: true + text: participantItem.displayName + color: DefaultStyle.main2_700 + wrapMode: Text.WrapAnywhere font { - pixelSize: Typography.p3.pixelSize - weight: Typography.p3.weight - capitalization: Font.Capitalize - } - } - } - } - Control.ScrollBar.vertical: ScrollBar { - id: scrollbar - active: true - interactive: true - policy: Control.ScrollBar.AsNeeded - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.right: parent.right + pixelSize: Typography.p3.pixelSize + weight: Typography.p3.weight + capitalization: Font.Capitalize + } + } + } + } + Control.ScrollBar.vertical: ScrollBar { + id: scrollbar + active: true + interactive: true + policy: Control.ScrollBar.AsNeeded + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.right: parent.right anchors.rightMargin: mainItem.participantscSrollBarRightMargin - visible: participantList.height < participantList.contentHeight - } - } - SearchBar { - id: searchBar - Layout.fillWidth: true - Layout.topMargin: Math.round(6 * DefaultStyle.dp) - Layout.rightMargin: Math.round(28 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(45 * DefaultStyle.dp) - placeholderText: mainItem.placeHolderText - focus: participantList.count == 0 - color: mainItem.searchBarColor - borderColor: mainItem.searchBarColor - KeyNavigation.up: participantList.count > 0 - ? participantList - : nextItemInFocusChain(false) - KeyNavigation.down: contactList - } - ColumnLayout { - id: content - spacing: Math.round(15 * DefaultStyle.dp) - Text { - visible: !contactList.loading && contactList.count === 0 - Layout.alignment: Qt.AlignHCenter - Layout.topMargin: Math.round(137 * DefaultStyle.dp) + visible: participantList.height < participantList.contentHeight + } + } + SearchBar { + id: searchBar + Layout.fillWidth: true + Layout.topMargin: Utils.getSizeWithScreenRatio(6) + Layout.rightMargin: Utils.getSizeWithScreenRatio(28) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(45) + placeholderText: mainItem.placeHolderText + focus: participantList.count == 0 + color: mainItem.searchBarColor + borderColor: mainItem.searchBarColor + KeyNavigation.up: participantList.count > 0 ? participantList : nextItemInFocusChain(false) + KeyNavigation.down: contactList + } + ColumnLayout { + id: content + spacing: Utils.getSizeWithScreenRatio(15) + Text { + visible: !contactList.loading && contactList.count === 0 + Layout.alignment: Qt.AlignHCenter + Layout.topMargin: Utils.getSizeWithScreenRatio(137) //: "Aucun contact" text: searchBar.text.length !== 0 ? qsTr("list_filter_no_result_found") : qsTr("contact_list_empty") - font { + font { pixelSize: Typography.h4.pixelSize weight: Typography.h4.weight - } - } - AllContactListView{ - id: contactList - Layout.fillWidth: true - Layout.fillHeight: true - itemsRightMargin: Math.round(28 * DefaultStyle.dp) - multiSelectionEnabled: true - showContactMenu: false - confInfoGui: mainItem.conferenceInfoGui - selectedContacts: mainItem.selectedParticipants - onSelectedContactsChanged: Qt.callLater(function(){mainItem.selectedParticipants = selectedContacts}) - searchBarText: searchBar.text - onContactAddedToSelection: (address) => { - contactList.addContactToSelection(address) - } - onContactRemovedFromSelection: (address) => contactList.removeSelectedContactByAddress(address) - } - } - } + } + } + AllContactListView { + id: contactList + Layout.fillWidth: true + Layout.fillHeight: true + itemsRightMargin: Utils.getSizeWithScreenRatio(28) + multiSelectionEnabled: true + showContactMenu: false + confInfoGui: mainItem.conferenceInfoGui + selectedContacts: mainItem.selectedParticipants + onSelectedContactsChanged: Qt.callLater(function () { + mainItem.selectedParticipants = selectedContacts; + }) + searchBarText: searchBar.text + onContactAddedToSelection: address => { + contactList.addContactToSelection(address); + } + onContactRemovedFromSelection: address => contactList.removeSelectedContactByAddress(address) + } + } + } } diff --git a/Linphone/view/Page/Form/Meeting/MeetingForm.qml b/Linphone/view/Page/Form/Meeting/MeetingForm.qml index d620feb7e..1c0534544 100644 --- a/Linphone/view/Page/Form/Meeting/MeetingForm.qml +++ b/Linphone/view/Page/Form/Meeting/MeetingForm.qml @@ -239,6 +239,7 @@ FocusScope { event.accepted = true; } } + KeyNavigation.tab: addParticipantsButton background: Rectangle { anchors.fill: parent color: descriptionEdit.hovered || descriptionEdit.activeFocus ? DefaultStyle.grey_100 : "transparent" diff --git a/Linphone/view/Page/Form/Register/RegisterPage.qml b/Linphone/view/Page/Form/Register/RegisterPage.qml index 7252a9335..aad987379 100644 --- a/Linphone/view/Page/Form/Register/RegisterPage.qml +++ b/Linphone/view/Page/Form/Register/RegisterPage.qml @@ -4,6 +4,7 @@ import QtQuick.Controls.Basic as Control import Linphone import UtilsCpp 1.0 import ConstantsCpp 1.0 +import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle LoginLayout { @@ -32,8 +33,8 @@ LoginLayout { titleContent: [ RowLayout { - spacing: Math.round(21 * DefaultStyle.dp) - Layout.leftMargin: Math.round(79 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(21) + Layout.leftMargin: Utils.getSizeWithScreenRatio(79) BigButton { style: ButtonStyle.noBackground icon.source: AppIcons.leftArrow @@ -41,12 +42,14 @@ LoginLayout { console.debug("[RegisterPage] User: return") returnToLogin() } + //: Return + Accessible.name: qsTr("return_accessible_name") } EffectImage { fillMode: Image.PreserveAspectFit imageSource: AppIcons.profile - Layout.preferredHeight: Math.round(34 * DefaultStyle.dp) - Layout.preferredWidth: Math.round(34 * DefaultStyle.dp) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(34) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(34) colorizationColor: DefaultStyle.main2_600 } Text { @@ -65,10 +68,10 @@ LoginLayout { Layout.fillWidth: true }, RowLayout { - spacing: Math.round(20 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(20) Layout.rightMargin: Math.round(Math.max(10 * DefaultStyle.dp,(51 - ((51/(DefaultStyle.defaultWidth - mainWindow.minimumWidth))*(DefaultStyle.defaultWidth-mainWindow.width))) * DefaultStyle.dp)) Text { - Layout.rightMargin: Math.round(15 * DefaultStyle.dp) + Layout.rightMargin: Utils.getSizeWithScreenRatio(15) color: DefaultStyle.main2_700 // "Déjà un compte ?" text: qsTr("assistant_already_have_an_account") @@ -92,13 +95,13 @@ LoginLayout { ColumnLayout { id: registerForm anchors.fill: parent - anchors.leftMargin: Math.round(127 * DefaultStyle.dp) - spacing: Math.round(50 * DefaultStyle.dp) + anchors.leftMargin: Utils.getSizeWithScreenRatio(127) + spacing: Utils.getSizeWithScreenRatio(50) TabBar { Layout.fillWidth: true id: bar - spacing: Math.round(40 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(40) Layout.rightMargin: Math.round(Math.max(5 * DefaultStyle.dp,(127 - ((127/(DefaultStyle.defaultWidth - mainWindow.minimumWidth))*(DefaultStyle.defaultWidth-mainWindow.width))) * DefaultStyle.dp)) // "S'inscrire avec un numéro de téléphone" model: [qsTr("assistant_account_register_with_phone_number"), @@ -127,35 +130,38 @@ LoginLayout { id: contentLayout anchors.left: parent.left anchors.right: parent.right - spacing: Math.round(8 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(8) ColumnLayout { id: formLayout - spacing: Math.round(24 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(24) RowLayout { Layout.preferredHeight: usernameItem.height - spacing: Math.round(16 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(16) FormItemLayout { id: usernameItem label: qsTr("username") mandatory: true enableErrorText: true - Layout.preferredWidth: Math.round(346 * DefaultStyle.dp) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(346) contentItem: TextField { id: usernameInput - backgroundBorderColor: usernameItem.errorMessage.length > 0 ? DefaultStyle.danger_500main : DefaultStyle.grey_200 + backgroundBorderColor: usernameItem.errorMessage.length > 0 ? DefaultStyle.danger_500_main : DefaultStyle.grey_200 + //: "%1 mandatory" + Accessible.name: qsTr("mandatory_field_accessible_name").arg(qsTr("username")) } } RowLayout { - spacing: Math.round(10 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(10) ComboBox { - Layout.preferredWidth: Math.round(210 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(49 * DefaultStyle.dp) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(210) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(49) enabled: false model: [{text:"@sip.linphone.org"}] + Accessible.name: qsTr("domain") } EffectImage { - Layout.preferredWidth: Math.round(16 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(16 * DefaultStyle.dp) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(16) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(16) imageSource: AppIcons.lock colorizationColor: DefaultStyle.main2_600 } @@ -165,7 +171,7 @@ LoginLayout { currentIndex: bar.currentIndex PhoneNumberInput { id: phoneNumberInput - Layout.preferredWidth: Math.round(346 * DefaultStyle.dp) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(346) property string completePhoneNumber: countryCode + phoneNumber //: "Numéro de téléphone" label: qsTr("phone_number") @@ -173,17 +179,21 @@ LoginLayout { mandatory: true placeholderText: qsTr("phone_number") defaultCallingCode: "33" + //: "%1 mandatory" + Accessible.name: qsTr("mandatory_field_accessible_name").arg(qsTr("phone_number")) } FormItemLayout { id: emailItem Layout.fillWidth: false - Layout.preferredWidth: Math.round(346 * DefaultStyle.dp) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(346) label: qsTr("email") mandatory: true enableErrorText: true contentItem: TextField { id: emailInput - backgroundBorderColor: emailItem.errorMessage.length > 0 ? DefaultStyle.danger_500main : DefaultStyle.grey_200 + backgroundBorderColor: emailItem.errorMessage.length > 0 ? DefaultStyle.danger_500_main : DefaultStyle.grey_200 + //: "%1 mandatory" + Accessible.name: qsTr("mandatory_field_accessible_name").arg(qsTr("email")) } } } @@ -193,22 +203,24 @@ LoginLayout { clip: false RowLayout { id: rowlayout - spacing: Math.round(16 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(16) FormItemLayout { id: passwordItem - Layout.preferredWidth: Math.round(346 * DefaultStyle.dp) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(346) label: qsTr("password") mandatory: true enableErrorText: true contentItem: TextField { id: pwdInput hidden: true - Layout.preferredWidth: Math.round(346 * DefaultStyle.dp) - backgroundBorderColor: passwordItem.errorMessage.length > 0 ? DefaultStyle.danger_500main : DefaultStyle.grey_200 + Layout.preferredWidth: Utils.getSizeWithScreenRatio(346) + backgroundBorderColor: passwordItem.errorMessage.length > 0 ? DefaultStyle.danger_500_main : DefaultStyle.grey_200 + //: "%1 mandatory" + Accessible.name: qsTr("mandatory_field_accessible_name").arg(qsTr("password")) } } FormItemLayout { - Layout.preferredWidth: Math.round(346 * DefaultStyle.dp) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(346) //: "Confirmation mot de passe" label: qsTr("assistant_account_register_password_confirmation") mandatory: true @@ -216,22 +228,24 @@ LoginLayout { contentItem: TextField { id: confirmPwdInput hidden: true - Layout.preferredWidth: Math.round(346 * DefaultStyle.dp) - backgroundBorderColor: passwordItem.errorMessage.length > 0 ? DefaultStyle.danger_500main : DefaultStyle.grey_200 + Layout.preferredWidth: Utils.getSizeWithScreenRatio(346) + backgroundBorderColor: passwordItem.errorMessage.length > 0 ? DefaultStyle.danger_500_main : DefaultStyle.grey_200 + //: "%1 mandatory" + Accessible.name: qsTr("mandatory_field_accessible_name").arg(qsTr("assistant_account_register_password_confirmation")) } } } TemporaryText { id: otherErrorText Layout.fillWidth: true - Layout.topMargin: Math.round(5 * DefaultStyle.dp) + Layout.topMargin: Utils.getSizeWithScreenRatio(5) } } } // ColumnLayout { - // spacing: Math.round(18 * DefaultStyle.dp) + // spacing: Utils.getSizeWithScreenRatio(18) // RowLayout { - // spacing: Math.round(10 * DefaultStyle.dp) + // spacing: Utils.getSizeWithScreenRatio(10) // CheckBox { // id: subscribeToNewsletterCheckBox // } @@ -249,17 +263,20 @@ LoginLayout { // } RowLayout { - spacing: Math.round(10 * DefaultStyle.dp) - CheckBox { - id: termsCheckBox - } - Text { - //: "J'accepte les %1 et la %2" - text: qsTr("assistant_dialog_cgu_and_privacy_policy_message") + id: acceptCguAndPrivacyPolicyItem + spacing: Utils.getSizeWithScreenRatio(10) + //: "J'accepte les %1 et la %2" + property string associatedText: qsTr("assistant_dialog_cgu_and_privacy_policy_message") //: "conditions d'utilisation" .arg(("%2").arg(ConstantsCpp.CguUrl).arg(qsTr("assistant_dialog_general_terms_label"))) //: "politique de confidentialité" .arg(("%2").arg(ConstantsCpp.PrivatePolicyUrl).arg(qsTr("assistant_dialog_privacy_policy_label"))) + CheckBox { + id: termsCheckBox + Accessible.name: acceptCguAndPrivacyPolicyItem.associatedText + } + Text { + text: acceptCguAndPrivacyPolicyItem.associatedText onLinkActivated: (link) => Qt.openUrlExternally(link) font { pixelSize: Typography.p1.pixelSize @@ -318,10 +335,10 @@ LoginLayout { // visible: registerForm.x+registerForm.width < x anchors.top: parent.top anchors.right: parent.right - anchors.topMargin: Math.round(129 * DefaultStyle.dp) - anchors.rightMargin: Math.round(127 * DefaultStyle.dp) - width: Math.round(395 * DefaultStyle.dp) - height: Math.round(350 * DefaultStyle.dp) + anchors.topMargin: Utils.getSizeWithScreenRatio(129) + anchors.rightMargin: Utils.getSizeWithScreenRatio(127) + width: Utils.getSizeWithScreenRatio(395) + height: Utils.getSizeWithScreenRatio(350) fillMode: Image.PreserveAspectFit source: AppIcons.loginImage } diff --git a/Linphone/view/Page/Form/Settings/AbstractSettingsMenu.qml b/Linphone/view/Page/Form/Settings/AbstractSettingsMenu.qml index be81d9436..3cbe9ee8e 100644 --- a/Linphone/view/Page/Form/Settings/AbstractSettingsMenu.qml +++ b/Linphone/view/Page/Form/Settings/AbstractSettingsMenu.qml @@ -4,6 +4,7 @@ import QtQuick.Layouts import QtQuick.Controls.Basic as Control import Linphone import UtilsCpp +import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle AbstractMainPage { @@ -28,17 +29,19 @@ AbstractMainPage { id: leftPanel Layout.fillWidth: true Layout.fillHeight: true - property real sideMargin: Math.round(45 * DefaultStyle.dp) - spacing: Math.round(5 * DefaultStyle.dp) + property real sideMargin: Utils.getSizeWithScreenRatio(45) + spacing: Utils.getSizeWithScreenRatio(5) RowLayout { Layout.fillWidth: true Layout.leftMargin: leftPanel.sideMargin Layout.rightMargin: leftPanel.sideMargin - spacing: Math.round(5 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(5) Button { id: backButton - Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) - Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) + icon.width: Utils.getSizeWithScreenRatio(24) + icon.height: Utils.getSizeWithScreenRatio(24) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(30) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(30) icon.source: AppIcons.leftArrow style: ButtonStyle.noBackground focus: true @@ -61,10 +64,11 @@ AbstractMainPage { Layout.fillWidth: true Layout.fillHeight: true model: mainItem.families - Layout.topMargin: Math.round(41 * DefaultStyle.dp) + Layout.topMargin: Utils.getSizeWithScreenRatio(41) Layout.leftMargin: leftPanel.sideMargin property int selectedIndex: mainItem.defaultIndex != -1 ? mainItem.defaultIndex : 0 activeFocusOnTab: true + spacing: Utils.getSizeWithScreenRatio(5) delegate: SettingsMenuItem { titleText: modelData.title diff --git a/Linphone/view/Page/Layout/Chat/ConversationInfos.qml b/Linphone/view/Page/Layout/Chat/ConversationInfos.qml index 007c3e30d..fdf479eaf 100644 --- a/Linphone/view/Page/Layout/Chat/ConversationInfos.qml +++ b/Linphone/view/Page/Layout/Chat/ConversationInfos.qml @@ -118,7 +118,7 @@ ColumnLayout { anchors.fill: parent fillMode: Image.PreserveAspectFit imageSource: titleMainItem.isEditingSubject ? AppIcons.check : AppIcons.pencil - colorizationColor: titleMainItem.isEditingSubject ? DefaultStyle.main1_500_main : DefaultStyle.main2_500main + colorizationColor: titleMainItem.isEditingSubject ? DefaultStyle.main1_500_main : DefaultStyle.main2_500_main } MouseArea { @@ -352,7 +352,7 @@ ColumnLayout { visible: true, //: Delete history text: qsTr("group_infos_delete_history"), - color: DefaultStyle.danger_500main, + color: DefaultStyle.danger_500_main, showRightArrow: false, action: function() { //: Delete history ? @@ -383,7 +383,7 @@ ColumnLayout { icon: AppIcons.trashCan, visible: true, text: qsTr("one_one_infos_delete_history"), - color: DefaultStyle.danger_500main, + color: DefaultStyle.danger_500_main, showRightArrow: false, action: function() { //: Delete history ? diff --git a/Linphone/view/Page/Layout/Chat/GroupChatInfoParticipants.qml b/Linphone/view/Page/Layout/Chat/GroupChatInfoParticipants.qml index 53d683e5b..9be955b4b 100644 --- a/Linphone/view/Page/Layout/Chat/GroupChatInfoParticipants.qml +++ b/Linphone/view/Page/Layout/Chat/GroupChatInfoParticipants.qml @@ -93,7 +93,7 @@ ColumnLayout { visible: participantCore.isAdmin text: qsTr("group_infos_participant_is_admin") font: Typography.p3 - color: DefaultStyle.main2_500main + color: DefaultStyle.main2_500_main } } } diff --git a/Linphone/view/Page/Layout/Login/LoginLayout.qml b/Linphone/view/Page/Layout/Login/LoginLayout.qml index 2005b7f2a..d0f6a66e1 100644 --- a/Linphone/view/Page/Layout/Login/LoginLayout.qml +++ b/Linphone/view/Page/Layout/Login/LoginLayout.qml @@ -8,6 +8,7 @@ import QtQuick.Controls.Basic as Control import Linphone import ConstantsCpp +import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle Rectangle { @@ -18,15 +19,15 @@ Rectangle { component AboutLine: RowLayout { id: line - spacing: Math.round(20 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(20) property var imageSource property string title property string text property bool enableMouseArea: false signal contentClicked() EffectImage { - Layout.preferredWidth: Math.round(32 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(32 * DefaultStyle.dp) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(32) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(32) imageSource: parent.imageSource colorizationColor: DefaultStyle.main1_500_main } @@ -46,8 +47,8 @@ Rectangle { id: content Layout.fillWidth: true text: line.text - color: DefaultStyle.main2_500main - font.pixelSize: Math.round(14 * DefaultStyle.dp) + color: DefaultStyle.main2_500_main + font.pixelSize: Utils.getSizeWithScreenRatio(14) horizontalAlignment: Layout.AlignLeft Keys.onPressed: (event)=> { if (event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return) { @@ -71,14 +72,14 @@ Rectangle { Dialog { id: aboutPopup anchors.centerIn: parent - width: Math.round(637 * DefaultStyle.dp) + width: Utils.getSizeWithScreenRatio(637) //: À propos de %1 title: qsTr("help_about_title").arg(applicationName) - bottomPadding: Math.round(10 * DefaultStyle.dp) + bottomPadding: Utils.getSizeWithScreenRatio(10) buttons: [] content: RowLayout { ColumnLayout { - spacing: Math.round(17 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(17) Layout.alignment: Qt.AlignTop | Qt.AlignLeft AboutLine { imageSource: AppIcons.detective @@ -109,7 +110,7 @@ Rectangle { } Item { // Item to shift close button - Layout.preferredHeight: Math.round(10 * DefaultStyle.dp) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(10) } } MediumButton { @@ -137,10 +138,10 @@ Rectangle { id: aboutButton Layout.alignment: Qt.AlignRight | Qt.AlignVCenter icon.source: AppIcons.info - text: qsTr("help_about_title").arg(applicationName) + text: qsTr("help_about_title").arg(applicationName) textSize: Typography.p1.pixelSize textWeight: Typography.p1.weight - textColor: DefaultStyle.main2_500main + textColor: DefaultStyle.main2_500_main onClicked: aboutPopup.open() style: ButtonStyle.noBackground } @@ -165,7 +166,7 @@ Rectangle { source: AppIcons.belledonne fillMode: Image.Stretch Layout.fillWidth: true - Layout.preferredHeight: Math.round(108 * DefaultStyle.dp) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(108) } } diff --git a/Linphone/view/Page/Layout/Main/MainLayout.qml b/Linphone/view/Page/Layout/Main/MainLayout.qml index 9ad85bd33..64a30fded 100644 --- a/Linphone/view/Page/Layout/Main/MainLayout.qml +++ b/Linphone/view/Page/Layout/Main/MainLayout.qml @@ -24,64 +24,65 @@ Item { signal displayChatRequested(string contactAddress) signal openChatRequested(ChatGui chat) signal createContactRequested(string name, string address) - signal scheduleMeetingRequested(string subject, list addresses) + signal scheduleMeetingRequested(string subject, list addresses) signal accountRemoved function goToNewCall() { - tabbar.currentIndex = 0 - mainItem.openNewCallRequest() + tabbar.currentIndex = 0; + mainItem.openNewCallRequest(); } function goToCallHistory() { - tabbar.currentIndex = 0 - mainItem.openCallHistory() + tabbar.currentIndex = 0; + mainItem.openCallHistory(); } function displayContactPage(contactAddress) { - tabbar.currentIndex = 1 - mainItem.displayContactRequested(contactAddress) + tabbar.currentIndex = 1; + mainItem.displayContactRequested(contactAddress); } function displayChatPage(contactAddress) { - tabbar.currentIndex = 2 - mainItem.displayChatRequested(contactAddress) + tabbar.currentIndex = 2; + mainItem.displayChatRequested(contactAddress); } function openChat(chat) { - tabbar.currentIndex = 2 - mainItem.openChatRequested(chat) + tabbar.currentIndex = 2; + mainItem.openChatRequested(chat); } function createContact(name, address) { - tabbar.currentIndex = 1 - mainItem.createContactRequested(name, address) + tabbar.currentIndex = 1; + mainItem.createContactRequested(name, address); } - function scheduleMeeting(subject, addresses) { - tabbar.currentIndex = 3 - mainItem.scheduleMeetingRequested(subject, addresses) + function scheduleMeeting(subject, addresses) { + tabbar.currentIndex = 3; + mainItem.scheduleMeetingRequested(subject, addresses); } function openContextualMenuComponent(component) { - if (mainItem.contextualMenuOpenedComponent - && mainItem.contextualMenuOpenedComponent != component) { - mainStackView.pop() + if (mainItem.contextualMenuOpenedComponent && mainItem.contextualMenuOpenedComponent != component) { + mainStackView.pop(); if (mainItem.contextualMenuOpenedComponent) { - mainItem.contextualMenuOpenedComponent.destroy() + mainItem.contextualMenuOpenedComponent.destroy(); } - mainItem.contextualMenuOpenedComponent = undefined + mainItem.contextualMenuOpenedComponent = undefined; } if (!mainItem.contextualMenuOpenedComponent) { - mainStackView.push(component) - mainItem.contextualMenuOpenedComponent = component + mainStackView.push(component); + mainItem.contextualMenuOpenedComponent = component; } - settingsMenuButton.popup.close() + settingsMenuButton.popup.close(); } function closeContextualMenuComponent() { - mainStackView.pop() + mainStackView.pop(); if (mainItem.contextualMenuOpenedComponent) - mainItem.contextualMenuOpenedComponent.destroy() - mainItem.contextualMenuOpenedComponent = undefined + mainItem.contextualMenuOpenedComponent.destroy(); + mainItem.contextualMenuOpenedComponent = undefined; } function openAccountSettings(account) { - var page = accountSettingsPageComponent.createObject(parent, {"account": account}) - openContextualMenuComponent(page) + var page = accountSettingsPageComponent.createObject(parent, { + "account": account + }); + openContextualMenuComponent(page); } AccountProxy { @@ -103,10 +104,7 @@ Item { id: currentCallNotif background: Item {} closePolicy: Control.Popup.NoAutoClose - visible: currentCall - && currentCall.core.state != LinphoneEnums.CallState.Idle - && currentCall.core.state != LinphoneEnums.CallState.IncomingReceived - && currentCall.core.state != LinphoneEnums.CallState.PushIncomingReceived + visible: currentCall && currentCall.core.state != LinphoneEnums.CallState.Idle && currentCall.core.state != LinphoneEnums.CallState.IncomingReceived && currentCall.core.state != LinphoneEnums.CallState.PushIncomingReceived x: mainItem.width / 2 - width / 2 y: contentItem.height / 2 property var currentCall: callsModel.currentCall ? callsModel.currentCall : null @@ -115,9 +113,8 @@ Item { style: ButtonStyle.toast text: currentCallNotif.currentCall ? currentCallNotif.currentCall.core.conference ? ("Réunion en cours : ") + currentCallNotif.currentCall.core.conference.core.subject : (("Appel en cours : ") + currentCallNotif.remoteName) : "appel en cours" onClicked: { - var callsWindow = UtilsCpp.getCallsWindow( - currentCallNotif.currentCall) - UtilsCpp.smartShowWindow(callsWindow) + var callsWindow = UtilsCpp.getCallsWindow(currentCallNotif.currentCall); + UtilsCpp.smartShowWindow(callsWindow); } } } @@ -125,71 +122,85 @@ Item { RowLayout { anchors.fill: parent spacing: 0 - anchors.topMargin: Math.round(25 * DefaultStyle.dp) + anchors.topMargin: Utils.getSizeWithScreenRatio(25) VerticalTabBar { id: tabbar Layout.fillHeight: true - Layout.preferredWidth: Math.round(82 * DefaultStyle.dp) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(82) defaultAccount: accountProxy.defaultAccount currentIndex: 0 Binding on currentIndex { when: mainItem.contextualMenuOpenedComponent != undefined value: -1 } - model: [{ + model: [ + { "icon": AppIcons.phone, "selectedIcon": AppIcons.phoneSelected, //: "Appels" - "label": qsTr("bottom_navigation_calls_label") - }, { + "label": qsTr("bottom_navigation_calls_label"), + //: "Open calls page" + "accessibilityLabel": qsTr("open_calls_page_accessible_name") + }, + { "icon": AppIcons.adressBook, "selectedIcon": AppIcons.adressBookSelected, //: "Contacts" - "label": qsTr("bottom_navigation_contacts_label") - }, { + "label": qsTr("bottom_navigation_contacts_label"), + //: "Open contacts page" + "accessibilityLabel": qsTr("open_contacts_page_accessible_name") + }, + { "icon": AppIcons.chatTeardropText, "selectedIcon": AppIcons.chatTeardropTextSelected, //: "Conversations" "label": qsTr("bottom_navigation_conversations_label"), + //: "Open conversations page" + "accessibilityLabel": qsTr("open_conversations_page_accessible_name"), "visible": !SettingsCpp.disableChatFeature - }, { + }, + { "icon": AppIcons.videoconference, "selectedIcon": AppIcons.videoconferenceSelected, //: "Réunions" "label": qsTr("bottom_navigation_meetings_label"), + //: "Open meetings page" + "accessibilityLabel": qsTr("open_contact_page_accessible_name"), "visible": !SettingsCpp.disableMeetingsFeature - }] + } + ] onCurrentIndexChanged: { if (currentIndex === -1) - return + return; if (currentIndex === 0 && accountProxy.defaultAccount) - accountProxy.defaultAccount.core?.lResetMissedCalls() + accountProxy.defaultAccount.core?.lResetMissedCalls(); if (mainItem.contextualMenuOpenedComponent) { - closeContextualMenuComponent() + closeContextualMenuComponent(); } } Keys.onPressed: event => { - if (event.key == Qt.Key_Right) { - mainStackView.currentItem.forceActiveFocus() - } - } + if (event.key == Qt.Key_Right) { + mainStackView.currentItem.forceActiveFocus(); + } + } Component.onCompleted: { if (SettingsCpp.shortcutCount > 0) { - var shortcuts = SettingsCpp.shortcuts + var shortcuts = SettingsCpp.shortcuts; shortcuts.forEach(shortcut => { - model.push({ - "icon": shortcut.icon, - "selectedIcon": shortcut.icon, - "label": shortcut.name, - "colored": true, - "link": shortcut.link - }) - }) + model.push({ + "icon": shortcut.icon, + "selectedIcon": shortcut.icon, + "label": shortcut.name, + "colored": true, + "link": shortcut.link + }); + }); } - initButtons() - currentIndex = SettingsCpp.getLastActiveTabIndex() - if (currentIndex === -1) currentIndex = 0 + initButtons(); + currentIndex = SettingsCpp.getLastActiveTabIndex(); + if (currentIndex === -1) + currentIndex = 0; } } ColumnLayout { @@ -197,18 +208,17 @@ Item { RowLayout { id: topRow - Layout.preferredHeight: Math.round(50 * DefaultStyle.dp) - Layout.leftMargin: Math.round(45 * DefaultStyle.dp) - Layout.rightMargin: Math.round(41 * DefaultStyle.dp) - spacing: Math.round(25 * DefaultStyle.dp) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(50) + Layout.leftMargin: Utils.getSizeWithScreenRatio(45) + Layout.rightMargin: Utils.getSizeWithScreenRatio(41) + spacing: Utils.getSizeWithScreenRatio(25) SearchBar { id: magicSearchBar Layout.fillWidth: true //: "Rechercher un contact, appeler %1" - placeholderText: qsTr("searchbar_placeholder_text").arg(SettingsCpp.disableChatFeature - ? "…" - //: "ou envoyer un message …" - : qsTr("searchbar_placeholder_text_chat_feature_enabled")) + placeholderText: qsTr("searchbar_placeholder_text").arg(SettingsCpp.disableChatFeature ? "…" : + //: "ou envoyer un message …" + qsTr("searchbar_placeholder_text_chat_feature_enabled")) focusedBorderColor: DefaultStyle.main1_500_main numericPadButton.visible: text.length === 0 numericPadButton.checkable: false @@ -219,16 +229,16 @@ Item { Connections { target: mainItem function onCallCreated() { - magicSearchBar.focus = false - magicSearchBar.clearText() + magicSearchBar.focus = false; + magicSearchBar.clearText(); } } onTextChanged: { if (text.length != 0) - listPopup.open() + listPopup.open(); else - listPopup.close() + listPopup.close(); } KeyNavigation.down: contactList //contactLoader.item?.count > 0 || !contactLoader.item?.footerItem? contactLoader.item : contactLoader.item?.footerItem KeyNavigation.up: contactList //contactLoader.item?.footerItem ? contactLoader.item?.footerItem : contactLoader.item @@ -236,24 +246,22 @@ Item { Popup { id: listPopup width: magicSearchBar.width - property real maxHeight: Math.round(400 * DefaultStyle.dp) + property real maxHeight: Utils.getSizeWithScreenRatio(400) property bool displayScrollbar: contactList.height > maxHeight - height: Math.min( - contactList.contentHeight, - maxHeight) + topPadding + bottomPadding + height: Math.min(contactList.contentHeight, maxHeight) + topPadding + bottomPadding y: magicSearchBar.height // closePolicy: Popup.CloseOnEscape - topPadding: Math.round(20 * DefaultStyle.dp) - bottomPadding: Math.round((contactList.haveContacts ? 20 : 10) * DefaultStyle.dp) - rightPadding: Math.round(8 * DefaultStyle.dp) - leftPadding: Math.round(20 * DefaultStyle.dp) + topPadding: Utils.getSizeWithScreenRatio(20) + bottomPadding: Math.round((contactList.haveContacts ? 20 : 10) * DefaultStyle.dp) + rightPadding: Utils.getSizeWithScreenRatio(8) + leftPadding: Utils.getSizeWithScreenRatio(20) visible: magicSearchBar.text.length != 0 background: Item { anchors.fill: parent Rectangle { id: popupBg - radius: Math.round(16 * DefaultStyle.dp) + radius: Utils.getSizeWithScreenRatio(16) color: DefaultStyle.grey_0 anchors.fill: parent border.color: DefaultStyle.main1_500_main @@ -271,9 +279,8 @@ Item { contentItem: AllContactListView { id: contactList - width: listPopup.width - listPopup.leftPadding - - listPopup.rightPadding - itemsRightMargin: Math.round(5 * DefaultStyle.dp) //(Actions have already 10 of margin) + width: listPopup.width - listPopup.leftPadding - listPopup.rightPadding + itemsRightMargin: Utils.getSizeWithScreenRatio(5) //(Actions have already 10 of margin) showInitials: false showContactMenu: false showActions: true @@ -283,26 +290,28 @@ Item { sectionsPixelSize: Typography.p2.pixelSize sectionsWeight: Typography.p2.weight - sectionsSpacing: Math.round(5 * DefaultStyle.dp) + sectionsSpacing: Utils.getSizeWithScreenRatio(5) searchBarText: magicSearchBar.text } } } RowLayout { - spacing: Math.round(10 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(10) PopupButton { id: deactivateDndButton - Layout.preferredWidth: Math.round(32 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(32 * DefaultStyle.dp) - popup.padding: Math.round(14 * DefaultStyle.dp) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(32) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(32) + popup.padding: Utils.getSizeWithScreenRatio(14) + //: "Do not disturb" + popUpTitle: qsTr("do_not_disturb_accessible_name") visible: SettingsCpp.dnd contentItem: EffectImage { imageSource: AppIcons.bellDnd - width: Math.round(32 * DefaultStyle.dp) - height: Math.round(32 * DefaultStyle.dp) - Layout.preferredWidth: Math.round(32 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(32 * DefaultStyle.dp) + width: Utils.getSizeWithScreenRatio(32) + height: Utils.getSizeWithScreenRatio(32) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(32) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(32) fillMode: Image.PreserveAspectFit colorizationColor: DefaultStyle.main1_500_main } @@ -310,199 +319,195 @@ Item { IconLabelButton { Layout.fillWidth: true focus: visible - icon.width: Math.round(32 * DefaultStyle.dp) - icon.height: Math.round(32 * DefaultStyle.dp) + icon.width: Utils.getSizeWithScreenRatio(32) + icon.height: Utils.getSizeWithScreenRatio(32) //: "Désactiver ne pas déranger" text: qsTr("contact_presence_status_disable_do_not_disturb") icon.source: AppIcons.bellDnd onClicked: { - deactivateDndButton.popup.close() - SettingsCpp.dnd = false + deactivateDndButton.popup.close(); + SettingsCpp.dnd = false; } } } } Voicemail { id: voicemail - Layout.preferredWidth: Math.round(42 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(36 * DefaultStyle.dp) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(42) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(36) Repeater { model: accountProxy delegate: Item { Connections { target: modelData.core function onShowMwiChanged() { - voicemail.updateCumulatedMwi() + voicemail.updateCumulatedMwi(); } function onVoicemailAddressChanged() { - voicemail.updateCumulatedMwi() + voicemail.updateCumulatedMwi(); } } } } function updateCumulatedMwi() { - var count = 0 - var showMwi = false - var supportsVoiceMail = false + var count = 0; + var showMwi = false; + var supportsVoiceMail = false; for (var i = 0; i < accountProxy.count; i++) { - var core = accountProxy.getAt(i).core - count += core.voicemailCount - showMwi |= core.showMwi - supportsVoiceMail |= core.voicemailAddress.length > 0 + var core = accountProxy.getAt(i).core; + count += core.voicemailCount; + showMwi |= core.showMwi; + supportsVoiceMail |= core.voicemailAddress.length > 0; } - voicemail.showMwi = showMwi - voicemail.voicemailCount = count - voicemail.visible = showMwi || supportsVoiceMail + voicemail.showMwi = showMwi; + voicemail.voicemailCount = count; + voicemail.visible = showMwi || supportsVoiceMail; } Component.onCompleted: { - updateCumulatedMwi() + updateCumulatedMwi(); } onClicked: { if (accountProxy.count > 1) { - avatarButton.popup.open() + avatarButton.popup.open(); } else { - if (accountProxy.defaultAccount.core.voicemailAddress.length - > 0) - UtilsCpp.createCall( - accountProxy.defaultAccount.core.voicemailAddress) + if (accountProxy.defaultAccount.core.voicemailAddress.length > 0) + UtilsCpp.createCall(accountProxy.defaultAccount.core.voicemailAddress); else UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), - //: "L'URI de messagerie vocale n'est pas définie." - qsTr("no_voicemail_uri_error_message"), false) + //: "L'URI de messagerie vocale n'est pas définie." + qsTr("no_voicemail_uri_error_message"), false); } } } PopupButton { id: avatarButton - Layout.preferredWidth: Math.round(54 * DefaultStyle.dp) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(54) Layout.preferredHeight: width - popup.topPadding: Math.round(23 * DefaultStyle.dp) - popup.bottomPadding: Math.round(23 * DefaultStyle.dp) - popup.leftPadding: Math.round(24 * DefaultStyle.dp) - popup.rightPadding: Math.round(24 * DefaultStyle.dp) - contentItem: Avatar { - id: avatar - height: avatarButton.height - width: avatarButton.width - account: accountProxy.defaultAccount - } - popup.contentItem: ColumnLayout { - AccountListView { - id: accounts - onAddAccountRequest: mainItem.addAccountRequest() - onEditAccount: function (account) { - avatarButton.popup.close() - openAccountSettings(account) - } + popup.topPadding: Utils.getSizeWithScreenRatio(23) + popup.bottomPadding: Utils.getSizeWithScreenRatio(23) + popup.leftPadding: Utils.getSizeWithScreenRatio(24) + popup.rightPadding: Utils.getSizeWithScreenRatio(24) + //: "Account list" + popUpTitle: qsTr("account_list_accessible_name") + contentItem: Item { + Avatar { + id: avatar + height: avatarButton.height + width: avatarButton.width + account: accountProxy.defaultAccount } + Rectangle { + // Black border for keyboard navigation + visible: avatarButton.keyboardFocus + width: avatar.width + height: avatar.height + color: "transparent" + border.color: DefaultStyle.main2_900 + border.width: Utils.getSizeWithScreenRatio(3) + radius: width / 2 + } + } + popup.contentItem: AccountListView { + id: accounts + popupId: avatarButton + onAddAccountRequest: mainItem.addAccountRequest() + onEditAccount: function (account) { + avatarButton.popup.close(); + openAccountSettings(account); + } + getPreviousItem: avatarButton.getPreviousItem + getNextItem: avatarButton.getNextItem } } PopupButton { id: settingsMenuButton - Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) - popup.width: Math.round(271 * DefaultStyle.dp) - popup.padding: Math.round(14 * DefaultStyle.dp) + icon.width: Utils.getSizeWithScreenRatio(24) + icon.height: Utils.getSizeWithScreenRatio(24) + popup.width: Utils.getSizeWithScreenRatio(271) + popup.padding: Utils.getSizeWithScreenRatio(14) + //: "Application options" + popUpTitle: qsTr("application_options_accessible_name") popup.contentItem: FocusScope { id: popupFocus implicitHeight: settingsButtons.implicitHeight implicitWidth: settingsButtons.implicitWidth Keys.onPressed: event => { - if (event.key == Qt.Key_Left - || event.key == Qt.Key_Escape) { - settingsMenuButton.popup.close() - event.accepted = true - } - } + if (event.key == Qt.Key_Left || event.key == Qt.Key_Escape) { + settingsMenuButton.popup.close(); + event.accepted = true; + } + } ColumnLayout { id: settingsButtons - spacing: Math.round(16 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(16) anchors.fill: parent IconLabelButton { id: accountButton Layout.fillWidth: true visible: !SettingsCpp.hideAccountSettings - icon.width: Math.round(32 * DefaultStyle.dp) - icon.height: Math.round(32 * DefaultStyle.dp) + icon.width: Utils.getSizeWithScreenRatio(32) + icon.height: Utils.getSizeWithScreenRatio(32) //: Mon compte text: qsTr("drawer_menu_manage_account") icon.source: AppIcons.manageProfile - onClicked: openAccountSettings(accountProxy.defaultAccount - ? accountProxy.defaultAccount - : accountProxy.firstAccount()) - KeyNavigation.up: visibleChildren.length - != 0 ? settingsMenuButton.getPreviousItem( - 0) : null - KeyNavigation.down: visibleChildren.length - != 0 ? settingsMenuButton.getNextItem( - 0) : null + onClicked: openAccountSettings(accountProxy.defaultAccount ? accountProxy.defaultAccount : accountProxy.firstAccount()) + KeyNavigation.up: visibleChildren.length != 0 ? settingsMenuButton.getPreviousItem(0) : null + KeyNavigation.down: visibleChildren.length != 0 ? settingsMenuButton.getNextItem(0) : null } IconLabelButton { id: dndButton Layout.fillWidth: true - icon.width: Math.round(32 * DefaultStyle.dp) - icon.height: Math.round(32 * DefaultStyle.dp) - text: SettingsCpp.dnd ? qsTr("contact_presence_status_disable_do_not_disturb") - //: "Activer ne pas déranger" - : qsTr("contact_presence_status_enable_do_not_disturb") + icon.width: Utils.getSizeWithScreenRatio(32) + icon.height: Utils.getSizeWithScreenRatio(32) + text: SettingsCpp.dnd ? qsTr("contact_presence_status_disable_do_not_disturb") : + //: "Activer ne pas déranger" + qsTr("contact_presence_status_enable_do_not_disturb") icon.source: AppIcons.bellDnd onClicked: { - settingsMenuButton.popup.close() - SettingsCpp.dnd = !SettingsCpp.dnd + settingsMenuButton.popup.close(); + SettingsCpp.dnd = !SettingsCpp.dnd; } - KeyNavigation.up: visibleChildren.length - != 0 ? settingsMenuButton.getPreviousItem( - 1) : null - KeyNavigation.down: visibleChildren.length - != 0 ? settingsMenuButton.getNextItem( - 1) : null + KeyNavigation.up: visibleChildren.length != 0 ? settingsMenuButton.getPreviousItem(1) : null + KeyNavigation.down: visibleChildren.length != 0 ? settingsMenuButton.getNextItem(1) : null } IconLabelButton { id: settingsButton Layout.fillWidth: true visible: !SettingsCpp.hideSettings - icon.width: Math.round(32 * DefaultStyle.dp) - icon.height: Math.round(32 * DefaultStyle.dp) + icon.width: Utils.getSizeWithScreenRatio(32) + icon.height: Utils.getSizeWithScreenRatio(32) text: qsTr("settings_title") icon.source: AppIcons.settings onClicked: { var page = settingsPageComponent.createObject(parent); openContextualMenuComponent(page) } - KeyNavigation.up: visibleChildren.length - != 0 ? settingsMenuButton.getPreviousItem( - 2) : null - KeyNavigation.down: visibleChildren.length - != 0 ? settingsMenuButton.getNextItem( - 2) : null + KeyNavigation.up: visibleChildren.length != 0 ? settingsMenuButton.getPreviousItem(2) : null + KeyNavigation.down: visibleChildren.length != 0 ? settingsMenuButton.getNextItem(2) : null } IconLabelButton { id: recordsButton Layout.fillWidth: true visible: !SettingsCpp.disableCallRecordings - icon.width: Math.round(32 * DefaultStyle.dp) - icon.height: Math.round(32 * DefaultStyle.dp) + icon.width: Utils.getSizeWithScreenRatio(32) + icon.height: Utils.getSizeWithScreenRatio(32) //: "Enregistrements" text: qsTr("recordings_title") icon.source: AppIcons.micro - KeyNavigation.up: visibleChildren.length - != 0 ? settingsMenuButton.getPreviousItem( - 3) : null - KeyNavigation.down: visibleChildren.length - != 0 ? settingsMenuButton.getNextItem( - 3) : null + KeyNavigation.up: visibleChildren.length != 0 ? settingsMenuButton.getPreviousItem(3) : null + KeyNavigation.down: visibleChildren.length != 0 ? settingsMenuButton.getNextItem(3) : null } IconLabelButton { id: helpButton Layout.fillWidth: true - icon.width: Math.round(32 * DefaultStyle.dp) - icon.height: Math.round(32 * DefaultStyle.dp) + icon.width: Utils.getSizeWithScreenRatio(32) + icon.height: Utils.getSizeWithScreenRatio(32) //: "Aide" text: qsTr("help_title") icon.source: AppIcons.question @@ -510,62 +515,48 @@ Item { var page = helpPageComponent.createObject(parent); openContextualMenuComponent(page) } - KeyNavigation.up: visibleChildren.length - != 0 ? settingsMenuButton.getPreviousItem( - 4) : null - KeyNavigation.down: visibleChildren.length - != 0 ? settingsMenuButton.getNextItem( - 4) : null + KeyNavigation.up: visibleChildren.length != 0 ? settingsMenuButton.getPreviousItem(4) : null + KeyNavigation.down: visibleChildren.length != 0 ? settingsMenuButton.getNextItem(4) : null } IconLabelButton { id: quitButton Layout.fillWidth: true - icon.width: Math.round(32 * DefaultStyle.dp) - icon.height: Math.round(32 * DefaultStyle.dp) + icon.width: Utils.getSizeWithScreenRatio(32) + icon.height: Utils.getSizeWithScreenRatio(32) //: "Quitter l'application" text: qsTr("help_quit_title") icon.source: AppIcons.power onClicked: { - settingsMenuButton.popup.close() + settingsMenuButton.popup.close(); //: "Quitter %1 ?" - UtilsCpp.getMainWindow().showConfirmationLambdaPopup("", qsTr("quit_app_question").arg(applicationName),"", - function (confirmed) { - if (confirmed) { - console.info("Exiting App from Top Menu") - Qt.quit() - } - }) + UtilsCpp.getMainWindow().showConfirmationLambdaPopup("", qsTr("quit_app_question").arg(applicationName), "", function (confirmed) { + if (confirmed) { + console.info("Exiting App from Top Menu"); + Qt.quit(); + } + }); } - KeyNavigation.up: visibleChildren.length - != 0 ? settingsMenuButton.getPreviousItem( - 5) : null - KeyNavigation.down: visibleChildren.length - != 0 ? settingsMenuButton.getNextItem( - 5) : null + KeyNavigation.up: visibleChildren.length != 0 ? settingsMenuButton.getPreviousItem(5) : null + KeyNavigation.down: visibleChildren.length != 0 ? settingsMenuButton.getNextItem(5) : null } Rectangle { Layout.fillWidth: true - Layout.preferredHeight: Math.max(Math.round(1 * DefaultStyle.dp), 1) + Layout.preferredHeight: Math.max(Utils.getSizeWithScreenRatio(1), 1) visible: addAccountButton.visible color: DefaultStyle.main2_400 } IconLabelButton { id: addAccountButton Layout.fillWidth: true - visible: SettingsCpp.maxAccount == 0 - || SettingsCpp.maxAccount > accountProxy.count - icon.width: Math.round(32 * DefaultStyle.dp) - icon.height: Math.round(32 * DefaultStyle.dp) + visible: SettingsCpp.maxAccount == 0 || SettingsCpp.maxAccount > accountProxy.count + icon.width: Utils.getSizeWithScreenRatio(32) + icon.height: Utils.getSizeWithScreenRatio(32) //: "Ajouter un compte" text: qsTr("drawer_menu_add_account") icon.source: AppIcons.plusCircle onClicked: mainItem.addAccountRequest() - KeyNavigation.up: visibleChildren.length - != 0 ? settingsMenuButton.getPreviousItem( - 7) : null - KeyNavigation.down: visibleChildren.length - != 0 ? settingsMenuButton.getNextItem( - 7) : null + KeyNavigation.up: visibleChildren.length != 0 ? settingsMenuButton.getPreviousItem(7) : null + KeyNavigation.down: visibleChildren.length != 0 ? settingsMenuButton.getNextItem(7) : null } } } @@ -579,16 +570,15 @@ Item { objectName: "mainStackLayout" property int _currentIndex: tabbar.currentIndex currentIndex: -1 - onActiveFocusChanged: if (activeFocus - && currentIndex >= 0) - children[currentIndex].forceActiveFocus() + onActiveFocusChanged: if (activeFocus && currentIndex >= 0) + children[currentIndex].forceActiveFocus() on_CurrentIndexChanged: { if (count > 0) { if (_currentIndex >= count && tabbar.model[_currentIndex].link) { - Qt.openUrlExternally(tabbar.model[_currentIndex].link) + Qt.openUrlExternally(tabbar.model[_currentIndex].link); } else if (_currentIndex >= 0) { - currentIndex = _currentIndex - SettingsCpp.setLastActiveTabIndex(currentIndex) + currentIndex = _currentIndex; + SettingsCpp.setLastActiveTabIndex(currentIndex); } } } @@ -597,41 +587,40 @@ Item { Connections { target: mainItem function onOpenNewCallRequest() { - callPage.goToNewCall() + callPage.goToNewCall(); } function onCallCreated() { - callPage.goToCallHistory() + callPage.goToCallHistory(); } function onOpenCallHistory() { - callPage.goToCallHistory() + callPage.goToCallHistory(); } function onOpenNumPadRequest() { - callPage.openNumPadRequest() + callPage.openNumPadRequest(); } } onCreateContactRequested: (name, address) => { - mainItem.createContact( - name, address) - } + mainItem.createContact(name, address); + } Component.onCompleted: { - magicSearchBar.numericPadPopup = callPage.numericPadPopup + magicSearchBar.numericPadPopup = callPage.numericPadPopup; } onGoToCallForwardSettings: { - var page = settingsPageComponent.createObject(parent, { - defaultIndex: 1 - }); - openContextualMenuComponent(page) - } + var page = settingsPageComponent.createObject(parent, { + defaultIndex: 1 + }); + openContextualMenuComponent(page); + } } ContactPage { id: contactPage Connections { target: mainItem function onCreateContactRequested(name, address) { - contactPage.createContact(name, address) + contactPage.createContact(name, address); } function onDisplayContactRequested(contactAddress) { - contactPage.initialFriendToDisplay = contactAddress + contactPage.initialFriendToDisplay = contactAddress; } } } @@ -640,25 +629,25 @@ Item { Connections { target: mainItem function onDisplayChatRequested(contactAddress) { - console.log("display chat requested, open with address", contactAddress) - chatPage.remoteAddress = "" - chatPage.remoteAddress = contactAddress + console.log("display chat requested, open with address", contactAddress); + chatPage.remoteAddress = ""; + chatPage.remoteAddress = contactAddress; } function onOpenChatRequested(chat) { - console.log("open chat requested, open", chat.core.title) - chatPage.openChatRequested(chat) + console.log("open chat requested, open", chat.core.title); + chatPage.openChatRequested(chat); } } } MeetingPage { - id: meetingPage - Connections { - target: mainItem - function onScheduleMeetingRequested(subject, addresses) { - meetingPage.createPreFilledMeeting(subject, addresses) - } - } - } + id: meetingPage + Connections { + target: mainItem + function onScheduleMeetingRequested(subject, addresses) { + meetingPage.createPreFilledMeeting(subject, addresses); + } + } + } } } Component { @@ -666,8 +655,8 @@ Item { AccountSettingsPage { onGoBack: closeContextualMenuComponent() onAccountRemoved: { - closeContextualMenuComponent() - mainItem.accountRemoved() + closeContextualMenuComponent(); + mainItem.accountRemoved(); } } } @@ -697,7 +686,7 @@ Item { pushExit: noTransition popEnter: noTransition popExit: noTransition - Layout.topMargin: Math.round(24 * DefaultStyle.dp) + Layout.topMargin: Utils.getSizeWithScreenRatio(24) Layout.fillWidth: true Layout.fillHeight: true initialItem: mainStackLayoutComponent diff --git a/Linphone/view/Page/Layout/Settings/AbstractSettingsLayout.qml b/Linphone/view/Page/Layout/Settings/AbstractSettingsLayout.qml index ccd744fbc..f14203d05 100644 --- a/Linphone/view/Page/Layout/Settings/AbstractSettingsLayout.qml +++ b/Linphone/view/Page/Layout/Settings/AbstractSettingsLayout.qml @@ -2,8 +2,8 @@ import QtQuick import QtQuick.Layouts import QtQuick.Controls.Basic as Control - import Linphone +import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle Rectangle { @@ -17,7 +17,7 @@ Rectangle { color: DefaultStyle.grey_0 property var container // property real contentHeight: contentListView.contentHeight - property real minimumWidthForSwitchintToRowLayout: Math.round(981 * DefaultStyle.dp) + property real minimumWidthForSwitchintToRowLayout: Utils.getSizeWithScreenRatio(981) property var useVerticalLayout property bool saveButtonVisible: true signal save() @@ -38,8 +38,8 @@ Rectangle { id: header anchors.left: parent.left anchors.right: parent.right - leftPadding: Math.round(45 * DefaultStyle.dp) - rightPadding: Math.round(45 * DefaultStyle.dp) + leftPadding: Utils.getSizeWithScreenRatio(45) + rightPadding: Utils.getSizeWithScreenRatio(45) z: 1 background: Rectangle { anchors.fill: parent @@ -48,21 +48,23 @@ Rectangle { contentItem: ColumnLayout { RowLayout { Layout.fillWidth: true - Layout.topMargin: Math.round(20 * DefaultStyle.dp) - spacing: Math.round(5 * DefaultStyle.dp) - Layout.bottomMargin: Math.round(10 * DefaultStyle.dp) + Layout.topMargin: Utils.getSizeWithScreenRatio(20) + spacing: Utils.getSizeWithScreenRatio(5) + Layout.bottomMargin: Utils.getSizeWithScreenRatio(10) Button { id: backButton - Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) - Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(30) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(30) icon.source: AppIcons.leftArrow focus: true visible: mainItem.container.depth > 1 - Layout.rightMargin: Math.round(41 * DefaultStyle.dp) + Layout.rightMargin: Utils.getSizeWithScreenRatio(41) style: ButtonStyle.noBackground onClicked: { mainItem.container.pop() } + //: Return + Accessible.name: qsTr("return_accessible_name") } Text { text: titleText @@ -75,15 +77,17 @@ Rectangle { Loader { Layout.alignment: Qt.AlignRight sourceComponent: mainItem.topbarOptionalComponent - Layout.rightMargin: Math.round(34 * DefaultStyle.dp) + Layout.rightMargin: Utils.getSizeWithScreenRatio(34) } MediumButton { id: saveButton style: ButtonStyle.main //: "Enregistrer" text: qsTr("save") - Layout.rightMargin: Math.round(6 * DefaultStyle.dp) + Layout.rightMargin: Utils.getSizeWithScreenRatio(6) visible: mainItem.saveButtonVisible + //: Save %1 settings + Accessible.name: qsTr("save_settings_accessible_name").arg(mainItem.titleText) onClicked: { mainItem.save() } @@ -91,8 +95,8 @@ Rectangle { } Rectangle { Layout.fillWidth: true - height: Math.max(Math.round(1 * DefaultStyle.dp), 1) - color: DefaultStyle.main2_500main + height: Math.max(Utils.getSizeWithScreenRatio(1), 1) + color: DefaultStyle.main2_500_main } } } @@ -102,7 +106,7 @@ Rectangle { anchors.right: parent.right anchors.bottom: parent.bottom anchors.top: header.bottom - anchors.topMargin: Math.round(16 * DefaultStyle.dp) + anchors.topMargin: Utils.getSizeWithScreenRatio(16) // Workaround while the CI is made with Qt6.5.3 // When updated to 6.8, remove this Item and // change the ScrollView with a Flickable @@ -116,7 +120,7 @@ Rectangle { anchors.top: parent.top anchors.bottom: parent.bottom anchors.right: parent.right - anchors.rightMargin: Math.round(15 * DefaultStyle.dp) + anchors.rightMargin: Utils.getSizeWithScreenRatio(15) } Control.ScrollBar.horizontal: ScrollBar { active: false @@ -126,22 +130,22 @@ Rectangle { model: mainItem.contentModel anchors.left: parent.left anchors.right: parent.right - anchors.leftMargin: Math.round(45 * DefaultStyle.dp) - anchors.rightMargin: Math.round(45 * DefaultStyle.dp) + anchors.leftMargin: Utils.getSizeWithScreenRatio(45) + anchors.rightMargin: Utils.getSizeWithScreenRatio(45) height: contentHeight - spacing: Math.round(10 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(10) delegate: ColumnLayout { visible: modelData.visible != undefined ? modelData.visible: true Component.onCompleted: if (!visible) height = 0 - spacing: Math.round(16 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(16) width: contentListView.width Rectangle { visible: index !== 0 Layout.topMargin: Math.round((modelData.hideTopSeparator ? 0 : 16) * DefaultStyle.dp) - Layout.bottomMargin: Math.round(16 * DefaultStyle.dp) + Layout.bottomMargin: Utils.getSizeWithScreenRatio(16) Layout.fillWidth: true - height: Math.max(Math.round(1 * DefaultStyle.dp), 1) - color: modelData.hideTopSeparator ? 'transparent' : DefaultStyle.main2_500main + height: Math.max(Utils.getSizeWithScreenRatio(1), 1) + color: modelData.hideTopSeparator ? 'transparent' : DefaultStyle.main2_500_main } GridLayout { rows: 1 @@ -149,11 +153,11 @@ Rectangle { Layout.fillWidth: true // Layout.preferredWidth: parent.width rowSpacing: Math.round((modelData.title.length > 0 || modelData.subTitle.length > 0 ? 20 : 0) * DefaultStyle.dp) - columnSpacing: Math.round(47 * DefaultStyle.dp) + columnSpacing: Utils.getSizeWithScreenRatio(47) ColumnLayout { - Layout.preferredWidth: Math.round(341 * DefaultStyle.dp) - Layout.maximumWidth: Math.round(341 * DefaultStyle.dp) - spacing: Math.round(3 * DefaultStyle.dp) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(341) + Layout.maximumWidth: Utils.getSizeWithScreenRatio(341) + spacing: Utils.getSizeWithScreenRatio(3) Text { text: modelData.title visible: modelData.title.length > 0 @@ -176,8 +180,8 @@ Rectangle { } RowLayout { Layout.topMargin: Math.round((modelData.hideTopMargin ? 0 : (mainItem.useVerticalLayout ? 10 : 21)) * DefaultStyle.dp) - Layout.bottomMargin: Math.round(21 * DefaultStyle.dp) - Layout.leftMargin: mainItem.useVerticalLayout ? 0 : Math.round(17 * DefaultStyle.dp) + Layout.bottomMargin: Utils.getSizeWithScreenRatio(21) + Layout.leftMargin: mainItem.useVerticalLayout ? 0 : Utils.getSizeWithScreenRatio(17) Layout.preferredWidth: Math.round((modelData.customWidth > 0 ? modelData.customWidth : 545) * DefaultStyle.dp) Layout.alignment: Qt.AlignRight Loader { diff --git a/Linphone/view/Page/Layout/Settings/AccountSettingsGeneralLayout.qml b/Linphone/view/Page/Layout/Settings/AccountSettingsGeneralLayout.qml index 6997f8c1f..5d53d37ea 100644 --- a/Linphone/view/Page/Layout/Settings/AccountSettingsGeneralLayout.qml +++ b/Linphone/view/Page/Layout/Settings/AccountSettingsGeneralLayout.qml @@ -180,7 +180,7 @@ AbstractSettingsLayout { text: qsTr("manage_account_delete") font: Typography.p2l wrapMode: Text.WordWrap - color: DefaultStyle.danger_500main + color: DefaultStyle.danger_500_main Layout.fillWidth: true } Text { @@ -188,7 +188,7 @@ AbstractSettingsLayout { text: qsTr("manage_account_delete_message") font: Typography.p1 wrapMode: Text.WordWrap - color: DefaultStyle.main2_500main + color: DefaultStyle.main2_500_main Layout.fillWidth: true } } diff --git a/Linphone/view/Page/Layout/Settings/AdvancedSettingsLayout.qml b/Linphone/view/Page/Layout/Settings/AdvancedSettingsLayout.qml index 16e60e48c..c11fe3060 100644 --- a/Linphone/view/Page/Layout/Settings/AdvancedSettingsLayout.qml +++ b/Linphone/view/Page/Layout/Settings/AdvancedSettingsLayout.qml @@ -99,6 +99,8 @@ AbstractSettingsLayout { //: Invalid URL format UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), qsTr("settings_advanced_invalid_url_message"), false, UtilsCpp.getMainWindow()) } + //: "Download and apply remote provisioning" + Accessible.name: qsTr("download_apply_remote_provisioning_accessible_name") } } } @@ -124,6 +126,7 @@ AbstractSettingsLayout { propertyName: "mediaEncryption" textRole: 'display_name' propertyOwner: SettingsCpp + Accessible.name: qsTr("settings_advanced_media_encryption_title") } } SwitchSetting { diff --git a/Linphone/view/Page/Layout/Settings/CallSettingsLayout.qml b/Linphone/view/Page/Layout/Settings/CallSettingsLayout.qml index a615e9e83..89838878d 100644 --- a/Linphone/view/Page/Layout/Settings/CallSettingsLayout.qml +++ b/Linphone/view/Page/Layout/Settings/CallSettingsLayout.qml @@ -126,6 +126,8 @@ AbstractSettingsLayout { onClicked: { fileDialog.open() } + //: Choose ringtone file + Accessible.name:qsTr("choose_ringtone_file_accessible_name") } } } diff --git a/Linphone/view/Page/Layout/Settings/ContactsSettingsLayout.qml b/Linphone/view/Page/Layout/Settings/ContactsSettingsLayout.qml index e764dece2..194aaac20 100644 --- a/Linphone/view/Page/Layout/Settings/ContactsSettingsLayout.qml +++ b/Linphone/view/Page/Layout/Settings/ContactsSettingsLayout.qml @@ -42,6 +42,10 @@ AbstractSettingsLayout { addText: qsTr("settings_contacts_add_ldap_server_title") //: "Modifier un annuaire LDAP" editText: qsTr("settings_contacts_edit_ldap_server_title") + //: "Editer le serveur LDAP %1" + accessibleEditButtonText: qsTr("edit_ldap_server_accessible_name") + //: "Utiliser le serveur LDAP %1" + accessibleUseButtonText: qsTr("use_ldap_server_accessible_name") proxyModel: LdapProxy {} newItemGui: createGuiObject('Ldap') settingsLayout: layoutUrl("LdapSettingsLayout") @@ -69,6 +73,10 @@ AbstractSettingsLayout { addText: qsTr("settings_contacts_add_carddav_server_title") //: "Modifier un carnet d'adresse CardDAV" editText: qsTr("settings_contacts_edit_carddav_server_title") + //: "Editer le carnet d'adresses CardDAV %1" + accessibleEditButtonText: qsTr("edit_cardav_server_accessible_name") + //: "Utiliser le d'adresses CardDAV %1" + accessibleUseButtonText: qsTr("use_cardav_server_accessible_name") proxyModel: CarddavProxy { onModelReset: { carddavProvider.showAddButton = carddavProvider.proxyModel.count == 0 diff --git a/Linphone/view/Page/Layout/Settings/ContactsSettingsProviderLayout.qml b/Linphone/view/Page/Layout/Settings/ContactsSettingsProviderLayout.qml index 86f94bdfb..51d531475 100644 --- a/Linphone/view/Page/Layout/Settings/ContactsSettingsProviderLayout.qml +++ b/Linphone/view/Page/Layout/Settings/ContactsSettingsProviderLayout.qml @@ -5,6 +5,7 @@ import QtQuick.Controls.Basic as Control import SettingsCpp 1.0 import UtilsCpp import Linphone +import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle RowLayout { @@ -14,6 +15,8 @@ RowLayout { property string addText property string addTextDescription property string editText + property string accessibleEditButtonText + property string accessibleUseButtonText property var newItemGui property string settingsLayout property var proxyModel @@ -25,18 +28,18 @@ RowLayout { signal save() signal undo() - spacing: Math.round(5 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(5) ColumnLayout { Layout.fillWidth: true Layout.fillHeight: true - spacing: Math.round(16 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(16) Repeater { model: mainItem.proxyModel RowLayout { Layout.fillWidth: true Layout.alignment: Qt.AlignLeft|Qt.AlignHCenter - Layout.preferredHeight: Math.round(74 * DefaultStyle.dp) - spacing: Math.round(20 * DefaultStyle.dp) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(74) + spacing: Utils.getSizeWithScreenRatio(20) Text { text: modelData.core[titleProperty] font: Typography.p2l @@ -51,8 +54,10 @@ RowLayout { Button { style: ButtonStyle.noBackground icon.source: AppIcons.pencil - icon.width: Math.round(24 * DefaultStyle.dp) - icon.height: Math.round(24 * DefaultStyle.dp) + icon.width: Utils.getSizeWithScreenRatio(24) + icon.height: Utils.getSizeWithScreenRatio(24) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(30) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(30) onClicked: { mainItem.owner.container.push(mainItem.settingsLayout, { titleText: mainItem.editText, @@ -60,6 +65,7 @@ RowLayout { container: mainItem.owner.container, isNew: false}) } + Accessible.name: mainItem.accessibleEditButtonText.arg(modelData.core[titleProperty]) } Switch { id: switchButton @@ -69,6 +75,7 @@ RowLayout { onToggled: { binding.when = true } + Accessible.name: mainItem.accessibleUseButtonText.arg(modelData.core[titleProperty]) } Binding { id: binding @@ -106,7 +113,7 @@ RowLayout { } RowLayout { Layout.fillWidth: true - spacing: Math.round(5 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(5) Item { Layout.fillWidth: true } @@ -114,6 +121,7 @@ RowLayout { Layout.alignment: Qt.AlignRight | Qt.AlignHCenter //: "Ajouter" text: qsTr("add") + Accessible.name: mainItem.addText style: ButtonStyle.main visible: mainItem.showAddButton onClicked: { diff --git a/Linphone/view/Page/Layout/Settings/LdapSettingsLayout.qml b/Linphone/view/Page/Layout/Settings/LdapSettingsLayout.qml index fb27f2c05..b1513bfe6 100644 --- a/Linphone/view/Page/Layout/Settings/LdapSettingsLayout.qml +++ b/Linphone/view/Page/Layout/Settings/LdapSettingsLayout.qml @@ -6,6 +6,7 @@ import QtQuick.Dialogs import Linphone import SettingsCpp 1.0 import UtilsCpp +import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle AbstractSettingsLayout { @@ -39,12 +40,14 @@ AbstractSettingsLayout { Component { id: topBar RowLayout { - spacing: Math.round(20 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(20) Button { style: ButtonStyle.noBackground icon.source: AppIcons.trashCan - icon.width: Math.round(32 * DefaultStyle.dp) - icon.height: Math.round(32 * DefaultStyle.dp) + icon.width: Utils.getSizeWithScreenRatio(30) + icon.height: Utils.getSizeWithScreenRatio(30) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(38) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(38) visible: !isNew onClicked: { var mainWin = UtilsCpp.getMainWindow() @@ -60,6 +63,8 @@ AbstractSettingsLayout { } ) } + //: Delete LDAP server + Accessible.name: qsTr("delete_ldap_server_accessible_name") } } } @@ -68,10 +73,10 @@ AbstractSettingsLayout { id: ldapParametersComponent ColumnLayout { Layout.fillWidth: true - spacing: Math.round(20 * DefaultStyle.dp) - Layout.rightMargin: Math.round(44 * DefaultStyle.dp) - Layout.topMargin: Math.round(20 * DefaultStyle.dp) - Layout.leftMargin: Math.round(64 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(20) + Layout.rightMargin: Utils.getSizeWithScreenRatio(44) + Layout.topMargin: Utils.getSizeWithScreenRatio(20) + Layout.leftMargin: Utils.getSizeWithScreenRatio(64) DecoratedTextField { id: server propertyName: "serverUrl" diff --git a/Linphone/view/Page/Main/Account/AccountListView.qml b/Linphone/view/Page/Main/Account/AccountListView.qml index 006f98f7d..a7554c50b 100644 --- a/Linphone/view/Page/Main/Account/AccountListView.qml +++ b/Linphone/view/Page/Main/Account/AccountListView.qml @@ -7,84 +7,93 @@ import QtQuick.Dialogs import Linphone import UtilsCpp import SettingsCpp +import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils +import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle -Item { +ColumnLayout{ id: mainItem - width: Math.round(517 * DefaultStyle.dp) - - readonly property real spacing: Math.round(16 * DefaultStyle.dp) - property AccountProxy accountProxy + anchors.top: parent.top + anchors.topMargin: Utils.getSizeWithScreenRatio(23) + anchors.left: parent.left + anchors.leftMargin: Utils.getSizeWithScreenRatio(24) + anchors.right: parent.right + anchors.rightMargin: Utils.getSizeWithScreenRatio(24) + anchors.bottom: parent.bottom + anchors.bottomMargin: Utils.getSizeWithScreenRatio(23) signal addAccountRequest() signal editAccount(AccountGui account) + readonly property var childrenWidth: Utils.getSizeWithScreenRatio(517) - implicitHeight: list.contentHeight + Math.round(32 * DefaultStyle.dp) + 1 + addAccountButton.height - ColumnLayout{ - id: childLayout - anchors.top: parent.top - anchors.topMargin: mainItem.topPadding - anchors.left: parent.left - anchors.leftMargin: mainItem.leftPadding - anchors.right: parent.right - anchors.rightMargin: mainItem.rightPadding - anchors.bottom: parent.bottom - anchors.bottomMargin: mainItem.bottomPadding - ListView{ - id: list - Layout.preferredHeight: contentHeight - Layout.fillWidth: true - spacing: mainItem.spacing - model: AccountProxy { - id: accountProxy - sourceModel: AppCpp.accounts + readonly property real spacing: Utils.getSizeWithScreenRatio(16) + required property var getPreviousItem + required property var getNextItem + property AccountProxy accountProxy + property var popupId + Component{ + id: contactDelegate + Contact{ + id: contactItem + Layout.preferredWidth: mainItem.childrenWidth + account: modelData + isSelected: modelData && accountProxy.defaultAccount && modelData.core === accountProxy.defaultAccount.core + onAvatarClicked: fileDialog.open() + onBackgroundClicked: { + modelData.core.lSetDefaultAccount() } - delegate: Contact{ - id: contactItem - width: list.width - account: modelData - property bool isSelected: modelData && accountProxy.defaultAccount && modelData.core === accountProxy.defaultAccount.core - onAvatarClicked: fileDialog.open() - onBackgroundClicked: { - modelData.core.lSetDefaultAccount() - } - onEdit: editAccount(modelData) - hoverEnabled: true - backgroundColor: contactItem.isSelected - ? DefaultStyle.grey_200 - : hovered - ? DefaultStyle.main2_100 - : DefaultStyle.grey_0 - FileDialog { - id: fileDialog - currentFolder: StandardPaths.standardLocations(StandardPaths.PicturesLocation)[0] - onAccepted: { - var avatarPath = UtilsCpp.createAvatar( selectedFile ) - if(avatarPath){ - modelData.core.pictureUri = avatarPath - } + onEdit: editAccount(modelData) + hoverEnabled: true + spacing: mainItem.spacing + FileDialog { + id: fileDialog + currentFolder: StandardPaths.standardLocations(StandardPaths.PicturesLocation)[0] + onAccepted: { + var avatarPath = UtilsCpp.createAvatar( selectedFile ) + if(avatarPath){ + modelData.core.pictureUri = avatarPath } } } - } - Rectangle{ - id: separator - Layout.fillWidth: true - Layout.topMargin: mainItem.spacing - Layout.bottomMargin: mainItem.spacing - visible: addAccountButton.visible - height: Math.max(Math.round(1 * DefaultStyle.dp), 1) - color: DefaultStyle.main2_300 - } - IconLabelButton{ - id: addAccountButton - Layout.fillWidth: true - visible: SettingsCpp.maxAccount == 0 || SettingsCpp.maxAccount > accountProxy.count - onClicked: mainItem.addAccountRequest() - icon.source: AppIcons.plusCircle - icon.width: Math.round(32 * DefaultStyle.dp) - icon.height: Math.round(32 * DefaultStyle.dp) - text: 'Ajouter un compte' + style: ButtonStyle.whiteSelected + KeyNavigation.up: visibleChildren.length + != 0 ? getPreviousItem( + index) : null + KeyNavigation.down: visibleChildren.length + != 0 ? getNextItem( + index) : null } } -} + + Repeater{ + model: AccountProxy { + id: accountProxy + sourceModel: AppCpp.accounts + } + delegate: contactDelegate + } + HorizontalBar{ + Layout.topMargin: mainItem.spacing + Layout.bottomMargin: mainItem.spacing + visible: addAccountButton.visible + color: DefaultStyle.main2_300 + } + IconLabelButton{ + id: addAccountButton + Layout.fillWidth: true + visible: SettingsCpp.maxAccount == 0 || SettingsCpp.maxAccount > accountProxy.count + onClicked: mainItem.addAccountRequest() + icon.source: AppIcons.plusCircle + icon.width: Utils.getSizeWithScreenRatio(32) + icon.height: Utils.getSizeWithScreenRatio(32) + //: Add an account + text: qsTr("add_an_account") + KeyNavigation.up: visibleChildren.length + != 0 ? getPreviousItem( + AppCpp.accounts.getCount()) : null + KeyNavigation.down: visibleChildren.length + != 0 ? getNextItem( + AppCpp.accounts.getCount()) : null + } + } + diff --git a/Linphone/view/Page/Main/Call/CallPage.qml b/Linphone/view/Page/Main/Call/CallPage.qml index b5e9b8808..211af2f5b 100644 --- a/Linphone/view/Page/Main/Call/CallPage.qml +++ b/Linphone/view/Page/Main/Call/CallPage.qml @@ -60,7 +60,7 @@ AbstractMainPage { Control.StackView.Immediate) } rightPanelStackView.initialItem: emptySelection - rightPanelStackView.width: Math.round(360 * DefaultStyle.dp) + rightPanelStackView.width: Utils.getSizeWithScreenRatio(360) onNoItemButtonPressed: goToNewCall() @@ -81,7 +81,7 @@ AbstractMainPage { Dialog { id: deleteHistoryPopup - width: Math.round(637 * DefaultStyle.dp) + width: Utils.getSizeWithScreenRatio(637) //: Supprimer l\'historique d\'appels ? title: qsTr("history_dialog_delete_all_call_logs_title") //: "L'ensemble de votre historique d'appels sera définitivement supprimé." @@ -89,7 +89,7 @@ AbstractMainPage { } Dialog { id: deleteForUserPopup - width: Math.round(637 * DefaultStyle.dp) + width: Utils.getSizeWithScreenRatio(637) //: Supprimer l'historique d\'appels ? title: qsTr("history_dialog_delete_call_logs_title") //: "L\'ensemble de votre historique d\'appels avec ce correspondant sera définitivement supprimé." @@ -104,7 +104,7 @@ AbstractMainPage { Control.StackView { id: listStackView anchors.fill: parent - anchors.leftMargin: Math.round(45 * DefaultStyle.dp) + anchors.leftMargin: Utils.getSizeWithScreenRatio(45) clip: true initialItem: historyListItem focus: true @@ -117,7 +117,7 @@ AbstractMainPage { anchors.bottom: parent.bottom anchors.left: parent.left anchors.right: parent.right - height: Math.round(402 * DefaultStyle.dp) + height: Utils.getSizeWithScreenRatio(402) NumericPadPopup { id: numericPadPopupItem width: parent.width @@ -130,7 +130,7 @@ AbstractMainPage { } } - Component { + Component { id: historyListItem FocusScope { objectName: "historyListItem" @@ -140,7 +140,7 @@ AbstractMainPage { spacing: 0 RowLayout { id: titleCallLayout - spacing: Math.round(16 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(16) Text { Layout.fillWidth: true //: "Appels" @@ -154,12 +154,14 @@ AbstractMainPage { } PopupButton { id: removeHistory - width: Math.round(24 * DefaultStyle.dp) - height: Math.round(24 * DefaultStyle.dp) + icon.width: Utils.getSizeWithScreenRatio(24) + icon.height: Utils.getSizeWithScreenRatio(24) focus: true popup.x: 0 KeyNavigation.right: newCallButton KeyNavigation.down: listStackView + //: Call history options + popUpTitle: qsTr("call_history_list_options_accessible_name") popup.contentItem: ColumnLayout { IconLabelButton { Layout.fillWidth: true @@ -186,13 +188,15 @@ AbstractMainPage { id: newCallButton style: ButtonStyle.noBackground icon.source: AppIcons.newCall - Layout.preferredWidth: Math.round(28 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(28 * DefaultStyle.dp) - Layout.rightMargin: Math.round(39 * DefaultStyle.dp) - icon.width: Math.round(28 * DefaultStyle.dp) - icon.height: Math.round(28 * DefaultStyle.dp) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(34) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(34) + Layout.rightMargin: Utils.getSizeWithScreenRatio(39) + icon.width: Utils.getSizeWithScreenRatio(28) + icon.height: Utils.getSizeWithScreenRatio(28) KeyNavigation.left: removeHistory KeyNavigation.down: listStackView + //: Create new call + Accessible.name: qsTr("create_new_call_accessible_name") onClicked: { console.debug("[CallPage]User: create new call") listStackView.push(newCallItem) @@ -202,8 +206,8 @@ AbstractMainPage { SearchBar { id: searchBar Layout.fillWidth: true - Layout.topMargin: Math.round(18 * DefaultStyle.dp) - Layout.rightMargin: Math.round(39 * DefaultStyle.dp) + Layout.topMargin: Utils.getSizeWithScreenRatio(18) + Layout.rightMargin: Utils.getSizeWithScreenRatio(39) //: "Rechercher un appel" placeholderText: qsTr("call_search_in_history") visible: historyListView.count !== 0 || text.length !== 0 @@ -220,9 +224,9 @@ AbstractMainPage { Rectangle { visible: SettingsCpp.callForwardToAddress.length > 0 Layout.fillWidth: true - Layout.preferredHeight: Math.round(40 * DefaultStyle.dp) - Layout.topMargin: Math.round(18 * DefaultStyle.dp) - Layout.rightMargin: Math.round(39 * DefaultStyle.dp) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(40) + Layout.topMargin: Utils.getSizeWithScreenRatio(18) + Layout.rightMargin: Utils.getSizeWithScreenRatio(39) color: "transparent" radius: 25 * DefaultStyle.dp border.color: DefaultStyle.warning_500_main @@ -235,8 +239,8 @@ AbstractMainPage { fillMode: Image.PreserveAspectFit imageSource: AppIcons.callForward colorizationColor: DefaultStyle.warning_500_main - Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) - Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(24) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(24) } Text { text: qsTr("call_forward_to_address_info") + (SettingsCpp.callForwardToAddress == 'voicemail' ? qsTr("call_forward_to_address_info_voicemail") : SettingsCpp.callForwardToAddress) @@ -259,14 +263,14 @@ AbstractMainPage { Control.Control { id: listLayout anchors.fill: parent - anchors.rightMargin: Math.round(39 * DefaultStyle.dp) + anchors.rightMargin: Utils.getSizeWithScreenRatio(39) padding: 0 background: Item {} contentItem: ColumnLayout { Text { visible: historyListView.count === 0 && !historyListView.loading Layout.alignment: Qt.AlignHCenter - Layout.topMargin: Math.round(137 * DefaultStyle.dp) + Layout.topMargin: Utils.getSizeWithScreenRatio(137) //: "Aucun résultat…" text: searchBar.text.length != 0 ? qsTr("list_filter_no_result_found") //: "Aucun appel dans votre historique" @@ -280,7 +284,7 @@ AbstractMainPage { id: historyListView Layout.fillWidth: true Layout.fillHeight: true - Layout.topMargin: Math.round(38 * DefaultStyle.dp) + Layout.topMargin: Utils.getSizeWithScreenRatio(38) searchBar: searchBar Control.ScrollBar.vertical: scrollbar @@ -314,7 +318,7 @@ AbstractMainPage { anchors.top: parent.top anchors.bottom: parent.bottom anchors.right: parent.right - anchors.rightMargin: Math.round(8 * DefaultStyle.dp) + anchors.rightMargin: Utils.getSizeWithScreenRatio(8) policy: Control.ScrollBar.AsNeeded } } @@ -336,14 +340,18 @@ AbstractMainPage { anchors.fill: parent spacing: 0 RowLayout { - spacing: Math.round(10 * DefaultStyle.dp) + spacing: Utils.getSizeWithScreenRatio(10) Button { - Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) + icon.width: Utils.getSizeWithScreenRatio(24) + icon.height: Utils.getSizeWithScreenRatio(24) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(30) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(30) style: ButtonStyle.noBackground icon.source: AppIcons.leftArrow focus: true KeyNavigation.down: listStackView + //: Return to call history + Accessible.name: qsTr("return_to_call_history_accessible_name") onClicked: { console.debug( "[CallPage]User: return to call history") @@ -365,7 +373,7 @@ AbstractMainPage { } NewCallForm { id: callContactsList - Layout.topMargin: Math.round(18 * DefaultStyle.dp) + Layout.topMargin: Utils.getSizeWithScreenRatio(18) Layout.fillWidth: true Layout.fillHeight: true focus: true @@ -433,8 +441,8 @@ AbstractMainPage { CallHistoryLayout { id: contactDetail anchors.fill: parent - anchors.topMargin: Math.round(45 * DefaultStyle.dp) - anchors.bottomMargin: Math.round(45 * DefaultStyle.dp) + anchors.topMargin: Utils.getSizeWithScreenRatio(45) + anchors.bottomMargin: Utils.getSizeWithScreenRatio(45) visible: mainItem.selectedRowHistoryGui != undefined callHistoryGui: selectedRowHistoryGui @@ -448,6 +456,7 @@ AbstractMainPage { id: detailOptions anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter + popUpTitle: qsTr("call_history_options_accessible_name") popup.x: width popup.contentItem: FocusScope { implicitHeight: detailsButtons.implicitHeight @@ -463,14 +472,15 @@ AbstractMainPage { id: detailsButtons anchors.fill: parent IconLabelButton { + id: addContactButton Layout.fillWidth: true //: "Show contact" text: contactDetail.isLocalFriend ? qsTr("menu_see_existing_contact") : //: "Add to contacts" qsTr("menu_add_address_to_contacts") icon.source: AppIcons.plusCircle - icon.width: Math.round(32 * DefaultStyle.dp) - icon.height: Math.round(32 * DefaultStyle.dp) + icon.width: Utils.getSizeWithScreenRatio(32) + icon.height: Utils.getSizeWithScreenRatio(32) onClicked: { detailOptions.close() if (contactDetail.isLocalFriend) @@ -478,14 +488,21 @@ AbstractMainPage { else mainItem.createContactRequested(contactDetail.contactName, contactDetail.contactAddress) } + KeyNavigation.up: visibleChildren.length + != 0 ? detailOptions.getPreviousItem( + 0) : null + KeyNavigation.down: visibleChildren.length + != 0 ? detailOptions.getNextItem( + 0) : null } IconLabelButton { + id: copySIPAddressButton Layout.fillWidth: true //: "Copier l'adresse SIP" text: qsTr("menu_copy_sip_address") icon.source: AppIcons.copy - icon.width: Math.round(32 * DefaultStyle.dp) - icon.height: Math.round(32 * DefaultStyle.dp) + icon.width: Utils.getSizeWithScreenRatio(32) + icon.height: Utils.getSizeWithScreenRatio(32) onClicked: { detailOptions.close() var success = UtilsCpp.copyToClipboard( @@ -505,6 +522,12 @@ AbstractMainPage { qsTr("sip_address_copy_to_clipboard_error"), false) } + KeyNavigation.up: visibleChildren.length + != 0 ? detailOptions.getPreviousItem( + 1) : null + KeyNavigation.down: visibleChildren.length + != 0 ? detailOptions.getNextItem( + 1) : null } // IconLabelButton { // background: Item {} @@ -517,17 +540,18 @@ AbstractMainPage { // } Rectangle { Layout.fillWidth: true - Layout.preferredHeight: Math.round(2 * DefaultStyle.dp) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(2) color: DefaultStyle.main2_400 } IconLabelButton { + id: deleteHistoryButton Layout.fillWidth: true //: "Supprimer l'historique" text: qsTr("menu_delete_history") icon.source: AppIcons.trashCan - icon.width: Math.round(32 * DefaultStyle.dp) - icon.height: Math.round(32 * DefaultStyle.dp) + icon.width: Utils.getSizeWithScreenRatio(32) + icon.height: Utils.getSizeWithScreenRatio(32) style: ButtonStyle.hoveredBackgroundRed Connections { target: deleteForUserPopup @@ -541,12 +565,18 @@ AbstractMainPage { detailOptions.close() deleteForUserPopup.open() } + KeyNavigation.up: visibleChildren.length + != 0 ? detailOptions.getPreviousItem( + 2) : null + KeyNavigation.down: visibleChildren.length + != 0 ? detailOptions.getNextItem( + 2) : null } } } } detailContent: Item { - Layout.preferredWidth: Math.round(360 * DefaultStyle.dp) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(360) Layout.fillHeight: true RoundedPane { id: detailControl @@ -557,7 +587,7 @@ AbstractMainPage { id: detailListBackground anchors.fill: parent color: DefaultStyle.grey_0 - radius: Math.round(15 * DefaultStyle.dp) + radius: Utils.getSizeWithScreenRatio(15) } contentItem: Control.ScrollView { @@ -573,37 +603,37 @@ AbstractMainPage { id: detailListView Layout.fillWidth: true Layout.fillHeight: true - Layout.rightMargin: historyScrollBar.width + Math.round(8 * DefaultStyle.dp) - spacing: Math.round(14 * DefaultStyle.dp) + Layout.rightMargin: historyScrollBar.width + Utils.getSizeWithScreenRatio(8) + spacing: Utils.getSizeWithScreenRatio(14) clip: true searchText: mainItem.selectedRowHistoryGui ? mainItem.selectedRowHistoryGui.core.remoteAddress : "" - busyIndicatorSize: Math.round(40 * DefaultStyle.dp) + busyIndicatorSize: Utils.getSizeWithScreenRatio(40) - delegate: Item { - width: detailListView.width - height: Math.round(56 * DefaultStyle.dp) - RowLayout { - anchors.fill: parent - anchors.leftMargin: Math.round(20 * DefaultStyle.dp) - anchors.rightMargin: Math.round(20 * DefaultStyle.dp) - anchors.verticalCenter: parent.verticalCenter - ColumnLayout { - Layout.alignment: Qt.AlignVCenter - RowLayout { - EffectImage { - id: statusIcon - imageSource: modelData.core.status - === LinphoneEnums.CallStatus.Declined - || modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere || modelData.core.status === LinphoneEnums.CallStatus.Aborted || modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted ? AppIcons.arrowElbow : modelData.core.isOutgoing ? AppIcons.arrowUpRight : AppIcons.arrowDownLeft - colorizationColor: modelData.core.status === LinphoneEnums.CallStatus.Declined || modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere || modelData.core.status === LinphoneEnums.CallStatus.Aborted || modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted || modelData.core.status === LinphoneEnums.CallStatus.Missed ? DefaultStyle.danger_500main : modelData.core.isOutgoing ? DefaultStyle.info_500_main : DefaultStyle.success_500main - Layout.preferredWidth: Math.round(16 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(16 * DefaultStyle.dp) - transform: Rotation { - angle: modelData.core.isOutgoing - && (modelData.core.status === LinphoneEnums.CallStatus.Declined || modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere || modelData.core.status === LinphoneEnums.CallStatus.Aborted || modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted) ? 180 : 0 - origin { - x: statusIcon.width / 2 - y: statusIcon.height / 2 + delegate: Item { + width: detailListView.width + height: Utils.getSizeWithScreenRatio(56) + RowLayout { + anchors.fill: parent + anchors.leftMargin: Utils.getSizeWithScreenRatio(20) + anchors.rightMargin: Utils.getSizeWithScreenRatio(20) + anchors.verticalCenter: parent.verticalCenter + ColumnLayout { + Layout.alignment: Qt.AlignVCenter + RowLayout { + EffectImage { + id: statusIcon + imageSource: modelData.core.status + === LinphoneEnums.CallStatus.Declined + || modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere || modelData.core.status === LinphoneEnums.CallStatus.Aborted || modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted ? AppIcons.arrowElbow : modelData.core.isOutgoing ? AppIcons.arrowUpRight : AppIcons.arrowDownLeft + colorizationColor: modelData.core.status === LinphoneEnums.CallStatus.Declined || modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere || modelData.core.status === LinphoneEnums.CallStatus.Aborted || modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted || modelData.core.status === LinphoneEnums.CallStatus.Missed ? DefaultStyle.danger_500_main : modelData.core.isOutgoing ? DefaultStyle.info_500_main : DefaultStyle.success_500_main + Layout.preferredWidth: Utils.getSizeWithScreenRatio(16) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(16) + transform: Rotation { + angle: modelData.core.isOutgoing + && (modelData.core.status === LinphoneEnums.CallStatus.Declined || modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere || modelData.core.status === LinphoneEnums.CallStatus.Aborted || modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted) ? 180 : 0 + origin { + x: statusIcon.width / 2 + y: statusIcon.height / 2 } } } @@ -623,10 +653,10 @@ AbstractMainPage { } Text { text: UtilsCpp.formatDate(modelData.core.date) - color: modelData.core.status === LinphoneEnums.CallStatus.Missed ? DefaultStyle.danger_500main : DefaultStyle.main2_500main + color: modelData.core.status === LinphoneEnums.CallStatus.Missed ? DefaultStyle.danger_500_main : DefaultStyle.main2_500_main font { - pixelSize: Math.round(12 * DefaultStyle.dp) - weight: Math.round(300 * DefaultStyle.dp) + pixelSize: Utils.getSizeWithScreenRatio(12) + weight: Utils.getSizeWithScreenRatio(300) } } } @@ -639,8 +669,8 @@ AbstractMainPage { modelData.core.duration, false) font { - pixelSize: Math.round(12 * DefaultStyle.dp) - weight: Math.round(300 * DefaultStyle.dp) + pixelSize: Utils.getSizeWithScreenRatio(12) + weight: Utils.getSizeWithScreenRatio(300) } } } @@ -660,11 +690,11 @@ AbstractMainPage { id: iconLabel property string text property string iconSource - property color colorizationColor: DefaultStyle.main2_500main + property color colorizationColor: DefaultStyle.main2_500_main EffectImage { imageSource: iconLabel.iconSource - Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) + Layout.preferredWidth: Utils.getSizeWithScreenRatio(24) + Layout.preferredHeight: Utils.getSizeWithScreenRatio(24) fillMode: Image.PreserveAspectFit colorizationColor: iconLabel.colorizationColor } diff --git a/Linphone/view/Page/Main/Call/CallSettingsPanel.qml b/Linphone/view/Page/Main/Call/CallSettingsPanel.qml index e465d3d2d..870b3a3b7 100644 --- a/Linphone/view/Page/Main/Call/CallSettingsPanel.qml +++ b/Linphone/view/Page/Main/Call/CallSettingsPanel.qml @@ -2,6 +2,7 @@ import QtQuick import QtQuick.Layouts import QtQuick.Controls.Basic as Control import Linphone +import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle Control.Page { @@ -11,6 +12,8 @@ Control.Page { property alias customHeaderButtons: customButtonLayout.children property int contentItemHeight: scrollview.height property bool closeButtonVisible: true + property Item firstContentFocusableItem: undefined + property Item lastContentFocusableItem: undefined clip: true property string headerTitleText @@ -77,6 +80,9 @@ Control.Page { style: ButtonStyle.noBackground icon.source: AppIcons.closeX onClicked: mainItem.visible = false + //: Close %1 panel + Accessible.name: qsTr("close_name_panel_accessible_button").arg(mainItem.headerTitleText) + KeyNavigation.tab : firstContentFocusableItem ?? nextItemInFocusChain() } } RowLayout { @@ -106,7 +112,7 @@ Control.Page { verticalAlignment: Text.AlignVCenter text: mainItem.headerSubtitleText - color: DefaultStyle.main2_500main + color: DefaultStyle.main2_500_main font { pixelSize: Math.round(12 * DefaultStyle.dp) weight: Math.round(300 * DefaultStyle.dp) diff --git a/Linphone/view/Page/Main/Contact/ContactPage.qml b/Linphone/view/Page/Main/Contact/ContactPage.qml index b418a9f76..208c8e4d4 100644 --- a/Linphone/view/Page/Main/Contact/ContactPage.qml +++ b/Linphone/view/Page/Main/Contact/ContactPage.qml @@ -245,6 +245,8 @@ FriendGui{ mainItem.createContact("", "") } KeyNavigation.down: searchBar + //: Create new contact + Accessible.name: qsTr("create_contact_accessible_name") } } @@ -340,6 +342,8 @@ FriendGui{ icon.source: contactDetailLayout.icon style: ButtonStyle.noBackgroundOrange onClicked: contactDetailLayout.titleIconClicked() + //: More info %1 + Accessible.name: qsTr("more_info_accessible_name").arg(contactDetailLayout.label) } Item { Layout.fillWidth: true @@ -351,6 +355,12 @@ FriendGui{ checked: true icon.source: checked ? AppIcons.upArrow : AppIcons.downArrow KeyNavigation.down: contentControl + Accessible.name: (checked ? + //: Shrink %1 + qsTr("shrink_accessible_name"): + //: Expand %1 + qsTr("expand_accessible_name")).arg(contactDetailLayout.label) + } } RoundedPane { @@ -378,28 +388,6 @@ FriendGui{ property var computedContactNameObj: UtilsCpp.getDisplayName(contactAddress) property string computedContactName: computedContactNameObj ? computedContactNameObj.value : "" property string contactName: contact ? contact.core.fullName : computedContactName - component LabelButton: ColumnLayout { - id: labelButton - // property alias image: buttonImg - property alias button: button - property string label - spacing: Math.round(8 * DefaultStyle.dp) - RoundButton { - id: button - Layout.alignment: Qt.AlignHCenter - Layout.preferredWidth: Math.round(56 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(56 * DefaultStyle.dp) - style: ButtonStyle.grey - } - Text { - Layout.alignment: Qt.AlignHCenter - text: labelButton.label - font { - pixelSize: Typography.p1.pixelSize - weight: Typography.p1.weight - } - } - } component ActionsButtons: RowLayout { spacing: Math.round(58 * DefaultStyle.dp) LabelButton { @@ -533,6 +521,8 @@ FriendGui{ UtilsCpp.createCall( listViewModelData.address) } + //: Call address %1 + Accessible.name: qsTr("call_adress_accessible_name").arg(listViewModelData.address) } } @@ -639,6 +629,7 @@ FriendGui{ } onClicked: console.debug( "TODO : go to shared media") + Accessible.name: qsTr("contact_details_medias_subtitle") } } ContactDetailLayout { @@ -707,6 +698,8 @@ FriendGui{ style: ButtonStyle.tertiary //: "Vérifier" text: qsTr("contact_make_call_check_device_trust") + //: Verify %1 device + Accessible.name: qsTr("verify_device_accessible_name").arg(deviceDelegate.deviceName) onClicked: { if (SettingsCpp.getDisplayDeviceCheckConfirmation( )) { diff --git a/Linphone/view/Page/Main/Meeting/MeetingPage.qml b/Linphone/view/Page/Main/Meeting/MeetingPage.qml index 8276aa23d..45dbb2bd9 100644 --- a/Linphone/view/Page/Main/Meeting/MeetingPage.qml +++ b/Linphone/view/Page/Main/Meeting/MeetingPage.qml @@ -600,7 +600,7 @@ AbstractMainPage { Text { //: "%n participant(s) sélectionné(s)" text: qsTr("group_call_participant_selected", '', addParticipantLayout.selectedParticipantsCount).arg(addParticipantLayout.selectedParticipantsCount) - color: DefaultStyle.main2_500main + color: DefaultStyle.main2_500_main Layout.leftMargin: addParticipantsBackButton.width + addParticipantsButtons.spacing maximumLineCount: 1 font { diff --git a/Linphone/view/Page/Window/AbstractWindow.qml b/Linphone/view/Page/Window/AbstractWindow.qml index b2e38daee..b4d5d3446 100644 --- a/Linphone/view/Page/Window/AbstractWindow.qml +++ b/Linphone/view/Page/Window/AbstractWindow.qml @@ -275,7 +275,7 @@ ApplicationWindow { font.pixelSize: Math.round(14 * DefaultStyle.dp) // "%1 FPS" text: qsTr("fps_counter").arg(parent.fps) - color: parent.fps < 30 ? DefaultStyle.danger_500main : DefaultStyle.main2_900 + color: parent.fps < 30 ? DefaultStyle.danger_500_main : DefaultStyle.main2_900 } } } diff --git a/Linphone/view/Page/Window/Call/CallsWindow.qml b/Linphone/view/Page/Window/Call/CallsWindow.qml index 7b8498244..58211ed1c 100644 --- a/Linphone/view/Page/Window/Call/CallsWindow.qml +++ b/Linphone/view/Page/Window/Call/CallsWindow.qml @@ -7,6 +7,7 @@ import EnumsToStringCpp import UtilsCpp import SettingsCpp import DesktopToolsCpp +import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle AbstractWindow { @@ -28,6 +29,16 @@ AbstractWindow { property bool callTerminatedByUser: false property var callState: call ? call.core.state : LinphoneEnums.CallState.Idle property var transferState: call && call.core.transferState + property bool startingCall: mainWindow.callState == LinphoneEnums.CallState.OutgoingInit + || mainWindow.callState + == LinphoneEnums.CallState.OutgoingProgress + || mainWindow.callState + == LinphoneEnums.CallState.OutgoingRinging + || mainWindow.callState + == LinphoneEnums.CallState.OutgoingEarlyMedia + || mainWindow.callState == LinphoneEnums.CallState.IncomingReceived + property Item firstButtonInBottomTab : mainWindow.startingCall ? endCallButton : (videoCameraButton.visible && videoCameraButton.enabled ? videoCameraButton : audioMicrophoneButton) + property Item lastButtonInBottomTab : mainWindow.startingCall ? Utils.getLastFocussableItemInItem(controlCallButtons) : endCallButton onCallStateChanged: { if (callState === LinphoneEnums.CallState.Connected) { @@ -338,7 +349,7 @@ AbstractWindow { === LinphoneEnums.CallState.End || mainWindow.callState === LinphoneEnums.CallState.Released - || mainWindow.conference ? DefaultStyle.danger_500main : mainWindow.call.core.dir === LinphoneEnums.CallDir.Outgoing ? DefaultStyle.info_500_main : DefaultStyle.success_500main + || mainWindow.conference ? DefaultStyle.danger_500_main : mainWindow.call.core.dir === LinphoneEnums.CallDir.Outgoing ? DefaultStyle.info_500_main : DefaultStyle.success_500_main onColorizationColorChanged: { callStatusIcon.active = !callStatusIcon.active callStatusIcon.active = !callStatusIcon.active @@ -520,31 +531,36 @@ AbstractWindow { Item { Layout.fillWidth: true } - EffectImage { - Layout.preferredWidth: Math.round(32 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(32 * DefaultStyle.dp) - Layout.rightMargin: Math.round(30 * DefaultStyle.dp) + + // Button open statistics panel + Button{ + id: openStatisticPanelButton property int quality: mainWindow.call ? mainWindow.call.core.quality : 0 - imageSource: quality >= 4 ? AppIcons.cellSignalFull : quality >= 3 ? AppIcons.cellSignalMedium : quality >= 2 ? AppIcons.cellSignalLow : AppIcons.cellSignalNone + icon.width: Math.round(32 * DefaultStyle.dp) + icon.height: Math.round(32 * DefaultStyle.dp) + Layout.preferredWidth: Math.round(40 * DefaultStyle.dp) + Layout.preferredHeight: Math.round(40 * DefaultStyle.dp) + Layout.rightMargin: Math.round(30 * DefaultStyle.dp) + icon.source: quality >= 4 ? AppIcons.cellSignalFull : quality >= 3 ? AppIcons.cellSignalMedium : quality >= 2 ? AppIcons.cellSignalLow : AppIcons.cellSignalNone colorizationColor: DefaultStyle.grey_0 - MouseArea { - anchors.fill: parent - hoverEnabled: true - cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor - onClicked: { - if (rightPanel.visible - && rightPanel.contentLoader.item.objectName - === "statsPanel") - rightPanel.visible = false - else { - rightPanel.visible = true - rightPanel.replace(statsPanel) - } + style: ButtonStyle.noBackgroundLightBorder + Accessible.name: qsTr("open_statistic_panel_accessible_name") + onClicked: { + if (rightPanel.visible + && rightPanel.contentLoader.item.objectName + === "statsPanel") + rightPanel.visible = false + else { + rightPanel.visible = true + rightPanel.replace(statsPanel) } } + KeyNavigation.tab: rightPanel.visible ? nextItemInFocusChain() : mainWindow.firstButtonInBottomTab + KeyNavigation.backtab: mainWindow.lastButtonInBottomTab } } + // Banner middle of header - screen sharing or record screen Control.Control { id: screenSharingOrRecordBanner property var isScreenSharing: mainWindow.conference && mainWindow.conference.core.isLocalScreenSharing @@ -573,14 +589,14 @@ AbstractWindow { : AppIcons.recordFill colorizationColor: screenSharingOrRecordBanner.isScreenSharing ? DefaultStyle.grey_0 - : DefaultStyle.danger_500main + : DefaultStyle.danger_500_main Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) } Text { color: screenSharingOrRecordBanner.isScreenSharing ? DefaultStyle.grey_0 - : DefaultStyle.danger_500main + : DefaultStyle.danger_500_main font: Typography.b1 text: mainWindow.call ? screenSharingOrRecordBanner.isScreenSharing @@ -603,12 +619,18 @@ AbstractWindow { MediumButton { visible: mainWindow.call && mainWindow.call.core.recording || screenSharingOrRecordBanner.isScreenSharing - //: "Stop recording" + text: screenSharingOrRecordBanner.isScreenSharing - ? qsTr("call_stop_recording") //: "Stop sharing" - : qsTr("call_stop_screen_sharing") - style: ButtonStyle.main + ? qsTr("call_stop_screen_sharing") + //: "Stop recording" + : qsTr("call_stop_recording") + Accessible.name: screenSharingOrRecordBanner.isScreenSharing ? + //: "Stop screen sharing" + qsTr("stop_screen_sharing_accessible_name") + //: Stop recording + : qsTr("stop_recording_accessible_name") + style: ButtonStyle.mainLightBorder onPressed: { if (screenSharingOrRecordBanner.isScreenSharing) mainWindow.conference.core.lToggleScreenSharing() else mainWindow.call.core.lStopRecording() @@ -643,6 +665,7 @@ AbstractWindow { } headerStack.currentIndex: 0 headerValidateButtonText: qsTr("add") + KeyNavigation.tab : Utils.isDescendant(nextItemInFocusChain(), rightPanel) ? nextItemInFocusChain() : videoCameraButton // Do not consider padding for chat Binding on topPadding { @@ -711,6 +734,14 @@ AbstractWindow { if (!rightPanel.contentLoader.item || rightPanel.contentLoader.item.objectName !== "screencastPanel") screencastPanelButton.checked = false if (!rightPanel.contentLoader.item || rightPanel.contentLoader.item.objectName !== "chatPanel") chatPanelButton.checked = false if (!rightPanel.contentLoader.item || rightPanel.contentLoader.item.objectName !== "participantListPanel") participantListButton.checked = false + + // Update tab focus properties + var firstContentFocusableItem = Utils.getFirstFocussableItemInItem(rightPanel.contentLoader.item) + rightPanel.firstContentFocusableItem = firstContentFocusableItem ?? mainWindow.firstButtonInBottomTab + var lastContentFocusableItem = Utils.getLastFocussableItemInItem(rightPanel.contentLoader.item) + if(lastContentFocusableItem != undefined){ + lastContentFocusableItem.KeyNavigation.tab = mainWindow.firstButtonInBottomTab + } } } @@ -1209,11 +1240,16 @@ AbstractWindow { } } + + // ----------------------------------------------------------------------------- + // Bottom round buttons + // ----------------------------------------------------------------------------- RowLayout { id: bottomButtonsLayout Layout.alignment: Qt.AlignHCenter spacing: Math.round(58 * DefaultStyle.dp) visible: middleItemStackView.currentItem.objectName == "inCallItem" + property bool moreOptionsButtonVisibility: true function refreshLayout() { if (mainWindow.callState === LinphoneEnums.CallState.Connected @@ -1221,12 +1257,12 @@ AbstractWindow { || mainWindow.callState === LinphoneEnums.CallState.Paused || mainWindow.callState === LinphoneEnums.CallState.PausedByRemote) { connectedCallButtons.visible = bottomButtonsLayout.visible - moreOptionsButton.visible = bottomButtonsLayout.visible + moreOptionsButtonVisibility = bottomButtonsLayout.visible bottomButtonsLayout.layoutDirection = Qt.RightToLeft } else if (mainWindow.callState === LinphoneEnums.CallState.OutgoingInit) { connectedCallButtons.visible = false bottomButtonsLayout.layoutDirection = Qt.LeftToRight - moreOptionsButton.visible = false + moreOptionsButtonVisibility = false } } @@ -1244,35 +1280,40 @@ AbstractWindow { children[i].enabled = false } } + + // End call button BigButton { + id: endCallButton Layout.row: 0 icon.width: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp) //: "Terminer l'appel" ToolTip.text: qsTr("call_action_end_call") + Accessible.name: qsTr("call_action_end_call") Layout.preferredWidth: Math.round(75 * DefaultStyle.dp) Layout.preferredHeight: Math.round(55 * DefaultStyle.dp) radius: Math.round(71 * DefaultStyle.dp) - style: ButtonStyle.phoneRed - Layout.column: mainWindow.callState == LinphoneEnums.CallState.OutgoingInit - || mainWindow.callState - == LinphoneEnums.CallState.OutgoingProgress - || mainWindow.callState - == LinphoneEnums.CallState.OutgoingRinging - || mainWindow.callState - == LinphoneEnums.CallState.OutgoingEarlyMedia - || mainWindow.callState == LinphoneEnums.CallState.IncomingReceived ? 0 : bottomButtonsLayout.columns - 1 + style: ButtonStyle.phoneRedLightBorder + Layout.column: mainWindow.startingCall ? 0 : bottomButtonsLayout.columns - 1 + KeyNavigation.tab: mainWindow.startingCall ? (videoCameraButton.visible && videoCameraButton.enabled ? videoCameraButton : audioMicrophoneButton) : openStatisticPanelButton + KeyNavigation.backtab: mainWindow.startingCall ? rightPanel.visible ? Utils.getLastFocussableItemInItem(rightPanel) : nextItemInFocusChain(false): callListButton onClicked: { mainWindow.callTerminatedByUser = true mainWindow.endCall(mainWindow.call) } } + + // ----------------------------------------------------------------------------- + // Group button: pauseCall, transfertCall, newCall, callList + // ----------------------------------------------------------------------------- RowLayout { id: connectedCallButtons visible: false Layout.row: 0 Layout.column: 1 spacing: Math.round(10 * DefaultStyle.dp) + + // Pause call button CheckableButton { id: pauseButton Layout.preferredWidth: Math.round(55 * DefaultStyle.dp) @@ -1283,11 +1324,7 @@ AbstractWindow { ToolTip.text: checked ? qsTr("call_action_resume_call") //: "Mettre l'appel en pause" : qsTr("call_action_pause_call") - background: Rectangle { - anchors.fill: parent - radius: Math.round(71 * DefaultStyle.dp) - color: parent.enabled ? parent.checked ? DefaultStyle.success_500main : parent.pressed || parent.hovered ? DefaultStyle.main2_400 : DefaultStyle.grey_500 : DefaultStyle.grey_600 - } + Accessible.name: checked ? qsTr("call_action_resume_call") : qsTr("call_action_pause_call") enabled: mainWindow.conference || mainWindow.callState != LinphoneEnums.CallState.PausedByRemote icon.source: enabled @@ -1298,11 +1335,17 @@ AbstractWindow { || (!mainWindow.conference && mainWindow.callState == LinphoneEnums.CallState.PausedByRemote) + color: enabled ? DefaultStyle.grey_500 : DefaultStyle.grey_600 + pressedColor: enabled ? DefaultStyle.success_500_main : DefaultStyle.grey_600 + hoveredColor: enabled ? DefaultStyle.main2_400 : DefaultStyle.grey_600 onClicked: { mainWindow.call.core.lSetPaused( !mainWindow.call.core.paused) } + KeyNavigation.backtab: moreOptionsButton } + + // Transfert call button CheckableButton { id: transferCallButton visible: !mainWindow.conference @@ -1314,6 +1357,7 @@ AbstractWindow { contentImageColor: DefaultStyle.grey_0 //: "Transférer l'appel" ToolTip.text: qsTr("call_action_transfer_call") + Accessible.name: qsTr("call_action_transfer_call") onToggled: { console.log("checked transfer changed", checked) if (checked) { @@ -1324,6 +1368,8 @@ AbstractWindow { } } } + + // New call button CheckableButton { id: newCallButton checkable: true @@ -1334,6 +1380,7 @@ AbstractWindow { icon.height: Math.round(32 * DefaultStyle.dp) //: "Initier un nouvel appel" ToolTip.text: qsTr("call_action_start_new_call_hint") + Accessible.name: qsTr("call_action_start_new_call_hint") onToggled: { console.log("checked newcall changed", checked) if (checked) { @@ -1344,6 +1391,8 @@ AbstractWindow { } } } + + // Call list button CheckableButton { id: callListButton Layout.preferredWidth: Math.round(55 * DefaultStyle.dp) @@ -1354,6 +1403,7 @@ AbstractWindow { icon.height: Math.round(32 * DefaultStyle.dp) //: "Afficher la liste d'appels" ToolTip.text: qsTr("call_display_call_list_hint") + Accessible.name: qsTr("call_display_call_list_hint") onToggled: { if (checked) { rightPanel.visible = true @@ -1362,19 +1412,20 @@ AbstractWindow { rightPanel.visible = false } } + KeyNavigation.tab: mainWindow.startingCall ? nextItemInFocusChain() : endCallButton } } + + // ----------------------------------------------------------------------------- + // Group button: Video, audio, screensharing, chat, raiseHand, reaction, participantList, callOptions + // ----------------------------------------------------------------------------- RowLayout { + id: controlCallButtons Layout.row: 0 - Layout.column: mainWindow.callState == LinphoneEnums.CallState.OutgoingInit - || mainWindow.callState - == LinphoneEnums.CallState.OutgoingProgress - || mainWindow.callState - == LinphoneEnums.CallState.OutgoingRinging - || mainWindow.callState - == LinphoneEnums.CallState.OutgoingEarlyMedia - || mainWindow.callState == LinphoneEnums.CallState.IncomingReceived ? bottomButtonsLayout.columns - 1 : 0 + Layout.column: mainWindow.startingCall ? bottomButtonsLayout.columns - 1 : 0 spacing: Math.round(10 * DefaultStyle.dp) + + // Video camera button CheckableButton { id: videoCameraButton visible: SettingsCpp.videoEnabled @@ -1387,6 +1438,7 @@ AbstractWindow { //: "Désactiver la vidéo" //: "Activer la vidéo" ToolTip.text: mainWindow.localVideoEnabled ? qsTr("call_deactivate_video_hint") : qsTr("call_activate_video_hint") + Accessible.name: mainWindow.localVideoEnabled ? qsTr("call_deactivate_video_hint") : qsTr("call_activate_video_hint") checked: !mainWindow.localVideoEnabled Layout.preferredWidth: Math.round(55 * DefaultStyle.dp) Layout.preferredHeight: Math.round(55 * DefaultStyle.dp) @@ -1395,29 +1447,36 @@ AbstractWindow { onClicked: mainWindow.call.core.lSetLocalVideoEnabled( !mainWindow.call.core.localVideoEnabled) } + + // Audio microphone button CheckableButton { + id: audioMicrophoneButton iconUrl: AppIcons.microphone + checkedIconUrl: AppIcons.microphoneSlash ToolTip.text: mainWindow.call && mainWindow.call.core.microphoneMuted //: "Activer le micro" ? qsTr("call_activate_microphone") //: "Désactiver le micro" : qsTr("call_deactivate_microphone") - checkedIconUrl: AppIcons.microphoneSlash - checked: mainWindow.call - && mainWindow.call.core.microphoneMuted + Accessible.name: mainWindow.call && mainWindow.call.core.microphoneMuted ? qsTr("call_activate_microphone") : qsTr("call_deactivate_microphone") + checked: mainWindow.call && mainWindow.call.core.microphoneMuted Layout.preferredWidth: Math.round(55 * DefaultStyle.dp) Layout.preferredHeight: Math.round(55 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp) onClicked: mainWindow.call.core.lSetMicrophoneMuted( !mainWindow.call.core.microphoneMuted) + KeyNavigation.backtab: videoCameraButton.visible && videoCameraButton.enabled ? videoCameraButton : nextItemInFocusChain(false) } + + // Screen cast button CheckableButton { id: screencastPanelButton iconUrl: AppIcons.screencast visible: !!mainWindow.conference //: Partager l'écran… ToolTip.text: qsTr("call_share_screen_hint") + Accessible.name: qsTr("call_share_screen_hint") Layout.preferredWidth: Math.round(55 * DefaultStyle.dp) Layout.preferredHeight: Math.round(55 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp) @@ -1431,11 +1490,14 @@ AbstractWindow { } } } + + // Chat panel button CheckableButton { id: chatPanelButton iconUrl: AppIcons.chatTeardropText //: Open chat… ToolTip.text: qsTr("call_open_chat_hint") + Accessible.name: qsTr("call_open_chat_hint") Layout.preferredWidth: Math.round(55 * DefaultStyle.dp) Layout.preferredHeight: Math.round(55 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp) @@ -1449,31 +1511,42 @@ AbstractWindow { } } } + + // Raise hand button CheckableButton { + id: raiseHandButton visible: false checkable: false iconUrl: AppIcons.handWaving //: "Lever la main" ToolTip.text: qsTr("call_rise_hand_hint") + Accessible.name: qsTr("call_rise_hand_hint") Layout.preferredWidth: Math.round(55 * DefaultStyle.dp) Layout.preferredHeight: Math.round(55 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp) } + + // Reaction button CheckableButton { + id: reactionButton visible: false iconUrl: AppIcons.smiley //: "Envoyer une réaction" ToolTip.text: qsTr("call_send_reaction_hint") + Accessible.name: qsTr("call_send_reaction_hint") Layout.preferredWidth: Math.round(55 * DefaultStyle.dp) Layout.preferredHeight: Math.round(55 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp) } + + // Participant list button CheckableButton { id: participantListButton //: "Gérer les participants" ToolTip.text: qsTr("call_manage_participants_hint") + Accessible.name: qsTr("call_manage_participants_hint") visible: mainWindow.conference iconUrl: AppIcons.usersTwo Layout.preferredWidth: Math.round(55 * DefaultStyle.dp) @@ -1489,12 +1562,15 @@ AbstractWindow { } } } + + // More option button PopupButton { id: moreOptionsButton //: "Plus d'options…" ToolTip.text: qsTr("call_more_options_hint") - Layout.preferredWidth: Math.round(55 * DefaultStyle.dp) - Layout.preferredHeight: Math.round(55 * DefaultStyle.dp) + popUpTitle: qsTr("call_more_options_hint") + implicitWidth: Math.round(55 * DefaultStyle.dp) + implicitHeight: Math.round(55 * DefaultStyle.dp) popup.topPadding: Math.round(20 * DefaultStyle.dp) popup.bottomPadding: Math.round(20 * DefaultStyle.dp) popup.leftPadding: Math.round(10 * DefaultStyle.dp) @@ -1502,6 +1578,8 @@ AbstractWindow { style: ButtonStyle.checkable icon.width: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp) + KeyNavigation.tab: connectedCallButtons.visible ? pauseButton : nextItemInFocusChain() + visible: bottomButtonsLayout.moreOptionsButtonVisibility Connections { target: moreOptionsButton.popup @@ -1528,6 +1606,8 @@ AbstractWindow { rightPanel.replace(changeLayoutPanel) moreOptionsButton.close() } + KeyNavigation.up: visibleChildren.length != 0 ? moreOptionsButton.getPreviousItem(0) : null + KeyNavigation.down: visibleChildren.length != 0 ? moreOptionsButton.getNextItem(0) : null } IconLabelButton { Layout.fillWidth: true @@ -1549,6 +1629,8 @@ AbstractWindow { } moreOptionsButton.close() } + KeyNavigation.up: visibleChildren.length != 0 ? moreOptionsButton.getPreviousItem(1) : null + KeyNavigation.down: visibleChildren.length != 0 ? moreOptionsButton.getNextItem(1) : null } IconLabelButton { Layout.fillWidth: true @@ -1562,6 +1644,8 @@ AbstractWindow { rightPanel.replace(dialerPanel) moreOptionsButton.close() } + KeyNavigation.up: visibleChildren.length != 0 ? moreOptionsButton.getPreviousItem(2) : null + KeyNavigation.down: visibleChildren.length != 0 ? moreOptionsButton.getNextItem(2) : null } IconLabelButton { Layout.fillWidth: true @@ -1579,14 +1663,14 @@ AbstractWindow { && mainWindow.call.core.recording hoveredImageColor: contentImageColor contentImageColor: mainWindow.call - && mainWindow.call.core.recording ? DefaultStyle.danger_500main : DefaultStyle.main2_500main + && mainWindow.call.core.recording ? DefaultStyle.danger_500_main : DefaultStyle.main2_500_main text: mainWindow.call && mainWindow.call.core.recording //: "Terminer l'enregistrement" ? qsTr("call_action_stop_recording") //: "Enregistrer l'appel" : qsTr("call_action_record") textColor: mainWindow.call - && mainWindow.call.core.recording ? DefaultStyle.danger_500main : DefaultStyle.main2_500main + && mainWindow.call.core.recording ? DefaultStyle.danger_500_main : DefaultStyle.main2_500_main hoveredTextColor: textColor onToggled: { if (mainWindow.call) @@ -1596,6 +1680,8 @@ AbstractWindow { else mainWindow.call.core.lStartRecording() } + KeyNavigation.up: visibleChildren.length != 0 ? moreOptionsButton.getPreviousItem(3) : null + KeyNavigation.down: visibleChildren.length != 0 ? moreOptionsButton.getNextItem(3) : null } IconLabelButton { Layout.fillWidth: true @@ -1606,7 +1692,7 @@ AbstractWindow { icon.source: !mainWindow.call || mainWindow.call.core.speakerMuted ? AppIcons.speakerSlash : AppIcons.speaker contentImageColor: mainWindow.call - && mainWindow.call.core.speakerMuted ? DefaultStyle.danger_500main : DefaultStyle.main2_500main + && mainWindow.call.core.speakerMuted ? DefaultStyle.danger_500_main : DefaultStyle.main2_500_main hoveredImageColor: contentImageColor text: mainWindow.call && mainWindow.call.core.speakerMuted //: "Activer le son" @@ -1614,13 +1700,15 @@ AbstractWindow { //: "Désactiver le son" : qsTr("call_deactivate_speaker_hint") textColor: mainWindow.call - && mainWindow.call.core.speakerMuted ? DefaultStyle.danger_500main : DefaultStyle.main2_500main + && mainWindow.call.core.speakerMuted ? DefaultStyle.danger_500_main : DefaultStyle.main2_500_main hoveredTextColor: textColor onCheckedChanged: { if (mainWindow.call) mainWindow.call.core.lSetSpeakerMuted( !mainWindow.call.core.speakerMuted) } + KeyNavigation.up: visibleChildren.length != 0 ? moreOptionsButton.getPreviousItem(4) : null + KeyNavigation.down: visibleChildren.length != 0 ? moreOptionsButton.getNextItem(4) : null } IconLabelButton { Layout.fillWidth: true @@ -1635,6 +1723,8 @@ AbstractWindow { rightPanel.replace(settingsPanel) moreOptionsButton.close() } + KeyNavigation.up: visibleChildren.length != 0 ? moreOptionsButton.getPreviousItem(5) : null + KeyNavigation.down: visibleChildren.length != 0 ? moreOptionsButton.getNextItem(5) : null } } } diff --git a/Linphone/view/Page/Window/Main/MainWindow.qml b/Linphone/view/Page/Window/Main/MainWindow.qml index 5f55a64ee..e0e592687 100644 --- a/Linphone/view/Page/Window/Main/MainWindow.qml +++ b/Linphone/view/Page/Window/Main/MainWindow.qml @@ -116,6 +116,7 @@ AbstractWindow { console.log("Showing authentication dialog") var popup = authenticationPopupComp.createObject(mainWindow, {"identity": identity, "domain": domain, "callback":callback}) // Callback ownership is not passed popup.open() + popup.announce() } Connections { diff --git a/Linphone/view/Style/DefaultStyle.qml b/Linphone/view/Style/DefaultStyle.qml index dffa2ab87..2eb9a8cf6 100644 --- a/Linphone/view/Style/DefaultStyle.qml +++ b/Linphone/view/Style/DefaultStyle.qml @@ -15,12 +15,12 @@ QtObject { property color main1_600: currentTheme.main600 property color main1_700: currentTheme.main700 - property color main2_0: "#FAFEFF" + property color main2_000: "#FAFEFF" property color main2_100: "#EEF6F8" property color main2_200: "#DFECF2" property color main2_300: "#C0D1D9" property color main2_400: "#9AABB5" - property color main2_500main: "#6C7A87" + property color main2_500_main: "#6C7A87" property color main2_600: "#4E6074" property color main2_700: "#364860" property color main2_800: "#22334D" @@ -38,11 +38,11 @@ QtObject { property color grey_1000: "#000000" property color warning_600: "#DBB820" - property color danger_500main: "#DD5F5F" + property color danger_500_main: "#DD5F5F" property color warning_500_main: "#FFDC2E" property color danger_700: "#9E3548" property color danger_900: "#723333" - property color success_500main: "#4FAE80" + property color success_500_main: "#4FAE80" property color success_700: "#377d71" property color success_900: "#1E4C53" property color info_500_main: "#4AA8FF" diff --git a/Linphone/view/Style/buttonStyle.js b/Linphone/view/Style/buttonStyle.js index bc9810e23..3d0df5d08 100644 --- a/Linphone/view/Style/buttonStyle.js +++ b/Linphone/view/Style/buttonStyle.js @@ -19,6 +19,11 @@ pressed: Linphone.DefaultStyle.grey_0 } } + var mainLightBorder = Object.assign({ + borderColor : { + keybaordFocused: Linphone.DefaultStyle.main2_000 + } + }, main) // White with orange border var secondary = { @@ -27,7 +32,10 @@ hovered: Linphone.DefaultStyle.main1_100, pressed: Linphone.DefaultStyle.main1_500_main }, - borderColor: Linphone.DefaultStyle.main1_500_main, + borderColor: { + normal: Linphone.DefaultStyle.main1_500_main, + keybaordFocused: Linphone.DefaultStyle.main2_900 + }, text: { normal: Linphone.DefaultStyle.main1_500_main, pressed: Linphone.DefaultStyle.grey_0 @@ -80,11 +88,11 @@ pressed: Linphone.DefaultStyle.main2_400 }, text: { - normal: Linphone.DefaultStyle.main2_500main, + normal: Linphone.DefaultStyle.main2_500_main, pressed: Linphone.DefaultStyle.main2_700 }, image: { - normal: Linphone.DefaultStyle.main2_500main, + normal: Linphone.DefaultStyle.main2_500_main, pressed: Linphone.DefaultStyle.main2_700 } } @@ -93,7 +101,7 @@ var phoneRed = { iconSource: Linphone.AppIcons.endCall, color: { - normal: Linphone.DefaultStyle.danger_500main, + normal: Linphone.DefaultStyle.danger_500_main, hovered: Linphone.DefaultStyle.danger_700, pressed: Linphone.DefaultStyle.danger_900 }, @@ -106,12 +114,17 @@ pressed: Linphone.DefaultStyle.grey_0 } } + var phoneRedLightBorder = Object.assign({ + borderColor : { + keybaordFocused: Linphone.DefaultStyle.main2_000 + } + }, phoneRed) // Green phone var phoneGreen = { iconSource: Linphone.AppIcons.phone, color: { - normal: Linphone.DefaultStyle.success_500main, + normal: Linphone.DefaultStyle.success_500_main, hovered: Linphone.DefaultStyle.success_700, pressed: Linphone.DefaultStyle.success_900 }, @@ -137,6 +150,9 @@ normal: Linphone.DefaultStyle.grey_0, pressed: Linphone.DefaultStyle.grey_0 }, + borderColor: { + keybaordFocused: Linphone.DefaultStyle.main2_000 + }, image: { normal: Linphone.DefaultStyle.grey_0, pressed: Linphone.DefaultStyle.grey_0, @@ -156,13 +172,13 @@ normal: Linphone.DefaultStyle.main2_200, hovered: Linphone.DefaultStyle.main2_300, pressed: Linphone.DefaultStyle.main2_400, - checked: Linphone.DefaultStyle.main1_500main + checked: Linphone.DefaultStyle.main1_500_main }, image: { normal: Linphone.DefaultStyle.main2_200, hovered: Linphone.DefaultStyle.main2_300, pressed: Linphone.DefaultStyle.main2_400, - checked: Linphone.DefaultStyle.main1_500main, + checked: Linphone.DefaultStyle.main1_500_main, } } @@ -178,15 +194,20 @@ normal: Linphone.DefaultStyle.main2_600, hovered: Linphone.DefaultStyle.main2_700, pressed: Linphone.DefaultStyle.main2_800, - checked: Linphone.DefaultStyle.main1_500main + checked: Linphone.DefaultStyle.main1_500_main }, image: { normal: Linphone.DefaultStyle.main2_600, hovered: Linphone.DefaultStyle.main2_700, pressed: Linphone.DefaultStyle.main2_800, - checked: Linphone.DefaultStyle.main1_500main, + checked: Linphone.DefaultStyle.main1_500_main, } } + var noBackgroundLightBorder = Object.assign({ + borderColor : { + keybaordFocused: Linphone.DefaultStyle.main2_000 + } + }, noBackground) // No background red var noBackgroundRed = { @@ -196,12 +217,12 @@ pressed: "#00000000" }, text: { - normal: Linphone.DefaultStyle.danger_500main, + normal: Linphone.DefaultStyle.danger_500_main, hovered: Linphone.DefaultStyle.danger_700, pressed: Linphone.DefaultStyle.danger_900 }, image: { - normal: Linphone.DefaultStyle.danger_500main, + normal: Linphone.DefaultStyle.danger_500_main, hovered: Linphone.DefaultStyle.danger_700, pressed: Linphone.DefaultStyle.danger_900, checked: Linphone.DefaultStyle.danger_900 @@ -254,14 +275,14 @@ pressed: Linphone.DefaultStyle.main2_100 }, text: { - normal: Linphone.DefaultStyle.main2_500main, - hovered: Linphone.DefaultStyle.main2_500main, - pressed: Linphone.DefaultStyle.main2_500main + normal: Linphone.DefaultStyle.main2_500_main, + hovered: Linphone.DefaultStyle.main2_500_main, + pressed: Linphone.DefaultStyle.main2_500_main }, image: { - normal: Linphone.DefaultStyle.main2_500main, - hovered: Linphone.DefaultStyle.main2_500main, - pressed: Linphone.DefaultStyle.main2_500main + normal: Linphone.DefaultStyle.main2_500_main, + hovered: Linphone.DefaultStyle.main2_500_main, + pressed: Linphone.DefaultStyle.main2_500_main } } @@ -273,12 +294,12 @@ pressed: Linphone.DefaultStyle.main2_100 }, text: { - normal: Linphone.DefaultStyle.danger_500main, + normal: Linphone.DefaultStyle.danger_500_main, hovered: Linphone.DefaultStyle.danger_700, pressed: Linphone.DefaultStyle.danger_900 }, image: { - normal: Linphone.DefaultStyle.danger_500main, + normal: Linphone.DefaultStyle.danger_500_main, hovered: Linphone.DefaultStyle.danger_700, pressed: Linphone.DefaultStyle.danger_900 } @@ -304,9 +325,12 @@ hovered: Linphone.DefaultStyle.grey_0, pressed: Linphone.DefaultStyle.grey_0 }, - borderColor: Linphone.DefaultStyle.success_500main, + borderColor: { + normal: Linphone.DefaultStyle.success_500_main, + keybaordFocused: Linphone.DefaultStyle.main2_900 + }, text: { - normal: Linphone.DefaultStyle.success_500main, + normal: Linphone.DefaultStyle.success_500_main, pressed: Linphone.DefaultStyle.success_700 } } @@ -318,7 +342,10 @@ hovered: Linphone.DefaultStyle.grey_0, pressed: Linphone.DefaultStyle.grey_0 }, - borderColor: Linphone.DefaultStyle.info_500_main, + borderColor: { + normal: Linphone.DefaultStyle.info_500_main, + keybaordFocused: Linphone.DefaultStyle.main2_900 + }, text: { normal: Linphone.DefaultStyle.info_500_main, pressed: Linphone.DefaultStyle.info_500_main @@ -332,9 +359,32 @@ hovered: Linphone.DefaultStyle.grey_0, pressed: Linphone.DefaultStyle.grey_0 }, - borderColor: Linphone.DefaultStyle.danger_500main, + borderColor: { + normal: Linphone.DefaultStyle.danger_500_main, + keybaordFocused: Linphone.DefaultStyle.main2_900 + }, text: { - normal: Linphone.DefaultStyle.danger_500main, - pressed: Linphone.DefaultStyle.danger_500main + normal: Linphone.DefaultStyle.danger_500_main, + pressed: Linphone.DefaultStyle.danger_500_main } } + +// White selected + var whiteSelected = { + color: { + normal: Linphone.DefaultStyle.grey_0, + hovered: Linphone.DefaultStyle.main2_100, + selected: Linphone.DefaultStyle.grey_200, + }, + borderColor: { + keybaordFocused: Linphone.DefaultStyle.main2_900 + } + } + + var hoveredBackgroundBis = { + color: { + normal: "#00000000", + hovered: Linphone.DefaultStyle.main2_100, + pressed: Linphone.DefaultStyle.main2_100 + } + } \ No newline at end of file diff --git a/README.md b/README.md index 7387c567e..cc00b02ea 100644 --- a/README.md +++ b/README.md @@ -327,6 +327,30 @@ Please note that we don't offer free support and these contributions will be add - external : external projects. - linphone-sdk +#### Add new text/label + +For each text/label that you want to put in the application, you need to follow thoses steps: + +1. In you code, add the label like this : +```qml +//: "Trad in english" +qsTr("variable_name") +``` + +2. Build the application with the target `update_translations` + +3. In the translation files on `Linphone/data/languages/*.ts`, modify all translations that you can. They have been generated with `` +```xml + + + variable_name + "Trad in english" + My Translation + +``` + +4. Build again the application with the target `release_translations` + ### Languages