cmake + french translation

This commit is contained in:
gaelle 2025-03-05 09:15:48 +01:00
parent 9011106cc3
commit f81400eed0
89 changed files with 12161 additions and 939 deletions

View file

@ -28,6 +28,7 @@ if (UNIX AND NOT APPLE)
endif() endif()
find_package(Qt6 REQUIRED COMPONENTS Core) find_package(Qt6 REQUIRED COMPONENTS Core)
find_package(Qt6 REQUIRED COMPONENTS ${QT_PACKAGES}) find_package(Qt6 REQUIRED COMPONENTS ${QT_PACKAGES})
find_package(Qt6 REQUIRED COMPONENTS LinguistTools)
if(NOT WIN32) if(NOT WIN32)
find_package(X11) find_package(X11)
@ -124,6 +125,25 @@ add_subdirectory(model)
add_subdirectory(view) add_subdirectory(view)
add_subdirectory(core) 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 # set application details
if(WIN32) if(WIN32)
configure_file("${CMAKE_SOURCE_DIR}/cmake/install/windows/appDetailsWindows.rc.in" "${CMAKE_CURRENT_BINARY_DIR}/appDetailsWindows.rc") configure_file("${CMAKE_SOURCE_DIR}/cmake/install/windows/appDetailsWindows.rc.in" "${CMAKE_CURRENT_BINARY_DIR}/appDetailsWindows.rc")

View file

@ -35,6 +35,7 @@
#include <QQmlContext> #include <QQmlContext>
#include <QQmlFileSelector> #include <QQmlFileSelector>
#include <QQuickWindow> #include <QQuickWindow>
#include <QStandardPaths>
#include <QSystemTrayIcon> #include <QSystemTrayIcon>
#include <QTimer> #include <QTimer>
#include <QTranslator> #include <QTranslator>
@ -76,6 +77,7 @@
#include "core/setting/SettingsCore.hpp" #include "core/setting/SettingsCore.hpp"
#include "core/singleapplication/singleapplication.h" #include "core/singleapplication/singleapplication.h"
#include "core/timezone/TimeZoneProxy.hpp" #include "core/timezone/TimeZoneProxy.hpp"
#include "core/translator/DefaultTranslatorCore.hpp"
#include "core/variant/VariantList.hpp" #include "core/variant/VariantList.hpp"
#include "core/videoSource/VideoSourceDescriptorGui.hpp" #include "core/videoSource/VideoSourceDescriptorGui.hpp"
#include "model/object/VariantObject.hpp" #include "model/object/VariantObject.hpp"
@ -319,8 +321,8 @@ void App::setSelf(QSharedPointer<App>(me)) {
mCoreModelConnection->makeConnectToModel(&CoreModel::requestFetchConfig, [this](QString path) { mCoreModelConnection->makeConnectToModel(&CoreModel::requestFetchConfig, [this](QString path) {
mCoreModelConnection->invokeToCore([this, path]() { mCoreModelConnection->invokeToCore([this, path]() {
auto callback = [this, path]() { auto callback = [this, path]() {
RequestDialog *obj = new RequestDialog( //: Voulez-vous télécharger et appliquer la configuration depuis cette adresse ?
tr("Voulez-vous télécharger et appliquer la configuration depuis cette adresse ?"), path); RequestDialog *obj = new RequestDialog(tr("remote_provisioning_dialog"), path);
connect(obj, &RequestDialog::result, this, [this, obj, path](int result) { connect(obj, &RequestDialog::result, this, [this, obj, path](int result) {
if (result == 1) { if (result == 1) {
mCoreModelConnection->invokeToModel( mCoreModelConnection->invokeToModel(
@ -516,6 +518,10 @@ void App::initCore() {
setAutoStart(settings->getAutoStart()); setAutoStart(settings->getAutoStart());
setQuitOnLastWindowClosed(settings->getExitOnClose()); 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"); const QUrl url("qrc:/qt/qml/Linphone/view/Page/Window/Main/MainWindow.qml");
QObject::connect( QObject::connect(
mEngine, &QQmlApplicationEngine::objectCreated, this, mEngine, &QQmlApplicationEngine::objectCreated, this,
@ -549,6 +555,52 @@ void App::initCore() {
Qt::BlockingQueuedConnection); 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() { void App::initCppInterfaces() {
qmlRegisterSingletonType<App>(Constants::MainQmlUri, 1, 0, "AppCpp", qmlRegisterSingletonType<App>(Constants::MainQmlUri, 1, 0, "AppCpp",
[](QQmlEngine *engine, QJSEngine *) -> QObject * { return App::getInstance(); }); [](QQmlEngine *engine, QJSEngine *) -> QObject * { return App::getInstance(); });
@ -720,24 +772,35 @@ void App::createCommandParser() {
if (!mParser) delete mParser; if (!mParser) delete mParser;
mParser = new QCommandLineParser(); mParser = new QCommandLineParser();
mParser->setApplicationDescription(tr("A free (libre) SIP video-phone.")); //: "A free and open source SIP video-phone."
mParser->addPositionalArgument( mParser->setApplicationDescription(tr("application_description"));
"command", tr("Send an order to the application towards a command line").replace("%1", APPLICATION_NAME), //: "Send an order to the application towards a command line"
"[command]"); mParser->addPositionalArgument("command", tr("command_line_arg_order").replace("%1", APPLICATION_NAME), "[command]");
mParser->addOptions({ 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)}, //{"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", {"fetch-config",
tr("Specify the linphone configuration file to be fetched. It will be merged with the current " //: "Specify the linphone configuration file to be fetched. It will be merged with the current configuration."
"configuration.") tr("command_line_option_config_to_fetch")
.replace("%1", EXECUTABLE_NAME), .replace("%1", EXECUTABLE_NAME),
tr("URL, path or file")}, //: "URL, path or file"
//{{"c", "call"}, tr("commandLineOptionCall").replace("%1", EXECUTABLE_NAME), tr("commandLineOptionCallArg")}, tr("command_line_option_config_to_fetch_arg")},
{"minimized", tr("commandLineOptionMinimized")},
{{"V", "verbose"}, tr("Log to stdout some debug information while running")}, //{{"c", "call"}, tr("command_line_option_call").replace("%1", EXECUTABLE_NAME), tr("command_line_option_call_arg")}, {"minimized", tr("command_line_option_minimized")},
{"qt-logs-only", tr("Print only logs from the application")},
//: "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 // Should be call only at first start
@ -1003,7 +1066,7 @@ void App::exportDesktopFile() {
} }
bool App::generateDesktopFile(const QString &confPath, bool remove, bool openInBackground) { 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); QFile file(confPath);
if (remove) { if (remove) {
@ -1095,7 +1158,9 @@ void App::setSysTrayIcon() {
if (mSettings && !mSettings->getExitOnClose()) { if (mSettings && !mSettings->getExitOnClose()) {
restoreAction = new QAction(root); restoreAction = new QAction(root);
auto setRestoreActionText = [restoreAction](bool visible) { 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()); setRestoreActionText(root->isVisible());
connect(root, &QWindow::visibleChanged, restoreAction, setRestoreActionText); connect(root, &QWindow::visibleChanged, restoreAction, setRestoreActionText);
@ -1109,8 +1174,8 @@ void App::setSysTrayIcon() {
} }
}); });
} }
//: "Quitter"
QAction *quitAction = new QAction(tr("Quitter"), root); QAction *quitAction = new QAction(tr("quit_action"), root);
root->connect(quitAction, &QAction::triggered, this, &App::quit); root->connect(quitAction, &QAction::triggered, this, &App::quit);
// trayIcon: Left click actions. // trayIcon: Left click actions.
@ -1146,7 +1211,8 @@ void App::setSysTrayIcon() {
//----------------------------------------------------------- //-----------------------------------------------------------
void App::setLocale(QString configLocale) { void App::setLocale(QString configLocale) {
mLocale = QLocale(QLocale::French); if (configLocale.isEmpty()) mLocale = QLocale(configLocale);
else mLocale = QLocale(QLocale::system().name());
} }
QLocale App::getLocale() { QLocale App::getLocale() {
@ -1157,11 +1223,12 @@ QLocale App::getLocale() {
// Version infos. // Version infos.
//----------------------------------------------------------- //-----------------------------------------------------------
//: "Inconnue"
QString App::getShortApplicationVersion() { QString App::getShortApplicationVersion() {
#ifdef LINPHONEAPP_SHORT_VERSION #ifdef LINPHONEAPP_SHORT_VERSION
return QStringLiteral(LINPHONEAPP_SHORT_VERSION); return QStringLiteral(LINPHONEAPP_SHORT_VERSION);
#else #else
return tr("inconnue"); return tr('unknown');
#endif #endif
} }
@ -1169,7 +1236,7 @@ QString App::getGitBranchName() {
#ifdef GIT_BRANCH_NAME #ifdef GIT_BRANCH_NAME
return QStringLiteral(GIT_BRANCH_NAME); return QStringLiteral(GIT_BRANCH_NAME);
#else #else
return tr("inconnue"); return tr('unknown');
#endif #endif
} }
@ -1177,6 +1244,6 @@ QString App::getSdkVersion() {
#ifdef LINPHONESDK_VERSION #ifdef LINPHONESDK_VERSION
return QStringLiteral(LINPHONESDK_VERSION); return QStringLiteral(LINPHONESDK_VERSION);
#else #else
return tr("inconnue"); return tr('unknown');
#endif #endif
} }

View file

@ -35,6 +35,7 @@ class Thread;
class Notifier; class Notifier;
class QQuickWindow; class QQuickWindow;
class QSystemTrayIcon; class QSystemTrayIcon;
class DefaultTranslatorCore;
class App : public SingleApplication, public AbstractObject { class App : public SingleApplication, public AbstractObject {
Q_OBJECT Q_OBJECT
@ -112,6 +113,7 @@ public:
void clean(); void clean();
void init(); void init();
void initCore(); void initCore();
void initLocale();
void initCppInterfaces(); void initCppInterfaces();
void initFonts(); void initFonts();
void restart(); void restart();
@ -194,6 +196,8 @@ private:
bool mAutoStart = false; bool mAutoStart = false;
bool mCoreStarted = false; bool mCoreStarted = false;
QLocale mLocale = QLocale::system(); QLocale mLocale = QLocale::system();
DefaultTranslatorCore *mTranslatorCore = nullptr;
DefaultTranslatorCore *mDefaultTranslatorCore = nullptr;
QTimer mDateUpdateTimer; QTimer mDateUpdateTimer;
QDate mCurrentDate; QDate mCurrentDate;

View file

@ -54,6 +54,8 @@ list(APPEND _LINPHONEAPP_SOURCES
core/timezone/TimeZoneProxy.cpp core/timezone/TimeZoneProxy.cpp
core/timezone/TimeZone.cpp core/timezone/TimeZone.cpp
core/translator/DefaultTranslatorCore.cpp
core/participant/ParticipantCore.cpp core/participant/ParticipantCore.cpp
core/participant/ParticipantGui.cpp core/participant/ParticipantGui.cpp
core/participant/ParticipantDeviceCore.cpp core/participant/ParticipantDeviceCore.cpp

View file

@ -403,16 +403,21 @@ int AccountCore::getDialPlanIndex(QVariantMap dialPlanString) {
QString AccountCore::getHumanReadableRegistrationState() const { QString AccountCore::getHumanReadableRegistrationState() const {
switch (mRegistrationState) { switch (mRegistrationState) {
case LinphoneEnums::RegistrationState::Ok: case LinphoneEnums::RegistrationState::Ok:
return tr("Connecté"); //: "Connecté"
return tr("drawer_menu_account_connection_status_connected");
case LinphoneEnums::RegistrationState::Refreshing: 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: case LinphoneEnums::RegistrationState::Progress:
return tr("En cours de connexion…"); // "Connexion…"
return tr("drawer_menu_account_connection_status_progress");
case LinphoneEnums::RegistrationState::Failed: case LinphoneEnums::RegistrationState::Failed:
return tr("Erreur"); // "Erreur"
return tr("drawer_menu_account_connection_status_failed");
case LinphoneEnums::RegistrationState::None: case LinphoneEnums::RegistrationState::None:
case LinphoneEnums::RegistrationState::Cleared: case LinphoneEnums::RegistrationState::Cleared:
return tr("Désactivé"); // "Désactivé"
return tr("drawer_menu_account_connection_status_cleared");
default: default:
return " "; return " ";
} }
@ -421,12 +426,15 @@ QString AccountCore::getHumanReadableRegistrationState() const {
QString AccountCore::getHumanReadableRegistrationStateExplained() const { QString AccountCore::getHumanReadableRegistrationStateExplained() const {
switch (mRegistrationState) { switch (mRegistrationState) {
case LinphoneEnums::RegistrationState::Ok: 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: 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::None:
case LinphoneEnums::RegistrationState::Cleared: 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: default:
return " "; return " ";
} }

View file

@ -154,7 +154,8 @@ void AccountDeviceList::setSelf(QSharedPointer<AccountDeviceList> me) {
lDebug() << "REQUEST ERROR" << errorMessage << "/" << int(request->getType()); lDebug() << "REQUEST ERROR" << errorMessage << "/" << int(request->getType());
QString message = QString::fromStdString(errorMessage); QString message = QString::fromStdString(errorMessage);
if (request->getType() == linphone::AccountManagerServicesRequest::Type::GetDevicesList) { 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); emit requestError(message);
}); });

View file

@ -92,7 +92,7 @@ void CallHistoryList::setSelf(QSharedPointer<CallHistoryList> me) {
toConnect(callLogs->get()); toConnect(callLogs->get());
if (oldLog == mList.end()) { // New if (oldLog == mList.end()) { // New
prepend(*callLogs); prepend(*callLogs);
} else { // Update (status, duration, etc ...) } else { // Update (status, duration, etc )
replace(oldLog->objectCast<CallHistoryCore>(), *callLogs); replace(oldLog->objectCast<CallHistoryCore>(), *callLogs);
} }
delete[] callLogs; delete[] callLogs;

View file

@ -207,9 +207,10 @@ void CallCore::setSelf(QSharedPointer<CallCore> me) {
mCallModelConnection->invokeToCore([this, recording]() { mCallModelConnection->invokeToCore([this, recording]() {
setRecording(recording); setRecording(recording);
if (recording == false) { if (recording == false) {
Utils::showInformationPopup(tr("Enregistrement terminé"), //: "Enregistrement terminé"
tr("L'appel a été enregistré dans le fichier : %1") Utils::showInformationPopup(tr("call_record_end_message"),
.arg(QString::fromStdString(mCallModel->getRecordFile())), //: "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()); true, App::getInstance()->getCallsWindow());
} }
}); });
@ -385,19 +386,23 @@ void CallCore::setSelf(QSharedPointer<CallCore> me) {
auto codecType = playloadType ? playloadType->getMimeType() : ""; auto codecType = playloadType ? playloadType->getMimeType() : "";
auto codecRate = playloadType ? playloadType->getClockRate() / 1000 : 0; auto codecRate = playloadType ? playloadType->getClockRate() / 1000 : 0;
audioStats.mCodec = 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(); auto linAudioStats = call->getAudioStats();
if (linAudioStats) { 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("")
.arg(round(linAudioStats->getUploadBandwidth())) .arg(round(linAudioStats->getUploadBandwidth()))
.arg("") .arg("")
.arg(round(linAudioStats->getDownloadBandwidth())); .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->getSenderLossRate())
.arg(linAudioStats->getReceiverLossRate()); .arg(linAudioStats->getReceiverLossRate());
//: "Tampon de gigue: %1 ms"
audioStats.mJitterBufferSize = audioStats.mJitterBufferSize =
tr("Tampon de gigue: %1 ms").arg(linAudioStats->getJitterBufferSizeMs()); tr("call_stats_jitter_buffer_label").arg(linAudioStats->getJitterBufferSizeMs());
} }
setAudioStats(audioStats); setAudioStats(audioStats);
} else if (stats->getType() == linphone::StreamType::Video) { } else if (stats->getType() == linphone::StreamType::Video) {
@ -407,15 +412,15 @@ void CallCore::setSelf(QSharedPointer<CallCore> me) {
auto codecType = playloadType ? playloadType->getMimeType() : ""; auto codecType = playloadType ? playloadType->getMimeType() : "";
auto codecRate = playloadType ? playloadType->getClockRate() / 1000 : 0; auto codecRate = playloadType ? playloadType->getClockRate() / 1000 : 0;
videoStats.mCodec = 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(); auto linVideoStats = call->getVideoStats();
if (stats) { if (stats) {
videoStats.mBandwidth = tr("Bande passante : %1 %2 kbits/s %3 %4 kbits/s") videoStats.mBandwidth = tr("call_stats_bandwidth_label")
.arg("") .arg("")
.arg(round(linVideoStats->getUploadBandwidth())) .arg(round(linVideoStats->getUploadBandwidth()))
.arg("") .arg("")
.arg(round(linVideoStats->getDownloadBandwidth())); .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->getSenderLossRate())
.arg(linVideoStats->getReceiverLossRate()); .arg(linVideoStats->getReceiverLossRate());
} }
@ -423,12 +428,14 @@ void CallCore::setSelf(QSharedPointer<CallCore> me) {
params->getSentVideoDefinition() ? params->getSentVideoDefinition()->getName() : ""; params->getSentVideoDefinition() ? params->getSentVideoDefinition()->getName() : "";
auto receivedResolution = auto receivedResolution =
params->getReceivedVideoDefinition() ? params->getReceivedVideoDefinition()->getName() : ""; 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), "", .arg("", Utils::coreStringToAppString(sentResolution), "",
Utils::coreStringToAppString(receivedResolution)); Utils::coreStringToAppString(receivedResolution));
auto sentFps = params->getSentFramerate(); auto sentFps = params->getSentFramerate();
auto receivedFps = params->getReceivedFramerate(); 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); setVideoStats(videoStats);
} }
}); });

View file

@ -573,7 +573,9 @@ void ConferenceInfoCore::save() {
mCoreModelConnection->invokeToModel([this, thisCopy]() { mCoreModelConnection->invokeToModel([this, thisCopy]() {
if (CoreModel::getInstance()->getCore()->getDefaultAccount()->getState() != if (CoreModel::getInstance()->getCore()->getDefaultAccount()->getState() !=
linphone::RegistrationState::Ok) { 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(); emit saveFailed();
return; return;
} }

View file

@ -26,8 +26,10 @@
DEFINE_ABSTRACT_OBJECT(FriendCore) DEFINE_ABSTRACT_OBJECT(FriendCore)
const QString _addressLabel = FriendCore::tr("Adresse SIP"); //: "Adresse SIP"
const QString _phoneLabel = FriendCore::tr("Téléphone"); const QString _addressLabel = FriendCore::tr("sip_address");
//: "Téléphone"
const QString _phoneLabel = FriendCore::tr("device_id");
QSharedPointer<FriendCore> QSharedPointer<FriendCore>
FriendCore::create(const std::shared_ptr<linphone::Friend> &contact, bool isStored, int sourceFlags) { FriendCore::create(const std::shared_ptr<linphone::Friend> &contact, bool isStored, int sourceFlags) {
@ -413,7 +415,8 @@ void FriendCore::appendAddress(const QString &addr) {
QString interpretedFullAddress = linphoneAddr ? Utils::coreStringToAppString(linphoneAddr->asString()) : ""; QString interpretedFullAddress = linphoneAddr ? Utils::coreStringToAppString(linphoneAddr->asString()) : "";
QString interpretedAddress = linphoneAddr ? Utils::coreStringToAppString(linphoneAddr->asStringUriOnly()) : ""; QString interpretedAddress = linphoneAddr ? Utils::coreStringToAppString(linphoneAddr->asStringUriOnly()) : "";
mCoreModelConnection->invokeToCore([this, interpretedAddress, interpretedFullAddress]() { 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 { else {
mAddressList.append(Utils::createFriendAddressVariant(_addressLabel, interpretedAddress)); mAddressList.append(Utils::createFriendAddressVariant(_addressLabel, interpretedAddress));
if (mDefaultFullAddress.isEmpty()) mDefaultFullAddress = interpretedFullAddress; if (mDefaultFullAddress.isEmpty()) mDefaultFullAddress = interpretedFullAddress;

View file

@ -76,7 +76,8 @@ void LoginPage::login(const QString &username,
switch (state) { switch (state) {
case linphone::RegistrationState::Failed: { case linphone::RegistrationState::Failed: {
if (message.isEmpty()) if (message.isEmpty())
setErrorMessage(QString(tr("Erreur durant la connexion"))); //: Erreur durant la connexion
setErrorMessage(tr("default_account_connection_state_error_toast"));
else else
setErrorMessage(message); setErrorMessage(message);
if (accountManager) { if (accountManager) {

View file

@ -320,14 +320,14 @@ void Notifier::notifyReceivedMessages(const list<shared_ptr<linphone::ChatMessag
} }
} else if (fileContent->isVoiceRecording()) } else if (fileContent->isVoiceRecording())
//: 'Voice message received!' : message to warn the user in a notofication for voice messages. //: 'Voice message received!' : message to warn the user in a notofication for voice messages.
txt = tr("newVoiceMessage"); txt = tr("new_voice_message");
else txt = tr("newFileMessage"); else txt = tr("new_file_message");
if (txt.isEmpty() && message->hasConferenceInvitationContent()) if (txt.isEmpty() && message->hasConferenceInvitationContent())
//: 'Conference invitation received!' : Notification about receiving an invitation to a conference. //: 'Conference invitation received!' : Notification about receiving an invitation to a conference.
txt = tr("newConferenceInvitation"); txt = tr("new_conference_invitation");
} else } else
//: 'New messages received!' Notification that warn the user of new messages. //: 'New messages received!' Notification that warn the user of new messages.
txt = tr("newChatRoomMessages"); txt = tr("new_chat_room_messages");
map["message"] = txt; map["message"] = txt;
shared_ptr<linphone::ChatRoom> chatRoom(message->getChatRoom()); shared_ptr<linphone::ChatRoom> chatRoom(message->getChatRoom());
map["timelineModel"].setValue( map["timelineModel"].setValue(
@ -366,21 +366,21 @@ void Notifier::notifyReceivedReactions(
} }
} else if (fileContent->isVoiceRecording()) } else if (fileContent->isVoiceRecording())
//: 'Voice message' : Voice message type that has been reacted. //: 'Voice message' : Voice message type that has been reacted.
messageTxt += tr("voiceMessageReact"); messageTxt += tr("voice_message_react");
else { else {
QFileInfo file(Utils::coreStringToAppString(fileContent->getFilePath())); QFileInfo file(Utils::coreStringToAppString(fileContent->getFilePath()));
messageTxt += file.fileName(); messageTxt += file.fileName();
} }
if (messageTxt.isEmpty() && message->hasConferenceInvitationContent()) if (messageTxt.isEmpty() && message->hasConferenceInvitationContent())
//: 'Conference invitation' : Conference invitation message type that has been reacted. //: '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 //: ''Has reacted by %1 to: %2' : Reaction message. %1=Reaction(emoji), %2=type of message(Voice
//: Message/Conference invitation/ Message text) //: 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 } else
//: 'New reactions received!' : Notification that warn the user of new reactions. //: 'New reactions received!' : Notification that warn the user of new reactions.
txt = tr("newReactionsMessages"); txt = tr("new_reactions_messages");
map["message"] = txt; map["message"] = txt;
map["timelineModel"].setValue(timelineModel.get()); map["timelineModel"].setValue(timelineModel.get());
@ -412,7 +412,7 @@ void Notifier::notifyReceivedFileMessage(const shared_ptr<linphone::ChatMessage>
void Notifier::notifyNewVersionAvailable(const QString &version, const QString &url) { void Notifier::notifyNewVersionAvailable(const QString &version, const QString &url) {
QVariantMap map; QVariantMap map;
map["message"] = tr("newVersionAvailable").arg(version); map["message"] = tr("new_version_available").arg(version);
map["url"] = url; map["url"] = url;
CREATE_NOTIFICATION(Notifier::NewVersionAvailable, map) CREATE_NOTIFICATION(Notifier::NewVersionAvailable, map)
} }

View file

@ -84,7 +84,7 @@ void DownloadablePayloadTypeCore::setSelf(QSharedPointer<DownloadablePayloadType
void DownloadablePayloadTypeCore::downloadAndExtract(bool isUpdate) { void DownloadablePayloadTypeCore::downloadAndExtract(bool isUpdate) {
mustBeInMainThread(log().arg(Q_FUNC_INFO)); mustBeInMainThread(log().arg(Q_FUNC_INFO));
lInfo() << log().arg("Downloading `%1` codec...").arg(mMimeType); lInfo() << log().arg("Downloading `%1` codec").arg(mMimeType);
auto codecsFolder = Paths::getCodecsDirPath(); auto codecsFolder = Paths::getCodecsDirPath();
QString versionFilePath = codecsFolder + mMimeType + ".txt"; QString versionFilePath = codecsFolder + mMimeType + ".txt";
QFile versionFile(versionFilePath); QFile versionFile(versionFilePath);

View file

@ -123,7 +123,7 @@ void MagicSearchList::setSelf(QSharedPointer<MagicSearchList> me) {
linphoneFriend->addPhoneNumber(phoneNumber); linphoneFriend->addPhoneNumber(phoneNumber);
contact = FriendCore::create(linphoneFriend, isStored, it->getSourceFlags()); contact = FriendCore::create(linphoneFriend, isStored, it->getSourceFlags());
contact->setGivenName(Utils::coreStringToAppString(it->getPhoneNumber())); 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); contacts->append(contact);
} }
} }

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <QDirIterator>
#include <QtDebug>
#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;
}

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef DEFAULT_TRANSLATOR_CORE_H_
#define DEFAULT_TRANSLATOR_CORE_H_
#include <QSet>
#include <QTranslator>
// =============================================================================
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<QString> 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_

View file

@ -10,4 +10,10 @@ foreach(f ${files})
get_filename_component(filename ${f} NAME) get_filename_component(filename ${f} NAME)
list(APPEND _LINPHONEAPP_RC_FILES data/image/${filename}) list(APPEND _LINPHONEAPP_RC_FILES data/image/${filename})
endforeach() 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) set(_LINPHONEAPP_RC_FILES ${_LINPHONEAPP_RC_FILES} PARENT_SCOPE)

View file

@ -1,3 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="en_US"></TS>

View file

@ -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)

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -80,7 +80,8 @@ bool AccountManager::login(QString username,
auto otherParams = otherAccount->getParams(); auto otherParams = otherAccount->getParams();
if (otherParams->getIdentityAddress()->getUsername() == Utils::appStringToCoreString(username) && if (otherParams->getIdentityAddress()->getUsername() == Utils::appStringToCoreString(username) &&
otherParams->getDomain() == Utils::appStringToCoreString(domain)) { 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; return false;
} }
} }
@ -93,7 +94,8 @@ bool AccountManager::login(QString username,
auto serverAddress = auto serverAddress =
factory->createAddress(Utils::appStringToCoreString(QStringLiteral("sip:%1").arg(domain))); factory->createAddress(Utils::appStringToCoreString(QStringLiteral("sip:%1").arg(domain)));
if (!serverAddress) { 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; return false;
} }
serverAddress->setTransport(transportType); serverAddress->setTransport(transportType);
@ -104,13 +106,17 @@ bool AccountManager::login(QString username,
qWarning() << log() qWarning() << log()
.arg(QStringLiteral("Unable to set identity address: `%1`.")) .arg(QStringLiteral("Unable to set identity address: `%1`."))
.arg(Utils::coreStringToAppString(identity->asStringUriOnly())); .arg(Utils::coreStringToAppString(identity->asStringUriOnly()));
//: "Impossible de configurer l'adresse : `%1`."
*errorMessage = *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; return false;
} }
if (account->setParams(params)) { 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; return false;
} }
auto authInfo = factory->createAuthInfo(Utils::appStringToCoreString(username), // Username. auto authInfo = factory->createAuthInfo(Utils::appStringToCoreString(username), // Username.
@ -132,8 +138,10 @@ bool AccountManager::login(QString username,
connect( connect(
mAccountModel.get(), &AccountModel::removed, this, [this]() { mAccountModel = nullptr; }, mAccountModel.get(), &AccountModel::removed, this, [this]() { mAccountModel = nullptr; },
Qt::SingleShotConnection); Qt::SingleShotConnection);
if (account->getError() == linphone::Reason::Forbidden) errorMessage = tr("Le couple identifiant mot de passe ne correspond pas"); //: "Le couple identifiant mot de passe ne correspond pas"
else errorMessage = tr("Erreur durant la connexion"); 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(); mAccountModel->removeAccount();
} else if (state == linphone::RegistrationState::Ok) { } else if (state == linphone::RegistrationState::Ok) {
core->setDefaultAccount(account); core->setDefaultAccount(account);
@ -145,7 +153,8 @@ bool AccountManager::login(QString username,
}); });
auto status = core->addAccount(account); auto status = core->addAccount(account);
if (status == -1) { if (status == -1) {
*errorMessage = tr("Impossible d'ajouter le compte."); //: "Impossible d'ajouter le compte."
*errorMessage = tr("assistant_account_add_error");
core->removeAuthInfo(authInfo); core->removeAuthInfo(authInfo);
return false; return false;
} }

View file

@ -334,16 +334,32 @@ void CallModel::updateCallErrorFromReason(linphone::Reason reason) {
QString error; QString error;
switch (reason) { switch (reason) {
case linphone::Reason::Declined: 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; break;
case linphone::Reason::NotFound: 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; break;
case linphone::Reason::Busy: case linphone::Reason::Busy:
error = tr("Le correspondant est occupé"); //: "Le correspondant est occupé"
error = tr("call_error_user_busy_toast");
break; break;
case linphone::Reason::NotAcceptable: 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; break;
default: default:
break; break;

View file

@ -36,12 +36,12 @@ DEFINE_ABSTRACT_OBJECT(CliModel)
std::shared_ptr<CliModel> CliModel::gCliModel; std::shared_ptr<CliModel> CliModel::gCliModel;
QMap<QString, CliModel::Command> CliModel::mCommands{ QMap<QString, CliModel::Command> CliModel::mCommands{
createCommand("show", QT_TR_NOOP("showFunctionDescription"), &CliModel::cliShow, {}, true), createCommand("show", QT_TR_NOOP("show_function_description"), &CliModel::cliShow, {}, true),
createCommand("fetch-config", QT_TR_NOOP("fetchConfigFunctionDescription"), &CliModel::cliFetchConfig, {}, true), createCommand("fetch-config", QT_TR_NOOP("fetch_config_function_description"), &CliModel::cliFetchConfig, {}, true),
createCommand("call", QT_TR_NOOP("callFunctionDescription"), &CliModel::cliCall, {{"sip-address", {}}}, true), createCommand("call", QT_TR_NOOP("call_function_description"), &CliModel::cliCall, {{"sip-address", {}}}, true),
createCommand("bye", QT_TR_NOOP("byeFunctionDescription"), &CliModel::cliBye, {}, true), createCommand("bye", QT_TR_NOOP("bye_function_description"), &CliModel::cliBye, {}, true),
createCommand("accept", QT_TR_NOOP("acceptFunctionDescription"), &CliModel::cliAccept, {}, true), createCommand("accept", QT_TR_NOOP("accept_function_description"), &CliModel::cliAccept, {}, true),
createCommand("decline", QT_TR_NOOP("declineFunctionDescription"), &CliModel::cliDecline, {}, true), createCommand("decline", QT_TR_NOOP("decline_function_description"), &CliModel::cliDecline, {}, true),
/* /*
createCommand("initiate-conference", QT_TR_NOOP("initiateConferenceFunctionDescription"), cliInitiateConference, { createCommand("initiate-conference", QT_TR_NOOP("initiateConferenceFunctionDescription"), cliInitiateConference, {
{ "sip-address", {} }, { "conference-id", {} } { "sip-address", {} }, { "conference-id", {} }
@ -344,7 +344,7 @@ void CliModel::executeCommand(const QString &command) { //, CommandFormat *forma
const QString &functionName = parseFunctionName(command, false); const QString &functionName = parseFunctionName(command, false);
const QString configURI = QString(EXECUTABLE_NAME).toLower() + "-config"; const QString configURI = QString(EXECUTABLE_NAME).toLower() + "-config";
if (!functionName.isEmpty()) { // It is a CLI if (!functionName.isEmpty()) { // It is a CLI
qInfo() << QStringLiteral("Detecting cli command: `%1`...").arg(command); qInfo() << QStringLiteral("Detecting cli command: `%1`").arg(command);
QHash<QString, QString> args = parseArgs(command); QHash<QString, QString> args = parseArgs(command);
QHash<QString, QString> argsToProcess; QHash<QString, QString> argsToProcess;
for (auto it = args.begin(); it != args.end(); ++it) { 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( address = linphone::Factory::get()->createAddress(
Utils::appStringToCoreString(transformedCommand)); // Test if command is an address Utils::appStringToCoreString(transformedCommand)); // Test if command is an address
// if (format) *format = UriFormat; // if (format) *format = UriFormat;
qInfo() << QStringLiteral("Detecting URI command: `%1`...").arg(command); qInfo() << QStringLiteral("Detecting URI command: `%1`").arg(command);
QString functionName; QString functionName;
if (address) { if (address) {
functionName = Utils::coreStringToAppString(address->getHeader("method")).isEmpty() functionName = Utils::coreStringToAppString(address->getHeader("method")).isEmpty()

View file

@ -158,7 +158,8 @@ bool ToolModel::createCall(const QString &sipAddress,
lCritical() << "[" + QString(gClassName) + "] The calling address is not an interpretable SIP address: " lCritical() << "[" + QString(gClassName) + "] The calling address is not an interpretable SIP address: "
<< sipAddress; << sipAddress;
if (errorMessage) { 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; return false;
} }
@ -166,7 +167,7 @@ bool ToolModel::createCall(const QString &sipAddress,
if (isConference) mediaEncryption = linphone::MediaEncryption::ZRTP; if (isConference) mediaEncryption = linphone::MediaEncryption::ZRTP;
if (SettingsModel::dndEnabled( 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. // again when no more calls are running.
SettingsModel::getInstance()->setCallToneIndicationsEnabled(true); SettingsModel::getInstance()->setCallToneIndicationsEnabled(true);
} }
@ -313,17 +314,17 @@ bool ToolModel::friendIsInFriendList(const std::shared_ptr<linphone::FriendList>
void ToolModel::loadDownloadedCodecs() { void ToolModel::loadDownloadedCodecs() {
mustBeInLinphoneThread(sLog().arg(Q_FUNC_INFO)); mustBeInLinphoneThread(sLog().arg(Q_FUNC_INFO));
#if defined(Q_OS_LINUX) || defined(Q_OS_WIN) #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()); QDirIterator it(Paths::getCodecsDirPath());
while (it.hasNext()) { while (it.hasNext()) {
QFileInfo info(it.next()); QFileInfo info(it.next());
const QString filename(info.fileName()); const QString filename(info.fileName());
if (QLibrary::isLibrary(filename)) { if (QLibrary::isLibrary(filename)) {
qInfo() << QStringLiteral("Loading `%1` symbols...").arg(filename); qInfo() << QStringLiteral("Loading `%1` symbols").arg(filename);
auto library = QLibrary(info.filePath()); auto library = QLibrary(info.filePath());
if (!library.load()) // lib.load()) if (!library.load()) // lib.load())
qWarning() << QStringLiteral("Failed to load `%1` symbols.").arg(filename) << library.errorString(); 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); } else qWarning() << QStringLiteral("Found codec file `%1` that is not a library").arg(filename);
} }
CoreModel::getInstance()->getCore()->reloadMsPlugins(""); CoreModel::getInstance()->getCore()->reloadMsPlugins("");
@ -360,7 +361,8 @@ QVariantMap ToolModel::createVariant(const std::shared_ptr<const linphone::Audio
map.insert("id", device ? Utils::coreStringToAppString(device->getId()) : ""); map.insert("id", device ? Utils::coreStringToAppString(device->getId()) : "");
map.insert("display_name", map.insert("display_name",
device ? Utils::coreStringToAppString(device->getDriverName() + ": " + device->getDeviceName()) device ? Utils::coreStringToAppString(device->getDriverName() + ": " + device->getDeviceName())
: tr("Unknown device")); //: "Unknown device"
: tr("unknown_audio_device_name"));
return map; return map;
} }

View file

@ -156,7 +156,7 @@ public:
static constexpr char PathMessageHistoryList[] = "/message-history.db"; static constexpr char PathMessageHistoryList[] = "/message-history.db";
static constexpr char PathZrtpSecrets[] = "/zidcache"; static constexpr char PathZrtpSecrets[] = "/zidcache";
static constexpr char LanguagePath[] = ":/languages/"; static constexpr char LanguagePath[] = ":/data/languages/";
// The main windows of Linphone desktop. // The main windows of Linphone desktop.
static constexpr char QmlViewMainWindow[] = "qrc:/qt/qml/Linphone/view/Page/Window/Main/MainWindow.qml"; static constexpr char QmlViewMainWindow[] = "qrc:/qt/qml/Linphone/view/Page/Window/Main/MainWindow.qml";

View file

@ -63,7 +63,8 @@ QString LinphoneEnums::toString(LinphoneEnums::MediaEncryption encryption) {
case LinphoneEnums::MediaEncryption::Srtp: case LinphoneEnums::MediaEncryption::Srtp:
return QObject::tr("SRTP"); return QObject::tr("SRTP");
case LinphoneEnums::MediaEncryption::Zrtp: case LinphoneEnums::MediaEncryption::Zrtp:
return QObject::tr("ZRTP - Post quantique"); //: "ZRTP - Post quantique"
return QObject::tr("media_encryption_post_quantum");
default: default:
return QString(); return QString();
} }
@ -177,9 +178,11 @@ linphone::Call::Dir LinphoneEnums::toLinphone(const LinphoneEnums::CallDir &data
QString LinphoneEnums::toString(const LinphoneEnums::CallDir &data) { QString LinphoneEnums::toString(const LinphoneEnums::CallDir &data) {
switch (data) { switch (data) {
case LinphoneEnums::CallDir::Incoming: case LinphoneEnums::CallDir::Incoming:
return QObject::tr("Entrant"); //: "Entrant"
return QObject::tr("incoming");
case LinphoneEnums::CallDir::Outgoing: case LinphoneEnums::CallDir::Outgoing:
return QObject::tr("Sortant"); //: "Sortant"
return QObject::tr("outgoing");
default: default:
return QString(); return QString();
} }
@ -203,9 +206,12 @@ LinphoneEnums::ConferenceLayout LinphoneEnums::fromLinphone(const linphone::Conf
} }
QString LinphoneEnums::toString(LinphoneEnums::ConferenceLayout layout) { QString LinphoneEnums::toString(LinphoneEnums::ConferenceLayout layout) {
if (layout == LinphoneEnums::ConferenceLayout::ActiveSpeaker) return QObject::tr("Participant actif"); //: "Participant actif"
else if (layout == LinphoneEnums::ConferenceLayout::Grid) return QObject::tr("Grille"); if (layout == LinphoneEnums::ConferenceLayout::ActiveSpeaker) return QObject::tr("conference_layout_active_speaker");
else return QObject::tr("Audio seulement"); //: "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<LinphoneEnums::ConferenceLayout> list) { QVariantList LinphoneEnums::conferenceLayoutsToVariant(QList<LinphoneEnums::ConferenceLayout> list) {

View file

@ -147,8 +147,9 @@ void Utils::createCall(const QString &sipAddress,
bool success = ToolModel::createCall(sipAddress, options, prepareTransfertAddress, headers, bool success = ToolModel::createCall(sipAddress, options, prepareTransfertAddress, headers,
LinphoneEnums::toLinphone(mediaEncryption), &errorMessage); LinphoneEnums::toLinphone(mediaEncryption), &errorMessage);
if (!success) { if (!success) {
if (errorMessage.isEmpty()) errorMessage = tr("L'appel n'a pas pu être créé"); //: "L'appel n'a pas pu être créé"
showInformationPopup("Erreur", errorMessage, false); 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 // s, m, h, d, W, M, Y
// 1, 60, 3600, 86400, 604800, 2592000, 31104000 // 1, 60, 3600, 86400, 604800, 2592000, 31104000
auto y = floor(seconds / 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); 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); 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); 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 h = floor(seconds / 3600);
auto m = floor((seconds - h * 3600) / 60); 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 Utils::formatDate(const QDateTime &date, bool includeTime) {
QString dateDay; QString dateDay;
if (date.date() == QDate::currentDate()) dateDay = tr("Aujourd'hui"); //: "Aujourd'hui"
else if (date.date() == QDate::currentDate().addDays(-1)) dateDay = tr("Hier"); if (date.date() == QDate::currentDate()) dateDay = tr("today");
//: "Hier
else if (date.date() == QDate::currentDate().addDays(-1)) dateDay = tr("yesterday");
else { else {
QString format = date.date().year() == QDateTime::currentDateTime(date.timeZone()).date().year() QString format = date.date().year() == QDateTime::currentDateTime(date.timeZone()).date().year()
? "dd MMMM" ? "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 Utils::generateSecurityLettersArray(int arraySize, int correctIndex, QString correctCode) {
QStringList vec; QStringList vec;
const QString possibleCharacters(tr("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")); //: "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
const QString possibleCharacters(tr("call_zrtp_token_verification_possible_characters"));
const int n = 2; const int n = 2;
for (int i = 0; i < arraySize; ++i) { for (int i = 0; i < arraySize; ++i) {
QString randomString; QString randomString;

View file

@ -137,6 +137,8 @@ public:
Q_INVOKABLE static QString getFileChecksum(const QString &filePath); Q_INVOKABLE static QString getFileChecksum(const QString &filePath);
Q_INVOKABLE QList<QVariant> append(const QList<QVariant> a, const QList<QVariant> b); Q_INVOKABLE QList<QVariant> append(const QList<QVariant> a, const QList<QVariant> b);
// QDir findDirectoryByName(QString startPath, QString name);
static QString getApplicationProduct(); static QString getApplicationProduct();
static QString getOsProduct(); static QString getOsProduct();

View file

@ -6,7 +6,7 @@ import Linphone
Control.ComboBox { Control.ComboBox {
id: mainItem 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 // If string list, only text part of the delegate will be filled
// readonly property string currentText: selectedItemText.text // readonly property string currentText: selectedItemText.text
property alias listView: listView property alias listView: listView

View file

@ -127,12 +127,16 @@ ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
visible: mainItem.contact visible: mainItem.contact
text: mode === LinphoneEnums.ConsolidatedPresence.Online text: mode === LinphoneEnums.ConsolidatedPresence.Online
? qsTr("En ligne") //: "En ligne"
? qsTr("contact_presence_status_online")
: mode === LinphoneEnums.ConsolidatedPresence.Busy : mode === LinphoneEnums.ConsolidatedPresence.Busy
? qsTr("Occupé") //: "Occupé"
? qsTr("contact_presence_status_busy")
: mode === LinphoneEnums.ConsolidatedPresence.DoNotDisturb : mode === LinphoneEnums.ConsolidatedPresence.DoNotDisturb
? qsTr("Ne pas déranger") //: "Ne pas déranger"
: qsTr("Hors ligne") ? qsTr("contact_presence_status_do_not_disturb")
//: "Hors ligne"
: qsTr("contact_presence_status_offline")
color: mode === LinphoneEnums.ConsolidatedPresence.Online color: mode === LinphoneEnums.ConsolidatedPresence.Online
? DefaultStyle.success_500main ? DefaultStyle.success_500main
: mode === LinphoneEnums.ConsolidatedPresence.Busy : mode === LinphoneEnums.ConsolidatedPresence.Busy
@ -155,7 +159,8 @@ ColumnLayout {
MediumButton { MediumButton {
visible: mainItem.isConference && !SettingsCpp.disableMeetingsFeature visible: mainItem.isConference && !SettingsCpp.disableMeetingsFeature
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
text: qsTr("Rejoindre la réunion") //: "Rejoindre la réunion"
text: qsTr("meeting_info_join_title")
style: ButtonStyle.grey style: ButtonStyle.grey
onClicked: { onClicked: {
if (mainItem.conferenceInfo) { if (mainItem.conferenceInfo) {
@ -172,7 +177,8 @@ ColumnLayout {
button.icon.width: Math.round(24 * DefaultStyle.dp) button.icon.width: Math.round(24 * DefaultStyle.dp)
button.icon.height: Math.round(24 * DefaultStyle.dp) button.icon.height: Math.round(24 * DefaultStyle.dp)
button.icon.source: AppIcons.phone button.icon.source: AppIcons.phone
label: qsTr("Appel") //: "Appel"
label: qsTr("contact_call_action")
button.onClicked: { button.onClicked: {
if (mainItem.specificAddress === "") mainWindow.startCallWithContact(mainItem.contact, false, mainItem) if (mainItem.specificAddress === "") mainWindow.startCallWithContact(mainItem.contact, false, mainItem)
else UtilsCpp.createCall(mainItem.specificAddress) else UtilsCpp.createCall(mainItem.specificAddress)
@ -185,7 +191,8 @@ ColumnLayout {
button.icon.width: Math.round(24 * DefaultStyle.dp) button.icon.width: Math.round(24 * DefaultStyle.dp)
button.icon.height: Math.round(24 * DefaultStyle.dp) button.icon.height: Math.round(24 * DefaultStyle.dp)
button.icon.source: AppIcons.chatTeardropText button.icon.source: AppIcons.chatTeardropText
label: qsTr("Message") //: "Message"
label: qsTr("contact_message_action")
button.onClicked: console.debug("[ContactLayout.qml] TODO : open conversation") button.onClicked: console.debug("[ContactLayout.qml] TODO : open conversation")
} }
LabelButton { LabelButton {
@ -195,7 +202,8 @@ ColumnLayout {
button.icon.width: Math.round(24 * DefaultStyle.dp) button.icon.width: Math.round(24 * DefaultStyle.dp)
button.icon.height: Math.round(24 * DefaultStyle.dp) button.icon.height: Math.round(24 * DefaultStyle.dp)
button.icon.source: AppIcons.videoCamera button.icon.source: AppIcons.videoCamera
label: qsTr("Appel Video") //: "Appel Video"
label: qsTr("contact_video_call_action")
button.onClicked: { button.onClicked: {
if (mainItem.specificAddress === "") mainWindow.startCallWithContact(mainItem.contact, true, mainItem) if (mainItem.specificAddress === "") mainWindow.startCallWithContact(mainItem.contact, true, mainItem)
else UtilsCpp.createCall(mainItem.specificAddress, {'localVideoEnabled': true}) else UtilsCpp.createCall(mainItem.specificAddress, {'localVideoEnabled': true})

View file

@ -53,11 +53,14 @@ Item {
z: 1 z: 1
visible: mainItem.callState === LinphoneEnums.CallState.End || mainItem.callState === LinphoneEnums.CallState.Error || mainItem.callState === LinphoneEnums.CallState.Released visible: mainItem.callState === LinphoneEnums.CallState.End || mainItem.callState === LinphoneEnums.CallState.Error || mainItem.callState === LinphoneEnums.CallState.Released
text: mainItem.conference text: mainItem.conference
? qsTr("Vous avez quitté la conférence") //: "Vous avez quitté la conférence"
? qsTr("meeting_event_conference_destroyed")
: mainItem.callTerminatedByUser : mainItem.callTerminatedByUser
? qsTr("Vous avez terminé l'appel") //: "Vous avez terminé l'appel"
? qsTr("call_ended_by_user")
: mainItem.callStarted : mainItem.callStarted
? qsTr("Votre correspondant a terminé l'appel") //: "Votre correspondant a terminé l'appel"
? qsTr("call_ended_by_remote")
: call && call.core.lastErrorMessage || "" : call && call.core.lastErrorMessage || ""
color: DefaultStyle.grey_0 color: DefaultStyle.grey_0
font { font {
@ -85,7 +88,8 @@ Item {
width: waitText.implicitWidth width: waitText.implicitWidth
Text { Text {
id: waitText 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.preferredHeight: Math.round(67 * DefaultStyle.dp)
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
@ -102,13 +106,15 @@ Item {
borderColor: DefaultStyle.main2_400 borderColor: DefaultStyle.main2_400
icon.source: AppIcons.shareNetwork icon.source: AppIcons.shareNetwork
contentImageColor: DefaultStyle.main2_400 contentImageColor: DefaultStyle.main2_400
text: qsTr("Share invitation") //: "Partager le lien"
text: qsTr("conference_share_link_title")
anchors.centerIn: parent anchors.centerIn: parent
textColor: DefaultStyle.main2_400 textColor: DefaultStyle.main2_400
onClicked: { onClicked: {
if (mainItem.conference) { if (mainItem.conference) {
UtilsCpp.copyToClipboard(mainItem.call.core.remoteAddress) 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)
// }
// }

View file

@ -49,12 +49,16 @@ ListView {
} }
Text { Text {
id: callStateText 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) Layout.rightMargin: Math.round(2 * DefaultStyle.dp)
text: modelData.core.state === LinphoneEnums.CallState.Paused text: modelData.core.state === LinphoneEnums.CallState.Paused
|| modelData.core.state === LinphoneEnums.CallState.PausedByRemote || modelData.core.state === LinphoneEnums.CallState.PausedByRemote
? type + qsTr(" en pause") //: "%1 en pause"
: type + qsTr(" en cours") ? qsTr("paused_call_or_meeting").arg(type)
//: "%1 en cours"
: qsTr("ongoing_call_or_meeting").arg(type)
font { font {
pixelSize: Math.round(12 * DefaultStyle.dp) pixelSize: Math.round(12 * DefaultStyle.dp)
weight: Math.round(300 * DefaultStyle.dp) weight: Math.round(300 * DefaultStyle.dp)

View file

@ -25,7 +25,8 @@ ColumnLayout {
spacing: Math.round(12 * DefaultStyle.dp) spacing: Math.round(12 * DefaultStyle.dp)
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
Text { Text {
text: qsTr("Audio") //: "Audio"
text: qsTr("call_stats_audio_title")
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
font { font {
pixelSize: Math.round(12 * DefaultStyle.dp) pixelSize: Math.round(12 * DefaultStyle.dp)
@ -86,7 +87,8 @@ ColumnLayout {
spacing: Math.round(12 * DefaultStyle.dp) spacing: Math.round(12 * DefaultStyle.dp)
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
Text { Text {
text: qsTr("Vidéo") //: "Vidéo"
text: qsTr("call_stats_video_title")
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
font { font {
pixelSize: Math.round(12 * DefaultStyle.dp) pixelSize: Math.round(12 * DefaultStyle.dp)

View file

@ -150,7 +150,7 @@ Flickable {
} }
} }
onSearchTextChanged: { onSearchTextChanged: {
console.log("search texte changed, loading...") console.log("search texte changed, loading")
loading = true loading = true
} }
@ -273,7 +273,8 @@ Flickable {
selectionEnabled: mainItem.selectionEnabled selectionEnabled: mainItem.selectionEnabled
multiSelectionEnabled: mainItem.multiSelectionEnabled multiSelectionEnabled: mainItem.multiSelectionEnabled
selectedContacts: mainItem.selectedContacts selectedContacts: mainItem.selectedContacts
title: qsTr('Favoris') //: "Favoris"
title: qsTr("car_favorites_contacts_title")
itemsRightMargin: mainItem.itemsRightMargin itemsRightMargin: mainItem.itemsRightMargin
onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact
@ -318,7 +319,8 @@ Flickable {
multiSelectionEnabled: mainItem.multiSelectionEnabled multiSelectionEnabled: mainItem.multiSelectionEnabled
selectedContacts: mainItem.selectedContacts selectedContacts: mainItem.selectedContacts
itemsRightMargin: mainItem.itemsRightMargin itemsRightMargin: mainItem.itemsRightMargin
title: qsTr('Contacts') //: 'Contacts'
title: qsTr("generic_address_picker_contacts_list_title")
onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact
onContactSelected: contactGui => { onContactSelected: contactGui => {
@ -369,7 +371,8 @@ Flickable {
selectionEnabled: mainItem.selectionEnabled selectionEnabled: mainItem.selectionEnabled
multiSelectionEnabled: mainItem.multiSelectionEnabled multiSelectionEnabled: mainItem.multiSelectionEnabled
selectedContacts: mainItem.selectedContacts selectedContacts: mainItem.selectedContacts
title: qsTr('Suggestions') //: "Suggestions"
title: qsTr("generic_address_picker_suggestions_list_title")
itemsRightMargin: mainItem.itemsRightMargin itemsRightMargin: mainItem.itemsRightMargin
onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact

View file

@ -14,6 +14,8 @@ Control.Control{
padding: Math.round(10 * DefaultStyle.dp) padding: Math.round(10 * DefaultStyle.dp)
property AccountGui account 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 avatarClicked()
signal backgroundClicked() signal backgroundClicked()
@ -56,6 +58,7 @@ Control.Control{
Control.Control { Control.Control {
id: registrationStatusItem id: registrationStatusItem
Layout.minimumWidth: Math.round(49 * DefaultStyle.dp) Layout.minimumWidth: Math.round(49 * DefaultStyle.dp)
Layout.maximumWidth: 150
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) Layout.preferredHeight: Math.round(24 * DefaultStyle.dp)
topPadding: Math.round(4 * DefaultStyle.dp) topPadding: Math.round(4 * DefaultStyle.dp)
bottomPadding: Math.round(4 * DefaultStyle.dp) bottomPadding: Math.round(4 * DefaultStyle.dp)
@ -71,6 +74,8 @@ Control.Control{
contentItem: Text { contentItem: Text {
id: text id: text
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: registrationStatusItem.leftPadding
anchors.rightMargin: registrationStatusItem.rightPadding
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
visible: mainItem.account visible: mainItem.account
@ -98,12 +103,16 @@ Control.Control{
? DefaultStyle.main2_500main ? DefaultStyle.main2_500main
: DefaultStyle.danger_500main : DefaultStyle.danger_500main
text: mode == 0 text: mode == 0
? qsTr("Connecté") //: "Connecté"
? qsTr("drawer_menu_account_connection_status_connected")
: mode == 1 : mode == 1
? qsTr("Désactivé") //: "Désactivé"
? qsTr("drawer_menu_account_connection_status_cleared")
: mode == 2 : mode == 2
? qsTr("Connexion...") //: "Connexion"
: qsTr("Erreur") ? qsTr("drawer_menu_account_connection_status_refreshing")
//: "Erreur"
: qsTr("drawer_menu_account_connection_status_failed")
} }
} }
Item{ Item{
@ -156,7 +165,10 @@ Control.Control{
if (mainItem.account.core.voicemailAddress.length > 0) if (mainItem.account.core.voicemailAddress.length > 0)
UtilsCpp.createCall(mainItem.account.core.voicemailAddress) UtilsCpp.createCall(mainItem.account.core.voicemailAddress)
else 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} Item{Layout.fillWidth: true}

View file

@ -195,9 +195,9 @@ FocusScope {
IconLabelButton { IconLabelButton {
visible: searchResultItem.core.isStored visible: searchResultItem.core.isStored
&& !searchResultItem.core.readOnly && !searchResultItem.core.readOnly
text: searchResultItem.core.starred ? qsTr( //: "Enlever des favoris"
"Enlever des favoris") : qsTr( //: "Ajouter aux favoris"
"Mettre en favori") 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 icon.source: searchResultItem.core.starred ? AppIcons.heartFill : AppIcons.heart
spacing: Math.round(10 * DefaultStyle.dp) spacing: Math.round(10 * DefaultStyle.dp)
textColor: DefaultStyle.main2_500main textColor: DefaultStyle.main2_500main
@ -222,23 +222,22 @@ FocusScope {
var filepath = UtilsCpp.createVCardFile( var filepath = UtilsCpp.createVCardFile(
username, vcard) username, vcard)
if (filepath == "") if (filepath == "")
//: "La création du fichier vcard a échoué"
UtilsCpp.showInformationPopup( UtilsCpp.showInformationPopup(
qsTr("Erreur"), qsTr( qsTr("information_popup_error_title"), qsTr("information_popup_vcard_creation_error"),
"La création du fichier vcard a échoué"),
false) false)
else else
mainWindow.showInformationPopup( //: "VCard créée"
qsTr("VCard créée"), qsTr( //: "VCard du contact enregistrée dans %1"
"VCard du contact enregistrée dans %1").arg( mainWindow.showInformationPopup(qsTr("information_popup_vcard_creation_title"), qsTr("information_popup_vcard_creation_success").arg(filepath))
filepath)) //: "Partage de contact"
UtilsCpp.shareByEmail( UtilsCpp.shareByEmail(qsTr("contact_sharing_email_title"),vcard, filepath)
qsTr("Partage de contact"),
vcard, filepath)
} }
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
} }
IconLabelButton { IconLabelButton {
text: qsTr("Supprimer") //: "Supprimer"
text: qsTr("contact_details_delete")
icon.source: AppIcons.trashCan icon.source: AppIcons.trashCan
spacing: Math.round(10 * DefaultStyle.dp) spacing: Math.round(10 * DefaultStyle.dp)
visible: !searchResultItem.core.readOnly visible: !searchResultItem.core.readOnly

View file

@ -243,7 +243,8 @@ ListView {
} }
} }
Text { 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 color: itemDelegate.isCanceled ? DefaultStyle.danger_500main : DefaultStyle.main2_500main
font { font {
pixelSize: Typography.p1.pixelSize pixelSize: Typography.p1.pixelSize
@ -266,7 +267,8 @@ ListView {
anchors.leftMargin: Math.round(16 * DefaultStyle.dp) anchors.leftMargin: Math.round(16 * DefaultStyle.dp)
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
visible: !itemDelegate.haveModel 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 lineHeightMode: Text.FixedHeight
lineHeight: Math.round(18 * DefaultStyle.dp) lineHeight: Math.round(18 * DefaultStyle.dp)
font { font {

View file

@ -64,7 +64,8 @@ ListView {
Text { Text {
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
visible: modelData.core.isAdmin visible: modelData.core.isAdmin
text: qsTr("Admin") //: "Admin"
text: qsTr("meeting_participant_is_admin_label")
color: DefaultStyle.main2_400 color: DefaultStyle.main2_400
font { font {
pixelSize: Math.round(12 * DefaultStyle.dp) pixelSize: Math.round(12 * DefaultStyle.dp)
@ -106,7 +107,8 @@ ListView {
icon.source: AppIcons.plusCircle icon.source: AppIcons.plusCircle
icon.width: Math.round(16 * DefaultStyle.dp) icon.width: Math.round(16 * DefaultStyle.dp)
icon.height: 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 style: ButtonStyle.secondary
onClicked: mainItem.addParticipantRequested() onClicked: mainItem.addParticipantRequested()
} }

View file

@ -126,7 +126,8 @@ Item {
Text { Text {
Layout.preferredHeight: Math.round(27 * DefaultStyle.dp) Layout.preferredHeight: Math.round(27 * DefaultStyle.dp)
Layout.topMargin: Math.round(15 * DefaultStyle.dp) // (84-27)-42 Layout.topMargin: Math.round(15 * DefaultStyle.dp) // (84-27)-42
text: qsTr('rejoint...') //: "rejoint"
text: qsTr("conference_participant_joining_text")
color: DefaultStyle.grey_0 color: DefaultStyle.grey_0
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
@ -151,7 +152,8 @@ Item {
Text { Text {
color: DefaultStyle.grey_0 color: DefaultStyle.grey_0
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
text: qsTr("En pause") //: "En pause"
text: qsTr("conference_participant_paused_text")
font { font {
pixelSize: Math.round(20 * DefaultStyle.dp) pixelSize: Math.round(20 * DefaultStyle.dp)
weight: Math.round(500 * DefaultStyle.dp) weight: Math.round(500 * DefaultStyle.dp)

View file

@ -17,21 +17,16 @@ FocusScope {
anchors.leftMargin: Math.round(17 * DefaultStyle.dp) anchors.leftMargin: Math.round(17 * DefaultStyle.dp)
anchors.rightMargin: Math.round(17 * DefaultStyle.dp) anchors.rightMargin: Math.round(17 * DefaultStyle.dp)
spacing: Math.round(12 * 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 { RoundedPane {
Layout.fillWidth: true Layout.fillWidth: true
contentItem: ColumnLayout { contentItem: ColumnLayout {
spacing: 0 spacing: 0
Repeater { Repeater {
model: [ model: [
{text: qsTr("Mosaïque"), imgUrl: AppIcons.squaresFour}, {text: qsTr("conference_layout_grid"), imgUrl: AppIcons.squaresFour},
{text: qsTr("Intervenant actif"), imgUrl: AppIcons.pip}, {text: qsTr("conference_layout_active_speaker"), imgUrl: AppIcons.pip},
{text: qsTr("Audio seulement"), imgUrl: AppIcons.waveform} {text: qsTr("conference_layout_audio_only"), imgUrl: AppIcons.waveform}
] ]
RadioButton { RadioButton {
id: radiobutton id: radiobutton

View file

@ -12,7 +12,8 @@ ColumnLayout {
FormItemLayout { FormItemLayout {
id: username id: username
Layout.preferredWidth: Math.round(346 * DefaultStyle.dp) Layout.preferredWidth: Math.round(346 * DefaultStyle.dp)
label: qsTr("Nom d'utilisateur") //: "Nom d'utilisateur" : username
label: qsTr("username")
mandatory: true mandatory: true
enableErrorText: true enableErrorText: true
contentItem: TextField { contentItem: TextField {
@ -27,7 +28,8 @@ ColumnLayout {
FormItemLayout { FormItemLayout {
id: password id: password
width: Math.round(346 * DefaultStyle.dp) width: Math.round(346 * DefaultStyle.dp)
label: qsTr("Mot de passe") //: "Mot de passe"
label: qsTr("password")
mandatory: true mandatory: true
enableErrorText: true enableErrorText: true
contentItem: TextField { contentItem: TextField {
@ -62,7 +64,8 @@ ColumnLayout {
id: connectionButtonContent id: connectionButtonContent
currentIndex: 0 currentIndex: 0
Text { Text {
text: qsTr("Connexion") //: "Connexion"
text: qsTr("assistant_account_login")
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
@ -100,9 +103,11 @@ ColumnLayout {
if (usernameEdit.text.length == 0 || passwordEdit.text.length == 0) { if (usernameEdit.text.length == 0 || passwordEdit.text.length == 0) {
if (usernameEdit.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) 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 return
} }
LoginPageCpp.login(usernameEdit.text, passwordEdit.text) LoginPageCpp.login(usernameEdit.text, passwordEdit.text)
@ -120,7 +125,8 @@ ColumnLayout {
SmallButton { SmallButton {
id: forgottenButton id: forgottenButton
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
text: qsTr("Mot de passe oublié ?") //: "Mot de passe oublié ?"
text: qsTr("assistant_forgotten_password")
underline: true underline: true
onClicked: Qt.openUrlExternally(ConstantsCpp.PasswordRecoveryUrl) onClicked: Qt.openUrlExternally(ConstantsCpp.PasswordRecoveryUrl)
} }

View file

@ -18,7 +18,8 @@ ColumnLayout {
contentItem: ColumnLayout { contentItem: ColumnLayout {
spacing: Math.round(12 * DefaultStyle.dp) spacing: Math.round(12 * DefaultStyle.dp)
Text { Text {
text: qsTr("Chiffrement :") //: "Chiffrement :"
text: qsTr("call_stats_media_encryption_title")
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
font { font {
pixelSize: Math.round(12 * DefaultStyle.dp) pixelSize: Math.round(12 * DefaultStyle.dp)
@ -30,7 +31,9 @@ ColumnLayout {
spacing: Math.round(7 * DefaultStyle.dp) spacing: Math.round(7 * DefaultStyle.dp)
Text { Text {
property bool isPostQuantum: mainItem.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp && mainItem.call.core.zrtpStats.isPostQuantum 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 Layout.alignment: Qt.AlignHCenter
font { font {
pixelSize: Math.round(12 * DefaultStyle.dp) pixelSize: Math.round(12 * DefaultStyle.dp)
@ -40,7 +43,8 @@ ColumnLayout {
ColumnLayout { ColumnLayout {
visible: mainItem.call && mainItem.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp visible: mainItem.call && mainItem.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp
Text { 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 Layout.alignment: Qt.AlignHCenter
font { font {
pixelSize: Math.round(12 * DefaultStyle.dp) pixelSize: Math.round(12 * DefaultStyle.dp)
@ -48,7 +52,8 @@ ColumnLayout {
} }
} }
Text { 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 Layout.alignment: Qt.AlignHCenter
font { font {
pixelSize: Math.round(12 * DefaultStyle.dp) pixelSize: Math.round(12 * DefaultStyle.dp)
@ -56,7 +61,8 @@ ColumnLayout {
} }
} }
Text { 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 Layout.alignment: Qt.AlignHCenter
font { font {
pixelSize: Math.round(12 * DefaultStyle.dp) pixelSize: Math.round(12 * DefaultStyle.dp)
@ -64,7 +70,8 @@ ColumnLayout {
} }
} }
Text { 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 Layout.alignment: Qt.AlignHCenter
font { font {
pixelSize: Math.round(12 * DefaultStyle.dp) pixelSize: Math.round(12 * DefaultStyle.dp)
@ -72,7 +79,8 @@ ColumnLayout {
} }
} }
Text { 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 Layout.alignment: Qt.AlignHCenter
font { font {
pixelSize: Math.round(12 * DefaultStyle.dp) pixelSize: Math.round(12 * DefaultStyle.dp)
@ -87,7 +95,8 @@ ColumnLayout {
Button { Button {
visible: mainItem.call && !mainItem.call.core.conference && mainItem.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp visible: mainItem.call && !mainItem.call.core.conference && mainItem.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp
Layout.fillWidth: true Layout.fillWidth: true
text: qsTr("Validation chiffrement") //: "Validation chiffrement"
text: qsTr("call_zrtp_validation_button_label")
onClicked: mainItem.encryptionValidationRequested() onClicked: mainItem.encryptionValidationRequested()
Layout.bottomMargin: Math.round(13 * DefaultStyle.dp) Layout.bottomMargin: Math.round(13 * DefaultStyle.dp)
Layout.leftMargin: Math.round(16 * DefaultStyle.dp) Layout.leftMargin: Math.round(16 * DefaultStyle.dp)

View file

@ -40,7 +40,8 @@ ColumnLayout {
imageHeight: Math.round(24 * DefaultStyle.dp) imageHeight: Math.round(24 * DefaultStyle.dp)
} }
Text { Text {
text: qsTr("Sonnerie - Appels entrants") //: "Sonnerie - Appels entrants"
text: qsTr("multimedia_settings_ringer_title")
font: Typography.p2l font: Typography.p2l
color: DefaultStyle.main2_600 color: DefaultStyle.main2_600
Layout.fillWidth: true Layout.fillWidth: true
@ -72,7 +73,8 @@ ColumnLayout {
imageHeight: Math.round(24 * DefaultStyle.dp) imageHeight: Math.round(24 * DefaultStyle.dp)
} }
Text { Text {
text: qsTr("Haut-parleurs") //: "Haut-parleurs"
text: qsTr("multimedia_settings_speaker_title")
font: Typography.p2l font: Typography.p2l
Layout.fillWidth: true Layout.fillWidth: true
} }
@ -119,7 +121,8 @@ ColumnLayout {
imageHeight: Math.round(24 * DefaultStyle.dp) imageHeight: Math.round(24 * DefaultStyle.dp)
} }
Text { Text {
text: qsTr("Microphone") //: "Microphone"
text: qsTr("multimedia_settings_microphone_title")
font: Typography.p2l font: Typography.p2l
Layout.fillWidth: true Layout.fillWidth: true
} }
@ -205,7 +208,8 @@ ColumnLayout {
imageHeight: Math.round(24 * DefaultStyle.dp) imageHeight: Math.round(24 * DefaultStyle.dp)
} }
Text { Text {
text: qsTr("Caméra") //: "Caméra"
text: qsTr("multimedia_settings_camera_title")
font: Typography.p2l font: Typography.p2l
Layout.fillWidth: true Layout.fillWidth: true
} }

View file

@ -19,7 +19,8 @@ ColumnLayout {
onIsLocalScreenSharingChanged: {if(isLocalScreenSharing) mainItem.call.core.videoSourceDescriptor = mainItem.desc } onIsLocalScreenSharingChanged: {if(isLocalScreenSharing) mainItem.call.core.videoSourceDescriptor = mainItem.desc }
Text { Text {
Layout.fillWidth: true 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) font.pixelSize: Math.round(14 * DefaultStyle.dp)
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500main
} }
@ -27,7 +28,10 @@ ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
id: bar id: bar
pixelSize: Math.round(16 * DefaultStyle.dp) 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 { component ScreenPreviewLayout: Control.Control {
id: screenPreview id: screenPreview
@ -84,7 +88,8 @@ ColumnLayout {
} }
Text { Text {
Layout.fillWidth: true 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 horizontalAlignment: Text.AlignHCenter
font.pixelSize: Math.round((displayScreen ? 14 : 10) * DefaultStyle.dp) font.pixelSize: Math.round((displayScreen ? 14 : 10) * DefaultStyle.dp)
elide: Text.ElideRight elide: Text.ElideRight
@ -156,11 +161,13 @@ ColumnLayout {
} }
} }
Button { Button {
visible: mainItem.screenSharingAvailable visible: mainItem.screenSharingAvailable$
enabled: windowsLayout.currentIndex !== -1 || screensLayout.currentIndex !== -1 enabled: windowsLayout.currentIndex !== -1 || screensLayout.currentIndex !== -1
text: mainItem.conference && mainItem.conference.core.isLocalScreenSharing text: mainItem.conference && mainItem.conference.core.isLocalScreenSharing
? qsTr("Stop") //: "Stop
: qsTr("Partager") ? qsTr("stop")
//: "Partager"
: qsTr("share")
onClicked: mainItem.conference.core.lToggleScreenSharing() onClicked: mainItem.conference.core.lToggleScreenSharing()
style: ButtonStyle.main style: ButtonStyle.main
} }

View file

@ -45,9 +45,11 @@ FormItemLayout {
onValidationChecked: (isValid) => { onValidationChecked: (isValid) => {
if (isValid) return if (isValid) return
if (!canBeEmpty && empty) { if (!canBeEmpty && empty) {
mainItem.errorMessage = qsTr("ne peut être vide") //: "ne peut être vide"
mainItem.errorMessage = qsTr("textfield_error_message_cannot_be_empty")
} else { } else {
mainItem.errorMessage = qsTr("Format non reconnu") //: "Format non reconnu"
mainItem.errorMessage = qsTr("textfield_error_message_unknown_format")
} }
} }
onTextChanged: mainItem.clearErrorText() onTextChanged: mainItem.clearErrorText()

View file

@ -41,39 +41,31 @@ Dialog {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
wrapMode: Text.Wrap wrapMode: Text.Wrap
text: qsTr("Impossible de vous authentifier. Merci de vérifier votre mot de passe.") 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
//: 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:Math.round( 16 * DefaultStyle.dp)
} font {
ColumnLayout { pixelSize: Typography.h4.pixelSize
spacing:Math.round( 10 * DefaultStyle.dp) weight: Typography.h4.weight
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 { FormItemLayout {
id: passwordItem id: passwordItem
Layout.fillWidth: true Layout.fillWidth: true
label: qsTr("Mot de passe") label: qsTr("password")
enableErrorText: true enableErrorText: true
mandatory: true mandatory: true
contentItem: TextField { contentItem: TextField {
@ -85,13 +77,13 @@ Dialog {
} }
} }
} }
}
buttons: [ buttons: [
MediumButton { MediumButton {
id: cancelButton id: cancelButton
Layout.topMargin: Math.round( 10 * DefaultStyle.dp) Layout.topMargin: Math.round( 10 * DefaultStyle.dp)
text: qsTr("Annuler") //: "Annuler
text: qsTr("cancel")
style: ButtonStyle.secondary style: ButtonStyle.secondary
onClicked: mainItem.rejected() onClicked: mainItem.rejected()
KeyNavigation.up: passwordEdit KeyNavigation.up: passwordEdit
@ -100,14 +92,16 @@ Dialog {
MediumButton { MediumButton {
id: connectButton id: connectButton
Layout.topMargin:Math.round( 10 * DefaultStyle.dp) Layout.topMargin:Math.round( 10 * DefaultStyle.dp)
text: qsTr("Se connecter") //: Connexion
text: qsTr("assistant_account_login")
style: ButtonStyle.main style: ButtonStyle.main
KeyNavigation.up: passwordEdit KeyNavigation.up: passwordEdit
KeyNavigation.right: cancelButton KeyNavigation.right: cancelButton
onClicked: { onClicked: {
passwordItem.errorMessage = "" passwordItem.errorMessage = ""
if (passwordEdit.text.length == 0) { if (passwordEdit.text.length == 0) {
passwordItem.errorMessage = qsTr("Veuillez saisir un mot de passe") //: Veuillez saisir un mot de passe
passwordItem.errorMessage = qsTr("assistant_account_login_missing_password")
return return
} }
mainItem.accepted() mainItem.accepted()

View file

@ -20,8 +20,10 @@ Popup {
property var titleColor: DefaultStyle.main1_500_main property var titleColor: DefaultStyle.main1_500_main
property string text property string text
property string details property string details
property string firstButtonText: firstButtonAccept ? qsTr("Oui") : qsTr("Annuler") //: "Confirmer"
property string secondButtonText: secondButtonAccept ? qsTr("Confirmer") : qsTr("Non") //: "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 content: contentLayout.data
property alias buttons: buttonsLayout.data property alias buttons: buttonsLayout.data
property alias firstButton: firstButtonId property alias firstButton: firstButtonId

View file

@ -66,7 +66,8 @@ Dialog {
} }
} }
Text { 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 color: DefaultStyle.grey_0
Layout.Layout.alignment: Qt.AlignHCenter Layout.Layout.alignment: Qt.AlignHCenter
font { font {
@ -83,7 +84,8 @@ Dialog {
anchors.topMargin: Math.round(10 * DefaultStyle.dp) anchors.topMargin: Math.round(10 * DefaultStyle.dp)
anchors.rightMargin: Math.round(17 * DefaultStyle.dp) anchors.rightMargin: Math.round(17 * DefaultStyle.dp)
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
text: qsTr("Passer") //: "Passer"
text: qsTr("call_zrtp_sas_validation_skip")
textColor: DefaultStyle.grey_0 textColor: DefaultStyle.grey_0
hoveredTextColor: DefaultStyle.grey_100 hoveredTextColor: DefaultStyle.grey_100
pressedTextColor: DefaultStyle.grey_200 pressedTextColor: DefaultStyle.grey_200
@ -127,8 +129,10 @@ Dialog {
Layout.Layout.alignment: Qt.AlignHCenter Layout.Layout.alignment: Qt.AlignHCenter
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
text: !mainItem.isTokenVerified && mainItem.isCaseMismatch text: !mainItem.isTokenVerified && mainItem.isCaseMismatch
? qsTr("Pour garantir le chiffrement, nous avons besoin de réauthentifier lappareil de votre correspondant. Echangez vos codes :") //: "Pour garantir le chiffrement, nous avons besoin de réauthentifier lappareil de votre correspondant. Echangez vos codes :"
: qsTr("Pour garantir le chiffrement, nous avons besoin dauthentifier lappareil de votre correspondant. Veuillez échanger vos codes : ") ? qsTr("call_dialog_zrtp_validate_trust_warning_message")
//: "Pour garantir le chiffrement, nous avons besoin dauthentifier lappareil de votre correspondant. Veuillez échanger vos codes : "
: qsTr("call_dialog_zrtp_validate_trust_message")
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
font.pixelSize: Math.round(14 * DefaultStyle.dp) font.pixelSize: Math.round(14 * DefaultStyle.dp)
} }
@ -136,7 +140,8 @@ Dialog {
spacing: 0 spacing: 0
Layout.Layout.alignment: Qt.AlignHCenter Layout.Layout.alignment: Qt.AlignHCenter
Text { Text {
text: qsTr("Votre code :") //: "Votre code :"
text: qsTr("call_dialog_zrtp_validate_trust_local_code_label")
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
Layout.Layout.alignment: Qt.AlignHCenter Layout.Layout.alignment: Qt.AlignHCenter
font.pixelSize: Math.round(14 * DefaultStyle.dp) font.pixelSize: Math.round(14 * DefaultStyle.dp)
@ -164,7 +169,8 @@ Dialog {
anchors.fill: parent anchors.fill: parent
anchors.topMargin: Math.round(10 * DefaultStyle.dp) anchors.topMargin: Math.round(10 * DefaultStyle.dp)
Text { Text {
text: qsTr("Code correspondant :") //: "Code correspondant :"
text: qsTr("call_dialog_zrtp_validate_trust_remote_code_label")
font.pixelSize: Math.round(14 * DefaultStyle.dp) font.pixelSize: Math.round(14 * DefaultStyle.dp)
Layout.Layout.alignment: Qt.AlignHCenter Layout.Layout.alignment: Qt.AlignHCenter
} }
@ -210,7 +216,8 @@ Dialog {
Layout.Layout.alignment: Qt.AlignHCenter Layout.Layout.alignment: Qt.AlignHCenter
Layout.Layout.fillWidth: true Layout.Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter 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 wrapMode: Text.WordWrap
font.pixelSize: Math.round(14 * DefaultStyle.dp) font.pixelSize: Math.round(14 * DefaultStyle.dp)
} }
@ -220,7 +227,8 @@ Dialog {
Layout.Layout.alignment: Qt.AlignHCenter Layout.Layout.alignment: Qt.AlignHCenter
Layout.Layout.fillWidth: true Layout.Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter 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 wrapMode: Text.WordWrap
font.pixelSize: Math.round(14 * DefaultStyle.dp) font.pixelSize: Math.round(14 * DefaultStyle.dp)
} }
@ -232,7 +240,8 @@ Dialog {
MediumButton { MediumButton {
Layout.Layout.alignment: Qt.AlignHCenter Layout.Layout.alignment: Qt.AlignHCenter
Layout.Layout.preferredWidth: Math.round(247 * DefaultStyle.dp) 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 color: DefaultStyle.grey_0
borderColor: DefaultStyle.danger_500main borderColor: DefaultStyle.danger_500main
textColor: DefaultStyle.danger_500main textColor: DefaultStyle.danger_500main
@ -248,7 +257,8 @@ Dialog {
style: ButtonStyle.phoneRed style: ButtonStyle.phoneRed
onClicked: mainItem.call.core.lTerminate() onClicked: mainItem.call.core.lTerminate()
spacing: Math.round(15 * DefaultStyle.dp) spacing: Math.round(15 * DefaultStyle.dp)
text: qsTr("Raccrocher") //: "Raccrocher"
text: qsTr("call_action_hang_up")
} }
} }
} }

View file

@ -36,7 +36,7 @@ Popup {
MediumButton { MediumButton {
visible: mainItem.cancelButtonVisible visible: mainItem.cancelButtonVisible
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
text: qsTr("Annuler") text: qsTr("cancel")
style: ButtonStyle.main style: ButtonStyle.main
onClicked: { onClicked: {
if (callback) mainItem.callback() if (callback) mainItem.callback()

View file

@ -85,7 +85,8 @@ Notification {
} }
} }
Text { Text {
text: qsTr("Appel audio") //: "Appel entrant"
text: qsTr("call_audio_incoming")
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
color: DefaultStyle.grey_0 color: DefaultStyle.grey_0
font { font {
@ -107,7 +108,8 @@ Notification {
asynchronous: false asynchronous: false
icon.width: Math.round(19 * DefaultStyle.dp) icon.width: Math.round(19 * DefaultStyle.dp)
icon.height: 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) textSize: Math.round(14 * DefaultStyle.dp)
textWeight: Math.round(500 * DefaultStyle.dp) textWeight: Math.round(500 * DefaultStyle.dp)
onClicked: { onClicked: {
@ -124,7 +126,8 @@ Notification {
asynchronous: false asynchronous: false
icon.width: Math.round(19 * DefaultStyle.dp) icon.width: Math.round(19 * DefaultStyle.dp)
icon.height: 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) textSize: Math.round(14 * DefaultStyle.dp)
textWeight: Math.round(500 * DefaultStyle.dp) textWeight: Math.round(500 * DefaultStyle.dp)
onClicked: { onClicked: {

View file

@ -686,35 +686,48 @@ function computeAvatarSize (container, maxSize, ratio) {
function openCodecOnlineInstallerDialog (mainWindow, coreObject, cancelCallBack, successCallBack, errorCallBack) { function openCodecOnlineInstallerDialog (mainWindow, coreObject, cancelCallBack, successCallBack, errorCallBack) {
mainWindow.showConfirmationLambdaPopup("", mainWindow.showConfirmationLambdaPopup("",
qsTr("Installation de codec"), //: "Installation de codec"
qsTr("Télécharger le codec ") + capitalizeFirstLetter(coreObject.mimeType) + " ("+coreObject.encoderDescription+")"+" ?", qsTr("codec_install"),
//: "Télécharger le codec %1 (%2) ?"
qsTr("download_codec").arg(capitalizeFirstLetter(coreObject.mimeType)).arg(coreObject.encoderDescription),
function (confirmed) { function (confirmed) {
if (confirmed) { if (confirmed) {
coreObject.loaded.connect(function(success) { coreObject.loaded.connect(function(success) {
mainWindow.closeLoadingPopup() mainWindow.closeLoadingPopup()
if (success) { 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) if (successCallBack)
successCallBack() successCallBack()
} else { } 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) if (errorCallBack)
errorCallBack() errorCallBack()
} }
}) })
coreObject.extractError.connect(function() { coreObject.extractError.connect(function() {
mainWindow.closeLoadingPopup() 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) if (errorCallBack)
errorCallBack() errorCallBack()
}) })
coreObject.downloadError.connect(function() { coreObject.downloadError.connect(function() {
mainWindow.closeLoadingPopup() 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) if (errorCallBack)
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() coreObject.downloadAndExtract()
} else } else
if (cancelCallBack) if (cancelCallBack)

View file

@ -28,7 +28,8 @@ FocusScope {
spacing: Math.round(18 * DefaultStyle.dp) spacing: Math.round(18 * DefaultStyle.dp)
visible: mainItem.displayCurrentCalls visible: mainItem.displayCurrentCalls
Text { Text {
text: qsTr("Appels en cours") //: "Appels en cours"
text: qsTr("call_transfer_active_calls_label")
font { font {
pixelSize: Typography.h4.pixelSize pixelSize: Typography.h4.pixelSize
weight: Typography.h4.weight weight: Typography.h4.weight
@ -72,7 +73,8 @@ FocusScope {
focus: true focus: true
color: mainItem.searchBarColor color: mainItem.searchBarColor
borderColor: mainItem.searchBarBorderColor borderColor: mainItem.searchBarBorderColor
placeholderText: qsTr("Rechercher un contact") //: "Rechercher un contact"
placeholderText: qsTr("search_bar_look_for_contact_text")
numericPadPopup: mainItem.numPadPopup numericPadPopup: mainItem.numPadPopup
KeyNavigation.down: grouCallButton KeyNavigation.down: grouCallButton
} }

View file

@ -21,8 +21,10 @@ MainRightPanel {
} }
} }
} }
property string title: qsTr("Modifier contact") //: "Modifier contact"
property string saveButtonText: qsTr("Enregistrer") property string title: qsTr("contact_editor_title")
//: "Enregistrer
property string saveButtonText: qsTr("save")
property string oldPictureUri property string oldPictureUri
property int addressCount: 0 property int addressCount: 0
@ -35,7 +37,8 @@ MainRightPanel {
mainItem.closeEdition('') mainItem.closeEdition('')
} }
width: Math.round(278 * DefaultStyle.dp) 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: [ headerContent: [
@ -61,7 +64,7 @@ MainRightPanel {
icon.height: Math.round(24 * DefaultStyle.dp) icon.height: Math.round(24 * DefaultStyle.dp)
onClicked: { onClicked: {
if (contact.core.isSaved) mainItem.closeEdition('') 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) { if (confirmed) {
mainItem.contact.core.undo() mainItem.contact.core.undo()
mainItem.closeEdition('') mainItem.closeEdition('')
@ -81,11 +84,13 @@ MainRightPanel {
id: saveDelay id: saveDelay
interval: 200 interval: 200
onTriggered:{ onTriggered:{
//: "Veuillez saisir un prénom"
if (mainItem.contact.core.givenName.length === 0) { 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 return
} else if (addressesList.count === 0 && phoneNumberList.count === 0) { } 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 return
} }
mainItem.contact.core.save() mainItem.contact.core.save()
@ -101,7 +106,8 @@ MainRightPanel {
Layout.preferredWidth: width Layout.preferredWidth: width
visible: !mainItem.contact || mainItem.contact.core.pictureUri.length === 0 visible: !mainItem.contact || mainItem.contact.core.pictureUri.length === 0
icon.source: AppIcons.camera icon.source: AppIcons.camera
text: qsTr("Ajouter une image") //: "Ajouter une image"
text: qsTr("contact_editor_add_image_label")
textSize: Typography.h4.pixelSize textSize: Typography.h4.pixelSize
textWeight: Typography.h4.weight textWeight: Typography.h4.weight
textColor: DefaultStyle.main2_700 textColor: DefaultStyle.main2_700
@ -118,7 +124,8 @@ MainRightPanel {
id: editButton id: editButton
Layout.preferredWidth: width Layout.preferredWidth: width
icon.source: AppIcons.pencil icon.source: AppIcons.pencil
text: qsTr("Modifier") //: "Modifier"
text: qsTr("contact_details_edit")
textColor: DefaultStyle.main2_700 textColor: DefaultStyle.main2_700
hoveredTextColor: DefaultStyle.main2_800 hoveredTextColor: DefaultStyle.main2_800
pressedTextColor: DefaultStyle.main2_900 pressedTextColor: DefaultStyle.main2_900
@ -142,7 +149,8 @@ MainRightPanel {
id: removeButton id: removeButton
Layout.preferredWidth: width Layout.preferredWidth: width
icon.source: AppIcons.trashCan icon.source: AppIcons.trashCan
text: qsTr("Supprimer") //: "Supprimer"
text: qsTr("contact_details_delete")
textColor: DefaultStyle.main2_700 textColor: DefaultStyle.main2_700
hoveredTextColor: DefaultStyle.main2_800 hoveredTextColor: DefaultStyle.main2_800
pressedTextColor: DefaultStyle.main2_900 pressedTextColor: DefaultStyle.main2_900
@ -192,7 +200,8 @@ MainRightPanel {
id: givenName id: givenName
Layout.fillWidth: true Layout.fillWidth: true
enableErrorText: true enableErrorText: true
label: qsTr("Prénom") //: "Prénom"
label: qsTr("contact_editor_first_name")
contentItem: TextField { contentItem: TextField {
id: givenNameEdit id: givenNameEdit
Layout.preferredHeight: Math.round(49 * DefaultStyle.dp) Layout.preferredHeight: Math.round(49 * DefaultStyle.dp)
@ -207,7 +216,8 @@ MainRightPanel {
} }
} }
FormItemLayout { FormItemLayout {
label: qsTr("Nom") //: "Nom"
label: qsTr("contact_editor_last_name")
Layout.fillWidth: true Layout.fillWidth: true
contentItem: TextField { contentItem: TextField {
id: nameTextField id: nameTextField
@ -219,7 +229,8 @@ MainRightPanel {
} }
} }
FormItemLayout { FormItemLayout {
label: qsTr("Entreprise") //: "Entreprise"
label: qsTr("contact_editor_company")
Layout.fillWidth: true Layout.fillWidth: true
contentItem: TextField { contentItem: TextField {
id: companyTextField id: companyTextField
@ -231,7 +242,8 @@ MainRightPanel {
} }
} }
FormItemLayout { FormItemLayout {
label: qsTr("Fonction") //: "Fonction"
label: qsTr("contact_editor_job_title")
Layout.fillWidth: true Layout.fillWidth: true
contentItem: TextField { contentItem: TextField {
id: jobTextField id: jobTextField
@ -281,7 +293,7 @@ MainRightPanel {
Layout.preferredWidth: Math.round(421 * DefaultStyle.dp) Layout.preferredWidth: Math.round(421 * DefaultStyle.dp)
Layout.preferredHeight: height Layout.preferredHeight: height
onEditingFinished: { 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 property string _initialText: modelData.address
initialText: SettingsCpp.onlyDisplaySipUriUsername ? UtilsCpp.getUsername(_initialText) : _initialText initialText: SettingsCpp.onlyDisplaySipUriUsername ? UtilsCpp.getUsername(_initialText) : _initialText
@ -308,7 +320,7 @@ MainRightPanel {
} }
FormItemLayout { FormItemLayout {
id: newAddressSipTextField id: newAddressSipTextField
label: qsTr("Adresse SIP") label: qsTr("sip_address")
Layout.fillWidth: true Layout.fillWidth: true
onYChanged: { onYChanged: {
editionLayout.ensureVisibleRequested(newAddressSipTextField) editionLayout.ensureVisibleRequested(newAddressSipTextField)
@ -373,7 +385,8 @@ MainRightPanel {
KeyNavigation.right: removePhoneButton KeyNavigation.right: removePhoneButton
Keys.onPressed: (event) => phoneNumberLayout.updateFocus(event) Keys.onPressed: (event) => phoneNumberLayout.updateFocus(event)
onEditingFinished: { 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 { Button {
@ -395,7 +408,7 @@ MainRightPanel {
FormItemLayout { FormItemLayout {
id: phoneNumberInput id: phoneNumberInput
Layout.fillWidth: true Layout.fillWidth: true
label: qsTr("Phone") label: qsTr("phone")
onYChanged: { onYChanged: {
editionLayout.ensureVisibleRequested(phoneNumberInput) editionLayout.ensureVisibleRequested(phoneNumberInput)
} }

View file

@ -38,7 +38,8 @@ LoginLayout {
Layout.preferredWidth: Math.round(34 * DefaultStyle.dp) Layout.preferredWidth: Math.round(34 * DefaultStyle.dp)
} }
Text { Text {
text: qsTr("Connexion") //: Connexion
text: qsTr("assistant_account_login")
font { font {
pixelSize: Typography.h1.pixelSize pixelSize: Typography.h1.pixelSize
weight: Typography.h1.weight weight: Typography.h1.weight
@ -54,14 +55,16 @@ LoginLayout {
Layout.rightMargin: Math.round(51 * DefaultStyle.dp) Layout.rightMargin: Math.round(51 * DefaultStyle.dp)
Text { Text {
Layout.rightMargin: Math.round(15 * DefaultStyle.dp) 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.pixelSize: Typography.p1.pixelSize
font.weight: Typography.p1.weight font.weight: Typography.p1.weight
} }
BigButton { BigButton {
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
style: ButtonStyle.main style: ButtonStyle.main
text: qsTr("S'inscrire") //: "S'inscrire"
text: qsTr("assistant_account_register")
onClicked: { onClicked: {
console.debug("[LoginPage] User: go to register") console.debug("[LoginPage] User: go to register")
mainItem.goToRegister() mainItem.goToRegister()
@ -87,7 +90,8 @@ LoginLayout {
Layout.preferredHeight: Math.round(47 * DefaultStyle.dp) Layout.preferredHeight: Math.round(47 * DefaultStyle.dp)
Layout.topMargin: Math.round(39 * DefaultStyle.dp) Layout.topMargin: Math.round(39 * DefaultStyle.dp)
visible: !SettingsCpp.assistantHideThirdPartyAccount visible: !SettingsCpp.assistantHideThirdPartyAccount
text: qsTr("Compte SIP tiers") //: "Compte SIP tiers"
text: qsTr("assistant_login_third_party_sip_account_title")
style: ButtonStyle.secondary style: ButtonStyle.secondary
onClicked: {mainItem.useSIPButtonClicked()} onClicked: {mainItem.useSIPButtonClicked()}
} }
@ -95,7 +99,8 @@ LoginLayout {
Layout.preferredWidth: loginForm.width Layout.preferredWidth: loginForm.width
Layout.preferredHeight: Math.round(47 * DefaultStyle.dp) Layout.preferredHeight: Math.round(47 * DefaultStyle.dp)
Layout.topMargin: Math.round(25 * DefaultStyle.dp) Layout.topMargin: Math.round(25 * DefaultStyle.dp)
text: qsTr("Configuration distante") //: "Configuration distante"
text: qsTr("assistant_login_remote_provisioning")
style: ButtonStyle.secondary style: ButtonStyle.secondary
onClicked: {fetchConfigDialog.open()} onClicked: {fetchConfigDialog.open()}
} }
@ -122,14 +127,17 @@ LoginLayout {
topPadding: Math.round(41 * DefaultStyle.dp) topPadding: Math.round(41 * DefaultStyle.dp)
bottomPadding: Math.round(29 * DefaultStyle.dp) bottomPadding: Math.round(29 * DefaultStyle.dp)
radius: 0 radius: 0
title: qsTr('Télécharger une configuration distante') //: "Télécharger une configuration distante"
text: qsTr('Veuillez entrer le lien de configuration qui vous a été fourni :') 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 firstButtonAccept: false
firstButton.style: ButtonStyle.secondary firstButton.style: ButtonStyle.secondary
secondButton.text: 'Valider' //: "Valider"
secondButton.text: qsTr("validate")
secondButtonAccept: true secondButtonAccept: true
secondButton.style: ButtonStyle.main secondButton.style: ButtonStyle.main
onAccepted:{ onAccepted:{
@ -140,7 +148,8 @@ LoginLayout {
id: configUrl id: configUrl
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: Math.round(49 * DefaultStyle.dp) Layout.preferredHeight: Math.round(49 * DefaultStyle.dp)
placeholderText: qsTr('Lien de configuration distante') //: 'Lien de configuration distante'
placeholderText: qsTr("settings_advanced_remote_provisioning_url")
} }
] ]
} }

View file

@ -38,7 +38,8 @@ LoginLayout {
colorizationColor: DefaultStyle.main2_600 colorizationColor: DefaultStyle.main2_600
} }
Text { Text {
text: qsTr("Compte SIP tiers") //: Compte SIP tiers
text: qsTr("assistant_login_third_party_sip_account_title")
font { font {
pixelSize: Typography.h1.pixelSize pixelSize: Typography.h1.pixelSize
weight: Typography.h1.weight weight: Typography.h1.weight
@ -55,7 +56,8 @@ LoginLayout {
spacing: Math.round(20 * DefaultStyle.dp) spacing: Math.round(20 * DefaultStyle.dp)
Text { Text {
Layout.rightMargin: Math.round(15 * DefaultStyle.dp) Layout.rightMargin: Math.round(15 * DefaultStyle.dp)
text: qsTr("Pas encore de compte ?") //: Pas encore de compte ?
text: qsTr("assistant_no_account_yet")
font { font {
pixelSize: Typography.p1.pixelSize pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight weight: Typography.p1.weight
@ -63,7 +65,8 @@ LoginLayout {
} }
BigButton { BigButton {
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
text: qsTr("S'inscrire") //: S'inscrire
text: qsTr("assistant_account_register")
style: ButtonStyle.main style: ButtonStyle.main
onClicked: { onClicked: {
console.debug("[SIPLoginPage] User: go to register page") console.debug("[SIPLoginPage] User: go to register page")
@ -97,30 +100,30 @@ LoginLayout {
pixelSize: Typography.p1.pixelSize pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight weight: Typography.p1.weight
} }
text: "Certaines fonctionnalités nécessitent un compte Linphone, comme la messagerie de groupe, les vidéoconférences..." 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. "
} }
// 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 { SmallButton {
id: openLinkButton id: openLinkButton
@ -141,7 +144,8 @@ LoginLayout {
id: createAccountButton id: createAccountButton
style: ButtonStyle.secondary style: ButtonStyle.secondary
Layout.fillWidth: true 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: { onClicked: {
console.debug("[SIPLoginPage] User: click register") console.debug("[SIPLoginPage] User: click register")
mainItem.goToRegister() mainItem.goToRegister()
@ -152,7 +156,8 @@ LoginLayout {
BigButton { BigButton {
id: continueButton id: continueButton
Layout.fillWidth: true Layout.fillWidth: true
text: qsTr("Je comprends") //: "Je comprends"
text: qsTr("assistant_third_party_sip_account_warning_ok")
style: ButtonStyle.main style: ButtonStyle.main
onClicked: { onClicked: {
rootStackView.replace(secondItem) rootStackView.replace(secondItem)
@ -183,7 +188,8 @@ LoginLayout {
spacing: Math.round(16 * DefaultStyle.dp) spacing: Math.round(16 * DefaultStyle.dp)
FormItemLayout { FormItemLayout {
id: username id: username
label: qsTr("Nom d'utilisateur") //: "Nom d'utilisateur"
label: qsTr("username")
mandatory: true mandatory: true
enableErrorText: true enableErrorText: true
Layout.fillWidth: true Layout.fillWidth: true
@ -196,7 +202,7 @@ LoginLayout {
} }
FormItemLayout { FormItemLayout {
id: password id: password
label: qsTr("Mot de passe") label: qsTr("password")
mandatory: true mandatory: true
enableErrorText: true enableErrorText: true
Layout.fillWidth: true Layout.fillWidth: true
@ -211,7 +217,8 @@ LoginLayout {
} }
FormItemLayout { FormItemLayout {
id: domain id: domain
label: qsTr("Domaine") //: "Domaine"
label: qsTr("sip_address_domain")
mandatory: true mandatory: true
enableErrorText: true enableErrorText: true
Layout.fillWidth: true Layout.fillWidth: true
@ -231,7 +238,8 @@ LoginLayout {
} }
} }
FormItemLayout { FormItemLayout {
label: qsTr("Nom d'affichage") //: Nom d'affichage
label: qsTr("sip_address_display_name")
Layout.fillWidth: true Layout.fillWidth: true
contentItem: TextField { contentItem: TextField {
id: displayName id: displayName
@ -242,7 +250,8 @@ LoginLayout {
} }
} }
FormItemLayout { FormItemLayout {
label: qsTr("Transport") //: "Transport"
label: qsTr("transport")
Layout.fillWidth: true Layout.fillWidth: true
contentItem: ComboBox { contentItem: ComboBox {
id: transportCbox id: transportCbox
@ -281,7 +290,7 @@ LoginLayout {
id: connectionButtonContent id: connectionButtonContent
currentIndex: 0 currentIndex: 0
Text { Text {
text: qsTr("Connexion") text: qsTr("assistant_account_login")
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
@ -330,11 +339,12 @@ LoginLayout {
onTriggered: { onTriggered: {
if (usernameEdit.text.length == 0 || passwordEdit.text.length == 0 || domainEdit.text.length == 0) { if (usernameEdit.text.length == 0 || passwordEdit.text.length == 0 || domainEdit.text.length == 0) {
if (usernameEdit.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) 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) 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 return
} }
console.debug("[SIPLoginPage] User: Log in") console.debug("[SIPLoginPage] User: Log in")

View file

@ -9,8 +9,8 @@ import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
FocusScope{ FocusScope{
id: mainItem id: mainItem
//: "Rechercher des contacts"
property string placeHolderText: qsTr("Rechercher des contacts") property string placeHolderText: qsTr("search_bar_search_contacts_placeholder")
property list<string> selectedParticipants property list<string> selectedParticipants
property int selectedParticipantsCount: selectedParticipants.length property int selectedParticipantsCount: selectedParticipants.length
property ConferenceInfoGui conferenceInfoGui property ConferenceInfoGui conferenceInfoGui
@ -107,7 +107,8 @@ FocusScope{
visible: !contactList.loading && contactList.count === 0 visible: !contactList.loading && contactList.count === 0
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
Layout.topMargin: Math.round(137 * DefaultStyle.dp) 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 { font {
pixelSize: Typography.h4.pixelSize pixelSize: Typography.h4.pixelSize
weight: Typography.h4.weight weight: Typography.h4.weight

View file

@ -35,7 +35,8 @@ FocusScope {
icon.width: Math.round(24 * DefaultStyle.dp) icon.width: Math.round(24 * DefaultStyle.dp)
icon.height: Math.round(24 * DefaultStyle.dp) icon.height: Math.round(24 * DefaultStyle.dp)
enabled: false enabled: false
text: qsTr("Réunion") //: "Réunion"
text: qsTr("meeting_schedule_meeting_label")
checked: true checked: true
autoExclusive: true autoExclusive: true
style: ButtonStyle.secondary style: ButtonStyle.secondary
@ -46,7 +47,8 @@ FocusScope {
icon.source: AppIcons.slide icon.source: AppIcons.slide
icon.width: Math.round(24 * DefaultStyle.dp) icon.width: Math.round(24 * DefaultStyle.dp)
icon.height: Math.round(24 * DefaultStyle.dp) icon.height: Math.round(24 * DefaultStyle.dp)
text: qsTr("Broadcast") //: "Webinar"
text: qsTr("meeting_schedule_broadcast_label")
autoExclusive: true autoExclusive: true
style: ButtonStyle.secondary style: ButtonStyle.secondary
} }
@ -65,7 +67,8 @@ FocusScope {
TextInput { TextInput {
id: confTitle id: confTitle
Layout.fillWidth: true Layout.fillWidth: true
property string defaultText: qsTr("Ajouter un titre") //: "Ajouter un titre"
property string defaultText: qsTr("meeting_schedule_subject_hint")
text: defaultText text: defaultText
color: DefaultStyle.main2_600 color: DefaultStyle.main2_600
font { font {
@ -210,7 +213,8 @@ FocusScope {
leftPadding: Math.round(8 * DefaultStyle.dp) leftPadding: Math.round(8 * DefaultStyle.dp)
rightPadding: Math.round(8 * DefaultStyle.dp) rightPadding: Math.round(8 * DefaultStyle.dp)
hoverEnabled: true hoverEnabled: true
placeholderText: qsTr("Ajouter une description") //: "Ajouter une description"
placeholderText: qsTr("meeting_schedule_description_hint")
placeholderTextColor: DefaultStyle.main2_600 placeholderTextColor: DefaultStyle.main2_600
placeholderWeight: Typography.p2l.weight placeholderWeight: Typography.p2l.weight
color: DefaultStyle.main2_600 color: DefaultStyle.main2_600
@ -257,7 +261,8 @@ FocusScope {
} }
Text { Text {
Layout.fillWidth: true Layout.fillWidth: true
text: qsTr("Ajouter des participants") //: "Ajouter des participants"
text: qsTr("meeting_schedule_add_participants_title")
font { font {
pixelSize: Typography.p2l.pixelSize pixelSize: Typography.p2l.pixelSize
weight: Typography.p2l.weight weight: Typography.p2l.weight
@ -310,7 +315,8 @@ FocusScope {
] ]
} }
Switch { 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 checked: mainItem.conferenceInfoGui.core.inviteEnabled
onToggled: mainItem.conferenceInfoGui.core.inviteEnabled = checked onToggled: mainItem.conferenceInfoGui.core.inviteEnabled = checked
} }

View file

@ -39,8 +39,12 @@ LoginLayout {
Text { Text {
wrapMode: Text.NoWrap wrapMode: Text.NoWrap
text: { text: {
var completeString = mainItem.registerWithEmail ? qsTr("email") : qsTr("numéro") //: "email"
text = qsTr("Inscription | Confirmer votre ") + completeString 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 { font {
pixelSize: Typography.h1.pixelSize pixelSize: Typography.h1.pixelSize
@ -69,8 +73,9 @@ LoginLayout {
} }
color: DefaultStyle.main2_700 color: DefaultStyle.main2_700
text: { text: {
var completeString = mainItem.registerWithEmail ? ("email \"") : ("phone number \"") + address + "\"" var completeString = mainItem.registerWithEmail ? ("email") : ("phone_number")
text = "We have sent a verification code on your " + completeString + " <br>Please enter the verification code below:" //: Nous vous avons envoyé un code de vérification sur votre %1 %2<br> Merci de le saisir ci-dessous
text = qsTr("assistant_account_creation_confirmation_explanation").arg(completeString).arg(address)
} }
} }
RowLayout { RowLayout {
@ -141,14 +146,16 @@ LoginLayout {
RowLayout { RowLayout {
spacing: Math.round(20 * DefaultStyle.dp) spacing: Math.round(20 * DefaultStyle.dp)
Text { 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 color: DefaultStyle.main2_700
font.pixelSize: Typography.p1.pixelSize font.pixelSize: Typography.p1.pixelSize
font.weight: Typography.p1.weight font.weight: Typography.p1.weight
} }
BigButton { BigButton {
style: ButtonStyle.secondary style: ButtonStyle.secondary
text: "Resend a code" //: "Renvoyer un code"
text: qsTr("assistant_account_creation_confirmation_resend_code")
onClicked: { onClicked: {
console.debug("[RegisterCheckingPage] User: Resend code") console.debug("[RegisterCheckingPage] User: Resend code")
} }

View file

@ -51,7 +51,8 @@ LoginLayout {
} }
Text { Text {
Layout.preferredWidth: width Layout.preferredWidth: width
text: qsTr("Inscription") //: "Inscription
text: qsTr("assistant_account_register")
font { font {
pixelSize: Typography.h1.pixelSize pixelSize: Typography.h1.pixelSize
weight: Typography.h1.weight weight: Typography.h1.weight
@ -69,7 +70,8 @@ LoginLayout {
Text { Text {
Layout.rightMargin: Math.round(15 * DefaultStyle.dp) Layout.rightMargin: Math.round(15 * DefaultStyle.dp)
color: DefaultStyle.main2_700 color: DefaultStyle.main2_700
text: qsTr("Déjà un compte ?") // "Déjà un compte ?"
text: qsTr("assistant_already_have_an_account")
font { font {
pixelSize: Typography.p1.pixelSize pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight weight: Typography.p1.weight
@ -77,7 +79,7 @@ LoginLayout {
} }
BigButton { BigButton {
style: ButtonStyle.main style: ButtonStyle.main
text: qsTr("Connexion") text: qsTr("assistant_account_login")
onClicked: { onClicked: {
console.debug("[RegisterPage] User: return") console.debug("[RegisterPage] User: return")
returnToLogin() returnToLogin()
@ -96,7 +98,10 @@ LoginLayout {
TabBar { TabBar {
Layout.fillWidth: true Layout.fillWidth: true
id: bar 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 { Flickable {
Layout.fillWidth: true Layout.fillWidth: true
@ -112,7 +117,7 @@ LoginLayout {
spacing: Math.round(16 * DefaultStyle.dp) spacing: Math.round(16 * DefaultStyle.dp)
FormItemLayout { FormItemLayout {
id: usernameItem id: usernameItem
label: qsTr("Username") label: qsTr("username")
mandatory: true mandatory: true
enableErrorText: true enableErrorText: true
Layout.preferredWidth: Math.round(346 * DefaultStyle.dp) Layout.preferredWidth: Math.round(346 * DefaultStyle.dp)
@ -143,17 +148,18 @@ LoginLayout {
id: phoneNumberInput id: phoneNumberInput
Layout.preferredWidth: Math.round(346 * DefaultStyle.dp) Layout.preferredWidth: Math.round(346 * DefaultStyle.dp)
property string completePhoneNumber: countryCode + phoneNumber 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 enableErrorText: true
mandatory: true mandatory: true
placeholderText: "Phone number" placeholderText: qsTr("phone_number")
defaultCallingCode: "33" defaultCallingCode: "33"
} }
FormItemLayout { FormItemLayout {
id: emailItem id: emailItem
Layout.fillWidth: false Layout.fillWidth: false
Layout.preferredWidth: Math.round(346 * DefaultStyle.dp) Layout.preferredWidth: Math.round(346 * DefaultStyle.dp)
label: qsTr("Email") label: qsTr("email")
mandatory: true mandatory: true
enableErrorText: true enableErrorText: true
contentItem: TextField { contentItem: TextField {
@ -172,7 +178,7 @@ LoginLayout {
FormItemLayout { FormItemLayout {
id: passwordItem id: passwordItem
Layout.preferredWidth: Math.round(346 * DefaultStyle.dp) Layout.preferredWidth: Math.round(346 * DefaultStyle.dp)
label: qsTr("Mot de passe") label: qsTr("password")
mandatory: true mandatory: true
enableErrorText: true enableErrorText: true
contentItem: TextField { contentItem: TextField {
@ -184,7 +190,8 @@ LoginLayout {
} }
FormItemLayout { FormItemLayout {
Layout.preferredWidth: Math.round(346 * DefaultStyle.dp) 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 mandatory: true
enableErrorText: true enableErrorText: true
contentItem: TextField { contentItem: TextField {
@ -199,7 +206,6 @@ LoginLayout {
id: otherErrorText id: otherErrorText
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: Math.round(5 * DefaultStyle.dp) Layout.topMargin: Math.round(5 * DefaultStyle.dp)
onTextChanged: console.log("set error", text)
} }
} }
} }
@ -228,96 +234,53 @@ LoginLayout {
CheckBox { CheckBox {
id: termsCheckBox id: termsCheckBox
} }
RowLayout {
spacing: 0
Layout.fillWidth: true
Text { Text {
text: qsTr("J'accepte les ") //: "J'accepte les %1 et la %2"
text: qsTr("assistant_dialog_cgu_and_privacy_policy_message")
//: "conditions d'utilisation"
.arg(("<a href='%1'><font color='DefaultStyle.main2_600'>%2</font></a>").arg(ConstantsCpp.CguUrl).arg(qsTr("assistant_dialog_general_terms_label")))
//: "politique de confidentialité"
.arg(("<a href='%1'><font color='DefaultStyle.main2_600'>%2</font></a>").arg(ConstantsCpp.PrivatePolicyUrl).arg(qsTr("assistant_dialog_privacy_policy_label")))
onLinkActivated: (link) => Qt.openUrlExternally(link)
font { font {
pixelSize: Typography.p1.pixelSize pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight weight: Typography.p1.weight
} }
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
acceptedButtons: Qt.NoButton
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
onClicked: termsCheckBox.toggle() onClicked: termsCheckBox.toggle()
} }
} }
Text {
activeFocusOnTab: true
font {
underline: true
pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight
bold: activeFocus
}
text: qsTr("conditions dutilisation")
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)
}
}
}
} }
// } // }
Button { Button {
enabled: termsCheckBox.checked enabled: termsCheckBox.checked
style: ButtonStyle.main style: ButtonStyle.main
text: qsTr("Créer") //: "Créer"
text: qsTr("assistant_account_create")
onClicked:{ onClicked:{
if (usernameInput.text.length === 0) { if (usernameInput.text.length === 0) {
console.log("ERROR username") 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) { } else if (pwdInput.text.length === 0) {
console.log("ERROR password") 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) { } else if (pwdInput.text != confirmPwdInput.text) {
console.log("ERROR confirm pwd") 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) { } else if (bar.currentIndex === 0 && phoneNumberInput.phoneNumber.length === 0) {
console.log("ERROR phone number") 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) { } else if (bar.currentIndex === 1 && emailInput.text.length === 0) {
console.log("ERROR email") 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 { } else {
console.log("[RegisterPage] User: Call register") console.log("[RegisterPage] User: Call register")
mainItem.browserValidationRequested() mainItem.browserValidationRequested()

View file

@ -18,14 +18,16 @@ LoginLayout {
} }
ColumnLayout { ColumnLayout {
Text { Text {
text: qsTr("Choisir votre mode") //: "Choisir votre mode"
text: qsTr("manage_account_choose_mode_title")
font { font {
pixelSize: Typography.h1.pixelSize pixelSize: Typography.h1.pixelSize
weight: Typography.h1.weight weight: Typography.h1.weight
} }
} }
Text { 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.bold: true
font { font {
pixelSize: Typography.p1.pixelSize pixelSize: Typography.p1.pixelSize
@ -44,8 +46,14 @@ LoginLayout {
spacing: Math.round(70 * DefaultStyle.dp) spacing: Math.round(70 * DefaultStyle.dp)
Repeater { Repeater {
model: [ 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}, //: "Chiffrement de bout en bout"
{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 nimporte quelle autre service SIP."), imgUrl: AppIcons.interoperable, color: DefaultStyle.main1_500_main} {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 nimporte quelle autre service SIP."
text: qsTr("manage_account_e2e_encrypted_mode_interoperable_summary"), imgUrl: AppIcons.interoperable, color: DefaultStyle.main1_500_main}
] ]
SecurityRadioButton { SecurityRadioButton {
title: modelData.title title: modelData.title
@ -64,7 +72,8 @@ LoginLayout {
property int selectedIndex: 0 property int selectedIndex: 0
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: Math.round(360 * DefaultStyle.dp) Layout.preferredWidth: Math.round(360 * DefaultStyle.dp)
text: qsTr("Continuer") //: "Continuer"
text: qsTr("dialog_continue")
style: ButtonStyle.main style: ButtonStyle.main
onClicked: mainItem.modeSelected(selectedIndex) onClicked: mainItem.modeSelected(selectedIndex)
} }

View file

@ -9,20 +9,25 @@ import SettingsCpp
AbstractSettingsMenu { AbstractSettingsMenu {
id: mainItem id: mainItem
layoutsPath: "qrc:/qt/qml/Linphone/view/Page/Layout/Settings" layoutsPath: "qrc:/qt/qml/Linphone/view/Page/Layout/Settings"
titleText: qsTr("Mon compte") //: "Mon compte"
titleText: qsTr("drawer_menu_manage_account")
property AccountGui account property AccountGui account
signal accountRemoved() signal accountRemoved()
families: [ families: [
{title: qsTr("Général"), layout: "AccountSettingsGeneralLayout", model: account}, //: "Général"
{title: qsTr("Paramètres de compte"), layout: "AccountSettingsParametersLayout", model: account} {title: qsTr("settings_general_title"), layout: "AccountSettingsGeneralLayout", model: account},
//: "Paramètres de compte"
{title: qsTr("settings_account_title"), layout: "AccountSettingsParametersLayout", model: account}
] ]
Connections { Connections {
target: account.core target: account.core
function onRemoved() { accountRemoved() } function onRemoved() { accountRemoved() }
} }
onGoBackRequested: if (!account.core.isSaved) { onGoBackRequested: if (!account.core.isSaved) {
UtilsCpp.getMainWindow().showConfirmationLambdaPopup(qsTr("Modifications non enregistrées"), //: "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 ?"), 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) { function (confirmed) {
if (confirmed) { if (confirmed) {
@ -31,7 +36,9 @@ AbstractSettingsMenu {
account.core.undo() account.core.undo()
} }
mainItem.goBack() 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()} } else {mainItem.goBack()}
} }

View file

@ -8,20 +8,30 @@ import UtilsCpp
AbstractSettingsMenu { AbstractSettingsMenu {
id: mainItem id: mainItem
layoutsPath: "qrc:/qt/qml/Linphone/view/Page/Layout/Settings" layoutsPath: "qrc:/qt/qml/Linphone/view/Page/Layout/Settings"
titleText: qsTr("Paramètres") //: "Paramètres"
titleText: qsTr("settings_title")
families: [ families: [
{title: qsTr("Appels"), layout: "CallSettingsLayout"}, //: "Appels"
{title: qsTr("Conversations"), layout: "ChatSettingsLayout", visible: !SettingsCpp.disableChatFeature}, {title: qsTr("settings_calls_title"), layout: "CallSettingsLayout"},
{title: qsTr("Contacts"), layout: "ContactsSettingsLayout"}, //: "Conversations"
{title: qsTr("Réunions"), layout: "MeetingsSettingsLayout", visible: !SettingsCpp.disableMeetingsFeature}, {title: qsTr("settings_conversations_title"), layout: "ChatSettingsLayout", visible: !SettingsCpp.disableChatFeature},
//{title: qsTr("Affichage"), layout: "DisplaySettingsLayout"}, //: "Contacts"
{title: qsTr("Réseau"), layout: "NetworkSettingsLayout"}, {title: qsTr("settings_contacts_title"), layout: "ContactsSettingsLayout"},
{title: qsTr("Paramètres avancés"), layout: "AdvancedSettingsLayout"} //: "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) { onGoBackRequested: if (!SettingsCpp.isSaved) {
UtilsCpp.getMainWindow().showConfirmationLambdaPopup(qsTr("Modifications non enregistrées"), //: 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 ?"), 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) { function (confirmed) {
if (confirmed) { if (confirmed) {
@ -30,7 +40,10 @@ AbstractSettingsMenu {
SettingsCpp.undo() SettingsCpp.undo()
} }
mainItem.goBack() 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()} } else {mainItem.goBack()}
} }

View file

@ -72,7 +72,8 @@ Rectangle {
id: aboutPopup id: aboutPopup
anchors.centerIn: parent anchors.centerIn: parent
width: Math.round(637 * DefaultStyle.dp) 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) bottomPadding: Math.round(10 * DefaultStyle.dp)
buttons: [] buttons: []
content: RowLayout { content: RowLayout {
@ -81,24 +82,29 @@ Rectangle {
Layout.alignment: Qt.AlignTop | Qt.AlignLeft Layout.alignment: Qt.AlignTop | Qt.AlignLeft
AboutLine { AboutLine {
imageSource: AppIcons.detective imageSource: AppIcons.detective
title: qsTr("Politique de confidentialité") //: "Politique de confidentialité"
text: qsTr("Visiter notre potilique de confidentialité") title: qsTr("help_about_privacy_policy_title")
//: "Visiter notre potilique de confidentialité"
text: qsTr("help_about_privacy_policy_link")
enableMouseArea: true enableMouseArea: true
onContentClicked: Qt.openUrlExternally(ConstantsCpp.PrivatePolicyUrl) onContentClicked: Qt.openUrlExternally(ConstantsCpp.PrivatePolicyUrl)
} }
AboutLine { AboutLine {
imageSource: AppIcons.info imageSource: AppIcons.info
title: qsTr("Version") //: "Version"
title: qsTr("help_about_version_title")
text: Qt.application.version text: Qt.application.version
} }
AboutLine { AboutLine {
imageSource: AppIcons.checkSquareOffset imageSource: AppIcons.checkSquareOffset
title: qsTr("Licence") //: "Licence"
title: qsTr("help_about_licence_title")
text: applicationLicence text: applicationLicence
} }
AboutLine { AboutLine {
imageSource: AppIcons.copyright imageSource: AppIcons.copyright
title: qsTr("Copyright") //: "Copyright
title: qsTr("help_about_copyright_title")
text: applicationVendor text: applicationVendor
} }
Item { Item {
@ -108,7 +114,8 @@ Rectangle {
} }
MediumButton { MediumButton {
Layout.alignment: Qt.AlignRight | Qt.AlignBottom Layout.alignment: Qt.AlignRight | Qt.AlignBottom
text: qsTr("Fermer") //: "Fermer"
text: qsTr("close")
style: ButtonStyle.main style: ButtonStyle.main
onClicked: aboutPopup.close() onClicked: aboutPopup.close()
} }
@ -131,7 +138,7 @@ Rectangle {
id: aboutButton id: aboutButton
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
icon.source: AppIcons.info icon.source: AppIcons.info
text: qsTr("À propos") text: qsTr("help_about_title").arg(applicationName)
textSize: Typography.p1.pixelSize textSize: Typography.p1.pixelSize
textWeight: Typography.p1.weight textWeight: Typography.p1.weight
textColor: DefaultStyle.main2_500main textColor: DefaultStyle.main2_500main

View file

@ -129,20 +129,24 @@ Item {
model: [{ model: [{
"icon": AppIcons.phone, "icon": AppIcons.phone,
"selectedIcon": AppIcons.phoneSelected, "selectedIcon": AppIcons.phoneSelected,
"label": qsTr("Appels") //: "Appels"
"label": qsTr("bottom_navigation_calls_label")
}, { }, {
"icon": AppIcons.adressBook, "icon": AppIcons.adressBook,
"selectedIcon": AppIcons.adressBookSelected, "selectedIcon": AppIcons.adressBookSelected,
"label": qsTr("Contacts") //: "Contacts"
"label": qsTr("bottom_navigation_contacts_label")
}, { }, {
"icon": AppIcons.chatTeardropText, "icon": AppIcons.chatTeardropText,
"selectedIcon": AppIcons.chatTeardropTextSelected, "selectedIcon": AppIcons.chatTeardropTextSelected,
"label": qsTr("Conversations"), //: "Conversations"
"label": qsTr("bottom_navigation_conversations_label"),
"visible": !SettingsCpp.disableChatFeature "visible": !SettingsCpp.disableChatFeature
}, { }, {
"icon": AppIcons.videoconference, "icon": AppIcons.videoconference,
"selectedIcon": AppIcons.videoconferenceSelected, "selectedIcon": AppIcons.videoconferenceSelected,
"label": qsTr("Réunions"), //: "Réunions"
"label": qsTr("bottom_navigation_meetings_label"),
"visible": !SettingsCpp.disableMeetingsFeature "visible": !SettingsCpp.disableMeetingsFeature
}] }]
onCurrentIndexChanged: { onCurrentIndexChanged: {
@ -188,7 +192,9 @@ Item {
SearchBar { SearchBar {
id: magicSearchBar id: magicSearchBar
Layout.fillWidth: true 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 focusedBorderColor: DefaultStyle.main1_500_main
numericPadButton.visible: text.length === 0 numericPadButton.visible: text.length === 0
numericPadButton.checkable: false numericPadButton.checkable: false
@ -293,7 +299,8 @@ Item {
focus: visible focus: visible
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp)
icon.height: 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 icon.source: AppIcons.bellDnd
onClicked: { onClicked: {
deactivateDndButton.popup.close() deactivateDndButton.popup.close()
@ -349,10 +356,9 @@ Item {
UtilsCpp.createCall( UtilsCpp.createCall(
accountProxy.defaultAccount.core.voicemailAddress) accountProxy.defaultAccount.core.voicemailAddress)
else else
UtilsCpp.showInformationPopup( UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
qsTr("Erreur"), qsTr( //: "L'URI de messagerie vocale n'est pas définie."
"L'URI de messagerie vocale n'est pas définie."), qsTr("no_voicemail_uri_error_message"), false)
false)
} }
} }
} }
@ -360,7 +366,10 @@ Item {
id: avatarButton id: avatarButton
Layout.preferredWidth: Math.round(54 * DefaultStyle.dp) Layout.preferredWidth: Math.round(54 * DefaultStyle.dp)
Layout.preferredHeight: width 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 { contentItem: Avatar {
id: avatar id: avatar
height: avatarButton.height height: avatarButton.height
@ -407,7 +416,9 @@ Item {
visible: !SettingsCpp.hideAccountSettings visible: !SettingsCpp.hideAccountSettings
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp)
icon.height: 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 icon.source: AppIcons.manageProfile
onClicked: openAccountSettings( onClicked: openAccountSettings(
accountProxy.defaultAccount ? accountProxy.defaultAccount : accountProxy.firstAccount()) accountProxy.defaultAccount ? accountProxy.defaultAccount : accountProxy.firstAccount())
@ -423,8 +434,9 @@ Item {
Layout.fillWidth: true Layout.fillWidth: true
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp)
icon.height: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp)
text: SettingsCpp.dnd ? qsTr("Désactiver ne pas déranger") : qsTr( text: SettingsCpp.dnd ? qsTr("contact_presence_status_disable_do_not_disturb")
"Activer ne pas déranger") //: "Activer ne pas déranger"
: qsTr("contact_presence_status_enable_do_not_disturb")
icon.source: AppIcons.bellDnd icon.source: AppIcons.bellDnd
onClicked: { onClicked: {
settingsMenuButton.popup.close() settingsMenuButton.popup.close()
@ -443,7 +455,7 @@ Item {
visible: !SettingsCpp.hideSettings visible: !SettingsCpp.hideSettings
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp)
icon.height: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp)
text: qsTr("Paramètres") text: qsTr("settings_title")
icon.source: AppIcons.settings icon.source: AppIcons.settings
onClicked: openContextualMenuComponent( onClicked: openContextualMenuComponent(
settingsPageComponent) settingsPageComponent)
@ -460,7 +472,8 @@ Item {
visible: !SettingsCpp.disableCallRecordings visible: !SettingsCpp.disableCallRecordings
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp)
icon.height: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp)
text: qsTr("Enregistrements") //: "Enregistrements"
text: qsTr("recordings_title")
icon.source: AppIcons.micro icon.source: AppIcons.micro
KeyNavigation.up: visibleChildren.length KeyNavigation.up: visibleChildren.length
!= 0 ? settingsMenuButton.getPreviousItem( != 0 ? settingsMenuButton.getPreviousItem(
@ -474,7 +487,8 @@ Item {
Layout.fillWidth: true Layout.fillWidth: true
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp)
icon.height: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp)
text: qsTr("Aide") //: "Aide"
text: qsTr("help_title")
icon.source: AppIcons.question icon.source: AppIcons.question
onClicked: openContextualMenuComponent( onClicked: openContextualMenuComponent(
helpPageComponent) helpPageComponent)
@ -490,15 +504,13 @@ Item {
Layout.fillWidth: true Layout.fillWidth: true
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp)
icon.height: 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 icon.source: AppIcons.power
onClicked: { onClicked: {
settingsMenuButton.popup.close() settingsMenuButton.popup.close()
UtilsCpp.getMainWindow( //: "Quitter %1 ?"
).showConfirmationLambdaPopup( UtilsCpp.getMainWindow().showConfirmationLambdaPopup("", qsTr("quit_app_question").arg(applicationName),"",
"", qsTr(
"Quitter Linphone ?"),
"",
function (confirmed) { function (confirmed) {
if (confirmed) { if (confirmed) {
console.info("Exiting App from Top Menu") console.info("Exiting App from Top Menu")
@ -526,7 +538,8 @@ Item {
|| SettingsCpp.maxAccount > accountProxy.count || SettingsCpp.maxAccount > accountProxy.count
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp)
icon.height: 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 icon.source: AppIcons.plusCircle
onClicked: mainItem.addAccountRequest() onClicked: mainItem.addAccountRequest()
KeyNavigation.up: visibleChildren.length KeyNavigation.up: visibleChildren.length

View file

@ -80,7 +80,8 @@ Rectangle {
MediumButton { MediumButton {
id: saveButton id: saveButton
style: ButtonStyle.main style: ButtonStyle.main
text: qsTr("Enregistrer") //: "Enregistrer"
text: qsTr("save")
Layout.rightMargin: Math.round(6 * DefaultStyle.dp) Layout.rightMargin: Math.round(6 * DefaultStyle.dp)
visible: mainItem.saveButtonVisible visible: mainItem.saveButtonVisible
onClicked: { onClicked: {

View file

@ -15,13 +15,17 @@ AbstractSettingsLayout {
width: parent?.width width: parent?.width
contentModel: [ contentModel: [
{ {
title: qsTr("Détails"), //: "Détails"
subTitle: qsTr("Editer les informations de votre compte."), title: qsTr("manage_account_details_title"),
//: Éditer les informations de votre compte.
subTitle: qsTr("manage_account_details_subtitle"),
contentComponent: accountParametersComponent contentComponent: accountParametersComponent
}, },
{ {
title: qsTr("Vos appareils"), //: "Vos appareils"
subTitle: qsTr("La liste des appareils connectés à votre compte. Vous pouvez retirer les appareils que vous nutilisez plus."), title: qsTr("manage_account_devices_title"),
//: "La liste des appareils connectés à votre compte. Vous pouvez retirer les appareils que vous nutilisez plus."
subTitle: qsTr("manage_account_devices_subtitle"),
contentComponent: accountDevicesComponent contentComponent: accountDevicesComponent
} }
] ]
@ -50,7 +54,8 @@ AbstractSettingsLayout {
icon.source: AppIcons.camera icon.source: AppIcons.camera
icon.width: Math.round(17 * DefaultStyle.dp) icon.width: Math.round(17 * DefaultStyle.dp)
icon.height: 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 style: ButtonStyle.noBackground
onClicked: fileDialog.open() onClicked: fileDialog.open()
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
@ -64,7 +69,8 @@ AbstractSettingsLayout {
icon.source: AppIcons.pencil icon.source: AppIcons.pencil
icon.width: Math.round(17 * DefaultStyle.dp) icon.width: Math.round(17 * DefaultStyle.dp)
icon.height: 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 style: ButtonStyle.noBackground
onClicked: fileDialog.open() onClicked: fileDialog.open()
} }
@ -73,7 +79,8 @@ AbstractSettingsLayout {
icon.source: AppIcons.trashCan icon.source: AppIcons.trashCan
icon.width: Math.round(17 * DefaultStyle.dp) icon.width: Math.round(17 * DefaultStyle.dp)
icon.height: 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 style: ButtonStyle.noBackground
onClicked: model.core.pictureUri = "" onClicked: model.core.pictureUri = ""
} }
@ -94,7 +101,7 @@ AbstractSettingsLayout {
spacing: Math.round(5 * DefaultStyle.dp) spacing: Math.round(5 * DefaultStyle.dp)
Text { Text {
Layout.alignment: Qt.AlignLeft Layout.alignment: Qt.AlignLeft
text: qsTr("Adresse SIP :") text: "%1 :".arg(qsTr("sip_address"))
color: DefaultStyle.main2_600 color: DefaultStyle.main2_600
font: Typography.p2l font: Typography.p2l
} }
@ -118,12 +125,14 @@ AbstractSettingsLayout {
spacing: Math.round(5 * DefaultStyle.dp) spacing: Math.round(5 * DefaultStyle.dp)
Layout.alignment: Qt.AlignLeft Layout.alignment: Qt.AlignLeft
Text { Text {
text: qsTr("Nom daffichage") //: "Nom d'affichage
text: qsTr("sip_address_display_name")
color: DefaultStyle.main2_600 color: DefaultStyle.main2_600
font: Typography.p2l font: Typography.p2l
} }
Text { 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 color: DefaultStyle.main2_600
font: Typography.p1 font: Typography.p1
} }
@ -140,7 +149,8 @@ AbstractSettingsLayout {
toValidate: true toValidate: true
} }
Text { Text {
text: qsTr("Indicatif international*") //: "Indicatif international*"
text: qsTr("manage_account_international_prefix")
color: DefaultStyle.main2_600 color: DefaultStyle.main2_600
font: Typography.p2l font: Typography.p2l
} }
@ -165,14 +175,16 @@ AbstractSettingsLayout {
ColumnLayout { ColumnLayout {
spacing : Math.round(5 * DefaultStyle.dp) spacing : Math.round(5 * DefaultStyle.dp)
Text { Text {
text: qsTr("Supprimer mon compte") //: "Déconnecter mon compte"
text: qsTr("manage_account_delete")
font: Typography.p2l font: Typography.p2l
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
color: DefaultStyle.danger_500main color: DefaultStyle.danger_500main
Layout.fillWidth: true Layout.fillWidth: true
} }
Text { 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 font: Typography.p1
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500main
@ -190,8 +202,10 @@ AbstractSettingsLayout {
onClicked: { onClicked: {
var mainWin = UtilsCpp.getMainWindow() var mainWin = UtilsCpp.getMainWindow()
mainWin.showConfirmationLambdaPopup("", mainWin.showConfirmationLambdaPopup("",
qsTr("Supprimer ") + (model.core.displayName.length > 0 ? model.core.displayName : qsTr("le compte")) + " ?", //: "Se déconnecter du 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."), 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) { function (confirmed) {
if (confirmed) { if (confirmed) {
account.core.removeAccount() account.core.removeAccount()
@ -247,7 +261,8 @@ AbstractSettingsLayout {
onDevicesSet: devices.loading = false; onDevicesSet: devices.loading = false;
onRequestError: (errorMessage) => { onRequestError: (errorMessage) => {
devices.loading = false; devices.loading = false;
mainWindow.showInformationPopup(qsTr("Erreur"), errorMessage, false) //: Erreur
mainWindow.showInformationPopup(qsTr("error"), errorMessage, false)
} }
} }
Control.Control { Control.Control {
@ -284,7 +299,8 @@ AbstractSettingsLayout {
} }
MediumButton { MediumButton {
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
text: qsTr("Supprimer") //: "Supprimer"
text: qsTr("manage_account_device_remove")
icon.source: AppIcons.trashCan icon.source: AppIcons.trashCan
icon.width: Math.round(16 * DefaultStyle.dp) icon.width: Math.round(16 * DefaultStyle.dp)
icon.height: Math.round(16 * DefaultStyle.dp) icon.height: Math.round(16 * DefaultStyle.dp)
@ -292,7 +308,8 @@ AbstractSettingsLayout {
onClicked: { onClicked: {
var mainWin = UtilsCpp.getMainWindow() var mainWin = UtilsCpp.getMainWindow()
mainWin.showConfirmationLambdaPopup("", mainWin.showConfirmationLambdaPopup("",
qsTr("Supprimer ") + modelData.core.deviceName + " ?", "", //:"Supprimer %1 ?"
qsTr("manage_account_device_remove_confirm_dialog").arg(modelData.core.deviceName), "",
function (confirmed) { function (confirmed) {
if (confirmed) { if (confirmed) {
accountDeviceProxy.deleteDevice(modelData) accountDeviceProxy.deleteDevice(modelData)
@ -305,7 +322,8 @@ AbstractSettingsLayout {
RowLayout { RowLayout {
spacing: Math.round(5 * DefaultStyle.dp) spacing: Math.round(5 * DefaultStyle.dp)
Text { Text {
text: qsTr("Dernière connexion:") //: "Dernière connexion:"
text: qsTr("manage_account_device_last_connection")
color: DefaultStyle.main2_600 color: DefaultStyle.main2_600
font: Typography.p2 font: Typography.p2
} }

View file

@ -11,11 +11,11 @@ AbstractSettingsLayout {
id: mainItem id: mainItem
width: parent?.width width: parent?.width
contentModel: [{ contentModel: [{
"title": qsTr("Paramètres"), "title": qsTr("settings_title"),
"subTitle": "", "subTitle": "",
"contentComponent": generalParametersComponent "contentComponent": generalParametersComponent
}, { }, {
"title": qsTr("Paramètres de compte"), "title": qsTr("settings_account_title"),
"subTitle": "", "subTitle": "",
"contentComponent": advancedParametersComponent "contentComponent": advancedParametersComponent
}] }]
@ -31,8 +31,9 @@ AbstractSettingsLayout {
function onIsSavedChanged() { function onIsSavedChanged() {
if (account.core.isSaved) if (account.core.isSaved)
UtilsCpp.showInformationPopup( UtilsCpp.showInformationPopup(
qsTr("Succès"), qsTr("information_popup_success_title"),
qsTr("Les changements ont été sauvegardés"), true, //: "Modifications sauvegardés"
qsTr("contact_editor_saved_changes_toast"), true,
mainWindow) mainWindow)
} }
} }
@ -48,7 +49,8 @@ AbstractSettingsLayout {
DecoratedTextField { DecoratedTextField {
propertyName: "mwiServerAddress" propertyName: "mwiServerAddress"
propertyOwnerGui: account 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 Layout.fillWidth: true
isValid: function (text) { isValid: function (text) {
return text.length == 0 || !text.endsWith(".") return text.length == 0 || !text.endsWith(".")
@ -58,7 +60,9 @@ AbstractSettingsLayout {
DecoratedTextField { DecoratedTextField {
propertyName: "voicemailAddress" propertyName: "voicemailAddress"
propertyOwnerGui: account propertyOwnerGui: account
title: qsTr("URI de messagerie vocale") //: "URI de messagerie vocale"
title: qsTr("account_settings_voicemail_uri_title")
Layout.fillWidth: true Layout.fillWidth: true
toValidate: true toValidate: true
} }
@ -73,7 +77,8 @@ AbstractSettingsLayout {
Layout.fillWidth: true Layout.fillWidth: true
spacing: Math.round(20 * DefaultStyle.dp) spacing: Math.round(20 * DefaultStyle.dp)
Text { Text {
text: qsTr("Transport") //: "Transport"
text: qsTr("account_settings_transport_title")
color: DefaultStyle.main2_600 color: DefaultStyle.main2_600
font: Typography.p2l font: Typography.p2l
} }
@ -86,13 +91,15 @@ AbstractSettingsLayout {
} }
DecoratedTextField { DecoratedTextField {
Layout.fillWidth: true Layout.fillWidth: true
title: qsTr("URL du serveur mandataire") //:"URL du serveur mandataire"
title: qsTr("account_settings_sip_proxy_url_title")
propertyName: "serverAddress" propertyName: "serverAddress"
propertyOwnerGui: account propertyOwnerGui: account
toValidate: true toValidate: true
} }
SwitchSetting { SwitchSetting {
titleText: qsTr("Serveur mandataire sortant") //: "Serveur mandataire sortant"
titleText: qsTr("account_settings_outbound_proxy_title")
propertyName: "outboundProxyEnabled" propertyName: "outboundProxyEnabled"
propertyOwnerGui: account propertyOwnerGui: account
} }
@ -100,21 +107,25 @@ AbstractSettingsLayout {
Layout.fillWidth: true Layout.fillWidth: true
propertyName: "stunServer" propertyName: "stunServer"
propertyOwnerGui: account propertyOwnerGui: account
title: qsTr("Adresse du serveur STUN") //: "Adresse du serveur STUN"
title: qsTr("account_settings_stun_server_url_title")
toValidate: true toValidate: true
} }
SwitchSetting { SwitchSetting {
titleText: qsTr("Activer ICE") //: "Activer ICE"
titleText: qsTr("account_settings_enable_ice_title")
propertyName: "iceEnabled" propertyName: "iceEnabled"
propertyOwnerGui: account propertyOwnerGui: account
} }
SwitchSetting { SwitchSetting {
titleText: qsTr("AVPF") //: "AVPF"
titleText: qsTr("account_settings_avpf_title")
propertyName: "avpfEnabled" propertyName: "avpfEnabled"
propertyOwnerGui: account propertyOwnerGui: account
} }
SwitchSetting { SwitchSetting {
titleText: qsTr("Mode bundle") //: "Mode bundle"
titleText: qsTr("account_settings_bundle_mode_title")
propertyName: "bundleModeEnabled" propertyName: "bundleModeEnabled"
propertyOwnerGui: account propertyOwnerGui: account
} }
@ -122,7 +133,8 @@ AbstractSettingsLayout {
Layout.fillWidth: true Layout.fillWidth: true
propertyName: "expire" propertyName: "expire"
propertyOwnerGui: account propertyOwnerGui: account
title: qsTr("Expiration (en seconde)") //: "Expiration (en seconde)"
title: qsTr("account_settings_expire_title")
canBeEmpty: false canBeEmpty: false
isValid: function (text) { isValid: function (text) {
return !isNaN(Number(text)) return !isNaN(Number(text))
@ -131,21 +143,24 @@ AbstractSettingsLayout {
} }
DecoratedTextField { DecoratedTextField {
Layout.fillWidth: true Layout.fillWidth: true
title: qsTr("URI de lusine à conversations") //: "URI du serveur de conversations"
title: qsTr("account_settings_conference_factory_uri_title")
propertyName: "conferenceFactoryAddress" propertyName: "conferenceFactoryAddress"
propertyOwnerGui: account propertyOwnerGui: account
toValidate: true toValidate: true
} }
DecoratedTextField { DecoratedTextField {
Layout.fillWidth: true Layout.fillWidth: true
title: qsTr("URI de lusine à réunions")
propertyName: "audioVideoConferenceFactoryAddress" propertyName: "audioVideoConferenceFactoryAddress"
//: "URI du serveur de réunions"
title: qsTr("account_settings_audio_video_conference_factory_uri_title")
propertyOwnerGui: account propertyOwnerGui: account
toValidate: true toValidate: true
} }
DecoratedTextField { DecoratedTextField {
Layout.fillWidth: true 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" propertyName: "limeServerUrl"
propertyOwnerGui: account propertyOwnerGui: account
toValidate: true toValidate: true

View file

@ -12,28 +12,33 @@ AbstractSettingsLayout {
width: parent?.width width: parent?.width
contentModel: [ contentModel: [
{ {
title: qsTr("Système"), //: "Système"
title: qsTr("settings_system_title"),
subTitle: "", subTitle: "",
contentComponent: systemComponent contentComponent: systemComponent
}, },
{ {
title: qsTr("Configuration distante"), //: "Configuration distante"
title: qsTr("settings_remote_provisioning_title"),
subTitle: "", subTitle: "",
contentComponent: remoteProvisioningComponent, contentComponent: remoteProvisioningComponent,
hideTopSeparator: true hideTopSeparator: true
}, },
{ {
title: qsTr("Sécurité / Chiffrement"), //: "Sécurité / Chiffrement"
title: qsTr("settings_security_title"),
subTitle: "", subTitle: "",
contentComponent: securityComponent, contentComponent: securityComponent,
}, },
{ {
title: qsTr("Codecs audio"), //: "Codecs audio"
title: qsTr("settings_advanced_audio_codecs_title"),
subTitle: "", subTitle: "",
contentComponent: audioCodecsComponent, contentComponent: audioCodecsComponent,
}, },
{ {
title: qsTr("Codecs vidéo"), //: "Codecs vidéo"
title: qsTr("settings_advanced_video_codecs_title"),
subTitle: "", subTitle: "",
contentComponent: videoCodecsComponent contentComponent: videoCodecsComponent
}, },
@ -58,7 +63,8 @@ AbstractSettingsLayout {
spacing: Math.round(40 * DefaultStyle.dp) spacing: Math.round(40 * DefaultStyle.dp)
SwitchSetting { SwitchSetting {
Layout.fillWidth: true Layout.fillWidth: true
titleText: qsTr("Démarrer automatiquement Linphone") //: "Démarrer automatiquement Linphone"
titleText: qsTr("settings_advanced_auto_start_title")
propertyName: "autoStart" propertyName: "autoStart"
propertyOwner: SettingsCpp propertyOwner: SettingsCpp
} }
@ -75,20 +81,23 @@ AbstractSettingsLayout {
DecoratedTextField { DecoratedTextField {
Layout.fillWidth: true Layout.fillWidth: true
id: configUri id: configUri
title: qsTr("URL de configuration distante") //: "URL de configuration distante"
title: qsTr("settings_advanced_remote_provisioning_url")
toValidate: true toValidate: true
} }
SmallButton { SmallButton {
Layout.topMargin: -Math.round(20 * DefaultStyle.dp) Layout.topMargin: -Math.round(20 * DefaultStyle.dp)
Layout.alignment: Qt.AlignRight 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 style: ButtonStyle.tertiary
onClicked: { onClicked: {
var url = configUri.value() var url = configUri.value()
if (UtilsCpp.isValidURL(url)) if (UtilsCpp.isValidURL(url))
UtilsCpp.useFetchConfig(configUri.value()) UtilsCpp.useFetchConfig(configUri.value())
else 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 { ColumnLayout {
spacing: Math.round(5 * DefaultStyle.dp) spacing: Math.round(5 * DefaultStyle.dp)
Text { Text {
text: qsTr("Chiffrement du média") //: "Chiffrement du média"
text: qsTr("settings_advanced_media_encryption_title")
font { font {
pixelSize: Typography.p2l.pixelSize pixelSize: Typography.p2l.pixelSize
weight: Typography.p2l.weight weight: Typography.p2l.weight
@ -118,7 +128,8 @@ AbstractSettingsLayout {
} }
SwitchSetting { SwitchSetting {
Layout.fillWidth: true 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" propertyName: "mediaEncryptionMandatory"
propertyOwner: SettingsCpp propertyOwner: SettingsCpp
} }
@ -213,7 +224,8 @@ AbstractSettingsLayout {
ColumnLayout { ColumnLayout {
spacing: Math.round(40 * DefaultStyle.dp) spacing: Math.round(40 * DefaultStyle.dp)
SwitchSetting { SwitchSetting {
titleText:qsTr("Cacher les FPS") //:"Cacher les FPS"
titleText:qsTr("settings_advanced_hide_fps_title")
propertyName: "hideFps" propertyName: "hideFps"
propertyOwner: SettingsCpp propertyOwner: SettingsCpp
} }

View file

@ -16,8 +16,10 @@ AbstractSettingsLayout {
contentComponent: genericParametersComponent contentComponent: genericParametersComponent
}, },
{ {
title: qsTr("Périphériques"), //: "Périphériques"
subTitle: qsTr("Vous pouvez modifier les périphériques de sortie audio, le microphone et la caméra de capture."), 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, contentComponent: multiMediaParametersComponent,
customWidth: 540, customWidth: 540,
customRightMargin: 36 customRightMargin: 36
@ -37,15 +39,17 @@ AbstractSettingsLayout {
ColumnLayout { ColumnLayout {
spacing: Math.round(20 * DefaultStyle.dp) spacing: Math.round(20 * DefaultStyle.dp)
SwitchSetting { SwitchSetting {
titleText: qsTr("Annulateur d'écho") //: "Annulateur d'écho"
subTitleText: qsTr("Évite que de l'écho soit entendu par votre correspondant") 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" propertyName: "echoCancellationEnabled"
propertyOwner: SettingsCpp propertyOwner: SettingsCpp
} }
SwitchSetting { SwitchSetting {
Layout.fillWidth: true Layout.fillWidth: true
titleText: qsTr("Activer lenregistrement automatique des appels") //: "Activer lenregistrement automatique des appels"
subTitleText: qsTr("Enregistrer tous les appels par défaut") titleText: qsTr("settings_calls_auto_record_title")
propertyName: "automaticallyRecordCallsEnabled" propertyName: "automaticallyRecordCallsEnabled"
propertyOwner: SettingsCpp propertyOwner: SettingsCpp
visible: !SettingsCpp.disableCallRecordings visible: !SettingsCpp.disableCallRecordings
@ -57,8 +61,8 @@ AbstractSettingsLayout {
propertyOwner: SettingsCpp propertyOwner: SettingsCpp
} }
SwitchSetting { SwitchSetting {
titleText: qsTr("Vidéo") //: "Autoriser la vidéo"
subTitleText: qsTr("Autoriser la vidéo") titleText: qsTr("settings_calls_enable_video_title")
propertyName: "videoEnabled" propertyName: "videoEnabled"
propertyOwner: SettingsCpp propertyOwner: SettingsCpp
} }

View file

@ -13,8 +13,10 @@ AbstractSettingsLayout {
width: parent?.width width: parent?.width
contentModel: [ contentModel: [
{ {
title: qsTr("Carnet d'adresse CardDAV"), //: Carnet d'adresse CardDAV
subTitle: qsTr("Ajouter un carnet dadresse CardDAV pour synchroniser vos contacts Linphone avec un carnet dadresse tiers."), title: qsTr("settings_contacts_carddav_title"),
//: "Ajouter un carnet dadresse CardDAV pour synchroniser vos contacts Linphone avec un carnet dadresse tiers."
subTitle: qsTr("settings_contacts_carddav_subtitle"),
contentComponent: cardDavParametersComponent contentComponent: cardDavParametersComponent
} }
] ]
@ -25,16 +27,19 @@ AbstractSettingsLayout {
if (carddavGui.core.isValid()) { if (carddavGui.core.isValid()) {
carddavGui.core.save() carddavGui.core.save()
} else { } 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 { Connections {
target: carddavGui.core target: carddavGui.core
function onSaved(success) { function onSaved(success) {
if (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 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 { Component {
@ -50,7 +55,8 @@ AbstractSettingsLayout {
onClicked: { onClicked: {
var mainWin = UtilsCpp.getMainWindow() var mainWin = UtilsCpp.getMainWindow()
mainWin.showConfirmationLambdaPopup("", mainWin.showConfirmationLambdaPopup("",
qsTr("Supprimer le carnet d'adresse CardDAV ?"), //: "Supprimer le carnet d'adresse CardDAV ?"
qsTr("settings_contacts_delete_carddav_server_title"),
"", "",
function (confirmed) { function (confirmed) {
if (confirmed) { if (confirmed) {
@ -75,7 +81,8 @@ AbstractSettingsLayout {
DecoratedTextField { DecoratedTextField {
propertyName: "displayName" propertyName: "displayName"
propertyOwnerGui: carddavGui propertyOwnerGui: carddavGui
title: qsTr("Nom daffichage") //: Nom d'affichage
title: qsTr("sip_address_display_name")
canBeEmpty: false canBeEmpty: false
toValidate: true toValidate: true
Layout.fillWidth: true Layout.fillWidth: true
@ -83,7 +90,8 @@ AbstractSettingsLayout {
DecoratedTextField { DecoratedTextField {
propertyName: "uri" propertyName: "uri"
propertyOwnerGui: carddavGui propertyOwnerGui: carddavGui
title: qsTr("URL du serveur") //: "URL du serveur"
title: qsTr("settings_contacts_carddav_server_url_title")
canBeEmpty: false canBeEmpty: false
toValidate: true toValidate: true
Layout.fillWidth: true Layout.fillWidth: true
@ -91,7 +99,7 @@ AbstractSettingsLayout {
DecoratedTextField { DecoratedTextField {
propertyName: "username" propertyName: "username"
propertyOwnerGui: carddavGui propertyOwnerGui: carddavGui
title: qsTr("Nom dutilisateur") title: qsTr("username")
toValidate: true toValidate: true
Layout.fillWidth: true Layout.fillWidth: true
} }
@ -99,19 +107,21 @@ AbstractSettingsLayout {
propertyName: "password" propertyName: "password"
hidden: true hidden: true
propertyOwnerGui: carddavGui propertyOwnerGui: carddavGui
title: qsTr("Mot de passe") title: qsTr("password")
toValidate: true toValidate: true
Layout.fillWidth: true Layout.fillWidth: true
} }
DecoratedTextField { DecoratedTextField {
propertyName: "realm" propertyName: "realm"
propertyOwnerGui: carddavGui propertyOwnerGui: carddavGui
title: qsTr("Domaine dauthentification") //: Domaine dauthentification
title: qsTr("settings_contacts_carddav_realm_title")
toValidate: true toValidate: true
Layout.fillWidth: true Layout.fillWidth: true
} }
SwitchSetting { 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" propertyName: "storeNewFriendsInIt"
propertyOwnerGui: carddavGui propertyOwnerGui: carddavGui
} }

View file

@ -10,14 +10,16 @@ AbstractSettingsLayout {
width: parent?.width width: parent?.width
contentModel: [ contentModel: [
{ {
title: qsTr("Annuaires LDAP"), //: Annuaires LDAP
subTitle: qsTr("Ajouter vos annuaires LDAP pour pouvoir effectuer des recherches dans la magic search bar."), 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, contentComponent: ldapParametersComponent,
hideTopMargin: true hideTopMargin: true
}, },
{ {
title: qsTr("Carnet d'adresse CardDAV"), title: qsTr("settings_contacts_carddav_title"),
subTitle: qsTr("Ajouter un carnet dadresse CardDAV pour synchroniser vos contacts Linphone avec un carnet dadresse tiers."), subTitle: qsTr("settings_contacts_carddav_subtitle"),
contentComponent: cardDavParametersComponent, contentComponent: cardDavParametersComponent,
hideTopMargin: true hideTopMargin: true
} }
@ -36,8 +38,10 @@ AbstractSettingsLayout {
Component { Component {
id: ldapParametersComponent id: ldapParametersComponent
ContactsSettingsProviderLayout { ContactsSettingsProviderLayout {
addText: qsTr("Ajouter un annuaire LDAP") //: "Ajouter un annuaire LDAP"
editText: qsTr("Modifier 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 {} proxyModel: LdapProxy {}
newItemGui: createGuiObject('Ldap') newItemGui: createGuiObject('Ldap')
settingsLayout: layoutUrl("LdapSettingsLayout") settingsLayout: layoutUrl("LdapSettingsLayout")
@ -61,8 +65,10 @@ AbstractSettingsLayout {
id: cardDavParametersComponent id: cardDavParametersComponent
ContactsSettingsProviderLayout { ContactsSettingsProviderLayout {
id: carddavProvider id: carddavProvider
addText: qsTr("Ajouter un carnet d'adresse CardDAV") //: "Ajouter un carnet d'adresse CardDAV"
editText: qsTr("Modifier 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 { proxyModel: CarddavProxy {
onModelReset: { onModelReset: {
carddavProvider.showAddButton = carddavProvider.proxyModel.count == 0 carddavProvider.showAddButton = carddavProvider.proxyModel.count == 0

View file

@ -89,7 +89,8 @@ RowLayout {
Connections { Connections {
target: modelData.core target: modelData.core
function onSavedChanged() { 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 { MediumButton {
Layout.alignment: Qt.AlignRight | Qt.AlignHCenter Layout.alignment: Qt.AlignRight | Qt.AlignHCenter
text: qsTr("Ajouter") //: "Ajouter"
text: qsTr("add")
style: ButtonStyle.main style: ButtonStyle.main
visible: mainItem.showAddButton visible: mainItem.showAddButton
onClicked: { onClicked: {

View file

@ -28,7 +28,8 @@ AbstractSettingsLayout {
Dialog { Dialog {
id: deleteLogs 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() onAccepted: SettingsCpp.cleanLogs()
} }
@ -38,10 +39,12 @@ AbstractSettingsLayout {
Dialog { Dialog {
id: shareLogs 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: [ buttons: [
BigButton { BigButton {
text: qsTr("Presse-papier") //: "Presse-papier"
text: qsTr("settings_debug_clipboard")
style: ButtonStyle.main style: ButtonStyle.main
onClicked: { onClicked: {
shareLogs.close() shareLogs.close()
@ -49,16 +52,20 @@ AbstractSettingsLayout {
} }
}, },
BigButton { BigButton {
text: qsTr("E-Mail") //: "E-Mail"
text: qsTr("settings_debug_email")
style: ButtonStyle.main style: ButtonStyle.main
onClicked: { onClicked: {
shareLogs.close() shareLogs.close()
if(!Qt.openUrlExternally( //: "Traces %1"
'mailto:' + encodeURIComponent(SettingsCpp.logsEmail) + if(!Qt.openUrlExternally("mailto:%1%2%3%4%5".arg(encodeURIComponent(SettingsCpp.logsEmail))
'?subject=' + encodeURIComponent(qsTr('Traces Linphone')) + .arg('?subject=').arg(encodeURIComponent(qsTr("debug_settings_trace").arg(applicationName)))
'&body=' + encodeURIComponent(mainItem.logsUrl) .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 { ColumnLayout {
spacing: Math.round(20 * DefaultStyle.dp) spacing: Math.round(20 * DefaultStyle.dp)
SwitchSetting { SwitchSetting {
titleText: qsTr("Activer les traces de débogage") //: "Activer les traces de débogage"
titleText: qsTr("settings_debug_enable_logs_title")
propertyName: "logsEnabled" propertyName: "logsEnabled"
propertyOwner: SettingsCpp propertyOwner: SettingsCpp
} }
SwitchSetting { 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" propertyName: "fullLogsEnabled"
propertyOwner: SettingsCpp propertyOwner: SettingsCpp
} }
@ -83,17 +92,20 @@ AbstractSettingsLayout {
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
MediumButton { MediumButton {
style: ButtonStyle.tertiary style: ButtonStyle.tertiary
text: qsTr("Supprimer les traces") //: "Supprimer les traces"
text: qsTr("settings_debug_delete_logs_title")
onClicked: { onClicked: {
deleteLogs.open() deleteLogs.open()
} }
} }
MediumButton { MediumButton {
style: ButtonStyle.tertiary style: ButtonStyle.tertiary
text: qsTr("Partager les traces") //: "Partager les traces"
text: qsTr("settings_debug_share_logs_title")
enabled: SettingsCpp.logsEnabled || SettingsCpp.fullLogsEnabled enabled: SettingsCpp.logsEnabled || SettingsCpp.fullLogsEnabled
onClicked: { 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() SettingsCpp.sendLogs()
} }
} }
@ -117,7 +129,8 @@ AbstractSettingsLayout {
} }
ColumnLayout { ColumnLayout {
Text { Text {
text: qsTr("Version de l'application") //: "Version de l'application"
text: qsTr("settings_debug_app_version_title")
font: Typography.p2l font: Typography.p2l
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
color: DefaultStyle.main2_600 color: DefaultStyle.main2_600
@ -145,7 +158,8 @@ AbstractSettingsLayout {
} }
ColumnLayout { ColumnLayout {
Text { Text {
text: qsTr("Version du SDK") //: "Version du SDK"
text: qsTr("settings_debug_sdk_version_title")
font: Typography.p2l font: Typography.p2l
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
color: DefaultStyle.main2_600 color: DefaultStyle.main2_600
@ -172,7 +186,9 @@ AbstractSettingsLayout {
mainItem.logsUrl = url mainItem.logsUrl = url
shareLogs.open() shareLogs.open()
} else { } 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)
} }
} }
} }

View file

@ -13,8 +13,8 @@ AbstractSettingsLayout {
width: parent?.width width: parent?.width
contentModel: [ contentModel: [
{ {
title: qsTr("Annuaires LDAP"), title: qsTr("settings_contacts_ldap_title"),
subTitle: qsTr("Ajouter vos annuaires LDAP pour pouvoir effectuer des recherches dans la magic search bar."), subTitle: qsTr("settings_contacts_ldap_subtitle"),
contentComponent: ldapParametersComponent contentComponent: ldapParametersComponent
} }
] ]
@ -26,9 +26,11 @@ AbstractSettingsLayout {
onSave: { onSave: {
if (ldapGui.core.isValid()) { if (ldapGui.core.isValid()) {
ldapGui.core.save() 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 { } 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: { onClicked: {
var mainWin = UtilsCpp.getMainWindow() var mainWin = UtilsCpp.getMainWindow()
mainWin.showConfirmationLambdaPopup("", mainWin.showConfirmationLambdaPopup("",
qsTr("Supprimer l'annuaire LDAP ?"), //: "Supprimer l'annuaire LDAP ?"
qsTr("settings_contacts_ldap_delete_confirmation_message"),
"", "",
function (confirmed) { function (confirmed) {
if (confirmed) { if (confirmed) {
@ -71,14 +74,16 @@ AbstractSettingsLayout {
id: server id: server
propertyName: "serverUrl" propertyName: "serverUrl"
propertyOwnerGui: ldapGui 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 toValidate: true
Layout.fillWidth: true Layout.fillWidth: true
} }
DecoratedTextField { DecoratedTextField {
propertyName: "bindDn" propertyName: "bindDn"
propertyOwnerGui: ldapGui propertyOwnerGui: ldapGui
title: qsTr("Bind DN") //: "Bind DN"
title: qsTr("settings_contacts_ldap_bind_dn_title")
toValidate: true toValidate: true
Layout.fillWidth: true Layout.fillWidth: true
} }
@ -86,26 +91,30 @@ AbstractSettingsLayout {
propertyName: "password" propertyName: "password"
hidden: true hidden: true
propertyOwnerGui: ldapGui propertyOwnerGui: ldapGui
title: qsTr("Mot de passe") //: "Mot de passe"
title: qsTr("settings_contacts_ldap_password_title")
toValidate: true toValidate: true
Layout.fillWidth: true Layout.fillWidth: true
} }
SwitchSetting { SwitchSetting {
titleText: qsTr("Utiliser TLS") //: "Utiliser TLS"
titleText: qsTr("settings_contacts_ldap_use_tls_title")
propertyName: "tls" propertyName: "tls"
propertyOwnerGui: ldapGui propertyOwnerGui: ldapGui
} }
DecoratedTextField { DecoratedTextField {
propertyName: "baseObject" propertyName: "baseObject"
propertyOwnerGui: ldapGui 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 toValidate: true
Layout.fillWidth: true Layout.fillWidth: true
} }
DecoratedTextField { DecoratedTextField {
propertyName: "filter" propertyName: "filter"
propertyOwnerGui: ldapGui propertyOwnerGui: ldapGui
title: qsTr("Filtre") //: "Filtre"
title: qsTr("settings_contacts_ldap_search_filter_title")
toValidate: true toValidate: true
Layout.fillWidth: true Layout.fillWidth: true
} }
@ -113,7 +122,8 @@ AbstractSettingsLayout {
propertyName: "limit" propertyName: "limit"
propertyOwnerGui: ldapGui propertyOwnerGui: ldapGui
validator: RegularExpressionValidator { regularExpression: /[0-9]+/ } 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 toValidate: true
Layout.fillWidth: true Layout.fillWidth: true
} }
@ -121,14 +131,16 @@ AbstractSettingsLayout {
propertyName: "delay" propertyName: "delay"
propertyOwnerGui: ldapGui propertyOwnerGui: ldapGui
validator: RegularExpressionValidator { regularExpression: /[0-9]+/ } 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 toValidate: true
Layout.fillWidth: true Layout.fillWidth: true
} }
DecoratedTextField { DecoratedTextField {
propertyName: "timeout" propertyName: "timeout"
propertyOwnerGui: ldapGui 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]+/ } validator: RegularExpressionValidator { regularExpression: /[0-9]+/ }
toValidate: true toValidate: true
Layout.fillWidth: true Layout.fillWidth: true
@ -136,7 +148,8 @@ AbstractSettingsLayout {
DecoratedTextField { DecoratedTextField {
propertyName: "minCharacters" propertyName: "minCharacters"
propertyOwnerGui: ldapGui 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]+/ } validator: RegularExpressionValidator { regularExpression: /[0-9]+/ }
toValidate: true toValidate: true
Layout.fillWidth: true Layout.fillWidth: true
@ -144,26 +157,30 @@ AbstractSettingsLayout {
DecoratedTextField { DecoratedTextField {
propertyName: "nameAttribute" propertyName: "nameAttribute"
propertyOwnerGui: ldapGui propertyOwnerGui: ldapGui
title: qsTr("Attributs de nom") //: "Attributs de nom"
title: qsTr("settings_contacts_ldap_name_attributes_title")
toValidate: true toValidate: true
Layout.fillWidth: true Layout.fillWidth: true
} }
DecoratedTextField { DecoratedTextField {
propertyName: "sipAttribute" propertyName: "sipAttribute"
propertyOwnerGui: ldapGui propertyOwnerGui: ldapGui
title: qsTr("Attributs SIP") //: "Attributs SIP"
title: qsTr("settings_contacts_ldap_sip_attributes_title")
toValidate: true toValidate: true
Layout.fillWidth: true Layout.fillWidth: true
} }
DecoratedTextField { DecoratedTextField {
propertyName: "sipDomain" propertyName: "sipDomain"
propertyOwnerGui: ldapGui propertyOwnerGui: ldapGui
title: qsTr("Domaine SIP") //: "Domaine SIP"
title: qsTr("settings_contacts_ldap_sip_domain_title")
toValidate: true toValidate: true
Layout.fillWidth: true Layout.fillWidth: true
} }
SwitchSetting { SwitchSetting {
titleText: qsTr("Débogage") //: "Débogage"
titleText: qsTr("settings_contacts_ldap_debug_title")
propertyName: "debug" propertyName: "debug"
propertyOwnerGui: ldapGui propertyOwnerGui: ldapGui
} }

View file

@ -11,7 +11,8 @@ AbstractSettingsLayout {
width: parent?.width width: parent?.width
contentModel: [ contentModel: [
{ {
title: qsTr("Affichage"), //: "Affichage"
title: qsTr("settings_meetings_display_title"),
subTitle: "", subTitle: "",
contentComponent: confDisplayParametersComponent, contentComponent: confDisplayParametersComponent,
hideTopMargin: true hideTopMargin: true
@ -28,14 +29,16 @@ AbstractSettingsLayout {
ColumnLayout { ColumnLayout {
spacing: Math.round(5 * DefaultStyle.dp) spacing: Math.round(5 * DefaultStyle.dp)
Text { Text {
text: qsTr("Mode daffichage par défaut") //: "Mode daffichage par défaut"
text: qsTr("settings_meetings_default_layout_title")
font { font {
pixelSize: Typography.p2l.pixelSize pixelSize: Typography.p2l.pixelSize
weight: Typography.p2l.weight weight: Typography.p2l.weight
} }
} }
Text { Text {
text: qsTr("Le mode daffichage des participants en réunions") //: "Le mode daffichage des participants en réunions"
text: qsTr("settings_meetings_default_layout_subtitle")
font { font {
pixelSize: Typography.p1.pixelSize pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight weight: Typography.p1.weight

View file

@ -10,7 +10,8 @@ AbstractSettingsLayout {
width: parent?.width width: parent?.width
contentModel: [ contentModel: [
{ {
title: qsTr("Réseau"), //: "Réseau"
title: qsTr("settings_network_title"),
subTitle: "", subTitle: "",
contentComponent: content contentComponent: content
} }
@ -26,7 +27,8 @@ AbstractSettingsLayout {
spacing: Math.round(40 * DefaultStyle.dp) spacing: Math.round(40 * DefaultStyle.dp)
SwitchSetting { SwitchSetting {
Layout.fillWidth: true Layout.fillWidth: true
titleText: qsTr("Autoriser l'IPv6") //: "Autoriser l'IPv6"
titleText: qsTr("settings_network_allow_ipv6")
propertyName: "ipv6Enabled" propertyName: "ipv6Enabled"
propertyOwner: SettingsCpp propertyOwner: SettingsCpp
} }

View file

@ -25,8 +25,10 @@ AbstractSettingsLayout {
ColumnLayout { ColumnLayout {
spacing: Math.round(40 * DefaultStyle.dp) spacing: Math.round(40 * DefaultStyle.dp)
SwitchSetting { SwitchSetting {
titleText: qsTr("Chiffrer tous les fichiers") //: "Chiffrer tous les fichiers"
subTitleText: qsTr("Attention, vous ne pourrez pas revenir en arrière !") 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" propertyName: "vfsEnabled"
propertyOwner: SettingsCpp propertyOwner: SettingsCpp
} }

View file

@ -11,17 +11,14 @@ import SettingsCpp
Item { Item {
id: mainItem id: mainItem
width: Math.round(517 * DefaultStyle.dp) 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) readonly property real spacing: Math.round(16 * DefaultStyle.dp)
property AccountProxy accountProxy property AccountProxy accountProxy
signal addAccountRequest() 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{ ColumnLayout{
id: childLayout id: childLayout
anchors.top: parent.top anchors.top: parent.top

View file

@ -10,8 +10,10 @@ import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
AbstractMainPage { AbstractMainPage {
id: mainItem id: mainItem
noItemButtonText: qsTr("Nouvel appel") //: "Nouvel appel"
emptyListText: qsTr("Historique d'appel vide") noItemButtonText: qsTr("history_call_start_title")
//: "Historique d'appel vide"
emptyListText: qsTr("call_history_empty_title")
newItemIconSource: AppIcons.newCall newItemIconSource: AppIcons.newCall
property var selectedRowHistoryGui property var selectedRowHistoryGui
@ -79,14 +81,19 @@ AbstractMainPage {
Dialog { Dialog {
id: deleteHistoryPopup id: deleteHistoryPopup
width: Math.round(278 * DefaultStyle.dp) width: Math.round(637 * DefaultStyle.dp)
text: qsTr("L'historique d'appel sera supprimé. Souhaitez-vous continuer ?") //: 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 { Dialog {
id: deleteForUserPopup id: deleteForUserPopup
width: Math.round(278 * DefaultStyle.dp) width: Math.round(637 * DefaultStyle.dp)
text: qsTr( //: Supprimer l'historique d\'appels ?
"L'historique d'appel de l'utilisateur sera supprimé. Souhaitez-vous continuer ?") 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 { leftPanelContent: Item {
@ -118,7 +125,6 @@ AbstractMainPage {
visible: false visible: false
onLaunchCall: { onLaunchCall: {
mainItem.createCallFromSearchBarRequested() mainItem.createCallFromSearchBarRequested()
// TODO : auto completion instead of sip linphone
} }
} }
} }
@ -136,7 +142,9 @@ AbstractMainPage {
id: titleCallLayout id: titleCallLayout
spacing: Math.round(16 * DefaultStyle.dp) spacing: Math.round(16 * DefaultStyle.dp)
Text { Text {
text: qsTr("Appels") Layout.fillWidth: true
//: "Appels"
text: qsTr("call_history_call_list_title")
color: DefaultStyle.main2_700 color: DefaultStyle.main2_700
font.pixelSize: Typography.h2.pixelSize font.pixelSize: Typography.h2.pixelSize
font.weight: Typography.h2.weight font.weight: Typography.h2.weight
@ -156,7 +164,8 @@ AbstractMainPage {
IconLabelButton { IconLabelButton {
Layout.fillWidth: true Layout.fillWidth: true
focus: visible focus: visible
text: qsTr("Supprimer l'historique") //: "Supprimer l'historique"
text: qsTr("menu_delete_history")
icon.source: AppIcons.trashCan icon.source: AppIcons.trashCan
style: ButtonStyle.hoveredBackgroundRed style: ButtonStyle.hoveredBackgroundRed
onClicked: { onClicked: {
@ -195,7 +204,8 @@ AbstractMainPage {
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: Math.round(18 * DefaultStyle.dp) Layout.topMargin: Math.round(18 * DefaultStyle.dp)
Layout.rightMargin: Math.round(39 * 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 visible: historyListView.count !== 0 || text.length !== 0
focus: true focus: true
KeyNavigation.up: newCallButton KeyNavigation.up: newCallButton
@ -221,8 +231,9 @@ AbstractMainPage {
visible: historyListView.count === 0 visible: historyListView.count === 0
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
Layout.topMargin: Math.round(137 * DefaultStyle.dp) Layout.topMargin: Math.round(137 * DefaultStyle.dp)
text: qsTr("Aucun appel%1").arg( //: "Aucun appel dans votre historique"
searchBar.text.length != 0 ? " correspondant" : "") //: "Aucun résultat"
text: searchBar.text.length != 0 ? qsTr("list_filter_no_result_found") : qsTr("history_list_empty_history")
font { font {
pixelSize: Typography.h4.pixelSize pixelSize: Typography.h4.pixelSize
weight: Typography.h4.weight weight: Typography.h4.weight
@ -297,7 +308,9 @@ AbstractMainPage {
} }
} }
Text { Text {
text: qsTr("Nouvel appel") Layout.fillWidth: true
//: "Nouvel appel"
text: qsTr("call_action_start_new_call")
color: DefaultStyle.main2_700 color: DefaultStyle.main2_700
font.pixelSize: Typography.h2.pixelSize font.pixelSize: Typography.h2.pixelSize
font.weight: Typography.h2.weight font.weight: Typography.h2.weight
@ -364,7 +377,8 @@ AbstractMainPage {
ColumnLayout { ColumnLayout {
spacing: Math.round(3 * DefaultStyle.dp) spacing: Math.round(3 * DefaultStyle.dp)
Text { Text {
text: qsTr("Appel de groupe") //: "Appel de groupe"
text: qsTr("call_start_group_call_title")
color: DefaultStyle.main1_500_main color: DefaultStyle.main1_500_main
maximumLineCount: 1 maximumLineCount: 1
font { font {
@ -374,9 +388,8 @@ AbstractMainPage {
Layout.fillWidth: true Layout.fillWidth: true
} }
Text { Text {
text: qsTr("%1 participant%2 sélectionné").arg( //: "%n participant(s) sélectionné(s)"
mainItem.selectedParticipantsCount).arg( text: qsTr("group_call_participant_selected").arg(mainItem.selectedParticipantsCount)
mainItem.selectedParticipantsCount > 1 ? "s" : "")
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500main
maximumLineCount: 1 maximumLineCount: 1
font { font {
@ -390,7 +403,8 @@ AbstractMainPage {
id: groupCallButton id: groupCallButton
enabled: mainItem.selectedParticipantsCount.length != 0 enabled: mainItem.selectedParticipantsCount.length != 0
Layout.rightMargin: Math.round(21 * DefaultStyle.dp) Layout.rightMargin: Math.round(21 * DefaultStyle.dp)
text: qsTr("Lancer") //: "Lancer"
text: qsTr("call_action_start_group_call")
style: ButtonStyle.main style: ButtonStyle.main
KeyNavigation.down: listStackView KeyNavigation.down: listStackView
KeyNavigation.left: backGroupCallButton KeyNavigation.left: backGroupCallButton
@ -407,7 +421,8 @@ AbstractMainPage {
Text { Text {
font.pixelSize: Typography.p2.pixelSize font.pixelSize: Typography.p2.pixelSize
font.weight: Typography.p2.weight font.weight: Typography.p2.weight
text: qsTr("Nom du groupe") //: "Nom du groupe"
text: qsTr("history_group_call_start_dialog_subject_hint")
} }
Item { Item {
Layout.fillWidth: true Layout.fillWidth: true
@ -415,7 +430,8 @@ AbstractMainPage {
Text { Text {
font.pixelSize: Math.round(12 * DefaultStyle.dp) font.pixelSize: Math.round(12 * DefaultStyle.dp)
font.weight: Math.round(300 * DefaultStyle.dp) font.weight: Math.round(300 * DefaultStyle.dp)
text: qsTr("Requis") //: "Requis"
text: qsTr("required")
} }
} }
TextField { TextField {
@ -438,14 +454,15 @@ AbstractMainPage {
target: mainItem target: mainItem
function onStartGroupCallRequested() { function onStartGroupCallRequested() {
if (groupCallName.text.length === 0) { if (groupCallName.text.length === 0) {
UtilsCpp.showInformationPopup( UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
qsTr("Erreur"), qsTr( //: "Un nom doit être donné à l'appel de groupe
"Un nom doit être donné à l'appel de groupe"), qsTr("group_call_error_must_have_name"),
false) false)
} else if (!mainItem.isRegistered) { } else if (!mainItem.isRegistered) {
UtilsCpp.showInformationPopup( UtilsCpp.showInformationPopup(
qsTr("Erreur"), qsTr("information_popup_error_title"),
qsTr("Vous n'etes pas connecté"), //: "Vous n'etes pas connecté"
qsTr("group_call_error_not_connected"),
false) false)
} else { } else {
mainItem.confInfoGui = Qt.createQmlObject( mainItem.confInfoGui = Qt.createQmlObject(
@ -515,8 +532,10 @@ ConferenceInfoGui{
|| false || false
property bool isCardDAV: contactDetail.contact?.core?.isCardDAV property bool isCardDAV: contactDetail.contact?.core?.isCardDAV
|| false || false
text: contactDetail.contact ? qsTr("Voir le contact") : qsTr( //: "Voir le contact"
"Ajouter aux contacts") text: contactDetail.contact ? qsTr("menu_see_existing_contact") :
//: "Ajouter aux contacts"
qsTr("menu_add_address_to_contacts")
icon.source: AppIcons.plusCircle icon.source: AppIcons.plusCircle
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp)
icon.height: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp)
@ -534,7 +553,8 @@ ConferenceInfoGui{
} }
IconLabelButton { IconLabelButton {
Layout.fillWidth: true Layout.fillWidth: true
text: qsTr("Copier l'adresse SIP") //: "Copier l'adresse SIP"
text: qsTr("menu_copy_sip_address")
icon.source: AppIcons.copy icon.source: AppIcons.copy
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp)
icon.height: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp)
@ -545,13 +565,16 @@ ConferenceInfoGui{
&& mainItem.selectedRowHistoryGui.core.remoteAddress) && mainItem.selectedRowHistoryGui.core.remoteAddress)
if (success) if (success)
UtilsCpp.showInformationPopup( UtilsCpp.showInformationPopup(
qsTr("Copié"), qsTr( //: Adresse copiée
"L'adresse a été copiée dans le presse-papier"), qsTr("sip_address_copied_to_clipboard_toast"),
//: L'adresse a été copié dans le presse_papiers
qsTr("sip_address_copied_to_clipboard_message"),
true) true)
else else
UtilsCpp.showInformationPopup( UtilsCpp.showInformationPopup(
qsTr("Erreur"), qsTr( qsTr("information_popup_error_title"),
"Erreur lors de la copie de l'adresse"), //: "Erreur lors de la copie de l'adresse"
qsTr("sip_address_copy_to_clipboard_error"),
false) false)
} }
} }
@ -572,7 +595,8 @@ ConferenceInfoGui{
IconLabelButton { IconLabelButton {
Layout.fillWidth: true Layout.fillWidth: true
text: qsTr("Supprimer l'historique") //: "Supprimer l'historique"
text: qsTr("menu_delete_history")
icon.source: AppIcons.trashCan icon.source: AppIcons.trashCan
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp)
icon.height: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp)
@ -647,7 +671,13 @@ ConferenceInfoGui{
} }
} }
Text { 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 { font {
pixelSize: Typography.p1.pixelSize pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight weight: Typography.p1.weight

View file

@ -93,7 +93,8 @@ RowLayout {
spacing: 0 spacing: 0
Text { Text {
Layout.fillWidth: true Layout.fillWidth: true
text: qsTr("Participer à :") //: Participer à :
text: qsTr("meeting_waiting_room_title")
color: DefaultStyle.grey_0 color: DefaultStyle.grey_0
font { font {
pixelSize: Math.round(30 * DefaultStyle.dp) pixelSize: Math.round(30 * DefaultStyle.dp)
@ -114,7 +115,8 @@ RowLayout {
spacing: Math.round(5 * DefaultStyle.dp) spacing: Math.round(5 * DefaultStyle.dp)
BigButton { BigButton {
Layout.preferredWidth: Math.round(292 * DefaultStyle.dp) Layout.preferredWidth: Math.round(292 * DefaultStyle.dp)
text: qsTr("Rejoindre") //: "Rejoindre"
text: qsTr("meeting_waiting_room_join")
style: ButtonStyle.main style: ButtonStyle.main
onClicked: { onClicked: {
settingsButton.checked = false settingsButton.checked = false
@ -125,7 +127,7 @@ RowLayout {
BigButton { BigButton {
Layout.preferredWidth: Math.round(292 * DefaultStyle.dp) Layout.preferredWidth: Math.round(292 * DefaultStyle.dp)
style: ButtonStyle.secondary style: ButtonStyle.secondary
text: qsTr("Annuler") text: qsTr("cancel")
onClicked: { onClicked: {
mainItem.cancelJoiningRequested() mainItem.cancelJoiningRequested()
} }
@ -138,7 +140,8 @@ RowLayout {
spacing: Math.round(13 * DefaultStyle.dp) spacing: Math.round(13 * DefaultStyle.dp)
Text { Text {
Layout.fillWidth: true Layout.fillWidth: true
text: qsTr("Connexion à la réunion") //: "Connexion à la réunion"
text: qsTr("meeting_waiting_room_joining_title")
color: DefaultStyle.grey_0 color: DefaultStyle.grey_0
font { font {
pixelSize: Math.round(30 * DefaultStyle.dp) pixelSize: Math.round(30 * DefaultStyle.dp)
@ -147,7 +150,8 @@ RowLayout {
} }
Text { Text {
Layout.fillWidth: true 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 color: DefaultStyle.grey_0
font { font {
pixelSize: Typography.p1.pixelSize pixelSize: Typography.p1.pixelSize
@ -165,7 +169,7 @@ RowLayout {
Layout.preferredWidth: Math.round(292 * DefaultStyle.dp) Layout.preferredWidth: Math.round(292 * DefaultStyle.dp)
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
style: ButtonStyle.main style: ButtonStyle.main
text: qsTr("Annuler") text: qsTr("cancel")
onClicked: { onClicked: {
settingsButton.checked = false settingsButton.checked = false
stackLayout.currentIndex = 1 stackLayout.currentIndex = 1

View file

@ -10,8 +10,10 @@ import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
AbstractMainPage { AbstractMainPage {
id: mainItem id: mainItem
noItemButtonText: qsTr("Ajouter un contact") //: "Ajouter un contact"
emptyListText: qsTr("Aucun contact pour le moment") noItemButtonText: qsTr("contacts_add")
//: "Aucun contact pour le moment"
emptyListText: qsTr("contacts_list_empty")
newItemIconSource: AppIcons.plusCircle newItemIconSource: AppIcons.plusCircle
// disable left panel contact list interaction while a contact is being edited // disable left panel contact list interaction while a contact is being edited
@ -69,16 +71,19 @@ FriendGui{
|| rightPanelStackView.currentItem.objectName != "contactEdition") || rightPanelStackView.currentItem.objectName != "contactEdition")
rightPanelStackView.push(contactEdition, { rightPanelStackView.push(contactEdition, {
"contact": friendGui, "contact": friendGui,
"title": qsTr("Nouveau contact"), //: "Nouveau contact"
"saveButtonText": qsTr("Créer") "title": qsTr("contact_new_title"),
// "Créer"
"saveButtonText": qsTr("create")
}) })
} }
function editContact(friendGui) { function editContact(friendGui) {
rightPanelStackView.push(contactEdition, { rightPanelStackView.push(contactEdition, {
"contact": friendGui, "contact": friendGui,
"title": qsTr("Modifier contact"), //: "Modifier contact"
"saveButtonText": qsTr("Enregistrer") "title": qsTr("contact_edit_title"),
"saveButtonText": qsTr("save")
}) })
} }
@ -91,16 +96,19 @@ FriendGui{
return return
var mainWin = UtilsCpp.getMainWindow() var mainWin = UtilsCpp.getMainWindow()
mainWin.showConfirmationLambdaPopup( mainWin.showConfirmationLambdaPopup(
"", qsTr( //: Supprimer %1 ?"
"%1 sera supprimé des contacts. Voulez-vous continuer ?").arg( qsTr("contact_dialog_delete_title").arg(contact.core.fullName),
contact.core.fullName), "", function (confirmed) { //: Ce contact sera définitivement supprimé.
qsTr("contact_dialog_delete_message"), "", function (confirmed) {
if (confirmed) { if (confirmed) {
var name = contact.core.fullName var name = contact.core.fullName
contact.core.remove() contact.core.remove()
contactList.resetSelections() contactList.resetSelections()
UtilsCpp.showInformationPopup( UtilsCpp.showInformationPopup(
qsTr("Supprimé"), //: "Contact supprimé"
qsTr("%1 a été supprimé").arg(name)) qsTr("contact_deleted_toast"),
//: "%1 a été supprimé"
qsTr("contact_deleted_message").arg(name))
} }
}) })
} }
@ -115,9 +123,10 @@ FriendGui{
closePolicy: Control.Popup.CloseOnEscape closePolicy: Control.Popup.CloseOnEscape
modal: true modal: true
onAboutToHide: neverDisplayAgainCheckbox.checked = false onAboutToHide: neverDisplayAgainCheckbox.checked = false
title: qsTr("Augmenter la confiance") //: "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.<br><br>Vous êtes sur le point dappeler “%1” voulez vous continuer ?").arg( title: qsTr("contact_dialog_devices_trust_popup_title")
verifyDevicePopup.deviceName) //: "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 dappeler %1 voulez vous continuer ?"
text: qsTr("contact_dialog_devices_trust_popup_message").arg(verifyDevicePopup.deviceName)
buttons: RowLayout { buttons: RowLayout {
RowLayout { RowLayout {
spacing: Math.round(7 * DefaultStyle.dp) spacing: Math.round(7 * DefaultStyle.dp)
@ -125,7 +134,8 @@ FriendGui{
id: neverDisplayAgainCheckbox id: neverDisplayAgainCheckbox
} }
Text { Text {
text: qsTr("Ne plus afficher") //: Ne plus afficher
text: qsTr("popup_do_not_show_again")
font.pixelSize: Math.round(14 * DefaultStyle.dp) font.pixelSize: Math.round(14 * DefaultStyle.dp)
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
@ -140,12 +150,13 @@ FriendGui{
spacing: Math.round(15 * DefaultStyle.dp) spacing: Math.round(15 * DefaultStyle.dp)
BigButton { BigButton {
style: ButtonStyle.secondary style: ButtonStyle.secondary
text: qsTr("Annuler") text: qsTr("cancel")
onClicked: verifyDevicePopup.close() onClicked: verifyDevicePopup.close()
} }
BigButton { BigButton {
style: ButtonStyle.main style: ButtonStyle.main
text: qsTr("Appeler") //: "Appeler"
text: qsTr("dialog_call")
onClicked: { onClicked: {
SettingsCpp.setDisplayDeviceCheckConfirmation( SettingsCpp.setDisplayDeviceCheckConfirmation(
!neverDisplayAgainCheckbox.checked) !neverDisplayAgainCheckbox.checked)
@ -161,8 +172,10 @@ FriendGui{
Dialog { Dialog {
id: trustInfoDialog id: trustInfoDialog
width: Math.round(637 * DefaultStyle.dp) width: Math.round(637 * DefaultStyle.dp)
title: qsTr("Niveau de confiance") //: "Niveau de confiance"
text: qsTr("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.") 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. <br>Quand tous seront vérifiés, vous atteindrez le niveau de confiance maximal."
text: qsTr("contact_dialog_devices_trust_help_message")
content: RowLayout { content: RowLayout {
spacing: Math.round(50 * DefaultStyle.dp) spacing: Math.round(50 * DefaultStyle.dp)
Avatar { Avatar {
@ -184,7 +197,8 @@ FriendGui{
} }
} }
buttons: Button { buttons: Button {
text: qsTr("Ok") //: "Ok"
text: qsTr("dialog_ok")
style: ButtonStyle.main style: ButtonStyle.main
leftPadding: Math.round(30 * DefaultStyle.dp) leftPadding: Math.round(30 * DefaultStyle.dp)
rightPadding: Math.round(30 * DefaultStyle.dp) rightPadding: Math.round(30 * DefaultStyle.dp)
@ -209,7 +223,8 @@ FriendGui{
anchors.rightMargin: leftPanel.rightMargin anchors.rightMargin: leftPanel.rightMargin
Text { Text {
text: qsTr("Contacts") //: "Contacts"
text: qsTr("bottom_navigation_contacts_label")
color: DefaultStyle.main2_700 color: DefaultStyle.main2_700
font.pixelSize: Typography.h2.pixelSize font.pixelSize: Typography.h2.pixelSize
font.weight: Typography.h2.weight font.weight: Typography.h2.weight
@ -248,7 +263,8 @@ FriendGui{
Layout.rightMargin: leftPanel.rightMargin Layout.rightMargin: leftPanel.rightMargin
Layout.topMargin: Math.round(18 * DefaultStyle.dp) Layout.topMargin: Math.round(18 * DefaultStyle.dp)
Layout.fillWidth: true Layout.fillWidth: true
placeholderText: qsTr("Rechercher un contact") //: Rechercher un contact
placeholderText: qsTr("search_bar_look_for_contact_text")
KeyNavigation.up: createContactButton KeyNavigation.up: createContactButton
KeyNavigation.down: contactList KeyNavigation.down: contactList
} }
@ -259,8 +275,10 @@ FriendGui{
visible: !contactList.loading && !contactList.haveContacts visible: !contactList.loading && !contactList.haveContacts
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
Layout.topMargin: Math.round(137 * DefaultStyle.dp) Layout.topMargin: Math.round(137 * DefaultStyle.dp)
text: qsTr("Aucun contact%1").arg( //: Aucun résultat
searchBar.text.length !== 0 ? " correspondant" : "") text: searchBar.text.length !== 0 ? qsTr("list_filter_no_result_found")
//: Aucun contact pour le moment
: qsTr("contact_list_empty")
font { font {
pixelSize: Typography.h4.pixelSize pixelSize: Typography.h4.pixelSize
weight: Typography.h4.weight weight: Typography.h4.weight
@ -352,7 +370,7 @@ FriendGui{
anchors.fill: parent anchors.fill: parent
contact: mainItem.selectedContact contact: mainItem.selectedContact
button.color: DefaultStyle.main1_100 button.color: DefaultStyle.main1_100
button.text: qsTr("Modifier") button.text: qsTr("contact_details_edit")
button.style: ButtonStyle.tertiary button.style: ButtonStyle.tertiary
button.icon.source: AppIcons.pencil button.icon.source: AppIcons.pencil
button.onClicked: mainItem.editContact(mainItem.selectedContact) button.onClicked: mainItem.editContact(mainItem.selectedContact)
@ -388,7 +406,8 @@ FriendGui{
spacing: Math.round(58 * DefaultStyle.dp) spacing: Math.round(58 * DefaultStyle.dp)
LabelButton { LabelButton {
button.icon.source: AppIcons.phone button.icon.source: AppIcons.phone
label: qsTr("Appel") //: "Appel"
label: qsTr("contact_call_action")
width: Math.round(56 * DefaultStyle.dp) width: Math.round(56 * DefaultStyle.dp)
height: Math.round(56 * DefaultStyle.dp) height: Math.round(56 * DefaultStyle.dp)
button.icon.width: Math.round(24 * DefaultStyle.dp) button.icon.width: Math.round(24 * DefaultStyle.dp)
@ -400,7 +419,8 @@ FriendGui{
LabelButton { LabelButton {
button.icon.source: AppIcons.chatTeardropText button.icon.source: AppIcons.chatTeardropText
visible: !SettingsCpp.disableChatFeature visible: !SettingsCpp.disableChatFeature
label: qsTr("Message") //: "Message"
label: qsTr("contact_message_action")
width: Math.round(56 * DefaultStyle.dp) width: Math.round(56 * DefaultStyle.dp)
height: Math.round(56 * DefaultStyle.dp) height: Math.round(56 * DefaultStyle.dp)
button.icon.width: Math.round(24 * DefaultStyle.dp) button.icon.width: Math.round(24 * DefaultStyle.dp)
@ -411,7 +431,8 @@ FriendGui{
LabelButton { LabelButton {
visible: SettingsCpp.videoEnabled visible: SettingsCpp.videoEnabled
button.icon.source: AppIcons.videoCamera 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) width: Math.round(56 * DefaultStyle.dp)
height: Math.round(56 * DefaultStyle.dp) height: Math.round(56 * DefaultStyle.dp)
button.icon.width: Math.round(24 * 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 property var mode: contactDetail.contact ? contactDetail.contact.core.consolidatedPresence : -1
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft
Layout.fillWidth: true 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") text: mode === LinphoneEnums.ConsolidatedPresence.Online
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 //: "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) font.pixelSize: Math.round(14 * DefaultStyle.dp)
} }
}, },
@ -461,7 +498,8 @@ FriendGui{
ContactDetailLayout { ContactDetailLayout {
id: infoLayout id: infoLayout
Layout.fillWidth: true Layout.fillWidth: true
label: qsTr("Informations") //: "Coordonnées"
label: qsTr("contact_details_numbers_and_addresses_title")
content: ListView { content: ListView {
id: addrList id: addrList
height: contentHeight height: contentHeight
@ -547,7 +585,8 @@ FriendGui{
height: Math.round(50 * DefaultStyle.dp) height: Math.round(50 * DefaultStyle.dp)
visible: companyText.text.length != 0 visible: companyText.text.length != 0
Text { Text {
text: qsTr("Société :") //: "Société :"
text: qsTr("contact_details_company_name")
font { font {
pixelSize: Typography.p2.pixelSize pixelSize: Typography.p2.pixelSize
weight: Typography.p2.weight weight: Typography.p2.weight
@ -567,7 +606,8 @@ FriendGui{
height: Math.round(50 * DefaultStyle.dp) height: Math.round(50 * DefaultStyle.dp)
visible: jobText.text.length != 0 visible: jobText.text.length != 0
Text { Text {
text: qsTr("Poste :") //: "Poste :"
text: qsTr("contact_details_job_title")
font { font {
pixelSize: Typography.p2.pixelSize pixelSize: Typography.p2.pixelSize
weight: Typography.p2.weight weight: Typography.p2.weight
@ -588,7 +628,8 @@ FriendGui{
} }
ContactDetailLayout { ContactDetailLayout {
visible: !SettingsCpp.disableChatFeature visible: !SettingsCpp.disableChatFeature
label: qsTr("Medias") //: "Medias"
label: qsTr("contact_details_medias_title")
Layout.fillWidth: true Layout.fillWidth: true
content: Button { content: Button {
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
@ -600,7 +641,8 @@ FriendGui{
colorizationColor: DefaultStyle.main2_600 colorizationColor: DefaultStyle.main2_600
} }
Text { Text {
text: qsTr("Afficher les medias partagés") //: "Afficher les medias partagés"
text: qsTr("contact_details_medias_subtitle")
font { font {
pixelSize: Typography.p1.pixelSize pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight weight: Typography.p1.weight
@ -622,13 +664,15 @@ FriendGui{
} }
ContactDetailLayout { ContactDetailLayout {
Layout.fillWidth: true Layout.fillWidth: true
label: qsTr("Confiance") //: "Confiance"
label: qsTr("contact_details_trust_title")
icon: AppIcons.question icon: AppIcons.question
onTitleIconClicked: trustInfoDialog.open() onTitleIconClicked: trustInfoDialog.open()
content: ColumnLayout { content: ColumnLayout {
spacing: Math.round(13 * DefaultStyle.dp) spacing: Math.round(13 * DefaultStyle.dp)
Text { 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 { font {
pixelSize: Typography.p2.pixelSize pixelSize: Typography.p2.pixelSize
weight: Typography.p2.weight weight: Typography.p2.weight
@ -636,7 +680,8 @@ FriendGui{
} }
Text { Text {
visible: deviceList.count === 0 visible: deviceList.count === 0
text: qsTr("Aucun appareil") //: "Aucun appareil"
text: qsTr("contact_details_no_device_found")
} }
ProgressBar { ProgressBar {
visible: deviceList.count > 0 visible: deviceList.count > 0
@ -660,7 +705,8 @@ FriendGui{
property var listViewModelData: modelData property var listViewModelData: modelData
property var callObj property var callObj
property CallGui deviceCall: callObj ? callObj.value : null 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 {
text: deviceDelegate.deviceName text: deviceDelegate.deviceName
font.pixelSize: Math.round(14 * DefaultStyle.dp) font.pixelSize: Math.round(14 * DefaultStyle.dp)
@ -680,7 +726,8 @@ FriendGui{
visible: listViewModelData.securityLevel != LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified visible: listViewModelData.securityLevel != LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified
icon.source: AppIcons.warningCircle icon.source: AppIcons.warningCircle
style: ButtonStyle.tertiary style: ButtonStyle.tertiary
text: qsTr("Vérifier") //: "Vérifier"
text: qsTr("contact_make_call_check_device_trust")
onClicked: { onClicked: {
if (SettingsCpp.getDisplayDeviceCheckConfirmation( if (SettingsCpp.getDisplayDeviceCheckConfirmation(
)) { )) {
@ -705,14 +752,16 @@ FriendGui{
} }
ContactDetailLayout { ContactDetailLayout {
Layout.fillWidth: true Layout.fillWidth: true
label: qsTr("Autres actions") //: "Autres actions"
label: qsTr("contact_details_actions_title")
content: ColumnLayout { content: ColumnLayout {
width: parent.width width: parent.width
IconLabelButton { IconLabelButton {
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: Math.round(50 * DefaultStyle.dp) Layout.preferredHeight: Math.round(50 * DefaultStyle.dp)
icon.source: AppIcons.pencil icon.source: AppIcons.pencil
text: qsTr("Éditer") //: "Éditer"
text: qsTr("contact_details_edit")
onClicked: mainItem.editContact( onClicked: mainItem.editContact(
mainItem.selectedContact) mainItem.selectedContact)
visible: !mainItem.selectedContact?.core.readOnly visible: !mainItem.selectedContact?.core.readOnly
@ -729,7 +778,11 @@ FriendGui{
icon.source: mainItem.selectedContact icon.source: mainItem.selectedContact
&& mainItem.selectedContact.core.starred ? AppIcons.heartFill : AppIcons.heart && mainItem.selectedContact.core.starred ? AppIcons.heartFill : AppIcons.heart
text: mainItem.selectedContact 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 style: ButtonStyle.noBackground
onClicked: if (mainItem.selectedContact) onClicked: if (mainItem.selectedContact)
mainItem.selectedContact.core.lSetStarred( mainItem.selectedContact.core.lSetStarred(
@ -744,7 +797,8 @@ FriendGui{
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: Math.round(50 * DefaultStyle.dp) Layout.preferredHeight: Math.round(50 * DefaultStyle.dp)
icon.source: AppIcons.shareNetwork icon.source: AppIcons.shareNetwork
text: qsTr("Partager") //: "Partager"
text: qsTr("contact_details_share")
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
onClicked: { onClicked: {
if (mainItem.selectedContact) { if (mainItem.selectedContact) {
@ -755,17 +809,19 @@ FriendGui{
username, vcard) username, vcard)
if (filepath == "") if (filepath == "")
UtilsCpp.showInformationPopup( UtilsCpp.showInformationPopup(
qsTr("Erreur"), qsTr("information_popup_error_title"),
qsTr("La création du fichier vcard a échoué"), //: "La création du fichier vcard a échoué"
qsTr("contact_details_share_error_mesage"),
false) false)
else else
mainWindow.showInformationPopup( mainWindow.showInformationPopup(
qsTr( //: "VCard créée"
"VCard créée"), qsTr("contact_details_share_success_title"),
qsTr("VCard du contact enregistrée dans %1").arg( //: "VCard du contact enregistrée dans %1"
filepath)) qsTr("contact_details_share_success_mesage").arg(filepath))
UtilsCpp.shareByEmail( UtilsCpp.shareByEmail(
qsTr("Partage de contact"), //: "Partage de contact"
qsTr("contact_details_share_email_title"),
vcard, filepath) vcard, filepath)
} }
} }
@ -803,7 +859,8 @@ FriendGui{
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: Math.round(50 * DefaultStyle.dp) Layout.preferredHeight: Math.round(50 * DefaultStyle.dp)
icon.source: AppIcons.trashCan icon.source: AppIcons.trashCan
text: qsTr("Supprimer ce contact") //: "Supprimer ce contact"
text: qsTr("contact_details_delete")
visible: !mainItem.selectedContact?.core.readOnly visible: !mainItem.selectedContact?.core.readOnly
onClicked: { onClicked: {
mainItem.deleteContact( mainItem.deleteContact(

View file

@ -35,7 +35,8 @@ AbstractMainPage {
} }
} }
Text { Text {
text: qsTr("Aide") //: "Aide"
text: qsTr("help_title")
color: DefaultStyle.main2_700 color: DefaultStyle.main2_700
font: Typography.h2 font: Typography.h2
} }
@ -48,7 +49,8 @@ AbstractMainPage {
Layout.rightMargin: leftPanel.sideMargin Layout.rightMargin: leftPanel.sideMargin
Layout.topMargin: Math.round(41 * DefaultStyle.dp) Layout.topMargin: Math.round(41 * DefaultStyle.dp)
Layout.fillWidth: true Layout.fillWidth: true
text: qsTr("À propos de Linphone") //: "À propos de %1"
text: qsTr("help_about_title").arg(applicationName)
color: DefaultStyle.main2_600 color: DefaultStyle.main2_600
font: Typography.h4 font: Typography.h4
} }
@ -61,8 +63,10 @@ AbstractMainPage {
HelpIconLabelButton { HelpIconLabelButton {
Layout.fillWidth: true Layout.fillWidth: true
iconSource: AppIcons.detective iconSource: AppIcons.detective
title: qsTr("Règles de confidentialité") //: "Règles de confidentialité"
subTitle: qsTr("Comment Linphone récolte et utilise les informations") title: qsTr("help_about_privacy_policy_title")
//: Quelles informations %1 collecte et utilise
subTitle: qsTr("help_about_privacy_policy_subtitle").arg(applicationName)
onClicked: { onClicked: {
rightPanelStackView.clear() rightPanelStackView.clear()
Qt.openUrlExternally(ConstantsCpp.PrivatePolicyUrl) Qt.openUrlExternally(ConstantsCpp.PrivatePolicyUrl)
@ -71,14 +75,16 @@ AbstractMainPage {
HelpIconLabelButton { HelpIconLabelButton {
Layout.fillWidth: true Layout.fillWidth: true
iconSource: AppIcons.info iconSource: AppIcons.info
title: qsTr("Version") //: "Version"
title: qsTr("help_about_version_title")
subTitle: AppCpp.shortApplicationVersion subTitle: AppCpp.shortApplicationVersion
onClicked: {} onClicked: {}
} }
HelpIconLabelButton { HelpIconLabelButton {
Layout.fillWidth: true Layout.fillWidth: true
iconSource: AppIcons.license iconSource: AppIcons.license
title: qsTr("Licences GPLv3") //: "Licences GPLv3"
title: qsTr("help_about_gpl_licence_title")
subTitle: (copyrightRangeDate || applicationVendor ? '\u00A9 ': '') + (copyrightRangeDate ? copyrightRangeDate : '')+ (applicationVendor ? ' ' + applicationVendor : '') subTitle: (copyrightRangeDate || applicationVendor ? '\u00A9 ': '') + (copyrightRangeDate ? copyrightRangeDate : '')+ (applicationVendor ? ' ' + applicationVendor : '')
onClicked: { onClicked: {
rightPanelStackView.clear() rightPanelStackView.clear()
@ -88,7 +94,8 @@ AbstractMainPage {
HelpIconLabelButton { HelpIconLabelButton {
Layout.fillWidth: true Layout.fillWidth: true
iconSource: AppIcons.world 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: { onClicked: {
rightPanelStackView.clear() rightPanelStackView.clear()
Qt.openUrlExternally(ConstantsCpp.TranslationUrl) Qt.openUrlExternally(ConstantsCpp.TranslationUrl)
@ -100,7 +107,8 @@ AbstractMainPage {
Layout.rightMargin: leftPanel.sideMargin Layout.rightMargin: leftPanel.sideMargin
Layout.topMargin: Math.round(32 * DefaultStyle.dp) Layout.topMargin: Math.round(32 * DefaultStyle.dp)
Layout.fillWidth: true Layout.fillWidth: true
text: qsTr("À propos de Linphone") //: "À propos de %1"
text: qsTr("help_about_title").arg(applicationName)
color: DefaultStyle.main2_600 color: DefaultStyle.main2_600
font: Typography.h4 font: Typography.h4
} }
@ -111,7 +119,8 @@ AbstractMainPage {
Layout.rightMargin: leftPanel.sideMargin Layout.rightMargin: leftPanel.sideMargin
Layout.topMargin: Math.round(24 * DefaultStyle.dp) Layout.topMargin: Math.round(24 * DefaultStyle.dp)
iconSource: AppIcons.debug iconSource: AppIcons.debug
title: qsTr("Dépannage") //: "Dépannage"
title: qsTr("help_troubleshooting_title")
onClicked: { onClicked: {
rightPanelStackView.clear() rightPanelStackView.clear()
rightPanelStackView.push("qrc:/qt/qml/Linphone/view/Page/Layout/Settings/DebugSettingsLayout.qml", { titleText: troubleShooting.title, container: rightPanelStackView }) rightPanelStackView.push("qrc:/qt/qml/Linphone/view/Page/Layout/Settings/DebugSettingsLayout.qml", { titleText: troubleShooting.title, container: rightPanelStackView })

View file

@ -14,9 +14,10 @@ AbstractMainPage {
property int meetingListCount property int meetingListCount
signal returnRequested() signal returnRequested()
signal addParticipantsValidated(list<string> selectedParticipants) signal addParticipantsValidated(list<string> selectedParticipants)
//: "Créer une réunion"
noItemButtonText: qsTr("Créer une réunion") noItemButtonText: qsTr("meetings_add")
emptyListText: qsTr("Aucune réunion") //: "Aucune réunion"
emptyListText: qsTr("meetings_list_empty")
newItemIconSource: AppIcons.plusCircle newItemIconSource: AppIcons.plusCircle
rightPanelColor: selectedConference ? DefaultStyle.grey_0 : DefaultStyle.grey_100 rightPanelColor: selectedConference ? DefaultStyle.grey_0 : DefaultStyle.grey_100
showDefaultItem: leftPanelStackView.currentItem?.objectName === "listLayout" && meetingListCount === 0 showDefaultItem: leftPanelStackView.currentItem?.objectName === "listLayout" && meetingListCount === 0
@ -73,12 +74,16 @@ AbstractMainPage {
property bool cancel: false property bool cancel: false
signal cancelRequested() signal cancelRequested()
// width: Math.round(278 * DefaultStyle.dp) // 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: [ buttons: [
BigButton { BigButton {
visible: cancelAndDeleteConfDialog.cancel visible: cancelAndDeleteConfDialog.cancel
style: ButtonStyle.main style: ButtonStyle.main
text: qsTr("Annuler et supprimer") //: "Annuler et supprimer"
text: qsTr("meeting_schedule_cancel_and_delete_action")
onClicked: { onClicked: {
cancelAndDeleteConfDialog.cancelRequested() cancelAndDeleteConfDialog.cancelRequested()
cancelAndDeleteConfDialog.accepted() cancelAndDeleteConfDialog.accepted()
@ -86,7 +91,10 @@ AbstractMainPage {
} }
}, },
BigButton { 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 style: ButtonStyle.main
onClicked: { onClicked: {
cancelAndDeleteConfDialog.accepted() cancelAndDeleteConfDialog.accepted()
@ -94,7 +102,8 @@ AbstractMainPage {
} }
}, },
BigButton { BigButton {
text: qsTr("Retour") //: Retour
text: qsTr("back_action")
style: ButtonStyle.secondary style: ButtonStyle.secondary
onClicked: { onClicked: {
cancelAndDeleteConfDialog.rejected() cancelAndDeleteConfDialog.rejected()
@ -136,7 +145,8 @@ AbstractMainPage {
spacing: 0 spacing: 0
Text { Text {
Layout.fillWidth: true Layout.fillWidth: true
text: qsTr("Réunions") //: Réunions
text: qsTr("meetings_list_title")
color: DefaultStyle.main2_700 color: DefaultStyle.main2_700
font.pixelSize: Typography.h2.pixelSize font.pixelSize: Typography.h2.pixelSize
font.weight: Typography.h2.weight font.weight: Typography.h2.weight
@ -159,7 +169,8 @@ AbstractMainPage {
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: Math.round(18 * DefaultStyle.dp) Layout.topMargin: Math.round(18 * DefaultStyle.dp)
Layout.rightMargin: Math.round(38 * 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.up: conferenceList
KeyNavigation.down: conferenceList KeyNavigation.down: conferenceList
visible: conferenceList.count !== 0 || text.length !== 0 visible: conferenceList.count !== 0 || text.length !== 0
@ -175,7 +186,10 @@ AbstractMainPage {
Layout.topMargin: Math.round(137 * DefaultStyle.dp) Layout.topMargin: Math.round(137 * DefaultStyle.dp)
Layout.fillHeight: true Layout.fillHeight: true
Layout.alignment: Qt.AlignHCenter 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 { font {
pixelSize: Typography.h4.pixelSize pixelSize: Typography.h4.pixelSize
weight: Typography.h4.weight weight: Typography.h4.weight
@ -237,7 +251,8 @@ AbstractMainPage {
} }
} }
Text { Text {
text: qsTr("Nouvelle réunion") //: "Nouvelle réunion"
text: qsTr("meeting_schedule_title")
color: DefaultStyle.main2_700 color: DefaultStyle.main2_700
font { font {
pixelSize: Typography.h3.pixelSize pixelSize: Typography.h3.pixelSize
@ -248,21 +263,24 @@ AbstractMainPage {
Item {Layout.fillWidth: true} Item {Layout.fillWidth: true}
SmallButton { SmallButton {
id: createButton id: createButton
text: qsTr("Créer") text: qsTr("create")
style: ButtonStyle.main style: ButtonStyle.main
KeyNavigation.left: backButton KeyNavigation.left: backButton
KeyNavigation.down: meetingSetup KeyNavigation.down: meetingSetup
onClicked: { onClicked: {
if (meetingSetup.conferenceInfoGui.core.subject.length === 0) { if (meetingSetup.conferenceInfoGui.core.subject.length === 0 || meetingSetup.conferenceInfoGui.core.participantCount === 0) {
UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La conférence doit contenir un sujet"), false) 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) { } 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) UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
} else if (meetingSetup.conferenceInfoGui.core.participantCount === 0) { //: "La fin de la conférence doit être plus récente que son début"
UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La conférence doit contenir au moins un participant"), false) qsTr("meeting_schedule_duration_error_toast"), false)
} else { } else {
meetingSetup.conferenceInfoGui.core.save() meetingSetup.conferenceInfoGui.core.save()
mainWindow.showLoadingPopup(qsTr("Création de la réunion en cours ..."), true, function () { //: "Création de la réunion en cours "
mainWindow.showLoadingPopup(qsTr("meeting_schedule_creation_in_progress"), true, function () {
meetingSetup.conferenceInfoGui.core.cancelCreation() meetingSetup.conferenceInfoGui.core.cancelCreation()
}) })
} }
@ -282,17 +300,23 @@ AbstractMainPage {
var mainWin = UtilsCpp.getMainWindow() var mainWin = UtilsCpp.getMainWindow()
if (meetingSetup.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Ready) { if (meetingSetup.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Ready) {
leftPanelStackView.pop() 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() mainWindow.closeLoadingPopup()
} }
else if (meetingSetup.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.AllocationPending else if (meetingSetup.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.AllocationPending
|| meetingSetup.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Updating) { || 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() leftPanelStackView.pop()
}) })
} else { } else {
if (meetingSetup.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Error) { 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() mainWin.closeLoadingPopup()
} }
@ -385,18 +409,18 @@ AbstractMainPage {
id: saveButton id: saveButton
style: ButtonStyle.main style: ButtonStyle.main
focus: true focus: true
text: qsTr("Enregistrer") text: qsTr("save")
KeyNavigation.left: titleText KeyNavigation.left: titleText
KeyNavigation.right: backButton KeyNavigation.right: backButton
KeyNavigation.down: conferenceEdit KeyNavigation.down: conferenceEdit
KeyNavigation.up: conferenceEdit KeyNavigation.up: conferenceEdit
onClicked: { onClicked: {
if (mainItem.selectedConference.core.subject.length === 0) { if (mainItem.selectedConference.core.subject.length === 0 || mainItem.selectedConference.core.participantCount === 0) {
UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La conférence doit contenir un sujet"), false) UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
qsTr("meeting_schedule_mandatory_field_not_filled_toast"), false)
} else if (mainItem.selectedConference.core.duration <= 0) { } 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) UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
} else if (mainItem.selectedConference.core.participantCount === 0) { qsTr("meeting_schedule_duration_error_toast"), false)
UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La conférence doit contenir au moins un participant"), false)
} else { } else {
mainItem.selectedConference.core.save() mainItem.selectedConference.core.save()
} }
@ -434,13 +458,19 @@ AbstractMainPage {
if (conferenceEdit.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Ready) { if (conferenceEdit.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Ready) {
overridenRightPanelStackView.pop() overridenRightPanelStackView.pop()
UtilsCpp.getMainWindow().closeLoadingPopup() 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 else if (conferenceEdit.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.AllocationPending
|| conferenceEdit.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Updating) { || 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) { } 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() UtilsCpp.getMainWindow().closeLoadingPopup()
} }
} }
@ -476,7 +506,8 @@ AbstractMainPage {
onClicked: container.pop() onClicked: container.pop()
} }
Text { Text {
text: qsTr("Ajouter des participants") //: "Ajouter des participants"
text: qsTr("meeting_schedule_add_participants_title")
color: DefaultStyle.main1_500_main color: DefaultStyle.main1_500_main
maximumLineCount: 1 maximumLineCount: 1
font { font {
@ -491,7 +522,7 @@ AbstractMainPage {
Layout.leftMargin: Math.round(11 * DefaultStyle.dp) Layout.leftMargin: Math.round(11 * DefaultStyle.dp)
focus: enabled focus: enabled
style: ButtonStyle.main style: ButtonStyle.main
text: qsTr("Ajouter") text: qsTr("add")
KeyNavigation.left: addParticipantsBackButton KeyNavigation.left: addParticipantsBackButton
KeyNavigation.down: addParticipantLayout KeyNavigation.down: addParticipantLayout
onClicked: { onClicked: {
@ -500,7 +531,8 @@ AbstractMainPage {
} }
} }
Text { 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 color: DefaultStyle.main2_500main
Layout.leftMargin: addParticipantsBackButton.width + addParticipantsButtons.spacing Layout.leftMargin: addParticipantsBackButton.width + addParticipantsButtons.spacing
maximumLineCount: 1 maximumLineCount: 1
@ -584,7 +616,8 @@ AbstractMainPage {
property var isMeObj: UtilsCpp.isMe(mainItem.selectedConference?.core?.organizerAddress) property var isMeObj: UtilsCpp.isMe(mainItem.selectedConference?.core?.organizerAddress)
property bool canCancel: isMeObj && isMeObj.value && mainItem.selectedConference?.core?.state !== LinphoneEnums.ConferenceInfoState.Cancelled property bool canCancel: isMeObj && isMeObj.value && mainItem.selectedConference?.core?.state !== LinphoneEnums.ConferenceInfoState.Cancelled
icon.source: AppIcons.trashCan icon.source: AppIcons.trashCan
text: qsTr("Supprimer cette réunion") //: "Supprimer la réunion"
text: qsTr("meeting_info_delete")
onClicked: { onClicked: {
if (mainItem.selectedConference) { if (mainItem.selectedConference) {
@ -653,7 +686,9 @@ AbstractMainPage {
KeyNavigation.down: joinButton KeyNavigation.down: joinButton
onClicked: { onClicked: {
UtilsCpp.copyToClipboard(mainItem.selectedConference.core.uri) 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 colorizationColor: DefaultStyle.main2_600
} }
Text { 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 { font {
pixelSize: Math.round(14 * DefaultStyle.dp) pixelSize: Math.round(14 * DefaultStyle.dp)
capitalization: Font.Capitalize capitalization: Font.Capitalize
@ -779,7 +815,8 @@ AbstractMainPage {
} }
} }
Text { Text {
text: qsTr("Organizer") //: "Organisateur"
text: qsTr("meeting_info_organizer_label")
visible: mainItem.selectedConference && mainItem.selectedConference.core?.organizerAddress === modelData.address visible: mainItem.selectedConference && mainItem.selectedConference.core?.organizerAddress === modelData.address
color: DefaultStyle.main2_400 color: DefaultStyle.main2_400
font { font {
@ -795,7 +832,8 @@ AbstractMainPage {
id: joinButton id: joinButton
visible: mainItem.selectedConference && mainItem.selectedConference.core?.state !== LinphoneEnums.ConferenceInfoState.Cancelled visible: mainItem.selectedConference && mainItem.selectedConference.core?.state !== LinphoneEnums.ConferenceInfoState.Cancelled
Layout.fillWidth: true Layout.fillWidth: true
text: qsTr("Rejoindre la réunion") //: "Rejoindre la réunion"
text: qsTr("meeting_info_join_title")
focus: true focus: true
KeyNavigation.up: shareNetworkButton KeyNavigation.up: shareNetworkButton
KeyNavigation.down: deletePopup KeyNavigation.down: deletePopup

View file

@ -12,7 +12,8 @@ LoginLayout {
titleContent: [ titleContent: [
Text { Text {
id: welcome id: welcome
text: qsTr("Bienvenue") //: "Bienvenue"
text: qsTr("welcome_page_title")
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
Layout.leftMargin: Math.round(132 * DefaultStyle.dp) Layout.leftMargin: Math.round(132 * DefaultStyle.dp)
color: DefaultStyle.main2_800 color: DefaultStyle.main2_800
@ -27,7 +28,8 @@ LoginLayout {
Layout.leftMargin: Math.round(29 * DefaultStyle.dp) Layout.leftMargin: Math.round(29 * DefaultStyle.dp)
Layout.bottomMargin: Math.round(19 * DefaultStyle.dp) Layout.bottomMargin: Math.round(19 * DefaultStyle.dp)
color: DefaultStyle.main2_800 color: DefaultStyle.main2_800
text: qsTr("sur Linphone") //: "sur %1"
text: qsTr("welcome_page_subtitle").arg(applicationName)
font { font {
pixelSize: Typography.h1.pixelSize pixelSize: Typography.h1.pixelSize
weight: Typography.h1.weight weight: Typography.h1.weight
@ -43,7 +45,8 @@ LoginLayout {
Layout.rightMargin: Math.round(50 * DefaultStyle.dp) Layout.rightMargin: Math.round(50 * DefaultStyle.dp)
Layout.alignment: Qt.AlignVCenter | Layout.AlignRight Layout.alignment: Qt.AlignVCenter | Layout.AlignRight
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
text: qsTr("Passer") //: "Passer"
text: qsTr("welcome_carousel_skip")
underline: true underline: true
onClicked: { onClicked: {
console.debug("[WelcomePage] User: Click skip") console.debug("[WelcomePage] User: Click skip")
@ -76,9 +79,16 @@ LoginLayout {
itemsList: Repeater { itemsList: Repeater {
id: slideRepeater id: slideRepeater
model: [ model: [
{title: qsTr("Linphone"), text: qsTr("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>."
{title: qsTr("Sécurisé"), text: qsTr("Vos communications sont en sécurité grâce aux <br><b>Chiffrement de bout en bout</b>.")}, {title: applicationName, text: qsTr("welcome_page_1_message")},
{title: qsTr("Open Source"), text: qsTr("Une application open source et un <b>service gratuit</b> <br>depuis <b>2001</b>")} //: "Sécurisé"
{title: qsTr("welcome_page_2_title"),
//: "Vos communications sont en sécurité grâce aux <br><b>Chiffrement de bout en bout</b>."
text: qsTr("welcome_page_2_message")},
//: "Open Source"
{title: qsTr("welcome_page_3_title"),
//: "Une application open source et un <b>service gratuit</b> <br>depuis <b>2001</b>"
text: qsTr("welcome_page_3_message")}
] ]
ColumnLayout { ColumnLayout {
spacing: Math.round(10 * DefaultStyle.dp) spacing: Math.round(10 * DefaultStyle.dp)
@ -108,7 +118,10 @@ LoginLayout {
BigButton { BigButton {
Layout.leftMargin: Math.round(509 * DefaultStyle.dp) Layout.leftMargin: Math.round(509 * DefaultStyle.dp)
style: ButtonStyle.main style: ButtonStyle.main
text: carousel.currentIndex < (carousel.itemsCount - 1) ? qsTr("Suivant") : qsTr("Commencer") //: "Suivant"
text: carousel.currentIndex < (carousel.itemsCount - 1) ? qsTr("next")
//: "Commencer"
: qsTr("start")
onClicked: { onClicked: {
if (carousel.currentIndex < carousel.itemsCount - 1) carousel.goToSlide(carousel.currentIndex + 1); if (carousel.currentIndex < carousel.itemsCount - 1) carousel.goToSlide(carousel.currentIndex + 1);
else mainItem.startButtonPressed(); else mainItem.startButtonPressed();

View file

@ -74,7 +74,8 @@ ApplicationWindow {
spacing: Math.round(5 * DefaultStyle.dp) spacing: Math.round(5 * DefaultStyle.dp)
width: startCallPopup.width width: startCallPopup.width
Text { 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 wrapMode: Text.Wrap
Layout.fillWidth: true Layout.fillWidth: true
font { font {
@ -272,7 +273,8 @@ ApplicationWindow {
font.bold: true font.bold: true
font.italic: true font.italic: true
font.pixelSize: Math.round(14 * DefaultStyle.dp) 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 color: parent.fps < 30 ? DefaultStyle.danger_500main : DefaultStyle.main2_900
} }
} }

View file

@ -51,8 +51,8 @@ AbstractWindow {
var callsWin = UtilsCpp.getCallsWindow() var callsWin = UtilsCpp.getCallsWindow()
if (!callsWin) if (!callsWin)
return return
callsWin.showLoadingPopup( //: "Transfert en cours, veuillez patienter"
qsTr("Transfert en cours, veuillez patienter")) callsWin.showLoadingPopup(qsTr("call_transfer_in_progress_toast"))
} else if (mainWindow.transferState === LinphoneEnums.CallState.Error } else if (mainWindow.transferState === LinphoneEnums.CallState.Error
|| mainWindow.transferState === LinphoneEnums.CallState.End || mainWindow.transferState === LinphoneEnums.CallState.End
|| mainWindow.transferState === LinphoneEnums.CallState.Released || mainWindow.transferState === LinphoneEnums.CallState.Released
@ -61,8 +61,9 @@ AbstractWindow {
callsWin.closeLoadingPopup() callsWin.closeLoadingPopup()
if (transferState === LinphoneEnums.CallState.Error) if (transferState === LinphoneEnums.CallState.Error)
UtilsCpp.showInformationPopup( UtilsCpp.showInformationPopup(
qsTr("Erreur"), qsTr("information_popup_error_title"),
qsTr("Le transfert d'appel a échoué"), false, //: "Le transfert d'appel a échoué"
qsTr("call_transfer_failed_toast"), false,
mainWindow) mainWindow)
else if (transferState === LinphoneEnums.CallState.Connected) { else if (transferState === LinphoneEnums.CallState.Connected) {
var mainWin = UtilsCpp.getMainWindow() var mainWin = UtilsCpp.getMainWindow()
@ -130,10 +131,8 @@ AbstractWindow {
function joinConference(uri, options) { function joinConference(uri, options) {
if (uri.length === 0) if (uri.length === 0)
UtilsCpp.showInformationPopup( //: "La conférence n'a pas pu démarrer en raison d'une erreur d'uri."
qsTr("Erreur"), qsTr( UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), qsTr("conference_error_empty_uri"),mainWindow)
"La conférence n'a pas pu démarrer en raison d'une erreur d'uri."),
mainWindow)
else { else {
UtilsCpp.createCall(uri, options) UtilsCpp.createCall(uri, options)
} }
@ -188,7 +187,10 @@ AbstractWindow {
call.core.lTerminateAllCalls() call.core.lTerminateAllCalls()
} }
width: Math.round(278 * DefaultStyle.dp) 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 { CallProxy {
@ -280,7 +282,8 @@ AbstractWindow {
} }
Text { Text {
color: DefaultStyle.info_500_main color: DefaultStyle.info_500_main
text: qsTr("Appareil vérifié") //: "Appareil authentifié"
text: qsTr("call_can_be_trusted_toast")
Layout.fillWidth: true Layout.fillWidth: true
font { font {
pixelSize: Math.round(14 * DefaultStyle.dp) pixelSize: Math.round(14 * DefaultStyle.dp)
@ -344,8 +347,22 @@ AbstractWindow {
spacing: Math.round(10 * DefaultStyle.dp) spacing: Math.round(10 * DefaultStyle.dp)
Text { Text {
id: callStatusText 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) : "") property string remoteName: mainWindow.callState === LinphoneEnums.CallState.Connected || mainWindow.callState === LinphoneEnums.CallState.StreamsRunning
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 ? 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 color: DefaultStyle.grey_0
font { font {
pixelSize: Typography.h3.pixelSize pixelSize: Typography.h3.pixelSize
@ -426,17 +443,40 @@ AbstractWindow {
=== LinphoneEnums.CallState.Connected === LinphoneEnums.CallState.Connected
|| mainWindow.callState || mainWindow.callState
=== LinphoneEnums.CallState.StreamsRunning === 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 {
text: mainWindow.call text: mainWindow.call && mainWindow.callState === LinphoneEnums.CallState.Connected || mainWindow.callState === LinphoneEnums.CallState.StreamsRunning
&& mainWindow.callState ? mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Srtp
=== LinphoneEnums.CallState.Connected //: "Appel chiffré de point à point"
|| 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") ? qsTr("call_srtp_point_to_point_encrypted")
color: mainWindow.call : mainWindow.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp
&& mainWindow.callState ? mainWindow.call.core.isMismatch || !mainWindow.call.core.tokenVerified
=== LinphoneEnums.CallState.Connected //: "Vérification nécessaire"
|| 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 ? 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 { font {
pixelSize: Math.round(12 * DefaultStyle.dp) pixelSize: Math.round(12 * DefaultStyle.dp)
weight: Math.round(400 * DefaultStyle.dp) weight: Math.round(400 * DefaultStyle.dp)
@ -510,13 +550,26 @@ AbstractWindow {
Text { Text {
color: DefaultStyle.danger_500main color: DefaultStyle.danger_500main
font.pixelSize: Math.round(14 * DefaultStyle.dp) 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 { BigButton {
visible: mainWindow.call visible: mainWindow.call
&& mainWindow.call.core.recording && mainWindow.call.core.recording
text: qsTr("Arrêter l'enregistrement") //: "Arrêter l'enregistrement"
text: qsTr("call_stop_recording")
style: ButtonStyle.main style: ButtonStyle.main
onPressed: mainWindow.call.core.lStopRecording() onPressed: mainWindow.call.core.lStopRecording()
} }
@ -549,7 +602,7 @@ AbstractWindow {
} }
headerStack.currentIndex: 0 headerStack.currentIndex: 0
contentStackView.initialItem: callListPanel contentStackView.initialItem: callListPanel
headerValidateButtonText: qsTr("Ajouter") headerValidateButtonText: qsTr("add")
Item { Item {
id: numericPadContainer id: numericPadContainer
@ -565,9 +618,8 @@ AbstractWindow {
id: callTransferPanel id: callTransferPanel
NewCallForm { NewCallForm {
id: newCallForm id: newCallForm
Control.StackView.onActivated: rightPanel.headerTitleText = qsTr( //: "Transférer %1 à"
"Transférer %1 à :").arg( Control.StackView.onActivated: rightPanel.headerTitleText = qsTr("call_transfer_current_call_title").arg(mainWindow.call.core.remoteName)
mainWindow.call.core.remoteName)
Keys.onEscapePressed: event => { Keys.onEscapePressed: event => {
rightPanel.visible = false rightPanel.visible = false
event.accepted = true event.accepted = true
@ -579,30 +631,21 @@ AbstractWindow {
onContactClicked: contact => { onContactClicked: contact => {
var callsWin = UtilsCpp.getCallsWindow() var callsWin = UtilsCpp.getCallsWindow()
if (contact) if (contact)
callsWin.showConfirmationLambdaPopup( //: "Confirmer le transfert"
qsTr("Confirmer le transfert ?"), callsWin.showConfirmationLambdaPopup(qsTr("call_transfer_confirm_dialog_tittle"),
qsTr("Vous allez transférer %1 à %2.").arg( //: "Vous allez transférer %1 à %2."
mainWindow.call.core.remoteName).arg( qsTr("call_transfer_confirm_dialog_message").arg(mainWindow.call.core.remoteName).arg(contact.core.fullName), "",
contact.core.fullName), "",
function (confirmed) { function (confirmed) {
if (confirmed) { if (confirmed) {
mainWindow.transferCallToContact( mainWindow.transferCallToContact(mainWindow.call,contact,newCallForm)
mainWindow.call,
contact,
newCallForm)
} }
}) })
} }
onTransferCallToAnotherRequested: dest => { onTransferCallToAnotherRequested: dest => {
var callsWin = UtilsCpp.getCallsWindow() var callsWin = UtilsCpp.getCallsWindow()
console.log( console.log("transfer to",dest)
"transfer to", callsWin.showConfirmationLambdaPopup(qsTr("call_transfer_confirm_dialog_tittle"),
dest) qsTr("call_transfer_confirm_dialog_message").arg(mainWindow.call.core.remoteName).arg(dest.core.remoteName),"",
callsWin.showConfirmationLambdaPopup(
qsTr("Confirmer le transfert ?"),
qsTr("Vous allez transférer %1 à %2.").arg(mainWindow.call.core.remoteName).arg(
dest.core.remoteName),
"",
function (confirmed) { function (confirmed) {
if (confirmed) { if (confirmed) {
mainWindow.call.core.lTransferCallToAnother(dest.core.remoteAddress) mainWindow.call.core.lTransferCallToAnother(dest.core.remoteAddress)
@ -631,8 +674,8 @@ AbstractWindow {
NewCallForm { NewCallForm {
id: newCallForm id: newCallForm
objectName: "newCallPanel" 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 groupCallVisible: false
searchBarColor: DefaultStyle.grey_0 searchBarColor: DefaultStyle.grey_0
searchBarBorderColor: DefaultStyle.grey_200 searchBarBorderColor: DefaultStyle.grey_200
@ -671,8 +714,8 @@ AbstractWindow {
id: dialerPanel id: dialerPanel
Item { Item {
id: dialerPanelContent id: dialerPanelContent
Control.StackView.onActivated: rightPanel.headerTitleText = qsTr( //: "Pavé numérique"
"Dialer") Control.StackView.onActivated: rightPanel.headerTitleText = qsTr("call_action_show_dialer")
anchors.top: parent.top anchors.top: parent.top
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
Keys.onEscapePressed: event => { Keys.onEscapePressed: event => {
@ -709,8 +752,8 @@ AbstractWindow {
Component { Component {
id: changeLayoutPanel id: changeLayoutPanel
ChangeLayoutForm { 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 => { Keys.onEscapePressed: event => {
rightPanel.visible = false rightPanel.visible = false
event.accepted = true event.accepted = true
@ -725,7 +768,8 @@ AbstractWindow {
id: callListPanel id: callListPanel
ColumnLayout { ColumnLayout {
Control.StackView.onActivated: { 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.customHeaderButtons = mergeCallPopupButton.createObject(
rightPanel) rightPanel)
} }
@ -743,6 +787,7 @@ AbstractWindow {
icon.source: AppIcons.arrowsMerge icon.source: AppIcons.arrowsMerge
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp)
icon.height: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp)
//: call_action_merge_calls
text: qsTr("Merger tous les appels") text: qsTr("Merger tous les appels")
textSize: Math.round(14 * DefaultStyle.dp) textSize: Math.round(14 * DefaultStyle.dp)
onClicked: { onClicked: {
@ -779,7 +824,8 @@ AbstractWindow {
id: settingsPanel id: settingsPanel
Item { Item {
Control.StackView.onActivated: { Control.StackView.onActivated: {
rightPanel.headerTitleText = qsTr("Paramètres") //: "Paramètres"
rightPanel.headerTitleText = qsTr("call_action_go_to_settings")
} }
Keys.onEscapePressed: event => { Keys.onEscapePressed: event => {
rightPanel.visible = false rightPanel.visible = false
@ -799,8 +845,8 @@ AbstractWindow {
Component { Component {
id: screencastPanel id: screencastPanel
Item { 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 => { Keys.onEscapePressed: event => {
rightPanel.visible = false rightPanel.visible = false
event.accepted = true event.accepted = true
@ -850,38 +896,33 @@ AbstractWindow {
PopupButton { PopupButton {
popup.contentItem: IconLabelButton { popup.contentItem: IconLabelButton {
icon.source: AppIcons.shareNetwork 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: { onClicked: {
UtilsCpp.copyToClipboard( UtilsCpp.copyToClipboard(mainWindow.call.core.remoteAddress)
mainWindow.call.core.remoteAddress) //: Copié
showInformationPopup( showInformationPopup(qsTr("copied"),
qsTr("Copié"), qsTr( //: 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"), qsTr("information_popup_meeting_address_copied_to_clipboard"),true)
true)
} }
} }
} }
} }
Control.StackView.onActivated: { Control.StackView.onActivated: {
rightPanel.customHeaderButtons = headerbutton.createObject( rightPanel.customHeaderButtons = headerbutton.createObject(rightPanel)
rightPanel) //: "Participants (%1)"
rightPanel.headerTitleText = qsTr( rightPanel.headerTitleText = qsTr("conference_participants_list_title").arg(count)
"Participants (%1)").arg(count)
} }
call: mainWindow.call call: mainWindow.call
onAddParticipantRequested: participantsStack.push( onAddParticipantRequested: participantsStack.push(addParticipantComp)
addParticipantComp)
onCountChanged: { onCountChanged: {
rightPanel.headerTitleText = qsTr( rightPanel.headerTitleText = qsTr("conference_participants_list_title").arg(count)
"Participants (%1)").arg(count)
} }
Connections { Connections {
target: participantsStack target: participantsStack
function onCurrentItemChanged() { function onCurrentItemChanged() {
if (participantsStack.currentItem == participantList) if (participantsStack.currentItem == participantList)
rightPanel.headerTitleText = qsTr( rightPanel.headerTitleText = qsTr("conference_participants_list_title").arg(participantList.count)
"Participants (%1)").arg(
participantList.count)
} }
} }
Connections { Connections {
@ -901,21 +942,15 @@ AbstractWindow {
searchBarColor: DefaultStyle.grey_0 searchBarColor: DefaultStyle.grey_0
searchBarBorderColor: DefaultStyle.grey_200 searchBarBorderColor: DefaultStyle.grey_200
onSelectedParticipantsCountChanged: { onSelectedParticipantsCountChanged: {
rightPanel.headerSubtitleText = qsTr( rightPanel.headerSubtitleText = qsTr("group_call_participant_selected").arg(selectedParticipantsCount)
"%1 participant%2 sélectionné%2").arg(
selectedParticipantsCount).arg(
selectedParticipantsCount > 1 ? "s" : "")
participantsStack.selectedParticipants = selectedParticipants participantsStack.selectedParticipants = selectedParticipants
} }
Connections { Connections {
target: participantsStack target: participantsStack
function onCurrentItemChanged() { function onCurrentItemChanged() {
if (participantsStack.currentItem == addParticipantLayout) { if (participantsStack.currentItem == addParticipantLayout) {
rightPanel.headerTitleText = qsTr( rightPanel.headerTitleText = qsTr("meeting_schedule_add_participants_title")
"Ajouter des participants") rightPanel.headerSubtitleText = qsTr("group_call_participant_selected").arg(addParticipantLayout.selectedParticipants.length)
rightPanel.headerSubtitleText = qsTr(
"%1 participant%2 sélectionné%2").arg(
addParticipantLayout.selectedParticipants.length).arg(addParticipantLayout.selectedParticipants.length > 1 ? "s" : "")
} }
} }
} }
@ -929,7 +964,8 @@ AbstractWindow {
EncryptionSettings { EncryptionSettings {
call: mainWindow.call call: mainWindow.call
Control.StackView.onActivated: { Control.StackView.onActivated: {
rightPanel.headerTitleText = qsTr("Chiffrement") //: Chiffrement
rightPanel.headerTitleText = qsTr("call_encryption_title")
} }
onEncryptionValidationRequested: zrtpValidation.open() onEncryptionValidationRequested: zrtpValidation.open()
} }
@ -938,7 +974,8 @@ AbstractWindow {
id: statsPanel id: statsPanel
CallStatistics { CallStatistics {
Control.StackView.onActivated: { Control.StackView.onActivated: {
rightPanel.headerTitleText = qsTr("Statistiques") //: Statistiques
rightPanel.headerTitleText = qsTr("call_stats_title")
} }
call: mainWindow.call call: mainWindow.call
} }
@ -1055,7 +1092,8 @@ AbstractWindow {
Layout.row: 0 Layout.row: 0
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp)
icon.height: 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.preferredWidth: Math.round(75 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(55 * DefaultStyle.dp) Layout.preferredHeight: Math.round(55 * DefaultStyle.dp)
radius: Math.round(71 * DefaultStyle.dp) radius: Math.round(71 * DefaultStyle.dp)
@ -1085,9 +1123,10 @@ AbstractWindow {
Layout.preferredHeight: Math.round(55 * DefaultStyle.dp) Layout.preferredHeight: Math.round(55 * DefaultStyle.dp)
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp)
icon.height: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp)
ToolTip.text: checked ? qsTr( //: "Reprendre l'appel"
"Reprendre l'appel") : qsTr( ToolTip.text: checked ? qsTr("call_action_resume_call")
"Mettre l'appel en pause") //: "Mettre l'appel en pause"
: qsTr("call_action_pause_call")
background: Rectangle { background: Rectangle {
anchors.fill: parent anchors.fill: parent
radius: Math.round(71 * DefaultStyle.dp) radius: Math.round(71 * DefaultStyle.dp)
@ -1117,7 +1156,8 @@ AbstractWindow {
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp)
icon.height: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp)
contentImageColor: DefaultStyle.grey_0 contentImageColor: DefaultStyle.grey_0
ToolTip.text: qsTr("Transférer l'appel") //: "Transférer l'appel"
ToolTip.text: qsTr("call_action_transfer_call")
onCheckedChanged: { onCheckedChanged: {
console.log("checked transfer changed", checked) console.log("checked transfer changed", checked)
if (checked) { if (checked) {
@ -1143,7 +1183,8 @@ AbstractWindow {
Layout.preferredHeight: Math.round(55 * DefaultStyle.dp) Layout.preferredHeight: Math.round(55 * DefaultStyle.dp)
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp)
icon.height: 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: { onCheckedChanged: {
console.log("checked newcall changed", checked) console.log("checked newcall changed", checked)
if (checked) { if (checked) {
@ -1169,7 +1210,8 @@ AbstractWindow {
icon.source: AppIcons.callList icon.source: AppIcons.callList
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp)
icon.height: 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: { onCheckedChanged: {
if (checked) { if (checked) {
rightPanel.visible = true rightPanel.visible = true
@ -1207,8 +1249,9 @@ AbstractWindow {
=== LinphoneEnums.CallState.StreamsRunning) === LinphoneEnums.CallState.StreamsRunning)
iconUrl: AppIcons.videoCamera iconUrl: AppIcons.videoCamera
checkedIconUrl: AppIcons.videoCameraSlash checkedIconUrl: AppIcons.videoCameraSlash
ToolTip.text: mainWindow.localVideoEnabled ? qsTr("Désactiver la vidéo") : qsTr( //: "Désactiver la vidéo"
"Activer la vidéo") //: "Activer la vidéo"
ToolTip.text: mainWindow.localVideoEnabled ? qsTr("call_deactivate_video_hint") : qsTr("call_activate_video_hint")
checked: !mainWindow.localVideoEnabled checked: !mainWindow.localVideoEnabled
Layout.preferredWidth: Math.round(55 * DefaultStyle.dp) Layout.preferredWidth: Math.round(55 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(55 * DefaultStyle.dp) Layout.preferredHeight: Math.round(55 * DefaultStyle.dp)
@ -1219,8 +1262,11 @@ AbstractWindow {
} }
CheckableButton { CheckableButton {
iconUrl: AppIcons.microphone iconUrl: AppIcons.microphone
ToolTip.text: mainWindow.call ToolTip.text: mainWindow.call && mainWindow.call.core.microphoneMuted
&& mainWindow.call.core.microphoneMuted ? qsTr("Activer le son") : qsTr("Désactiver le son") //: "Activer le micro"
? qsTr("call_activate_microphone")
//: "Désactiver le micro"
: qsTr("call_deactivate_microphone")
checkedIconUrl: AppIcons.microphoneSlash checkedIconUrl: AppIcons.microphoneSlash
checked: mainWindow.call checked: mainWindow.call
&& mainWindow.call.core.microphoneMuted && mainWindow.call.core.microphoneMuted
@ -1234,7 +1280,8 @@ AbstractWindow {
CheckableButton { CheckableButton {
iconUrl: AppIcons.screencast iconUrl: AppIcons.screencast
visible: !!mainWindow.conference 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.preferredWidth: Math.round(55 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(55 * DefaultStyle.dp) Layout.preferredHeight: Math.round(55 * DefaultStyle.dp)
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp)
@ -1252,7 +1299,8 @@ AbstractWindow {
visible: false visible: false
checkable: false checkable: false
iconUrl: AppIcons.handWaving 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.preferredWidth: Math.round(55 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(55 * DefaultStyle.dp) Layout.preferredHeight: Math.round(55 * DefaultStyle.dp)
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp)
@ -1261,7 +1309,8 @@ AbstractWindow {
CheckableButton { CheckableButton {
visible: false visible: false
iconUrl: AppIcons.smiley 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.preferredWidth: Math.round(55 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(55 * DefaultStyle.dp) Layout.preferredHeight: Math.round(55 * DefaultStyle.dp)
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp)
@ -1269,7 +1318,8 @@ AbstractWindow {
} }
CheckableButton { CheckableButton {
id: participantListButton id: participantListButton
ToolTip.text: qsTr("Gérer les participants") //: "Gérer les participants"
ToolTip.text: qsTr("call_manage_participants_hint")
visible: mainWindow.conference visible: mainWindow.conference
iconUrl: AppIcons.usersTwo iconUrl: AppIcons.usersTwo
Layout.preferredWidth: Math.round(55 * DefaultStyle.dp) Layout.preferredWidth: Math.round(55 * DefaultStyle.dp)
@ -1292,7 +1342,8 @@ AbstractWindow {
} }
PopupButton { PopupButton {
id: moreOptionsButton 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.preferredWidth: Math.round(55 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(55 * DefaultStyle.dp) Layout.preferredHeight: Math.round(55 * DefaultStyle.dp)
popup.topPadding: Math.round(20 * DefaultStyle.dp) popup.topPadding: Math.round(20 * DefaultStyle.dp)
@ -1320,7 +1371,8 @@ AbstractWindow {
icon.source: AppIcons.squaresFour icon.source: AppIcons.squaresFour
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp)
icon.height: 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 style: ButtonStyle.noBackground
onClicked: { onClicked: {
rightPanel.visible = true rightPanel.visible = true
@ -1331,7 +1383,8 @@ AbstractWindow {
IconLabelButton { IconLabelButton {
Layout.fillWidth: true Layout.fillWidth: true
icon.source: AppIcons.fullscreen 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.width: Math.round(32 * DefaultStyle.dp)
icon.height: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp)
checkable: true checkable: true
@ -1351,7 +1404,7 @@ AbstractWindow {
IconLabelButton { IconLabelButton {
Layout.fillWidth: true Layout.fillWidth: true
icon.source: AppIcons.dialer icon.source: AppIcons.dialer
text: qsTr("Dialer") text: qsTr("call_action_show_dialer")
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp)
icon.height: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp)
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
@ -1378,8 +1431,11 @@ AbstractWindow {
hoveredImageColor: contentImageColor hoveredImageColor: contentImageColor
contentImageColor: mainWindow.call contentImageColor: mainWindow.call
&& mainWindow.call.core.recording ? DefaultStyle.danger_500main : DefaultStyle.main2_500main && mainWindow.call.core.recording ? DefaultStyle.danger_500main : DefaultStyle.main2_500main
text: mainWindow.call text: mainWindow.call && mainWindow.call.core.recording
&& mainWindow.call.core.recording ? qsTr("Terminer l'enregistrement") : qsTr("Enregistrer l'appel") //: "Terminer l'enregistrement"
? qsTr("call_action_stop_recording")
//: "Enregistrer l'appel"
: qsTr("call_action_record")
textColor: mainWindow.call textColor: mainWindow.call
&& mainWindow.call.core.recording ? DefaultStyle.danger_500main : DefaultStyle.main2_500main && mainWindow.call.core.recording ? DefaultStyle.danger_500main : DefaultStyle.main2_500main
hoveredTextColor: textColor hoveredTextColor: textColor
@ -1403,8 +1459,11 @@ AbstractWindow {
contentImageColor: mainWindow.call contentImageColor: mainWindow.call
&& mainWindow.call.core.speakerMuted ? DefaultStyle.danger_500main : DefaultStyle.main2_500main && mainWindow.call.core.speakerMuted ? DefaultStyle.danger_500main : DefaultStyle.main2_500main
hoveredImageColor: contentImageColor hoveredImageColor: contentImageColor
text: mainWindow.call text: mainWindow.call && mainWindow.call.core.speakerMuted
&& mainWindow.call.core.speakerMuted ? qsTr("Activer le son") : qsTr("Désactiver le son") //: "Activer le son"
? qsTr("call_activate_speaker_hint")
//: "Désactiver le son"
: qsTr("call_deactivate_speaker_hint")
textColor: mainWindow.call textColor: mainWindow.call
&& mainWindow.call.core.speakerMuted ? DefaultStyle.danger_500main : DefaultStyle.main2_500main && mainWindow.call.core.speakerMuted ? DefaultStyle.danger_500main : DefaultStyle.main2_500main
hoveredTextColor: textColor hoveredTextColor: textColor
@ -1419,7 +1478,8 @@ AbstractWindow {
icon.source: AppIcons.settings icon.source: AppIcons.settings
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp)
icon.height: 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 style: ButtonStyle.noBackground
onClicked: { onClicked: {
rightPanel.visible = true rightPanel.visible = true

View file

@ -10,7 +10,7 @@ import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
AbstractWindow { AbstractWindow {
id: mainWindow id: mainWindow
// height: Math.round(982 * DefaultStyle.dp) // height: Math.round(982 * DefaultStyle.dp)
title: qsTr("Linphone") title: applicationName
// TODO : handle this bool when security mode is implemented // TODO : handle this bool when security mode is implemented
property bool firstConnection: true property bool firstConnection: true
@ -31,7 +31,12 @@ AbstractWindow {
function openMainPage(connectionSucceed){ function openMainPage(connectionSucceed){
if (mainWindowStackView.currentItem.objectName !== "mainPage") mainWindowStackView.replace(mainPage, StackView.Immediate) 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() { function goToCallHistory() {
openMainPage() openMainPage()
@ -47,7 +52,10 @@ AbstractWindow {
} }
function transferCallSucceed() { function transferCallSucceed() {
openMainPage() 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() { function initStackViewItem() {
if(accountProxy && accountProxy.isInitialized) { if(accountProxy && accountProxy.isInitialized) {
@ -93,7 +101,8 @@ AbstractWindow {
initStackViewItem() initStackViewItem()
} }
function onIsSavedChanged() { 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)
} }
} }
@ -177,14 +186,16 @@ AbstractWindow {
id: registerPage id: registerPage
RegisterPage { RegisterPage {
onReturnToLogin: goToLogin() 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 { Connections {
target: RegisterPageCpp target: RegisterPageCpp
function onNewAccountCreationSucceed(withEmail, address, sipIdentityAddress) { function onNewAccountCreationSucceed(withEmail, address, sipIdentityAddress) {
mainWindowStackView.push(checkingPage, {"registerWithEmail": withEmail, "address": address, "sipIdentityAddress": sipIdentityAddress}) mainWindowStackView.push(checkingPage, {"registerWithEmail": withEmail, "address": address, "sipIdentityAddress": sipIdentityAddress})
} }
function onRegisterNewAccountFailed(errorMessage) { 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() mainWindow.closeLoadingPopup()
} }
function onTokenConversionSucceed(){ mainWindow.closeLoadingPopup()} function onTokenConversionSucceed(){ mainWindow.closeLoadingPopup()}
@ -202,11 +213,15 @@ AbstractWindow {
target: RegisterPageCpp target: RegisterPageCpp
function onLinkingNewAccountWithCodeSucceed() { function onLinkingNewAccountWithCodeSucceed() {
goToLogin() 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) { function onLinkingNewAccountWithCodeFailed(errorMessage) {
if (errorMessage.length === 0) errorMessage = qsTr("Erreur dans le code de validation") //: "Erreur dans le code de validation"
mainWindow.showInformationPopup(qsTr("Erreur"), errorMessage, false) if (errorMessage.length === 0) errorMessage = qsTr("assistant_register_error_code")
mainWindow.showInformationPopup(qsTr("information_popup_error_title"), errorMessage, false)
} }
} }
} }

View file

@ -7,7 +7,7 @@ Window {
width: 960 width: 960
height: 600 height: 600
visible: true visible: true
title: qsTr("Test") title: ("Test")
ColumnLayout { ColumnLayout {
RowLayout { RowLayout {
ColumnLayout { ColumnLayout {
@ -134,7 +134,7 @@ Window {
TabBar { TabBar {
spacing: 10 spacing: 10
contentWidth: 400 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")]
} }
} }