diff --git a/Linphone/CMakeLists.txt b/Linphone/CMakeLists.txt index ad7a358c0..e01ac7cfc 100644 --- a/Linphone/CMakeLists.txt +++ b/Linphone/CMakeLists.txt @@ -28,6 +28,7 @@ if (UNIX AND NOT APPLE) endif() find_package(Qt6 REQUIRED COMPONENTS Core) find_package(Qt6 REQUIRED COMPONENTS ${QT_PACKAGES}) +find_package(Qt6 REQUIRED COMPONENTS LinguistTools) if(NOT WIN32) find_package(X11) @@ -124,6 +125,25 @@ add_subdirectory(model) add_subdirectory(view) add_subdirectory(core) +set(LANGUAGES_DIRECTORY "data/languages") +set(I18N_FILENAME i18n.qrc) +set(LANGUAGES en fr_FR) + +# Add languages support. +add_subdirectory("${LANGUAGES_DIRECTORY}" "data/languages") + +set(LANGUAGES en fr_FR) +qt_standard_project_setup(I18N_TRANSLATED_LANGUAGES ${LANGUAGES}) + +set(TS_FILES) +foreach (lang ${LANGUAGES}) + list(APPEND TS_FILES "${CMAKE_CURRENT_SOURCE_DIR}/${LANGUAGES_DIRECTORY}/${lang}.ts") +endforeach() + +qt_add_translations(${TARGET_NAME} +TS_FILES ${TS_FILES} +RESOURCE_PREFIX ${LANGUAGES_DIRECTORY}) + # set application details if(WIN32) configure_file("${CMAKE_SOURCE_DIR}/cmake/install/windows/appDetailsWindows.rc.in" "${CMAKE_CURRENT_BINARY_DIR}/appDetailsWindows.rc") @@ -135,7 +155,7 @@ endif() set(_LINPHONEAPP_FONTS_FILES) qt6_add_big_resources(_LINPHONEAPP_FONTS_FILES data/fonts.qrc) - # Have big_resource.qrc treated as a source file by Qt Creator +# Have big_resource.qrc treated as a source file by Qt Creator list(APPEND _LINPHONEAPP_FONTS_FILES data/fonts.qrc) set_property(SOURCE data/fonts.qrc PROPERTY SKIP_AUTORCC ON) diff --git a/Linphone/core/App.cpp b/Linphone/core/App.cpp index 01f2c383e..8d833f5b1 100644 --- a/Linphone/core/App.cpp +++ b/Linphone/core/App.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -76,6 +77,7 @@ #include "core/setting/SettingsCore.hpp" #include "core/singleapplication/singleapplication.h" #include "core/timezone/TimeZoneProxy.hpp" +#include "core/translator/DefaultTranslatorCore.hpp" #include "core/variant/VariantList.hpp" #include "core/videoSource/VideoSourceDescriptorGui.hpp" #include "model/object/VariantObject.hpp" @@ -257,7 +259,7 @@ void App::setAutoStart(bool enabled) { // ----------------------------------------------------------------------------- App::App(int &argc, char *argv[]) - : SingleApplication(argc, argv, true, Mode::User | Mode::ExcludeAppPath | Mode::ExcludeAppVersion) { +: SingleApplication(argc, argv, true, Mode::User | Mode::ExcludeAppPath | Mode::ExcludeAppVersion) { // Do not use APPLICATION_NAME here. // The EXECUTABLE_NAME will be used in qt standard paths. It's our goal. QThread::currentThread()->setPriority(QThread::HighPriority); @@ -319,8 +321,8 @@ void App::setSelf(QSharedPointer(me)) { mCoreModelConnection->makeConnectToModel(&CoreModel::requestFetchConfig, [this](QString path) { mCoreModelConnection->invokeToCore([this, path]() { auto callback = [this, path]() { - RequestDialog *obj = new RequestDialog( - tr("Voulez-vous télécharger et appliquer la configuration depuis cette adresse ?"), path); + //: Voulez-vous télécharger et appliquer la configuration depuis cette adresse ? + RequestDialog *obj = new RequestDialog(tr("remote_provisioning_dialog"), path); connect(obj, &RequestDialog::result, this, [this, obj, path](int result) { if (result == 1) { mCoreModelConnection->invokeToModel( @@ -486,10 +488,10 @@ void App::initCore() { mEngine->setObjectOwnership(settings.get(), QQmlEngine::CppOwnership); mEngine->setObjectOwnership(this, QQmlEngine::CppOwnership); if (!mAccountList) setAccountList(AccountList::create()); - else { - mAccountList->setInitialized(false); - mAccountList->lUpdate(true); - } + else { + mAccountList->setInitialized(false); + mAccountList->lUpdate(true); + } if (!mCallList) setCallList(CallList::create()); else mCallList->lUpdate(); if (!mSettings) { @@ -515,7 +517,11 @@ void App::initCore() { setLocale(settings->getConfigLocale()); setAutoStart(settings->getAutoStart()); setQuitOnLastWindowClosed(settings->getExitOnClose()); - } + } + // Init locale. + mTranslatorCore = new DefaultTranslatorCore(this); + mDefaultTranslatorCore = new DefaultTranslatorCore(this); + initLocale(); const QUrl url("qrc:/qt/qml/Linphone/view/Page/Window/Main/MainWindow.qml"); QObject::connect( mEngine, &QQmlApplicationEngine::objectCreated, this, @@ -549,6 +555,52 @@ void App::initCore() { Qt::BlockingQueuedConnection); } +static inline bool installLocale(App &app, QTranslator &translator, const QLocale &locale) { + auto appPath = QStandardPaths::ApplicationsLocation; + bool ok = translator.load(locale.name(), Constants::LanguagePath); + ok = ok && app.installTranslator(&translator); + if (ok) QLocale::setDefault(locale); + return ok; +} + +void App::initLocale() { + + // Try to use preferred locale. + QString locale; + + // Use english. This default translator is used if there are no found translations in others loads + mLocale = QLocale(QLocale::French); + if (!installLocale(*this, *mDefaultTranslatorCore, mLocale)) qFatal("Unable to install default translator."); + + + if (installLocale(*this, *mTranslatorCore, getLocale())) { + qDebug() << "installed locale" << getLocale().name(); + return; + } + + // Try to use system locale. + // #ifdef Q_OS_MACOS + // Use this workaround if there is still an issue about detecting wrong language from system on Mac. Qt doesn't use + // the current system language on QLocale::system(). So we need to get it from user settings and overwrite its + // Locale. + // QSettings settings; + // QString preferredLanguage = settings.value("AppleLanguages").toStringList().first(); + // QStringList qtLocale = QLocale::system().name().split('_'); + // if(qtLocale[0] != preferredLanguage){ + // qInfo() << "Override Qt language from " << qtLocale[0] << " to the preferred language : " << + // preferredLanguage; qtLocale[0] = preferredLanguage; + // } + // QLocale sysLocale = QLocale(qtLocale.join('_')); + // #else + QLocale sysLocale(QLocale::system().name()); // Use Locale from name because Qt has a bug where it didn't use the + // QLocale::language (aka : translator.language != locale.language) on + // Mac. #endif + if (installLocale(*this, *mTranslatorCore, sysLocale)) { + qDebug() << "installed sys locale" << sysLocale.name(); + setLocale(sysLocale.name()); + } +} + void App::initCppInterfaces() { qmlRegisterSingletonType(Constants::MainQmlUri, 1, 0, "AppCpp", [](QQmlEngine *engine, QJSEngine *) -> QObject * { return App::getInstance(); }); @@ -720,24 +772,35 @@ void App::createCommandParser() { if (!mParser) delete mParser; mParser = new QCommandLineParser(); - mParser->setApplicationDescription(tr("A free (libre) SIP video-phone.")); - mParser->addPositionalArgument( - "command", tr("Send an order to the application towards a command line").replace("%1", APPLICATION_NAME), - "[command]"); + //: "A free and open source SIP video-phone." + mParser->setApplicationDescription(tr("application_description")); + //: "Send an order to the application towards a command line" + mParser->addPositionalArgument("command", tr("command_line_arg_order").replace("%1", APPLICATION_NAME), "[command]"); mParser->addOptions({ - {{"h", "help"}, tr("Show this help")}, + //: "Show this help" + {{"h", "help"}, tr("command_line_option_show_help")}, + //{"cli-help", tr("commandLineOptionCliHelp").replace("%1", APPLICATION_NAME)}, - {{"v", "version"}, tr("Show app version")}, - //{"config", tr("commandLineOptionConfig").replace("%1", EXECUTABLE_NAME), tr("commandLineOptionConfigArg")}, + + //:"Show app version" + {{"v", "version"}, tr("command_line_option_show_app_version")}, + + //{"config", tr("command_line_option_config").replace("%1", EXECUTABLE_NAME), tr("command_line_option_config_arg")}, + {"fetch-config", - tr("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." + tr("command_line_option_config_to_fetch") .replace("%1", EXECUTABLE_NAME), - tr("URL, path or file")}, - //{{"c", "call"}, tr("commandLineOptionCall").replace("%1", EXECUTABLE_NAME), tr("commandLineOptionCallArg")}, - {"minimized", tr("commandLineOptionMinimized")}, - {{"V", "verbose"}, tr("Log to stdout some debug information while running")}, - {"qt-logs-only", tr("Print only logs from the application")}, + //: "URL, path or file" + tr("command_line_option_config_to_fetch_arg")}, + + //{{"c", "call"}, tr("command_line_option_call").replace("%1", EXECUTABLE_NAME), tr("command_line_option_call_arg")}, {"minimized", tr("command_line_option_minimized")}, + + //: "Log to stdout some debug information while running" + {{"V", "verbose"}, tr("command_line_option_log_to_stdout")}, + + //: "Print only logs from the application" + {"qt-logs-only", tr("command_line_option_print_app_logs_only")}, }); } // Should be call only at first start @@ -1003,7 +1066,7 @@ void App::exportDesktopFile() { } bool App::generateDesktopFile(const QString &confPath, bool remove, bool openInBackground) { - qInfo() << QStringLiteral("Updating `%1`...").arg(confPath); + qInfo() << QStringLiteral("Updating `%1`…").arg(confPath); QFile file(confPath); if (remove) { @@ -1095,7 +1158,9 @@ void App::setSysTrayIcon() { if (mSettings && !mSettings->getExitOnClose()) { restoreAction = new QAction(root); auto setRestoreActionText = [restoreAction](bool visible) { - restoreAction->setText(visible ? tr("Cacher") : tr("Afficher")); + //: "Cacher" + //: "Afficher" + restoreAction->setText(visible ? tr("hide_action") : tr("show_action")); }; setRestoreActionText(root->isVisible()); connect(root, &QWindow::visibleChanged, restoreAction, setRestoreActionText); @@ -1109,8 +1174,8 @@ void App::setSysTrayIcon() { } }); } - - QAction *quitAction = new QAction(tr("Quitter"), root); + //: "Quitter" + QAction *quitAction = new QAction(tr("quit_action"), root); root->connect(quitAction, &QAction::triggered, this, &App::quit); // trayIcon: Left click actions. @@ -1146,7 +1211,8 @@ void App::setSysTrayIcon() { //----------------------------------------------------------- void App::setLocale(QString configLocale) { - mLocale = QLocale(QLocale::French); + if (configLocale.isEmpty()) mLocale = QLocale(configLocale); + else mLocale = QLocale(QLocale::system().name()); } QLocale App::getLocale() { @@ -1157,11 +1223,12 @@ QLocale App::getLocale() { // Version infos. //----------------------------------------------------------- +//: "Inconnue" QString App::getShortApplicationVersion() { #ifdef LINPHONEAPP_SHORT_VERSION return QStringLiteral(LINPHONEAPP_SHORT_VERSION); #else - return tr("inconnue"); + return tr('unknown'); #endif } @@ -1169,7 +1236,7 @@ QString App::getGitBranchName() { #ifdef GIT_BRANCH_NAME return QStringLiteral(GIT_BRANCH_NAME); #else - return tr("inconnue"); + return tr('unknown'); #endif } @@ -1177,6 +1244,6 @@ QString App::getSdkVersion() { #ifdef LINPHONESDK_VERSION return QStringLiteral(LINPHONESDK_VERSION); #else - return tr("inconnue"); + return tr('unknown'); #endif } diff --git a/Linphone/core/App.hpp b/Linphone/core/App.hpp index 4375f28bd..2655b220a 100644 --- a/Linphone/core/App.hpp +++ b/Linphone/core/App.hpp @@ -35,6 +35,7 @@ class Thread; class Notifier; class QQuickWindow; class QSystemTrayIcon; +class DefaultTranslatorCore; class App : public SingleApplication, public AbstractObject { Q_OBJECT @@ -112,6 +113,7 @@ public: void clean(); void init(); void initCore(); + void initLocale(); void initCppInterfaces(); void initFonts(); void restart(); @@ -194,6 +196,8 @@ private: bool mAutoStart = false; bool mCoreStarted = false; QLocale mLocale = QLocale::system(); + DefaultTranslatorCore *mTranslatorCore = nullptr; + DefaultTranslatorCore *mDefaultTranslatorCore = nullptr; QTimer mDateUpdateTimer; QDate mCurrentDate; diff --git a/Linphone/core/CMakeLists.txt b/Linphone/core/CMakeLists.txt index 8614b3b84..c40492f8c 100644 --- a/Linphone/core/CMakeLists.txt +++ b/Linphone/core/CMakeLists.txt @@ -54,6 +54,8 @@ list(APPEND _LINPHONEAPP_SOURCES core/timezone/TimeZoneProxy.cpp core/timezone/TimeZone.cpp + core/translator/DefaultTranslatorCore.cpp + core/participant/ParticipantCore.cpp core/participant/ParticipantGui.cpp core/participant/ParticipantDeviceCore.cpp diff --git a/Linphone/core/account/AccountCore.cpp b/Linphone/core/account/AccountCore.cpp index 45bb4dc4f..0aac0d32f 100644 --- a/Linphone/core/account/AccountCore.cpp +++ b/Linphone/core/account/AccountCore.cpp @@ -403,16 +403,21 @@ int AccountCore::getDialPlanIndex(QVariantMap dialPlanString) { QString AccountCore::getHumanReadableRegistrationState() const { switch (mRegistrationState) { case LinphoneEnums::RegistrationState::Ok: - return tr("Connecté"); + //: "Connecté" + return tr("drawer_menu_account_connection_status_connected"); case LinphoneEnums::RegistrationState::Refreshing: - return tr("En cours de rafraîchissement…"); + // "En cours de rafraîchissement…" + return tr("drawer_menu_account_connection_status_refreshing"); case LinphoneEnums::RegistrationState::Progress: - return tr("En cours de connexion…"); + // "Connexion…" + return tr("drawer_menu_account_connection_status_progress"); case LinphoneEnums::RegistrationState::Failed: - return tr("Erreur"); + // "Erreur" + return tr("drawer_menu_account_connection_status_failed"); case LinphoneEnums::RegistrationState::None: case LinphoneEnums::RegistrationState::Cleared: - return tr("Désactivé"); + // "Désactivé" + return tr("drawer_menu_account_connection_status_cleared"); default: return " "; } @@ -421,12 +426,15 @@ QString AccountCore::getHumanReadableRegistrationState() const { QString AccountCore::getHumanReadableRegistrationStateExplained() const { switch (mRegistrationState) { case LinphoneEnums::RegistrationState::Ok: - return tr("Vous êtes en ligne et joignable."); + //: "Vous êtes en ligne et joignable." + return tr("manage_account_status_connected_summary"); case LinphoneEnums::RegistrationState::Failed: - return tr("Erreur de connexion, vérifiez vos paramètres."); + //: "Erreur de connexion, vérifiez vos paramètres." + return tr("manage_account_status_failed_summary"); case LinphoneEnums::RegistrationState::None: case LinphoneEnums::RegistrationState::Cleared: - return tr("Compte désactivé, vous ne recevrez ni appel ni message."); + //: "Compte désactivé, vous ne recevrez ni appel ni message." + return tr("manage_account_status_cleared_summary"); default: return " "; } diff --git a/Linphone/core/account/AccountDeviceList.cpp b/Linphone/core/account/AccountDeviceList.cpp index 2d35a8ec0..a576e31a1 100644 --- a/Linphone/core/account/AccountDeviceList.cpp +++ b/Linphone/core/account/AccountDeviceList.cpp @@ -154,7 +154,8 @@ void AccountDeviceList::setSelf(QSharedPointer me) { lDebug() << "REQUEST ERROR" << errorMessage << "/" << int(request->getType()); QString message = QString::fromStdString(errorMessage); if (request->getType() == linphone::AccountManagerServicesRequest::Type::GetDevicesList) { - message = tr("Erreur lors de la récupération des appareils"); + //: "Erreur lors de la récupération des appareils" + message = tr("manage_account_no_device_found_error_message"); } emit requestError(message); }); diff --git a/Linphone/core/call-history/CallHistoryList.cpp b/Linphone/core/call-history/CallHistoryList.cpp index e3fe4a3d2..686e2c034 100644 --- a/Linphone/core/call-history/CallHistoryList.cpp +++ b/Linphone/core/call-history/CallHistoryList.cpp @@ -92,7 +92,7 @@ void CallHistoryList::setSelf(QSharedPointer me) { toConnect(callLogs->get()); if (oldLog == mList.end()) { // New prepend(*callLogs); - } else { // Update (status, duration, etc ...) + } else { // Update (status, duration, etc …) replace(oldLog->objectCast(), *callLogs); } delete[] callLogs; diff --git a/Linphone/core/call/CallCore.cpp b/Linphone/core/call/CallCore.cpp index f70dd3417..9e97b0cf3 100644 --- a/Linphone/core/call/CallCore.cpp +++ b/Linphone/core/call/CallCore.cpp @@ -207,9 +207,10 @@ void CallCore::setSelf(QSharedPointer me) { mCallModelConnection->invokeToCore([this, recording]() { setRecording(recording); if (recording == false) { - Utils::showInformationPopup(tr("Enregistrement terminé"), - tr("L'appel a été enregistré dans le fichier : %1") - .arg(QString::fromStdString(mCallModel->getRecordFile())), + //: "Enregistrement terminé" + Utils::showInformationPopup(tr("call_record_end_message"), + //: "L'appel a été enregistré dans le fichier : %1" + tr("call_record_saved_in_file_message").arg(QString::fromStdString(mCallModel->getRecordFile())), true, App::getInstance()->getCallsWindow()); } }); @@ -385,19 +386,23 @@ void CallCore::setSelf(QSharedPointer me) { auto codecType = playloadType ? playloadType->getMimeType() : ""; auto codecRate = playloadType ? playloadType->getClockRate() / 1000 : 0; audioStats.mCodec = - tr("Codec: %1 / %2 kHz").arg(Utils::coreStringToAppString(codecType)).arg(codecRate); + //: "Codec: %1 / %2 kHz" + tr("call_stats_codec_label").arg(Utils::coreStringToAppString(codecType)).arg(codecRate); auto linAudioStats = call->getAudioStats(); if (linAudioStats) { - audioStats.mBandwidth = tr("Bande passante : %1 %2 kbits/s %3 %4 kbits/s") + //: "Bande passante : %1 %2 kbits/s %3 %4 kbits/s" + audioStats.mBandwidth = tr("call_stats_bandwidth_label") .arg("↑") .arg(round(linAudioStats->getUploadBandwidth())) .arg("↓") .arg(round(linAudioStats->getDownloadBandwidth())); - audioStats.mLossRate = tr("Taux de perte: %1% %2%") + //: "Taux de perte: %1% %2%" + audioStats.mLossRate = tr("call_stats_loss_rate_label") .arg(linAudioStats->getSenderLossRate()) .arg(linAudioStats->getReceiverLossRate()); - audioStats.mJitterBufferSize = - tr("Tampon de gigue: %1 ms").arg(linAudioStats->getJitterBufferSizeMs()); + //: "Tampon de gigue: %1 ms" + audioStats.mJitterBufferSize = + tr("call_stats_jitter_buffer_label").arg(linAudioStats->getJitterBufferSizeMs()); } setAudioStats(audioStats); } else if (stats->getType() == linphone::StreamType::Video) { @@ -407,15 +412,15 @@ void CallCore::setSelf(QSharedPointer me) { auto codecType = playloadType ? playloadType->getMimeType() : ""; auto codecRate = playloadType ? playloadType->getClockRate() / 1000 : 0; videoStats.mCodec = - tr("Codec: %1 / %2 kHz").arg(Utils::coreStringToAppString(codecType)).arg(codecRate); + tr("call_stats_codec_label").arg(Utils::coreStringToAppString(codecType)).arg(codecRate); auto linVideoStats = call->getVideoStats(); if (stats) { - videoStats.mBandwidth = tr("Bande passante : %1 %2 kbits/s %3 %4 kbits/s") + videoStats.mBandwidth = tr("call_stats_bandwidth_label") .arg("↑") .arg(round(linVideoStats->getUploadBandwidth())) .arg("↓") .arg(round(linVideoStats->getDownloadBandwidth())); - videoStats.mLossRate = tr("Taux de perte: %1% %2%") + videoStats.mLossRate = tr("call_stats_loss_rate_label") .arg(linVideoStats->getSenderLossRate()) .arg(linVideoStats->getReceiverLossRate()); } @@ -423,12 +428,14 @@ void CallCore::setSelf(QSharedPointer me) { params->getSentVideoDefinition() ? params->getSentVideoDefinition()->getName() : ""; auto receivedResolution = params->getReceivedVideoDefinition() ? params->getReceivedVideoDefinition()->getName() : ""; - videoStats.mResolution = tr("Définition vidéo : %1 %2 %3 %4") + //: "Définition vidéo : %1 %2 %3 %4" + videoStats.mResolution = tr("call_stats_resolution_label") .arg("↑", Utils::coreStringToAppString(sentResolution), "↓", Utils::coreStringToAppString(receivedResolution)); auto sentFps = params->getSentFramerate(); auto receivedFps = params->getReceivedFramerate(); - videoStats.mFps = tr("FPS : %1 %2 %3 %4").arg("↑").arg(sentFps).arg("↓").arg(receivedFps); + //: "FPS : %1 %2 %3 %4" + videoStats.mFps = tr("call_stats_fps_label").arg("↑").arg(sentFps).arg("↓").arg(receivedFps); setVideoStats(videoStats); } }); diff --git a/Linphone/core/conference/ConferenceInfoCore.cpp b/Linphone/core/conference/ConferenceInfoCore.cpp index 1b0c101ab..f477127ad 100644 --- a/Linphone/core/conference/ConferenceInfoCore.cpp +++ b/Linphone/core/conference/ConferenceInfoCore.cpp @@ -573,7 +573,9 @@ void ConferenceInfoCore::save() { mCoreModelConnection->invokeToModel([this, thisCopy]() { if (CoreModel::getInstance()->getCore()->getDefaultAccount()->getState() != linphone::RegistrationState::Ok) { - Utils::showInformationPopup(tr("Erreur"), tr("Votre compte est déconnecté"), false); + //: "Erreur" + //: "Votre compte est déconnecté" + Utils::showInformationPopup(tr("information_popup_error_title"), tr("information_popup_disconnected_account_message"), false); emit saveFailed(); return; } diff --git a/Linphone/core/friend/FriendCore.cpp b/Linphone/core/friend/FriendCore.cpp index a6d9a4e89..acf71d57f 100644 --- a/Linphone/core/friend/FriendCore.cpp +++ b/Linphone/core/friend/FriendCore.cpp @@ -26,8 +26,10 @@ DEFINE_ABSTRACT_OBJECT(FriendCore) -const QString _addressLabel = FriendCore::tr("Adresse SIP"); -const QString _phoneLabel = FriendCore::tr("Téléphone"); +//: "Adresse SIP" +const QString _addressLabel = FriendCore::tr("sip_address"); +//: "Téléphone" +const QString _phoneLabel = FriendCore::tr("device_id"); QSharedPointer FriendCore::create(const std::shared_ptr &contact, bool isStored, int sourceFlags) { @@ -413,7 +415,8 @@ void FriendCore::appendAddress(const QString &addr) { QString interpretedFullAddress = linphoneAddr ? Utils::coreStringToAppString(linphoneAddr->asString()) : ""; QString interpretedAddress = linphoneAddr ? Utils::coreStringToAppString(linphoneAddr->asStringUriOnly()) : ""; mCoreModelConnection->invokeToCore([this, interpretedAddress, interpretedFullAddress]() { - if (interpretedAddress.isEmpty()) Utils::showInformationPopup(tr("Erreur"), tr("Adresse invalide"), false); + //: "Adresse invalide" + if (interpretedAddress.isEmpty()) Utils::showInformationPopup(tr("information_popup_error_title"), tr("information_popup_invalid_address_message"), false); else { mAddressList.append(Utils::createFriendAddressVariant(_addressLabel, interpretedAddress)); if (mDefaultFullAddress.isEmpty()) mDefaultFullAddress = interpretedFullAddress; diff --git a/Linphone/core/login/LoginPage.cpp b/Linphone/core/login/LoginPage.cpp index 05f744e09..74f8bec38 100644 --- a/Linphone/core/login/LoginPage.cpp +++ b/Linphone/core/login/LoginPage.cpp @@ -76,7 +76,8 @@ void LoginPage::login(const QString &username, switch (state) { case linphone::RegistrationState::Failed: { if (message.isEmpty()) - setErrorMessage(QString(tr("Erreur durant la connexion"))); + //: Erreur durant la connexion + setErrorMessage(tr("default_account_connection_state_error_toast")); else setErrorMessage(message); if (accountManager) { diff --git a/Linphone/core/notifier/Notifier.cpp b/Linphone/core/notifier/Notifier.cpp index 888128ea5..20ff59d72 100644 --- a/Linphone/core/notifier/Notifier.cpp +++ b/Linphone/core/notifier/Notifier.cpp @@ -320,14 +320,14 @@ void Notifier::notifyReceivedMessages(const listisVoiceRecording()) //: 'Voice message received!' : message to warn the user in a notofication for voice messages. - txt = tr("newVoiceMessage"); - else txt = tr("newFileMessage"); + txt = tr("new_voice_message"); + else txt = tr("new_file_message"); if (txt.isEmpty() && message->hasConferenceInvitationContent()) //: 'Conference invitation received!' : Notification about receiving an invitation to a conference. - txt = tr("newConferenceInvitation"); + txt = tr("new_conference_invitation"); } else //: 'New messages received!' Notification that warn the user of new messages. - txt = tr("newChatRoomMessages"); + txt = tr("new_chat_room_messages"); map["message"] = txt; shared_ptr chatRoom(message->getChatRoom()); map["timelineModel"].setValue( @@ -366,21 +366,21 @@ void Notifier::notifyReceivedReactions( } } else if (fileContent->isVoiceRecording()) //: 'Voice message' : Voice message type that has been reacted. - messageTxt += tr("voiceMessageReact"); + messageTxt += tr("voice_message_react"); else { QFileInfo file(Utils::coreStringToAppString(fileContent->getFilePath())); messageTxt += file.fileName(); } if (messageTxt.isEmpty() && message->hasConferenceInvitationContent()) //: 'Conference invitation' : Conference invitation message type that has been reacted. - messageTxt += tr("conferenceInvitationReact"); + messageTxt += tr("conference_invitation_react"); //: ''Has reacted by %1 to: %2' : Reaction message. %1=Reaction(emoji), %2=type of message(Voice //: Message/Conference invitation/ Message text) - txt = tr("reactionMessage").arg(Utils::coreStringToAppString(reaction.second->getBody())).arg(messageTxt); + txt = tr("reaction_message").arg(Utils::coreStringToAppString(reaction.second->getBody())).arg(messageTxt); } else //: 'New reactions received!' : Notification that warn the user of new reactions. - txt = tr("newReactionsMessages"); + txt = tr("new_reactions_messages"); map["message"] = txt; map["timelineModel"].setValue(timelineModel.get()); @@ -412,7 +412,7 @@ void Notifier::notifyReceivedFileMessage(const shared_ptr void Notifier::notifyNewVersionAvailable(const QString &version, const QString &url) { QVariantMap map; - map["message"] = tr("newVersionAvailable").arg(version); + map["message"] = tr("new_version_available").arg(version); map["url"] = url; CREATE_NOTIFICATION(Notifier::NewVersionAvailable, map) } diff --git a/Linphone/core/payload-type/DownloadablePayloadTypeCore.cpp b/Linphone/core/payload-type/DownloadablePayloadTypeCore.cpp index e2c56c1a6..28dc708e9 100644 --- a/Linphone/core/payload-type/DownloadablePayloadTypeCore.cpp +++ b/Linphone/core/payload-type/DownloadablePayloadTypeCore.cpp @@ -84,7 +84,7 @@ void DownloadablePayloadTypeCore::setSelf(QSharedPointer me) { linphoneFriend->addPhoneNumber(phoneNumber); contact = FriendCore::create(linphoneFriend, isStored, it->getSourceFlags()); contact->setGivenName(Utils::coreStringToAppString(it->getPhoneNumber())); - contact->appendPhoneNumber(tr("Phone"), Utils::coreStringToAppString(it->getPhoneNumber())); + contact->appendPhoneNumber(tr("device_id"), Utils::coreStringToAppString(it->getPhoneNumber())); contacts->append(contact); } } diff --git a/Linphone/core/translator/DefaultTranslatorCore.cpp b/Linphone/core/translator/DefaultTranslatorCore.cpp new file mode 100644 index 000000000..dbd695561 --- /dev/null +++ b/Linphone/core/translator/DefaultTranslatorCore.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2010-2020 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 +#include + +#include "DefaultTranslatorCore.hpp" + +// ============================================================================= + +DefaultTranslatorCore::DefaultTranslatorCore (QObject *parent) : QTranslator(parent) { + QDirIterator it(":", QDirIterator::Subdirectories); + while (it.hasNext()) { + QFileInfo info(it.next()); + + if (info.suffix() == QLatin1String("qml")) { + QString dir = info.absoluteDir().absolutePath(); + + // Ignore extra selectors. + // TODO: Remove 5.9 support in July 2019. + for (const auto &selector : { "+linux", "+mac", "+windows", "+custom", "+5.9" }) + if (dir.contains(selector)) + goto end; + + // Ignore default imports. + if (dir.startsWith(":/QtQuick")) + continue; + + QString basename = info.baseName(); + if (!mContexts.contains(basename)) + mContexts << basename; + } + end:; + } +} + +QString DefaultTranslatorCore::translate ( + const char *context, + const char *sourceText, + const char *disambiguation, + int n +) const { + if (!context) + return QString(""); + + QString translation = QTranslator::translate(context, sourceText, disambiguation, n); + + if (translation.length() == 0 && mContexts.contains(context)) + qDebug() << QStringLiteral("Unable to find a translation. (context=%1, label=%2, disambiguation=%3)") + .arg(context).arg(sourceText).arg(disambiguation); + + return translation; +} diff --git a/Linphone/core/translator/DefaultTranslatorCore.hpp b/Linphone/core/translator/DefaultTranslatorCore.hpp new file mode 100644 index 000000000..6718bce3c --- /dev/null +++ b/Linphone/core/translator/DefaultTranslatorCore.hpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2010-2020 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 DEFAULT_TRANSLATOR_CORE_H_ +#define DEFAULT_TRANSLATOR_CORE_H_ + +#include +#include + +// ============================================================================= + +class DefaultTranslatorCore : public QTranslator { +public: + DefaultTranslatorCore (QObject *parent = Q_NULLPTR); + + QString translate ( + const char *context, + const char *sourceText, + const char *disambiguation = Q_NULLPTR, + int n = -1 + ) const override; + +private: + QSet mContexts; +}; + +// Workaround for bad Application Menu translation on Mac: +// Overwrite Qt source by our translations : +//static const char *application_menu_strings[] = +//{ +// QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","About %1"), +// QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Preferences…"), +// QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Services"), +// QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Hide %1"), +// QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Hide Others"), +// QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Show All"), +// QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Quit %1") +//}; + +//class MAC_APPLICATION_MENU : public QObject{ +// QString forcedTranslation(){ +// return tr("About %1") + tr("Preferences…") + tr("Services") + tr("Hide %1") + tr("Hide Others") + tr("Show All") + tr("Quit %1"); +// } +//}; + +#endif // DEFAULT_TRANSLATOR_CORE_H_ diff --git a/Linphone/data/CMakeLists.txt b/Linphone/data/CMakeLists.txt index 01282f4df..106ef5030 100644 --- a/Linphone/data/CMakeLists.txt +++ b/Linphone/data/CMakeLists.txt @@ -10,4 +10,10 @@ foreach(f ${files}) get_filename_component(filename ${f} NAME) list(APPEND _LINPHONEAPP_RC_FILES data/image/${filename}) endforeach() + +#file(GLOB files LIST_DIRECTORIES false languages/*) +#foreach(f ${files}) +# get_filename_component(filename ${f} NAME) +# list(APPEND _LINPHONEAPP_RC_FILES data/languages/${filename}) +#endforeach() set(_LINPHONEAPP_RC_FILES ${_LINPHONEAPP_RC_FILES} PARENT_SCOPE) diff --git a/Linphone/data/lang/Linphone_en_US.ts b/Linphone/data/lang/Linphone_en_US.ts deleted file mode 100644 index edd0d342c..000000000 --- a/Linphone/data/lang/Linphone_en_US.ts +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/Linphone/data/languages/CMakeLists.txt b/Linphone/data/languages/CMakeLists.txt new file mode 100644 index 000000000..58debf53e --- /dev/null +++ b/Linphone/data/languages/CMakeLists.txt @@ -0,0 +1,10 @@ +# ============================================================================== +# data/languages/CMakeLists.txt +# ============================================================================== + +# This line prevent `.ts` files deletion. +# See: https://bugreports.qt.io/browse/QTBUG-31860 +# +# On October 17, 2016, this issue was marked `invalid` but it's a +# bullshit. It's not tolerated to remove source files. +#set_directory_properties(PROPERTIES CLEAN_NO_CUSTOM true) diff --git a/Linphone/data/languages/en.ts b/Linphone/data/languages/en.ts new file mode 100644 index 000000000..c451bfcd1 --- /dev/null +++ b/Linphone/data/languages/en.ts @@ -0,0 +1,5221 @@ + + + + + AbstractSettingsLayout + + + save + "Enregistrer" + + + + + AbstractWindow + + + contact_dialog_pick_phone_number_or_sip_address_title + "Choisissez un numéro ou adresse SIP" + + + + + fps_counter + + + + + AccountCore + + + drawer_menu_account_connection_status_connected + "Connecté" + + + + + drawer_menu_account_connection_status_refreshing + + + + + drawer_menu_account_connection_status_progress + + + + + drawer_menu_account_connection_status_failed + + + + + drawer_menu_account_connection_status_cleared + + + + + manage_account_status_connected_summary + "Vous êtes en ligne et joignable." + + + + + manage_account_status_failed_summary + "Erreur de connexion, vérifiez vos paramètres." + + + + + manage_account_status_cleared_summary + "Compte désactivé, vous ne recevrez ni appel ni message." + + + + + AccountDeviceList + + + manage_account_no_device_found_error_message + "Erreur lors de la récupération des appareils" + + + + + AccountManager + + + assistant_account_login_already_connected_error + "Le compte est déjà connecté" + + + + + assistant_account_login_proxy_address_error + "Impossible de créer l'adresse proxy. Merci de vérifier le nom de domaine." + + + + + assistant_account_login_address_configuration_error + "Impossible de configurer l'adresse : `%1`." + + + + + assistant_account_login_params_configuration_error + "Impossible de configurer les paramètres du compte." + + + + + assistant_account_login_forbidden_error + "Le couple identifiant mot de passe ne correspond pas" + + + + + assistant_account_login_error + "Erreur durant la connexion" + + + + + assistant_account_add_error + "Impossible d'ajouter le compte." + + + + + AccountSettingsGeneralLayout + + + manage_account_details_title + "Détails" + + + + + manage_account_details_subtitle + Éditer les informations de votre compte. + + + + + manage_account_devices_title + "Vos appareils" + + + + + manage_account_devices_subtitle + "La liste des appareils connectés à votre compte. Vous pouvez retirer les appareils que vous n’utilisez plus." + + + + + manage_account_add_picture + "Ajouter une image" + + + + + manage_account_edit_picture + "Modifier l'image" + + + + + manage_account_remove_picture + "Supprimer l'image" + + + + + sip_address + + + + + sip_address_display_name + "Nom d'affichage + + + + + sip_address_display_name_explaination + "Le nom qui sera affiché à vos correspondants lors de vos échanges." + + + + + manage_account_international_prefix + "Indicatif international*" + + + + + manage_account_delete + "Déconnecter mon compte" + + + + + manage_account_delete_message + + + + + manage_account_dialog_remove_account_title + "Se déconnecter du compte ?" + + + + + manage_account_dialog_remove_account_message + Si vous souhaitez supprimer définitivement votre compte rendez-vous sur : https://sip.linphone.org + + + + + error + Erreur + + + + + manage_account_device_remove + "Supprimer" + + + + + manage_account_device_remove_confirm_dialog + + + + + manage_account_device_last_connection + "Dernière connexion:" + + + + + AccountSettingsPage + + + drawer_menu_manage_account + "Mon compte" + + + + + settings_general_title + "Général" + + + + + settings_account_title + "Paramètres de compte" + + + + + contact_editor_popup_abort_confirmation_title + "Modifications non enregistrées" + + + + + contact_editor_popup_abort_confirmation_message + "Vous avez des modifications non enregistrées. Si vous quittez cette page, vos changements seront perdus. Voulez-vous enregistrer vos modifications avant de continuer ?" + + + + + contact_editor_dialog_abort_confirmation_do_not_save + "Ne pas enregistrer" "Enregistrer" + + + + + contact_editor_dialog_abort_confirmation_save + + + + + AccountSettingsParametersLayout + + + settings_title + + + + + settings_account_title + + + + + information_popup_success_title + + + + + contact_editor_saved_changes_toast + "Modifications sauvegardés" + + + + + account_settings_mwi_uri_title + "URI du serveur de messagerie vocale" + + + + + account_settings_voicemail_uri_title + "URI de messagerie vocale" + + + + + account_settings_transport_title + "Transport" + + + + + account_settings_sip_proxy_url_title + + + + + account_settings_outbound_proxy_title + "Serveur mandataire sortant" + + + + + account_settings_stun_server_url_title + "Adresse du serveur STUN" + + + + + account_settings_enable_ice_title + "Activer ICE" + + + + + account_settings_avpf_title + "AVPF" + + + + + account_settings_bundle_mode_title + "Mode bundle" + + + + + account_settings_expire_title + "Expiration (en seconde)" + + + + + account_settings_conference_factory_uri_title + "URI du serveur de conversations" + + + + + account_settings_audio_video_conference_factory_uri_title + "URI du serveur de réunions" + + + + + account_settings_lime_server_url_title + "URL du serveur d’échange de clés de chiffrement" + + + + + AddParticipantsForm + + + search_bar_search_contacts_placeholder + "Rechercher des contacts" + + + + + list_filter_no_result_found + "Aucun contact" + + + + + contact_list_empty + + + + + AdvancedSettingsLayout + + + settings_system_title + "Système" + + + + + settings_remote_provisioning_title + "Configuration distante" + + + + + settings_security_title + "Sécurité / Chiffrement" + + + + + settings_advanced_audio_codecs_title + "Codecs audio" + + + + + settings_advanced_video_codecs_title + "Codecs vidéo" + + + + + settings_advanced_auto_start_title + "Démarrer automatiquement Linphone" + + + + + settings_advanced_remote_provisioning_url + "URL de configuration distante" + + + + + settings_advanced_download_apply_remote_provisioning + "Télécharger et appliquer" + + + + + information_popup_error_title + "Format d'url invalide" + + + + + settings_advanced_invalid_url_message + + + + + settings_advanced_media_encryption_title + "Chiffrement du média" + + + + + settings_advanced_media_encryption_mandatory_title + "Chiffrement du média obligatoire" + + + + + settings_advanced_hide_fps_title + + + + + AllContactListView + + + car_favorites_contacts_title + "Favoris" + + + + + generic_address_picker_contacts_list_title + 'Contacts' + + + + + generic_address_picker_suggestions_list_title + "Suggestions" + + + + + App + + + remote_provisioning_dialog + Voulez-vous télécharger et appliquer la configuration depuis cette adresse ? + + + + + application_description + "A free and open source SIP video-phone." + + + + + command_line_arg_order + "Send an order to the application towards a command line" + + + + + command_line_option_show_help + + + + + command_line_option_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." + + + + + command_line_option_config_to_fetch_arg + "URL, path or file" + + + + + command_line_option_log_to_stdout + + + + + command_line_option_print_app_logs_only + "Print only logs from the application" + + + + + hide_action + "Cacher" "Afficher" + + + + + show_action + + + + + quit_action + "Quitter" + + + + + AuthenticationDialog + + + account_settings_dialog_invalid_password_title + "Authentification requise" + + + + + account_settings_dialog_invalid_password_message + La connexion a échoué pour le compte %1. Vous pouvez renseigner votre mot de passe à nouveau ou bien vérifier les options de configuration de votre compte. + + + + + password + + + + + cancel + "Annuler + + + + + assistant_account_login + Connexion + + + + + assistant_account_login_missing_password + Veuillez saisir un mot de passe + + + + + CallCore + + + call_record_end_message + "Enregistrement terminé" + + + + + call_record_saved_in_file_message + "L'appel a été enregistré dans le fichier : %1" + + + + + + call_stats_codec_label + "Codec: %1 / %2 kHz" + + + + + + call_stats_bandwidth_label + "Bande passante : %1 %2 kbits/s %3 %4 kbits/s" + + + + + + call_stats_loss_rate_label + "Taux de perte: %1% %2%" + + + + + call_stats_jitter_buffer_label + "Tampon de gigue: %1 ms" + + + + + call_stats_resolution_label + "Définition vidéo : %1 %2 %3 %4" + + + + + call_stats_fps_label + "FPS : %1 %2 %3 %4" + + + + + CallHistoryLayout + + + contact_presence_status_online + "En ligne" + + + + + contact_presence_status_busy + "Occupé" + + + + + contact_presence_status_do_not_disturb + "Ne pas déranger" + + + + + contact_presence_status_offline + "Hors ligne" + + + + + meeting_info_join_title + "Rejoindre la réunion" + + + + + contact_call_action + "Appel" + + + + + contact_message_action + "Message" + + + + + contact_video_call_action + "Appel Video" + + + + + CallLayout + + + meeting_event_conference_destroyed + "Vous avez quitté la conférence" + + + + + call_ended_by_user + "Vous avez terminé l'appel" + + + + + call_ended_by_remote + "Votre correspondant a terminé l'appel" + + + + + conference_call_empty + "En attente d'autres participants…" + + + + + conference_share_link_title + "Partager le lien" + + + + + copied + Le lien de la réunion a été copié dans le presse-papier + + + + + information_popup_meeting_address_copied_to_clipboard + + + + + CallListView + + + meeting + "Réunion "Appel" + + + + + call + + + + + paused_call_or_meeting + "%1 en pause" + + + + + ongoing_call_or_meeting + "%1 en cours" + + + + + CallModel + + + call_error_user_declined_toast + "Le correspondant a décliné l'appel" + + + + + call_error_user_not_found_toast + "Le correspondant n'a pas été trouvé" + + + + + call_error_user_busy_toast + "Le correspondant est occupé" + + + + + call_error_incompatible_media_params_toast + "Le correspondant ne peut accepter votre appel." + + + + + call_error_io_error_toast + "Service indisponible ou erreur réseau" + + + + + call_error_temporarily_unavailable_toast + "Temporairement indisponible" + + + + + call_error_server_timeout_toast + "Délai d'attente du serveur dépassé" + + + + + CallPage + + + history_call_start_title + "Nouvel appel" + + + + + call_history_empty_title + "Historique d'appel vide" + + + + + history_dialog_delete_all_call_logs_title + Supprimer l'historique d'appels ? + + + + + history_dialog_delete_all_call_logs_message + "L'ensemble de votre historique d'appels sera définitivement supprimé." + + + + + history_dialog_delete_call_logs_title + Supprimer l'historique d'appels ? + + + + + history_dialog_delete_call_logs_message + "L'ensemble de votre historique d'appels avec ce correspondant sera définitivement supprimé." + + + + + call_history_call_list_title + "Appels" + + + + + + menu_delete_history + "Supprimer l'historique" + + + + + call_search_in_history + "Rechercher un appel" + + + + + list_filter_no_result_found + "Aucun appel dans votre historique" "Aucun résultat…" + + + + + history_list_empty_history + + + + + call_action_start_new_call + "Nouvel appel" + + + + + call_start_group_call_title + "Appel de groupe" + + + + + group_call_participant_selected + "%n participant(s) sélectionné(s)" + + + + + call_action_start_group_call + "Lancer" + + + + + history_group_call_start_dialog_subject_hint + "Nom du groupe" + + + + + required + "Requis" + + + + + + + information_popup_error_title + + + + + group_call_error_must_have_name + "Un nom doit être donné à l'appel de groupe + + + + + group_call_error_not_connected + "Vous n'etes pas connecté" + + + + + menu_see_existing_contact + "Voir le contact" + + + + + menu_add_address_to_contacts + "Ajouter aux contacts" + + + + + menu_copy_sip_address + "Copier l'adresse SIP" + + + + + sip_address_copied_to_clipboard_toast + Adresse copiée + + + + + sip_address_copied_to_clipboard_message + L'adresse a été copié dans le presse_papiers + + + + + sip_address_copy_to_clipboard_error + "Erreur lors de la copie de l'adresse" + + + + + notification_missed_call_title + "Appel manqué" + + + + + call_outgoing + "Appel sortant" + + + + + call_audio_incoming + "Appel entrant" + + + + + CallSettingsLayout + + + settings_call_devices_title + "Périphériques" + + + + + settings_call_devices_subtitle + "Vous pouvez modifier les périphériques de sortie audio, le microphone et la caméra de capture." + + + + + settings_calls_echo_canceller_title + "Annulateur d'écho" + + + + + settings_calls_echo_canceller_subtitle + "Évite que de l'écho soit entendu par votre correspondant" + + + + + settings_calls_auto_record_title + "Activer l’enregistrement automatique des appels" + + + + + Tonalités + + + + + Activer les tonalités + + + + + settings_calls_enable_video_title + "Autoriser la vidéo" + + + + + CallStatistics + + + call_stats_audio_title + "Audio" + + + + + call_stats_video_title + "Vidéo" + + + + + CallsWindow + + + call_transfer_in_progress_toast + "Transfert en cours, veuillez patienter" + + + + + + information_popup_error_title + "La conférence n'a pas pu démarrer en raison d'une erreur d'uri." + + + + + call_transfer_failed_toast + "Le transfert d'appel a échoué" + + + + + conference_error_empty_uri + + + + + call_close_window_dialog_title + "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." + + + + + call_can_be_trusted_toast + "Appareil authentifié" + + + + + call_dir + "Appel %1" + + + + + call_ended + "Appel terminé" + + + + + conference_paused + "Réunion mise en pause" + + + + + call_paused + "Appel mis en pause" + + + + + call_srtp_point_to_point_encrypted + "Appel chiffré de point à point" + + + + + call_zrtp_sas_validation_required + "Vérification nécessaire" + + + + + call_zrtp_end_to_end_encrypted + "Appel chiffré de bout en bout" + + + + + call_not_encrypted + "Appel non chiffré" + + + + + call_waiting_for_encryption_info + "En attente de chiffrement" + + + + + conference_user_is_recording + "Vous enregistrez la réunion" + + + + + call_user_is_recording + "Vous enregistrez l'appel" + + + + + conference_remote_is_recording + "Un participant enregistre la réunion" + + + + + call_remote_recording + "Votre correspondant enregistre l'appel" + + + + + call_stop_recording + "Arrêter l'enregistrement" + + + + + add + + + + + call_transfer_current_call_title + "Transférer %1 à…" + + + + + + call_transfer_confirm_dialog_tittle + "Confirmer le transfert" + + + + + + call_transfer_confirm_dialog_message + "Vous allez transférer %1 à %2." + + + + + call_action_start_new_call + "Nouvel appel" + + + + + + call_action_show_dialer + "Pavé numérique" + + + + + call_action_change_layout + "Modifier la disposition" + + + + + call_action_go_to_calls_list + "Liste d'appel" + + + + + Merger tous les appels + call_action_merge_calls + + + + + + call_action_go_to_settings + "Paramètres" + + + + + conference_action_screen_sharing + "Partage de votre écran" + + + + + conference_share_link_title + Partager le lien de la réunion + + + + + copied + Copié + + + + + information_popup_meeting_address_copied_to_clipboard + Le lien de la réunion a été copié dans le presse-papier + + + + + + + conference_participants_list_title + "Participants (%1)" + + + + + + group_call_participant_selected + + + + + meeting_schedule_add_participants_title + + + + + call_encryption_title + Chiffrement + + + + + call_stats_title + Statistiques + + + + + call_action_end_call + "Terminer l'appel" + + + + + call_action_resume_call + "Reprendre l'appel" + + + + + call_action_pause_call + "Mettre l'appel en pause" + + + + + call_action_transfer_call + "Transférer l'appel" + + + + + call_action_start_new_call_hint + "Initier un nouvel appel" + + + + + call_display_call_list_hint + "Afficher la liste d'appels" + + + + + call_deactivate_video_hint + "Désactiver la vidéo" "Activer la vidéo" + + + + + call_activate_video_hint + + + + + call_activate_microphone + "Activer le micro" + + + + + call_deactivate_microphone + "Désactiver le micro" + + + + + call_share_screen_hint + Partager l'écran… + + + + + call_rise_hand_hint + "Lever la main" + + + + + call_send_reaction_hint + "Envoyer une réaction" + + + + + call_manage_participants_hint + "Gérer les participants" + + + + + call_more_options_hint + "Plus d'options…" + + + + + call_action_change_conference_layout + "Modifier la disposition" + + + + + call_action_full_screen + "Mode Plein écran" + + + + + call_action_stop_recording + "Terminer l'enregistrement" + + + + + call_action_record + "Enregistrer l'appel" + + + + + call_activate_speaker_hint + "Activer le son" + + + + + call_deactivate_speaker_hint + "Désactiver le son" + + + + + CarddavSettingsLayout + + + settings_contacts_carddav_title + Carnet d'adresse CardDAV + + + + + settings_contacts_carddav_subtitle + "Ajouter un carnet d’adresse CardDAV pour synchroniser vos contacts Linphone avec un carnet d’adresse tiers." + + + + + information_popup_error_title + "Vérifiez que toutes les informations ont été saisies." + + + + + settings_contacts_carddav_popup_invalid_error + + + + + information_popup_synchronization_success_title + "Le carnet d'adresse CardDAV est synchronisé." + + + + + settings_contacts_carddav_synchronization_success_message + + + + + settings_contacts_carddav_popup_synchronization_error_title + "Erreur de synchronisation!" + + + + + settings_contacts_carddav_popup_synchronization_error_message + + + + + settings_contacts_delete_carddav_server_title + "Supprimer le carnet d'adresse CardDAV ?" + + + + + sip_address_display_name + Nom d'affichage + + + + + settings_contacts_carddav_server_url_title + "URL du serveur" + + + + + username + + + + + password + + + + + settings_contacts_carddav_realm_title + Domaine d’authentification + + + + + settings_contacts_carddav_use_as_default_title + "Stocker ici les contacts nouvellement crées" + + + + + ChangeLayoutForm + + + conference_layout_grid + + + + + conference_layout_active_speaker + + + + + conference_layout_audio_only + + + + + CliModel + + + show_function_description + + + + + fetch_config_function_description + + + + + call_function_description + + + + + bye_function_description + + + + + accept_function_description + + + + + decline_function_description + + + + + ConferenceInfoCore + + + information_popup_error_title + "Erreur" "Votre compte est déconnecté" + + + + + information_popup_disconnected_account_message + + + + + Contact + + + drawer_menu_account_connection_status_connected + "Connecté" + + + + + drawer_menu_account_connection_status_cleared + "Désactivé" + + + + + drawer_menu_account_connection_status_refreshing + "Connexion…" + + + + + drawer_menu_account_connection_status_failed + "Erreur" + + + + + information_popup_error_title + Erreur + + + + + information_popup_voicemail_address_undefined_message + L'URI de messagerie vocale n'est pas définie. + + + + + ContactEdition + + + contact_editor_title + "Modifier contact" + + + + + save + "Enregistrer + + + + + + contact_editor_dialog_cancel_change_message + "Les changements seront annulés. Souhaitez-vous continuer ?" + + + + + contact_editor_mandatory_first_name_not_filled + "Veuillez saisir un prénom" + + + + + contact_editor_mandatory_address_or_number_not_filled + "Veuillez saisir une adresse ou un numéro de téléphone" + + + + + contact_editor_add_image_label + "Ajouter une image" + + + + + contact_details_edit + "Modifier" + + + + + contact_details_delete + "Supprimer" + + + + + contact_editor_first_name + "Prénom" + + + + + contact_editor_last_name + "Nom" + + + + + contact_editor_company + "Entreprise" + + + + + contact_editor_job_title + "Fonction" + + + + + + sip_address + + + + + + phone + "Téléphone" + + + + + ContactListItem + + + contact_details_remove_from_favourites + "Enlever des favoris" "Ajouter aux favoris" + + + + + contact_details_add_to_favourites + + + + + Partager + + + + + information_popup_error_title + "La création du fichier vcard a échoué" + + + + + information_popup_vcard_creation_error + + + + + information_popup_vcard_creation_title + "VCard créée" "VCard du contact enregistrée dans %1" + + + + + information_popup_vcard_creation_success + + + + + contact_sharing_email_title + "Partage de contact" + + + + + contact_details_delete + "Supprimer" + + + + + ContactPage + + + contacts_add + "Ajouter un contact" + + + + + contacts_list_empty + "Aucun contact pour le moment" + + + + + contact_new_title + "Nouveau contact" + + + + + create + + + + + contact_edit_title + "Modifier contact" + + + + + save + + + + + contact_dialog_delete_title + Supprimer %1 ?" + + + + + contact_dialog_delete_message + Ce contact sera définitivement supprimé. + + + + + contact_deleted_toast + "Contact supprimé" + + + + + contact_deleted_message + "%1 a été supprimé" + + + + + contact_dialog_devices_trust_popup_title + "Augmenter la confiance" + + + + + contact_dialog_devices_trust_popup_message + "Pour augmenter le niveau de confiance vous devez appeler les différents appareils de votre contact et valider un code.<br><br>Vous êtes sur le point d’appeler “%1” voulez vous continuer ?" + + + + + popup_do_not_show_again + Ne plus afficher + + + + + cancel + + + + + dialog_call + "Appeler" + + + + + contact_dialog_devices_trust_help_title + "Niveau de confiance" + + + + + contact_dialog_devices_trust_help_message + "Vérifiez les appareils de votre contact pour confirmer que vos communications seront sécurisées et sans compromission. <br>Quand tous seront vérifiés, vous atteindrez le niveau de confiance maximal." + + + + + dialog_ok + "Ok" + + + + + bottom_navigation_contacts_label + "Contacts" + + + + + search_bar_look_for_contact_text + Rechercher un contact + + + + + list_filter_no_result_found + Aucun résultat… + + + + + contact_list_empty + Aucun contact pour le moment + + + + + + contact_details_edit + "Éditer" + + + + + contact_call_action + "Appel" + + + + + contact_message_action + "Message" + + + + + contact_video_call_action + "Appel vidéo" + + + + + contact_presence_status_online + "En ligne" + + + + + contact_presence_status_busy + "Occupé" + + + + + contact_presence_status_do_not_disturb + "Ne pas déranger" + + + + + contact_presence_status_offline + "Hors ligne" + + + + + contact_details_numbers_and_addresses_title + "Coordonnées" + + + + + contact_details_company_name + "Société :" + + + + + contact_details_job_title + "Poste :" + + + + + contact_details_medias_title + "Medias" + + + + + contact_details_medias_subtitle + "Afficher les medias partagés" + + + + + contact_details_trust_title + "Confiance" + + + + + contact_dialog_devices_trust_title + "Niveau de confiance - Appareils vérifiés" + + + + + contact_details_no_device_found + "Aucun appareil" + + + + + contact_device_without_name + "Appareil sans nom" + + + + + contact_make_call_check_device_trust + "Vérifier" + + + + + contact_details_actions_title + "Autres actions" + + + + + contact_details_remove_from_favourites + "Retirer des favoris" + + + + + contact_details_add_to_favourites + "Ajouter aux favoris" + + + + + contact_details_share + "Partager" + + + + + information_popup_error_title + + + + + contact_details_share_error_mesage + "La création du fichier vcard a échoué" + + + + + contact_details_share_success_title + "VCard créée" + + + + + contact_details_share_success_mesage + "VCard du contact enregistrée dans %1" + + + + + contact_details_share_email_title + "Partage de contact" + + + + + contact_details_delete + "Supprimer ce contact" + + + + + ContactsSettingsLayout + + + settings_contacts_ldap_title + Annuaires LDAP + + + + + settings_contacts_ldap_subtitle + "Ajouter vos annuaires LDAP pour pouvoir effectuer des recherches dans la magic search bar." + + + + + settings_contacts_carddav_title + + + + + settings_contacts_carddav_subtitle + + + + + settings_contacts_add_ldap_server_title + "Ajouter un annuaire LDAP" + + + + + settings_contacts_edit_ldap_server_title + "Modifier un annuaire LDAP" + + + + + settings_contacts_add_carddav_server_title + "Ajouter un carnet d'adresse CardDAV" + + + + + settings_contacts_edit_carddav_server_title + "Modifier un carnet d'adresse CardDAV" + + + + + ContactsSettingsProviderLayout + + + information_popup_success_title + "Les changements ont été sauvegardés" + + + + + information_popup_changes_saved + + + + + add + "Ajouter" + + + + + DebugSettingsLayout + + + settings_debug_clean_logs_message + "Les traces de débogage seront supprimées. Souhaitez-vous continuer ?" + + + + + settings_debug_share_logs_message + "Les traces de débogage ont été téléversées. Comment souhaitez-vous partager le lien ? " + + + + + settings_debug_clipboard + "Presse-papier" + + + + + settings_debug_email + "E-Mail" + + + + + debug_settings_trace + "Traces %1" + + + + + information_popup_email_sharing_failed + "Le partage par mail a échoué. Veuillez envoyer le lien %1 directement à l'adresse %2." + + + + + + information_popup_error_title + Une erreur est survenue. + + + + + settings_debug_enable_logs_title + "Activer les traces de débogage" + + + + + settings_debug_enable_full_logs_title + "Activer les traces de débogage intégrales" + + + + + settings_debug_delete_logs_title + "Supprimer les traces" + + + + + settings_debug_share_logs_title + "Partager les traces" + + + + + settings_debug_share_logs_loading_message + "Téléversement des traces en cours …" + + + + + settings_debug_app_version_title + "Version de l'application" + + + + + settings_debug_sdk_version_title + "Version du SDK" + + + + + settings_debug_share_logs_error + "Le téléversement des traces a échoué. Vous pouvez partager les fichiers de trace directement depuis le répertoire suivant : %1" + + + + + DecoratedTextField + + + textfield_error_message_cannot_be_empty + "ne peut être vide" + + + + + textfield_error_message_unknown_format + "Format non reconnu" + + + + + Dialog + + + + dialog_confirm + "Confirmer" "Annuler" + + + + + + dialog_cancel + + + + + EncryptionSettings + + + call_stats_media_encryption_title + "Chiffrement :" + + + + + call_stats_media_encryption + "Chiffrement du média : %1%2" "ZRTP Post Quantique" + + + + + call_stats_zrtp_cipher_algo + "Algorithme de chiffrement : %1" + + + + + call_stats_zrtp_key_agreement_algo + "Algorithme d'accord de clé : %1" + + + + + call_stats_zrtp_hash_algo + "Algorithme de hachage : %1" + + + + + call_stats_zrtp_auth_tag_algo + "Algorithme d'authentification : %1" + + + + + call_stats_zrtp_sas_algo + "Algorithme SAS : %1" + + + + + call_zrtp_validation_button_label + "Validation chiffrement" + + + + + FriendCore + + + sip_address + "Adresse SIP" + + + + + device_id + "Téléphone" + + + + + information_popup_error_title + "Adresse invalide" + + + + + information_popup_invalid_address_message + + + + + HelpPage + + + help_title + "Aide" + + + + + + help_about_title + "À propos de %1" + + + + + help_about_privacy_policy_title + "Règles de confidentialité" + + + + + help_about_privacy_policy_subtitle + Quelles informations %1 collecte et utilise + + + + + help_about_version_title + "Version" + + + + + help_about_gpl_licence_title + "Licences GPLv3" + + + + + help_about_contribute_translations_title + "Contribuer à la traduction de %1" + + + + + help_troubleshooting_title + "Dépannage" + + + + + LdapSettingsLayout + + + settings_contacts_ldap_title + + + + + settings_contacts_ldap_subtitle + + + + + information_popup_success_title + "L'annuaire LDAP a été sauvegardé" + + + + + settings_contacts_ldap_success_toast + + + + + settings_contacts_ldap_error_toast + + + + + 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 ?" + + + + + settings_contacts_ldap_server_url_title + "URL du serveur (ne peut être vide)" + + + + + settings_contacts_ldap_bind_dn_title + "Bind DN" + + + + + settings_contacts_ldap_password_title + "Mot de passe" + + + + + settings_contacts_ldap_use_tls_title + "Utiliser TLS" + + + + + settings_contacts_ldap_search_base_title + "Base de recherche (ne peut être vide)" + + + + + settings_contacts_ldap_search_filter_title + "Filtre" + + + + + settings_contacts_ldap_max_results_title + "Nombre maximum de résultats" + + + + + settings_contacts_ldap_request_delay_title + "Délai entre 2 requêtes (en millisecondes)" + + + + + settings_contacts_ldap_request_timeout_title + "Durée maximun (en secondes)" + + + + + settings_contacts_ldap_min_characters_title + "Nombre minimum de caractères pour la requête" + + + + + settings_contacts_ldap_name_attributes_title + "Attributs de nom" + + + + + settings_contacts_ldap_sip_attributes_title + "Attributs SIP" + + + + + settings_contacts_ldap_sip_domain_title + "Domaine SIP" + + + + + settings_contacts_ldap_debug_title + "Débogage" + + + + + LoadingPopup + + + cancel + + + + + LoginForm + + + username + "Nom d'utilisateur" : username + + + + + password + "Mot de passe" + + + + + 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_forgotten_password + "Mot de passe oublié ?" + + + + + LoginLayout + + + + help_about_title + À propos de %1 + + + + + help_about_privacy_policy_title + "Politique de confidentialité" + + + + + help_about_privacy_policy_link + "Visiter notre potilique de confidentialité" + + + + + help_about_version_title + "Version" + + + + + help_about_licence_title + "Licence" + + + + + help_about_copyright_title + "Copyright + + + + + close + "Fermer" + + + + + LoginPage + + + assistant_account_login + Connexion + + + + + assistant_no_account_yet + "Pas encore de compte ?" + + + + + assistant_account_register + "S'inscrire" + + + + + assistant_login_third_party_sip_account_title + "Compte SIP tiers" + + + + + assistant_login_remote_provisioning + "Configuration distante" + + + + + assistant_login_download_remote_config + "Télécharger une configuration distante" + + + + + assistant_login_remote_provisioning_url + 'Veuillez entrer le lien de configuration qui vous a été fourni :' + + + + + cancel + + + + + validate + "Valider" + + + + + settings_advanced_remote_provisioning_url + 'Lien de configuration distante' + + + + + default_account_connection_state_error_toast + + + + + MagicSearchList + + + device_id + + + + + MainLayout + + + bottom_navigation_calls_label + "Appels" + + + + + bottom_navigation_contacts_label + "Contacts" + + + + + bottom_navigation_conversations_label + "Conversations" + + + + + bottom_navigation_meetings_label + "Réunions" + + + + + searchbar_placeholder_text + "Rechercher un contact, appeler %1" "ou envoyer un message …" + + + + + searchbar_placeholder_text_chat_feature_enabled + + + + + + contact_presence_status_disable_do_not_disturb + "Désactiver ne pas déranger" + + + + + information_popup_error_title + + + + + no_voicemail_uri_error_message + "L'URI de messagerie vocale n'est pas définie." + + + + + drawer_menu_manage_account + Mon compte + + + + + contact_presence_status_enable_do_not_disturb + "Activer ne pas déranger" + + + + + settings_title + + + + + recordings_title + "Enregistrements" + + + + + help_title + "Aide" + + + + + help_quit_title + "Quitter l'application" + + + + + quit_app_question + "Quitter %1 ?" + + + + + drawer_menu_add_account + "Ajouter un compte" + + + + + MainWindow + + + information_popup_connexion_succeed_title + "Connexion réussie" + + + + + information_popup_connexion_succeed_message + "Vous êtes connecté en mode %1" + + + + + interoperable + interopérable + + + + + call_transfer_successful_toast_title + "Appel transféré" + + + + + call_transfer_successful_toast_message + "Votre correspondant a été transféré au contact sélectionné" + + + + + information_popup_success_title + "Les changements ont été sauvegardés" + + + + + information_popup_changes_saved + + + + + captcha_validation_loading_message + "Veuillez valider le captcha sur la page web" + + + + + assistant_register_error_title + "Erreur lors de la création" + + + + + assistant_register_success_title + "Compte créé" + + + + + assistant_register_success_message + "Le compte a été créé. Vous pouvez maintenant vous connecter" + + + + + assistant_register_error_code + "Erreur dans le code de validation" + + + + + information_popup_error_title + + + + + MeetingForm + + + meeting_schedule_meeting_label + "Réunion" + + + + + meeting_schedule_broadcast_label + "Webinar" + + + + + meeting_schedule_subject_hint + "Ajouter un titre" + + + + + meeting_schedule_description_hint + "Ajouter une description" + + + + + meeting_schedule_add_participants_title + "Ajouter des participants" + + + + + meeting_schedule_send_invitations_title + "Envoyer une invitation aux participants" + + + + + MeetingListView + + + meeting_info_cancelled + "Réunion annulée" + + + + + meetings_list_no_meeting_for_today + "Aucune réunion aujourd'hui" + + + + + MeetingPage + + + meetings_add + "Créer une réunion" + + + + + meetings_list_empty + "Aucune réunion" + + + + + meeting_schedule_cancel_dialog_message + "Souhaitez-vous annuler et supprimer cette réunion ?" + + + + + meeting_schedule_delete_dialog_message + Souhaitez-vous supprimer cette réunion ? + + + + + meeting_schedule_cancel_and_delete_action + "Annuler et supprimer" + + + + + meeting_schedule_delete_only_action + "Supprimer seulement" + + + + + meeting_schedule_delete_action + "Supprimer" + + + + + back_action + Retour + + + + + meetings_list_title + Réunions + + + + + meetings_search_hint + "Rechercher une réunion" + + + + + list_filter_no_result_found + "Aucun résultat…" + + + + + meetings_empty_list + "Aucune réunion" + + + + + + meeting_schedule_title + "Nouvelle réunion" + + + + + create + + + + + + + + + + information_popup_error_title + + + + + + meeting_schedule_mandatory_field_not_filled_toast + Veuillez saisir un titre et sélectionner au moins un participant + + + + + + meeting_schedule_duration_error_toast + "La fin de la conférence doit être plus récente que son début" + + + + + meeting_schedule_creation_in_progress + "Création de la réunion en cours …" + + + + + meeting_info_created_toast + "Réunion planifiée avec succès" + + + + + meeting_schedule_creation_processing + Création de la réunion en cours… + + + + + meeting_failed_to_schedule_toast + "Échec de création de la réunion !" + + + + + save + + + + + + saved + "Enregistré" + + + + + meeting_info_updated_toast + "Réunion mise à jour" + + + + + meeting_schedule_edit_in_progress + "Modification de la réunion en cours…" + + + + + meeting_failed_to_edit_toast + "Échec de la modification de la réunion !" + + + + + meeting_schedule_add_participants_title + "Ajouter des participants" + + + + + add + + + + + group_call_participant_selected + "%n participant(s) sélectionné(s)" + + + + + meeting_info_delete + "Supprimer la réunion" + + + + + meeting_address_copied_to_clipboard_toast + "Adresse de la réunion copiée" + + + + + meeting_schedule_timezone_title + "Fuseau horaire" + + + + + meeting_info_organizer_label + "Organisateur" + + + + + meeting_info_join_title + "Rejoindre la réunion" + + + + + MeetingsSettingsLayout + + + settings_meetings_display_title + "Affichage" + + + + + settings_meetings_default_layout_title + "Mode d’affichage par défaut" + + + + + settings_meetings_default_layout_subtitle + "Le mode d’affichage des participants en réunions" + + + + + MultimediaSettings + + + multimedia_settings_ringer_title + "Sonnerie - Appels entrants" + + + + + multimedia_settings_speaker_title + "Haut-parleurs" + + + + + multimedia_settings_microphone_title + "Microphone" + + + + + multimedia_settings_camera_title + "Caméra" + + + + + NetworkSettingsLayout + + + settings_network_title + "Réseau" + + + + + settings_network_allow_ipv6 + "Autoriser l'IPv6" + + + + + NewCallForm + + + call_transfer_active_calls_label + "Appels en cours" + + + + + search_bar_look_for_contact_text + "Rechercher un contact" + + + + + NotificationReceivedCall + + + call_audio_incoming + "Appel entrant" + + + + + dialog_accept + "Accepter" + + + + + dialog_deny + "Refuser + + + + + ParticipantListView + + + meeting_participant_is_admin_label + "Admin" + + + + + meeting_add_participants_title + "Ajouter des participants" + + + + + QObject + + + DTLS + + + + + None + + + + + SRTP + + + + + media_encryption_post_quantum + "ZRTP - Post quantique" + + + + + incoming + "Entrant" + + + + + outgoing + "Sortant" + + + + + conference_layout_active_speaker + "Participant actif" + + + + + conference_layout_grid + "Mosaïque" + + + + + conference_layout_audio_only + "Audio uniquement" + + + + + RegisterCheckingPage + + + email + "email" + + + + + phone_number + "numéro de téléphone" + + + + + confirm_register_title + "Inscription | Confirmer votre %1" + + + + + assistant_account_creation_confirmation_explanation + Nous vous avons envoyé un code de vérification sur votre %1 %2<br> Merci de le saisir ci-dessous + + + + + assistant_account_creation_confirmation_did_not_receive_code + "Vous n'avez pas reçu le code ?" + + + + + assistant_account_creation_confirmation_resend_code + "Renvoyer un code" + + + + + RegisterPage + + + assistant_account_register + "Inscription + + + + + assistant_already_have_an_account + + + + + assistant_account_login + + + + + assistant_account_register_with_phone_number + + + + + assistant_account_register_with_email + + + + + username + + + + + + phone_number + "Numéro de téléphone" + + + + + email + + + + + password + + + + + assistant_account_register_password_confirmation + "Confirmation mot de passe" + + + + + assistant_dialog_cgu_and_privacy_policy_message + "J'accepte les %1 et la %2" + + + + + assistant_dialog_general_terms_label + "conditions d'utilisation" + + + + + assistant_dialog_privacy_policy_label + "politique de confidentialité" + + + + + assistant_account_create + "Créer" + + + + + assistant_account_create_missing_username_error + "Veuillez entrer un nom d'utilisateur" + + + + + assistant_account_create_missing_password_error + "Veuillez entrer un mot de passe" + + + + + assistant_account_create_confirm_password_error + "Les mots de passe sont différents" + + + + + assistant_account_create_missing_number_error + "Veuillez entrer un numéro de téléphone" + + + + + assistant_account_create_missing_email_error + "Veuillez entrer un email" + + + + + SIPLoginPage + + + assistant_login_third_party_sip_account_title + Compte SIP tiers + + + + + assistant_no_account_yet + Pas encore de compte ? + + + + + assistant_account_register + 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. + +Pour les activer dans un projet commercial, merci de nous contacter. + + + + + assistant_third_party_sip_account_create_linphone_account + "Créer un compte linphone" + + + + + assistant_third_party_sip_account_warning_ok + "Je comprends" + + + + + username + "Nom d'utilisateur" + + + + + password + + + + + sip_address_domain + "Domaine" + + + + + sip_address_display_name + Nom d'affichage + + + + + transport + "Transport" + + + + + assistant_account_login + + + + + assistant_account_login_missing_username + + + + + assistant_account_login_missing_password + + + + + assistant_account_login_missing_domain + "Veuillez saisir un nom de domaine + + + + + ScreencastSettings + + + screencast_settings_choose_window_text + "Veuillez choisir l’écran ou la fenêtre que vous souihaitez partager au autres participants" + + + + + screencast_settings_all_screen_label + "Ecran entier" + + + + + screencast_settings_one_window_label + "Fenêtre" + + + + + screencast_settings_screen + "Ecran %1" + + + + + stop + "Stop + + + + + share + "Partager" + + + + + SecurityModePage + + + manage_account_choose_mode_title + "Choisir votre mode" + + + + + manage_account_choose_mode_message + "Vous pourrez changer de mode plus tard." + + + + + manage_account_e2e_encrypted_mode_default_title + "Chiffrement de bout en bout" + + + + + manage_account_e2e_encrypted_mode_default_summary + "Ce mode vous garanti la confidentialité de tous vos échanges. Notre technologie de chiffrement de bout en bout assure un niveau de sécurité maximal pour tous vos échanges." + + + + + manage_account_e2e_encrypted_mode_interoperable_title + "Interoperable" + + + + + manage_account_e2e_encrypted_mode_interoperable_summary + "Ce mode vous permet de profiter de toute les fonctionnalités de Linphone, toute en restant interopérable avec n’importe qu’elle autre service SIP." + + + + + dialog_continue + "Continuer" + + + + + SecuritySettingsLayout + + + settings_security_enable_vfs_title + "Chiffrer tous les fichiers" + + + + + settings_security_enable_vfs_subtitle + "Attention, vous ne pourrez pas revenir en arrière !" + + + + + SettingsPage + + + settings_title + "Paramètres" + + + + + settings_calls_title + "Appels" + + + + + settings_conversations_title + "Conversations" + + + + + settings_contacts_title + "Contacts" + + + + + settings_meetings_title + "Réunions" + + + + + settings_network_title + "Affichage" "Réseau" + + + + + settings_advanced_title + "Paramètres avancés" + + + + + contact_editor_popup_abort_confirmation_title + Modifications non enregistrées + + + + + contact_editor_popup_abort_confirmation_message + Vous avez des modifications non enregistrées. Si vous quittez cette page, vos changements seront perdus. Voulez-vous enregistrer vos modifications avant de continuer ? + + + + + contact_editor_dialog_abort_confirmation_do_not_save + "Ne pas enregistrer" + + + + + contact_editor_dialog_abort_confirmation_save + "Enregistrer" + + + + + Sticker + + + conference_participant_joining_text + "rejoint…" + + + + + conference_participant_paused_text + "En pause" + + + + + ToolModel + + + call_error_uninterpretable_sip_address + "The calling address is not an interpretable SIP address : %1 + + + + + unknown_audio_device_name + + + + + Utils + + + information_popup_call_not_created_message + "L'appel n'a pas pu être créé" + + + + + number_of_years + %n an(s) + + + + + + + + number_of_month + "%n mois" + + + + + + + + number_of_weeks + %n semaine(s) + + + + + + + + number_of_days + %n jour(s) + + + + + + + + today + "Aujourd'hui" + + + + + yesterday + "Hier + + + + + call_zrtp_token_verification_possible_characters + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + + + + + WaitingRoom + + + meeting_waiting_room_title + Participer à : + + + + + meeting_waiting_room_join + "Rejoindre" + + + + + + cancel + + + + + meeting_waiting_room_joining_title + "Connexion à la réunion" + + + + + meeting_waiting_room_joining_subtitle + "Vous allez rejoindre la réunion dans quelques instants…" + + + + + WelcomePage + + + welcome_page_title + "Bienvenue" + + + + + welcome_page_subtitle + "sur %1" + + + + + welcome_carousel_skip + "Passer" + + + + + welcome_page_1_message + "Une application de communication <b>sécurisée</b>,<br> <b>open source</b> et <b>française</b>." + + + + + welcome_page_2_title + "Sécurisé" + + + + + welcome_page_2_message + "Vos communications sont en sécurité grâce aux <br><b>Chiffrement de bout en bout</b>." + + + + + welcome_page_3_title + "Open Source" + + + + + welcome_page_3_message + "Une application open source et un <b>service gratuit</b> <br>depuis <b>2001</b>" + + + + + next + "Suivant" + + + + + start + "Commencer" + + + + + ZrtpAuthenticationDialog + + + call_dialog_zrtp_validate_trust_title + Vérification de sécurité + + + + + call_zrtp_sas_validation_skip + "Passer" + + + + + call_dialog_zrtp_validate_trust_warning_message + "Pour garantir le chiffrement, nous avons besoin de réauthentifier l’appareil de votre correspondant. Echangez vos codes :" + + + + + call_dialog_zrtp_validate_trust_message + "Pour garantir le chiffrement, nous avons besoin d’authentifier l’appareil de votre correspondant. Veuillez échanger vos codes : " + + + + + call_dialog_zrtp_validate_trust_local_code_label + "Votre code :" + + + + + call_dialog_zrtp_validate_trust_remote_code_label + "Code correspondant :" + + + + + call_dialog_zrtp_validate_trust_letters_do_not_match_text + "Le code fourni ne correspond pas." + + + + + call_dialog_zrtp_security_alert_message + "La confidentialité de votre appel peut être compromise !" + + + + + call_dialog_zrtp_validate_trust_letters_do_not_match + "Aucune correspondance" + + + + + call_action_hang_up + "Raccrocher" + + + + + country + + + Afghanistan + + + + + Albania + + + + + Algeria + + + + + AmericanSamoa + + + + + Andorra + + + + + Angola + + + + + Anguilla + + + + + AntiguaAndBarbuda + + + + + Argentina + + + + + Armenia + + + + + Aruba + + + + + Australia + + + + + Austria + + + + + Azerbaijan + + + + + Bahamas + + + + + Bahrain + + + + + Bangladesh + + + + + Barbados + + + + + Belarus + + + + + Belgium + + + + + Belize + + + + + Benin + + + + + Bermuda + + + + + Bhutan + + + + + Bolivia + + + + + BosniaAndHerzegowina + + + + + Botswana + + + + + Brazil + + + + + Brunei + + + + + Bulgaria + + + + + BurkinaFaso + + + + + Burundi + + + + + Cambodia + + + + + Cameroon + + + + + Canada + + + + + CapeVerde + + + + + CaymanIslands + + + + + CentralAfricanRepublic + + + + + Chad + + + + + Chile + + + + + China + + + + + Colombia + + + + + Comoros + + + + + PeoplesRepublicOfCongo + + + + + DemocraticRepublicOfCongo + + + + + CookIslands + + + + + CostaRica + + + + + IvoryCoast + + + + + Croatia + + + + + Cuba + + + + + Cyprus + + + + + CzechRepublic + + + + + Denmark + + + + + Djibouti + + + + + Dominica + + + + + DominicanRepublic + + + + + Ecuador + + + + + Egypt + + + + + ElSalvador + + + + + EquatorialGuinea + + + + + Eritrea + + + + + Estonia + + + + + Ethiopia + + + + + FalklandIslands + + + + + FaroeIslands + + + + + Fiji + + + + + Finland + + + + + France + + + + + FrenchGuiana + + + + + FrenchPolynesia + + + + + Gabon + + + + + Gambia + + + + + Georgia + + + + + Germany + + + + + Ghana + + + + + Gibraltar + + + + + Greece + + + + + Greenland + + + + + Grenada + + + + + Guadeloupe + + + + + Guam + + + + + Guatemala + + + + + Guinea + + + + + GuineaBissau + + + + + Guyana + + + + + Haiti + + + + + Honduras + + + + + HongKong + + + + + Hungary + + + + + Iceland + + + + + India + + + + + Indonesia + + + + + Iran + + + + + Iraq + + + + + Ireland + + + + + Israel + + + + + Italy + + + + + Jamaica + + + + + Japan + + + + + Jordan + + + + + Kazakhstan + + + + + Kenya + + + + + Kiribati + + + + + DemocraticRepublicOfKorea + + + + + RepublicOfKorea + + + + + Kuwait + + + + + Kyrgyzstan + + + + + Laos + + + + + Latvia + + + + + Lebanon + + + + + Lesotho + + + + + Liberia + + + + + Libya + + + + + Liechtenstein + + + + + Lithuania + + + + + Luxembourg + + + + + Macau + + + + + Macedonia + + + + + Madagascar + + + + + Malawi + + + + + Malaysia + + + + + Maldives + + + + + Mali + + + + + Malta + + + + + MarshallIslands + + + + + Martinique + + + + + Mauritania + + + + + Mauritius + + + + + Mayotte + + + + + Mexico + + + + + Micronesia + + + + + Moldova + + + + + Monaco + + + + + Mongolia + + + + + Montenegro + + + + + Montserrat + + + + + Morocco + + + + + Mozambique + + + + + Myanmar + + + + + Namibia + + + + + NauruCountry + + + + + Nepal + + + + + Netherlands + + + + + NewCaledonia + + + + + NewZealand + + + + + Nicaragua + + + + + Niger + + + + + Nigeria + + + + + Niue + + + + + NorfolkIsland + + + + + NorthernMarianaIslands + + + + + Norway + + + + + Oman + + + + + Pakistan + + + + + Palau + + + + + PalestinianTerritories + + + + + Panama + + + + + PapuaNewGuinea + + + + + Paraguay + + + + + Peru + + + + + Philippines + + + + + Poland + + + + + Portugal + + + + + PuertoRico + + + + + Qatar + + + + + Reunion + + + + + Romania + + + + + RussianFederation + + + + + Rwanda + + + + + SaintHelena + + + + + SaintKittsAndNevis + + + + + SaintLucia + + + + + SaintPierreAndMiquelon + + + + + SaintVincentAndTheGrenadines + + + + + Samoa + + + + + SanMarino + + + + + SaoTomeAndPrincipe + + + + + SaudiArabia + + + + + Senegal + + + + + Serbia + + + + + Seychelles + + + + + SierraLeone + + + + + Singapore + + + + + Slovakia + + + + + Slovenia + + + + + SolomonIslands + + + + + Somalia + + + + + SouthAfrica + + + + + Spain + + + + + SriLanka + + + + + Sudan + + + + + Suriname + + + + + Swaziland + + + + + Sweden + + + + + Switzerland + + + + + Syria + + + + + Taiwan + + + + + Tajikistan + + + + + Tanzania + + + + + Thailand + + + + + Togo + + + + + Tokelau + + + + + Tonga + + + + + TrinidadAndTobago + + + + + Tunisia + + + + + Turkey + + + + + Turkmenistan + + + + + TurksAndCaicosIslands + + + + + Tuvalu + + + + + Uganda + + + + + Ukraine + + + + + UnitedArabEmirates + + + + + UnitedKingdom + + + + + UnitedStates + + + + + Uruguay + + + + + Uzbekistan + + + + + Vanuatu + + + + + Venezuela + + + + + Vietnam + + + + + WallisAndFutunaIslands + + + + + Yemen + + + + + Zambia + + + + + Zimbabwe + + + + + utils + + + formatYears + '%1 year' + + + + + + + + formatMonths + '%1 month' + + + + + + + + formatWeeks + '%1 week' + + + + + + + + formatDays + '%1 day' + + + + + + + + formatHours + '%1 hour' + + + + + + + + formatMinutes + '%1 minute' + + + + + + + + formatSeconds + '%1 second' + + + + + + + + codec_install + "Installation de codec" + + + + + download_codec + "Télécharger le codec %1 (%2) ?" + + + + + information_popup_success_title + "Succès" + + + + + information_popup_codec_install_success_text + "Le codec a été installé avec succès." + + + + + + + information_popup_error_title + + + + + information_popup_codec_install_error_text + "Le codec n'a pas pu être installé." + + + + + information_popup_codec_save_error_text + "Le codec n'a pas pu être sauvegardé." + + + + + information_popup_codec_download_error_text + "Le codec n'a pas pu être téléchargé." + + + + + loading_popup_codec_install_progress + "Téléchargement en cours …" + + + + + okButton + + + + diff --git a/Linphone/data/languages/fr_FR.ts b/Linphone/data/languages/fr_FR.ts new file mode 100644 index 000000000..259e19826 --- /dev/null +++ b/Linphone/data/languages/fr_FR.ts @@ -0,0 +1,5239 @@ + + + + + AbstractSettingsLayout + + + save + "Enregistrer" + Enregistrer + + + + AbstractWindow + + + contact_dialog_pick_phone_number_or_sip_address_title + "Choisissez un numéro ou adresse SIP" + Choisissez un numéro ou adresse SIP + + + + fps_counter + %1 FPS + + + + 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. + + + + AccountDeviceList + + + manage_account_no_device_found_error_message + "Erreur lors de la récupération des appareils" + Erreur lors de la récupération des appareils + + + + AccountManager + + + assistant_account_login_already_connected_error + "Le compte est déjà connecté" + Le compte est déjà connecté + + + + assistant_account_login_proxy_address_error + "Impossible de créer l'adresse proxy. Merci de vérifier le nom de domaine." + Impossible de créer l'adresse proxy. Merci de vérifier le nom de domaine. + + + + assistant_account_login_address_configuration_error + "Impossible de configurer l'adresse : `%1`." + Impossible de configurer l'adresse : `%1`. + + + + assistant_account_login_params_configuration_error + "Impossible de configurer les paramètres du compte." + Impossible de configurer les paramètres du compte. + + + + assistant_account_login_forbidden_error + "Le couple identifiant mot de passe ne correspond pas" + Le couple identifiant mot de passe ne correspond pas + + + + assistant_account_login_error + "Erreur durant la connexion" + Erreur durant la connexion + + + + assistant_account_add_error + "Impossible d'ajouter le compte." + Impossible d'ajouter le compte. + + + + AccountSettingsGeneralLayout + + + manage_account_details_title + "Détails" + Détails + + + + manage_account_details_subtitle + Éditer les informations de votre compte. + Éditer les informations de votre compte. + + + + manage_account_devices_title + "Vos appareils" + Vos appareils + + + + manage_account_devices_subtitle + "La liste des appareils connectés à votre compte. Vous pouvez retirer les appareils que vous n’utilisez plus." + La liste des appareils connectés à votre compte. Vous pouvez retirer les appareils que vous n’utilisez plus. + + + + manage_account_add_picture + "Ajouter une image" + Ajouter une image + + + + manage_account_edit_picture + "Modifier l'image" + Modifier l'image + + + + manage_account_remove_picture + "Supprimer l'image" + Supprimer l'image + + + + sip_address + Adresse SIP + + + + sip_address_display_name + "Nom d'affichage + Nom d'affichage + + + + sip_address_display_name_explaination + "Le nom qui sera affiché à vos correspondants lors de vos échanges." + Le nom qui sera affiché à vos correspondants lors de vos échanges. + + + + manage_account_international_prefix + "Indicatif international*" + Indicatif international* + + + + manage_account_delete + "Déconnecter mon compte" + Déconnecter mon compte + + + + manage_account_delete_message + Votre compte sera retiré de ce client linphone, mais vous restez connecté sur vos autres clients + + + + manage_account_dialog_remove_account_title + "Se déconnecter du compte ?" + Se déconnecter du compte ? + + + + manage_account_dialog_remove_account_message + Si vous souhaitez supprimer définitivement votre compte rendez-vous sur : https://sip.linphone.org + Si vous souhaitez supprimer définitivement votre compte rendez-vous sur : https://sip.linphone.org + + + + error + Erreur + Erreur + + + + manage_account_device_remove + "Supprimer" + Supprimer + + + + manage_account_device_remove_confirm_dialog + Supprimer %1 ? + + + + manage_account_device_last_connection + "Dernière connexion:" + Dernière connexion: + + + + AccountSettingsPage + + + drawer_menu_manage_account + "Mon compte" + Mon compte + + + + settings_general_title + "Général" + Général + + + + settings_account_title + "Paramètres de compte" + Paramètres de compte + + + + contact_editor_popup_abort_confirmation_title + "Modifications non enregistrées" + Modifications non enregistrées + + + + contact_editor_popup_abort_confirmation_message + "Vous avez des modifications non enregistrées. Si vous quittez cette page, vos changements seront perdus. Voulez-vous enregistrer vos modifications avant de continuer ?" + Vous avez des modifications non enregistrées. Si vous quittez cette page, vos changements seront perdus. Voulez-vous enregistrer vos modifications avant de continuer ? + + + + contact_editor_dialog_abort_confirmation_do_not_save + "Ne pas enregistrer" "Enregistrer" + Ne pas enregistrer + + + + contact_editor_dialog_abort_confirmation_save + Enregistrer + + + + AccountSettingsParametersLayout + + + settings_title + Paramètres + + + + settings_account_title + Paramètres de compte + + + + information_popup_success_title + Succès + + + + contact_editor_saved_changes_toast + "Modifications sauvegardés" + Modifications sauvegardés + + + + account_settings_mwi_uri_title + "URI du serveur de messagerie vocale" + URI du serveur de messagerie vocale + + + + account_settings_voicemail_uri_title + "URI de messagerie vocale" + URI de messagerie vocale + + + + account_settings_transport_title + "Transport" + Transport + + + + account_settings_sip_proxy_url_title + URL du serveur mandataire + + + + account_settings_outbound_proxy_title + "Serveur mandataire sortant" + Serveur mandataire sortant + + + + account_settings_stun_server_url_title + "Adresse du serveur STUN" + Adresse du serveur STUN + + + + account_settings_enable_ice_title + "Activer ICE" + Activer ICE + + + + account_settings_avpf_title + "AVPF" + AVPF + + + + account_settings_bundle_mode_title + "Mode bundle" + Mode bundle + + + + account_settings_expire_title + "Expiration (en seconde)" + Expiration (en seconde) + + + + account_settings_conference_factory_uri_title + "URI du serveur de conversations" + URI du serveur de conversations + + + + account_settings_audio_video_conference_factory_uri_title + "URI du serveur de réunions" + URI du serveur de réunions + + + + account_settings_lime_server_url_title + "URL du serveur d’échange de clés de chiffrement" + URL du serveur d’échange de clés de chiffrement + + + + AddParticipantsForm + + + search_bar_search_contacts_placeholder + "Rechercher des contacts" + Rechercher des contacts + + + + list_filter_no_result_found + "Aucun contact" + Aucun résultat… + + + + contact_list_empty + Aucun contact + + + + AdvancedSettingsLayout + + + settings_system_title + "Système" + Système + + + + settings_remote_provisioning_title + "Configuration distante" + Configuration distante + + + + settings_security_title + "Sécurité / Chiffrement" + Sécurité / Chiffrement + + + + settings_advanced_audio_codecs_title + "Codecs audio" + Codecs audio + + + + settings_advanced_video_codecs_title + "Codecs vidéo" + Codecs vidéo + + + + settings_advanced_auto_start_title + "Démarrer automatiquement Linphone" + Démarrer automatiquement Linphone + + + + settings_advanced_remote_provisioning_url + "URL de configuration distante" + URL de configuration distante + + + + settings_advanced_download_apply_remote_provisioning + "Télécharger et appliquer" + Télécharger et appliquer + + + + information_popup_error_title + "Format d'url invalide" + Erreur + + + + settings_advanced_invalid_url_message + Format d'url invalide + + + + settings_advanced_media_encryption_title + "Chiffrement du média" + Chiffrement du média + + + + settings_advanced_media_encryption_mandatory_title + "Chiffrement du média obligatoire" + Chiffrement du média obligatoire + + + + settings_advanced_hide_fps_title + Cacher les FPS + + + + AllContactListView + + + car_favorites_contacts_title + "Favoris" + Favoris + + + + generic_address_picker_contacts_list_title + 'Contacts' + Contacts + + + + generic_address_picker_suggestions_list_title + "Suggestions" + Suggestions + + + + 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 ? + + + + 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_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 + + + + AuthenticationDialog + + + account_settings_dialog_invalid_password_title + "Authentification requise" + Authentification requise + + + + account_settings_dialog_invalid_password_message + La connexion a échoué pour le compte %1. Vous pouvez renseigner votre mot de passe à nouveau ou bien vérifier les options de configuration de votre compte. + La connexion a échoué pour le compte %1. Vous pouvez renseigner votre mot de passe à nouveau ou bien vérifier les options de configuration de votre compte. + + + + password + Mot de passe + + + + cancel + "Annuler + Annuler + + + + assistant_account_login + Connexion + Connexion + + + + assistant_account_login_missing_password + Veuillez saisir un mot de passe + Veuillez saisir un mot de passe + + + + CallCore + + + call_record_end_message + "Enregistrement terminé" + Enregistrement terminé + + + + call_record_saved_in_file_message + "L'appel a été enregistré dans le fichier : %1" + L'appel a été enregistré dans le fichier : %1 + + + + + call_stats_codec_label + "Codec: %1 / %2 kHz" + Codec: %1 / %2 kHz + + + + + call_stats_bandwidth_label + "Bande passante : %1 %2 kbits/s %3 %4 kbits/s" + Bande passante : %1 %2 kbits/s %3 %4 kbits/s + + + + + call_stats_loss_rate_label + "Taux de perte: %1% %2%" + Taux de perte: %1% %2% + + + + call_stats_jitter_buffer_label + "Tampon de gigue: %1 ms" + Tampon de gigue: %1 ms + + + + call_stats_resolution_label + "Définition vidéo : %1 %2 %3 %4" + Définition vidéo : %1 %2 %3 %4 + + + + call_stats_fps_label + "FPS : %1 %2 %3 %4" + FPS : %1 %2 %3 %4 + + + + CallHistoryLayout + + + contact_presence_status_online + "En ligne" + En ligne + + + + contact_presence_status_busy + "Occupé" + Occupé + + + + contact_presence_status_do_not_disturb + "Ne pas déranger" + Ne pas déranger + + + + contact_presence_status_offline + "Hors ligne" + Hors ligne + + + + meeting_info_join_title + "Rejoindre la réunion" + Rejoindre la réunion + + + + contact_call_action + "Appel" + Appel + + + + contact_message_action + "Message" + Message + + + + contact_video_call_action + "Appel Video" + Appel Vidéo + + + + CallLayout + + + meeting_event_conference_destroyed + "Vous avez quitté la conférence" + Vous avez quitté la conférence + + + + call_ended_by_user + "Vous avez terminé l'appel" + Vous avez terminé l'appel + + + + call_ended_by_remote + "Votre correspondant a terminé l'appel" + Votre correspondant a terminé l'appel + + + + conference_call_empty + "En attente d'autres participants…" + En attente d'autres participants… + + + + conference_share_link_title + "Partager le lien" + Partager le lien + + + + copied + Le lien de la réunion a été copié dans le presse-papier + Copié + + + + information_popup_meeting_address_copied_to_clipboard + Le lien de la réunion a été copié dans le presse-papier + + + + CallListView + + + meeting + "Réunion "Appel" + Réunion + + + + call + Appel + + + + paused_call_or_meeting + "%1 en pause" + %1 en pause + + + + ongoing_call_or_meeting + "%1 en cours" + %1 en cours + + + + CallModel + + + call_error_user_declined_toast + "Le correspondant a décliné l'appel" + Le correspondant a décliné l'appel + + + + call_error_user_not_found_toast + "Le correspondant n'a pas été trouvé" + Le correspondant n'a pas été trouvé + + + + call_error_user_busy_toast + "Le correspondant est occupé" + Le correspondant est occupé + + + + call_error_incompatible_media_params_toast + "Le correspondant ne peut accepter votre appel." + Le correspondant ne peut accepter votre appel + + + + call_error_io_error_toast + "Service indisponible ou erreur réseau" + Service indisponible ou erreur réseau + + + + call_error_temporarily_unavailable_toast + "Temporairement indisponible" + Temporairement indisponible + + + + call_error_server_timeout_toast + "Délai d'attente du serveur dépassé" + Délai d'attente du serveur dépassé + + + + CallPage + + + history_call_start_title + "Nouvel appel" + Nouvel appel + + + + call_history_empty_title + "Historique d'appel vide" + Historique d'appel vide + + + + history_dialog_delete_all_call_logs_title + Supprimer l'historique d'appels ? + Supprimer l'historique d'appels ? + + + + history_dialog_delete_all_call_logs_message + "L'ensemble de votre historique d'appels sera définitivement supprimé." + L'ensemble de votre historique d'appels sera définitivement supprimé. + + + + history_dialog_delete_call_logs_title + Supprimer l'historique d'appels ? + Supprimer l'historique d'appels ? + + + + history_dialog_delete_call_logs_message + "L'ensemble de votre historique d'appels avec ce correspondant sera définitivement supprimé." + L'ensemble de votre historique d'appels avec ce correspondant sera définitivement supprimé. + + + + call_history_call_list_title + "Appels" + Appels + + + + + menu_delete_history + "Supprimer l'historique" + Supprimer l'historique + + + + call_search_in_history + "Rechercher un appel" + Rechercher un appel + + + + list_filter_no_result_found + "Aucun appel dans votre historique" "Aucun résultat…" + Aucun résultat… + + + + history_list_empty_history + Aucun appel dans votre historique + + + + call_action_start_new_call + "Nouvel appel" + Nouvel appel + + + + call_start_group_call_title + "Appel de groupe" + Appel de groupe + + + + group_call_participant_selected + "%n participant(s) sélectionné(s)" + %n participant(s) sélectionné(s) + + + + call_action_start_group_call + "Lancer" + Lancer + + + + history_group_call_start_dialog_subject_hint + "Nom du groupe" + Nom du groupe + + + + required + "Requis" + Requis + + + + + + 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 + "Voir le contact" + Voir le contact + + + + menu_add_address_to_contacts + "Ajouter aux 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 + + + + CallSettingsLayout + + + settings_call_devices_title + "Périphériques" + Périphériques + + + + settings_call_devices_subtitle + "Vous pouvez modifier les périphériques de sortie audio, le microphone et la caméra de capture." + Vous pouvez modifier les périphériques de sortie audio, le microphone et la caméra de capture. + + + + settings_calls_echo_canceller_title + "Annulateur d'écho" + Annulateur d'écho + + + + settings_calls_echo_canceller_subtitle + "Évite que de l'écho soit entendu par votre correspondant" + Évite que de l'écho soit entendu par votre correspondant + + + + settings_calls_auto_record_title + "Activer l’enregistrement automatique des appels" + Activer l’enregistrement automatique des appels + + + + Tonalités + Tonalités + + + + Activer les tonalités + Activer les tonalités + + + + settings_calls_enable_video_title + "Autoriser la vidéo" + Autoriser la vidéo + + + + CallStatistics + + + call_stats_audio_title + "Audio" + Audio + + + + call_stats_video_title + "Vidéo" + Vidéo + + + + CallsWindow + + + call_transfer_in_progress_toast + "Transfert en cours, veuillez patienter" + Transfert en cours, veuillez patienter + + + + + information_popup_error_title + "La conférence n'a pas pu démarrer en raison d'une erreur d'uri." + 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. + + + + 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" + Appel %1 + + + + call_ended + "Appel terminé" + Appel terminé + + + + conference_paused + "Réunion mise en pause" + Réunion mise en pause + + + + call_paused + "Appel mis en pause" + 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 + "En attente de chiffrement" + En attente de chiffrement + + + + conference_user_is_recording + "Vous enregistrez la réunion" + Vous enregistrez la réunion + + + + call_user_is_recording + "Vous enregistrez l'appel" + Vous enregistrez l'appel + + + + conference_remote_is_recording + "Un participant enregistre la réunion" + Un participant enregistre la réunion + + + + call_remote_recording + "Votre correspondant enregistre l'appel" + Votre correspondant enregistre l'appel + + + + call_stop_recording + "Arrêter l'enregistrement" + 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 + %n participant(s) sélectionné(s) + + + + meeting_schedule_add_participants_title + Ajouter des participants + + + + call_encryption_title + Chiffrement + Chiffrement + + + + 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_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 + + + + CarddavSettingsLayout + + + settings_contacts_carddav_title + Carnet d'adresse CardDAV + Carnet d'adresse CardDAV + + + + settings_contacts_carddav_subtitle + "Ajouter un carnet d’adresse CardDAV pour synchroniser vos contacts Linphone avec un carnet d’adresse tiers." + Ajouter un carnet d’adresse CardDAV pour synchroniser vos contacts Linphone avec un carnet d’adresse tiers. + + + + information_popup_error_title + "Vérifiez que toutes les informations ont été saisies." + Erreur + + + + settings_contacts_carddav_popup_invalid_error + Vérifiez que toutes les informations ont été saisies. + + + + information_popup_synchronization_success_title + "Le carnet d'adresse CardDAV est synchronisé." + Succès + + + + settings_contacts_carddav_synchronization_success_message + Le carnet d'adresse CardDAV est synchronisé. + + + + settings_contacts_carddav_popup_synchronization_error_title + "Erreur de synchronisation!" + Erreur + + + + settings_contacts_carddav_popup_synchronization_error_message + Erreur de synchronisation! + + + + settings_contacts_delete_carddav_server_title + "Supprimer le carnet d'adresse CardDAV ?" + Supprimer le carnet d'adresse CardDAV ? + + + + sip_address_display_name + Nom d'affichage + Nom d'affichage + + + + settings_contacts_carddav_server_url_title + "URL du serveur" + URL du serveur + + + + username + Nom d'utilisateur + + + + password + Mot de passe + + + + settings_contacts_carddav_realm_title + Domaine d’authentification + Domaine d’authentification + + + + settings_contacts_carddav_use_as_default_title + "Stocker ici les contacts nouvellement crées" + Stocker ici les contacts nouvellement crées + + + + ChangeLayoutForm + + + conference_layout_grid + Mosaïque + + + + conference_layout_active_speaker + Intervenant actif + + + + conference_layout_audio_only + Audio uniquement + + + + CliModel + + + show_function_description + Afficher + + + + fetch_config_function_description + Récupérer une configuration + + + + call_function_description + Appeler + + + + bye_function_description + Raccrocher + + + + accept_function_description + Accepter + + + + decline_function_description + Décliner + + + + ConferenceInfoCore + + + information_popup_error_title + "Erreur" "Votre compte est déconnecté" + Erreur + + + + information_popup_disconnected_account_message + Votre compte est déconnecté + + + + Contact + + + drawer_menu_account_connection_status_connected + "Connecté" + Connecté + + + + drawer_menu_account_connection_status_cleared + "Désactivé" + Désactivé + + + + drawer_menu_account_connection_status_refreshing + "Connexion…" + Connexion… + + + + drawer_menu_account_connection_status_failed + "Erreur" + Erreur + + + + 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. + + + + 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 ? + + + + contact_editor_mandatory_first_name_not_filled + "Veuillez saisir un prénom" + Veuillez saisir un prénom + + + + 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 + + + + contact_details_delete + "Supprimer" + Supprimer + + + + 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 + + + + + phone + "Téléphone" + Téléphone + + + + ContactListItem + + + contact_details_remove_from_favourites + "Enlever des favoris" "Ajouter aux favoris" + Enlever des favoris + + + + contact_details_add_to_favourites + Ajouter aux favoris + + + + Partager + Partager + + + + information_popup_error_title + "La création du fichier vcard a échoué" + Erreur + + + + information_popup_vcard_creation_error + La création du fichier vcard a échoué + + + + information_popup_vcard_creation_title + "VCard créée" "VCard du contact enregistrée dans %1" + VCard créée + + + + information_popup_vcard_creation_success + VCard du contact enregistrée dans %1 + + + + contact_sharing_email_title + "Partage de contact" + Partage de contact + + + + contact_details_delete + "Supprimer" + Supprimer + + + + ContactPage + + + contacts_add + "Ajouter un contact" + Ajouter un contact + + + + contacts_list_empty + "Aucun contact pour le moment" + Aucun contact pour le moment + + + + contact_new_title + "Nouveau contact" + Nouveau contact + + + + create + Créer + + + + contact_edit_title + "Modifier contact" + Modifier contact + + + + save + Enregistrer + + + + contact_dialog_delete_title + Supprimer %1 ?" + Supprimer %1 ? + + + + contact_dialog_delete_message + Ce contact sera définitivement supprimé. + Ce contact sera définitivement supprimé. + + + + contact_deleted_toast + "Contact supprimé" + Contact supprimé + + + + contact_deleted_message + "%1 a été supprimé" + %1 a été supprimé + + + + contact_dialog_devices_trust_popup_title + "Augmenter la confiance" + Augmenter la confiance + + + + contact_dialog_devices_trust_popup_message + "Pour augmenter le niveau de confiance vous devez appeler les différents appareils de votre contact et valider un code.<br><br>Vous êtes sur le point d’appeler “%1” voulez vous continuer ?" + Pour augmenter le niveau de confiance vous devez appeler les différents appareils de votre contact et valider un code.<br><br>Vous êtes sur le point d’appeler “%1” voulez vous continuer ? + + + + popup_do_not_show_again + Ne plus afficher + Ne plus afficher + + + + cancel + Annuler + + + + dialog_call + "Appeler" + Appeler + + + + contact_dialog_devices_trust_help_title + "Niveau de confiance" + Niveau de confiance + + + + contact_dialog_devices_trust_help_message + "Vérifiez les appareils de votre contact pour confirmer que vos communications seront sécurisées et sans compromission. <br>Quand tous seront vérifiés, vous atteindrez le niveau de confiance maximal." + Vérifiez les appareils de votre contact pour confirmer que vos communications seront sécurisées et sans compromission. <br>Quand tous seront vérifiés, vous atteindrez le niveau de confiance maximal. + + + + dialog_ok + "Ok" + Ok + + + + bottom_navigation_contacts_label + "Contacts" + 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 + + + + + contact_details_edit + "Éditer" + Éditer + + + + contact_call_action + "Appel" + Appel + + + + contact_message_action + "Message" + Message + + + + contact_video_call_action + "Appel vidéo" + Appel vidéo + + + + contact_presence_status_online + "En ligne" + En ligne + + + + contact_presence_status_busy + "Occupé" + Occupé + + + + contact_presence_status_do_not_disturb + "Ne pas déranger" + Ne pas déranger + + + + contact_presence_status_offline + "Hors ligne" + Hors ligne + + + + contact_details_numbers_and_addresses_title + "Coordonnées" + Coordonnées + + + + 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 sans nom" + Appareil sans nom + + + + contact_make_call_check_device_trust + "Vérifier" + Vérifier + + + + 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 + + + + ContactsSettingsLayout + + + settings_contacts_ldap_title + Annuaires LDAP + Annuaires LDAP + + + + + "Ajouter vos annuaires LDAP pour pouvoir effectuer des recherches dans la magic search bar." + Ajouter vos annuaires LDAP pour pouvoir effectuer des recherches dans la magic search bar. + + + + settings_contacts_ldap_subtitle + "Ajouter vos annuaires LDAP pour pouvoir effectuer des recherches dans la magic search bar." + fr + + + + settings_contacts_carddav_title + Carnet d'adresse CardDAV + + + + settings_contacts_carddav_subtitle + Ajouter un carnet d’adresse CardDAV pour synchroniser vos contacts Linphone avec un carnet d’adresse tiers. + + + + settings_contacts_add_ldap_server_title + "Ajouter un annuaire LDAP" + Ajouter un annuaire LDAP + + + + settings_contacts_edit_ldap_server_title + "Modifier un annuaire LDAP" + Modifier un annuaire LDAP + + + + 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 + + + + ContactsSettingsProviderLayout + + + information_popup_success_title + "Les changements ont été sauvegardés" + Succès + + + + information_popup_changes_saved + Les changements ont été sauvegardés + + + + add + "Ajouter" + Ajouter + + + + DebugSettingsLayout + + + settings_debug_clean_logs_message + "Les traces de débogage seront supprimées. Souhaitez-vous continuer ?" + Les traces de débogage seront supprimées. Souhaitez-vous continuer ? + + + + settings_debug_share_logs_message + "Les traces de débogage ont été téléversées. Comment souhaitez-vous partager le lien ? " + Les traces de débogage ont été téléversées. Comment souhaitez-vous partager le lien ? + + + + settings_debug_clipboard + "Presse-papier" + Presse-papier + + + + settings_debug_email + "E-Mail" + E-Mail + + + + debug_settings_trace + "Traces %1" + Traces %1 + + + + information_popup_email_sharing_failed + "Le partage par mail a échoué. Veuillez envoyer le lien %1 directement à l'adresse %2." + Le partage par mail a échoué. Veuillez envoyer le lien %1 directement à l'adresse %2. + + + + + information_popup_error_title + Une erreur est survenue. + Une erreur est survenue. + + + + settings_debug_enable_logs_title + "Activer les traces de débogage" + Activer les traces de débogage + + + + settings_debug_enable_full_logs_title + "Activer les traces de débogage intégrales" + Activer les traces de débogage intégrales + + + + settings_debug_delete_logs_title + "Supprimer les traces" + Supprimer les traces + + + + settings_debug_share_logs_title + "Partager les traces" + Partager les traces + + + + settings_debug_share_logs_loading_message + "Téléversement des traces en cours …" + Téléversement des traces en cours… + + + + settings_debug_app_version_title + "Version de l'application" + Version de l'application + + + + settings_debug_sdk_version_title + "Version du SDK" + Version du SDK + + + + settings_debug_share_logs_error + "Le téléversement des traces a échoué. Vous pouvez partager les fichiers de trace directement depuis le répertoire suivant : %1" + Le téléversement des traces a échoué. Vous pouvez partager les fichiers de trace directement depuis le répertoire suivant : %1 + + + + DecoratedTextField + + + textfield_error_message_cannot_be_empty + "ne peut être vide" + ne peut être vide + + + + textfield_error_message_unknown_format + "Format non reconnu" + Format non reconnu + + + + Dialog + + + + dialog_confirm + "Confirmer" "Annuler" + Confirmer + + + + + dialog_cancel + Annuler + + + + EncryptionSettings + + + call_stats_media_encryption_title + "Chiffrement :" + Chiffrement : + + + + call_stats_media_encryption + "Chiffrement du média : %1%2" "ZRTP Post Quantique" + Chiffrement du média : %1%2 + + + + call_stats_zrtp_cipher_algo + "Algorithme de chiffrement : %1" + Algorithme de chiffrement : %1 + + + + call_stats_zrtp_key_agreement_algo + "Algorithme d'accord de clé : %1" + Algorithme d'accord de clé : %1 + + + + call_stats_zrtp_hash_algo + "Algorithme de hachage : %1" + Algorithme de hachage : %1 + + + + call_stats_zrtp_auth_tag_algo + "Algorithme d'authentification : %1" + Algorithme d'authentification : %1 + + + + call_stats_zrtp_sas_algo + "Algorithme SAS : %1" + Algorithme SAS : %1 + + + + call_zrtp_validation_button_label + "Validation chiffrement" + Validation chiffrement + + + + FriendCore + + + sip_address + "Adresse SIP" + Adresse SIP + + + + device_id + "Téléphone" + Téléphone + + + + information_popup_error_title + "Adresse invalide" + Erreur + + + + information_popup_invalid_address_message + Adresse invalide + + + + HelpPage + + + help_title + "Aide" + Aide + + + + + help_about_title + "À propos de %1" + À propos de %1 + + + + help_about_privacy_policy_title + "Règles de confidentialité" + Règles de confidentialité + + + + help_about_privacy_policy_subtitle + Quelles informations %1 collecte et utilise + Quelles informations %1 collecte et utilise + + + + help_about_version_title + "Version" + Version + + + + help_about_gpl_licence_title + "Licences GPLv3" + Licences GPLv3 + + + + help_about_contribute_translations_title + "Contribuer à la traduction de %1" + Contribuer à la traduction de %1 + + + + help_troubleshooting_title + "Dépannage" + Dépannage + + + + 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 + "L'annuaire LDAP a été sauvegardé" + Succès + + + + settings_contacts_ldap_success_toast + L'annuaire LDAP a été sauvegardé + + + + settings_contacts_ldap_error_toast + Erreur + + + + information_popup_error_title + "Une erreur s'est produite, la configuration LDAP n'a pas été sauvegardée !" + 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 ? + + + + 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 + + + + LoadingPopup + + + cancel + Annuler + + + + LoginForm + + + username + "Nom d'utilisateur" : username + Nom d'utilisateur + + + + password + "Mot de passe" + Mot de passe + + + + 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é ? + + + + 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 + + + + LoginPage + + + 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 + + + + default_account_connection_state_error_toast + Erreur durant la connexion + + + + MagicSearchList + + + device_id + Téléphone + + + + MainLayout + + + bottom_navigation_calls_label + "Appels" + Appels + + + + bottom_navigation_contacts_label + "Contacts" + Contacts + + + + bottom_navigation_conversations_label + "Conversations" + Conversations + + + + bottom_navigation_meetings_label + "Réunions" + Réunions + + + + searchbar_placeholder_text + "Rechercher un contact, appeler %1" "ou envoyer un message …" + Rechercher un contact, appeler %1 + + + + searchbar_placeholder_text_chat_feature_enabled + ou envoyer un message … + + + + + 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. + + + + 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 + + + + MainWindow + + + information_popup_connexion_succeed_title + "Connexion réussie" + Connexion réussie + + + + information_popup_connexion_succeed_message + "Vous êtes connecté en mode %1" + Vous êtes connecté en mode %1 + + + + interoperable + interopérable + interopérable + + + + call_transfer_successful_toast_title + "Appel transféré" + Appel transféré + + + + call_transfer_successful_toast_message + "Votre correspondant a été transféré au contact sélectionné" + Votre correspondant a été transféré au contact sélectionné + + + + information_popup_success_title + "Les changements ont été sauvegardés" + Enregistré + + + + information_popup_changes_saved + 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 + + + + MeetingForm + + + meeting_schedule_meeting_label + "Réunion" + Réunion + + + + meeting_schedule_broadcast_label + "Webinar" + Webinar + + + + meeting_schedule_subject_hint + "Ajouter un titre" + Ajouter un titre + + + + meeting_schedule_description_hint + "Ajouter une description" + 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 + + + + MeetingListView + + + meeting_info_cancelled + "Réunion annulée" + Réunion annulée + + + + meetings_list_no_meeting_for_today + "Aucune réunion aujourd'hui" + Aucune réunion aujourd'hui + + + + MeetingPage + + + meetings_add + "Créer une réunion" + Créer une réunion + + + + meetings_list_empty + "Aucune réunion" + Aucune réunion + + + + meeting_schedule_cancel_dialog_message + "Souhaitez-vous annuler et supprimer cette réunion ?" + Souhaitez-vous annuler et supprimer cette réunion ? + + + + meeting_schedule_delete_dialog_message + Souhaitez-vous supprimer cette réunion ? + Souhaitez-vous supprimer cette réunion ? + + + + meeting_schedule_cancel_and_delete_action + "Annuler et supprimer" + Annuler et supprimer + + + + meeting_schedule_delete_only_action + "Supprimer seulement" + Supprimer seulement + + + + meeting_schedule_delete_action + "Supprimer" + Supprimer + + + + back_action + Retour + Retour + + + + meetings_list_title + Réunions + Réunions + + + + meetings_search_hint + "Rechercher une réunion" + Rechercher une réunion + + + + list_filter_no_result_found + "Aucun résultat…" + Aucun résultat… + + + + meetings_empty_list + "Aucune réunion" + Aucune réunion + + + + + meeting_schedule_title + "Nouvelle réunion" + Nouvelle réunion + + + + create + Créer + + + + + + + + + information_popup_error_title + Erreur + + + + + meeting_schedule_mandatory_field_not_filled_toast + Veuillez saisir un titre et sélectionner au moins un participant + Veuillez saisir un titre et sélectionner au moins un participant + + + + + meeting_schedule_duration_error_toast + "La fin de la conférence doit être plus récente que son début" + La fin de la conférence doit être plus récente que son début + + + + meeting_schedule_creation_in_progress + "Création de la réunion en cours …" + Création de la réunion en cours… + + + + meeting_info_created_toast + "Réunion planifiée avec succès" + Réunion planifiée avec succès + + + + meeting_schedule_creation_processing + Création de la réunion en cours… + Création de la réunion en cours… + + + + meeting_failed_to_schedule_toast + "Échec de création de la réunion !" + Échec de création de la réunion ! + + + + save + Enregistrer + + + + + saved + "Enregistré" + Enregistré + + + + meeting_info_updated_toast + "Réunion mise à jour" + Réunion mise à jour + + + + meeting_schedule_edit_in_progress + "Modification de la réunion en cours…" + Modification de la réunion en cours… + + + + meeting_failed_to_edit_toast + "Échec de la modification de la réunion !" + Échec de la modification de la réunion ! + + + + meeting_schedule_add_participants_title + "Ajouter des participants" + Ajouter des participants + + + + add + Ajouter + + + + group_call_participant_selected + "%n participant(s) sélectionné(s)" + %n participant(s) sélectionné(s) + + + + meeting_info_delete + "Supprimer la réunion" + Supprimer la réunion + + + + meeting_address_copied_to_clipboard_toast + "Adresse de la réunion copiée" + Adresse de la réunion copiée + + + + meeting_schedule_timezone_title + "Fuseau horaire" + Fuseau horaire + + + + meeting_info_organizer_label + "Organisateur" + Organisateur + + + + meeting_info_join_title + "Rejoindre la réunion" + Rejoindre la réunion + + + + MeetingsSettingsLayout + + + settings_meetings_display_title + "Affichage" + Affichage + + + + settings_meetings_default_layout_title + "Mode d’affichage par défaut" + Mode d’affichage par défaut + + + + settings_meetings_default_layout_subtitle + "Le mode d’affichage des participants en réunions" + Le mode d’affichage des participants en réunions + + + + MultimediaSettings + + + multimedia_settings_ringer_title + "Sonnerie - Appels entrants" + Sonnerie - Appels entrants + + + + multimedia_settings_speaker_title + "Haut-parleurs" + Haut-parleurs + + + + multimedia_settings_microphone_title + "Microphone" + Microphone + + + + multimedia_settings_camera_title + "Caméra" + Caméra + + + + NetworkSettingsLayout + + + settings_network_title + "Réseau" + Réseau + + + + settings_network_allow_ipv6 + "Autoriser l'IPv6" + Autoriser l'IPv6 + + + + NewCallForm + + + call_transfer_active_calls_label + "Appels en cours" + Appels en cours + + + + search_bar_look_for_contact_text + "Rechercher un contact" + Rechercher un contact + + + + NotificationReceivedCall + + + call_audio_incoming + "Appel entrant" + Appel entrant + + + + dialog_accept + "Accepter" + Accepter + + + + dialog_deny + "Refuser + Refuser + + + + ParticipantListView + + + meeting_participant_is_admin_label + "Admin" + Admin + + + + meeting_add_participants_title + "Ajouter des participants" + Ajouter des participants + + + + QObject + + + DTLS + DTLS + + + + None + None + + + + SRTP + SRTP + + + + media_encryption_post_quantum + "ZRTP - Post quantique" + ZRTP - Post quantique + + + + incoming + "Entrant" + Entrant + + + + outgoing + "Sortant" + Sortant + + + + conference_layout_active_speaker + "Participant actif" + Intervenant actif + + + + conference_layout_grid + "Mosaïque" + Mosaïque + + + + conference_layout_audio_only + "Audio uniquement" + Audio uniquement + + + + RegisterCheckingPage + + + email + "email" + email + + + + phone_number + "numéro de téléphone" + numéro de téléphone + + + + confirm_register_title + "Inscription | Confirmer votre %1" + Inscription | Confirmer votre %1 + + + + assistant_account_creation_confirmation_explanation + Nous vous avons envoyé un code de vérification sur votre %1 %2<br> Merci de le saisir ci-dessous + Nous vous avons envoyé un code de vérification sur votre %1 %2<br> Merci de le saisir ci-dessous + + + + assistant_account_creation_confirmation_did_not_receive_code + "Vous n'avez pas reçu le code ?" + Vous n'avez pas reçu le code ? + + + + assistant_account_creation_confirmation_resend_code + "Renvoyer un code" + Renvoyer un code + + + + RegisterPage + + + 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 + + + + + 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 + + + + SIPLoginPage + + + 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. + +Pour les activer dans un projet commercial, merci de nous contacter. + 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. + +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 + + + + 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 + + + + ScreencastSettings + + + screencast_settings_choose_window_text + "Veuillez choisir l’écran ou la fenêtre que vous souihaitez partager au autres participants" + Veuillez choisir l’écran ou la fenêtre que vous souihaitez partager au autres participants + + + + screencast_settings_all_screen_label + "Ecran entier" + Écran entier + + + + screencast_settings_one_window_label + "Fenêtre" + Fenêtre + + + + screencast_settings_screen + "Ecran %1" + Écran %1 + + + + stop + "Stop + Stop + + + + share + "Partager" + Partager + + + + SecurityModePage + + + manage_account_choose_mode_title + "Choisir votre mode" + Choisir votre mode + + + + manage_account_choose_mode_message + "Vous pourrez changer de mode plus tard." + Vous pourrez changer de mode plus tard. + + + + manage_account_e2e_encrypted_mode_default_title + "Chiffrement de bout en bout" + Chiffrement de bout en bout + + + + manage_account_e2e_encrypted_mode_default_summary + "Ce mode vous garanti la confidentialité de tous vos échanges. Notre technologie de chiffrement de bout en bout assure un niveau de sécurité maximal pour tous vos échanges." + Ce mode vous garanti la confidentialité de tous vos échanges. Notre technologie de chiffrement de bout en bout assure un niveau de sécurité maximal pour tous vos échanges. + + + + manage_account_e2e_encrypted_mode_interoperable_title + "Interoperable" + Interopérable + + + + manage_account_e2e_encrypted_mode_interoperable_summary + "Ce mode vous permet de profiter de toute les fonctionnalités de Linphone, toute en restant interopérable avec n’importe qu’elle autre service SIP." + Ce mode vous permet de profiter de toute les fonctionnalités de Linphone, toute en restant interopérable avec n’importe qu’elle autre service SIP. + + + + dialog_continue + "Continuer" + Continuer + + + + SecuritySettingsLayout + + + settings_security_enable_vfs_title + "Chiffrer tous les fichiers" + Chiffrer tous les fichiers + + + + settings_security_enable_vfs_subtitle + "Attention, vous ne pourrez pas revenir en arrière !" + Attention, vous ne pourrez pas revenir en arrière ! + + + + SettingsPage + + + settings_title + "Paramètres" + Paramètres + + + + settings_calls_title + "Appels" + Appels + + + + settings_conversations_title + "Conversations" + Conversations + + + + settings_contacts_title + "Contacts" + Contacts + + + + settings_meetings_title + "Réunions" + Réunions + + + + settings_network_title + "Affichage" "Réseau" + Réseau + + + + settings_advanced_title + "Paramètres avancés" + Paramètres avancés + + + + contact_editor_popup_abort_confirmation_title + Modifications non enregistrées + Modifications non enregistrées + + + + contact_editor_popup_abort_confirmation_message + Vous avez des modifications non enregistrées. Si vous quittez cette page, vos changements seront perdus. Voulez-vous enregistrer vos modifications avant de continuer ? + Vous avez des modifications non enregistrées. Si vous quittez cette page, vos changements seront perdus. Voulez-vous enregistrer vos modifications avant de continuer ? + + + + contact_editor_dialog_abort_confirmation_do_not_save + "Ne pas enregistrer" + Ne pas enregistrer + + + + contact_editor_dialog_abort_confirmation_save + "Enregistrer" + Enregistrer + + + + Sticker + + + conference_participant_joining_text + "rejoint…" + rejoint… + + + + conference_participant_paused_text + "En pause" + En pause + + + + ToolModel + + + call_error_uninterpretable_sip_address + "The calling address is not an interpretable SIP address : %1 + L'adresse n'est pas interprétable comme une adresse SIP + + + + unknown_audio_device_name + Appareil inconnu + + + + Utils + + + information_popup_call_not_created_message + "L'appel n'a pas pu être créé" + L'appel n'a pas pu être créé + + + + number_of_years + %n an(s) + + un an + %n ans + + + + + number_of_month + "%n mois" + + un mois + %n mois + + + + + number_of_weeks + %n semaine(s) + + une semaine + %n semaines + + + + + number_of_days + %n jour(s) + + un jour + %n jours + + + + + today + "Aujourd'hui" + Aujourd'hui + + + + yesterday + "Hier + Hier + + + + call_zrtp_token_verification_possible_characters + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 + + + + WaitingRoom + + + meeting_waiting_room_title + Participer à : + Participer à : + + + + meeting_waiting_room_join + "Rejoindre" + Rejoindre + + + + + cancel + Annuler + + + + meeting_waiting_room_joining_title + "Connexion à la réunion" + Connexion à la réunion + + + + meeting_waiting_room_joining_subtitle + "Vous allez rejoindre la réunion dans quelques instants…" + Vous allez rejoindre la réunion dans quelques instants… + + + + WelcomePage + + + welcome_page_title + "Bienvenue" + Bienvenue + + + + welcome_page_subtitle + "sur %1" + sur %1 + + + + welcome_carousel_skip + "Passer" + Passer + + + + welcome_page_1_message + "Une application de communication <b>sécurisée</b>,<br> <b>open source</b> et <b>française</b>." + Une application de communication <b>sécurisée</b>,<br> <b>open source</b> et <b>française</b>. + + + + welcome_page_2_title + "Sécurisé" + Sécurisé + + + + welcome_page_2_message + "Vos communications sont en sécurité grâce aux <br><b>Chiffrement de bout en bout</b>." + Vos communications sont en sécurité grâce aux <br><b>Chiffrement de bout en bout</b>. + + + + welcome_page_3_title + "Open Source" + Open Source + + + + welcome_page_3_message + "Une application open source et un <b>service gratuit</b> <br>depuis <b>2001</b>" + Une application open source et un <b>service gratuit</b> <br>depuis <b>2001</b> + + + + next + "Suivant" + Suivant + + + + start + "Commencer" + Commencer + + + + ZrtpAuthenticationDialog + + + call_dialog_zrtp_validate_trust_title + Vérification de sécurité + Vérification de sécurité + + + + call_zrtp_sas_validation_skip + "Passer" + Passer + + + + call_dialog_zrtp_validate_trust_warning_message + "Pour garantir le chiffrement, nous avons besoin de réauthentifier l’appareil de votre correspondant. Echangez vos codes :" + Pour garantir le chiffrement, nous avons besoin de réauthentifier l’appareil de votre correspondant. Echangez vos codes : + + + + call_dialog_zrtp_validate_trust_message + "Pour garantir le chiffrement, nous avons besoin d’authentifier l’appareil de votre correspondant. Veuillez échanger vos codes : " + Pour garantir le chiffrement, nous avons besoin d’authentifier l’appareil de votre correspondant. Veuillez échanger vos codes : + + + + call_dialog_zrtp_validate_trust_local_code_label + "Votre code :" + Votre code : + + + + call_dialog_zrtp_validate_trust_remote_code_label + "Code correspondant :" + Code correspondant : + + + + call_dialog_zrtp_validate_trust_letters_do_not_match_text + "Le code fourni ne correspond pas." + Le code fourni ne correspond pas. + + + + call_dialog_zrtp_security_alert_message + "La confidentialité de votre appel peut être compromise !" + La confidentialité de votre appel peut être compromise ! + + + + call_dialog_zrtp_validate_trust_letters_do_not_match + "Aucune correspondance" + Aucune correspondance + + + + call_action_hang_up + "Raccrocher" + Raccrocher + + + + country + + + Afghanistan + Afghanistan + + + + Albania + Albanie + + + + Algeria + Algérie + + + + AmericanSamoa + Samoa américaines + + + + Andorra + Andorre + + + + Angola + Angola + + + + Anguilla + Anguilla + + + + AntiguaAndBarbuda + Antigua-et-Barbuda + + + + Argentina + Argentine + + + + Armenia + Arménie + + + + Aruba + Aruba + + + + Australia + Australie + + + + Austria + Autriche + + + + Azerbaijan + Azerbaïdjan + + + + Bahamas + Bahamas + + + + Bahrain + Bahreïn + + + + Bangladesh + Bangladesh + + + + Barbados + Barbade + + + + Belarus + Biélorussie + + + + Belgium + Belgique + + + + Belize + Belize + + + + Benin + Bénin + + + + Bermuda + Bermudes + + + + Bhutan + Bhoutan + + + + Bolivia + Bolivie + + + + BosniaAndHerzegowina + Bosnie-Herzégovine + + + + Botswana + Botswana + + + + Brazil + Brésil + + + + Brunei + Brunéi + + + + Bulgaria + Bulgarie + + + + BurkinaFaso + Burkina Faso + + + + Burundi + Burundi + + + + Cambodia + Cambodge + + + + Cameroon + Cameroun + + + + Canada + Canada + + + + CapeVerde + Cap-Vert + + + + CaymanIslands + Îles Caïmans + + + + CentralAfricanRepublic + République centrafricaine + + + + Chad + Tchad + + + + Chile + Chili + + + + China + Chine + + + + Colombia + Colombie + + + + Comoros + Comores + + + + PeoplesRepublicOfCongo + fr + + + République démocratique du Congo + fr + + + + CookIslands + Îles Cook + + + + CostaRica + Costa Rica + + + + IvoryCoast + Côte d'Ivoire + + + + Croatia + Croatie + + + + Cuba + Cuba + + + + Cyprus + Chypre + + + + CzechRepublic + République Tchèque + + + + Denmark + Danemark + + + + Djibouti + Djibouti + + + + Dominica + Dominique + + + + DominicanRepublic + République dominicaine + + + + Ecuador + Équateur + + + + Egypt + Égypte + + + + ElSalvador + El Salvador + + + + EquatorialGuinea + Guinée équatoriale + + + + Eritrea + Érythrée + + + + Estonia + Estonie + + + + Ethiopia + Éthiopie + + + + FalklandIslands + Îles Falkland + + + + FaroeIslands + Îles Féroé + + + + Fiji + Fidji + + + + Finland + Finlande + + + + France + France + + + + FrenchGuiana + Guyane française + + + + FrenchPolynesia + Polynésie française + + + + Gabon + Gabon + + + + Gambia + Gambie + + + + Georgia + Géorgie + + + + Germany + Allemagne + + + + Ghana + Ghana + + + + Gibraltar + Gibraltar + + + + Greece + Grèce + + + + Greenland + Groenland + + + + Grenada + Grenade + + + + Guadeloupe + Guadeloupe + + + + Guam + Guam + + + + Guatemala + Guatemala + + + + Guinea + Guinée + + + + GuineaBissau + Guinée-Bissau + + + + Guyana + Guyana + + + + Haiti + Haïti + + + + Honduras + Honduras + + + Hong Kong + HongKong + + + + DemocraticRepublicOfCongo + + + + + HongKong + + + + + Hungary + Hongrie + + + + Iceland + Islande + + + + India + Inde + + + + Indonesia + Indonésie + + + + Iran + Iran + + + + Iraq + Irak + + + + Ireland + Irlande + + + + Israel + Israël + + + + Italy + Italie + + + + Jamaica + Jamaïque + + + + Japan + Japon + + + + Jordan + Jordanie + + + + Kazakhstan + Kazakhstan + + + + Kenya + Kenya + + + + Kiribati + Kiribati + + + + DemocraticRepublicOfKorea + Corée du Nord + + + + RepublicOfKorea + Corée du Sud + + + + Kuwait + Koweït + + + + Kyrgyzstan + Kirghizistan + + + + Laos + Laos + + + + Latvia + Lettonie + + + + Lebanon + Liban + + + + Lesotho + Lesotho + + + + Liberia + Libéria + + + + Libya + Libye + + + + Liechtenstein + Liechtenstein + + + + Lithuania + Lituanie + + + + Luxembourg + Luxembourg + + + + Macau + Macao + + + + Macedonia + Macédoine + + + + Madagascar + Madagascar + + + + Malawi + Malawi + + + + Malaysia + Malaisie + + + + Maldives + Maldives + + + + Mali + Mali + + + + Malta + Malte + + + + MarshallIslands + Îles Marshall + + + + Martinique + Martinique + + + + Mauritania + Mauritanie + + + + Mauritius + Maurice + + + + Mayotte + Mayotte + + + + Mexico + Mexique + + + + Micronesia + Micronésie + + + + Moldova + Moldavie + + + + Monaco + Monaco + + + + Mongolia + Mongolie + + + + Montenegro + Montenegro + + + + Montserrat + Montserrat + + + + Morocco + Maroc + + + + Mozambique + Mozambique + + + + Myanmar + Myanmar + + + + Namibia + Namibie + + + + NauruCountry + Nauru + + + + Nepal + Népal + + + + Netherlands + Pays-Bas + + + + NewCaledonia + Nouvelle-Calédonie + + + + NewZealand + Nouvelle-Zélande + + + + Nicaragua + Nicaragua + + + + Niger + Niger + + + + Nigeria + Nigeria + + + + Niue + Niué + + + + NorfolkIsland + Île Norfolk + + + + NorthernMarianaIslands + Îles Mariannes du Nord + + + + Norway + Norvège + + + + Oman + Oman + + + + Pakistan + Pakistan + + + + Palau + Palaos + + + + PalestinianTerritories + Palestine + + + + Panama + Panama + + + + PapuaNewGuinea + Papouasie-Nouvelle-Guinée + + + + Paraguay + Paraguay + + + + Peru + Pérou + + + + Philippines + Philippines + + + + Poland + Pologne + + + + Portugal + Portugal + + + + PuertoRico + Porto Rico + + + + Qatar + Qatar + + + + Reunion + La Réunion + + + + Romania + Roumanie + + + + RussianFederation + Russie + + + + Rwanda + Rwanda + + + + SaintHelena + Sainte-Hélène + + + + SaintKittsAndNevis + Saint-Christophe-et-Niévès + + + + SaintLucia + Sainte-Lucie + + + + SaintPierreAndMiquelon + Saint-Pierre-et-Miquelon + + + + SaintVincentAndTheGrenadines + Saint-Vincent et les Grenadines + + + + Samoa + Samoa + + + + SanMarino + Saint-Marin + + + + SaoTomeAndPrincipe + Sao Tomé-et-Principe + + + + SaudiArabia + Arabie saoudite + + + + Senegal + Sénégal + + + + Serbia + Serbie + + + + Seychelles + Seychelles + + + + SierraLeone + Sierra Leone + + + + Singapore + Singapour + + + + Slovakia + Slovaquie + + + + Slovenia + Slovénie + + + + SolomonIslands + Îles Salomon + + + + Somalia + Somalie + + + + SouthAfrica + Afrique du Sud + + + + Spain + Espagne + + + + SriLanka + Sri Lanka + + + + Sudan + Soudan + + + + Suriname + Suriname + + + + Swaziland + Eswatini + + + + Sweden + Suède + + + + Switzerland + Suisse + + + + Syria + Syrie + + + + Taiwan + Taïwan + + + + Tajikistan + Tadjikistan + + + + Tanzania + Tanzanie + + + + Thailand + Thaïlande + + + + Togo + Togo + + + + Tokelau + Tokelau + + + + Tonga + Tonga + + + + TrinidadAndTobago + Trinité-et-Tobago + + + + Tunisia + Tunisie + + + + Turkey + Turquie + + + + Turkmenistan + Turkménistan + + + + TurksAndCaicosIslands + Îles Turks et Caïques + + + + Tuvalu + Tuvalu + + + + Uganda + Ouganda + + + + Ukraine + Ukraine + + + + UnitedArabEmirates + Émirats arabes unis + + + + UnitedKingdom + Royaume-Uni + + + + UnitedStates + États-Unis + + + + Uruguay + Uruguay + + + + Uzbekistan + Ouzbékistan + + + + Vanuatu + Vanuatu + + + + Venezuela + Venezuela + + + + Vietnam + Vietnam + + + + WallisAndFutunaIslands + Wallis et Futuna + + + + Yemen + Yémen + + + + Zambia + Zambie + + + + Zimbabwe + Zimbabwe + + + + utils + + + formatYears + '%1 year' + + un an + %1 ans + + + + + formatMonths + '%1 month' + + un mois + %1 mois + + + + + formatWeeks + '%1 week' + + une semaine + %1 semaines + + + + + formatDays + '%1 day' + + un jour + %1 jours + + + + + formatHours + '%1 hour' + + une heure + %1 heures + + + + + formatMinutes + '%1 minute' + + une minute + %1 minutes + + + + + formatSeconds + '%1 second' + + une seconde + %1 secondes + + + + + 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/model/account/AccountManager.cpp b/Linphone/model/account/AccountManager.cpp index 17f8ebaaf..34630e260 100644 --- a/Linphone/model/account/AccountManager.cpp +++ b/Linphone/model/account/AccountManager.cpp @@ -80,7 +80,8 @@ bool AccountManager::login(QString username, auto otherParams = otherAccount->getParams(); if (otherParams->getIdentityAddress()->getUsername() == Utils::appStringToCoreString(username) && otherParams->getDomain() == Utils::appStringToCoreString(domain)) { - *errorMessage = tr("Le compte est déjà connecté"); + //: "Le compte est déjà connecté" + *errorMessage = tr("assistant_account_login_already_connected_error"); return false; } } @@ -93,7 +94,8 @@ bool AccountManager::login(QString username, auto serverAddress = factory->createAddress(Utils::appStringToCoreString(QStringLiteral("sip:%1").arg(domain))); if (!serverAddress) { - *errorMessage = tr("Impossible de créer l'adresse proxy. Merci de vérifier le nom de domaine."); + //: "Impossible de créer l'adresse proxy. Merci de vérifier le nom de domaine." + *errorMessage = tr("assistant_account_login_proxy_address_error"); return false; } serverAddress->setTransport(transportType); @@ -104,13 +106,17 @@ bool AccountManager::login(QString username, qWarning() << log() .arg(QStringLiteral("Unable to set identity address: `%1`.")) .arg(Utils::coreStringToAppString(identity->asStringUriOnly())); + + + //: "Impossible de configurer l'adresse : `%1`." *errorMessage = - tr("Impossible de configurer l'adresse : `%1`.").arg(Utils::coreStringToAppString(identity->asStringUriOnly())); + tr("assistant_account_login_address_configuration_error").arg(Utils::coreStringToAppString(identity->asStringUriOnly())); return false; } if (account->setParams(params)) { - *errorMessage = tr("Impossible de configurer les paramètres du compte."); + //: "Impossible de configurer les paramètres du compte." + *errorMessage = tr("assistant_account_login_params_configuration_error"); return false; } auto authInfo = factory->createAuthInfo(Utils::appStringToCoreString(username), // Username. @@ -132,8 +138,10 @@ bool AccountManager::login(QString username, connect( mAccountModel.get(), &AccountModel::removed, this, [this]() { mAccountModel = nullptr; }, Qt::SingleShotConnection); - if (account->getError() == linphone::Reason::Forbidden) errorMessage = tr("Le couple identifiant mot de passe ne correspond pas"); - else errorMessage = tr("Erreur durant la connexion"); + //: "Le couple identifiant mot de passe ne correspond pas" + if (account->getError() == linphone::Reason::Forbidden) errorMessage = tr("assistant_account_login_forbidden_error"); + //: "Erreur durant la connexion" + else errorMessage = tr("assistant_account_login_error"); mAccountModel->removeAccount(); } else if (state == linphone::RegistrationState::Ok) { core->setDefaultAccount(account); @@ -145,7 +153,8 @@ bool AccountManager::login(QString username, }); auto status = core->addAccount(account); if (status == -1) { - *errorMessage = tr("Impossible d'ajouter le compte."); + //: "Impossible d'ajouter le compte." + *errorMessage = tr("assistant_account_add_error"); core->removeAuthInfo(authInfo); return false; } diff --git a/Linphone/model/call/CallModel.cpp b/Linphone/model/call/CallModel.cpp index ef75d1c89..196af199a 100644 --- a/Linphone/model/call/CallModel.cpp +++ b/Linphone/model/call/CallModel.cpp @@ -334,16 +334,32 @@ void CallModel::updateCallErrorFromReason(linphone::Reason reason) { QString error; switch (reason) { case linphone::Reason::Declined: - error = tr("Le correspondant a décliné l'appel"); + //: "Le correspondant a décliné l'appel" + error = tr("call_error_user_declined_toast"); break; case linphone::Reason::NotFound: - error = tr("Le correspondant n'a pas été trouvé"); + //: "Le correspondant n'a pas été trouvé" + error = tr("call_error_user_not_found_toast"); break; case linphone::Reason::Busy: - error = tr("Le correspondant est occupé"); + //: "Le correspondant est occupé" + error = tr("call_error_user_busy_toast"); break; case linphone::Reason::NotAcceptable: - error = tr("Le correspondant ne peut accepter votre appel."); + //: "Le correspondant ne peut accepter votre appel." + error = tr("call_error_incompatible_media_params_toast"); + break; + case linphone::Reason::IOError: + //: "Service indisponible ou erreur réseau" + error = tr("call_error_io_error_toast"); + break; + case linphone::Reason::TemporarilyUnavailable: + //: "Temporairement indisponible" + error = tr("call_error_temporarily_unavailable_toast"); + break; + case linphone::Reason::ServerTimeout: + //: "Délai d'attente du serveur dépassé" + error = tr("call_error_server_timeout_toast"); break; default: break; diff --git a/Linphone/model/cli/CliModel.cpp b/Linphone/model/cli/CliModel.cpp index c39d5a91b..813a26f42 100644 --- a/Linphone/model/cli/CliModel.cpp +++ b/Linphone/model/cli/CliModel.cpp @@ -36,12 +36,12 @@ DEFINE_ABSTRACT_OBJECT(CliModel) std::shared_ptr CliModel::gCliModel; QMap CliModel::mCommands{ - createCommand("show", QT_TR_NOOP("showFunctionDescription"), &CliModel::cliShow, {}, true), - createCommand("fetch-config", QT_TR_NOOP("fetchConfigFunctionDescription"), &CliModel::cliFetchConfig, {}, true), - createCommand("call", QT_TR_NOOP("callFunctionDescription"), &CliModel::cliCall, {{"sip-address", {}}}, true), - createCommand("bye", QT_TR_NOOP("byeFunctionDescription"), &CliModel::cliBye, {}, true), - createCommand("accept", QT_TR_NOOP("acceptFunctionDescription"), &CliModel::cliAccept, {}, true), - createCommand("decline", QT_TR_NOOP("declineFunctionDescription"), &CliModel::cliDecline, {}, true), + createCommand("show", QT_TR_NOOP("show_function_description"), &CliModel::cliShow, {}, true), + createCommand("fetch-config", QT_TR_NOOP("fetch_config_function_description"), &CliModel::cliFetchConfig, {}, true), + createCommand("call", QT_TR_NOOP("call_function_description"), &CliModel::cliCall, {{"sip-address", {}}}, true), + createCommand("bye", QT_TR_NOOP("bye_function_description"), &CliModel::cliBye, {}, true), + createCommand("accept", QT_TR_NOOP("accept_function_description"), &CliModel::cliAccept, {}, true), + createCommand("decline", QT_TR_NOOP("decline_function_description"), &CliModel::cliDecline, {}, true), /* createCommand("initiate-conference", QT_TR_NOOP("initiateConferenceFunctionDescription"), cliInitiateConference, { { "sip-address", {} }, { "conference-id", {} } @@ -344,7 +344,7 @@ void CliModel::executeCommand(const QString &command) { //, CommandFormat *forma const QString &functionName = parseFunctionName(command, false); const QString configURI = QString(EXECUTABLE_NAME).toLower() + "-config"; if (!functionName.isEmpty()) { // It is a CLI - qInfo() << QStringLiteral("Detecting cli command: `%1`...").arg(command); + qInfo() << QStringLiteral("Detecting cli command: `%1`…").arg(command); QHash args = parseArgs(command); QHash argsToProcess; for (auto it = args.begin(); it != args.end(); ++it) { @@ -410,7 +410,7 @@ void CliModel::executeCommand(const QString &command) { //, CommandFormat *forma address = linphone::Factory::get()->createAddress( Utils::appStringToCoreString(transformedCommand)); // Test if command is an address // if (format) *format = UriFormat; - qInfo() << QStringLiteral("Detecting URI command: `%1`...").arg(command); + qInfo() << QStringLiteral("Detecting URI command: `%1`…").arg(command); QString functionName; if (address) { functionName = Utils::coreStringToAppString(address->getHeader("method")).isEmpty() diff --git a/Linphone/model/tool/ToolModel.cpp b/Linphone/model/tool/ToolModel.cpp index 73aec9fca..90839d692 100644 --- a/Linphone/model/tool/ToolModel.cpp +++ b/Linphone/model/tool/ToolModel.cpp @@ -158,7 +158,8 @@ bool ToolModel::createCall(const QString &sipAddress, lCritical() << "[" + QString(gClassName) + "] The calling address is not an interpretable SIP address: " << sipAddress; if (errorMessage) { - *errorMessage = tr("The calling address is not an interpretable SIP address : %1").arg(sipAddress); + //: "The calling address is not an interpretable SIP address : %1 + *errorMessage = tr("call_error_uninterpretable_sip_address").arg(sipAddress); } return false; } @@ -166,7 +167,7 @@ bool ToolModel::createCall(const QString &sipAddress, if (isConference) mediaEncryption = linphone::MediaEncryption::ZRTP; if (SettingsModel::dndEnabled( - core->getConfig())) { // Force tones for outgoing calls when in DND mode (ringback, dtmf, etc ... ) disabled + core->getConfig())) { // Force tones for outgoing calls when in DND mode (ringback, dtmf, etc … ) disabled // again when no more calls are running. SettingsModel::getInstance()->setCallToneIndicationsEnabled(true); } @@ -313,17 +314,17 @@ bool ToolModel::friendIsInFriendList(const std::shared_ptr void ToolModel::loadDownloadedCodecs() { mustBeInLinphoneThread(sLog().arg(Q_FUNC_INFO)); #if defined(Q_OS_LINUX) || defined(Q_OS_WIN) - qInfo() << QStringLiteral("Loading downloaded codecs in folder %1...").arg(Paths::getCodecsDirPath()); + qInfo() << QStringLiteral("Loading downloaded codecs in folder %1…").arg(Paths::getCodecsDirPath()); QDirIterator it(Paths::getCodecsDirPath()); while (it.hasNext()) { QFileInfo info(it.next()); const QString filename(info.fileName()); if (QLibrary::isLibrary(filename)) { - qInfo() << QStringLiteral("Loading `%1` symbols...").arg(filename); + qInfo() << QStringLiteral("Loading `%1` symbols…").arg(filename); auto library = QLibrary(info.filePath()); if (!library.load()) // lib.load()) qWarning() << QStringLiteral("Failed to load `%1` symbols.").arg(filename) << library.errorString(); - else qInfo() << QStringLiteral("Loaded `%1` symbols...").arg(filename); + else qInfo() << QStringLiteral("Loaded `%1` symbols…").arg(filename); } else qWarning() << QStringLiteral("Found codec file `%1` that is not a library").arg(filename); } CoreModel::getInstance()->getCore()->reloadMsPlugins(""); @@ -360,7 +361,8 @@ QVariantMap ToolModel::createVariant(const std::shared_ptrgetId()) : ""); map.insert("display_name", device ? Utils::coreStringToAppString(device->getDriverName() + ": " + device->getDeviceName()) - : tr("Unknown device")); + //: "Unknown device" + : tr("unknown_audio_device_name")); return map; } diff --git a/Linphone/tool/Constants.hpp b/Linphone/tool/Constants.hpp index 309eb3a89..b277a5841 100644 --- a/Linphone/tool/Constants.hpp +++ b/Linphone/tool/Constants.hpp @@ -156,7 +156,7 @@ public: static constexpr char PathMessageHistoryList[] = "/message-history.db"; static constexpr char PathZrtpSecrets[] = "/zidcache"; - static constexpr char LanguagePath[] = ":/languages/"; + static constexpr char LanguagePath[] = ":/data/languages/"; // The main windows of Linphone desktop. static constexpr char QmlViewMainWindow[] = "qrc:/qt/qml/Linphone/view/Page/Window/Main/MainWindow.qml"; diff --git a/Linphone/tool/LinphoneEnums.cpp b/Linphone/tool/LinphoneEnums.cpp index 39625f664..f40030bc7 100644 --- a/Linphone/tool/LinphoneEnums.cpp +++ b/Linphone/tool/LinphoneEnums.cpp @@ -63,7 +63,8 @@ QString LinphoneEnums::toString(LinphoneEnums::MediaEncryption encryption) { case LinphoneEnums::MediaEncryption::Srtp: return QObject::tr("SRTP"); case LinphoneEnums::MediaEncryption::Zrtp: - return QObject::tr("ZRTP - Post quantique"); + //: "ZRTP - Post quantique" + return QObject::tr("media_encryption_post_quantum"); default: return QString(); } @@ -177,9 +178,11 @@ linphone::Call::Dir LinphoneEnums::toLinphone(const LinphoneEnums::CallDir &data QString LinphoneEnums::toString(const LinphoneEnums::CallDir &data) { switch (data) { case LinphoneEnums::CallDir::Incoming: - return QObject::tr("Entrant"); + //: "Entrant" + return QObject::tr("incoming"); case LinphoneEnums::CallDir::Outgoing: - return QObject::tr("Sortant"); + //: "Sortant" + return QObject::tr("outgoing"); default: return QString(); } @@ -203,9 +206,12 @@ LinphoneEnums::ConferenceLayout LinphoneEnums::fromLinphone(const linphone::Conf } QString LinphoneEnums::toString(LinphoneEnums::ConferenceLayout layout) { - if (layout == LinphoneEnums::ConferenceLayout::ActiveSpeaker) return QObject::tr("Participant actif"); - else if (layout == LinphoneEnums::ConferenceLayout::Grid) return QObject::tr("Grille"); - else return QObject::tr("Audio seulement"); + //: "Participant actif" + if (layout == LinphoneEnums::ConferenceLayout::ActiveSpeaker) return QObject::tr("conference_layout_active_speaker"); + //: "Mosaïque" + else if (layout == LinphoneEnums::ConferenceLayout::Grid) return QObject::tr("conference_layout_grid"); + //: "Audio uniquement" + else return QObject::tr("conference_layout_audio_only"); } QVariantList LinphoneEnums::conferenceLayoutsToVariant(QList list) { diff --git a/Linphone/tool/Utils.cpp b/Linphone/tool/Utils.cpp index 1d7618e81..53be978ba 100644 --- a/Linphone/tool/Utils.cpp +++ b/Linphone/tool/Utils.cpp @@ -147,8 +147,9 @@ void Utils::createCall(const QString &sipAddress, bool success = ToolModel::createCall(sipAddress, options, prepareTransfertAddress, headers, LinphoneEnums::toLinphone(mediaEncryption), &errorMessage); if (!success) { - if (errorMessage.isEmpty()) errorMessage = tr("L'appel n'a pas pu être créé"); - showInformationPopup("Erreur", errorMessage, false); + //: "L'appel n'a pas pu être créé" + if (errorMessage.isEmpty()) errorMessage = tr("information_popup_call_not_created_message"); + showInformationPopup("information_popup_error_title", errorMessage, false); } }); } @@ -265,13 +266,17 @@ QString Utils::formatElapsedTime(int seconds, bool dotsSeparator) { // s, m, h, d, W, M, Y // 1, 60, 3600, 86400, 604800, 2592000, 31104000 auto y = floor(seconds / 31104000); - if (y > 0) return tr("%n year(s)", "", y); + //: %n an(s) + if (y > 0) return tr("number_of_years", "", y); auto M = floor(seconds / 2592000); - if (M > 0) return tr("%n month(s)", "", M); + //: "%n mois" + if (M > 0) return tr("number_of_month", "", M); auto w = floor(seconds / 604800); - if (w > 0) return tr("%n week(s)", "", w); + //: %n semaine(s) + if (w > 0) return tr("number_of_weeks", "", w); auto d = floor(seconds / 86400); - if (d > 0) return tr("%n day(s)", "", d); + //: %n jour(s) + if (d > 0) return tr("number_of_days", "", d); auto h = floor(seconds / 3600); auto m = floor((seconds - h * 3600) / 60); @@ -294,8 +299,10 @@ QString Utils::formatElapsedTime(int seconds, bool dotsSeparator) { QString Utils::formatDate(const QDateTime &date, bool includeTime) { QString dateDay; - if (date.date() == QDate::currentDate()) dateDay = tr("Aujourd'hui"); - else if (date.date() == QDate::currentDate().addDays(-1)) dateDay = tr("Hier"); + //: "Aujourd'hui" + if (date.date() == QDate::currentDate()) dateDay = tr("today"); + //: "Hier + else if (date.date() == QDate::currentDate().addDays(-1)) dateDay = tr("yesterday"); else { QString format = date.date().year() == QDateTime::currentDateTime(date.timeZone()).date().year() ? "dd MMMM" @@ -436,7 +443,8 @@ QString Utils::generateSavedFilename(const QString &from, const QString &to) { QStringList Utils::generateSecurityLettersArray(int arraySize, int correctIndex, QString correctCode) { QStringList vec; - const QString possibleCharacters(tr("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")); + //: "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + const QString possibleCharacters(tr("call_zrtp_token_verification_possible_characters")); const int n = 2; for (int i = 0; i < arraySize; ++i) { QString randomString; diff --git a/Linphone/tool/Utils.hpp b/Linphone/tool/Utils.hpp index afd7dd5c7..648b76f42 100644 --- a/Linphone/tool/Utils.hpp +++ b/Linphone/tool/Utils.hpp @@ -137,6 +137,8 @@ public: Q_INVOKABLE static QString getFileChecksum(const QString &filePath); Q_INVOKABLE QList append(const QList a, const QList b); +// QDir findDirectoryByName(QString startPath, QString name); + static QString getApplicationProduct(); static QString getOsProduct(); diff --git a/Linphone/view/Control/Button/ComboBox.qml b/Linphone/view/Control/Button/ComboBox.qml index 0c9d45908..c60a78dfd 100644 --- a/Linphone/view/Control/Button/ComboBox.qml +++ b/Linphone/view/Control/Button/ComboBox.qml @@ -6,7 +6,7 @@ import Linphone Control.ComboBox { id: mainItem - // Usage : each item of the model list must be {text: ..., img: ...} + // 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 diff --git a/Linphone/view/Control/Container/Call/CallHistoryLayout.qml b/Linphone/view/Control/Container/Call/CallHistoryLayout.qml index f9eb6460c..41f597628 100644 --- a/Linphone/view/Control/Container/Call/CallHistoryLayout.qml +++ b/Linphone/view/Control/Container/Call/CallHistoryLayout.qml @@ -127,12 +127,16 @@ ColumnLayout { Layout.fillWidth: true visible: mainItem.contact text: mode === LinphoneEnums.ConsolidatedPresence.Online - ? qsTr("En ligne") + //: "En ligne" + ? qsTr("contact_presence_status_online") : mode === LinphoneEnums.ConsolidatedPresence.Busy - ? qsTr("Occupé") + //: "Occupé" + ? qsTr("contact_presence_status_busy") : mode === LinphoneEnums.ConsolidatedPresence.DoNotDisturb - ? qsTr("Ne pas déranger") - : qsTr("Hors ligne") + //: "Ne pas déranger" + ? qsTr("contact_presence_status_do_not_disturb") + //: "Hors ligne" + : qsTr("contact_presence_status_offline") color: mode === LinphoneEnums.ConsolidatedPresence.Online ? DefaultStyle.success_500main : mode === LinphoneEnums.ConsolidatedPresence.Busy @@ -155,7 +159,8 @@ ColumnLayout { MediumButton { visible: mainItem.isConference && !SettingsCpp.disableMeetingsFeature Layout.alignment: Qt.AlignHCenter - text: qsTr("Rejoindre la réunion") + //: "Rejoindre la réunion" + text: qsTr("meeting_info_join_title") style: ButtonStyle.grey onClicked: { if (mainItem.conferenceInfo) { @@ -172,7 +177,8 @@ ColumnLayout { button.icon.width: Math.round(24 * DefaultStyle.dp) button.icon.height: Math.round(24 * DefaultStyle.dp) button.icon.source: AppIcons.phone - label: qsTr("Appel") + //: "Appel" + label: qsTr("contact_call_action") button.onClicked: { if (mainItem.specificAddress === "") mainWindow.startCallWithContact(mainItem.contact, false, mainItem) else UtilsCpp.createCall(mainItem.specificAddress) @@ -184,8 +190,9 @@ ColumnLayout { height: Math.round(56 * DefaultStyle.dp) button.icon.width: Math.round(24 * DefaultStyle.dp) button.icon.height: Math.round(24 * DefaultStyle.dp) - button.icon.source: AppIcons.chatTeardropText - label: qsTr("Message") + button.icon.source: AppIcons.chatTeardropText + //: "Message" + label: qsTr("contact_message_action") button.onClicked: console.debug("[ContactLayout.qml] TODO : open conversation") } LabelButton { @@ -195,7 +202,8 @@ ColumnLayout { button.icon.width: Math.round(24 * DefaultStyle.dp) button.icon.height: Math.round(24 * DefaultStyle.dp) button.icon.source: AppIcons.videoCamera - label: qsTr("Appel Video") + //: "Appel Video" + label: qsTr("contact_video_call_action") button.onClicked: { if (mainItem.specificAddress === "") mainWindow.startCallWithContact(mainItem.contact, true, mainItem) else UtilsCpp.createCall(mainItem.specificAddress, {'localVideoEnabled': true}) diff --git a/Linphone/view/Control/Container/Call/CallLayout.qml b/Linphone/view/Control/Container/Call/CallLayout.qml index 5bb61f43b..19f72b813 100644 --- a/Linphone/view/Control/Container/Call/CallLayout.qml +++ b/Linphone/view/Control/Container/Call/CallLayout.qml @@ -53,11 +53,14 @@ Item { z: 1 visible: mainItem.callState === LinphoneEnums.CallState.End || mainItem.callState === LinphoneEnums.CallState.Error || mainItem.callState === LinphoneEnums.CallState.Released text: mainItem.conference - ? qsTr("Vous avez quitté la conférence") - : mainItem.callTerminatedByUser - ? qsTr("Vous avez terminé l'appel") - : mainItem.callStarted - ? qsTr("Votre correspondant a terminé l'appel") + //: "Vous avez quitté la conférence" + ? qsTr("meeting_event_conference_destroyed") + : mainItem.callTerminatedByUser + //: "Vous avez terminé l'appel" + ? qsTr("call_ended_by_user") + : mainItem.callStarted + //: "Votre correspondant a terminé l'appel" + ? qsTr("call_ended_by_remote") : call && call.core.lastErrorMessage || "" color: DefaultStyle.grey_0 font { @@ -85,7 +88,8 @@ Item { width: waitText.implicitWidth Text { id: waitText - text: qsTr("Waiting for other participants...") + //: "En attente d'autres participants…" + text: qsTr("conference_call_empty") Layout.preferredHeight: Math.round(67 * DefaultStyle.dp) Layout.alignment: Qt.AlignHCenter horizontalAlignment: Text.AlignHCenter @@ -102,13 +106,15 @@ Item { borderColor: DefaultStyle.main2_400 icon.source: AppIcons.shareNetwork contentImageColor: DefaultStyle.main2_400 - text: qsTr("Share invitation") + //: "Partager le lien" + text: qsTr("conference_share_link_title") anchors.centerIn: parent textColor: DefaultStyle.main2_400 onClicked: { if (mainItem.conference) { UtilsCpp.copyToClipboard(mainItem.call.core.remoteAddress) - showInformationPopup(qsTr("Copié"), qsTr("Le lien de la réunion a été copié dans le presse-papier"), true) + //: Le lien de la réunion a été copié dans le presse-papier + showInformationPopup(qsTr("copied"), qsTr("information_popup_meeting_address_copied_to_clipboard"), true) } } } @@ -134,23 +140,3 @@ Item { } } } -// TODO : waitingForParticipant - // ColumnLayout { - // id: waitingForParticipant - // Text { - // text: qsTr("Waiting for other participants...") - // color: DefaultStyle.frey_0 - // font { - // pixelSize: Math.round(30 * DefaultStyle.dp) - // weight: Math.round(300 * DefaultStyle.dp) - // } - // } - // Button { - // text: qsTr("Share invitation") - // icon.source: AppIcons.shareNetwork - // color: DefaultStyle.main2_400 - // Layout.preferredWidth: Math.round(206 * DefaultStyle.dp) - // Layout.preferredHeight: Math.round(47 * DefaultStyle.dp) - // } - // } - diff --git a/Linphone/view/Control/Display/Call/CallListView.qml b/Linphone/view/Control/Display/Call/CallListView.qml index b340a45f2..659260560 100644 --- a/Linphone/view/Control/Display/Call/CallListView.qml +++ b/Linphone/view/Control/Display/Call/CallListView.qml @@ -49,12 +49,16 @@ ListView { } Text { id: callStateText - property string type: modelData.core.isConference ? qsTr('Réunion') : qsTr('Appel') + //: "Réunion + //: "Appel" + property string type: modelData.core.isConference ? qsTr("meeting") : qsTr("call") Layout.rightMargin: Math.round(2 * DefaultStyle.dp) text: modelData.core.state === LinphoneEnums.CallState.Paused || modelData.core.state === LinphoneEnums.CallState.PausedByRemote - ? type + qsTr(" en pause") - : type + qsTr(" en cours") + //: "%1 en pause" + ? qsTr("paused_call_or_meeting").arg(type) + //: "%1 en cours" + : qsTr("ongoing_call_or_meeting").arg(type) font { pixelSize: Math.round(12 * DefaultStyle.dp) weight: Math.round(300 * DefaultStyle.dp) diff --git a/Linphone/view/Control/Display/Call/CallStatistics.qml b/Linphone/view/Control/Display/Call/CallStatistics.qml index 40b24adbf..59d0a55f4 100644 --- a/Linphone/view/Control/Display/Call/CallStatistics.qml +++ b/Linphone/view/Control/Display/Call/CallStatistics.qml @@ -25,7 +25,8 @@ ColumnLayout { spacing: Math.round(12 * DefaultStyle.dp) Layout.alignment: Qt.AlignHCenter Text { - text: qsTr("Audio") + //: "Audio" + text: qsTr("call_stats_audio_title") Layout.alignment: Qt.AlignHCenter font { pixelSize: Math.round(12 * DefaultStyle.dp) @@ -86,7 +87,8 @@ ColumnLayout { spacing: Math.round(12 * DefaultStyle.dp) Layout.alignment: Qt.AlignHCenter Text { - text: qsTr("Vidéo") + //: "Vidéo" + text: qsTr("call_stats_video_title") Layout.alignment: Qt.AlignHCenter font { pixelSize: Math.round(12 * DefaultStyle.dp) diff --git a/Linphone/view/Control/Display/Contact/AllContactListView.qml b/Linphone/view/Control/Display/Contact/AllContactListView.qml index 3ae19f223..eabaeb640 100644 --- a/Linphone/view/Control/Display/Contact/AllContactListView.qml +++ b/Linphone/view/Control/Display/Contact/AllContactListView.qml @@ -150,7 +150,7 @@ Flickable { } } onSearchTextChanged: { - console.log("search texte changed, loading...") + console.log("search texte changed, loading…") loading = true } @@ -273,7 +273,8 @@ Flickable { selectionEnabled: mainItem.selectionEnabled multiSelectionEnabled: mainItem.multiSelectionEnabled selectedContacts: mainItem.selectedContacts - title: qsTr('Favoris') + //: "Favoris" + title: qsTr("car_favorites_contacts_title") itemsRightMargin: mainItem.itemsRightMargin onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact @@ -318,7 +319,8 @@ Flickable { multiSelectionEnabled: mainItem.multiSelectionEnabled selectedContacts: mainItem.selectedContacts itemsRightMargin: mainItem.itemsRightMargin - title: qsTr('Contacts') + //: 'Contacts' + title: qsTr("generic_address_picker_contacts_list_title") onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact onContactSelected: contactGui => { @@ -369,7 +371,8 @@ Flickable { selectionEnabled: mainItem.selectionEnabled multiSelectionEnabled: mainItem.multiSelectionEnabled selectedContacts: mainItem.selectedContacts - title: qsTr('Suggestions') + //: "Suggestions" + title: qsTr("generic_address_picker_suggestions_list_title") itemsRightMargin: mainItem.itemsRightMargin onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact diff --git a/Linphone/view/Control/Display/Contact/Contact.qml b/Linphone/view/Control/Display/Contact/Contact.qml index 281288178..084357db1 100644 --- a/Linphone/view/Control/Display/Contact/Contact.qml +++ b/Linphone/view/Control/Display/Contact/Contact.qml @@ -13,7 +13,9 @@ Control.Control{ id: mainItem padding: Math.round(10 * DefaultStyle.dp) property AccountGui account - property color backgroundColor: DefaultStyle.grey_0 + property color backgroundColor: DefaultStyle.grey_0 + leftPadding: Math.round(8 * DefaultStyle.dp) + rightPadding: Math.round(8 * DefaultStyle.dp) signal avatarClicked() signal backgroundClicked() @@ -56,6 +58,7 @@ Control.Control{ Control.Control { id: registrationStatusItem Layout.minimumWidth: Math.round(49 * DefaultStyle.dp) + Layout.maximumWidth: 150 Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) topPadding: Math.round(4 * DefaultStyle.dp) bottomPadding: Math.round(4 * DefaultStyle.dp) @@ -70,8 +73,10 @@ Control.Control{ } contentItem: Text { id: text - anchors.fill: parent - verticalAlignment: Text.AlignVCenter + anchors.fill: parent + anchors.leftMargin: registrationStatusItem.leftPadding + anchors.rightMargin: registrationStatusItem.rightPadding + verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter visible: mainItem.account property int mode : !mainItem.account || mainItem.account.core.registrationState == LinphoneEnums.RegistrationState.Ok @@ -98,12 +103,16 @@ Control.Control{ ? DefaultStyle.main2_500main : DefaultStyle.danger_500main text: mode == 0 - ? qsTr("Connecté") + //: "Connecté" + ? qsTr("drawer_menu_account_connection_status_connected") : mode == 1 - ? qsTr("Désactivé") + //: "Désactivé" + ? qsTr("drawer_menu_account_connection_status_cleared") : mode == 2 - ? qsTr("Connexion...") - : qsTr("Erreur") + //: "Connexion…" + ? qsTr("drawer_menu_account_connection_status_refreshing") + //: "Erreur" + : qsTr("drawer_menu_account_connection_status_failed") } } Item{ @@ -156,7 +165,10 @@ Control.Control{ if (mainItem.account.core.voicemailAddress.length > 0) UtilsCpp.createCall(mainItem.account.core.voicemailAddress) else - UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("L'URI de messagerie vocale n'est pas définie."), false) + //: Erreur + UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), + //: L'URI de messagerie vocale n'est pas définie. + qsTr("information_popup_voicemail_address_undefined_message"), false) } } Item{Layout.fillWidth: true} diff --git a/Linphone/view/Control/Display/Contact/ContactListItem.qml b/Linphone/view/Control/Display/Contact/ContactListItem.qml index 07df59be6..adb21e940 100644 --- a/Linphone/view/Control/Display/Contact/ContactListItem.qml +++ b/Linphone/view/Control/Display/Contact/ContactListItem.qml @@ -195,9 +195,9 @@ FocusScope { IconLabelButton { visible: searchResultItem.core.isStored && !searchResultItem.core.readOnly - text: searchResultItem.core.starred ? qsTr( - "Enlever des favoris") : qsTr( - "Mettre en favori") + //: "Enlever des favoris" + //: "Ajouter aux favoris" + text: searchResultItem.core.starred ? qsTr("contact_details_remove_from_favourites") : 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 @@ -222,23 +222,22 @@ FocusScope { var filepath = UtilsCpp.createVCardFile( username, vcard) if (filepath == "") + //: "La création du fichier vcard a échoué" UtilsCpp.showInformationPopup( - qsTr("Erreur"), qsTr( - "La création du fichier vcard a échoué"), + qsTr("information_popup_error_title"), qsTr("information_popup_vcard_creation_error"), false) else - mainWindow.showInformationPopup( - qsTr("VCard créée"), qsTr( - "VCard du contact enregistrée dans %1").arg( - filepath)) - UtilsCpp.shareByEmail( - qsTr("Partage de contact"), - vcard, filepath) + //: "VCard créée" + //: "VCard du contact enregistrée dans %1" + mainWindow.showInformationPopup(qsTr("information_popup_vcard_creation_title"), qsTr("information_popup_vcard_creation_success").arg(filepath)) + //: "Partage de contact" + UtilsCpp.shareByEmail(qsTr("contact_sharing_email_title"),vcard, filepath) } style: ButtonStyle.noBackground } IconLabelButton { - text: qsTr("Supprimer") + //: "Supprimer" + text: qsTr("contact_details_delete") icon.source: AppIcons.trashCan spacing: Math.round(10 * DefaultStyle.dp) visible: !searchResultItem.core.readOnly diff --git a/Linphone/view/Control/Display/Meeting/MeetingListView.qml b/Linphone/view/Control/Display/Meeting/MeetingListView.qml index e315d2043..6348878cc 100644 --- a/Linphone/view/Control/Display/Meeting/MeetingListView.qml +++ b/Linphone/view/Control/Display/Meeting/MeetingListView.qml @@ -243,7 +243,8 @@ ListView { } } Text { - text: itemDelegate.isCanceled ? qsTr("Réunion annulée") : UtilsCpp.toDateHourString(dateTime) + " - " + UtilsCpp.toDateHourString(endDateTime) + //: "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 font { pixelSize: Typography.p1.pixelSize @@ -266,7 +267,8 @@ ListView { anchors.leftMargin: Math.round(16 * DefaultStyle.dp) verticalAlignment: Text.AlignVCenter visible: !itemDelegate.haveModel - text: qsTr("Aucune réunion aujourd'hui") + //: "Aucune réunion aujourd'hui" + text: qsTr("meetings_list_no_meeting_for_today") lineHeightMode: Text.FixedHeight lineHeight: Math.round(18 * DefaultStyle.dp) font { diff --git a/Linphone/view/Control/Display/Participant/ParticipantListView.qml b/Linphone/view/Control/Display/Participant/ParticipantListView.qml index e0aeec56f..b97e7f3e3 100644 --- a/Linphone/view/Control/Display/Participant/ParticipantListView.qml +++ b/Linphone/view/Control/Display/Participant/ParticipantListView.qml @@ -64,7 +64,8 @@ ListView { Text { Layout.alignment: Qt.AlignRight visible: modelData.core.isAdmin - text: qsTr("Admin") + //: "Admin" + text: qsTr("meeting_participant_is_admin_label") color: DefaultStyle.main2_400 font { pixelSize: Math.round(12 * DefaultStyle.dp) @@ -106,7 +107,8 @@ ListView { icon.source: AppIcons.plusCircle icon.width: Math.round(16 * DefaultStyle.dp) icon.height: Math.round(16 * DefaultStyle.dp) - text: qsTr("Ajouter des participants") + //: "Ajouter des participants" + text: qsTr("meeting_add_participants_title") style: ButtonStyle.secondary onClicked: mainItem.addParticipantRequested() } diff --git a/Linphone/view/Control/Display/Sticker.qml b/Linphone/view/Control/Display/Sticker.qml index d9b3e68bf..cba54da36 100644 --- a/Linphone/view/Control/Display/Sticker.qml +++ b/Linphone/view/Control/Display/Sticker.qml @@ -126,7 +126,8 @@ Item { Text { Layout.preferredHeight: Math.round(27 * DefaultStyle.dp) Layout.topMargin: Math.round(15 * DefaultStyle.dp) // (84-27)-42 - text: qsTr('rejoint...') + //: "rejoint…" + text: qsTr("conference_participant_joining_text") color: DefaultStyle.grey_0 Layout.alignment: Qt.AlignHCenter horizontalAlignment: Text.AlignHCenter @@ -151,7 +152,8 @@ Item { Text { color: DefaultStyle.grey_0 Layout.alignment: Qt.AlignHCenter - text: qsTr("En pause") + //: "En pause" + text: qsTr("conference_participant_paused_text") font { pixelSize: Math.round(20 * DefaultStyle.dp) weight: Math.round(500 * DefaultStyle.dp) diff --git a/Linphone/view/Control/Form/Call/ChangeLayoutForm.qml b/Linphone/view/Control/Form/Call/ChangeLayoutForm.qml index 40a63b573..70432a520 100644 --- a/Linphone/view/Control/Form/Call/ChangeLayoutForm.qml +++ b/Linphone/view/Control/Form/Call/ChangeLayoutForm.qml @@ -17,21 +17,16 @@ FocusScope { anchors.leftMargin: Math.round(17 * DefaultStyle.dp) anchors.rightMargin: Math.round(17 * DefaultStyle.dp) spacing: Math.round(12 * DefaultStyle.dp) - // Text { - // Layout.fillWidth: true - // text: qsTr("La disposition choisie sera enregistrée pour vos prochaines réunions") - // font.pixelSize: Math.round(14 * DefaultStyle.dp) - // color: DefaultStyle.main2_500main - // } + RoundedPane { Layout.fillWidth: true contentItem: ColumnLayout { spacing: 0 Repeater { model: [ - {text: qsTr("Mosaïque"), imgUrl: AppIcons.squaresFour}, - {text: qsTr("Intervenant actif"), imgUrl: AppIcons.pip}, - {text: qsTr("Audio seulement"), imgUrl: AppIcons.waveform} + {text: qsTr("conference_layout_grid"), imgUrl: AppIcons.squaresFour}, + {text: qsTr("conference_layout_active_speaker"), imgUrl: AppIcons.pip}, + {text: qsTr("conference_layout_audio_only"), imgUrl: AppIcons.waveform} ] RadioButton { id: radiobutton diff --git a/Linphone/view/Control/Form/Login/LoginForm.qml b/Linphone/view/Control/Form/Login/LoginForm.qml index 8481b53e4..cf2e1f5df 100644 --- a/Linphone/view/Control/Form/Login/LoginForm.qml +++ b/Linphone/view/Control/Form/Login/LoginForm.qml @@ -12,7 +12,8 @@ ColumnLayout { FormItemLayout { id: username Layout.preferredWidth: Math.round(346 * DefaultStyle.dp) - label: qsTr("Nom d'utilisateur") + //: "Nom d'utilisateur" : username + label: qsTr("username") mandatory: true enableErrorText: true contentItem: TextField { @@ -27,7 +28,8 @@ ColumnLayout { FormItemLayout { id: password width: Math.round(346 * DefaultStyle.dp) - label: qsTr("Mot de passe") + //: "Mot de passe" + label: qsTr("password") mandatory: true enableErrorText: true contentItem: TextField { @@ -62,7 +64,8 @@ ColumnLayout { id: connectionButtonContent currentIndex: 0 Text { - text: qsTr("Connexion") + //: "Connexion" + text: qsTr("assistant_account_login") horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter @@ -100,9 +103,11 @@ ColumnLayout { if (usernameEdit.text.length == 0 || passwordEdit.text.length == 0) { if (usernameEdit.text.length == 0) - username.errorMessage = qsTr("Veuillez saisir un nom d'utilisateur") + //: "Veuillez saisir un nom d'utilisateur" + username.errorMessage = qsTr("assistant_account_login_missing_username") if (passwordEdit.text.length == 0) - password.errorMessage = qsTr("Veuillez saisir un mot de passe") + //: "Veuillez saisir un mot de passe" + password.errorMessage = qsTr("assistant_account_login_missing_password") return } LoginPageCpp.login(usernameEdit.text, passwordEdit.text) @@ -120,7 +125,8 @@ ColumnLayout { SmallButton { id: forgottenButton style: ButtonStyle.noBackground - text: qsTr("Mot de passe oublié ?") + //: "Mot de passe oublié ?" + text: qsTr("assistant_forgotten_password") underline: true onClicked: Qt.openUrlExternally(ConstantsCpp.PasswordRecoveryUrl) } diff --git a/Linphone/view/Control/Form/Settings/EncryptionSettings.qml b/Linphone/view/Control/Form/Settings/EncryptionSettings.qml index ff7c00f43..910658a92 100644 --- a/Linphone/view/Control/Form/Settings/EncryptionSettings.qml +++ b/Linphone/view/Control/Form/Settings/EncryptionSettings.qml @@ -18,7 +18,8 @@ ColumnLayout { contentItem: ColumnLayout { spacing: Math.round(12 * DefaultStyle.dp) Text { - text: qsTr("Chiffrement :") + //: "Chiffrement :" + text: qsTr("call_stats_media_encryption_title") Layout.alignment: Qt.AlignHCenter font { pixelSize: Math.round(12 * DefaultStyle.dp) @@ -30,7 +31,9 @@ ColumnLayout { spacing: Math.round(7 * DefaultStyle.dp) Text { property bool isPostQuantum: mainItem.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp && mainItem.call.core.zrtpStats.isPostQuantum - text: qsTr("Chiffrement du média : %1%2").arg(isPostQuantum ? "post Quantum " : "").arg(mainItem.call.core.encryptionString) + //: "Chiffrement du média : %1%2" + //: "ZRTP Post Quantique" + text: qsTr("call_stats_media_encryption").arg(isPostQuantum ? tr("call_stats_media_encryption_zrtp_post_quantum") : mainItem.call.core.encryptionString) Layout.alignment: Qt.AlignHCenter font { pixelSize: Math.round(12 * DefaultStyle.dp) @@ -40,7 +43,8 @@ ColumnLayout { ColumnLayout { visible: mainItem.call && mainItem.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp Text { - text: qsTr("Cipher algorithm : %1").arg(mainItem.call && mainItem.call.core.zrtpStats.cipherAlgo) + //: "Algorithme de chiffrement : %1" + text: qsTr("call_stats_zrtp_cipher_algo").arg(mainItem.call && mainItem.call.core.zrtpStats.cipherAlgo) Layout.alignment: Qt.AlignHCenter font { pixelSize: Math.round(12 * DefaultStyle.dp) @@ -48,7 +52,8 @@ ColumnLayout { } } Text { - text: qsTr("Key agreement algorithm : %1").arg(mainItem.call && mainItem.call.core.zrtpStats.keyAgreementAlgo) + //: "Algorithme d'accord de clé : %1" + text: qsTr("call_stats_zrtp_key_agreement_algo").arg(mainItem.call && mainItem.call.core.zrtpStats.keyAgreementAlgo) Layout.alignment: Qt.AlignHCenter font { pixelSize: Math.round(12 * DefaultStyle.dp) @@ -56,7 +61,8 @@ ColumnLayout { } } Text { - text: qsTr("Hash algorithm : %1").arg(mainItem.call && mainItem.call.core.zrtpStats.hashAlgo) + //: "Algorithme de hachage : %1" + text: qsTr("call_stats_zrtp_hash_algo").arg(mainItem.call && mainItem.call.core.zrtpStats.hashAlgo) Layout.alignment: Qt.AlignHCenter font { pixelSize: Math.round(12 * DefaultStyle.dp) @@ -64,7 +70,8 @@ ColumnLayout { } } Text { - text: qsTr("Authentication algorithm : %1").arg(mainItem.call && mainItem.call.core.zrtpStats.authenticationAlgo) + //: "Algorithme d'authentification : %1" + text: qsTr("call_stats_zrtp_auth_tag_algo").arg(mainItem.call && mainItem.call.core.zrtpStats.authenticationAlgo) Layout.alignment: Qt.AlignHCenter font { pixelSize: Math.round(12 * DefaultStyle.dp) @@ -72,7 +79,8 @@ ColumnLayout { } } Text { - text: qsTr("SAS algorithm : %1").arg(mainItem.call && mainItem.call.core.zrtpStats.sasAlgo) + //: "Algorithme SAS : %1" + text: qsTr("call_stats_zrtp_sas_algo").arg(mainItem.call && mainItem.call.core.zrtpStats.sasAlgo) Layout.alignment: Qt.AlignHCenter font { pixelSize: Math.round(12 * DefaultStyle.dp) @@ -87,7 +95,8 @@ ColumnLayout { Button { visible: mainItem.call && !mainItem.call.core.conference && mainItem.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp Layout.fillWidth: true - text: qsTr("Validation chiffrement") + //: "Validation chiffrement" + text: qsTr("call_zrtp_validation_button_label") onClicked: mainItem.encryptionValidationRequested() Layout.bottomMargin: Math.round(13 * DefaultStyle.dp) Layout.leftMargin: Math.round(16 * DefaultStyle.dp) diff --git a/Linphone/view/Control/Form/Settings/MultimediaSettings.qml b/Linphone/view/Control/Form/Settings/MultimediaSettings.qml index fcb3496c3..e2f005d3a 100644 --- a/Linphone/view/Control/Form/Settings/MultimediaSettings.qml +++ b/Linphone/view/Control/Form/Settings/MultimediaSettings.qml @@ -40,7 +40,8 @@ ColumnLayout { imageHeight: Math.round(24 * DefaultStyle.dp) } Text { - text: qsTr("Sonnerie - Appels entrants") + //: "Sonnerie - Appels entrants" + text: qsTr("multimedia_settings_ringer_title") font: Typography.p2l color: DefaultStyle.main2_600 Layout.fillWidth: true @@ -72,7 +73,8 @@ ColumnLayout { imageHeight: Math.round(24 * DefaultStyle.dp) } Text { - text: qsTr("Haut-parleurs") + //: "Haut-parleurs" + text: qsTr("multimedia_settings_speaker_title") font: Typography.p2l Layout.fillWidth: true } @@ -119,7 +121,8 @@ ColumnLayout { imageHeight: Math.round(24 * DefaultStyle.dp) } Text { - text: qsTr("Microphone") + //: "Microphone" + text: qsTr("multimedia_settings_microphone_title") font: Typography.p2l Layout.fillWidth: true } @@ -205,7 +208,8 @@ ColumnLayout { imageHeight: Math.round(24 * DefaultStyle.dp) } Text { - text: qsTr("Caméra") + //: "Caméra" + text: qsTr("multimedia_settings_camera_title") font: Typography.p2l Layout.fillWidth: true } diff --git a/Linphone/view/Control/Form/Settings/ScreencastSettings.qml b/Linphone/view/Control/Form/Settings/ScreencastSettings.qml index aa5c14c65..1fae29550 100644 --- a/Linphone/view/Control/Form/Settings/ScreencastSettings.qml +++ b/Linphone/view/Control/Form/Settings/ScreencastSettings.qml @@ -19,7 +19,8 @@ ColumnLayout { onIsLocalScreenSharingChanged: {if(isLocalScreenSharing) mainItem.call.core.videoSourceDescriptor = mainItem.desc } Text { Layout.fillWidth: true - text: qsTr("Veuillez choisir l’écran ou la fenêtre que vous souihaitez partager au autres participants") + //: "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 } @@ -27,7 +28,10 @@ ColumnLayout { Layout.fillWidth: true id: bar pixelSize: Math.round(16 * DefaultStyle.dp) - model: [qsTr("Ecran entier"), qsTr("Fenêtre")] + //: "Ecran entier" + model: [qsTr("screencast_settings_all_screen_label"), + //: "Fenêtre" + qsTr("screencast_settings_one_window_label")] } component ScreenPreviewLayout: Control.Control { id: screenPreview @@ -84,7 +88,8 @@ ColumnLayout { } Text { Layout.fillWidth: true - text: !!$modelData?.windowId ? $modelData.name : qsTr("Ecran %1").arg(screenIndex+1) + //: "Ecran %1" + text: !!$modelData?.windowId ? $modelData.name : qsTr("screencast_settings_screen").arg(screenIndex+1) horizontalAlignment: Text.AlignHCenter font.pixelSize: Math.round((displayScreen ? 14 : 10) * DefaultStyle.dp) elide: Text.ElideRight @@ -156,11 +161,13 @@ ColumnLayout { } } Button { - visible: mainItem.screenSharingAvailable + visible: mainItem.screenSharingAvailable$ enabled: windowsLayout.currentIndex !== -1 || screensLayout.currentIndex !== -1 text: mainItem.conference && mainItem.conference.core.isLocalScreenSharing - ? qsTr("Stop") - : qsTr("Partager") + //: "Stop + ? qsTr("stop") + //: "Partager" + : qsTr("share") onClicked: mainItem.conference.core.lToggleScreenSharing() style: ButtonStyle.main } diff --git a/Linphone/view/Control/Input/DecoratedTextField.qml b/Linphone/view/Control/Input/DecoratedTextField.qml index b9052faf6..1cb75b25e 100644 --- a/Linphone/view/Control/Input/DecoratedTextField.qml +++ b/Linphone/view/Control/Input/DecoratedTextField.qml @@ -45,9 +45,11 @@ FormItemLayout { onValidationChecked: (isValid) => { if (isValid) return if (!canBeEmpty && empty) { - mainItem.errorMessage = qsTr("ne peut être vide") + //: "ne peut être vide" + mainItem.errorMessage = qsTr("textfield_error_message_cannot_be_empty") } else { - mainItem.errorMessage = qsTr("Format non reconnu") + //: "Format non reconnu" + mainItem.errorMessage = qsTr("textfield_error_message_unknown_format") } } onTextChanged: mainItem.clearErrorText() diff --git a/Linphone/view/Control/Popup/Dialog/AuthenticationDialog.qml b/Linphone/view/Control/Popup/Dialog/AuthenticationDialog.qml index 734587142..7ebab2d54 100644 --- a/Linphone/view/Control/Popup/Dialog/AuthenticationDialog.qml +++ b/Linphone/view/Control/Popup/Dialog/AuthenticationDialog.qml @@ -35,63 +35,55 @@ Dialog { content: ColumnLayout { spacing:Math.round( 20 * DefaultStyle.dp) id: contentLayout + Text { + Layout.fillWidth: true + Layout.preferredWidth:Math.round( 250 * DefaultStyle.dp) + Layout.alignment: Qt.AlignHCenter + horizontalAlignment: Text.AlignHCenter + wrapMode: Text.Wrap + font { + pixelSize: Typography.h3.pixelSize + weight: Typography.h3.weight + } + //: "Authentification requise" + text: qsTr("account_settings_dialog_invalid_password_title") + } Text { Layout.fillWidth: true Layout.preferredWidth:Math.round( 250 * DefaultStyle.dp) Layout.alignment: Qt.AlignHCenter horizontalAlignment: Text.AlignHCenter wrapMode: Text.Wrap - text: qsTr("Impossible de vous authentifier. Merci de vérifier votre mot de passe.") + //: La connexion a échoué pour le compte %1. Vous pouvez renseigner votre mot de passe à nouveau ou bien vérifier les options de configuration de votre compte. + text: qsTr("account_settings_dialog_invalid_password_message").arg(mainItem.identity) font.pixelSize:Math.round( 16 * DefaultStyle.dp) + font { + pixelSize: Typography.h4.pixelSize + weight: Typography.h4.weight + } } - ColumnLayout { - spacing:Math.round( 10 * DefaultStyle.dp) - FormItemLayout { - Layout.fillWidth: true - label: qsTr("Identité") - contentItem: TextField { - enabled: false - initialText: mainItem.identity - } - } - FormItemLayout { - Layout.fillWidth: true - label: qsTr("Domaine") - contentItem: TextField { - enabled: false - initialText: mainItem.domain - } - } - FormItemLayout { - Layout.fillWidth: true - label: qsTr("Nom d'utilisateur (optionnel)") - contentItem: TextField { - id: usernameEdit - KeyNavigation.down: passwordEdit - } - } - FormItemLayout { - id: passwordItem - Layout.fillWidth: true - label: qsTr("Mot de passe") - enableErrorText: true - mandatory: true - contentItem: TextField { - id: passwordEdit - hidden: true - isError: passwordItem.errorTextVisible - KeyNavigation.up: usernameEdit - KeyNavigation.down: cancelButton - } - } - } + FormItemLayout { + id: passwordItem + Layout.fillWidth: true + label: qsTr("password") + enableErrorText: true + mandatory: true + contentItem: TextField { + id: passwordEdit + hidden: true + isError: passwordItem.errorTextVisible + KeyNavigation.up: usernameEdit + KeyNavigation.down: cancelButton + } + } } buttons: [ MediumButton { id: cancelButton Layout.topMargin: Math.round( 10 * DefaultStyle.dp) - text: qsTr("Annuler") + //: "Annuler + text: qsTr("cancel") style: ButtonStyle.secondary onClicked: mainItem.rejected() KeyNavigation.up: passwordEdit @@ -100,14 +92,16 @@ Dialog { MediumButton { id: connectButton Layout.topMargin:Math.round( 10 * DefaultStyle.dp) - text: qsTr("Se connecter") + //: Connexion + text: qsTr("assistant_account_login") style: ButtonStyle.main KeyNavigation.up: passwordEdit KeyNavigation.right: cancelButton onClicked: { passwordItem.errorMessage = "" - if (passwordEdit.text.length == 0) { - passwordItem.errorMessage = qsTr("Veuillez saisir un mot de passe") + if (passwordEdit.text.length == 0) { + //: Veuillez saisir un mot de passe + passwordItem.errorMessage = qsTr("assistant_account_login_missing_password") return } mainItem.accepted() diff --git a/Linphone/view/Control/Popup/Dialog/Dialog.qml b/Linphone/view/Control/Popup/Dialog/Dialog.qml index 84d846af1..bbb62d492 100644 --- a/Linphone/view/Control/Popup/Dialog/Dialog.qml +++ b/Linphone/view/Control/Popup/Dialog/Dialog.qml @@ -20,8 +20,10 @@ Popup { property var titleColor: DefaultStyle.main1_500_main property string text property string details - property string firstButtonText: firstButtonAccept ? qsTr("Oui") : qsTr("Annuler") - property string secondButtonText: secondButtonAccept ? qsTr("Confirmer") : qsTr("Non") + //: "Confirmer" + //: "Annuler" + property string firstButtonText: firstButtonAccept ? qsTr("dialog_confirm") : qsTr("dialog_cancel") + property string secondButtonText: secondButtonAccept ? qsTr("dialog_confirm") : qsTr("dialog_cancel") property alias content: contentLayout.data property alias buttons: buttonsLayout.data property alias firstButton: firstButtonId diff --git a/Linphone/view/Control/Popup/Dialog/ZrtpAuthenticationDialog.qml b/Linphone/view/Control/Popup/Dialog/ZrtpAuthenticationDialog.qml index cd1db427b..791c25090 100644 --- a/Linphone/view/Control/Popup/Dialog/ZrtpAuthenticationDialog.qml +++ b/Linphone/view/Control/Popup/Dialog/ZrtpAuthenticationDialog.qml @@ -66,7 +66,8 @@ Dialog { } } Text { - text: qsTr("Vérification de sécurité") + //: Vérification de sécurité + text: qsTr("call_dialog_zrtp_validate_trust_title") color: DefaultStyle.grey_0 Layout.Layout.alignment: Qt.AlignHCenter font { @@ -83,7 +84,8 @@ Dialog { anchors.topMargin: Math.round(10 * DefaultStyle.dp) anchors.rightMargin: Math.round(17 * DefaultStyle.dp) style: ButtonStyle.noBackground - text: qsTr("Passer") + //: "Passer" + text: qsTr("call_zrtp_sas_validation_skip") textColor: DefaultStyle.grey_0 hoveredTextColor: DefaultStyle.grey_100 pressedTextColor: DefaultStyle.grey_200 @@ -127,8 +129,10 @@ Dialog { Layout.Layout.alignment: Qt.AlignHCenter horizontalAlignment: Text.AlignHCenter text: !mainItem.isTokenVerified && mainItem.isCaseMismatch - ? qsTr("Pour garantir le chiffrement, nous avons besoin de réauthentifier l’appareil de votre correspondant. Echangez vos codes :") - : qsTr("Pour garantir le chiffrement, nous avons besoin d’authentifier l’appareil de votre correspondant. Veuillez échanger vos codes : ") + //: "Pour garantir le chiffrement, nous avons besoin de réauthentifier l’appareil de votre correspondant. Echangez vos codes :" + ? qsTr("call_dialog_zrtp_validate_trust_warning_message") + //: "Pour garantir le chiffrement, nous avons besoin d’authentifier l’appareil de votre correspondant. Veuillez échanger vos codes : " + : qsTr("call_dialog_zrtp_validate_trust_message") wrapMode: Text.WordWrap font.pixelSize: Math.round(14 * DefaultStyle.dp) } @@ -136,7 +140,8 @@ Dialog { spacing: 0 Layout.Layout.alignment: Qt.AlignHCenter Text { - text: qsTr("Votre code :") + //: "Votre code :" + text: qsTr("call_dialog_zrtp_validate_trust_local_code_label") horizontalAlignment: Text.AlignHCenter Layout.Layout.alignment: Qt.AlignHCenter font.pixelSize: Math.round(14 * DefaultStyle.dp) @@ -164,7 +169,8 @@ Dialog { anchors.fill: parent anchors.topMargin: Math.round(10 * DefaultStyle.dp) Text { - text: qsTr("Code correspondant :") + //: "Code correspondant :" + text: qsTr("call_dialog_zrtp_validate_trust_remote_code_label") font.pixelSize: Math.round(14 * DefaultStyle.dp) Layout.Layout.alignment: Qt.AlignHCenter } @@ -210,7 +216,8 @@ Dialog { Layout.Layout.alignment: Qt.AlignHCenter Layout.Layout.fillWidth: true horizontalAlignment: Text.AlignHCenter - text: qsTr("Le code fourni ne correspond pas.") + //: "Le code fourni ne correspond pas." + text: qsTr("call_dialog_zrtp_validate_trust_letters_do_not_match_text") wrapMode: Text.WordWrap font.pixelSize: Math.round(14 * DefaultStyle.dp) } @@ -220,7 +227,8 @@ Dialog { Layout.Layout.alignment: Qt.AlignHCenter Layout.Layout.fillWidth: true horizontalAlignment: Text.AlignHCenter - text: qsTr("La confidentialité de votre appel peut être compromise !") + //: "La confidentialité de votre appel peut être compromise !" + text: qsTr("call_dialog_zrtp_security_alert_message") wrapMode: Text.WordWrap font.pixelSize: Math.round(14 * DefaultStyle.dp) } @@ -232,7 +240,8 @@ Dialog { MediumButton { Layout.Layout.alignment: Qt.AlignHCenter Layout.Layout.preferredWidth: Math.round(247 * DefaultStyle.dp) - text: qsTr("Aucune correspondance") + //: "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 @@ -248,7 +257,8 @@ Dialog { style: ButtonStyle.phoneRed onClicked: mainItem.call.core.lTerminate() spacing: Math.round(15 * DefaultStyle.dp) - text: qsTr("Raccrocher") + //: "Raccrocher" + text: qsTr("call_action_hang_up") } } } diff --git a/Linphone/view/Control/Popup/Loading/LoadingPopup.qml b/Linphone/view/Control/Popup/Loading/LoadingPopup.qml index ee5479dbe..b7a7c24e8 100644 --- a/Linphone/view/Control/Popup/Loading/LoadingPopup.qml +++ b/Linphone/view/Control/Popup/Loading/LoadingPopup.qml @@ -36,7 +36,7 @@ Popup { MediumButton { visible: mainItem.cancelButtonVisible Layout.alignment: Qt.AlignHCenter - text: qsTr("Annuler") + text: qsTr("cancel") style: ButtonStyle.main onClicked: { if (callback) mainItem.callback() diff --git a/Linphone/view/Control/Popup/Notification/NotificationReceivedCall.qml b/Linphone/view/Control/Popup/Notification/NotificationReceivedCall.qml index f48b049fe..65d902f7f 100644 --- a/Linphone/view/Control/Popup/Notification/NotificationReceivedCall.qml +++ b/Linphone/view/Control/Popup/Notification/NotificationReceivedCall.qml @@ -85,7 +85,8 @@ Notification { } } Text { - text: qsTr("Appel audio") + //: "Appel entrant" + text: qsTr("call_audio_incoming") Layout.alignment: Qt.AlignHCenter color: DefaultStyle.grey_0 font { @@ -107,7 +108,8 @@ Notification { asynchronous: false icon.width: Math.round(19 * DefaultStyle.dp) icon.height: Math.round(19 * DefaultStyle.dp) - text: qsTr("Répondre") + //: "Accepter" + text: qsTr("dialog_accept") textSize: Math.round(14 * DefaultStyle.dp) textWeight: Math.round(500 * DefaultStyle.dp) onClicked: { @@ -124,7 +126,8 @@ Notification { asynchronous: false icon.width: Math.round(19 * DefaultStyle.dp) icon.height: Math.round(19 * DefaultStyle.dp) - text: qsTr("Refuser") + //: "Refuser + text: qsTr("dialog_deny") textSize: Math.round(14 * DefaultStyle.dp) textWeight: Math.round(500 * DefaultStyle.dp) onClicked: { diff --git a/Linphone/view/Control/Tool/Helper/utils.js b/Linphone/view/Control/Tool/Helper/utils.js index 60c3eb62d..ca3f1da03 100644 --- a/Linphone/view/Control/Tool/Helper/utils.js +++ b/Linphone/view/Control/Tool/Helper/utils.js @@ -686,35 +686,48 @@ function computeAvatarSize (container, maxSize, ratio) { function openCodecOnlineInstallerDialog (mainWindow, coreObject, cancelCallBack, successCallBack, errorCallBack) { mainWindow.showConfirmationLambdaPopup("", - qsTr("Installation de codec"), - qsTr("Télécharger le codec ") + capitalizeFirstLetter(coreObject.mimeType) + " ("+coreObject.encoderDescription+")"+" ?", + //: "Installation de codec" + qsTr("codec_install"), + //: "Télécharger le codec %1 (%2) ?" + qsTr("download_codec").arg(capitalizeFirstLetter(coreObject.mimeType)).arg(coreObject.encoderDescription), function (confirmed) { if (confirmed) { coreObject.loaded.connect(function(success) { mainWindow.closeLoadingPopup() if (success) { - mainWindow.showInformationPopup(qsTr("Succès"), qsTr("Le codec a été installé avec succès."), true) + //: "Succès" + mainWindow.showInformationPopup(qsTr("information_popup_success_title"), + //: "Le codec a été installé avec succès." + qsTr("information_popup_codec_install_success_text"), true) if (successCallBack) successCallBack() } else { - mainWindow.showInformationPopup(qsTr("Erreur"), qsTr("Le codec n'a pas pu être installé."), false) + mainWindow.showInformationPopup(qsTr("information_popup_error_title"), + //: "Le codec n'a pas pu être installé." + qsTr("information_popup_codec_install_error_text"), false) if (errorCallBack) errorCallBack() } }) coreObject.extractError.connect(function() { mainWindow.closeLoadingPopup() - mainWindow.showInformationPopup(qsTr("Erreur"), qsTr("Le codec n'a pas pu être sauvegardé."), false) + mainWindow.showInformationPopup(qsTr("information_popup_error_title"), + //: "Le codec n'a pas pu être sauvegardé." + qsTr("information_popup_codec_save_error_text"), false) if (errorCallBack) errorCallBack() }) coreObject.downloadError.connect(function() { mainWindow.closeLoadingPopup() - mainWindow.showInformationPopup(qsTr("Erreur"), qsTr("Le codec n'a pas pu être téléchargé."), false) + mainWindow.showInformationPopup(qsTr("information_popup_error_title"), + //: "Le codec n'a pas pu être téléchargé." + qsTr("information_popup_codec_download_error_text"), false) if (errorCallBack) errorCallBack() }) - mainWindow.showLoadingPopup(qsTr("Téléchargement en cours ...")) + + //: "Téléchargement en cours …" + mainWindow.showLoadingPopup(qsTr("loading_popup_codec_install_progress")) coreObject.downloadAndExtract() } else if (cancelCallBack) diff --git a/Linphone/view/Page/Form/Call/NewCallForm.qml b/Linphone/view/Page/Form/Call/NewCallForm.qml index 6a0793464..43b18a30f 100644 --- a/Linphone/view/Page/Form/Call/NewCallForm.qml +++ b/Linphone/view/Page/Form/Call/NewCallForm.qml @@ -28,7 +28,8 @@ FocusScope { spacing: Math.round(18 * DefaultStyle.dp) visible: mainItem.displayCurrentCalls Text { - text: qsTr("Appels en cours") + //: "Appels en cours" + text: qsTr("call_transfer_active_calls_label") font { pixelSize: Typography.h4.pixelSize weight: Typography.h4.weight @@ -72,7 +73,8 @@ FocusScope { focus: true color: mainItem.searchBarColor borderColor: mainItem.searchBarBorderColor - placeholderText: qsTr("Rechercher un contact") + //: "Rechercher un contact" + placeholderText: qsTr("search_bar_look_for_contact_text") numericPadPopup: mainItem.numPadPopup KeyNavigation.down: grouCallButton } diff --git a/Linphone/view/Page/Form/Contact/ContactEdition.qml b/Linphone/view/Page/Form/Contact/ContactEdition.qml index 7f082f343..939dc7da6 100644 --- a/Linphone/view/Page/Form/Contact/ContactEdition.qml +++ b/Linphone/view/Page/Form/Contact/ContactEdition.qml @@ -21,8 +21,10 @@ MainRightPanel { } } } - property string title: qsTr("Modifier contact") - property string saveButtonText: qsTr("Enregistrer") + //: "Modifier contact" + property string title: qsTr("contact_editor_title") + //: "Enregistrer + property string saveButtonText: qsTr("save") property string oldPictureUri property int addressCount: 0 @@ -35,7 +37,8 @@ MainRightPanel { mainItem.closeEdition('') } width: Math.round(278 * DefaultStyle.dp) - text: qsTr("Les changements seront annulés. Souhaitez-vous continuer ?") + //: "Les changements seront annulés. Souhaitez-vous continuer ?" + text: qsTr("contact_editor_dialog_cancel_change_message") } headerContent: [ @@ -61,7 +64,7 @@ MainRightPanel { icon.height: Math.round(24 * DefaultStyle.dp) onClicked: { if (contact.core.isSaved) mainItem.closeEdition('') - else showConfirmationLambdaPopup("", qsTr("Les changements seront annulés. Souhaitez-vous continuer ?"), "", function(confirmed) { + else showConfirmationLambdaPopup("", qsTr("contact_editor_dialog_cancel_change_message"), "", function(confirmed) { if (confirmed) { mainItem.contact.core.undo() mainItem.closeEdition('') @@ -81,11 +84,13 @@ MainRightPanel { id: saveDelay interval: 200 onTriggered:{ + //: "Veuillez saisir un prénom" if (mainItem.contact.core.givenName.length === 0) { - givenName.errorMessage = qsTr("Veuillez saisir un prénom") + givenName.errorMessage = qsTr("contact_editor_mandatory_first_name_not_filled") return } else if (addressesList.count === 0 && phoneNumberList.count === 0) { - addressesErrorText.setText(qsTr("Veuillez saisir une adresse ou un numéro de téléphone")) + //: "Veuillez saisir une adresse ou un numéro de téléphone" + addressesErrorText.setText(qsTr("contact_editor_mandatory_address_or_number_not_filled")) return } mainItem.contact.core.save() @@ -101,7 +106,8 @@ MainRightPanel { Layout.preferredWidth: width visible: !mainItem.contact || mainItem.contact.core.pictureUri.length === 0 icon.source: AppIcons.camera - text: qsTr("Ajouter une image") + //: "Ajouter une image" + text: qsTr("contact_editor_add_image_label") textSize: Typography.h4.pixelSize textWeight: Typography.h4.weight textColor: DefaultStyle.main2_700 @@ -118,7 +124,8 @@ MainRightPanel { id: editButton Layout.preferredWidth: width icon.source: AppIcons.pencil - text: qsTr("Modifier") + //: "Modifier" + text: qsTr("contact_details_edit") textColor: DefaultStyle.main2_700 hoveredTextColor: DefaultStyle.main2_800 pressedTextColor: DefaultStyle.main2_900 @@ -142,7 +149,8 @@ MainRightPanel { id: removeButton Layout.preferredWidth: width icon.source: AppIcons.trashCan - text: qsTr("Supprimer") + //: "Supprimer" + text: qsTr("contact_details_delete") textColor: DefaultStyle.main2_700 hoveredTextColor: DefaultStyle.main2_800 pressedTextColor: DefaultStyle.main2_900 @@ -192,7 +200,8 @@ MainRightPanel { id: givenName Layout.fillWidth: true enableErrorText: true - label: qsTr("Prénom") + //: "Prénom" + label: qsTr("contact_editor_first_name") contentItem: TextField { id: givenNameEdit Layout.preferredHeight: Math.round(49 * DefaultStyle.dp) @@ -206,8 +215,9 @@ MainRightPanel { KeyNavigation.down: nameTextField } } - FormItemLayout { - label: qsTr("Nom") + FormItemLayout { + //: "Nom" + label: qsTr("contact_editor_last_name") Layout.fillWidth: true contentItem: TextField { id: nameTextField @@ -219,7 +229,8 @@ MainRightPanel { } } FormItemLayout { - label: qsTr("Entreprise") + //: "Entreprise" + label: qsTr("contact_editor_company") Layout.fillWidth: true contentItem: TextField { id: companyTextField @@ -231,7 +242,8 @@ MainRightPanel { } } FormItemLayout { - label: qsTr("Fonction") + //: "Fonction" + label: qsTr("contact_editor_job_title") Layout.fillWidth: true contentItem: TextField { id: jobTextField @@ -281,7 +293,7 @@ MainRightPanel { Layout.preferredWidth: Math.round(421 * DefaultStyle.dp) Layout.preferredHeight: height onEditingFinished: { - if (text.length != 0) mainItem.contact.core.setAddressAt(index, qsTr("Adresse SIP"), text) + if (text.length != 0) mainItem.contact.core.setAddressAt(index, qsTr("sip_address"), text) } property string _initialText: modelData.address initialText: SettingsCpp.onlyDisplaySipUriUsername ? UtilsCpp.getUsername(_initialText) : _initialText @@ -308,7 +320,7 @@ MainRightPanel { } FormItemLayout { id: newAddressSipTextField - label: qsTr("Adresse SIP") + label: qsTr("sip_address") Layout.fillWidth: true onYChanged: { editionLayout.ensureVisibleRequested(newAddressSipTextField) @@ -373,7 +385,8 @@ MainRightPanel { KeyNavigation.right: removePhoneButton Keys.onPressed: (event) => phoneNumberLayout.updateFocus(event) onEditingFinished: { - if (text.length != 0) mainItem.contact.core.setPhoneNumberAt(index, qsTr("Téléphone"), text) + //: "Téléphone" + if (text.length != 0) mainItem.contact.core.setPhoneNumberAt(index, qsTr("phone"), text) } } Button { @@ -395,7 +408,7 @@ MainRightPanel { FormItemLayout { id: phoneNumberInput Layout.fillWidth: true - label: qsTr("Phone") + label: qsTr("phone") onYChanged: { editionLayout.ensureVisibleRequested(phoneNumberInput) } diff --git a/Linphone/view/Page/Form/Login/LoginPage.qml b/Linphone/view/Page/Form/Login/LoginPage.qml index 23cc96d73..4c5e9048e 100644 --- a/Linphone/view/Page/Form/Login/LoginPage.qml +++ b/Linphone/view/Page/Form/Login/LoginPage.qml @@ -38,7 +38,8 @@ LoginLayout { Layout.preferredWidth: Math.round(34 * DefaultStyle.dp) } Text { - text: qsTr("Connexion") + //: Connexion + text: qsTr("assistant_account_login") font { pixelSize: Typography.h1.pixelSize weight: Typography.h1.weight @@ -54,14 +55,16 @@ LoginLayout { Layout.rightMargin: Math.round(51 * DefaultStyle.dp) Text { Layout.rightMargin: Math.round(15 * DefaultStyle.dp) - text: qsTr("Pas encore de compte ?") + //: "Pas encore de compte ?" + text: qsTr("assistant_no_account_yet") font.pixelSize: Typography.p1.pixelSize font.weight: Typography.p1.weight } BigButton { Layout.alignment: Qt.AlignRight style: ButtonStyle.main - text: qsTr("S'inscrire") + //: "S'inscrire" + text: qsTr("assistant_account_register") onClicked: { console.debug("[LoginPage] User: go to register") mainItem.goToRegister() @@ -87,7 +90,8 @@ LoginLayout { Layout.preferredHeight: Math.round(47 * DefaultStyle.dp) Layout.topMargin: Math.round(39 * DefaultStyle.dp) visible: !SettingsCpp.assistantHideThirdPartyAccount - text: qsTr("Compte SIP tiers") + //: "Compte SIP tiers" + text: qsTr("assistant_login_third_party_sip_account_title") style: ButtonStyle.secondary onClicked: {mainItem.useSIPButtonClicked()} } @@ -95,7 +99,8 @@ LoginLayout { Layout.preferredWidth: loginForm.width Layout.preferredHeight: Math.round(47 * DefaultStyle.dp) Layout.topMargin: Math.round(25 * DefaultStyle.dp) - text: qsTr("Configuration distante") + //: "Configuration distante" + text: qsTr("assistant_login_remote_provisioning") style: ButtonStyle.secondary onClicked: {fetchConfigDialog.open()} } @@ -122,14 +127,17 @@ LoginLayout { topPadding: Math.round(41 * DefaultStyle.dp) bottomPadding: Math.round(29 * DefaultStyle.dp) radius: 0 - title: qsTr('Télécharger une configuration distante') - text: qsTr('Veuillez entrer le lien de configuration qui vous a été fourni :') + //: "Télécharger une configuration distante" + title: qsTr('assistant_login_download_remote_config') + //: 'Veuillez entrer le lien de configuration qui vous a été fourni :' + text: qsTr('assistant_login_remote_provisioning_url') - firstButton.text: 'Annuler' + firstButton.text: qsTr("cancel") firstButtonAccept: false firstButton.style: ButtonStyle.secondary - secondButton.text: 'Valider' + //: "Valider" + secondButton.text: qsTr("validate") secondButtonAccept: true secondButton.style: ButtonStyle.main onAccepted:{ @@ -140,7 +148,8 @@ LoginLayout { id: configUrl Layout.fillWidth: true Layout.preferredHeight: Math.round(49 * DefaultStyle.dp) - placeholderText: qsTr('Lien de configuration distante') + //: '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 5772b40af..6ffaac94c 100644 --- a/Linphone/view/Page/Form/Login/SIPLoginPage.qml +++ b/Linphone/view/Page/Form/Login/SIPLoginPage.qml @@ -38,7 +38,8 @@ LoginLayout { colorizationColor: DefaultStyle.main2_600 } Text { - text: qsTr("Compte SIP tiers") + //: Compte SIP tiers + text: qsTr("assistant_login_third_party_sip_account_title") font { pixelSize: Typography.h1.pixelSize weight: Typography.h1.weight @@ -55,7 +56,8 @@ LoginLayout { spacing: Math.round(20 * DefaultStyle.dp) Text { Layout.rightMargin: Math.round(15 * DefaultStyle.dp) - text: qsTr("Pas encore de compte ?") + //: Pas encore de compte ? + text: qsTr("assistant_no_account_yet") font { pixelSize: Typography.p1.pixelSize weight: Typography.p1.weight @@ -63,7 +65,8 @@ LoginLayout { } BigButton { Layout.alignment: Qt.AlignRight - text: qsTr("S'inscrire") + //: S'inscrire + text: qsTr("assistant_account_register") style: ButtonStyle.main onClicked: { console.debug("[SIPLoginPage] User: go to register page") @@ -97,30 +100,30 @@ LoginLayout { pixelSize: Typography.p1.pixelSize weight: Typography.p1.weight } - text: "Certaines fonctionnalités nécessitent un compte Linphone, comme la messagerie de groupe, les vidéoconférences..." - } - Text { - Layout.fillWidth: true - Layout.preferredWidth: rootStackView.width - wrapMode: Text.WordWrap - color: DefaultStyle.main2_900 - font { - pixelSize: Typography.p1.pixelSize - weight: Typography.p1.weight - } - text:"Ces fonctionnalités sont cachées lorsque vous vous enregistrez avec un compte SIP tiers." - } - Text { - Layout.fillWidth: true - Layout.preferredWidth: rootStackView.width - wrapMode: Text.WordWrap - color: DefaultStyle.main2_900 - font { - pixelSize: Typography.p1.pixelSize - weight: Typography.p1.weight - } - text: "Pour les activer dans un projet commercial, veuillez nous contacter. " + text: qsTr("Certaines fonctionnalités telles que les conversations de groupe, les vidéo-conférences, etc… nécessitent un compte %1.\n\nCes fonctionnalités seront masquées si vous utilisez un compte SIP tiers.\n\nPour les activer dans un projet commercial, merci de nous contacter.").arg(applicationName) } +// Text { +// Layout.fillWidth: true +// Layout.preferredWidth: rootStackView.width +// wrapMode: Text.WordWrap +// color: DefaultStyle.main2_900 +// font { +// pixelSize: Typography.p1.pixelSize +// weight: Typography.p1.weight +// } +// text:"Ces fonctionnalités sont cachées lorsque vous vous enregistrez avec un compte SIP tiers." +// } +// Text { +// Layout.fillWidth: true +// Layout.preferredWidth: rootStackView.width +// wrapMode: Text.WordWrap +// color: DefaultStyle.main2_900 +// font { +// pixelSize: Typography.p1.pixelSize +// weight: Typography.p1.weight +// } +// text: "Pour les activer dans un projet commercial, veuillez nous contacter. " +// } } SmallButton { id: openLinkButton @@ -141,7 +144,8 @@ LoginLayout { id: createAccountButton style: ButtonStyle.secondary Layout.fillWidth: true - text: qsTr("Créer un compte linphone") + //: "Créer un compte linphone" + text: qsTr("assistant_third_party_sip_account_create_linphone_account") onClicked: { console.debug("[SIPLoginPage] User: click register") mainItem.goToRegister() @@ -152,7 +156,8 @@ LoginLayout { BigButton { id: continueButton Layout.fillWidth: true - text: qsTr("Je comprends") + //: "Je comprends" + text: qsTr("assistant_third_party_sip_account_warning_ok") style: ButtonStyle.main onClicked: { rootStackView.replace(secondItem) @@ -183,7 +188,8 @@ LoginLayout { spacing: Math.round(16 * DefaultStyle.dp) FormItemLayout { id: username - label: qsTr("Nom d'utilisateur") + //: "Nom d'utilisateur" + label: qsTr("username") mandatory: true enableErrorText: true Layout.fillWidth: true @@ -196,7 +202,7 @@ LoginLayout { } FormItemLayout { id: password - label: qsTr("Mot de passe") + label: qsTr("password") mandatory: true enableErrorText: true Layout.fillWidth: true @@ -211,7 +217,8 @@ LoginLayout { } FormItemLayout { id: domain - label: qsTr("Domaine") + //: "Domaine" + label: qsTr("sip_address_domain") mandatory: true enableErrorText: true Layout.fillWidth: true @@ -231,7 +238,8 @@ LoginLayout { } } FormItemLayout { - label: qsTr("Nom d'affichage") + //: Nom d'affichage + label: qsTr("sip_address_display_name") Layout.fillWidth: true contentItem: TextField { id: displayName @@ -242,7 +250,8 @@ LoginLayout { } } FormItemLayout { - label: qsTr("Transport") + //: "Transport" + label: qsTr("transport") Layout.fillWidth: true contentItem: ComboBox { id: transportCbox @@ -281,7 +290,7 @@ LoginLayout { id: connectionButtonContent currentIndex: 0 Text { - text: qsTr("Connexion") + text: qsTr("assistant_account_login") horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter @@ -330,11 +339,12 @@ LoginLayout { onTriggered: { if (usernameEdit.text.length == 0 || passwordEdit.text.length == 0 || domainEdit.text.length == 0) { if (usernameEdit.text.length == 0) - username.errorMessage = qsTr("Veuillez saisir un nom d'utilisateur") + username.errorMessage = qsTr("assistant_account_login_missing_username") if (passwordEdit.text.length == 0) - password.errorMessage = qsTr("Veuillez saisir un mot de passe") + password.errorMessage = qsTr("assistant_account_login_missing_password") if (domainEdit.text.length == 0) - domain.errorMessage = qsTr("Veuillez saisir un nom de domaine") + //: "Veuillez saisir un nom de domaine + domain.errorMessage = qsTr("assistant_account_login_missing_domain") return } console.debug("[SIPLoginPage] User: Log in") diff --git a/Linphone/view/Page/Form/Meeting/AddParticipantsForm.qml b/Linphone/view/Page/Form/Meeting/AddParticipantsForm.qml index 16238632b..271741601 100644 --- a/Linphone/view/Page/Form/Meeting/AddParticipantsForm.qml +++ b/Linphone/view/Page/Form/Meeting/AddParticipantsForm.qml @@ -9,8 +9,8 @@ import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle FocusScope{ id: mainItem - - property string placeHolderText: qsTr("Rechercher des contacts") + //: "Rechercher des contacts" + property string placeHolderText: qsTr("search_bar_search_contacts_placeholder") property list selectedParticipants property int selectedParticipantsCount: selectedParticipants.length property ConferenceInfoGui conferenceInfoGui @@ -107,7 +107,8 @@ FocusScope{ visible: !contactList.loading && contactList.count === 0 Layout.alignment: Qt.AlignHCenter Layout.topMargin: Math.round(137 * DefaultStyle.dp) - text: qsTr("Aucun contact%1").arg(searchBar.text.length !== 0 ? " correspondant" : "") + //: "Aucun contact" + text: searchBar.text.length !== 0 ? qsTr("list_filter_no_result_found") : qsTr("contact_list_empty") font { pixelSize: Typography.h4.pixelSize weight: Typography.h4.weight diff --git a/Linphone/view/Page/Form/Meeting/MeetingForm.qml b/Linphone/view/Page/Form/Meeting/MeetingForm.qml index d2d2d7f54..09d1ec86c 100644 --- a/Linphone/view/Page/Form/Meeting/MeetingForm.qml +++ b/Linphone/view/Page/Form/Meeting/MeetingForm.qml @@ -35,7 +35,8 @@ FocusScope { icon.width: Math.round(24 * DefaultStyle.dp) icon.height: Math.round(24 * DefaultStyle.dp) enabled: false - text: qsTr("Réunion") + //: "Réunion" + text: qsTr("meeting_schedule_meeting_label") checked: true autoExclusive: true style: ButtonStyle.secondary @@ -46,7 +47,8 @@ FocusScope { icon.source: AppIcons.slide icon.width: Math.round(24 * DefaultStyle.dp) icon.height: Math.round(24 * DefaultStyle.dp) - text: qsTr("Broadcast") + //: "Webinar" + text: qsTr("meeting_schedule_broadcast_label") autoExclusive: true style: ButtonStyle.secondary } @@ -65,7 +67,8 @@ FocusScope { TextInput { id: confTitle Layout.fillWidth: true - property string defaultText: qsTr("Ajouter un titre") + //: "Ajouter un titre" + property string defaultText: qsTr("meeting_schedule_subject_hint") text: defaultText color: DefaultStyle.main2_600 font { @@ -210,7 +213,8 @@ FocusScope { leftPadding: Math.round(8 * DefaultStyle.dp) rightPadding: Math.round(8 * DefaultStyle.dp) hoverEnabled: true - placeholderText: qsTr("Ajouter une description") + //: "Ajouter une description" + placeholderText: qsTr("meeting_schedule_description_hint") placeholderTextColor: DefaultStyle.main2_600 placeholderWeight: Typography.p2l.weight color: DefaultStyle.main2_600 @@ -257,7 +261,8 @@ FocusScope { } Text { Layout.fillWidth: true - text: qsTr("Ajouter des participants") + //: "Ajouter des participants" + text: qsTr("meeting_schedule_add_participants_title") font { pixelSize: Typography.p2l.pixelSize weight: Typography.p2l.weight @@ -310,7 +315,8 @@ FocusScope { ] } Switch { - text: qsTr("Envoyer une invitation aux participants") + //: "Envoyer une invitation aux participants" + text: qsTr("meeting_schedule_send_invitations_title") checked: mainItem.conferenceInfoGui.core.inviteEnabled onToggled: mainItem.conferenceInfoGui.core.inviteEnabled = checked } diff --git a/Linphone/view/Page/Form/Register/RegisterCheckingPage.qml b/Linphone/view/Page/Form/Register/RegisterCheckingPage.qml index aca4c707c..32a25085d 100644 --- a/Linphone/view/Page/Form/Register/RegisterCheckingPage.qml +++ b/Linphone/view/Page/Form/Register/RegisterCheckingPage.qml @@ -39,8 +39,12 @@ LoginLayout { Text { wrapMode: Text.NoWrap text: { - var completeString = mainItem.registerWithEmail ? qsTr("email") : qsTr("numéro") - text = qsTr("Inscription | Confirmer votre ") + completeString + //: "email" + var completeString = mainItem.registerWithEmail ? qsTr("email") + //: "numéro de téléphone" + : qsTr("phone_number") + //: "Inscription | Confirmer votre %1" + text = qsTr("confirm_register_title").arg(completeString) } font { pixelSize: Typography.h1.pixelSize @@ -68,9 +72,10 @@ LoginLayout { weight: Typography.h3.weight } color: DefaultStyle.main2_700 - text: { - var completeString = mainItem.registerWithEmail ? ("email \"") : ("phone number \"") + address + "\"" - text = "We have sent a verification code on your " + completeString + "
Please enter the verification code below:" + text: { + var completeString = mainItem.registerWithEmail ? ("email") : ("phone_number") + //: Nous vous avons envoyé un code de vérification sur votre %1 %2
Merci de le saisir ci-dessous + text = qsTr("assistant_account_creation_confirmation_explanation").arg(completeString).arg(address) } } RowLayout { @@ -141,14 +146,16 @@ LoginLayout { RowLayout { spacing: Math.round(20 * DefaultStyle.dp) Text { - text: "Didn't receive the code ?" + //: "Vous n'avez pas reçu le code ?" + text: qsTr("assistant_account_creation_confirmation_did_not_receive_code") color: DefaultStyle.main2_700 font.pixelSize: Typography.p1.pixelSize font.weight: Typography.p1.weight } BigButton { style: ButtonStyle.secondary - text: "Resend a code" + //: "Renvoyer un code" + text: qsTr("assistant_account_creation_confirmation_resend_code") onClicked: { console.debug("[RegisterCheckingPage] User: Resend code") } diff --git a/Linphone/view/Page/Form/Register/RegisterPage.qml b/Linphone/view/Page/Form/Register/RegisterPage.qml index c0840f6ed..5e921abb9 100644 --- a/Linphone/view/Page/Form/Register/RegisterPage.qml +++ b/Linphone/view/Page/Form/Register/RegisterPage.qml @@ -51,7 +51,8 @@ LoginLayout { } Text { Layout.preferredWidth: width - text: qsTr("Inscription") + //: "Inscription + text: qsTr("assistant_account_register") font { pixelSize: Typography.h1.pixelSize weight: Typography.h1.weight @@ -69,7 +70,8 @@ LoginLayout { Text { Layout.rightMargin: Math.round(15 * DefaultStyle.dp) color: DefaultStyle.main2_700 - text: qsTr("Déjà un compte ?") + // "Déjà un compte ?" + text: qsTr("assistant_already_have_an_account") font { pixelSize: Typography.p1.pixelSize weight: Typography.p1.weight @@ -77,7 +79,7 @@ LoginLayout { } BigButton { style: ButtonStyle.main - text: qsTr("Connexion") + text: qsTr("assistant_account_login") onClicked: { console.debug("[RegisterPage] User: return") returnToLogin() @@ -96,7 +98,10 @@ LoginLayout { TabBar { Layout.fillWidth: true id: bar - model: [qsTr("Register with phone number"), qsTr("Register with email")] + // "S'inscrire avec un numéro de téléphone" + model: [qsTr("assistant_account_register_with_phone_number"), + // "S'inscrire avec un email" + qsTr("assistant_account_register_with_email")] } Flickable { Layout.fillWidth: true @@ -112,7 +117,7 @@ LoginLayout { spacing: Math.round(16 * DefaultStyle.dp) FormItemLayout { id: usernameItem - label: qsTr("Username") + label: qsTr("username") mandatory: true enableErrorText: true Layout.preferredWidth: Math.round(346 * DefaultStyle.dp) @@ -143,17 +148,18 @@ LoginLayout { id: phoneNumberInput Layout.preferredWidth: Math.round(346 * DefaultStyle.dp) property string completePhoneNumber: countryCode + phoneNumber - label: qsTr("Numéro de téléphone") + //: "Numéro de téléphone" + label: qsTr("phone_number") enableErrorText: true mandatory: true - placeholderText: "Phone number" + placeholderText: qsTr("phone_number") defaultCallingCode: "33" } FormItemLayout { id: emailItem Layout.fillWidth: false Layout.preferredWidth: Math.round(346 * DefaultStyle.dp) - label: qsTr("Email") + label: qsTr("email") mandatory: true enableErrorText: true contentItem: TextField { @@ -172,7 +178,7 @@ LoginLayout { FormItemLayout { id: passwordItem Layout.preferredWidth: Math.round(346 * DefaultStyle.dp) - label: qsTr("Mot de passe") + label: qsTr("password") mandatory: true enableErrorText: true contentItem: TextField { @@ -184,7 +190,8 @@ LoginLayout { } FormItemLayout { Layout.preferredWidth: Math.round(346 * DefaultStyle.dp) - label: qsTr("Confirmation mot de passe") + //: "Confirmation mot de passe" + label: qsTr("assistant_account_register_password_confirmation") mandatory: true enableErrorText: true contentItem: TextField { @@ -199,7 +206,6 @@ LoginLayout { id: otherErrorText Layout.fillWidth: true Layout.topMargin: Math.round(5 * DefaultStyle.dp) - onTextChanged: console.log("set error", text) } } } @@ -227,97 +233,54 @@ LoginLayout { spacing: Math.round(10 * DefaultStyle.dp) CheckBox { id: termsCheckBox - } - RowLayout { - spacing: 0 - Layout.fillWidth: true - Text { - text: qsTr("J'accepte les ") - font { - pixelSize: Typography.p1.pixelSize - weight: Typography.p1.weight - } - MouseArea { - anchors.fill: parent - onClicked: termsCheckBox.toggle() - } - } - Text { - activeFocusOnTab: true - font { - underline: true - pixelSize: Typography.p1.pixelSize - weight: Typography.p1.weight - bold: activeFocus - } - text: qsTr("conditions d’utilisation") - Keys.onPressed: (event)=> { - if (event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return) { - cguMouseArea.clicked(undefined) - event.accepted = true; - } - } - MouseArea { - id: cguMouseArea - anchors.fill: parent - hoverEnabled: true - cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor - onClicked: Qt.openUrlExternally(ConstantsCpp.CguUrl) - } - } - Text { - text: qsTr(" et la ") - font { - pixelSize: Typography.p1.pixelSize - weight: Typography.p1.weight - } - } - Text { - activeFocusOnTab: true - font { - underline: true - pixelSize: Typography.p1.pixelSize - weight: Typography.p1.weight - bold: activeFocus - } - text: qsTr("politique de confidentialité.") - Keys.onPressed: (event)=> { - if (event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return) { - privateMouseArea.clicked(undefined) - event.accepted = true; - } - } - MouseArea { - id: privateMouseArea - anchors.fill: parent - hoverEnabled: true - cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor - onClicked: Qt.openUrlExternally(ConstantsCpp.PrivatePolicyUrl) - } - } - } - } - // } + } + Text { + //: "J'accepte les %1 et la %2" + text: 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"))) + onLinkActivated: (link) => Qt.openUrlExternally(link) + font { + pixelSize: Typography.p1.pixelSize + weight: Typography.p1.weight + } + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.NoButton + cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor + onClicked: termsCheckBox.toggle() + } + } + } + // } Button { enabled: termsCheckBox.checked style: ButtonStyle.main - text: qsTr("Créer") + //: "Créer" + text: qsTr("assistant_account_create") onClicked:{ if (usernameInput.text.length === 0) { console.log("ERROR username") - usernameItem.errorMessage = qsTr("Veuillez entrer un nom d'utilisateur") + //: "Veuillez entrer un nom d'utilisateur" + usernameItem.errorMessage = qsTr("assistant_account_create_missing_username_error") } else if (pwdInput.text.length === 0) { console.log("ERROR password") - passwordItem.errorMessage = qsTr("Veuillez entrer un mot de passe") + //: "Veuillez entrer un mot de passe" + passwordItem.errorMessage = qsTr("assistant_account_create_missing_password_error") } else if (pwdInput.text != confirmPwdInput.text) { console.log("ERROR confirm pwd") - passwordItem.errorMessage = qsTr("Les mots de passe sont différents") + //: "Les mots de passe sont différents" + passwordItem.errorMessage = qsTr("assistant_account_create_confirm_password_error") } else if (bar.currentIndex === 0 && phoneNumberInput.phoneNumber.length === 0) { console.log("ERROR phone number") - phoneNumberInput.errorMessage = qsTr("Veuillez entrer un numéro de téléphone") + //: "Veuillez entrer un numéro de téléphone" + phoneNumberInput.errorMessage = qsTr("assistant_account_create_missing_number_error") } else if (bar.currentIndex === 1 && emailInput.text.length === 0) { console.log("ERROR email") - emailItem.errorMessage = qsTr("Veuillez entrer un email") + //: "Veuillez entrer un email" + emailItem.errorMessage = qsTr("assistant_account_create_missing_email_error") } else { console.log("[RegisterPage] User: Call register") mainItem.browserValidationRequested() diff --git a/Linphone/view/Page/Form/Security/SecurityModePage.qml b/Linphone/view/Page/Form/Security/SecurityModePage.qml index fcd0f64d8..90555720e 100644 --- a/Linphone/view/Page/Form/Security/SecurityModePage.qml +++ b/Linphone/view/Page/Form/Security/SecurityModePage.qml @@ -18,14 +18,16 @@ LoginLayout { } ColumnLayout { Text { - text: qsTr("Choisir votre mode") + //: "Choisir votre mode" + text: qsTr("manage_account_choose_mode_title") font { pixelSize: Typography.h1.pixelSize weight: Typography.h1.weight } } Text { - text: qsTr("Vous pourrez changer de mode plus tard.") + //: "Vous pourrez changer de mode plus tard." + text: qsTr("manage_account_choose_mode_message") font.bold: true font { pixelSize: Typography.p1.pixelSize @@ -44,8 +46,14 @@ LoginLayout { spacing: Math.round(70 * DefaultStyle.dp) Repeater { model: [ - {checked: true, title: qsTr("Chiffrement de bout en bout"), text: qsTr("Ce mode vous garanti la confidentialité de tous vos échanges. Notre technologie de chiffrement de bout en bout assure un niveau de sécurité maximal pour tous vos échanges."), imgUrl: AppIcons.chiffrement, color: DefaultStyle.info_500_main}, - {checked: false, title: qsTr("Interoperable"), text: qsTr("Ce mode vous permet de profiter de toute les fonctionnalités de Linphone, toute en restant interopérable avec n’importe qu’elle autre service SIP."), imgUrl: AppIcons.interoperable, color: DefaultStyle.main1_500_main} + //: "Chiffrement de bout en bout" + {checked: true, title: qsTr("manage_account_e2e_encrypted_mode_default_title"), + //: "Ce mode vous garanti la confidentialité de tous vos échanges. Notre technologie de chiffrement de bout en bout assure un niveau de sécurité maximal pour tous vos échanges." + text: qsTr("manage_account_e2e_encrypted_mode_default_summary"), imgUrl: AppIcons.chiffrement, color: DefaultStyle.info_500_main}, + //: "Interoperable" + {checked: false, title: qsTr("manage_account_e2e_encrypted_mode_interoperable_title"), + //: "Ce mode vous permet de profiter de toute les fonctionnalités de Linphone, toute en restant interopérable avec n’importe qu’elle autre service SIP." + text: qsTr("manage_account_e2e_encrypted_mode_interoperable_summary"), imgUrl: AppIcons.interoperable, color: DefaultStyle.main1_500_main} ] SecurityRadioButton { title: modelData.title @@ -64,7 +72,8 @@ LoginLayout { property int selectedIndex: 0 Layout.alignment: Qt.AlignHCenter Layout.preferredWidth: Math.round(360 * DefaultStyle.dp) - text: qsTr("Continuer") + //: "Continuer" + text: qsTr("dialog_continue") style: ButtonStyle.main onClicked: mainItem.modeSelected(selectedIndex) } diff --git a/Linphone/view/Page/Form/Settings/AccountSettingsPage.qml b/Linphone/view/Page/Form/Settings/AccountSettingsPage.qml index 35c238d96..742d7ee9f 100644 --- a/Linphone/view/Page/Form/Settings/AccountSettingsPage.qml +++ b/Linphone/view/Page/Form/Settings/AccountSettingsPage.qml @@ -9,20 +9,25 @@ import SettingsCpp AbstractSettingsMenu { id: mainItem layoutsPath: "qrc:/qt/qml/Linphone/view/Page/Layout/Settings" - titleText: qsTr("Mon compte") + //: "Mon compte" + titleText: qsTr("drawer_menu_manage_account") property AccountGui account signal accountRemoved() families: [ - {title: qsTr("Général"), layout: "AccountSettingsGeneralLayout", model: account}, - {title: qsTr("Paramètres de compte"), layout: "AccountSettingsParametersLayout", model: account} + //: "Général" + {title: qsTr("settings_general_title"), layout: "AccountSettingsGeneralLayout", model: account}, + //: "Paramètres de compte" + {title: qsTr("settings_account_title"), layout: "AccountSettingsParametersLayout", model: account} ] Connections { target: account.core function onRemoved() { accountRemoved() } } onGoBackRequested: if (!account.core.isSaved) { - UtilsCpp.getMainWindow().showConfirmationLambdaPopup(qsTr("Modifications non enregistrées"), - qsTr("Vous avez des modifications non enregistrées. Si vous quittez cette page, vos changements seront perdus. Voulez-vous enregistrer vos modifications avant de continuer ?"), + //: "Modifications non enregistrées" + UtilsCpp.getMainWindow().showConfirmationLambdaPopup(qsTr("contact_editor_popup_abort_confirmation_title"), + //: "Vous avez des modifications non enregistrées. Si vous quittez cette page, vos changements seront perdus. Voulez-vous enregistrer vos modifications avant de continuer ?" + qsTr("contact_editor_popup_abort_confirmation_message"), "", function (confirmed) { if (confirmed) { @@ -31,7 +36,9 @@ AbstractSettingsMenu { account.core.undo() } mainItem.goBack() - }, qsTr("Ne pas enregistrer"), qsTr("Enregistrer") + //: "Ne pas enregistrer" + //: "Enregistrer" + }, qsTr("contact_editor_dialog_abort_confirmation_do_not_save"), qsTr("contact_editor_dialog_abort_confirmation_save") ) } else {mainItem.goBack()} } diff --git a/Linphone/view/Page/Form/Settings/SettingsPage.qml b/Linphone/view/Page/Form/Settings/SettingsPage.qml index 4f3327fdf..0a9509ce6 100644 --- a/Linphone/view/Page/Form/Settings/SettingsPage.qml +++ b/Linphone/view/Page/Form/Settings/SettingsPage.qml @@ -8,20 +8,30 @@ import UtilsCpp AbstractSettingsMenu { id: mainItem layoutsPath: "qrc:/qt/qml/Linphone/view/Page/Layout/Settings" - titleText: qsTr("Paramètres") + //: "Paramètres" + titleText: qsTr("settings_title") families: [ - {title: qsTr("Appels"), layout: "CallSettingsLayout"}, - {title: qsTr("Conversations"), layout: "ChatSettingsLayout", visible: !SettingsCpp.disableChatFeature}, - {title: qsTr("Contacts"), layout: "ContactsSettingsLayout"}, - {title: qsTr("Réunions"), layout: "MeetingsSettingsLayout", visible: !SettingsCpp.disableMeetingsFeature}, - //{title: qsTr("Affichage"), layout: "DisplaySettingsLayout"}, - {title: qsTr("Réseau"), layout: "NetworkSettingsLayout"}, - {title: qsTr("Paramètres avancés"), layout: "AdvancedSettingsLayout"} + //: "Appels" + {title: qsTr("settings_calls_title"), layout: "CallSettingsLayout"}, + //: "Conversations" + {title: qsTr("settings_conversations_title"), layout: "ChatSettingsLayout", visible: !SettingsCpp.disableChatFeature}, + //: "Contacts" + {title: qsTr("settings_contacts_title"), layout: "ContactsSettingsLayout"}, + //: "Réunions" + {title: qsTr("settings_meetings_title"), layout: "MeetingsSettingsLayout", visible: !SettingsCpp.disableMeetingsFeature}, + //: "Affichage" + //{title: qsTr("settings_user_interface_title"), layout: "DisplaySettingsLayout"}, + //: "Réseau" + {title: qsTr("settings_network_title"), layout: "NetworkSettingsLayout"}, + //: "Paramètres avancés" + {title: qsTr("settings_advanced_title"), layout: "AdvancedSettingsLayout"} ] onGoBackRequested: if (!SettingsCpp.isSaved) { - UtilsCpp.getMainWindow().showConfirmationLambdaPopup(qsTr("Modifications non enregistrées"), - qsTr("Vous avez des modifications non enregistrées. Si vous quittez cette page, vos changements seront perdus. Voulez-vous enregistrer vos modifications avant de continuer ?"), + //: Modifications non enregistrées + UtilsCpp.getMainWindow().showConfirmationLambdaPopup(qsTr("contact_editor_popup_abort_confirmation_title"), + //: Vous avez des modifications non enregistrées. Si vous quittez cette page, vos changements seront perdus. Voulez-vous enregistrer vos modifications avant de continuer ? + qsTr("contact_editor_popup_abort_confirmation_message"), "", function (confirmed) { if (confirmed) { @@ -30,7 +40,10 @@ AbstractSettingsMenu { SettingsCpp.undo() } mainItem.goBack() - }, qsTr("Ne pas enregistrer"), qsTr("Enregistrer") + //: "Ne pas enregistrer" + }, qsTr("contact_editor_dialog_abort_confirmation_do_not_save"), + //: "Enregistrer" + qsTr("contact_editor_dialog_abort_confirmation_save") ) } else {mainItem.goBack()} } diff --git a/Linphone/view/Page/Layout/Login/LoginLayout.qml b/Linphone/view/Page/Layout/Login/LoginLayout.qml index 33feddf76..daf492347 100644 --- a/Linphone/view/Page/Layout/Login/LoginLayout.qml +++ b/Linphone/view/Page/Layout/Login/LoginLayout.qml @@ -72,7 +72,8 @@ Rectangle { id: aboutPopup anchors.centerIn: parent width: Math.round(637 * DefaultStyle.dp) - title: qsTr("À propos de Linphone") + //: À propos de %1 + title: qsTr("help_about_title").arg(applicationName) bottomPadding: Math.round(10 * DefaultStyle.dp) buttons: [] content: RowLayout { @@ -81,24 +82,29 @@ Rectangle { Layout.alignment: Qt.AlignTop | Qt.AlignLeft AboutLine { imageSource: AppIcons.detective - title: qsTr("Politique de confidentialité") - text: qsTr("Visiter notre potilique de confidentialité") + //: "Politique de confidentialité" + title: qsTr("help_about_privacy_policy_title") + //: "Visiter notre potilique de confidentialité" + text: qsTr("help_about_privacy_policy_link") enableMouseArea: true onContentClicked: Qt.openUrlExternally(ConstantsCpp.PrivatePolicyUrl) } AboutLine { imageSource: AppIcons.info - title: qsTr("Version") + //: "Version" + title: qsTr("help_about_version_title") text: Qt.application.version } AboutLine { imageSource: AppIcons.checkSquareOffset - title: qsTr("Licence") + //: "Licence" + title: qsTr("help_about_licence_title") text: applicationLicence } AboutLine { imageSource: AppIcons.copyright - title: qsTr("Copyright") + //: "Copyright + title: qsTr("help_about_copyright_title") text: applicationVendor } Item { @@ -108,7 +114,8 @@ Rectangle { } MediumButton { Layout.alignment: Qt.AlignRight | Qt.AlignBottom - text: qsTr("Fermer") + //: "Fermer" + text: qsTr("close") style: ButtonStyle.main onClicked: aboutPopup.close() } @@ -131,7 +138,7 @@ Rectangle { id: aboutButton Layout.alignment: Qt.AlignRight | Qt.AlignVCenter icon.source: AppIcons.info - text: qsTr("À propos") + text: qsTr("help_about_title").arg(applicationName) textSize: Typography.p1.pixelSize textWeight: Typography.p1.weight textColor: DefaultStyle.main2_500main diff --git a/Linphone/view/Page/Layout/Main/MainLayout.qml b/Linphone/view/Page/Layout/Main/MainLayout.qml index da7e289a9..e4ec0938e 100644 --- a/Linphone/view/Page/Layout/Main/MainLayout.qml +++ b/Linphone/view/Page/Layout/Main/MainLayout.qml @@ -129,20 +129,24 @@ Item { model: [{ "icon": AppIcons.phone, "selectedIcon": AppIcons.phoneSelected, - "label": qsTr("Appels") + //: "Appels" + "label": qsTr("bottom_navigation_calls_label") }, { "icon": AppIcons.adressBook, "selectedIcon": AppIcons.adressBookSelected, - "label": qsTr("Contacts") + //: "Contacts" + "label": qsTr("bottom_navigation_contacts_label") }, { "icon": AppIcons.chatTeardropText, "selectedIcon": AppIcons.chatTeardropTextSelected, - "label": qsTr("Conversations"), + //: "Conversations" + "label": qsTr("bottom_navigation_conversations_label"), "visible": !SettingsCpp.disableChatFeature }, { "icon": AppIcons.videoconference, "selectedIcon": AppIcons.videoconferenceSelected, - "label": qsTr("Réunions"), + //: "Réunions" + "label": qsTr("bottom_navigation_meetings_label"), "visible": !SettingsCpp.disableMeetingsFeature }] onCurrentIndexChanged: { @@ -188,7 +192,9 @@ Item { SearchBar { id: magicSearchBar Layout.fillWidth: true - placeholderText: SettingsCpp.disableChatFeature ? qsTr("Rechercher un contact, appeler...") : qsTr("Rechercher un contact, appeler ou envoyer un message...") + //: "Rechercher un contact, appeler %1" + //: "ou envoyer un message …" + placeholderText: qsTr("searchbar_placeholder_text").arg(SettingsCpp.disableChatFeature ? "…" : qsTr("searchbar_placeholder_text_chat_feature_enabled")) focusedBorderColor: DefaultStyle.main1_500_main numericPadButton.visible: text.length === 0 numericPadButton.checkable: false @@ -293,7 +299,8 @@ Item { focus: visible icon.width: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp) - text: qsTr("Désactiver ne pas déranger") + //: "Désactiver ne pas déranger" + text: qsTr("contact_presence_status_disable_do_not_disturb") icon.source: AppIcons.bellDnd onClicked: { deactivateDndButton.popup.close() @@ -349,10 +356,9 @@ Item { UtilsCpp.createCall( accountProxy.defaultAccount.core.voicemailAddress) else - UtilsCpp.showInformationPopup( - qsTr("Erreur"), qsTr( - "L'URI de messagerie vocale n'est pas définie."), - false) + UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), + //: "L'URI de messagerie vocale n'est pas définie." + qsTr("no_voicemail_uri_error_message"), false) } } } @@ -360,7 +366,10 @@ Item { id: avatarButton Layout.preferredWidth: Math.round(54 * DefaultStyle.dp) Layout.preferredHeight: width - popup.padding: Math.round(14 * DefaultStyle.dp) + 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 @@ -407,7 +416,9 @@ Item { visible: !SettingsCpp.hideAccountSettings icon.width: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp) - text: qsTr("Mon compte") + + //: Mon compte + text: qsTr("drawer_menu_manage_account") icon.source: AppIcons.manageProfile onClicked: openAccountSettings( accountProxy.defaultAccount ? accountProxy.defaultAccount : accountProxy.firstAccount()) @@ -423,8 +434,9 @@ Item { Layout.fillWidth: true icon.width: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp) - text: SettingsCpp.dnd ? qsTr("Désactiver ne pas déranger") : qsTr( - "Activer ne pas déranger") + 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() @@ -443,7 +455,7 @@ Item { visible: !SettingsCpp.hideSettings icon.width: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp) - text: qsTr("Paramètres") + text: qsTr("settings_title") icon.source: AppIcons.settings onClicked: openContextualMenuComponent( settingsPageComponent) @@ -460,7 +472,8 @@ Item { visible: !SettingsCpp.disableCallRecordings icon.width: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp) - text: qsTr("Enregistrements") + //: "Enregistrements" + text: qsTr("recordings_title") icon.source: AppIcons.micro KeyNavigation.up: visibleChildren.length != 0 ? settingsMenuButton.getPreviousItem( @@ -474,7 +487,8 @@ Item { Layout.fillWidth: true icon.width: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp) - text: qsTr("Aide") + //: "Aide" + text: qsTr("help_title") icon.source: AppIcons.question onClicked: openContextualMenuComponent( helpPageComponent) @@ -490,15 +504,13 @@ Item { Layout.fillWidth: true icon.width: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp) - text: qsTr("Quitter Linphone") + //: "Quitter l'application" + text: qsTr("help_quit_title") icon.source: AppIcons.power onClicked: { settingsMenuButton.popup.close() - UtilsCpp.getMainWindow( - ).showConfirmationLambdaPopup( - "", qsTr( - "Quitter Linphone ?"), - "", + //: "Quitter %1 ?" + UtilsCpp.getMainWindow().showConfirmationLambdaPopup("", qsTr("quit_app_question").arg(applicationName),"", function (confirmed) { if (confirmed) { console.info("Exiting App from Top Menu") @@ -526,7 +538,8 @@ Item { || SettingsCpp.maxAccount > accountProxy.count icon.width: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp) - text: qsTr("Ajouter un compte") + //: "Ajouter un compte" + text: qsTr("drawer_menu_add_account") icon.source: AppIcons.plusCircle onClicked: mainItem.addAccountRequest() KeyNavigation.up: visibleChildren.length diff --git a/Linphone/view/Page/Layout/Settings/AbstractSettingsLayout.qml b/Linphone/view/Page/Layout/Settings/AbstractSettingsLayout.qml index b0a49ca5d..f0db99974 100644 --- a/Linphone/view/Page/Layout/Settings/AbstractSettingsLayout.qml +++ b/Linphone/view/Page/Layout/Settings/AbstractSettingsLayout.qml @@ -80,7 +80,8 @@ Rectangle { MediumButton { id: saveButton style: ButtonStyle.main - text: qsTr("Enregistrer") + //: "Enregistrer" + text: qsTr("save") Layout.rightMargin: Math.round(6 * DefaultStyle.dp) visible: mainItem.saveButtonVisible onClicked: { diff --git a/Linphone/view/Page/Layout/Settings/AccountSettingsGeneralLayout.qml b/Linphone/view/Page/Layout/Settings/AccountSettingsGeneralLayout.qml index ed3356200..fda798321 100644 --- a/Linphone/view/Page/Layout/Settings/AccountSettingsGeneralLayout.qml +++ b/Linphone/view/Page/Layout/Settings/AccountSettingsGeneralLayout.qml @@ -15,13 +15,17 @@ AbstractSettingsLayout { width: parent?.width contentModel: [ { - title: qsTr("Détails"), - subTitle: qsTr("Editer les informations de votre compte."), + //: "Détails" + title: qsTr("manage_account_details_title"), + //: Éditer les informations de votre compte. + subTitle: qsTr("manage_account_details_subtitle"), contentComponent: accountParametersComponent }, { - title: qsTr("Vos appareils"), - subTitle: qsTr("La liste des appareils connectés à votre compte. Vous pouvez retirer les appareils que vous n’utilisez plus."), + //: "Vos appareils" + title: qsTr("manage_account_devices_title"), + //: "La liste des appareils connectés à votre compte. Vous pouvez retirer les appareils que vous n’utilisez plus." + subTitle: qsTr("manage_account_devices_subtitle"), contentComponent: accountDevicesComponent } ] @@ -50,7 +54,8 @@ AbstractSettingsLayout { icon.source: AppIcons.camera icon.width: Math.round(17 * DefaultStyle.dp) icon.height: Math.round(17 * DefaultStyle.dp) - text: qsTr("Ajouter une image") + //: "Ajouter une image" + text: qsTr("manage_account_add_picture") style: ButtonStyle.noBackground onClicked: fileDialog.open() Layout.alignment: Qt.AlignHCenter @@ -64,7 +69,8 @@ AbstractSettingsLayout { icon.source: AppIcons.pencil icon.width: Math.round(17 * DefaultStyle.dp) icon.height: Math.round(17 * DefaultStyle.dp) - text: qsTr("Modifier l'image") + //: "Modifier l'image" + text: qsTr("manage_account_edit_picture") style: ButtonStyle.noBackground onClicked: fileDialog.open() } @@ -73,7 +79,8 @@ AbstractSettingsLayout { icon.source: AppIcons.trashCan icon.width: Math.round(17 * DefaultStyle.dp) icon.height: Math.round(17 * DefaultStyle.dp) - text: qsTr("Supprimer l'image") + //: "Supprimer l'image" + text: qsTr("manage_account_remove_picture") style: ButtonStyle.noBackground onClicked: model.core.pictureUri = "" } @@ -94,7 +101,7 @@ AbstractSettingsLayout { spacing: Math.round(5 * DefaultStyle.dp) Text { Layout.alignment: Qt.AlignLeft - text: qsTr("Adresse SIP :") + text: "%1 :".arg(qsTr("sip_address")) color: DefaultStyle.main2_600 font: Typography.p2l } @@ -118,12 +125,14 @@ AbstractSettingsLayout { spacing: Math.round(5 * DefaultStyle.dp) Layout.alignment: Qt.AlignLeft Text { - text: qsTr("Nom d’affichage") + //: "Nom d'affichage + text: qsTr("sip_address_display_name") color: DefaultStyle.main2_600 font: Typography.p2l } Text { - text: qsTr("Le nom qui sera affiché à vos correspondants lors de vos échanges.") + //: "Le nom qui sera affiché à vos correspondants lors de vos échanges." + text: qsTr("sip_address_display_name_explaination") color: DefaultStyle.main2_600 font: Typography.p1 } @@ -140,7 +149,8 @@ AbstractSettingsLayout { toValidate: true } Text { - text: qsTr("Indicatif international*") + //: "Indicatif international*" + text: qsTr("manage_account_international_prefix") color: DefaultStyle.main2_600 font: Typography.p2l } @@ -165,14 +175,16 @@ AbstractSettingsLayout { ColumnLayout { spacing : Math.round(5 * DefaultStyle.dp) Text { - text: qsTr("Supprimer mon compte") + //: "Déconnecter mon compte" + text: qsTr("manage_account_delete") font: Typography.p2l wrapMode: Text.WordWrap color: DefaultStyle.danger_500main Layout.fillWidth: true } Text { - text: qsTr("Votre compte sera retiré de ce client linphone, mais vous restez connecté sur vos autres clients") + // "Votre compte sera retiré de ce client linphone, mais vous restez connecté sur vos autres clients + text: qsTr("manage_account_delete_message") font: Typography.p1 wrapMode: Text.WordWrap color: DefaultStyle.main2_500main @@ -190,8 +202,10 @@ AbstractSettingsLayout { onClicked: { var mainWin = UtilsCpp.getMainWindow() mainWin.showConfirmationLambdaPopup("", - qsTr("Supprimer ") + (model.core.displayName.length > 0 ? model.core.displayName : qsTr("le compte")) + " ?", - qsTr("Vous pouvez vous reconnecter à tout moment en cliquant sur \"Ajouter un compte\".\nCependant toutes les informations stockées sur ce périphérique seront supprimées."), + //: "Se déconnecter du compte ?" + qsTr("manage_account_dialog_remove_account_title"), + //: Si vous souhaitez supprimer définitivement votre compte rendez-vous sur : https://sip.linphone.org + qsTr("manage_account_dialog_remove_account_message"), function (confirmed) { if (confirmed) { account.core.removeAccount() @@ -247,7 +261,8 @@ AbstractSettingsLayout { onDevicesSet: devices.loading = false; onRequestError: (errorMessage) => { devices.loading = false; - mainWindow.showInformationPopup(qsTr("Erreur"), errorMessage, false) + //: Erreur + mainWindow.showInformationPopup(qsTr("error"), errorMessage, false) } } Control.Control { @@ -284,7 +299,8 @@ AbstractSettingsLayout { } MediumButton { Layout.alignment: Qt.AlignRight - text: qsTr("Supprimer") + //: "Supprimer" + text: qsTr("manage_account_device_remove") icon.source: AppIcons.trashCan icon.width: Math.round(16 * DefaultStyle.dp) icon.height: Math.round(16 * DefaultStyle.dp) @@ -292,7 +308,8 @@ AbstractSettingsLayout { onClicked: { var mainWin = UtilsCpp.getMainWindow() mainWin.showConfirmationLambdaPopup("", - qsTr("Supprimer ") + modelData.core.deviceName + " ?", "", + //:"Supprimer %1 ?" + qsTr("manage_account_device_remove_confirm_dialog").arg(modelData.core.deviceName), "", function (confirmed) { if (confirmed) { accountDeviceProxy.deleteDevice(modelData) @@ -305,7 +322,8 @@ AbstractSettingsLayout { RowLayout { spacing: Math.round(5 * DefaultStyle.dp) Text { - text: qsTr("Dernière connexion:") + //: "Dernière connexion:" + text: qsTr("manage_account_device_last_connection") color: DefaultStyle.main2_600 font: Typography.p2 } diff --git a/Linphone/view/Page/Layout/Settings/AccountSettingsParametersLayout.qml b/Linphone/view/Page/Layout/Settings/AccountSettingsParametersLayout.qml index b6759a54b..bdfa25824 100644 --- a/Linphone/view/Page/Layout/Settings/AccountSettingsParametersLayout.qml +++ b/Linphone/view/Page/Layout/Settings/AccountSettingsParametersLayout.qml @@ -11,11 +11,11 @@ AbstractSettingsLayout { id: mainItem width: parent?.width contentModel: [{ - "title": qsTr("Paramètres"), + "title": qsTr("settings_title"), "subTitle": "", "contentComponent": generalParametersComponent }, { - "title": qsTr("Paramètres de compte"), + "title": qsTr("settings_account_title"), "subTitle": "", "contentComponent": advancedParametersComponent }] @@ -31,8 +31,9 @@ AbstractSettingsLayout { function onIsSavedChanged() { if (account.core.isSaved) UtilsCpp.showInformationPopup( - qsTr("Succès"), - qsTr("Les changements ont été sauvegardés"), true, + qsTr("information_popup_success_title"), + //: "Modifications sauvegardés" + qsTr("contact_editor_saved_changes_toast"), true, mainWindow) } } @@ -48,7 +49,8 @@ AbstractSettingsLayout { DecoratedTextField { propertyName: "mwiServerAddress" propertyOwnerGui: account - title: qsTr("URI du serveur de messagerie vocale") + //: "URI du serveur de messagerie vocale" + title: qsTr("account_settings_mwi_uri_title") Layout.fillWidth: true isValid: function (text) { return text.length == 0 || !text.endsWith(".") @@ -58,7 +60,9 @@ AbstractSettingsLayout { DecoratedTextField { propertyName: "voicemailAddress" propertyOwnerGui: account - title: qsTr("URI de messagerie vocale") + //: "URI de messagerie vocale" + + title: qsTr("account_settings_voicemail_uri_title") Layout.fillWidth: true toValidate: true } @@ -73,7 +77,8 @@ AbstractSettingsLayout { Layout.fillWidth: true spacing: Math.round(20 * DefaultStyle.dp) Text { - text: qsTr("Transport") + //: "Transport" + text: qsTr("account_settings_transport_title") color: DefaultStyle.main2_600 font: Typography.p2l } @@ -86,13 +91,15 @@ AbstractSettingsLayout { } DecoratedTextField { Layout.fillWidth: true - title: qsTr("URL du serveur mandataire") + //:"URL du serveur mandataire" + title: qsTr("account_settings_sip_proxy_url_title") propertyName: "serverAddress" propertyOwnerGui: account toValidate: true } SwitchSetting { - titleText: qsTr("Serveur mandataire sortant") + //: "Serveur mandataire sortant" + titleText: qsTr("account_settings_outbound_proxy_title") propertyName: "outboundProxyEnabled" propertyOwnerGui: account } @@ -100,21 +107,25 @@ AbstractSettingsLayout { Layout.fillWidth: true propertyName: "stunServer" propertyOwnerGui: account - title: qsTr("Adresse du serveur STUN") + //: "Adresse du serveur STUN" + title: qsTr("account_settings_stun_server_url_title") toValidate: true } SwitchSetting { - titleText: qsTr("Activer ICE") + //: "Activer ICE" + titleText: qsTr("account_settings_enable_ice_title") propertyName: "iceEnabled" propertyOwnerGui: account } SwitchSetting { - titleText: qsTr("AVPF") + //: "AVPF" + titleText: qsTr("account_settings_avpf_title") propertyName: "avpfEnabled" propertyOwnerGui: account } SwitchSetting { - titleText: qsTr("Mode bundle") + //: "Mode bundle" + titleText: qsTr("account_settings_bundle_mode_title") propertyName: "bundleModeEnabled" propertyOwnerGui: account } @@ -122,7 +133,8 @@ AbstractSettingsLayout { Layout.fillWidth: true propertyName: "expire" propertyOwnerGui: account - title: qsTr("Expiration (en seconde)") + //: "Expiration (en seconde)" + title: qsTr("account_settings_expire_title") canBeEmpty: false isValid: function (text) { return !isNaN(Number(text)) @@ -131,21 +143,24 @@ AbstractSettingsLayout { } DecoratedTextField { Layout.fillWidth: true - title: qsTr("URI de l’usine à conversations") + //: "URI du serveur de conversations" + title: qsTr("account_settings_conference_factory_uri_title") propertyName: "conferenceFactoryAddress" propertyOwnerGui: account toValidate: true } DecoratedTextField { Layout.fillWidth: true - title: qsTr("URI de l’usine à réunions") propertyName: "audioVideoConferenceFactoryAddress" + //: "URI du serveur de réunions" + title: qsTr("account_settings_audio_video_conference_factory_uri_title") propertyOwnerGui: account toValidate: true } DecoratedTextField { Layout.fillWidth: true - title: qsTr("URL du serveur d’échange de clés de chiffrement") + //: "URL du serveur d’échange de clés de chiffrement" + title: qsTr("account_settings_lime_server_url_title") propertyName: "limeServerUrl" propertyOwnerGui: account toValidate: true diff --git a/Linphone/view/Page/Layout/Settings/AdvancedSettingsLayout.qml b/Linphone/view/Page/Layout/Settings/AdvancedSettingsLayout.qml index 5ccf0236d..128bfadb5 100644 --- a/Linphone/view/Page/Layout/Settings/AdvancedSettingsLayout.qml +++ b/Linphone/view/Page/Layout/Settings/AdvancedSettingsLayout.qml @@ -12,28 +12,33 @@ AbstractSettingsLayout { width: parent?.width contentModel: [ { - title: qsTr("Système"), + //: "Système" + title: qsTr("settings_system_title"), subTitle: "", contentComponent: systemComponent }, { - title: qsTr("Configuration distante"), + //: "Configuration distante" + title: qsTr("settings_remote_provisioning_title"), subTitle: "", contentComponent: remoteProvisioningComponent, hideTopSeparator: true }, { - title: qsTr("Sécurité / Chiffrement"), + //: "Sécurité / Chiffrement" + title: qsTr("settings_security_title"), subTitle: "", contentComponent: securityComponent, }, { - title: qsTr("Codecs audio"), + //: "Codecs audio" + title: qsTr("settings_advanced_audio_codecs_title"), subTitle: "", contentComponent: audioCodecsComponent, }, { - title: qsTr("Codecs vidéo"), + //: "Codecs vidéo" + title: qsTr("settings_advanced_video_codecs_title"), subTitle: "", contentComponent: videoCodecsComponent }, @@ -58,7 +63,8 @@ AbstractSettingsLayout { spacing: Math.round(40 * DefaultStyle.dp) SwitchSetting { Layout.fillWidth: true - titleText: qsTr("Démarrer automatiquement Linphone") + //: "Démarrer automatiquement Linphone" + titleText: qsTr("settings_advanced_auto_start_title") propertyName: "autoStart" propertyOwner: SettingsCpp } @@ -75,20 +81,23 @@ AbstractSettingsLayout { DecoratedTextField { Layout.fillWidth: true id: configUri - title: qsTr("URL de configuration distante") + //: "URL de configuration distante" + title: qsTr("settings_advanced_remote_provisioning_url") toValidate: true } SmallButton { Layout.topMargin: -Math.round(20 * DefaultStyle.dp) Layout.alignment: Qt.AlignRight - text: qsTr("Télécharger et appliquer") + //: "Télécharger et appliquer" + text: qsTr("settings_advanced_download_apply_remote_provisioning") style: ButtonStyle.tertiary onClicked: { var url = configUri.value() if (UtilsCpp.isValidURL(url)) UtilsCpp.useFetchConfig(configUri.value()) else - UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("Format d'url invalide"), false, UtilsCpp.getMainWindow()) + //: "Format d'url invalide" + UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), qsTr("settings_advanced_invalid_url_message"), false, UtilsCpp.getMainWindow()) } } } @@ -101,7 +110,8 @@ AbstractSettingsLayout { ColumnLayout { spacing: Math.round(5 * DefaultStyle.dp) Text { - text: qsTr("Chiffrement du média") + //: "Chiffrement du média" + text: qsTr("settings_advanced_media_encryption_title") font { pixelSize: Typography.p2l.pixelSize weight: Typography.p2l.weight @@ -118,7 +128,8 @@ AbstractSettingsLayout { } SwitchSetting { Layout.fillWidth: true - titleText: qsTr("Chiffrement du média obligatoire") + //: "Chiffrement du média obligatoire" + titleText: qsTr("settings_advanced_media_encryption_mandatory_title") propertyName: "mediaEncryptionMandatory" propertyOwner: SettingsCpp } @@ -213,7 +224,8 @@ AbstractSettingsLayout { ColumnLayout { spacing: Math.round(40 * DefaultStyle.dp) SwitchSetting { - titleText:qsTr("Cacher les FPS") + //:"Cacher les FPS" + titleText:qsTr("settings_advanced_hide_fps_title") propertyName: "hideFps" propertyOwner: SettingsCpp } diff --git a/Linphone/view/Page/Layout/Settings/CallSettingsLayout.qml b/Linphone/view/Page/Layout/Settings/CallSettingsLayout.qml index a03bec440..fac544515 100644 --- a/Linphone/view/Page/Layout/Settings/CallSettingsLayout.qml +++ b/Linphone/view/Page/Layout/Settings/CallSettingsLayout.qml @@ -16,8 +16,10 @@ AbstractSettingsLayout { contentComponent: genericParametersComponent }, { - title: qsTr("Périphériques"), - subTitle: qsTr("Vous pouvez modifier les périphériques de sortie audio, le microphone et la caméra de capture."), + //: "Périphériques" + title: qsTr("settings_call_devices_title"), + //: "Vous pouvez modifier les périphériques de sortie audio, le microphone et la caméra de capture." + subTitle: qsTr("settings_call_devices_subtitle"), contentComponent: multiMediaParametersComponent, customWidth: 540, customRightMargin: 36 @@ -37,15 +39,17 @@ AbstractSettingsLayout { ColumnLayout { spacing: Math.round(20 * DefaultStyle.dp) SwitchSetting { - titleText: qsTr("Annulateur d'écho") - subTitleText: qsTr("Évite que de l'écho soit entendu par votre correspondant") + //: "Annulateur d'écho" + titleText: qsTr("settings_calls_echo_canceller_title") + //: "Évite que de l'écho soit entendu par votre correspondant" + subTitleText: qsTr("settings_calls_echo_canceller_subtitle") propertyName: "echoCancellationEnabled" propertyOwner: SettingsCpp } SwitchSetting { Layout.fillWidth: true - titleText: qsTr("Activer l’enregistrement automatique des appels") - subTitleText: qsTr("Enregistrer tous les appels par défaut") + //: "Activer l’enregistrement automatique des appels" + titleText: qsTr("settings_calls_auto_record_title") propertyName: "automaticallyRecordCallsEnabled" propertyOwner: SettingsCpp visible: !SettingsCpp.disableCallRecordings @@ -57,8 +61,8 @@ AbstractSettingsLayout { propertyOwner: SettingsCpp } SwitchSetting { - titleText: qsTr("Vidéo") - subTitleText: qsTr("Autoriser la vidéo") + //: "Autoriser la vidéo" + titleText: qsTr("settings_calls_enable_video_title") propertyName: "videoEnabled" propertyOwner: SettingsCpp } diff --git a/Linphone/view/Page/Layout/Settings/CarddavSettingsLayout.qml b/Linphone/view/Page/Layout/Settings/CarddavSettingsLayout.qml index f2135bfe3..a64eba642 100644 --- a/Linphone/view/Page/Layout/Settings/CarddavSettingsLayout.qml +++ b/Linphone/view/Page/Layout/Settings/CarddavSettingsLayout.qml @@ -13,8 +13,10 @@ AbstractSettingsLayout { width: parent?.width contentModel: [ { - title: qsTr("Carnet d'adresse CardDAV"), - subTitle: qsTr("Ajouter un carnet d’adresse CardDAV pour synchroniser vos contacts Linphone avec un carnet d’adresse tiers."), + //: Carnet d'adresse CardDAV + title: qsTr("settings_contacts_carddav_title"), + //: "Ajouter un carnet d’adresse CardDAV pour synchroniser vos contacts Linphone avec un carnet d’adresse tiers." + subTitle: qsTr("settings_contacts_carddav_subtitle"), contentComponent: cardDavParametersComponent } ] @@ -25,16 +27,19 @@ AbstractSettingsLayout { if (carddavGui.core.isValid()) { carddavGui.core.save() } else { - UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("Vérifiez que toutes les informations ont été saisies."), false, mainWindow) + //: "Vérifiez que toutes les informations ont été saisies." + UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), qsTr("settings_contacts_carddav_popup_invalid_error"), false, mainWindow) } } Connections { target: carddavGui.core function onSaved(success) { if (success) - UtilsCpp.showInformationPopup(qsTr("Succès"), qsTr("Le carnet d'adresse CardDAV est synchronisé."), true, mainWindow) + //: "Le carnet d'adresse CardDAV est synchronisé." + UtilsCpp.showInformationPopup(qsTr("information_popup_synchronization_success_title"), qsTr("settings_contacts_carddav_synchronization_success_message"), true, mainWindow) else - UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("Erreur de synchronisation!"), false, mainWindow) + //: "Erreur de synchronisation!" + UtilsCpp.showInformationPopup(qsTr("settings_contacts_carddav_popup_synchronization_error_title"), qsTr("settings_contacts_carddav_popup_synchronization_error_message"), false, mainWindow) } } Component { @@ -50,7 +55,8 @@ AbstractSettingsLayout { onClicked: { var mainWin = UtilsCpp.getMainWindow() mainWin.showConfirmationLambdaPopup("", - qsTr("Supprimer le carnet d'adresse CardDAV ?"), + //: "Supprimer le carnet d'adresse CardDAV ?" + qsTr("settings_contacts_delete_carddav_server_title"), "", function (confirmed) { if (confirmed) { @@ -75,7 +81,8 @@ AbstractSettingsLayout { DecoratedTextField { propertyName: "displayName" propertyOwnerGui: carddavGui - title: qsTr("Nom d’affichage") + //: Nom d'affichage + title: qsTr("sip_address_display_name") canBeEmpty: false toValidate: true Layout.fillWidth: true @@ -83,7 +90,8 @@ AbstractSettingsLayout { DecoratedTextField { propertyName: "uri" propertyOwnerGui: carddavGui - title: qsTr("URL du serveur") + //: "URL du serveur" + title: qsTr("settings_contacts_carddav_server_url_title") canBeEmpty: false toValidate: true Layout.fillWidth: true @@ -91,7 +99,7 @@ AbstractSettingsLayout { DecoratedTextField { propertyName: "username" propertyOwnerGui: carddavGui - title: qsTr("Nom d’utilisateur") + title: qsTr("username") toValidate: true Layout.fillWidth: true } @@ -99,19 +107,21 @@ AbstractSettingsLayout { propertyName: "password" hidden: true propertyOwnerGui: carddavGui - title: qsTr("Mot de passe") + title: qsTr("password") toValidate: true Layout.fillWidth: true } DecoratedTextField { propertyName: "realm" propertyOwnerGui: carddavGui - title: qsTr("Domaine d’authentification") + //: Domaine d’authentification + title: qsTr("settings_contacts_carddav_realm_title") toValidate: true Layout.fillWidth: true } SwitchSetting { - titleText: qsTr("Stocker ici les contacts nouvellement crées") + //: "Stocker ici les contacts nouvellement crées" + titleText: qsTr("settings_contacts_carddav_use_as_default_title") propertyName: "storeNewFriendsInIt" propertyOwnerGui: carddavGui } diff --git a/Linphone/view/Page/Layout/Settings/ContactsSettingsLayout.qml b/Linphone/view/Page/Layout/Settings/ContactsSettingsLayout.qml index 4fd4ed8a4..419ce0120 100644 --- a/Linphone/view/Page/Layout/Settings/ContactsSettingsLayout.qml +++ b/Linphone/view/Page/Layout/Settings/ContactsSettingsLayout.qml @@ -10,14 +10,16 @@ AbstractSettingsLayout { width: parent?.width contentModel: [ { - title: qsTr("Annuaires LDAP"), - subTitle: qsTr("Ajouter vos annuaires LDAP pour pouvoir effectuer des recherches dans la magic search bar."), + //: Annuaires LDAP + title: qsTr("settings_contacts_ldap_title"), + //: "Ajouter vos annuaires LDAP pour pouvoir effectuer des recherches dans la magic search bar." + subTitle: qsTr("settings_contacts_ldap_subtitle"), contentComponent: ldapParametersComponent, hideTopMargin: true }, { - title: qsTr("Carnet d'adresse CardDAV"), - subTitle: qsTr("Ajouter un carnet d’adresse CardDAV pour synchroniser vos contacts Linphone avec un carnet d’adresse tiers."), + title: qsTr("settings_contacts_carddav_title"), + subTitle: qsTr("settings_contacts_carddav_subtitle"), contentComponent: cardDavParametersComponent, hideTopMargin: true } @@ -36,8 +38,10 @@ AbstractSettingsLayout { Component { id: ldapParametersComponent ContactsSettingsProviderLayout { - addText: qsTr("Ajouter un annuaire LDAP") - editText: qsTr("Modifier un annuaire LDAP") + //: "Ajouter un annuaire LDAP" + addText: qsTr("settings_contacts_add_ldap_server_title") + //: "Modifier un annuaire LDAP" + editText: qsTr("settings_contacts_edit_ldap_server_title") proxyModel: LdapProxy {} newItemGui: createGuiObject('Ldap') settingsLayout: layoutUrl("LdapSettingsLayout") @@ -61,8 +65,10 @@ AbstractSettingsLayout { id: cardDavParametersComponent ContactsSettingsProviderLayout { id: carddavProvider - addText: qsTr("Ajouter un carnet d'adresse CardDAV") - editText: qsTr("Modifier un carnet d'adresse CardDAV") + //: "Ajouter un carnet d'adresse CardDAV" + addText: qsTr("settings_contacts_add_carddav_server_title") + //: "Modifier un carnet d'adresse CardDAV" + editText: qsTr("settings_contacts_edit_carddav_server_title") 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 32d361fb8..c3385ed2d 100644 --- a/Linphone/view/Page/Layout/Settings/ContactsSettingsProviderLayout.qml +++ b/Linphone/view/Page/Layout/Settings/ContactsSettingsProviderLayout.qml @@ -89,7 +89,8 @@ RowLayout { Connections { target: modelData.core function onSavedChanged() { - if (modelData.core.saved) UtilsCpp.showInformationPopup(qsTr("Succès"), qsTr("Les changements ont été sauvegardés"), true, mainWindow) + //: "Les changements ont été sauvegardés" + if (modelData.core.saved) UtilsCpp.showInformationPopup(qsTr("information_popup_success_title"), qsTr("information_popup_changes_saved"), true, mainWindow) } } @@ -110,7 +111,8 @@ RowLayout { } MediumButton { Layout.alignment: Qt.AlignRight | Qt.AlignHCenter - text: qsTr("Ajouter") + //: "Ajouter" + text: qsTr("add") style: ButtonStyle.main visible: mainItem.showAddButton onClicked: { diff --git a/Linphone/view/Page/Layout/Settings/DebugSettingsLayout.qml b/Linphone/view/Page/Layout/Settings/DebugSettingsLayout.qml index d5de356cf..46b227b88 100644 --- a/Linphone/view/Page/Layout/Settings/DebugSettingsLayout.qml +++ b/Linphone/view/Page/Layout/Settings/DebugSettingsLayout.qml @@ -28,7 +28,8 @@ AbstractSettingsLayout { Dialog { id: deleteLogs - text: qsTr("Les traces de débogage seront supprimées. Souhaitez-vous continuer ?") + //: "Les traces de débogage seront supprimées. Souhaitez-vous continuer ?" + text: qsTr("settings_debug_clean_logs_message") onAccepted: SettingsCpp.cleanLogs() } @@ -38,10 +39,12 @@ AbstractSettingsLayout { Dialog { id: shareLogs - text: qsTr("Les traces de débogage ont été téléversées. Comment souhaitez-vous partager le lien ? ") + //: "Les traces de débogage ont été téléversées. Comment souhaitez-vous partager le lien ? " + text: qsTr("settings_debug_share_logs_message") buttons: [ BigButton { - text: qsTr("Presse-papier") + //: "Presse-papier" + text: qsTr("settings_debug_clipboard") style: ButtonStyle.main onClicked: { shareLogs.close() @@ -49,16 +52,20 @@ AbstractSettingsLayout { } }, BigButton { - text: qsTr("E-Mail") + //: "E-Mail" + text: qsTr("settings_debug_email") style: ButtonStyle.main onClicked: { shareLogs.close() - if(!Qt.openUrlExternally( - 'mailto:' + encodeURIComponent(SettingsCpp.logsEmail) + - '?subject=' + encodeURIComponent(qsTr('Traces Linphone')) + - '&body=' + encodeURIComponent(mainItem.logsUrl) + //: "Traces %1" + if(!Qt.openUrlExternally("mailto:%1%2%3%4%5".arg(encodeURIComponent(SettingsCpp.logsEmail)) + .arg('?subject=').arg(encodeURIComponent(qsTr("debug_settings_trace").arg(applicationName))) + .arg('&body=').arg(encodeURIComponent(mainItem.logsUrl)) )) - UtilsCpp.showInformationPopup(qsTr("Une erreur est survenue."), qsTr("Le partage par mail a échoué. Veuillez envoyer le lien %1 directement à l'adresse %2.").replace("%1",mainItem.logsUrl).replace("%2",SettingsCpp.logsEmail), false) + //: Une erreur est survenue. + UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), + //: "Le partage par mail a échoué. Veuillez envoyer le lien %1 directement à l'adresse %2." + qsTr("information_popup_email_sharing_failed").arg(mainItem.logsUrl).arg(SettingsCpp.logsEmail), false) } } ] @@ -69,12 +76,14 @@ AbstractSettingsLayout { ColumnLayout { spacing: Math.round(20 * DefaultStyle.dp) SwitchSetting { - titleText: qsTr("Activer les traces de débogage") + //: "Activer les traces de débogage" + titleText: qsTr("settings_debug_enable_logs_title") propertyName: "logsEnabled" propertyOwner: SettingsCpp } SwitchSetting { - titleText: qsTr("Activer les traces de débogage intégrales") + //: "Activer les traces de débogage intégrales" + titleText: qsTr("settings_debug_enable_full_logs_title") propertyName: "fullLogsEnabled" propertyOwner: SettingsCpp } @@ -83,17 +92,20 @@ AbstractSettingsLayout { Layout.alignment: Qt.AlignRight MediumButton { style: ButtonStyle.tertiary - text: qsTr("Supprimer les traces") + //: "Supprimer les traces" + text: qsTr("settings_debug_delete_logs_title") onClicked: { deleteLogs.open() } } MediumButton { style: ButtonStyle.tertiary - text: qsTr("Partager les traces") + //: "Partager les traces" + text: qsTr("settings_debug_share_logs_title") enabled: SettingsCpp.logsEnabled || SettingsCpp.fullLogsEnabled onClicked: { - UtilsCpp.getMainWindow().showLoadingPopup(qsTr("Téléversement des traces en cours ...")) + //: "Téléversement des traces en cours …" + UtilsCpp.getMainWindow().showLoadingPopup(qsTr("settings_debug_share_logs_loading_message")) SettingsCpp.sendLogs() } } @@ -117,7 +129,8 @@ AbstractSettingsLayout { } ColumnLayout { Text { - text: qsTr("Version de l'application") + //: "Version de l'application" + text: qsTr("settings_debug_app_version_title") font: Typography.p2l wrapMode: Text.WordWrap color: DefaultStyle.main2_600 @@ -145,7 +158,8 @@ AbstractSettingsLayout { } ColumnLayout { Text { - text: qsTr("Version du SDK") + //: "Version du SDK" + text: qsTr("settings_debug_sdk_version_title") font: Typography.p2l wrapMode: Text.WordWrap color: DefaultStyle.main2_600 @@ -172,7 +186,9 @@ AbstractSettingsLayout { mainItem.logsUrl = url shareLogs.open() } else { - UtilsCpp.showInformationPopup(qsTr("Une erreur est survenue."), qsTr("Le téléversement des traces a échoué. Vous pouvez partager les fichiers de trace directement depuis le répertoire suivant :") + SettingsCpp.logsFolder, false) + UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), + //: "Le téléversement des traces a échoué. Vous pouvez partager les fichiers de trace directement depuis le répertoire suivant : %1" + qsTr("settings_debug_share_logs_error").arg(SettingsCpp.logsFolder), false) } } } diff --git a/Linphone/view/Page/Layout/Settings/LdapSettingsLayout.qml b/Linphone/view/Page/Layout/Settings/LdapSettingsLayout.qml index 8184aed7c..a2c20adfc 100644 --- a/Linphone/view/Page/Layout/Settings/LdapSettingsLayout.qml +++ b/Linphone/view/Page/Layout/Settings/LdapSettingsLayout.qml @@ -13,8 +13,8 @@ AbstractSettingsLayout { width: parent?.width contentModel: [ { - title: qsTr("Annuaires LDAP"), - subTitle: qsTr("Ajouter vos annuaires LDAP pour pouvoir effectuer des recherches dans la magic search bar."), + title: qsTr("settings_contacts_ldap_title"), + subTitle: qsTr("settings_contacts_ldap_subtitle"), contentComponent: ldapParametersComponent } ] @@ -26,9 +26,11 @@ AbstractSettingsLayout { onSave: { if (ldapGui.core.isValid()) { ldapGui.core.save() - UtilsCpp.showInformationPopup(qsTr("Succès"), qsTr("L'annuaire LDAP a été sauvegardé"), true, mainWindow) + //: "L'annuaire LDAP a été sauvegardé" + UtilsCpp.showInformationPopup(qsTr("information_popup_success_title"), qsTr("settings_contacts_ldap_success_toast"), true, mainWindow) } else { - UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("Une erreur s'est produite, la configuration LDAP n'a pas été sauvegardée !"), false, mainWindow) + //: "Une erreur s'est produite, la configuration LDAP n'a pas été sauvegardée !" + UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), qsTr("settings_contacts_ldap_error_toast"), false, mainWindow) } } @@ -45,7 +47,8 @@ AbstractSettingsLayout { onClicked: { var mainWin = UtilsCpp.getMainWindow() mainWin.showConfirmationLambdaPopup("", - qsTr("Supprimer l'annuaire LDAP ?"), + //: "Supprimer l'annuaire LDAP ?" + qsTr("settings_contacts_ldap_delete_confirmation_message"), "", function (confirmed) { if (confirmed) { @@ -71,14 +74,16 @@ AbstractSettingsLayout { id: server propertyName: "serverUrl" propertyOwnerGui: ldapGui - title: qsTr("URL du serveur (ne peut être vide)") + //: "URL du serveur (ne peut être vide)" + title: qsTr("settings_contacts_ldap_server_url_title") toValidate: true Layout.fillWidth: true } DecoratedTextField { propertyName: "bindDn" propertyOwnerGui: ldapGui - title: qsTr("Bind DN") + //: "Bind DN" + title: qsTr("settings_contacts_ldap_bind_dn_title") toValidate: true Layout.fillWidth: true } @@ -86,26 +91,30 @@ AbstractSettingsLayout { propertyName: "password" hidden: true propertyOwnerGui: ldapGui - title: qsTr("Mot de passe") + //: "Mot de passe" + title: qsTr("settings_contacts_ldap_password_title") toValidate: true Layout.fillWidth: true } SwitchSetting { - titleText: qsTr("Utiliser TLS") + //: "Utiliser TLS" + titleText: qsTr("settings_contacts_ldap_use_tls_title") propertyName: "tls" propertyOwnerGui: ldapGui } DecoratedTextField { propertyName: "baseObject" propertyOwnerGui: ldapGui - title: qsTr("Base de recherche (ne peut être vide)") + //: "Base de recherche (ne peut être vide)" + title: qsTr("settings_contacts_ldap_search_base_title") toValidate: true Layout.fillWidth: true } DecoratedTextField { propertyName: "filter" propertyOwnerGui: ldapGui - title: qsTr("Filtre") + //: "Filtre" + title: qsTr("settings_contacts_ldap_search_filter_title") toValidate: true Layout.fillWidth: true } @@ -113,7 +122,8 @@ AbstractSettingsLayout { propertyName: "limit" propertyOwnerGui: ldapGui validator: RegularExpressionValidator { regularExpression: /[0-9]+/ } - title: qsTr("Nombre maximum de résultats") + //: "Nombre maximum de résultats" + title: qsTr("settings_contacts_ldap_max_results_title") toValidate: true Layout.fillWidth: true } @@ -121,14 +131,16 @@ AbstractSettingsLayout { propertyName: "delay" propertyOwnerGui: ldapGui validator: RegularExpressionValidator { regularExpression: /[0-9]+/ } - title: qsTr("Délai entre 2 requêtes (en millisecondes)") + //: "Délai entre 2 requêtes (en millisecondes)" + title: qsTr("settings_contacts_ldap_request_delay_title") toValidate: true Layout.fillWidth: true } DecoratedTextField { propertyName: "timeout" propertyOwnerGui: ldapGui - title: qsTr("Durée maximun (en secondes)") + //: "Durée maximun (en secondes)" + title: qsTr("settings_contacts_ldap_request_timeout_title") validator: RegularExpressionValidator { regularExpression: /[0-9]+/ } toValidate: true Layout.fillWidth: true @@ -136,7 +148,8 @@ AbstractSettingsLayout { DecoratedTextField { propertyName: "minCharacters" propertyOwnerGui: ldapGui - title: qsTr("Nombre minimum de caractères pour la requête") + //: "Nombre minimum de caractères pour la requête" + title: qsTr("settings_contacts_ldap_min_characters_title") validator: RegularExpressionValidator { regularExpression: /[0-9]+/ } toValidate: true Layout.fillWidth: true @@ -144,26 +157,30 @@ AbstractSettingsLayout { DecoratedTextField { propertyName: "nameAttribute" propertyOwnerGui: ldapGui - title: qsTr("Attributs de nom") + //: "Attributs de nom" + title: qsTr("settings_contacts_ldap_name_attributes_title") toValidate: true Layout.fillWidth: true } DecoratedTextField { propertyName: "sipAttribute" propertyOwnerGui: ldapGui - title: qsTr("Attributs SIP") + //: "Attributs SIP" + title: qsTr("settings_contacts_ldap_sip_attributes_title") toValidate: true Layout.fillWidth: true } DecoratedTextField { propertyName: "sipDomain" propertyOwnerGui: ldapGui - title: qsTr("Domaine SIP") + //: "Domaine SIP" + title: qsTr("settings_contacts_ldap_sip_domain_title") toValidate: true Layout.fillWidth: true } SwitchSetting { - titleText: qsTr("Débogage") + //: "Débogage" + titleText: qsTr("settings_contacts_ldap_debug_title") propertyName: "debug" propertyOwnerGui: ldapGui } diff --git a/Linphone/view/Page/Layout/Settings/MeetingsSettingsLayout.qml b/Linphone/view/Page/Layout/Settings/MeetingsSettingsLayout.qml index 4ca7e4ce4..0bb694f18 100644 --- a/Linphone/view/Page/Layout/Settings/MeetingsSettingsLayout.qml +++ b/Linphone/view/Page/Layout/Settings/MeetingsSettingsLayout.qml @@ -11,7 +11,8 @@ AbstractSettingsLayout { width: parent?.width contentModel: [ { - title: qsTr("Affichage"), + //: "Affichage" + title: qsTr("settings_meetings_display_title"), subTitle: "", contentComponent: confDisplayParametersComponent, hideTopMargin: true @@ -28,14 +29,16 @@ AbstractSettingsLayout { ColumnLayout { spacing: Math.round(5 * DefaultStyle.dp) Text { - text: qsTr("Mode d’affichage par défaut") + //: "Mode d’affichage par défaut" + text: qsTr("settings_meetings_default_layout_title") font { pixelSize: Typography.p2l.pixelSize weight: Typography.p2l.weight } } Text { - text: qsTr("Le mode d’affichage des participants en réunions") + //: "Le mode d’affichage des participants en réunions" + text: qsTr("settings_meetings_default_layout_subtitle") font { pixelSize: Typography.p1.pixelSize weight: Typography.p1.weight diff --git a/Linphone/view/Page/Layout/Settings/NetworkSettingsLayout.qml b/Linphone/view/Page/Layout/Settings/NetworkSettingsLayout.qml index 49ba4c930..268046f64 100644 --- a/Linphone/view/Page/Layout/Settings/NetworkSettingsLayout.qml +++ b/Linphone/view/Page/Layout/Settings/NetworkSettingsLayout.qml @@ -10,7 +10,8 @@ AbstractSettingsLayout { width: parent?.width contentModel: [ { - title: qsTr("Réseau"), + //: "Réseau" + title: qsTr("settings_network_title"), subTitle: "", contentComponent: content } @@ -26,7 +27,8 @@ AbstractSettingsLayout { spacing: Math.round(40 * DefaultStyle.dp) SwitchSetting { Layout.fillWidth: true - titleText: qsTr("Autoriser l'IPv6") + //: "Autoriser l'IPv6" + titleText: qsTr("settings_network_allow_ipv6") propertyName: "ipv6Enabled" propertyOwner: SettingsCpp } diff --git a/Linphone/view/Page/Layout/Settings/SecuritySettingsLayout.qml b/Linphone/view/Page/Layout/Settings/SecuritySettingsLayout.qml index e2127e479..5b681919e 100644 --- a/Linphone/view/Page/Layout/Settings/SecuritySettingsLayout.qml +++ b/Linphone/view/Page/Layout/Settings/SecuritySettingsLayout.qml @@ -25,8 +25,10 @@ AbstractSettingsLayout { ColumnLayout { spacing: Math.round(40 * DefaultStyle.dp) SwitchSetting { - titleText: qsTr("Chiffrer tous les fichiers") - subTitleText: qsTr("Attention, vous ne pourrez pas revenir en arrière !") + //: "Chiffrer tous les fichiers" + titleText: qsTr("settings_security_enable_vfs_title") + //: "Attention, vous ne pourrez pas revenir en arrière !" + subTitleText: qsTr("settings_security_enable_vfs_subtitle") propertyName: "vfsEnabled" propertyOwner: SettingsCpp } diff --git a/Linphone/view/Page/Main/Account/AccountListView.qml b/Linphone/view/Page/Main/Account/AccountListView.qml index 1bb225e45..006f98f7d 100644 --- a/Linphone/view/Page/Main/Account/AccountListView.qml +++ b/Linphone/view/Page/Main/Account/AccountListView.qml @@ -11,27 +11,24 @@ import SettingsCpp Item { id: mainItem width: Math.round(517 * DefaultStyle.dp) - readonly property real topPadding: Math.round(23 * DefaultStyle.dp) - readonly property real bottomPadding: Math.round(13 * DefaultStyle.dp) - readonly property real leftPadding: Math.round(24 * DefaultStyle.dp) - readonly property real rightPadding: Math.round(24 * DefaultStyle.dp) + readonly property real spacing: Math.round(16 * DefaultStyle.dp) property AccountProxy accountProxy signal addAccountRequest() - signal editAccount(AccountGui account) + signal editAccount(AccountGui account) - implicitHeight: list.contentHeight + topPadding + bottomPadding + Math.round(32 * DefaultStyle.dp) + 1 + addAccountButton.height + implicitHeight: list.contentHeight + Math.round(32 * DefaultStyle.dp) + 1 + addAccountButton.height ColumnLayout{ id: childLayout anchors.top: parent.top - anchors.topMargin: mainItem.topPadding + anchors.topMargin: mainItem.topPadding anchors.left: parent.left - anchors.leftMargin: mainItem.leftPadding + anchors.leftMargin: mainItem.leftPadding anchors.right: parent.right - anchors.rightMargin: mainItem.rightPadding + anchors.rightMargin: mainItem.rightPadding anchors.bottom: parent.bottom - anchors.bottomMargin: mainItem.bottomPadding + anchors.bottomMargin: mainItem.bottomPadding ListView{ id: list Layout.preferredHeight: contentHeight diff --git a/Linphone/view/Page/Main/Call/CallPage.qml b/Linphone/view/Page/Main/Call/CallPage.qml index 06f228c57..cad392f82 100644 --- a/Linphone/view/Page/Main/Call/CallPage.qml +++ b/Linphone/view/Page/Main/Call/CallPage.qml @@ -10,8 +10,10 @@ import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils AbstractMainPage { id: mainItem - noItemButtonText: qsTr("Nouvel appel") - emptyListText: qsTr("Historique d'appel vide") + //: "Nouvel appel" + noItemButtonText: qsTr("history_call_start_title") + //: "Historique d'appel vide" + emptyListText: qsTr("call_history_empty_title") newItemIconSource: AppIcons.newCall property var selectedRowHistoryGui @@ -79,14 +81,19 @@ AbstractMainPage { Dialog { id: deleteHistoryPopup - width: Math.round(278 * DefaultStyle.dp) - text: qsTr("L'historique d'appel sera supprimé. Souhaitez-vous continuer ?") + width: Math.round(637 * DefaultStyle.dp) + //: 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é." + text: qsTr("history_dialog_delete_all_call_logs_message") } Dialog { id: deleteForUserPopup - width: Math.round(278 * DefaultStyle.dp) - text: qsTr( - "L'historique d'appel de l'utilisateur sera supprimé. Souhaitez-vous continuer ?") + width: Math.round(637 * DefaultStyle.dp) + //: 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é." + text: qsTr("history_dialog_delete_call_logs_message") } leftPanelContent: Item { @@ -118,7 +125,6 @@ AbstractMainPage { visible: false onLaunchCall: { mainItem.createCallFromSearchBarRequested() - // TODO : auto completion instead of sip linphone } } } @@ -136,7 +142,9 @@ AbstractMainPage { id: titleCallLayout spacing: Math.round(16 * DefaultStyle.dp) Text { - text: qsTr("Appels") + Layout.fillWidth: true + //: "Appels" + text: qsTr("call_history_call_list_title") color: DefaultStyle.main2_700 font.pixelSize: Typography.h2.pixelSize font.weight: Typography.h2.weight @@ -156,7 +164,8 @@ AbstractMainPage { IconLabelButton { Layout.fillWidth: true focus: visible - text: qsTr("Supprimer l'historique") + //: "Supprimer l'historique" + text: qsTr("menu_delete_history") icon.source: AppIcons.trashCan style: ButtonStyle.hoveredBackgroundRed onClicked: { @@ -195,7 +204,8 @@ AbstractMainPage { Layout.fillWidth: true Layout.topMargin: Math.round(18 * DefaultStyle.dp) Layout.rightMargin: Math.round(39 * DefaultStyle.dp) - placeholderText: qsTr("Rechercher un appel") + //: "Rechercher un appel" + placeholderText: qsTr("call_search_in_history") visible: historyListView.count !== 0 || text.length !== 0 focus: true KeyNavigation.up: newCallButton @@ -221,8 +231,9 @@ AbstractMainPage { visible: historyListView.count === 0 Layout.alignment: Qt.AlignHCenter Layout.topMargin: Math.round(137 * DefaultStyle.dp) - text: qsTr("Aucun appel%1").arg( - searchBar.text.length != 0 ? " correspondant" : "") + //: "Aucun appel dans votre historique" + //: "Aucun résultat…" + text: searchBar.text.length != 0 ? qsTr("list_filter_no_result_found") : qsTr("history_list_empty_history") font { pixelSize: Typography.h4.pixelSize weight: Typography.h4.weight @@ -297,7 +308,9 @@ AbstractMainPage { } } Text { - text: qsTr("Nouvel appel") + Layout.fillWidth: true + //: "Nouvel appel" + text: qsTr("call_action_start_new_call") color: DefaultStyle.main2_700 font.pixelSize: Typography.h2.pixelSize font.weight: Typography.h2.weight @@ -364,7 +377,8 @@ AbstractMainPage { ColumnLayout { spacing: Math.round(3 * DefaultStyle.dp) Text { - text: qsTr("Appel de groupe") + //: "Appel de groupe" + text: qsTr("call_start_group_call_title") color: DefaultStyle.main1_500_main maximumLineCount: 1 font { @@ -374,9 +388,8 @@ AbstractMainPage { Layout.fillWidth: true } Text { - text: qsTr("%1 participant%2 sélectionné").arg( - mainItem.selectedParticipantsCount).arg( - mainItem.selectedParticipantsCount > 1 ? "s" : "") + //: "%n participant(s) sélectionné(s)" + text: qsTr("group_call_participant_selected").arg(mainItem.selectedParticipantsCount) color: DefaultStyle.main2_500main maximumLineCount: 1 font { @@ -390,7 +403,8 @@ AbstractMainPage { id: groupCallButton enabled: mainItem.selectedParticipantsCount.length != 0 Layout.rightMargin: Math.round(21 * DefaultStyle.dp) - text: qsTr("Lancer") + //: "Lancer" + text: qsTr("call_action_start_group_call") style: ButtonStyle.main KeyNavigation.down: listStackView KeyNavigation.left: backGroupCallButton @@ -407,7 +421,8 @@ AbstractMainPage { Text { font.pixelSize: Typography.p2.pixelSize font.weight: Typography.p2.weight - text: qsTr("Nom du groupe") + //: "Nom du groupe" + text: qsTr("history_group_call_start_dialog_subject_hint") } Item { Layout.fillWidth: true @@ -415,7 +430,8 @@ AbstractMainPage { Text { font.pixelSize: Math.round(12 * DefaultStyle.dp) font.weight: Math.round(300 * DefaultStyle.dp) - text: qsTr("Requis") + //: "Requis" + text: qsTr("required") } } TextField { @@ -438,14 +454,15 @@ AbstractMainPage { target: mainItem function onStartGroupCallRequested() { if (groupCallName.text.length === 0) { - UtilsCpp.showInformationPopup( - qsTr("Erreur"), qsTr( - "Un nom doit être donné à l'appel de groupe"), - false) + UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), + //: "Un nom doit être donné à l'appel de groupe + qsTr("group_call_error_must_have_name"), + false) } else if (!mainItem.isRegistered) { UtilsCpp.showInformationPopup( - qsTr("Erreur"), - qsTr("Vous n'etes pas connecté"), + qsTr("information_popup_error_title"), + //: "Vous n'etes pas connecté" + qsTr("group_call_error_not_connected"), false) } else { mainItem.confInfoGui = Qt.createQmlObject( @@ -515,8 +532,10 @@ ConferenceInfoGui{ || false property bool isCardDAV: contactDetail.contact?.core?.isCardDAV || false - text: contactDetail.contact ? qsTr("Voir le contact") : qsTr( - "Ajouter aux contacts") + //: "Voir le contact" + text: contactDetail.contact ? qsTr("menu_see_existing_contact") : + //: "Ajouter aux 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) @@ -534,7 +553,8 @@ ConferenceInfoGui{ } IconLabelButton { Layout.fillWidth: true - text: qsTr("Copier l'adresse SIP") + //: "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) @@ -545,13 +565,16 @@ ConferenceInfoGui{ && mainItem.selectedRowHistoryGui.core.remoteAddress) if (success) UtilsCpp.showInformationPopup( - qsTr("Copié"), qsTr( - "L'adresse a été copiée dans le presse-papier"), + //: Adresse copiée + qsTr("sip_address_copied_to_clipboard_toast"), + //: L'adresse a été copié dans le presse_papiers + qsTr("sip_address_copied_to_clipboard_message"), true) else UtilsCpp.showInformationPopup( - qsTr("Erreur"), qsTr( - "Erreur lors de la copie de l'adresse"), + qsTr("information_popup_error_title"), + //: "Erreur lors de la copie de l'adresse" + qsTr("sip_address_copy_to_clipboard_error"), false) } } @@ -572,7 +595,8 @@ ConferenceInfoGui{ IconLabelButton { Layout.fillWidth: true - text: qsTr("Supprimer l'historique") + //: "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) @@ -647,7 +671,13 @@ ConferenceInfoGui{ } } Text { - text: modelData.core.status === LinphoneEnums.CallStatus.Missed ? qsTr("Appel manqué") : modelData.core.isOutgoing ? qsTr("Appel sortant") : qsTr("Appel entrant") + //: "Appel manqué" + text: modelData.core.status === LinphoneEnums.CallStatus.Missed ? qsTr("notification_missed_call_title") + : modelData.core.isOutgoing + //: "Appel sortant" + ? qsTr("call_outgoing") + //: "Appel entrant" + : qsTr("call_audio_incoming") font { pixelSize: Typography.p1.pixelSize weight: Typography.p1.weight diff --git a/Linphone/view/Page/Main/Call/WaitingRoom.qml b/Linphone/view/Page/Main/Call/WaitingRoom.qml index adbd266fb..f29268312 100644 --- a/Linphone/view/Page/Main/Call/WaitingRoom.qml +++ b/Linphone/view/Page/Main/Call/WaitingRoom.qml @@ -93,7 +93,8 @@ RowLayout { spacing: 0 Text { Layout.fillWidth: true - text: qsTr("Participer à :") + //: Participer à : + text: qsTr("meeting_waiting_room_title") color: DefaultStyle.grey_0 font { pixelSize: Math.round(30 * DefaultStyle.dp) @@ -114,7 +115,8 @@ RowLayout { spacing: Math.round(5 * DefaultStyle.dp) BigButton { Layout.preferredWidth: Math.round(292 * DefaultStyle.dp) - text: qsTr("Rejoindre") + //: "Rejoindre" + text: qsTr("meeting_waiting_room_join") style: ButtonStyle.main onClicked: { settingsButton.checked = false @@ -125,7 +127,7 @@ RowLayout { BigButton { Layout.preferredWidth: Math.round(292 * DefaultStyle.dp) style: ButtonStyle.secondary - text: qsTr("Annuler") + text: qsTr("cancel") onClicked: { mainItem.cancelJoiningRequested() } @@ -138,7 +140,8 @@ RowLayout { spacing: Math.round(13 * DefaultStyle.dp) Text { Layout.fillWidth: true - text: qsTr("Connexion à la réunion") + //: "Connexion à la réunion" + text: qsTr("meeting_waiting_room_joining_title") color: DefaultStyle.grey_0 font { pixelSize: Math.round(30 * DefaultStyle.dp) @@ -147,7 +150,8 @@ RowLayout { } Text { Layout.fillWidth: true - text: qsTr("Vous allez rejoindre la réunion dans quelques instants...") + //: "Vous allez rejoindre la réunion dans quelques instants…" + text: qsTr("meeting_waiting_room_joining_subtitle") color: DefaultStyle.grey_0 font { pixelSize: Typography.p1.pixelSize @@ -165,7 +169,7 @@ RowLayout { Layout.preferredWidth: Math.round(292 * DefaultStyle.dp) Layout.alignment: Qt.AlignHCenter style: ButtonStyle.main - text: qsTr("Annuler") + text: qsTr("cancel") onClicked: { settingsButton.checked = false stackLayout.currentIndex = 1 diff --git a/Linphone/view/Page/Main/Contact/ContactPage.qml b/Linphone/view/Page/Main/Contact/ContactPage.qml index baf52c592..084035d80 100644 --- a/Linphone/view/Page/Main/Contact/ContactPage.qml +++ b/Linphone/view/Page/Main/Contact/ContactPage.qml @@ -10,8 +10,10 @@ import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle AbstractMainPage { id: mainItem - noItemButtonText: qsTr("Ajouter un contact") - emptyListText: qsTr("Aucun contact pour le moment") + //: "Ajouter un contact" + noItemButtonText: qsTr("contacts_add") + //: "Aucun contact pour le moment" + emptyListText: qsTr("contacts_list_empty") newItemIconSource: AppIcons.plusCircle // disable left panel contact list interaction while a contact is being edited @@ -69,16 +71,19 @@ FriendGui{ || rightPanelStackView.currentItem.objectName != "contactEdition") rightPanelStackView.push(contactEdition, { "contact": friendGui, - "title": qsTr("Nouveau contact"), - "saveButtonText": qsTr("Créer") + //: "Nouveau contact" + "title": qsTr("contact_new_title"), + // "Créer" + "saveButtonText": qsTr("create") }) } function editContact(friendGui) { rightPanelStackView.push(contactEdition, { "contact": friendGui, - "title": qsTr("Modifier contact"), - "saveButtonText": qsTr("Enregistrer") + //: "Modifier contact" + "title": qsTr("contact_edit_title"), + "saveButtonText": qsTr("save") }) } @@ -91,18 +96,21 @@ FriendGui{ return var mainWin = UtilsCpp.getMainWindow() mainWin.showConfirmationLambdaPopup( - "", qsTr( - "%1 sera supprimé des contacts. Voulez-vous continuer ?").arg( - contact.core.fullName), "", function (confirmed) { - if (confirmed) { - var name = contact.core.fullName - contact.core.remove() - contactList.resetSelections() - UtilsCpp.showInformationPopup( - qsTr("Supprimé"), - qsTr("%1 a été supprimé").arg(name)) - } - }) + //: Supprimer %1 ?" + qsTr("contact_dialog_delete_title").arg(contact.core.fullName), + //: Ce contact sera définitivement supprimé. + qsTr("contact_dialog_delete_message"), "", function (confirmed) { + if (confirmed) { + var name = contact.core.fullName + contact.core.remove() + contactList.resetSelections() + UtilsCpp.showInformationPopup( + //: "Contact supprimé" + qsTr("contact_deleted_toast"), + //: "%1 a été supprimé" + qsTr("contact_deleted_message").arg(name)) + } + }) } Dialog { @@ -115,9 +123,10 @@ FriendGui{ closePolicy: Control.Popup.CloseOnEscape modal: true onAboutToHide: neverDisplayAgainCheckbox.checked = false - title: qsTr("Augmenter la confiance") - text: qsTr("Pour augmenter le niveau de confiance vous devez appeler les différents appareils de votre contact et valider un code.

Vous êtes sur le point d’appeler “%1” voulez vous continuer ?").arg( - verifyDevicePopup.deviceName) + //: "Augmenter la confiance" + title: qsTr("contact_dialog_devices_trust_popup_title") + //: "Pour augmenter le niveau de confiance vous devez appeler les différents appareils de votre contact et valider un code.

Vous êtes sur le point d’appeler “%1” voulez vous continuer ?" + text: qsTr("contact_dialog_devices_trust_popup_message").arg(verifyDevicePopup.deviceName) buttons: RowLayout { RowLayout { spacing: Math.round(7 * DefaultStyle.dp) @@ -125,7 +134,8 @@ FriendGui{ id: neverDisplayAgainCheckbox } Text { - text: qsTr("Ne plus afficher") + //: Ne plus afficher + text: qsTr("popup_do_not_show_again") font.pixelSize: Math.round(14 * DefaultStyle.dp) MouseArea { anchors.fill: parent @@ -140,12 +150,13 @@ FriendGui{ spacing: Math.round(15 * DefaultStyle.dp) BigButton { style: ButtonStyle.secondary - text: qsTr("Annuler") + text: qsTr("cancel") onClicked: verifyDevicePopup.close() } BigButton { style: ButtonStyle.main - text: qsTr("Appeler") + //: "Appeler" + text: qsTr("dialog_call") onClicked: { SettingsCpp.setDisplayDeviceCheckConfirmation( !neverDisplayAgainCheckbox.checked) @@ -161,8 +172,10 @@ FriendGui{ Dialog { id: trustInfoDialog width: Math.round(637 * DefaultStyle.dp) - title: qsTr("Niveau de confiance") - text: qsTr("Vérifiez les appareils de votre contact pour confirmer que vos communications seront sécurisées et sans compromission.
Quand tous seront vérifiés, vous atteindrez le niveau de confiance maximal.") + //: "Niveau de confiance" + title: qsTr("contact_dialog_devices_trust_help_title") + //: "Vérifiez les appareils de votre contact pour confirmer que vos communications seront sécurisées et sans compromission.
Quand tous seront vérifiés, vous atteindrez le niveau de confiance maximal." + text: qsTr("contact_dialog_devices_trust_help_message") content: RowLayout { spacing: Math.round(50 * DefaultStyle.dp) Avatar { @@ -184,7 +197,8 @@ FriendGui{ } } buttons: Button { - text: qsTr("Ok") + //: "Ok" + text: qsTr("dialog_ok") style: ButtonStyle.main leftPadding: Math.round(30 * DefaultStyle.dp) rightPadding: Math.round(30 * DefaultStyle.dp) @@ -209,7 +223,8 @@ FriendGui{ anchors.rightMargin: leftPanel.rightMargin Text { - text: qsTr("Contacts") + //: "Contacts" + text: qsTr("bottom_navigation_contacts_label") color: DefaultStyle.main2_700 font.pixelSize: Typography.h2.pixelSize font.weight: Typography.h2.weight @@ -248,7 +263,8 @@ FriendGui{ Layout.rightMargin: leftPanel.rightMargin Layout.topMargin: Math.round(18 * DefaultStyle.dp) Layout.fillWidth: true - placeholderText: qsTr("Rechercher un contact") + //: Rechercher un contact + placeholderText: qsTr("search_bar_look_for_contact_text") KeyNavigation.up: createContactButton KeyNavigation.down: contactList } @@ -259,8 +275,10 @@ FriendGui{ visible: !contactList.loading && !contactList.haveContacts Layout.alignment: Qt.AlignHCenter Layout.topMargin: Math.round(137 * DefaultStyle.dp) - text: qsTr("Aucun contact%1").arg( - searchBar.text.length !== 0 ? " correspondant" : "") + //: Aucun résultat… + text: searchBar.text.length !== 0 ? qsTr("list_filter_no_result_found") + //: Aucun contact pour le moment + : qsTr("contact_list_empty") font { pixelSize: Typography.h4.pixelSize weight: Typography.h4.weight @@ -352,7 +370,7 @@ FriendGui{ anchors.fill: parent contact: mainItem.selectedContact button.color: DefaultStyle.main1_100 - button.text: qsTr("Modifier") + button.text: qsTr("contact_details_edit") button.style: ButtonStyle.tertiary button.icon.source: AppIcons.pencil button.onClicked: mainItem.editContact(mainItem.selectedContact) @@ -388,7 +406,8 @@ FriendGui{ spacing: Math.round(58 * DefaultStyle.dp) LabelButton { button.icon.source: AppIcons.phone - label: qsTr("Appel") + //: "Appel" + label: qsTr("contact_call_action") width: Math.round(56 * DefaultStyle.dp) height: Math.round(56 * DefaultStyle.dp) button.icon.width: Math.round(24 * DefaultStyle.dp) @@ -400,7 +419,8 @@ FriendGui{ LabelButton { button.icon.source: AppIcons.chatTeardropText visible: !SettingsCpp.disableChatFeature - label: qsTr("Message") + //: "Message" + label: qsTr("contact_message_action") width: Math.round(56 * DefaultStyle.dp) height: Math.round(56 * DefaultStyle.dp) button.icon.width: Math.round(24 * DefaultStyle.dp) @@ -411,7 +431,8 @@ FriendGui{ LabelButton { visible: SettingsCpp.videoEnabled button.icon.source: AppIcons.videoCamera - label: qsTr("Appel vidéo") + //: "Appel vidéo" + label: qsTr("contact_video_call_action") width: Math.round(56 * DefaultStyle.dp) height: Math.round(56 * DefaultStyle.dp) button.icon.width: Math.round(24 * DefaultStyle.dp) @@ -439,8 +460,24 @@ FriendGui{ property var mode: contactDetail.contact ? contactDetail.contact.core.consolidatedPresence : -1 horizontalAlignment: Text.AlignLeft Layout.fillWidth: true - text: mode === LinphoneEnums.ConsolidatedPresence.Online ? qsTr("En ligne") : mode === LinphoneEnums.ConsolidatedPresence.Busy ? qsTr("Occupé") : mode === LinphoneEnums.ConsolidatedPresence.DoNotDisturb ? qsTr("Ne pas déranger") : qsTr("Hors ligne") - color: mode === LinphoneEnums.ConsolidatedPresence.Online ? DefaultStyle.success_500main : mode === LinphoneEnums.ConsolidatedPresence.Busy ? DefaultStyle.warning_600 : mode === LinphoneEnums.ConsolidatedPresence.DoNotDisturb ? DefaultStyle.danger_500main : DefaultStyle.main2_500main + text: mode === LinphoneEnums.ConsolidatedPresence.Online + //: "En ligne" + ? qsTr("contact_presence_status_online") + : mode === LinphoneEnums.ConsolidatedPresence.Busy + //: "Occupé" + ? qsTr("contact_presence_status_busy") + : mode === LinphoneEnums.ConsolidatedPresence.DoNotDisturb + //: "Ne pas déranger" + ? qsTr("contact_presence_status_do_not_disturb") + //: "Hors ligne" + : qsTr("contact_presence_status_offline") + color: mode === LinphoneEnums.ConsolidatedPresence.Online + ? DefaultStyle.success_500main + : mode === LinphoneEnums.ConsolidatedPresence.Busy + ? DefaultStyle.warning_600 + : mode === LinphoneEnums.ConsolidatedPresence.DoNotDisturb + ? DefaultStyle.danger_500main + : DefaultStyle.main2_500main font.pixelSize: Math.round(14 * DefaultStyle.dp) } }, @@ -461,7 +498,8 @@ FriendGui{ ContactDetailLayout { id: infoLayout Layout.fillWidth: true - label: qsTr("Informations") + //: "Coordonnées" + label: qsTr("contact_details_numbers_and_addresses_title") content: ListView { id: addrList height: contentHeight @@ -547,7 +585,8 @@ FriendGui{ height: Math.round(50 * DefaultStyle.dp) visible: companyText.text.length != 0 Text { - text: qsTr("Société :") + //: "Société :" + text: qsTr("contact_details_company_name") font { pixelSize: Typography.p2.pixelSize weight: Typography.p2.weight @@ -567,7 +606,8 @@ FriendGui{ height: Math.round(50 * DefaultStyle.dp) visible: jobText.text.length != 0 Text { - text: qsTr("Poste :") + //: "Poste :" + text: qsTr("contact_details_job_title") font { pixelSize: Typography.p2.pixelSize weight: Typography.p2.weight @@ -588,7 +628,8 @@ FriendGui{ } ContactDetailLayout { visible: !SettingsCpp.disableChatFeature - label: qsTr("Medias") + //: "Medias" + label: qsTr("contact_details_medias_title") Layout.fillWidth: true content: Button { style: ButtonStyle.noBackground @@ -600,7 +641,8 @@ FriendGui{ colorizationColor: DefaultStyle.main2_600 } Text { - text: qsTr("Afficher les medias partagés") + //: "Afficher les medias partagés" + text: qsTr("contact_details_medias_subtitle") font { pixelSize: Typography.p1.pixelSize weight: Typography.p1.weight @@ -622,13 +664,15 @@ FriendGui{ } ContactDetailLayout { Layout.fillWidth: true - label: qsTr("Confiance") + //: "Confiance" + label: qsTr("contact_details_trust_title") icon: AppIcons.question onTitleIconClicked: trustInfoDialog.open() content: ColumnLayout { spacing: Math.round(13 * DefaultStyle.dp) Text { - text: qsTr("Niveau de confiance - Appareils vérifiés") + //: "Niveau de confiance - Appareils vérifiés" + text: qsTr("contact_dialog_devices_trust_title") font { pixelSize: Typography.p2.pixelSize weight: Typography.p2.weight @@ -636,7 +680,8 @@ FriendGui{ } Text { visible: deviceList.count === 0 - text: qsTr("Aucun appareil") + //: "Aucun appareil" + text: qsTr("contact_details_no_device_found") } ProgressBar { visible: deviceList.count > 0 @@ -660,7 +705,8 @@ FriendGui{ property var listViewModelData: modelData property var callObj property CallGui deviceCall: callObj ? callObj.value : null - property string deviceName: listViewModelData.name.length != 0 ? listViewModelData.name : qsTr("Appareil sans nom") + //: "Appareil sans nom" + property string deviceName: listViewModelData.name.length != 0 ? listViewModelData.name : qsTr("contact_device_without_name") Text { text: deviceDelegate.deviceName font.pixelSize: Math.round(14 * DefaultStyle.dp) @@ -680,7 +726,8 @@ FriendGui{ visible: listViewModelData.securityLevel != LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified icon.source: AppIcons.warningCircle style: ButtonStyle.tertiary - text: qsTr("Vérifier") + //: "Vérifier" + text: qsTr("contact_make_call_check_device_trust") onClicked: { if (SettingsCpp.getDisplayDeviceCheckConfirmation( )) { @@ -705,14 +752,16 @@ FriendGui{ } ContactDetailLayout { Layout.fillWidth: true - label: qsTr("Autres actions") + //: "Autres actions" + label: qsTr("contact_details_actions_title") content: ColumnLayout { width: parent.width IconLabelButton { Layout.fillWidth: true Layout.preferredHeight: Math.round(50 * DefaultStyle.dp) icon.source: AppIcons.pencil - text: qsTr("Éditer") + //: "Éditer" + text: qsTr("contact_details_edit") onClicked: mainItem.editContact( mainItem.selectedContact) visible: !mainItem.selectedContact?.core.readOnly @@ -729,7 +778,11 @@ FriendGui{ icon.source: mainItem.selectedContact && mainItem.selectedContact.core.starred ? AppIcons.heartFill : AppIcons.heart text: mainItem.selectedContact - && mainItem.selectedContact.core.starred ? qsTr("Retirer des favoris") : qsTr("Ajouter aux favoris") + && mainItem.selectedContact.core.starred + //: "Retirer des favoris" + ? qsTr("contact_details_remove_from_favourites") + //: "Ajouter aux favoris" + : qsTr("contact_details_add_to_favourites") style: ButtonStyle.noBackground onClicked: if (mainItem.selectedContact) mainItem.selectedContact.core.lSetStarred( @@ -744,7 +797,8 @@ FriendGui{ Layout.fillWidth: true Layout.preferredHeight: Math.round(50 * DefaultStyle.dp) icon.source: AppIcons.shareNetwork - text: qsTr("Partager") + //: "Partager" + text: qsTr("contact_details_share") style: ButtonStyle.noBackground onClicked: { if (mainItem.selectedContact) { @@ -755,17 +809,19 @@ FriendGui{ username, vcard) if (filepath == "") UtilsCpp.showInformationPopup( - qsTr("Erreur"), - qsTr("La création du fichier vcard a échoué"), + qsTr("information_popup_error_title"), + //: "La création du fichier vcard a échoué" + qsTr("contact_details_share_error_mesage"), false) else mainWindow.showInformationPopup( - qsTr( - "VCard créée"), - qsTr("VCard du contact enregistrée dans %1").arg( - filepath)) + //: "VCard créée" + qsTr("contact_details_share_success_title"), + //: "VCard du contact enregistrée dans %1" + qsTr("contact_details_share_success_mesage").arg(filepath)) UtilsCpp.shareByEmail( - qsTr("Partage de contact"), + //: "Partage de contact" + qsTr("contact_details_share_email_title"), vcard, filepath) } } @@ -803,7 +859,8 @@ FriendGui{ Layout.fillWidth: true Layout.preferredHeight: Math.round(50 * DefaultStyle.dp) icon.source: AppIcons.trashCan - text: qsTr("Supprimer ce contact") + //: "Supprimer ce contact" + text: qsTr("contact_details_delete") visible: !mainItem.selectedContact?.core.readOnly onClicked: { mainItem.deleteContact( diff --git a/Linphone/view/Page/Main/Help/HelpPage.qml b/Linphone/view/Page/Main/Help/HelpPage.qml index dee916c56..3c3313b11 100644 --- a/Linphone/view/Page/Main/Help/HelpPage.qml +++ b/Linphone/view/Page/Main/Help/HelpPage.qml @@ -35,7 +35,8 @@ AbstractMainPage { } } Text { - text: qsTr("Aide") + //: "Aide" + text: qsTr("help_title") color: DefaultStyle.main2_700 font: Typography.h2 } @@ -48,7 +49,8 @@ AbstractMainPage { Layout.rightMargin: leftPanel.sideMargin Layout.topMargin: Math.round(41 * DefaultStyle.dp) Layout.fillWidth: true - text: qsTr("À propos de Linphone") + //: "À propos de %1" + text: qsTr("help_about_title").arg(applicationName) color: DefaultStyle.main2_600 font: Typography.h4 } @@ -61,8 +63,10 @@ AbstractMainPage { HelpIconLabelButton { Layout.fillWidth: true iconSource: AppIcons.detective - title: qsTr("Règles de confidentialité") - subTitle: qsTr("Comment Linphone récolte et utilise les informations") + //: "Règles de confidentialité" + title: qsTr("help_about_privacy_policy_title") + //: Quelles informations %1 collecte et utilise + subTitle: qsTr("help_about_privacy_policy_subtitle").arg(applicationName) onClicked: { rightPanelStackView.clear() Qt.openUrlExternally(ConstantsCpp.PrivatePolicyUrl) @@ -71,14 +75,16 @@ AbstractMainPage { HelpIconLabelButton { Layout.fillWidth: true iconSource: AppIcons.info - title: qsTr("Version") + //: "Version" + title: qsTr("help_about_version_title") subTitle: AppCpp.shortApplicationVersion onClicked: {} } HelpIconLabelButton { Layout.fillWidth: true iconSource: AppIcons.license - title: qsTr("Licences GPLv3") + //: "Licences GPLv3" + title: qsTr("help_about_gpl_licence_title") subTitle: (copyrightRangeDate || applicationVendor ? '\u00A9 ': '') + (copyrightRangeDate ? copyrightRangeDate : '')+ (applicationVendor ? ' ' + applicationVendor : '') onClicked: { rightPanelStackView.clear() @@ -88,7 +94,8 @@ AbstractMainPage { HelpIconLabelButton { Layout.fillWidth: true iconSource: AppIcons.world - title: qsTr("Contribuer à la traduction de Linphone") + //: "Contribuer à la traduction de %1" + title: qsTr("help_about_contribute_translations_title").arg(applicationName) onClicked: { rightPanelStackView.clear() Qt.openUrlExternally(ConstantsCpp.TranslationUrl) @@ -100,7 +107,8 @@ AbstractMainPage { Layout.rightMargin: leftPanel.sideMargin Layout.topMargin: Math.round(32 * DefaultStyle.dp) Layout.fillWidth: true - text: qsTr("À propos de Linphone") + //: "À propos de %1" + text: qsTr("help_about_title").arg(applicationName) color: DefaultStyle.main2_600 font: Typography.h4 } @@ -111,7 +119,8 @@ AbstractMainPage { Layout.rightMargin: leftPanel.sideMargin Layout.topMargin: Math.round(24 * DefaultStyle.dp) iconSource: AppIcons.debug - title: qsTr("Dépannage") + //: "Dépannage" + title: qsTr("help_troubleshooting_title") onClicked: { rightPanelStackView.clear() rightPanelStackView.push("qrc:/qt/qml/Linphone/view/Page/Layout/Settings/DebugSettingsLayout.qml", { titleText: troubleShooting.title, container: rightPanelStackView }) diff --git a/Linphone/view/Page/Main/Meeting/MeetingPage.qml b/Linphone/view/Page/Main/Meeting/MeetingPage.qml index 92f499c70..ae3a22e92 100644 --- a/Linphone/view/Page/Main/Meeting/MeetingPage.qml +++ b/Linphone/view/Page/Main/Meeting/MeetingPage.qml @@ -14,9 +14,10 @@ AbstractMainPage { property int meetingListCount signal returnRequested() signal addParticipantsValidated(list selectedParticipants) - - noItemButtonText: qsTr("Créer une réunion") - emptyListText: qsTr("Aucune réunion") + //: "Créer une réunion" + noItemButtonText: qsTr("meetings_add") + //: "Aucune réunion" + emptyListText: qsTr("meetings_list_empty") newItemIconSource: AppIcons.plusCircle rightPanelColor: selectedConference ? DefaultStyle.grey_0 : DefaultStyle.grey_100 showDefaultItem: leftPanelStackView.currentItem?.objectName === "listLayout" && meetingListCount === 0 @@ -73,12 +74,16 @@ AbstractMainPage { property bool cancel: false signal cancelRequested() // width: Math.round(278 * DefaultStyle.dp) - text: cancel ? qsTr("Souhaitez-vous annuler et supprimer cette réunion ?") : qsTr("Souhaitez-vous supprimer cette réunion ?") + //: "Souhaitez-vous annuler et supprimer cette réunion ?" + text: cancel ? qsTr("meeting_schedule_cancel_dialog_message") + //: Souhaitez-vous supprimer cette réunion ? + : qsTr("meeting_schedule_delete_dialog_message") buttons: [ BigButton { visible: cancelAndDeleteConfDialog.cancel style: ButtonStyle.main - text: qsTr("Annuler et supprimer") + //: "Annuler et supprimer" + text: qsTr("meeting_schedule_cancel_and_delete_action") onClicked: { cancelAndDeleteConfDialog.cancelRequested() cancelAndDeleteConfDialog.accepted() @@ -86,7 +91,10 @@ AbstractMainPage { } }, BigButton { - text: cancelAndDeleteConfDialog.cancel ? qsTr("Supprimer seulement") : qsTr("Supprimer") + //: "Supprimer seulement" + text: cancelAndDeleteConfDialog.cancel ? qsTr("meeting_schedule_delete_only_action") + //: "Supprimer" + : qsTr("meeting_schedule_delete_action") style: ButtonStyle.main onClicked: { cancelAndDeleteConfDialog.accepted() @@ -94,7 +102,8 @@ AbstractMainPage { } }, BigButton { - text: qsTr("Retour") + //: Retour + text: qsTr("back_action") style: ButtonStyle.secondary onClicked: { cancelAndDeleteConfDialog.rejected() @@ -136,7 +145,8 @@ AbstractMainPage { spacing: 0 Text { Layout.fillWidth: true - text: qsTr("Réunions") + //: Réunions + text: qsTr("meetings_list_title") color: DefaultStyle.main2_700 font.pixelSize: Typography.h2.pixelSize font.weight: Typography.h2.weight @@ -159,7 +169,8 @@ AbstractMainPage { Layout.fillWidth: true Layout.topMargin: Math.round(18 * DefaultStyle.dp) Layout.rightMargin: Math.round(38 * DefaultStyle.dp) - placeholderText: qsTr("Rechercher une réunion") + //: "Rechercher une réunion" + placeholderText: qsTr("meetings_search_hint") KeyNavigation.up: conferenceList KeyNavigation.down: conferenceList visible: conferenceList.count !== 0 || text.length !== 0 @@ -175,7 +186,10 @@ AbstractMainPage { Layout.topMargin: Math.round(137 * DefaultStyle.dp) Layout.fillHeight: true Layout.alignment: Qt.AlignHCenter - text: qsTr("Aucune réunion%1").arg(searchBar.text.length !== 0 ? " correspondante" : "") + //: "Aucun résultat…" + text: searchBar.text.length !== 0 ? qsTr("list_filter_no_result_found") + //: "Aucune réunion" + : qsTr("meetings_empty_list") font { pixelSize: Typography.h4.pixelSize weight: Typography.h4.weight @@ -237,7 +251,8 @@ AbstractMainPage { } } Text { - text: qsTr("Nouvelle réunion") + //: "Nouvelle réunion" + text: qsTr("meeting_schedule_title") color: DefaultStyle.main2_700 font { pixelSize: Typography.h3.pixelSize @@ -248,23 +263,26 @@ AbstractMainPage { Item {Layout.fillWidth: true} SmallButton { id: createButton - text: qsTr("Créer") + text: qsTr("create") style: ButtonStyle.main KeyNavigation.left: backButton KeyNavigation.down: meetingSetup onClicked: { - if (meetingSetup.conferenceInfoGui.core.subject.length === 0) { - UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La conférence doit contenir un sujet"), false) + if (meetingSetup.conferenceInfoGui.core.subject.length === 0 || meetingSetup.conferenceInfoGui.core.participantCount === 0) { + UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), + //: Veuillez saisir un titre et sélectionner au moins un participant + qsTr("meeting_schedule_mandatory_field_not_filled_toast"), false) } else if (meetingSetup.conferenceInfoGui.core.duration <= 0) { - UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La fin de la conférence doit être plus récente que son début"), false) - } else if (meetingSetup.conferenceInfoGui.core.participantCount === 0) { - UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La conférence doit contenir au moins un participant"), false) - } else { + UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), + //: "La fin de la conférence doit être plus récente que son début" + qsTr("meeting_schedule_duration_error_toast"), false) + } else { meetingSetup.conferenceInfoGui.core.save() - mainWindow.showLoadingPopup(qsTr("Création de la réunion en cours ..."), true, function () { - meetingSetup.conferenceInfoGui.core.cancelCreation() - }) + //: "Création de la réunion en cours …" + mainWindow.showLoadingPopup(qsTr("meeting_schedule_creation_in_progress"), true, function () { + meetingSetup.conferenceInfoGui.core.cancelCreation() + }) } } } @@ -282,17 +300,23 @@ AbstractMainPage { var mainWin = UtilsCpp.getMainWindow() if (meetingSetup.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Ready) { leftPanelStackView.pop() - UtilsCpp.showInformationPopup(qsTr("Nouvelle réunion"), qsTr("Réunion planifiée avec succès"), true) + //: "Nouvelle réunion" + UtilsCpp.showInformationPopup(qsTr("meeting_schedule_title"), + //: "Réunion planifiée avec succès" + qsTr("meeting_info_created_toast"), true) mainWindow.closeLoadingPopup() } else if (meetingSetup.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.AllocationPending || meetingSetup.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Updating) { - mainWin.showLoadingPopup(qsTr("Création de la réunion en cours..."), true, function () { + //: Création de la réunion en cours… + mainWin.showLoadingPopup(qsTr("meeting_schedule_creation_processing"), true, function () { leftPanelStackView.pop() }) } else { if (meetingSetup.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Error) { - UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La création de la conférence a échoué"), false) + UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), + //: "Échec de création de la réunion !" + qsTr("meeting_failed_to_schedule_toast"), false) } mainWin.closeLoadingPopup() } @@ -385,19 +409,19 @@ AbstractMainPage { id: saveButton style: ButtonStyle.main focus: true - text: qsTr("Enregistrer") + text: qsTr("save") KeyNavigation.left: titleText KeyNavigation.right: backButton KeyNavigation.down: conferenceEdit KeyNavigation.up: conferenceEdit onClicked: { - if (mainItem.selectedConference.core.subject.length === 0) { - UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La conférence doit contenir un sujet"), false) + if (mainItem.selectedConference.core.subject.length === 0 || mainItem.selectedConference.core.participantCount === 0) { + UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), + qsTr("meeting_schedule_mandatory_field_not_filled_toast"), false) } else if (mainItem.selectedConference.core.duration <= 0) { - UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La fin de la conférence doit être plus récente que son début"), false) - } else if (mainItem.selectedConference.core.participantCount === 0) { - UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La conférence doit contenir au moins un participant"), false) - } else { + UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), + qsTr("meeting_schedule_duration_error_toast"), false) + } else { mainItem.selectedConference.core.save() } } @@ -434,13 +458,19 @@ AbstractMainPage { if (conferenceEdit.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Ready) { overridenRightPanelStackView.pop() UtilsCpp.getMainWindow().closeLoadingPopup() - UtilsCpp.showInformationPopup(qsTr("Enregistré"), qsTr("Réunion modifiée avec succès"), true) + //: "Enregistré" + UtilsCpp.showInformationPopup(qsTr("saved"), + //: "Réunion mise à jour" + qsTr("meeting_info_updated_toast"), true) } else if (conferenceEdit.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.AllocationPending || conferenceEdit.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Updating) { - UtilsCpp.getMainWindow().showLoadingPopup(qsTr("Modification de la réunion en cours...")) + //: "Modification de la réunion en cours…" + UtilsCpp.getMainWindow().showLoadingPopup(qsTr("meeting_schedule_edit_in_progress")) } else if (conferenceEdit.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Error) { - UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La modification de la conférence a échoué"), false) + UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), + //: "Échec de la modification de la réunion !" + qsTr("meeting_failed_to_edit_toast"), false) UtilsCpp.getMainWindow().closeLoadingPopup() } } @@ -476,7 +506,8 @@ AbstractMainPage { onClicked: container.pop() } Text { - text: qsTr("Ajouter des participants") + //: "Ajouter des participants" + text: qsTr("meeting_schedule_add_participants_title") color: DefaultStyle.main1_500_main maximumLineCount: 1 font { @@ -491,7 +522,7 @@ AbstractMainPage { Layout.leftMargin: Math.round(11 * DefaultStyle.dp) focus: enabled style: ButtonStyle.main - text: qsTr("Ajouter") + text: qsTr("add") KeyNavigation.left: addParticipantsBackButton KeyNavigation.down: addParticipantLayout onClicked: { @@ -500,7 +531,8 @@ AbstractMainPage { } } Text { - text: qsTr("%1 participant%2 sélectionné%2").arg(addParticipantLayout.selectedParticipantsCount).arg(addParticipantLayout.selectedParticipantsCount > 1 ? "s" : "") + //: "%n participant(s) sélectionné(s)" + text: qsTr("group_call_participant_selected").arg(addParticipantLayout.selectedParticipantsCount) color: DefaultStyle.main2_500main Layout.leftMargin: addParticipantsBackButton.width + addParticipantsButtons.spacing maximumLineCount: 1 @@ -584,7 +616,8 @@ AbstractMainPage { property var isMeObj: UtilsCpp.isMe(mainItem.selectedConference?.core?.organizerAddress) property bool canCancel: isMeObj && isMeObj.value && mainItem.selectedConference?.core?.state !== LinphoneEnums.ConferenceInfoState.Cancelled icon.source: AppIcons.trashCan - text: qsTr("Supprimer cette réunion") + //: "Supprimer la réunion" + text: qsTr("meeting_info_delete") onClicked: { if (mainItem.selectedConference) { @@ -653,7 +686,9 @@ AbstractMainPage { KeyNavigation.down: joinButton onClicked: { UtilsCpp.copyToClipboard(mainItem.selectedConference.core.uri) - UtilsCpp.showInformationPopup(qsTr("Enregistré"), qsTr("Le lien de la réunion a été copié dans le presse-papiers")) + UtilsCpp.showInformationPopup(qsTr("saved"), + //: "Adresse de la réunion copiée" + qsTr("meeting_address_copied_to_clipboard_toast")) } } } @@ -687,7 +722,8 @@ AbstractMainPage { colorizationColor: DefaultStyle.main2_600 } Text { - text: qsTr("Time zone: ") + (mainItem.selectedConference && mainItem.selectedConference.core ? (mainItem.selectedConference.core.timeZoneModel.displayName + ", " + mainItem.selectedConference.core.timeZoneModel.countryName) : "") + //: "Fuseau horaire" + text: "%1: %2".arg(qsTr("meeting_schedule_timezone_title")).arg(mainItem.selectedConference && mainItem.selectedConference.core ? (mainItem.selectedConference.core.timeZoneModel.displayName + ", " + mainItem.selectedConference.core.timeZoneModel.countryName) : "") font { pixelSize: Math.round(14 * DefaultStyle.dp) capitalization: Font.Capitalize @@ -779,7 +815,8 @@ AbstractMainPage { } } Text { - text: qsTr("Organizer") + //: "Organisateur" + text: qsTr("meeting_info_organizer_label") visible: mainItem.selectedConference && mainItem.selectedConference.core?.organizerAddress === modelData.address color: DefaultStyle.main2_400 font { @@ -795,7 +832,8 @@ AbstractMainPage { id: joinButton visible: mainItem.selectedConference && mainItem.selectedConference.core?.state !== LinphoneEnums.ConferenceInfoState.Cancelled Layout.fillWidth: true - text: qsTr("Rejoindre la réunion") + //: "Rejoindre la réunion" + text: qsTr("meeting_info_join_title") focus: true KeyNavigation.up: shareNetworkButton KeyNavigation.down: deletePopup diff --git a/Linphone/view/Page/Main/Start/WelcomePage.qml b/Linphone/view/Page/Main/Start/WelcomePage.qml index e4ebdfa6e..716c2f52e 100644 --- a/Linphone/view/Page/Main/Start/WelcomePage.qml +++ b/Linphone/view/Page/Main/Start/WelcomePage.qml @@ -12,7 +12,8 @@ LoginLayout { titleContent: [ Text { id: welcome - text: qsTr("Bienvenue") + //: "Bienvenue" + text: qsTr("welcome_page_title") Layout.alignment: Qt.AlignVCenter Layout.leftMargin: Math.round(132 * DefaultStyle.dp) color: DefaultStyle.main2_800 @@ -27,7 +28,8 @@ LoginLayout { Layout.leftMargin: Math.round(29 * DefaultStyle.dp) Layout.bottomMargin: Math.round(19 * DefaultStyle.dp) color: DefaultStyle.main2_800 - text: qsTr("sur Linphone") + //: "sur %1" + text: qsTr("welcome_page_subtitle").arg(applicationName) font { pixelSize: Typography.h1.pixelSize weight: Typography.h1.weight @@ -43,7 +45,8 @@ LoginLayout { Layout.rightMargin: Math.round(50 * DefaultStyle.dp) Layout.alignment: Qt.AlignVCenter | Layout.AlignRight style: ButtonStyle.noBackground - text: qsTr("Passer") + //: "Passer" + text: qsTr("welcome_carousel_skip") underline: true onClicked: { console.debug("[WelcomePage] User: Click skip") @@ -76,9 +79,16 @@ LoginLayout { itemsList: Repeater { id: slideRepeater model: [ - {title: qsTr("Linphone"), text: qsTr("Une application de communication sécurisée,
open source et française.")}, - {title: qsTr("Sécurisé"), text: qsTr("Vos communications sont en sécurité grâce aux
Chiffrement de bout en bout.")}, - {title: qsTr("Open Source"), text: qsTr("Une application open source et un service gratuit
depuis 2001")} + //: "Une application de communication sécurisée,
open source et française." + {title: applicationName, text: qsTr("welcome_page_1_message")}, + //: "Sécurisé" + {title: qsTr("welcome_page_2_title"), + //: "Vos communications sont en sécurité grâce aux
Chiffrement de bout en bout." + text: qsTr("welcome_page_2_message")}, + //: "Open Source" + {title: qsTr("welcome_page_3_title"), + //: "Une application open source et un service gratuit
depuis 2001" + text: qsTr("welcome_page_3_message")} ] ColumnLayout { spacing: Math.round(10 * DefaultStyle.dp) @@ -107,8 +117,11 @@ LoginLayout { BigButton { Layout.leftMargin: Math.round(509 * DefaultStyle.dp) - style: ButtonStyle.main - text: carousel.currentIndex < (carousel.itemsCount - 1) ? qsTr("Suivant") : qsTr("Commencer") + style: ButtonStyle.main + //: "Suivant" + text: carousel.currentIndex < (carousel.itemsCount - 1) ? qsTr("next") + //: "Commencer" + : qsTr("start") onClicked: { if (carousel.currentIndex < carousel.itemsCount - 1) carousel.goToSlide(carousel.currentIndex + 1); else mainItem.startButtonPressed(); diff --git a/Linphone/view/Page/Window/AbstractWindow.qml b/Linphone/view/Page/Window/AbstractWindow.qml index 3bdccf635..db466f86a 100644 --- a/Linphone/view/Page/Window/AbstractWindow.qml +++ b/Linphone/view/Page/Window/AbstractWindow.qml @@ -74,7 +74,8 @@ ApplicationWindow { spacing: Math.round(5 * DefaultStyle.dp) width: startCallPopup.width Text { - text: qsTr("Quelle adresse souhaitez-vous appeler ?") + //: "Choisissez un numéro ou adresse SIP" + text: qsTr("contact_dialog_pick_phone_number_or_sip_address_title") wrapMode: Text.Wrap Layout.fillWidth: true font { @@ -272,7 +273,8 @@ ApplicationWindow { font.bold: true font.italic: true font.pixelSize: Math.round(14 * DefaultStyle.dp) - text: parent.fps + " FPS" + // "%1 FPS" + text: qsTr("fps_counter").arg(parent.fps) color: parent.fps < 30 ? DefaultStyle.danger_500main : DefaultStyle.main2_900 } } diff --git a/Linphone/view/Page/Window/Call/CallsWindow.qml b/Linphone/view/Page/Window/Call/CallsWindow.qml index 45e2ad12c..c300a6b49 100644 --- a/Linphone/view/Page/Window/Call/CallsWindow.qml +++ b/Linphone/view/Page/Window/Call/CallsWindow.qml @@ -51,8 +51,8 @@ AbstractWindow { var callsWin = UtilsCpp.getCallsWindow() if (!callsWin) return - callsWin.showLoadingPopup( - qsTr("Transfert en cours, veuillez patienter")) + //: "Transfert en cours, veuillez patienter" + callsWin.showLoadingPopup(qsTr("call_transfer_in_progress_toast")) } else if (mainWindow.transferState === LinphoneEnums.CallState.Error || mainWindow.transferState === LinphoneEnums.CallState.End || mainWindow.transferState === LinphoneEnums.CallState.Released @@ -61,8 +61,9 @@ AbstractWindow { callsWin.closeLoadingPopup() if (transferState === LinphoneEnums.CallState.Error) UtilsCpp.showInformationPopup( - qsTr("Erreur"), - qsTr("Le transfert d'appel a échoué"), false, + qsTr("information_popup_error_title"), + //: "Le transfert d'appel a échoué" + qsTr("call_transfer_failed_toast"), false, mainWindow) else if (transferState === LinphoneEnums.CallState.Connected) { var mainWin = UtilsCpp.getMainWindow() @@ -130,10 +131,8 @@ AbstractWindow { function joinConference(uri, options) { if (uri.length === 0) - UtilsCpp.showInformationPopup( - qsTr("Erreur"), qsTr( - "La conférence n'a pas pu démarrer en raison d'une erreur d'uri."), - mainWindow) + //: "La conférence n'a pas pu démarrer en raison d'une erreur d'uri." + UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), qsTr("conference_error_empty_uri"),mainWindow) else { UtilsCpp.createCall(uri, options) } @@ -188,7 +187,10 @@ AbstractWindow { call.core.lTerminateAllCalls() } width: Math.round(278 * DefaultStyle.dp) - text: qsTr("La fenêtre est sur le point d'être fermée. Cela terminera tous les appels en cours. Souhaitez vous continuer ?") + //: "Terminer tous les appels en cours ?" + title: qsTr("call_close_window_dialog_title") + //: "La fenêtre est sur le point d'être fermée. Cela terminera tous les appels en cours." + text: qsTr("call_close_window_dialog_message") } CallProxy { @@ -280,7 +282,8 @@ AbstractWindow { } Text { color: DefaultStyle.info_500_main - text: qsTr("Appareil vérifié") + //: "Appareil authentifié" + text: qsTr("call_can_be_trusted_toast") Layout.fillWidth: true font { pixelSize: Math.round(14 * DefaultStyle.dp) @@ -344,8 +347,22 @@ AbstractWindow { spacing: Math.round(10 * DefaultStyle.dp) Text { id: callStatusText - property string remoteName: mainWindow.callState === LinphoneEnums.CallState.Connected || mainWindow.callState === LinphoneEnums.CallState.StreamsRunning ? mainWindow.call.core.remoteName : qsTr("Appel %1").arg(mainWindow.call ? EnumsToStringCpp.dirToString(mainWindow.call.core.dir) : "") - text: (mainWindow.callState === LinphoneEnums.CallState.End || mainWindow.callState === LinphoneEnums.CallState.Released) ? qsTr("Fin d'appel") : mainWindow.call && (mainWindow.call.core.paused || (mainWindow.callState === LinphoneEnums.CallState.Paused || mainWindow.callState === LinphoneEnums.CallState.PausedByRemote)) ? (mainWindow.conference ? qsTr('Réunion mise ') : qsTr('Appel mis')) + qsTr(" en pause") : mainWindow.conference ? mainWindow.conference.core.subject : remoteName + property string remoteName: mainWindow.callState === LinphoneEnums.CallState.Connected || mainWindow.callState === LinphoneEnums.CallState.StreamsRunning + ? mainWindow.call.core.remoteName + //: "Appel %1" + : mainWindow.call ? qsTr("call_dir").arg(EnumsToStringCpp.dirToString(mainWindow.call.core.dir)) : "" + //: "Appel terminé" + text: (mainWindow.callState === LinphoneEnums.CallState.End || mainWindow.callState === LinphoneEnums.CallState.Released) + ? qsTr("call_ended") + : mainWindow.call && (mainWindow.call.core.paused || (mainWindow.callState === LinphoneEnums.CallState.Paused || mainWindow.callState === LinphoneEnums.CallState.PausedByRemote)) + ? (mainWindow.conference + //: "Réunion mise en pause" + ? qsTr("conference_paused") + //: "Appel mis en pause" + : qsTr("call_paused")) + : mainWindow.conference + ? mainWindow.conference.core.subject + : remoteName color: DefaultStyle.grey_0 font { pixelSize: Typography.h3.pixelSize @@ -426,17 +443,40 @@ AbstractWindow { === LinphoneEnums.CallState.Connected || mainWindow.callState === LinphoneEnums.CallState.StreamsRunning - imageSource: mainWindow.call ? mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Srtp ? AppIcons.lockSimple : mainWindow.call && mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp ? mainWindow.call.core.isMismatch || !mainWindow.call.core.tokenVerified ? AppIcons.warningCircle : AppIcons.lockKey : AppIcons.lockSimpleOpen : "" + imageSource: mainWindow.call + ? mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Srtp + ? AppIcons.lockSimple + : mainWindow.call && mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp + ? mainWindow.call.core.isMismatch || !mainWindow.call.core.tokenVerified + ? AppIcons.warningCircle + : AppIcons.lockKey + : AppIcons.lockSimpleOpen + : "" } Text { - text: mainWindow.call - && mainWindow.callState - === LinphoneEnums.CallState.Connected - || mainWindow.callState === LinphoneEnums.CallState.StreamsRunning ? mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Srtp ? qsTr("Appel chiffré de point à point") : mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp ? mainWindow.call.core.isMismatch || !mainWindow.call.core.tokenVerified ? qsTr("Vérification nécessaire") : qsTr("Appel chiffré de bout en bout") : qsTr("Appel non chiffré") : qsTr("En attente de chiffrement") - color: mainWindow.call - && mainWindow.callState - === LinphoneEnums.CallState.Connected - || mainWindow.callState === LinphoneEnums.CallState.StreamsRunning ? mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Srtp ? DefaultStyle.info_500_main : mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp ? mainWindow.call.core.isMismatch || !mainWindow.call.core.tokenVerified ? DefaultStyle.warning_600 : DefaultStyle.info_500_main : DefaultStyle.grey_0 : DefaultStyle.grey_0 + text: mainWindow.call && mainWindow.callState === LinphoneEnums.CallState.Connected || mainWindow.callState === LinphoneEnums.CallState.StreamsRunning + ? mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Srtp + //: "Appel chiffré de point à point" + ? qsTr("call_srtp_point_to_point_encrypted") + : mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp + ? mainWindow.call.core.isMismatch || !mainWindow.call.core.tokenVerified + //: "Vérification nécessaire" + ? qsTr("call_zrtp_sas_validation_required") + //: "Appel chiffré de bout en bout" + : qsTr("call_zrtp_end_to_end_encrypted") + //: "Appel non chiffré" + : qsTr("call_not_encrypted") + //: "En attente de chiffrement" + : qsTr("call_waiting_for_encryption_info") + color: mainWindow.call && mainWindow.callState === LinphoneEnums.CallState.Connected || mainWindow.callState === LinphoneEnums.CallState.StreamsRunning + ? mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Srtp + ? DefaultStyle.info_500_main + : mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp + ? mainWindow.call.core.isMismatch || !mainWindow.call.core.tokenVerified + ? DefaultStyle.warning_600 + : DefaultStyle.info_500_main + : DefaultStyle.grey_0 + : DefaultStyle.grey_0 font { pixelSize: Math.round(12 * DefaultStyle.dp) weight: Math.round(400 * DefaultStyle.dp) @@ -510,13 +550,26 @@ AbstractWindow { Text { color: DefaultStyle.danger_500main font.pixelSize: Math.round(14 * DefaultStyle.dp) - text: mainWindow.call ? mainWindow.call.core.recording ? mainWindow.conference ? qsTr("Vous enregistrez la réunion") : qsTr("Vous enregistrez l'appel") : mainWindow.conference ? qsTr("Un participant enregistre la réunion") : qsTr("Votre correspondant enregistre l'appel") : "" + text: mainWindow.call + ? mainWindow.call.core.recording + ? mainWindow.conference + //: "Vous enregistrez la réunion" + ? qsTr("conference_user_is_recording") + //: "Vous enregistrez l'appel" + : qsTr("call_user_is_recording") + : mainWindow.conference + //: "Un participant enregistre la réunion" + ? qsTr("conference_remote_is_recording") + //: "Votre correspondant enregistre l'appel" + : qsTr("call_remote_recording") + : "" } } BigButton { visible: mainWindow.call && mainWindow.call.core.recording - text: qsTr("Arrêter l'enregistrement") + //: "Arrêter l'enregistrement" + text: qsTr("call_stop_recording") style: ButtonStyle.main onPressed: mainWindow.call.core.lStopRecording() } @@ -549,7 +602,7 @@ AbstractWindow { } headerStack.currentIndex: 0 contentStackView.initialItem: callListPanel - headerValidateButtonText: qsTr("Ajouter") + headerValidateButtonText: qsTr("add") Item { id: numericPadContainer @@ -565,9 +618,8 @@ AbstractWindow { id: callTransferPanel NewCallForm { id: newCallForm - Control.StackView.onActivated: rightPanel.headerTitleText = qsTr( - "Transférer %1 à :").arg( - mainWindow.call.core.remoteName) + //: "Transférer %1 à…" + Control.StackView.onActivated: rightPanel.headerTitleText = qsTr("call_transfer_current_call_title").arg(mainWindow.call.core.remoteName) Keys.onEscapePressed: event => { rightPanel.visible = false event.accepted = true @@ -579,35 +631,26 @@ AbstractWindow { onContactClicked: contact => { var callsWin = UtilsCpp.getCallsWindow() if (contact) - callsWin.showConfirmationLambdaPopup( - qsTr("Confirmer le transfert ?"), - qsTr("Vous allez transférer %1 à %2.").arg( - mainWindow.call.core.remoteName).arg( - contact.core.fullName), "", + //: "Confirmer le transfert" + callsWin.showConfirmationLambdaPopup(qsTr("call_transfer_confirm_dialog_tittle"), + //: "Vous allez transférer %1 à %2." + qsTr("call_transfer_confirm_dialog_message").arg(mainWindow.call.core.remoteName).arg(contact.core.fullName), "", function (confirmed) { if (confirmed) { - mainWindow.transferCallToContact( - mainWindow.call, - contact, - newCallForm) + mainWindow.transferCallToContact(mainWindow.call,contact,newCallForm) } }) } onTransferCallToAnotherRequested: dest => { var callsWin = UtilsCpp.getCallsWindow() - console.log( - "transfer to", - dest) - callsWin.showConfirmationLambdaPopup( - qsTr("Confirmer le transfert ?"), - qsTr("Vous allez transférer %1 à %2.").arg(mainWindow.call.core.remoteName).arg( - dest.core.remoteName), - "", - function (confirmed) { + console.log("transfer to",dest) + callsWin.showConfirmationLambdaPopup(qsTr("call_transfer_confirm_dialog_tittle"), + qsTr("call_transfer_confirm_dialog_message").arg(mainWindow.call.core.remoteName).arg(dest.core.remoteName),"", + function (confirmed) { if (confirmed) { mainWindow.call.core.lTransferCallToAnother(dest.core.remoteAddress) } - }) + }) } numPadPopup: numPadPopup @@ -631,8 +674,8 @@ AbstractWindow { NewCallForm { id: newCallForm objectName: "newCallPanel" - Control.StackView.onActivated: rightPanel.headerTitleText = qsTr( - "Nouvel appel") + //: "Nouvel appel" + Control.StackView.onActivated: rightPanel.headerTitleText = qsTr("call_action_start_new_call") groupCallVisible: false searchBarColor: DefaultStyle.grey_0 searchBarBorderColor: DefaultStyle.grey_200 @@ -671,8 +714,8 @@ AbstractWindow { id: dialerPanel Item { id: dialerPanelContent - Control.StackView.onActivated: rightPanel.headerTitleText = qsTr( - "Dialer") + //: "Pavé numérique" + Control.StackView.onActivated: rightPanel.headerTitleText = qsTr("call_action_show_dialer") anchors.top: parent.top anchors.bottom: parent.bottom Keys.onEscapePressed: event => { @@ -709,8 +752,8 @@ AbstractWindow { Component { id: changeLayoutPanel ChangeLayoutForm { - Control.StackView.onActivated: rightPanel.headerTitleText = qsTr( - "Modifier la disposition") + //: "Modifier la disposition" + Control.StackView.onActivated: rightPanel.headerTitleText = qsTr("call_action_change_layout") Keys.onEscapePressed: event => { rightPanel.visible = false event.accepted = true @@ -725,7 +768,8 @@ AbstractWindow { id: callListPanel ColumnLayout { Control.StackView.onActivated: { - rightPanel.headerTitleText = qsTr("Liste d'appel") + //: "Liste d'appel" + rightPanel.headerTitleText = qsTr("call_action_go_to_calls_list") rightPanel.customHeaderButtons = mergeCallPopupButton.createObject( rightPanel) } @@ -743,6 +787,7 @@ AbstractWindow { icon.source: AppIcons.arrowsMerge icon.width: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp) + //: call_action_merge_calls text: qsTr("Merger tous les appels") textSize: Math.round(14 * DefaultStyle.dp) onClicked: { @@ -779,7 +824,8 @@ AbstractWindow { id: settingsPanel Item { Control.StackView.onActivated: { - rightPanel.headerTitleText = qsTr("Paramètres") + //: "Paramètres" + rightPanel.headerTitleText = qsTr("call_action_go_to_settings") } Keys.onEscapePressed: event => { rightPanel.visible = false @@ -799,8 +845,8 @@ AbstractWindow { Component { id: screencastPanel Item { - Control.StackView.onActivated: rightPanel.headerTitleText = qsTr( - "Partage de votre écran") + //: "Partage de votre écran" + Control.StackView.onActivated: rightPanel.headerTitleText = qsTr("conference_action_screen_sharing") Keys.onEscapePressed: event => { rightPanel.visible = false event.accepted = true @@ -850,38 +896,33 @@ AbstractWindow { PopupButton { popup.contentItem: IconLabelButton { icon.source: AppIcons.shareNetwork - text: qsTr("Partager le lien de la réunion") + //: Partager le lien de la réunion + text: qsTr("conference_share_link_title") onClicked: { - UtilsCpp.copyToClipboard( - mainWindow.call.core.remoteAddress) - showInformationPopup( - qsTr("Copié"), qsTr( - "Le lien de la réunion a été copié dans le presse-papier"), - true) + UtilsCpp.copyToClipboard(mainWindow.call.core.remoteAddress) + //: Copié + showInformationPopup(qsTr("copied"), + //: Le lien de la réunion a été copié dans le presse-papier + qsTr("information_popup_meeting_address_copied_to_clipboard"),true) } } } } Control.StackView.onActivated: { - rightPanel.customHeaderButtons = headerbutton.createObject( - rightPanel) - rightPanel.headerTitleText = qsTr( - "Participants (%1)").arg(count) + rightPanel.customHeaderButtons = headerbutton.createObject(rightPanel) + //: "Participants (%1)" + rightPanel.headerTitleText = qsTr("conference_participants_list_title").arg(count) } call: mainWindow.call - onAddParticipantRequested: participantsStack.push( - addParticipantComp) + onAddParticipantRequested: participantsStack.push(addParticipantComp) onCountChanged: { - rightPanel.headerTitleText = qsTr( - "Participants (%1)").arg(count) + rightPanel.headerTitleText = qsTr("conference_participants_list_title").arg(count) } Connections { target: participantsStack function onCurrentItemChanged() { if (participantsStack.currentItem == participantList) - rightPanel.headerTitleText = qsTr( - "Participants (%1)").arg( - participantList.count) + rightPanel.headerTitleText = qsTr("conference_participants_list_title").arg(participantList.count) } } Connections { @@ -901,21 +942,15 @@ AbstractWindow { searchBarColor: DefaultStyle.grey_0 searchBarBorderColor: DefaultStyle.grey_200 onSelectedParticipantsCountChanged: { - rightPanel.headerSubtitleText = qsTr( - "%1 participant%2 sélectionné%2").arg( - selectedParticipantsCount).arg( - selectedParticipantsCount > 1 ? "s" : "") + rightPanel.headerSubtitleText = qsTr("group_call_participant_selected").arg(selectedParticipantsCount) participantsStack.selectedParticipants = selectedParticipants } Connections { target: participantsStack function onCurrentItemChanged() { if (participantsStack.currentItem == addParticipantLayout) { - rightPanel.headerTitleText = qsTr( - "Ajouter des participants") - rightPanel.headerSubtitleText = qsTr( - "%1 participant%2 sélectionné%2").arg( - addParticipantLayout.selectedParticipants.length).arg(addParticipantLayout.selectedParticipants.length > 1 ? "s" : "") + rightPanel.headerTitleText = qsTr("meeting_schedule_add_participants_title") + rightPanel.headerSubtitleText = qsTr("group_call_participant_selected").arg(addParticipantLayout.selectedParticipants.length) } } } @@ -929,7 +964,8 @@ AbstractWindow { EncryptionSettings { call: mainWindow.call Control.StackView.onActivated: { - rightPanel.headerTitleText = qsTr("Chiffrement") + //: Chiffrement + rightPanel.headerTitleText = qsTr("call_encryption_title") } onEncryptionValidationRequested: zrtpValidation.open() } @@ -938,7 +974,8 @@ AbstractWindow { id: statsPanel CallStatistics { Control.StackView.onActivated: { - rightPanel.headerTitleText = qsTr("Statistiques") + //: Statistiques + rightPanel.headerTitleText = qsTr("call_stats_title") } call: mainWindow.call } @@ -1055,7 +1092,8 @@ AbstractWindow { Layout.row: 0 icon.width: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp) - ToolTip.text: qsTr("Terminer l'appel") + //: "Terminer l'appel" + ToolTip.text: 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) @@ -1085,9 +1123,10 @@ AbstractWindow { Layout.preferredHeight: Math.round(55 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp) - ToolTip.text: checked ? qsTr( - "Reprendre l'appel") : qsTr( - "Mettre l'appel en pause") + //: "Reprendre l'appel" + 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) @@ -1117,7 +1156,8 @@ AbstractWindow { icon.width: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp) contentImageColor: DefaultStyle.grey_0 - ToolTip.text: qsTr("Transférer l'appel") + //: "Transférer l'appel" + ToolTip.text: qsTr("call_action_transfer_call") onCheckedChanged: { console.log("checked transfer changed", checked) if (checked) { @@ -1143,7 +1183,8 @@ AbstractWindow { Layout.preferredHeight: Math.round(55 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp) - ToolTip.text: qsTr("Initier un nouvel appel") + //: "Initier un nouvel appel" + ToolTip.text: qsTr("call_action_start_new_call_hint") onCheckedChanged: { console.log("checked newcall changed", checked) if (checked) { @@ -1169,7 +1210,8 @@ AbstractWindow { icon.source: AppIcons.callList icon.width: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp) - ToolTip.text: qsTr("Afficher la liste d'appels") + //: "Afficher la liste d'appels" + ToolTip.text: qsTr("call_display_call_list_hint") onCheckedChanged: { if (checked) { rightPanel.visible = true @@ -1207,8 +1249,9 @@ AbstractWindow { === LinphoneEnums.CallState.StreamsRunning) iconUrl: AppIcons.videoCamera checkedIconUrl: AppIcons.videoCameraSlash - ToolTip.text: mainWindow.localVideoEnabled ? qsTr("Désactiver la vidéo") : qsTr( - "Activer la vidéo") + //: "Désactiver la vidéo" + //: "Activer la vidéo" + ToolTip.text: 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) @@ -1219,8 +1262,11 @@ AbstractWindow { } CheckableButton { iconUrl: AppIcons.microphone - ToolTip.text: mainWindow.call - && mainWindow.call.core.microphoneMuted ? qsTr("Activer le son") : qsTr("Désactiver le son") + 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 @@ -1234,7 +1280,8 @@ AbstractWindow { CheckableButton { iconUrl: AppIcons.screencast visible: !!mainWindow.conference - ToolTip.text: qsTr("Partager l'écran...") + //: Partager l'écran… + ToolTip.text: 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) @@ -1252,7 +1299,8 @@ AbstractWindow { visible: false checkable: false iconUrl: AppIcons.handWaving - ToolTip.text: qsTr("Lever la main") + //: "Lever la main" + ToolTip.text: 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) @@ -1261,7 +1309,8 @@ AbstractWindow { CheckableButton { visible: false iconUrl: AppIcons.smiley - ToolTip.text: qsTr("Envoyer une réaction") + //: "Envoyer une réaction" + ToolTip.text: 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) @@ -1269,7 +1318,8 @@ AbstractWindow { } CheckableButton { id: participantListButton - ToolTip.text: qsTr("Gérer les participants") + //: "Gérer les participants" + ToolTip.text: qsTr("call_manage_participants_hint") visible: mainWindow.conference iconUrl: AppIcons.usersTwo Layout.preferredWidth: Math.round(55 * DefaultStyle.dp) @@ -1292,7 +1342,8 @@ AbstractWindow { } PopupButton { id: moreOptionsButton - ToolTip.text: qsTr("Plus d'options...") + //: "Plus d'options…" + ToolTip.text: qsTr("call_more_options_hint") Layout.preferredWidth: Math.round(55 * DefaultStyle.dp) Layout.preferredHeight: Math.round(55 * DefaultStyle.dp) popup.topPadding: Math.round(20 * DefaultStyle.dp) @@ -1320,7 +1371,8 @@ AbstractWindow { icon.source: AppIcons.squaresFour icon.width: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp) - text: qsTr("Modifier la disposition") + //: "Modifier la disposition" + text: qsTr("call_action_change_conference_layout") style: ButtonStyle.noBackground onClicked: { rightPanel.visible = true @@ -1331,7 +1383,8 @@ AbstractWindow { IconLabelButton { Layout.fillWidth: true icon.source: AppIcons.fullscreen - text: qsTr("Mode Plein écran") + //: "Mode Plein écran" + text: qsTr("call_action_full_screen") icon.width: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp) checkable: true @@ -1351,7 +1404,7 @@ AbstractWindow { IconLabelButton { Layout.fillWidth: true icon.source: AppIcons.dialer - text: qsTr("Dialer") + text: qsTr("call_action_show_dialer") icon.width: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp) style: ButtonStyle.noBackground @@ -1378,8 +1431,11 @@ AbstractWindow { hoveredImageColor: contentImageColor contentImageColor: mainWindow.call && mainWindow.call.core.recording ? DefaultStyle.danger_500main : DefaultStyle.main2_500main - text: mainWindow.call - && mainWindow.call.core.recording ? qsTr("Terminer l'enregistrement") : qsTr("Enregistrer l'appel") + 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 hoveredTextColor: textColor @@ -1403,8 +1459,11 @@ AbstractWindow { contentImageColor: mainWindow.call && mainWindow.call.core.speakerMuted ? DefaultStyle.danger_500main : DefaultStyle.main2_500main hoveredImageColor: contentImageColor - text: mainWindow.call - && mainWindow.call.core.speakerMuted ? qsTr("Activer le son") : qsTr("Désactiver le son") + text: mainWindow.call && mainWindow.call.core.speakerMuted + //: "Activer le son" + ? qsTr("call_activate_speaker_hint") + //: "Désactiver le son" + : qsTr("call_deactivate_speaker_hint") textColor: mainWindow.call && mainWindow.call.core.speakerMuted ? DefaultStyle.danger_500main : DefaultStyle.main2_500main hoveredTextColor: textColor @@ -1419,7 +1478,8 @@ AbstractWindow { icon.source: AppIcons.settings icon.width: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp) - text: qsTr("Paramètres") + //: "Paramètres" + text: qsTr("call_action_go_to_settings") style: ButtonStyle.noBackground onClicked: { rightPanel.visible = true diff --git a/Linphone/view/Page/Window/Main/MainWindow.qml b/Linphone/view/Page/Window/Main/MainWindow.qml index e72e339f9..a83fc21d6 100644 --- a/Linphone/view/Page/Window/Main/MainWindow.qml +++ b/Linphone/view/Page/Window/Main/MainWindow.qml @@ -10,7 +10,7 @@ import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils AbstractWindow { id: mainWindow // height: Math.round(982 * DefaultStyle.dp) - title: qsTr("Linphone") + title: applicationName // TODO : handle this bool when security mode is implemented property bool firstConnection: true @@ -31,7 +31,12 @@ AbstractWindow { function openMainPage(connectionSucceed){ if (mainWindowStackView.currentItem.objectName !== "mainPage") mainWindowStackView.replace(mainPage, StackView.Immediate) - if (connectionSucceed) mainWindow.showInformationPopup(qsTr("Connexion réussie"), qsTr("Vous êtes connecté en mode %1").arg("interopérable")) + //: "Connexion réussie" + if (connectionSucceed) mainWindow.showInformationPopup(qsTr("information_popup_connexion_succeed_title"), + //: "Vous êtes connecté en mode %1" + qsTr("information_popup_connexion_succeed_message").arg( + //: interopérable + qsTr("interoperable"))) } function goToCallHistory() { openMainPage() @@ -47,16 +52,19 @@ AbstractWindow { } function transferCallSucceed() { openMainPage() - mainWindow.showInformationPopup(qsTr("Appel transféré"), qsTr("Votre correspondant a été transféré au contact sélectionné")) + //: "Appel transféré" + mainWindow.showInformationPopup(qsTr("call_transfer_successful_toast_title"), + //: "Votre correspondant a été transféré au contact sélectionné" + qsTr("call_transfer_successful_toast_message")) } function initStackViewItem() { - if(accountProxy && accountProxy.isInitialized) { - if (accountProxy.haveAccount) openMainPage() - else if (SettingsCpp.getFirstLaunch()) mainWindowStackView.replace(welcomePage, StackView.Immediate) - else if (SettingsCpp.assistantGoDirectlyToThirdPartySipAccountLogin) mainWindowStackView.replace(sipLoginPage, StackView.Immediate) - else mainWindowStackView.replace(loginPage, StackView.Immediate) - } - } + if(accountProxy && accountProxy.isInitialized) { + if (accountProxy.haveAccount) openMainPage() + else if (SettingsCpp.getFirstLaunch()) mainWindowStackView.replace(welcomePage, StackView.Immediate) + else if (SettingsCpp.assistantGoDirectlyToThirdPartySipAccountLogin) mainWindowStackView.replace(sipLoginPage, StackView.Immediate) + else mainWindowStackView.replace(loginPage, StackView.Immediate) + } + } function goToLogin() { if (SettingsCpp.assistantGoDirectlyToThirdPartySipAccountLogin) @@ -93,7 +101,8 @@ AbstractWindow { initStackViewItem() } function onIsSavedChanged() { - if (SettingsCpp.isSaved) UtilsCpp.showInformationPopup(qsTr("Succès"), qsTr("Les changements ont été sauvegardés"), true, mainWindow) + //: "Les changements ont été sauvegardés" + if (SettingsCpp.isSaved) UtilsCpp.showInformationPopup(qsTr("information_popup_success_title"), qsTr("information_popup_changes_saved"), true, mainWindow) } } @@ -122,7 +131,7 @@ AbstractWindow { StackView { id: mainWindowStackView anchors.fill: parent - initialItem: splashScreen + initialItem: splashScreen } Component { id: splashScreen @@ -177,14 +186,16 @@ AbstractWindow { id: registerPage RegisterPage { onReturnToLogin: goToLogin() - onBrowserValidationRequested: mainWindow.showLoadingPopup(qsTr("Veuillez valider le captcha sur la page web"), true) + //: "Veuillez valider le captcha sur la page web" + onBrowserValidationRequested: mainWindow.showLoadingPopup(qsTr("captcha_validation_loading_message"), true) Connections { target: RegisterPageCpp function onNewAccountCreationSucceed(withEmail, address, sipIdentityAddress) { mainWindowStackView.push(checkingPage, {"registerWithEmail": withEmail, "address": address, "sipIdentityAddress": sipIdentityAddress}) } function onRegisterNewAccountFailed(errorMessage) { - mainWindow.showInformationPopup(qsTr("Erreur lors de la création"), errorMessage, false) + //: "Erreur lors de la création" + mainWindow.showInformationPopup(qsTr("assistant_register_error_title"), errorMessage, false) mainWindow.closeLoadingPopup() } function onTokenConversionSucceed(){ mainWindow.closeLoadingPopup()} @@ -202,11 +213,15 @@ AbstractWindow { target: RegisterPageCpp function onLinkingNewAccountWithCodeSucceed() { goToLogin() - mainWindow.showInformationPopup(qsTr("Compte créé"), qsTr("Le compte a été créé avec succès. Vous pouvez maintenant vous connecter"), true) + //: "Compte créé" + mainWindow.showInformationPopup(qsTr("assistant_register_success_title"), + //: "Le compte a été créé. Vous pouvez maintenant vous connecter" + qsTr("assistant_register_success_message"), true) } function onLinkingNewAccountWithCodeFailed(errorMessage) { - if (errorMessage.length === 0) errorMessage = qsTr("Erreur dans le code de validation") - mainWindow.showInformationPopup(qsTr("Erreur"), errorMessage, false) + //: "Erreur dans le code de validation" + if (errorMessage.length === 0) errorMessage = qsTr("assistant_register_error_code") + mainWindow.showInformationPopup(qsTr("information_popup_error_title"), errorMessage, false) } } } diff --git a/Linphone/view/Test/ItemsTest.qml b/Linphone/view/Test/ItemsTest.qml index e5acbf5ab..d0647f9c9 100644 --- a/Linphone/view/Test/ItemsTest.qml +++ b/Linphone/view/Test/ItemsTest.qml @@ -7,7 +7,7 @@ Window { width: 960 height: 600 visible: true - title: qsTr("Test") + title: ("Test") ColumnLayout { RowLayout { ColumnLayout { @@ -134,7 +134,7 @@ Window { TabBar { spacing: 10 contentWidth: 400 - model: [qsTr("A"), qsTr("Lot"), qsTr("Of"), qsTr("Tab"), qsTr("Buttons (which one has a very long label)"), qsTr("For"), qsTr("The"), qsTr("Tab"), qsTr("Bar"), qsTr("To"), qsTr("Not"), qsTr("Have"), qsTr("Enough"), qsTr("Space"), qsTr("To"), qsTr("Display"), qsTr("Them"), qsTr("All")] + model: [("A"), ("Lot"), ("Of"), ("Tab"), ("Buttons (which one has a very long label)"), ("For"), ("The"), ("Tab"), ("Bar"), ("To"), ("Not"), ("Have"), ("Enough"), ("Space"), ("To"), ("Display"), ("Them"), ("All")] } }