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()
find_package(Qt6 REQUIRED COMPONENTS Core)
find_package(Qt6 REQUIRED COMPONENTS ${QT_PACKAGES})
find_package(Qt6 REQUIRED COMPONENTS LinguistTools)
if(NOT WIN32)
find_package(X11)
@ -124,6 +125,25 @@ add_subdirectory(model)
add_subdirectory(view)
add_subdirectory(core)
set(LANGUAGES_DIRECTORY "data/languages")
set(I18N_FILENAME i18n.qrc)
set(LANGUAGES en fr_FR)
# Add languages support.
add_subdirectory("${LANGUAGES_DIRECTORY}" "data/languages")
set(LANGUAGES en fr_FR)
qt_standard_project_setup(I18N_TRANSLATED_LANGUAGES ${LANGUAGES})
set(TS_FILES)
foreach (lang ${LANGUAGES})
list(APPEND TS_FILES "${CMAKE_CURRENT_SOURCE_DIR}/${LANGUAGES_DIRECTORY}/${lang}.ts")
endforeach()
qt_add_translations(${TARGET_NAME}
TS_FILES ${TS_FILES}
RESOURCE_PREFIX ${LANGUAGES_DIRECTORY})
# set application details
if(WIN32)
configure_file("${CMAKE_SOURCE_DIR}/cmake/install/windows/appDetailsWindows.rc.in" "${CMAKE_CURRENT_BINARY_DIR}/appDetailsWindows.rc")
@ -135,7 +155,7 @@ endif()
set(_LINPHONEAPP_FONTS_FILES)
qt6_add_big_resources(_LINPHONEAPP_FONTS_FILES data/fonts.qrc)
# Have big_resource.qrc treated as a source file by Qt Creator
# Have big_resource.qrc treated as a source file by Qt Creator
list(APPEND _LINPHONEAPP_FONTS_FILES data/fonts.qrc)
set_property(SOURCE data/fonts.qrc PROPERTY SKIP_AUTORCC ON)

View file

@ -35,6 +35,7 @@
#include <QQmlContext>
#include <QQmlFileSelector>
#include <QQuickWindow>
#include <QStandardPaths>
#include <QSystemTrayIcon>
#include <QTimer>
#include <QTranslator>
@ -76,6 +77,7 @@
#include "core/setting/SettingsCore.hpp"
#include "core/singleapplication/singleapplication.h"
#include "core/timezone/TimeZoneProxy.hpp"
#include "core/translator/DefaultTranslatorCore.hpp"
#include "core/variant/VariantList.hpp"
#include "core/videoSource/VideoSourceDescriptorGui.hpp"
#include "model/object/VariantObject.hpp"
@ -257,7 +259,7 @@ void App::setAutoStart(bool enabled) {
// -----------------------------------------------------------------------------
App::App(int &argc, char *argv[])
: SingleApplication(argc, argv, true, Mode::User | Mode::ExcludeAppPath | Mode::ExcludeAppVersion) {
: SingleApplication(argc, argv, true, Mode::User | Mode::ExcludeAppPath | Mode::ExcludeAppVersion) {
// Do not use APPLICATION_NAME here.
// The EXECUTABLE_NAME will be used in qt standard paths. It's our goal.
QThread::currentThread()->setPriority(QThread::HighPriority);
@ -319,8 +321,8 @@ void App::setSelf(QSharedPointer<App>(me)) {
mCoreModelConnection->makeConnectToModel(&CoreModel::requestFetchConfig, [this](QString path) {
mCoreModelConnection->invokeToCore([this, path]() {
auto callback = [this, path]() {
RequestDialog *obj = new RequestDialog(
tr("Voulez-vous télécharger et appliquer la configuration depuis cette adresse ?"), path);
//: Voulez-vous télécharger et appliquer la configuration depuis cette adresse ?
RequestDialog *obj = new RequestDialog(tr("remote_provisioning_dialog"), path);
connect(obj, &RequestDialog::result, this, [this, obj, path](int result) {
if (result == 1) {
mCoreModelConnection->invokeToModel(
@ -486,10 +488,10 @@ void App::initCore() {
mEngine->setObjectOwnership(settings.get(), QQmlEngine::CppOwnership);
mEngine->setObjectOwnership(this, QQmlEngine::CppOwnership);
if (!mAccountList) setAccountList(AccountList::create());
else {
mAccountList->setInitialized(false);
mAccountList->lUpdate(true);
}
else {
mAccountList->setInitialized(false);
mAccountList->lUpdate(true);
}
if (!mCallList) setCallList(CallList::create());
else mCallList->lUpdate();
if (!mSettings) {
@ -515,7 +517,11 @@ void App::initCore() {
setLocale(settings->getConfigLocale());
setAutoStart(settings->getAutoStart());
setQuitOnLastWindowClosed(settings->getExitOnClose());
}
}
// Init locale.
mTranslatorCore = new DefaultTranslatorCore(this);
mDefaultTranslatorCore = new DefaultTranslatorCore(this);
initLocale();
const QUrl url("qrc:/qt/qml/Linphone/view/Page/Window/Main/MainWindow.qml");
QObject::connect(
mEngine, &QQmlApplicationEngine::objectCreated, this,
@ -549,6 +555,52 @@ void App::initCore() {
Qt::BlockingQueuedConnection);
}
static inline bool installLocale(App &app, QTranslator &translator, const QLocale &locale) {
auto appPath = QStandardPaths::ApplicationsLocation;
bool ok = translator.load(locale.name(), Constants::LanguagePath);
ok = ok && app.installTranslator(&translator);
if (ok) QLocale::setDefault(locale);
return ok;
}
void App::initLocale() {
// Try to use preferred locale.
QString locale;
// Use english. This default translator is used if there are no found translations in others loads
mLocale = QLocale(QLocale::French);
if (!installLocale(*this, *mDefaultTranslatorCore, mLocale)) qFatal("Unable to install default translator.");
if (installLocale(*this, *mTranslatorCore, getLocale())) {
qDebug() << "installed locale" << getLocale().name();
return;
}
// Try to use system locale.
// #ifdef Q_OS_MACOS
// Use this workaround if there is still an issue about detecting wrong language from system on Mac. Qt doesn't use
// the current system language on QLocale::system(). So we need to get it from user settings and overwrite its
// Locale.
// QSettings settings;
// QString preferredLanguage = settings.value("AppleLanguages").toStringList().first();
// QStringList qtLocale = QLocale::system().name().split('_');
// if(qtLocale[0] != preferredLanguage){
// qInfo() << "Override Qt language from " << qtLocale[0] << " to the preferred language : " <<
// preferredLanguage; qtLocale[0] = preferredLanguage;
// }
// QLocale sysLocale = QLocale(qtLocale.join('_'));
// #else
QLocale sysLocale(QLocale::system().name()); // Use Locale from name because Qt has a bug where it didn't use the
// QLocale::language (aka : translator.language != locale.language) on
// Mac. #endif
if (installLocale(*this, *mTranslatorCore, sysLocale)) {
qDebug() << "installed sys locale" << sysLocale.name();
setLocale(sysLocale.name());
}
}
void App::initCppInterfaces() {
qmlRegisterSingletonType<App>(Constants::MainQmlUri, 1, 0, "AppCpp",
[](QQmlEngine *engine, QJSEngine *) -> QObject * { return App::getInstance(); });
@ -720,24 +772,35 @@ void App::createCommandParser() {
if (!mParser) delete mParser;
mParser = new QCommandLineParser();
mParser->setApplicationDescription(tr("A free (libre) SIP video-phone."));
mParser->addPositionalArgument(
"command", tr("Send an order to the application towards a command line").replace("%1", APPLICATION_NAME),
"[command]");
//: "A free and open source SIP video-phone."
mParser->setApplicationDescription(tr("application_description"));
//: "Send an order to the application towards a command line"
mParser->addPositionalArgument("command", tr("command_line_arg_order").replace("%1", APPLICATION_NAME), "[command]");
mParser->addOptions({
{{"h", "help"}, tr("Show this help")},
//: "Show this help"
{{"h", "help"}, tr("command_line_option_show_help")},
//{"cli-help", tr("commandLineOptionCliHelp").replace("%1", APPLICATION_NAME)},
{{"v", "version"}, tr("Show app version")},
//{"config", tr("commandLineOptionConfig").replace("%1", EXECUTABLE_NAME), tr("commandLineOptionConfigArg")},
//:"Show app version"
{{"v", "version"}, tr("command_line_option_show_app_version")},
//{"config", tr("command_line_option_config").replace("%1", EXECUTABLE_NAME), tr("command_line_option_config_arg")},
{"fetch-config",
tr("Specify the linphone configuration file to be fetched. It will be merged with the current "
"configuration.")
//: "Specify the linphone configuration file to be fetched. It will be merged with the current configuration."
tr("command_line_option_config_to_fetch")
.replace("%1", EXECUTABLE_NAME),
tr("URL, path or file")},
//{{"c", "call"}, tr("commandLineOptionCall").replace("%1", EXECUTABLE_NAME), tr("commandLineOptionCallArg")},
{"minimized", tr("commandLineOptionMinimized")},
{{"V", "verbose"}, tr("Log to stdout some debug information while running")},
{"qt-logs-only", tr("Print only logs from the application")},
//: "URL, path or file"
tr("command_line_option_config_to_fetch_arg")},
//{{"c", "call"}, tr("command_line_option_call").replace("%1", EXECUTABLE_NAME), tr("command_line_option_call_arg")}, {"minimized", tr("command_line_option_minimized")},
//: "Log to stdout some debug information while running"
{{"V", "verbose"}, tr("command_line_option_log_to_stdout")},
//: "Print only logs from the application"
{"qt-logs-only", tr("command_line_option_print_app_logs_only")},
});
}
// Should be call only at first start
@ -1003,7 +1066,7 @@ void App::exportDesktopFile() {
}
bool App::generateDesktopFile(const QString &confPath, bool remove, bool openInBackground) {
qInfo() << QStringLiteral("Updating `%1`...").arg(confPath);
qInfo() << QStringLiteral("Updating `%1`").arg(confPath);
QFile file(confPath);
if (remove) {
@ -1095,7 +1158,9 @@ void App::setSysTrayIcon() {
if (mSettings && !mSettings->getExitOnClose()) {
restoreAction = new QAction(root);
auto setRestoreActionText = [restoreAction](bool visible) {
restoreAction->setText(visible ? tr("Cacher") : tr("Afficher"));
//: "Cacher"
//: "Afficher"
restoreAction->setText(visible ? tr("hide_action") : tr("show_action"));
};
setRestoreActionText(root->isVisible());
connect(root, &QWindow::visibleChanged, restoreAction, setRestoreActionText);
@ -1109,8 +1174,8 @@ void App::setSysTrayIcon() {
}
});
}
QAction *quitAction = new QAction(tr("Quitter"), root);
//: "Quitter"
QAction *quitAction = new QAction(tr("quit_action"), root);
root->connect(quitAction, &QAction::triggered, this, &App::quit);
// trayIcon: Left click actions.
@ -1146,7 +1211,8 @@ void App::setSysTrayIcon() {
//-----------------------------------------------------------
void App::setLocale(QString configLocale) {
mLocale = QLocale(QLocale::French);
if (configLocale.isEmpty()) mLocale = QLocale(configLocale);
else mLocale = QLocale(QLocale::system().name());
}
QLocale App::getLocale() {
@ -1157,11 +1223,12 @@ QLocale App::getLocale() {
// Version infos.
//-----------------------------------------------------------
//: "Inconnue"
QString App::getShortApplicationVersion() {
#ifdef LINPHONEAPP_SHORT_VERSION
return QStringLiteral(LINPHONEAPP_SHORT_VERSION);
#else
return tr("inconnue");
return tr('unknown');
#endif
}
@ -1169,7 +1236,7 @@ QString App::getGitBranchName() {
#ifdef GIT_BRANCH_NAME
return QStringLiteral(GIT_BRANCH_NAME);
#else
return tr("inconnue");
return tr('unknown');
#endif
}
@ -1177,6 +1244,6 @@ QString App::getSdkVersion() {
#ifdef LINPHONESDK_VERSION
return QStringLiteral(LINPHONESDK_VERSION);
#else
return tr("inconnue");
return tr('unknown');
#endif
}

View file

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

View file

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

View file

@ -403,16 +403,21 @@ int AccountCore::getDialPlanIndex(QVariantMap dialPlanString) {
QString AccountCore::getHumanReadableRegistrationState() const {
switch (mRegistrationState) {
case LinphoneEnums::RegistrationState::Ok:
return tr("Connecté");
//: "Connecté"
return tr("drawer_menu_account_connection_status_connected");
case LinphoneEnums::RegistrationState::Refreshing:
return tr("En cours de rafraîchissement…");
// "En cours de rafraîchissement…"
return tr("drawer_menu_account_connection_status_refreshing");
case LinphoneEnums::RegistrationState::Progress:
return tr("En cours de connexion…");
// "Connexion…"
return tr("drawer_menu_account_connection_status_progress");
case LinphoneEnums::RegistrationState::Failed:
return tr("Erreur");
// "Erreur"
return tr("drawer_menu_account_connection_status_failed");
case LinphoneEnums::RegistrationState::None:
case LinphoneEnums::RegistrationState::Cleared:
return tr("Désactivé");
// "Désactivé"
return tr("drawer_menu_account_connection_status_cleared");
default:
return " ";
}
@ -421,12 +426,15 @@ QString AccountCore::getHumanReadableRegistrationState() const {
QString AccountCore::getHumanReadableRegistrationStateExplained() const {
switch (mRegistrationState) {
case LinphoneEnums::RegistrationState::Ok:
return tr("Vous êtes en ligne et joignable.");
//: "Vous êtes en ligne et joignable."
return tr("manage_account_status_connected_summary");
case LinphoneEnums::RegistrationState::Failed:
return tr("Erreur de connexion, vérifiez vos paramètres.");
//: "Erreur de connexion, vérifiez vos paramètres."
return tr("manage_account_status_failed_summary");
case LinphoneEnums::RegistrationState::None:
case LinphoneEnums::RegistrationState::Cleared:
return tr("Compte désactivé, vous ne recevrez ni appel ni message.");
//: "Compte désactivé, vous ne recevrez ni appel ni message."
return tr("manage_account_status_cleared_summary");
default:
return " ";
}

View file

@ -154,7 +154,8 @@ void AccountDeviceList::setSelf(QSharedPointer<AccountDeviceList> me) {
lDebug() << "REQUEST ERROR" << errorMessage << "/" << int(request->getType());
QString message = QString::fromStdString(errorMessage);
if (request->getType() == linphone::AccountManagerServicesRequest::Type::GetDevicesList) {
message = tr("Erreur lors de la récupération des appareils");
//: "Erreur lors de la récupération des appareils"
message = tr("manage_account_no_device_found_error_message");
}
emit requestError(message);
});

View file

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

View file

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

View file

@ -573,7 +573,9 @@ void ConferenceInfoCore::save() {
mCoreModelConnection->invokeToModel([this, thisCopy]() {
if (CoreModel::getInstance()->getCore()->getDefaultAccount()->getState() !=
linphone::RegistrationState::Ok) {
Utils::showInformationPopup(tr("Erreur"), tr("Votre compte est déconnecté"), false);
//: "Erreur"
//: "Votre compte est déconnecté"
Utils::showInformationPopup(tr("information_popup_error_title"), tr("information_popup_disconnected_account_message"), false);
emit saveFailed();
return;
}

View file

@ -26,8 +26,10 @@
DEFINE_ABSTRACT_OBJECT(FriendCore)
const QString _addressLabel = FriendCore::tr("Adresse SIP");
const QString _phoneLabel = FriendCore::tr("Téléphone");
//: "Adresse SIP"
const QString _addressLabel = FriendCore::tr("sip_address");
//: "Téléphone"
const QString _phoneLabel = FriendCore::tr("device_id");
QSharedPointer<FriendCore>
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 interpretedAddress = linphoneAddr ? Utils::coreStringToAppString(linphoneAddr->asStringUriOnly()) : "";
mCoreModelConnection->invokeToCore([this, interpretedAddress, interpretedFullAddress]() {
if (interpretedAddress.isEmpty()) Utils::showInformationPopup(tr("Erreur"), tr("Adresse invalide"), false);
//: "Adresse invalide"
if (interpretedAddress.isEmpty()) Utils::showInformationPopup(tr("information_popup_error_title"), tr("information_popup_invalid_address_message"), false);
else {
mAddressList.append(Utils::createFriendAddressVariant(_addressLabel, interpretedAddress));
if (mDefaultFullAddress.isEmpty()) mDefaultFullAddress = interpretedFullAddress;

View file

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

View file

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

View file

@ -84,7 +84,7 @@ void DownloadablePayloadTypeCore::setSelf(QSharedPointer<DownloadablePayloadType
void DownloadablePayloadTypeCore::downloadAndExtract(bool isUpdate) {
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();
QString versionFilePath = codecsFolder + mMimeType + ".txt";
QFile versionFile(versionFilePath);

View file

@ -123,7 +123,7 @@ void MagicSearchList::setSelf(QSharedPointer<MagicSearchList> me) {
linphoneFriend->addPhoneNumber(phoneNumber);
contact = FriendCore::create(linphoneFriend, isStored, it->getSourceFlags());
contact->setGivenName(Utils::coreStringToAppString(it->getPhoneNumber()));
contact->appendPhoneNumber(tr("Phone"), Utils::coreStringToAppString(it->getPhoneNumber()));
contact->appendPhoneNumber(tr("device_id"), Utils::coreStringToAppString(it->getPhoneNumber()));
contacts->append(contact);
}
}

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)
list(APPEND _LINPHONEAPP_RC_FILES data/image/${filename})
endforeach()
#file(GLOB files LIST_DIRECTORIES false languages/*)
#foreach(f ${files})
# get_filename_component(filename ${f} NAME)
# list(APPEND _LINPHONEAPP_RC_FILES data/languages/${filename})
#endforeach()
set(_LINPHONEAPP_RC_FILES ${_LINPHONEAPP_RC_FILES} PARENT_SCOPE)

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

View file

@ -334,16 +334,32 @@ void CallModel::updateCallErrorFromReason(linphone::Reason reason) {
QString error;
switch (reason) {
case linphone::Reason::Declined:
error = tr("Le correspondant a décliné l'appel");
//: "Le correspondant a décliné l'appel"
error = tr("call_error_user_declined_toast");
break;
case linphone::Reason::NotFound:
error = tr("Le correspondant n'a pas été trouvé");
//: "Le correspondant n'a pas été trouvé"
error = tr("call_error_user_not_found_toast");
break;
case linphone::Reason::Busy:
error = tr("Le correspondant est occupé");
//: "Le correspondant est occupé"
error = tr("call_error_user_busy_toast");
break;
case linphone::Reason::NotAcceptable:
error = tr("Le correspondant ne peut accepter votre appel.");
//: "Le correspondant ne peut accepter votre appel."
error = tr("call_error_incompatible_media_params_toast");
break;
case linphone::Reason::IOError:
//: "Service indisponible ou erreur réseau"
error = tr("call_error_io_error_toast");
break;
case linphone::Reason::TemporarilyUnavailable:
//: "Temporairement indisponible"
error = tr("call_error_temporarily_unavailable_toast");
break;
case linphone::Reason::ServerTimeout:
//: "Délai d'attente du serveur dépassé"
error = tr("call_error_server_timeout_toast");
break;
default:
break;

View file

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

View file

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

View file

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

View file

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

View file

@ -147,8 +147,9 @@ void Utils::createCall(const QString &sipAddress,
bool success = ToolModel::createCall(sipAddress, options, prepareTransfertAddress, headers,
LinphoneEnums::toLinphone(mediaEncryption), &errorMessage);
if (!success) {
if (errorMessage.isEmpty()) errorMessage = tr("L'appel n'a pas pu être créé");
showInformationPopup("Erreur", errorMessage, false);
//: "L'appel n'a pas pu être créé"
if (errorMessage.isEmpty()) errorMessage = tr("information_popup_call_not_created_message");
showInformationPopup("information_popup_error_title", errorMessage, false);
}
});
}
@ -265,13 +266,17 @@ QString Utils::formatElapsedTime(int seconds, bool dotsSeparator) {
// s, m, h, d, W, M, Y
// 1, 60, 3600, 86400, 604800, 2592000, 31104000
auto y = floor(seconds / 31104000);
if (y > 0) return tr("%n year(s)", "", y);
//: %n an(s)
if (y > 0) return tr("number_of_years", "", y);
auto M = floor(seconds / 2592000);
if (M > 0) return tr("%n month(s)", "", M);
//: "%n mois"
if (M > 0) return tr("number_of_month", "", M);
auto w = floor(seconds / 604800);
if (w > 0) return tr("%n week(s)", "", w);
//: %n semaine(s)
if (w > 0) return tr("number_of_weeks", "", w);
auto d = floor(seconds / 86400);
if (d > 0) return tr("%n day(s)", "", d);
//: %n jour(s)
if (d > 0) return tr("number_of_days", "", d);
auto h = floor(seconds / 3600);
auto m = floor((seconds - h * 3600) / 60);
@ -294,8 +299,10 @@ QString Utils::formatElapsedTime(int seconds, bool dotsSeparator) {
QString Utils::formatDate(const QDateTime &date, bool includeTime) {
QString dateDay;
if (date.date() == QDate::currentDate()) dateDay = tr("Aujourd'hui");
else if (date.date() == QDate::currentDate().addDays(-1)) dateDay = tr("Hier");
//: "Aujourd'hui"
if (date.date() == QDate::currentDate()) dateDay = tr("today");
//: "Hier
else if (date.date() == QDate::currentDate().addDays(-1)) dateDay = tr("yesterday");
else {
QString format = date.date().year() == QDateTime::currentDateTime(date.timeZone()).date().year()
? "dd MMMM"
@ -436,7 +443,8 @@ QString Utils::generateSavedFilename(const QString &from, const QString &to) {
QStringList Utils::generateSecurityLettersArray(int arraySize, int correctIndex, QString correctCode) {
QStringList vec;
const QString possibleCharacters(tr("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"));
//: "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
const QString possibleCharacters(tr("call_zrtp_token_verification_possible_characters"));
const int n = 2;
for (int i = 0; i < arraySize; ++i) {
QString randomString;

View file

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

View file

@ -6,7 +6,7 @@ import Linphone
Control.ComboBox {
id: mainItem
// Usage : each item of the model list must be {text: ..., img: ...}
// Usage : each item of the model list must be {text: , img: }
// If string list, only text part of the delegate will be filled
// readonly property string currentText: selectedItemText.text
property alias listView: listView

View file

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

View file

@ -53,11 +53,14 @@ Item {
z: 1
visible: mainItem.callState === LinphoneEnums.CallState.End || mainItem.callState === LinphoneEnums.CallState.Error || mainItem.callState === LinphoneEnums.CallState.Released
text: mainItem.conference
? qsTr("Vous avez quitté la conférence")
: mainItem.callTerminatedByUser
? qsTr("Vous avez terminé l'appel")
: mainItem.callStarted
? qsTr("Votre correspondant a terminé l'appel")
//: "Vous avez quitté la conférence"
? qsTr("meeting_event_conference_destroyed")
: mainItem.callTerminatedByUser
//: "Vous avez terminé l'appel"
? qsTr("call_ended_by_user")
: mainItem.callStarted
//: "Votre correspondant a terminé l'appel"
? qsTr("call_ended_by_remote")
: call && call.core.lastErrorMessage || ""
color: DefaultStyle.grey_0
font {
@ -85,7 +88,8 @@ Item {
width: waitText.implicitWidth
Text {
id: waitText
text: qsTr("Waiting for other participants...")
//: "En attente d'autres participants"
text: qsTr("conference_call_empty")
Layout.preferredHeight: Math.round(67 * DefaultStyle.dp)
Layout.alignment: Qt.AlignHCenter
horizontalAlignment: Text.AlignHCenter
@ -102,13 +106,15 @@ Item {
borderColor: DefaultStyle.main2_400
icon.source: AppIcons.shareNetwork
contentImageColor: DefaultStyle.main2_400
text: qsTr("Share invitation")
//: "Partager le lien"
text: qsTr("conference_share_link_title")
anchors.centerIn: parent
textColor: DefaultStyle.main2_400
onClicked: {
if (mainItem.conference) {
UtilsCpp.copyToClipboard(mainItem.call.core.remoteAddress)
showInformationPopup(qsTr("Copié"), qsTr("Le lien de la réunion a été copié dans le presse-papier"), true)
//: Le lien de la réunion a été copié dans le presse-papier
showInformationPopup(qsTr("copied"), qsTr("information_popup_meeting_address_copied_to_clipboard"), true)
}
}
}
@ -134,23 +140,3 @@ Item {
}
}
}
// TODO : waitingForParticipant
// ColumnLayout {
// id: waitingForParticipant
// Text {
// text: qsTr("Waiting for other participants...")
// color: DefaultStyle.frey_0
// font {
// pixelSize: Math.round(30 * DefaultStyle.dp)
// weight: Math.round(300 * DefaultStyle.dp)
// }
// }
// Button {
// text: qsTr("Share invitation")
// icon.source: AppIcons.shareNetwork
// color: DefaultStyle.main2_400
// Layout.preferredWidth: Math.round(206 * DefaultStyle.dp)
// Layout.preferredHeight: Math.round(47 * DefaultStyle.dp)
// }
// }

View file

@ -49,12 +49,16 @@ ListView {
}
Text {
id: callStateText
property string type: modelData.core.isConference ? qsTr('Réunion') : qsTr('Appel')
//: "Réunion
//: "Appel"
property string type: modelData.core.isConference ? qsTr("meeting") : qsTr("call")
Layout.rightMargin: Math.round(2 * DefaultStyle.dp)
text: modelData.core.state === LinphoneEnums.CallState.Paused
|| modelData.core.state === LinphoneEnums.CallState.PausedByRemote
? type + qsTr(" en pause")
: type + qsTr(" en cours")
//: "%1 en pause"
? qsTr("paused_call_or_meeting").arg(type)
//: "%1 en cours"
: qsTr("ongoing_call_or_meeting").arg(type)
font {
pixelSize: Math.round(12 * DefaultStyle.dp)
weight: Math.round(300 * DefaultStyle.dp)

View file

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

View file

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

View file

@ -13,7 +13,9 @@ Control.Control{
id: mainItem
padding: Math.round(10 * DefaultStyle.dp)
property AccountGui account
property color backgroundColor: DefaultStyle.grey_0
property color backgroundColor: DefaultStyle.grey_0
leftPadding: Math.round(8 * DefaultStyle.dp)
rightPadding: Math.round(8 * DefaultStyle.dp)
signal avatarClicked()
signal backgroundClicked()
@ -56,6 +58,7 @@ Control.Control{
Control.Control {
id: registrationStatusItem
Layout.minimumWidth: Math.round(49 * DefaultStyle.dp)
Layout.maximumWidth: 150
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp)
topPadding: Math.round(4 * DefaultStyle.dp)
bottomPadding: Math.round(4 * DefaultStyle.dp)
@ -70,8 +73,10 @@ Control.Control{
}
contentItem: Text {
id: text
anchors.fill: parent
verticalAlignment: Text.AlignVCenter
anchors.fill: parent
anchors.leftMargin: registrationStatusItem.leftPadding
anchors.rightMargin: registrationStatusItem.rightPadding
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
visible: mainItem.account
property int mode : !mainItem.account || mainItem.account.core.registrationState == LinphoneEnums.RegistrationState.Ok
@ -98,12 +103,16 @@ Control.Control{
? DefaultStyle.main2_500main
: DefaultStyle.danger_500main
text: mode == 0
? qsTr("Connecté")
//: "Connecté"
? qsTr("drawer_menu_account_connection_status_connected")
: mode == 1
? qsTr("Désactivé")
//: "Désactivé"
? qsTr("drawer_menu_account_connection_status_cleared")
: mode == 2
? qsTr("Connexion...")
: qsTr("Erreur")
//: "Connexion"
? qsTr("drawer_menu_account_connection_status_refreshing")
//: "Erreur"
: qsTr("drawer_menu_account_connection_status_failed")
}
}
Item{
@ -156,7 +165,10 @@ Control.Control{
if (mainItem.account.core.voicemailAddress.length > 0)
UtilsCpp.createCall(mainItem.account.core.voicemailAddress)
else
UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("L'URI de messagerie vocale n'est pas définie."), false)
//: Erreur
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
//: L'URI de messagerie vocale n'est pas définie.
qsTr("information_popup_voicemail_address_undefined_message"), false)
}
}
Item{Layout.fillWidth: true}

View file

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

View file

@ -243,7 +243,8 @@ ListView {
}
}
Text {
text: itemDelegate.isCanceled ? qsTr("Réunion annulée") : UtilsCpp.toDateHourString(dateTime) + " - " + UtilsCpp.toDateHourString(endDateTime)
//: "Réunion annulée"
text: itemDelegate.isCanceled ? qsTr("meeting_info_cancelled") : UtilsCpp.toDateHourString(dateTime) + " - " + UtilsCpp.toDateHourString(endDateTime)
color: itemDelegate.isCanceled ? DefaultStyle.danger_500main : DefaultStyle.main2_500main
font {
pixelSize: Typography.p1.pixelSize
@ -266,7 +267,8 @@ ListView {
anchors.leftMargin: Math.round(16 * DefaultStyle.dp)
verticalAlignment: Text.AlignVCenter
visible: !itemDelegate.haveModel
text: qsTr("Aucune réunion aujourd'hui")
//: "Aucune réunion aujourd'hui"
text: qsTr("meetings_list_no_meeting_for_today")
lineHeightMode: Text.FixedHeight
lineHeight: Math.round(18 * DefaultStyle.dp)
font {

View file

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

View file

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

View file

@ -17,21 +17,16 @@ FocusScope {
anchors.leftMargin: Math.round(17 * DefaultStyle.dp)
anchors.rightMargin: Math.round(17 * DefaultStyle.dp)
spacing: Math.round(12 * DefaultStyle.dp)
// Text {
// Layout.fillWidth: true
// text: qsTr("La disposition choisie sera enregistrée pour vos prochaines réunions")
// font.pixelSize: Math.round(14 * DefaultStyle.dp)
// color: DefaultStyle.main2_500main
// }
RoundedPane {
Layout.fillWidth: true
contentItem: ColumnLayout {
spacing: 0
Repeater {
model: [
{text: qsTr("Mosaïque"), imgUrl: AppIcons.squaresFour},
{text: qsTr("Intervenant actif"), imgUrl: AppIcons.pip},
{text: qsTr("Audio seulement"), imgUrl: AppIcons.waveform}
{text: qsTr("conference_layout_grid"), imgUrl: AppIcons.squaresFour},
{text: qsTr("conference_layout_active_speaker"), imgUrl: AppIcons.pip},
{text: qsTr("conference_layout_audio_only"), imgUrl: AppIcons.waveform}
]
RadioButton {
id: radiobutton

View file

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

View file

@ -18,7 +18,8 @@ ColumnLayout {
contentItem: ColumnLayout {
spacing: Math.round(12 * DefaultStyle.dp)
Text {
text: qsTr("Chiffrement :")
//: "Chiffrement :"
text: qsTr("call_stats_media_encryption_title")
Layout.alignment: Qt.AlignHCenter
font {
pixelSize: Math.round(12 * DefaultStyle.dp)
@ -30,7 +31,9 @@ ColumnLayout {
spacing: Math.round(7 * DefaultStyle.dp)
Text {
property bool isPostQuantum: mainItem.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp && mainItem.call.core.zrtpStats.isPostQuantum
text: qsTr("Chiffrement du média : %1%2").arg(isPostQuantum ? "post Quantum " : "").arg(mainItem.call.core.encryptionString)
//: "Chiffrement du média : %1%2"
//: "ZRTP Post Quantique"
text: qsTr("call_stats_media_encryption").arg(isPostQuantum ? tr("call_stats_media_encryption_zrtp_post_quantum") : mainItem.call.core.encryptionString)
Layout.alignment: Qt.AlignHCenter
font {
pixelSize: Math.round(12 * DefaultStyle.dp)
@ -40,7 +43,8 @@ ColumnLayout {
ColumnLayout {
visible: mainItem.call && mainItem.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp
Text {
text: qsTr("Cipher algorithm : %1").arg(mainItem.call && mainItem.call.core.zrtpStats.cipherAlgo)
//: "Algorithme de chiffrement : %1"
text: qsTr("call_stats_zrtp_cipher_algo").arg(mainItem.call && mainItem.call.core.zrtpStats.cipherAlgo)
Layout.alignment: Qt.AlignHCenter
font {
pixelSize: Math.round(12 * DefaultStyle.dp)
@ -48,7 +52,8 @@ ColumnLayout {
}
}
Text {
text: qsTr("Key agreement algorithm : %1").arg(mainItem.call && mainItem.call.core.zrtpStats.keyAgreementAlgo)
//: "Algorithme d'accord de clé : %1"
text: qsTr("call_stats_zrtp_key_agreement_algo").arg(mainItem.call && mainItem.call.core.zrtpStats.keyAgreementAlgo)
Layout.alignment: Qt.AlignHCenter
font {
pixelSize: Math.round(12 * DefaultStyle.dp)
@ -56,7 +61,8 @@ ColumnLayout {
}
}
Text {
text: qsTr("Hash algorithm : %1").arg(mainItem.call && mainItem.call.core.zrtpStats.hashAlgo)
//: "Algorithme de hachage : %1"
text: qsTr("call_stats_zrtp_hash_algo").arg(mainItem.call && mainItem.call.core.zrtpStats.hashAlgo)
Layout.alignment: Qt.AlignHCenter
font {
pixelSize: Math.round(12 * DefaultStyle.dp)
@ -64,7 +70,8 @@ ColumnLayout {
}
}
Text {
text: qsTr("Authentication algorithm : %1").arg(mainItem.call && mainItem.call.core.zrtpStats.authenticationAlgo)
//: "Algorithme d'authentification : %1"
text: qsTr("call_stats_zrtp_auth_tag_algo").arg(mainItem.call && mainItem.call.core.zrtpStats.authenticationAlgo)
Layout.alignment: Qt.AlignHCenter
font {
pixelSize: Math.round(12 * DefaultStyle.dp)
@ -72,7 +79,8 @@ ColumnLayout {
}
}
Text {
text: qsTr("SAS algorithm : %1").arg(mainItem.call && mainItem.call.core.zrtpStats.sasAlgo)
//: "Algorithme SAS : %1"
text: qsTr("call_stats_zrtp_sas_algo").arg(mainItem.call && mainItem.call.core.zrtpStats.sasAlgo)
Layout.alignment: Qt.AlignHCenter
font {
pixelSize: Math.round(12 * DefaultStyle.dp)
@ -87,7 +95,8 @@ ColumnLayout {
Button {
visible: mainItem.call && !mainItem.call.core.conference && mainItem.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp
Layout.fillWidth: true
text: qsTr("Validation chiffrement")
//: "Validation chiffrement"
text: qsTr("call_zrtp_validation_button_label")
onClicked: mainItem.encryptionValidationRequested()
Layout.bottomMargin: Math.round(13 * DefaultStyle.dp)
Layout.leftMargin: Math.round(16 * DefaultStyle.dp)

View file

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

View file

@ -19,7 +19,8 @@ ColumnLayout {
onIsLocalScreenSharingChanged: {if(isLocalScreenSharing) mainItem.call.core.videoSourceDescriptor = mainItem.desc }
Text {
Layout.fillWidth: true
text: qsTr("Veuillez choisir lécran ou la fenêtre que vous souihaitez partager au autres participants")
//: "Veuillez choisir lécran ou la fenêtre que vous souihaitez partager au autres participants"
text: qsTr("screencast_settings_choose_window_text")
font.pixelSize: Math.round(14 * DefaultStyle.dp)
color: DefaultStyle.main2_500main
}
@ -27,7 +28,10 @@ ColumnLayout {
Layout.fillWidth: true
id: bar
pixelSize: Math.round(16 * DefaultStyle.dp)
model: [qsTr("Ecran entier"), qsTr("Fenêtre")]
//: "Ecran entier"
model: [qsTr("screencast_settings_all_screen_label"),
//: "Fenêtre"
qsTr("screencast_settings_one_window_label")]
}
component ScreenPreviewLayout: Control.Control {
id: screenPreview
@ -84,7 +88,8 @@ ColumnLayout {
}
Text {
Layout.fillWidth: true
text: !!$modelData?.windowId ? $modelData.name : qsTr("Ecran %1").arg(screenIndex+1)
//: "Ecran %1"
text: !!$modelData?.windowId ? $modelData.name : qsTr("screencast_settings_screen").arg(screenIndex+1)
horizontalAlignment: Text.AlignHCenter
font.pixelSize: Math.round((displayScreen ? 14 : 10) * DefaultStyle.dp)
elide: Text.ElideRight
@ -156,11 +161,13 @@ ColumnLayout {
}
}
Button {
visible: mainItem.screenSharingAvailable
visible: mainItem.screenSharingAvailable$
enabled: windowsLayout.currentIndex !== -1 || screensLayout.currentIndex !== -1
text: mainItem.conference && mainItem.conference.core.isLocalScreenSharing
? qsTr("Stop")
: qsTr("Partager")
//: "Stop
? qsTr("stop")
//: "Partager"
: qsTr("share")
onClicked: mainItem.conference.core.lToggleScreenSharing()
style: ButtonStyle.main
}

View file

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

View file

@ -35,63 +35,55 @@ Dialog {
content: ColumnLayout {
spacing:Math.round( 20 * DefaultStyle.dp)
id: contentLayout
Text {
Layout.fillWidth: true
Layout.preferredWidth:Math.round( 250 * DefaultStyle.dp)
Layout.alignment: Qt.AlignHCenter
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.Wrap
font {
pixelSize: Typography.h3.pixelSize
weight: Typography.h3.weight
}
//: "Authentification requise"
text: qsTr("account_settings_dialog_invalid_password_title")
}
Text {
Layout.fillWidth: true
Layout.preferredWidth:Math.round( 250 * DefaultStyle.dp)
Layout.alignment: Qt.AlignHCenter
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.Wrap
text: qsTr("Impossible de vous authentifier. Merci de vérifier votre mot de passe.")
//: La connexion a échoué pour le compte %1. Vous pouvez renseigner votre mot de passe à nouveau ou bien vérifier les options de configuration de votre compte.
text: qsTr("account_settings_dialog_invalid_password_message").arg(mainItem.identity)
font.pixelSize:Math.round( 16 * DefaultStyle.dp)
font {
pixelSize: Typography.h4.pixelSize
weight: Typography.h4.weight
}
}
ColumnLayout {
spacing:Math.round( 10 * DefaultStyle.dp)
FormItemLayout {
Layout.fillWidth: true
label: qsTr("Identité")
contentItem: TextField {
enabled: false
initialText: mainItem.identity
}
}
FormItemLayout {
Layout.fillWidth: true
label: qsTr("Domaine")
contentItem: TextField {
enabled: false
initialText: mainItem.domain
}
}
FormItemLayout {
Layout.fillWidth: true
label: qsTr("Nom d'utilisateur (optionnel)")
contentItem: TextField {
id: usernameEdit
KeyNavigation.down: passwordEdit
}
}
FormItemLayout {
id: passwordItem
Layout.fillWidth: true
label: qsTr("Mot de passe")
enableErrorText: true
mandatory: true
contentItem: TextField {
id: passwordEdit
hidden: true
isError: passwordItem.errorTextVisible
KeyNavigation.up: usernameEdit
KeyNavigation.down: cancelButton
}
}
}
FormItemLayout {
id: passwordItem
Layout.fillWidth: true
label: qsTr("password")
enableErrorText: true
mandatory: true
contentItem: TextField {
id: passwordEdit
hidden: true
isError: passwordItem.errorTextVisible
KeyNavigation.up: usernameEdit
KeyNavigation.down: cancelButton
}
}
}
buttons: [
MediumButton {
id: cancelButton
Layout.topMargin: Math.round( 10 * DefaultStyle.dp)
text: qsTr("Annuler")
//: "Annuler
text: qsTr("cancel")
style: ButtonStyle.secondary
onClicked: mainItem.rejected()
KeyNavigation.up: passwordEdit
@ -100,14 +92,16 @@ Dialog {
MediumButton {
id: connectButton
Layout.topMargin:Math.round( 10 * DefaultStyle.dp)
text: qsTr("Se connecter")
//: Connexion
text: qsTr("assistant_account_login")
style: ButtonStyle.main
KeyNavigation.up: passwordEdit
KeyNavigation.right: cancelButton
onClicked: {
passwordItem.errorMessage = ""
if (passwordEdit.text.length == 0) {
passwordItem.errorMessage = qsTr("Veuillez saisir un mot de passe")
if (passwordEdit.text.length == 0) {
//: Veuillez saisir un mot de passe
passwordItem.errorMessage = qsTr("assistant_account_login_missing_password")
return
}
mainItem.accepted()

View file

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

View file

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

View file

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

View file

@ -85,7 +85,8 @@ Notification {
}
}
Text {
text: qsTr("Appel audio")
//: "Appel entrant"
text: qsTr("call_audio_incoming")
Layout.alignment: Qt.AlignHCenter
color: DefaultStyle.grey_0
font {
@ -107,7 +108,8 @@ Notification {
asynchronous: false
icon.width: Math.round(19 * DefaultStyle.dp)
icon.height: Math.round(19 * DefaultStyle.dp)
text: qsTr("Répondre")
//: "Accepter"
text: qsTr("dialog_accept")
textSize: Math.round(14 * DefaultStyle.dp)
textWeight: Math.round(500 * DefaultStyle.dp)
onClicked: {
@ -124,7 +126,8 @@ Notification {
asynchronous: false
icon.width: Math.round(19 * DefaultStyle.dp)
icon.height: Math.round(19 * DefaultStyle.dp)
text: qsTr("Refuser")
//: "Refuser
text: qsTr("dialog_deny")
textSize: Math.round(14 * DefaultStyle.dp)
textWeight: Math.round(500 * DefaultStyle.dp)
onClicked: {

View file

@ -686,35 +686,48 @@ function computeAvatarSize (container, maxSize, ratio) {
function openCodecOnlineInstallerDialog (mainWindow, coreObject, cancelCallBack, successCallBack, errorCallBack) {
mainWindow.showConfirmationLambdaPopup("",
qsTr("Installation de codec"),
qsTr("Télécharger le codec ") + capitalizeFirstLetter(coreObject.mimeType) + " ("+coreObject.encoderDescription+")"+" ?",
//: "Installation de codec"
qsTr("codec_install"),
//: "Télécharger le codec %1 (%2) ?"
qsTr("download_codec").arg(capitalizeFirstLetter(coreObject.mimeType)).arg(coreObject.encoderDescription),
function (confirmed) {
if (confirmed) {
coreObject.loaded.connect(function(success) {
mainWindow.closeLoadingPopup()
if (success) {
mainWindow.showInformationPopup(qsTr("Succès"), qsTr("Le codec a été installé avec succès."), true)
//: "Succès"
mainWindow.showInformationPopup(qsTr("information_popup_success_title"),
//: "Le codec a été installé avec succès."
qsTr("information_popup_codec_install_success_text"), true)
if (successCallBack)
successCallBack()
} else {
mainWindow.showInformationPopup(qsTr("Erreur"), qsTr("Le codec n'a pas pu être installé."), false)
mainWindow.showInformationPopup(qsTr("information_popup_error_title"),
//: "Le codec n'a pas pu être installé."
qsTr("information_popup_codec_install_error_text"), false)
if (errorCallBack)
errorCallBack()
}
})
coreObject.extractError.connect(function() {
mainWindow.closeLoadingPopup()
mainWindow.showInformationPopup(qsTr("Erreur"), qsTr("Le codec n'a pas pu être sauvegardé."), false)
mainWindow.showInformationPopup(qsTr("information_popup_error_title"),
//: "Le codec n'a pas pu être sauvegardé."
qsTr("information_popup_codec_save_error_text"), false)
if (errorCallBack)
errorCallBack()
})
coreObject.downloadError.connect(function() {
mainWindow.closeLoadingPopup()
mainWindow.showInformationPopup(qsTr("Erreur"), qsTr("Le codec n'a pas pu être téléchargé."), false)
mainWindow.showInformationPopup(qsTr("information_popup_error_title"),
//: "Le codec n'a pas pu être téléchargé."
qsTr("information_popup_codec_download_error_text"), false)
if (errorCallBack)
errorCallBack()
})
mainWindow.showLoadingPopup(qsTr("Téléchargement en cours ..."))
//: "Téléchargement en cours …"
mainWindow.showLoadingPopup(qsTr("loading_popup_codec_install_progress"))
coreObject.downloadAndExtract()
} else
if (cancelCallBack)

View file

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

View file

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

View file

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

View file

@ -38,7 +38,8 @@ LoginLayout {
colorizationColor: DefaultStyle.main2_600
}
Text {
text: qsTr("Compte SIP tiers")
//: Compte SIP tiers
text: qsTr("assistant_login_third_party_sip_account_title")
font {
pixelSize: Typography.h1.pixelSize
weight: Typography.h1.weight
@ -55,7 +56,8 @@ LoginLayout {
spacing: Math.round(20 * DefaultStyle.dp)
Text {
Layout.rightMargin: Math.round(15 * DefaultStyle.dp)
text: qsTr("Pas encore de compte ?")
//: Pas encore de compte ?
text: qsTr("assistant_no_account_yet")
font {
pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight
@ -63,7 +65,8 @@ LoginLayout {
}
BigButton {
Layout.alignment: Qt.AlignRight
text: qsTr("S'inscrire")
//: S'inscrire
text: qsTr("assistant_account_register")
style: ButtonStyle.main
onClicked: {
console.debug("[SIPLoginPage] User: go to register page")
@ -97,30 +100,30 @@ LoginLayout {
pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight
}
text: "Certaines fonctionnalités nécessitent un compte Linphone, comme la messagerie de groupe, les vidéoconférences..."
}
Text {
Layout.fillWidth: true
Layout.preferredWidth: rootStackView.width
wrapMode: Text.WordWrap
color: DefaultStyle.main2_900
font {
pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight
}
text:"Ces fonctionnalités sont cachées lorsque vous vous enregistrez avec un compte SIP tiers."
}
Text {
Layout.fillWidth: true
Layout.preferredWidth: rootStackView.width
wrapMode: Text.WordWrap
color: DefaultStyle.main2_900
font {
pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight
}
text: "Pour les activer dans un projet commercial, veuillez nous contacter. "
text: qsTr("Certaines fonctionnalités telles que les conversations de groupe, les vidéo-conférences, etc… nécessitent un compte %1.\n\nCes fonctionnalités seront masquées si vous utilisez un compte SIP tiers.\n\nPour les activer dans un projet commercial, merci de nous contacter.").arg(applicationName)
}
// Text {
// Layout.fillWidth: true
// Layout.preferredWidth: rootStackView.width
// wrapMode: Text.WordWrap
// color: DefaultStyle.main2_900
// font {
// pixelSize: Typography.p1.pixelSize
// weight: Typography.p1.weight
// }
// text:"Ces fonctionnalités sont cachées lorsque vous vous enregistrez avec un compte SIP tiers."
// }
// Text {
// Layout.fillWidth: true
// Layout.preferredWidth: rootStackView.width
// wrapMode: Text.WordWrap
// color: DefaultStyle.main2_900
// font {
// pixelSize: Typography.p1.pixelSize
// weight: Typography.p1.weight
// }
// text: "Pour les activer dans un projet commercial, veuillez nous contacter. "
// }
}
SmallButton {
id: openLinkButton
@ -141,7 +144,8 @@ LoginLayout {
id: createAccountButton
style: ButtonStyle.secondary
Layout.fillWidth: true
text: qsTr("Créer un compte linphone")
//: "Créer un compte linphone"
text: qsTr("assistant_third_party_sip_account_create_linphone_account")
onClicked: {
console.debug("[SIPLoginPage] User: click register")
mainItem.goToRegister()
@ -152,7 +156,8 @@ LoginLayout {
BigButton {
id: continueButton
Layout.fillWidth: true
text: qsTr("Je comprends")
//: "Je comprends"
text: qsTr("assistant_third_party_sip_account_warning_ok")
style: ButtonStyle.main
onClicked: {
rootStackView.replace(secondItem)
@ -183,7 +188,8 @@ LoginLayout {
spacing: Math.round(16 * DefaultStyle.dp)
FormItemLayout {
id: username
label: qsTr("Nom d'utilisateur")
//: "Nom d'utilisateur"
label: qsTr("username")
mandatory: true
enableErrorText: true
Layout.fillWidth: true
@ -196,7 +202,7 @@ LoginLayout {
}
FormItemLayout {
id: password
label: qsTr("Mot de passe")
label: qsTr("password")
mandatory: true
enableErrorText: true
Layout.fillWidth: true
@ -211,7 +217,8 @@ LoginLayout {
}
FormItemLayout {
id: domain
label: qsTr("Domaine")
//: "Domaine"
label: qsTr("sip_address_domain")
mandatory: true
enableErrorText: true
Layout.fillWidth: true
@ -231,7 +238,8 @@ LoginLayout {
}
}
FormItemLayout {
label: qsTr("Nom d'affichage")
//: Nom d'affichage
label: qsTr("sip_address_display_name")
Layout.fillWidth: true
contentItem: TextField {
id: displayName
@ -242,7 +250,8 @@ LoginLayout {
}
}
FormItemLayout {
label: qsTr("Transport")
//: "Transport"
label: qsTr("transport")
Layout.fillWidth: true
contentItem: ComboBox {
id: transportCbox
@ -281,7 +290,7 @@ LoginLayout {
id: connectionButtonContent
currentIndex: 0
Text {
text: qsTr("Connexion")
text: qsTr("assistant_account_login")
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
@ -330,11 +339,12 @@ LoginLayout {
onTriggered: {
if (usernameEdit.text.length == 0 || passwordEdit.text.length == 0 || domainEdit.text.length == 0) {
if (usernameEdit.text.length == 0)
username.errorMessage = qsTr("Veuillez saisir un nom d'utilisateur")
username.errorMessage = qsTr("assistant_account_login_missing_username")
if (passwordEdit.text.length == 0)
password.errorMessage = qsTr("Veuillez saisir un mot de passe")
password.errorMessage = qsTr("assistant_account_login_missing_password")
if (domainEdit.text.length == 0)
domain.errorMessage = qsTr("Veuillez saisir un nom de domaine")
//: "Veuillez saisir un nom de domaine
domain.errorMessage = qsTr("assistant_account_login_missing_domain")
return
}
console.debug("[SIPLoginPage] User: Log in")

View file

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

View file

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

View file

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

View file

@ -51,7 +51,8 @@ LoginLayout {
}
Text {
Layout.preferredWidth: width
text: qsTr("Inscription")
//: "Inscription
text: qsTr("assistant_account_register")
font {
pixelSize: Typography.h1.pixelSize
weight: Typography.h1.weight
@ -69,7 +70,8 @@ LoginLayout {
Text {
Layout.rightMargin: Math.round(15 * DefaultStyle.dp)
color: DefaultStyle.main2_700
text: qsTr("Déjà un compte ?")
// "Déjà un compte ?"
text: qsTr("assistant_already_have_an_account")
font {
pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight
@ -77,7 +79,7 @@ LoginLayout {
}
BigButton {
style: ButtonStyle.main
text: qsTr("Connexion")
text: qsTr("assistant_account_login")
onClicked: {
console.debug("[RegisterPage] User: return")
returnToLogin()
@ -96,7 +98,10 @@ LoginLayout {
TabBar {
Layout.fillWidth: true
id: bar
model: [qsTr("Register with phone number"), qsTr("Register with email")]
// "S'inscrire avec un numéro de téléphone"
model: [qsTr("assistant_account_register_with_phone_number"),
// "S'inscrire avec un email"
qsTr("assistant_account_register_with_email")]
}
Flickable {
Layout.fillWidth: true
@ -112,7 +117,7 @@ LoginLayout {
spacing: Math.round(16 * DefaultStyle.dp)
FormItemLayout {
id: usernameItem
label: qsTr("Username")
label: qsTr("username")
mandatory: true
enableErrorText: true
Layout.preferredWidth: Math.round(346 * DefaultStyle.dp)
@ -143,17 +148,18 @@ LoginLayout {
id: phoneNumberInput
Layout.preferredWidth: Math.round(346 * DefaultStyle.dp)
property string completePhoneNumber: countryCode + phoneNumber
label: qsTr("Numéro de téléphone")
//: "Numéro de téléphone"
label: qsTr("phone_number")
enableErrorText: true
mandatory: true
placeholderText: "Phone number"
placeholderText: qsTr("phone_number")
defaultCallingCode: "33"
}
FormItemLayout {
id: emailItem
Layout.fillWidth: false
Layout.preferredWidth: Math.round(346 * DefaultStyle.dp)
label: qsTr("Email")
label: qsTr("email")
mandatory: true
enableErrorText: true
contentItem: TextField {
@ -172,7 +178,7 @@ LoginLayout {
FormItemLayout {
id: passwordItem
Layout.preferredWidth: Math.round(346 * DefaultStyle.dp)
label: qsTr("Mot de passe")
label: qsTr("password")
mandatory: true
enableErrorText: true
contentItem: TextField {
@ -184,7 +190,8 @@ LoginLayout {
}
FormItemLayout {
Layout.preferredWidth: Math.round(346 * DefaultStyle.dp)
label: qsTr("Confirmation mot de passe")
//: "Confirmation mot de passe"
label: qsTr("assistant_account_register_password_confirmation")
mandatory: true
enableErrorText: true
contentItem: TextField {
@ -199,7 +206,6 @@ LoginLayout {
id: otherErrorText
Layout.fillWidth: true
Layout.topMargin: Math.round(5 * DefaultStyle.dp)
onTextChanged: console.log("set error", text)
}
}
}
@ -227,97 +233,54 @@ LoginLayout {
spacing: Math.round(10 * DefaultStyle.dp)
CheckBox {
id: termsCheckBox
}
RowLayout {
spacing: 0
Layout.fillWidth: true
Text {
text: qsTr("J'accepte les ")
font {
pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight
}
MouseArea {
anchors.fill: parent
onClicked: termsCheckBox.toggle()
}
}
Text {
activeFocusOnTab: true
font {
underline: true
pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight
bold: activeFocus
}
text: qsTr("conditions 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)
}
}
}
}
// }
}
Text {
//: "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 {
pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
onClicked: termsCheckBox.toggle()
}
}
}
// }
Button {
enabled: termsCheckBox.checked
style: ButtonStyle.main
text: qsTr("Créer")
//: "Créer"
text: qsTr("assistant_account_create")
onClicked:{
if (usernameInput.text.length === 0) {
console.log("ERROR username")
usernameItem.errorMessage = qsTr("Veuillez entrer un nom d'utilisateur")
//: "Veuillez entrer un nom d'utilisateur"
usernameItem.errorMessage = qsTr("assistant_account_create_missing_username_error")
} else if (pwdInput.text.length === 0) {
console.log("ERROR password")
passwordItem.errorMessage = qsTr("Veuillez entrer un mot de passe")
//: "Veuillez entrer un mot de passe"
passwordItem.errorMessage = qsTr("assistant_account_create_missing_password_error")
} else if (pwdInput.text != confirmPwdInput.text) {
console.log("ERROR confirm pwd")
passwordItem.errorMessage = qsTr("Les mots de passe sont différents")
//: "Les mots de passe sont différents"
passwordItem.errorMessage = qsTr("assistant_account_create_confirm_password_error")
} else if (bar.currentIndex === 0 && phoneNumberInput.phoneNumber.length === 0) {
console.log("ERROR phone number")
phoneNumberInput.errorMessage = qsTr("Veuillez entrer un numéro de téléphone")
//: "Veuillez entrer un numéro de téléphone"
phoneNumberInput.errorMessage = qsTr("assistant_account_create_missing_number_error")
} else if (bar.currentIndex === 1 && emailInput.text.length === 0) {
console.log("ERROR email")
emailItem.errorMessage = qsTr("Veuillez entrer un email")
//: "Veuillez entrer un email"
emailItem.errorMessage = qsTr("assistant_account_create_missing_email_error")
} else {
console.log("[RegisterPage] User: Call register")
mainItem.browserValidationRequested()

View file

@ -18,14 +18,16 @@ LoginLayout {
}
ColumnLayout {
Text {
text: qsTr("Choisir votre mode")
//: "Choisir votre mode"
text: qsTr("manage_account_choose_mode_title")
font {
pixelSize: Typography.h1.pixelSize
weight: Typography.h1.weight
}
}
Text {
text: qsTr("Vous pourrez changer de mode plus tard.")
//: "Vous pourrez changer de mode plus tard."
text: qsTr("manage_account_choose_mode_message")
font.bold: true
font {
pixelSize: Typography.p1.pixelSize
@ -44,8 +46,14 @@ LoginLayout {
spacing: Math.round(70 * DefaultStyle.dp)
Repeater {
model: [
{checked: true, title: qsTr("Chiffrement de bout en bout"), text: qsTr("Ce mode vous garanti la confidentialité de tous vos échanges. Notre technologie de chiffrement de bout en bout assure un niveau de sécurité maximal pour tous vos échanges."), imgUrl: AppIcons.chiffrement, color: DefaultStyle.info_500_main},
{checked: false, title: qsTr("Interoperable"), text: qsTr("Ce mode vous permet de profiter de toute les fonctionnalités de Linphone, toute en restant interopérable avec nimporte quelle autre service SIP."), imgUrl: AppIcons.interoperable, color: DefaultStyle.main1_500_main}
//: "Chiffrement de bout en bout"
{checked: true, title: qsTr("manage_account_e2e_encrypted_mode_default_title"),
//: "Ce mode vous garanti la confidentialité de tous vos échanges. Notre technologie de chiffrement de bout en bout assure un niveau de sécurité maximal pour tous vos échanges."
text: qsTr("manage_account_e2e_encrypted_mode_default_summary"), imgUrl: AppIcons.chiffrement, color: DefaultStyle.info_500_main},
//: "Interoperable"
{checked: false, title: qsTr("manage_account_e2e_encrypted_mode_interoperable_title"),
//: "Ce mode vous permet de profiter de toute les fonctionnalités de Linphone, toute en restant interopérable avec nimporte quelle autre service SIP."
text: qsTr("manage_account_e2e_encrypted_mode_interoperable_summary"), imgUrl: AppIcons.interoperable, color: DefaultStyle.main1_500_main}
]
SecurityRadioButton {
title: modelData.title
@ -64,7 +72,8 @@ LoginLayout {
property int selectedIndex: 0
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: Math.round(360 * DefaultStyle.dp)
text: qsTr("Continuer")
//: "Continuer"
text: qsTr("dialog_continue")
style: ButtonStyle.main
onClicked: mainItem.modeSelected(selectedIndex)
}

View file

@ -9,20 +9,25 @@ import SettingsCpp
AbstractSettingsMenu {
id: mainItem
layoutsPath: "qrc:/qt/qml/Linphone/view/Page/Layout/Settings"
titleText: qsTr("Mon compte")
//: "Mon compte"
titleText: qsTr("drawer_menu_manage_account")
property AccountGui account
signal accountRemoved()
families: [
{title: qsTr("Général"), layout: "AccountSettingsGeneralLayout", model: account},
{title: qsTr("Paramètres de compte"), layout: "AccountSettingsParametersLayout", model: account}
//: "Général"
{title: qsTr("settings_general_title"), layout: "AccountSettingsGeneralLayout", model: account},
//: "Paramètres de compte"
{title: qsTr("settings_account_title"), layout: "AccountSettingsParametersLayout", model: account}
]
Connections {
target: account.core
function onRemoved() { accountRemoved() }
}
onGoBackRequested: if (!account.core.isSaved) {
UtilsCpp.getMainWindow().showConfirmationLambdaPopup(qsTr("Modifications non enregistrées"),
qsTr("Vous avez des modifications non enregistrées. Si vous quittez cette page, vos changements seront perdus. Voulez-vous enregistrer vos modifications avant de continuer ?"),
//: "Modifications non enregistrées"
UtilsCpp.getMainWindow().showConfirmationLambdaPopup(qsTr("contact_editor_popup_abort_confirmation_title"),
//: "Vous avez des modifications non enregistrées. Si vous quittez cette page, vos changements seront perdus. Voulez-vous enregistrer vos modifications avant de continuer ?"
qsTr("contact_editor_popup_abort_confirmation_message"),
"",
function (confirmed) {
if (confirmed) {
@ -31,7 +36,9 @@ AbstractSettingsMenu {
account.core.undo()
}
mainItem.goBack()
}, qsTr("Ne pas enregistrer"), qsTr("Enregistrer")
//: "Ne pas enregistrer"
//: "Enregistrer"
}, qsTr("contact_editor_dialog_abort_confirmation_do_not_save"), qsTr("contact_editor_dialog_abort_confirmation_save")
)
} else {mainItem.goBack()}
}

View file

@ -8,20 +8,30 @@ import UtilsCpp
AbstractSettingsMenu {
id: mainItem
layoutsPath: "qrc:/qt/qml/Linphone/view/Page/Layout/Settings"
titleText: qsTr("Paramètres")
//: "Paramètres"
titleText: qsTr("settings_title")
families: [
{title: qsTr("Appels"), layout: "CallSettingsLayout"},
{title: qsTr("Conversations"), layout: "ChatSettingsLayout", visible: !SettingsCpp.disableChatFeature},
{title: qsTr("Contacts"), layout: "ContactsSettingsLayout"},
{title: qsTr("Réunions"), layout: "MeetingsSettingsLayout", visible: !SettingsCpp.disableMeetingsFeature},
//{title: qsTr("Affichage"), layout: "DisplaySettingsLayout"},
{title: qsTr("Réseau"), layout: "NetworkSettingsLayout"},
{title: qsTr("Paramètres avancés"), layout: "AdvancedSettingsLayout"}
//: "Appels"
{title: qsTr("settings_calls_title"), layout: "CallSettingsLayout"},
//: "Conversations"
{title: qsTr("settings_conversations_title"), layout: "ChatSettingsLayout", visible: !SettingsCpp.disableChatFeature},
//: "Contacts"
{title: qsTr("settings_contacts_title"), layout: "ContactsSettingsLayout"},
//: "Réunions"
{title: qsTr("settings_meetings_title"), layout: "MeetingsSettingsLayout", visible: !SettingsCpp.disableMeetingsFeature},
//: "Affichage"
//{title: qsTr("settings_user_interface_title"), layout: "DisplaySettingsLayout"},
//: "Réseau"
{title: qsTr("settings_network_title"), layout: "NetworkSettingsLayout"},
//: "Paramètres avancés"
{title: qsTr("settings_advanced_title"), layout: "AdvancedSettingsLayout"}
]
onGoBackRequested: if (!SettingsCpp.isSaved) {
UtilsCpp.getMainWindow().showConfirmationLambdaPopup(qsTr("Modifications non enregistrées"),
qsTr("Vous avez des modifications non enregistrées. Si vous quittez cette page, vos changements seront perdus. Voulez-vous enregistrer vos modifications avant de continuer ?"),
//: Modifications non enregistrées
UtilsCpp.getMainWindow().showConfirmationLambdaPopup(qsTr("contact_editor_popup_abort_confirmation_title"),
//: Vous avez des modifications non enregistrées. Si vous quittez cette page, vos changements seront perdus. Voulez-vous enregistrer vos modifications avant de continuer ?
qsTr("contact_editor_popup_abort_confirmation_message"),
"",
function (confirmed) {
if (confirmed) {
@ -30,7 +40,10 @@ AbstractSettingsMenu {
SettingsCpp.undo()
}
mainItem.goBack()
}, qsTr("Ne pas enregistrer"), qsTr("Enregistrer")
//: "Ne pas enregistrer"
}, qsTr("contact_editor_dialog_abort_confirmation_do_not_save"),
//: "Enregistrer"
qsTr("contact_editor_dialog_abort_confirmation_save")
)
} else {mainItem.goBack()}
}

View file

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

View file

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

View file

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

View file

@ -15,13 +15,17 @@ AbstractSettingsLayout {
width: parent?.width
contentModel: [
{
title: qsTr("Détails"),
subTitle: qsTr("Editer les informations de votre compte."),
//: "Détails"
title: qsTr("manage_account_details_title"),
//: Éditer les informations de votre compte.
subTitle: qsTr("manage_account_details_subtitle"),
contentComponent: accountParametersComponent
},
{
title: qsTr("Vos appareils"),
subTitle: qsTr("La liste des appareils connectés à votre compte. Vous pouvez retirer les appareils que vous nutilisez plus."),
//: "Vos appareils"
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
}
]
@ -50,7 +54,8 @@ AbstractSettingsLayout {
icon.source: AppIcons.camera
icon.width: Math.round(17 * DefaultStyle.dp)
icon.height: Math.round(17 * DefaultStyle.dp)
text: qsTr("Ajouter une image")
//: "Ajouter une image"
text: qsTr("manage_account_add_picture")
style: ButtonStyle.noBackground
onClicked: fileDialog.open()
Layout.alignment: Qt.AlignHCenter
@ -64,7 +69,8 @@ AbstractSettingsLayout {
icon.source: AppIcons.pencil
icon.width: Math.round(17 * DefaultStyle.dp)
icon.height: Math.round(17 * DefaultStyle.dp)
text: qsTr("Modifier l'image")
//: "Modifier l'image"
text: qsTr("manage_account_edit_picture")
style: ButtonStyle.noBackground
onClicked: fileDialog.open()
}
@ -73,7 +79,8 @@ AbstractSettingsLayout {
icon.source: AppIcons.trashCan
icon.width: Math.round(17 * DefaultStyle.dp)
icon.height: Math.round(17 * DefaultStyle.dp)
text: qsTr("Supprimer l'image")
//: "Supprimer l'image"
text: qsTr("manage_account_remove_picture")
style: ButtonStyle.noBackground
onClicked: model.core.pictureUri = ""
}
@ -94,7 +101,7 @@ AbstractSettingsLayout {
spacing: Math.round(5 * DefaultStyle.dp)
Text {
Layout.alignment: Qt.AlignLeft
text: qsTr("Adresse SIP :")
text: "%1 :".arg(qsTr("sip_address"))
color: DefaultStyle.main2_600
font: Typography.p2l
}
@ -118,12 +125,14 @@ AbstractSettingsLayout {
spacing: Math.round(5 * DefaultStyle.dp)
Layout.alignment: Qt.AlignLeft
Text {
text: qsTr("Nom daffichage")
//: "Nom d'affichage
text: qsTr("sip_address_display_name")
color: DefaultStyle.main2_600
font: Typography.p2l
}
Text {
text: qsTr("Le nom qui sera affiché à vos correspondants lors de vos échanges.")
//: "Le nom qui sera affiché à vos correspondants lors de vos échanges."
text: qsTr("sip_address_display_name_explaination")
color: DefaultStyle.main2_600
font: Typography.p1
}
@ -140,7 +149,8 @@ AbstractSettingsLayout {
toValidate: true
}
Text {
text: qsTr("Indicatif international*")
//: "Indicatif international*"
text: qsTr("manage_account_international_prefix")
color: DefaultStyle.main2_600
font: Typography.p2l
}
@ -165,14 +175,16 @@ AbstractSettingsLayout {
ColumnLayout {
spacing : Math.round(5 * DefaultStyle.dp)
Text {
text: qsTr("Supprimer mon compte")
//: "Déconnecter mon compte"
text: qsTr("manage_account_delete")
font: Typography.p2l
wrapMode: Text.WordWrap
color: DefaultStyle.danger_500main
Layout.fillWidth: true
}
Text {
text: qsTr("Votre compte sera retiré de ce client linphone, mais vous restez connecté sur vos autres clients")
// "Votre compte sera retiré de ce client linphone, mais vous restez connecté sur vos autres clients
text: qsTr("manage_account_delete_message")
font: Typography.p1
wrapMode: Text.WordWrap
color: DefaultStyle.main2_500main
@ -190,8 +202,10 @@ AbstractSettingsLayout {
onClicked: {
var mainWin = UtilsCpp.getMainWindow()
mainWin.showConfirmationLambdaPopup("",
qsTr("Supprimer ") + (model.core.displayName.length > 0 ? model.core.displayName : qsTr("le compte")) + " ?",
qsTr("Vous pouvez vous reconnecter à tout moment en cliquant sur \"Ajouter un compte\".\nCependant toutes les informations stockées sur ce périphérique seront supprimées."),
//: "Se déconnecter du compte ?"
qsTr("manage_account_dialog_remove_account_title"),
//: Si vous souhaitez supprimer définitivement votre compte rendez-vous sur : https://sip.linphone.org
qsTr("manage_account_dialog_remove_account_message"),
function (confirmed) {
if (confirmed) {
account.core.removeAccount()
@ -247,7 +261,8 @@ AbstractSettingsLayout {
onDevicesSet: devices.loading = false;
onRequestError: (errorMessage) => {
devices.loading = false;
mainWindow.showInformationPopup(qsTr("Erreur"), errorMessage, false)
//: Erreur
mainWindow.showInformationPopup(qsTr("error"), errorMessage, false)
}
}
Control.Control {
@ -284,7 +299,8 @@ AbstractSettingsLayout {
}
MediumButton {
Layout.alignment: Qt.AlignRight
text: qsTr("Supprimer")
//: "Supprimer"
text: qsTr("manage_account_device_remove")
icon.source: AppIcons.trashCan
icon.width: Math.round(16 * DefaultStyle.dp)
icon.height: Math.round(16 * DefaultStyle.dp)
@ -292,7 +308,8 @@ AbstractSettingsLayout {
onClicked: {
var mainWin = UtilsCpp.getMainWindow()
mainWin.showConfirmationLambdaPopup("",
qsTr("Supprimer ") + modelData.core.deviceName + " ?", "",
//:"Supprimer %1 ?"
qsTr("manage_account_device_remove_confirm_dialog").arg(modelData.core.deviceName), "",
function (confirmed) {
if (confirmed) {
accountDeviceProxy.deleteDevice(modelData)
@ -305,7 +322,8 @@ AbstractSettingsLayout {
RowLayout {
spacing: Math.round(5 * DefaultStyle.dp)
Text {
text: qsTr("Dernière connexion:")
//: "Dernière connexion:"
text: qsTr("manage_account_device_last_connection")
color: DefaultStyle.main2_600
font: Typography.p2
}

View file

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

View file

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

View file

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

View file

@ -13,8 +13,10 @@ AbstractSettingsLayout {
width: parent?.width
contentModel: [
{
title: qsTr("Carnet d'adresse CardDAV"),
subTitle: qsTr("Ajouter un carnet dadresse CardDAV pour synchroniser vos contacts Linphone avec un carnet dadresse tiers."),
//: Carnet d'adresse CardDAV
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
}
]
@ -25,16 +27,19 @@ AbstractSettingsLayout {
if (carddavGui.core.isValid()) {
carddavGui.core.save()
} else {
UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("Vérifiez que toutes les informations ont été saisies."), false, mainWindow)
//: "Vérifiez que toutes les informations ont été saisies."
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), qsTr("settings_contacts_carddav_popup_invalid_error"), false, mainWindow)
}
}
Connections {
target: carddavGui.core
function onSaved(success) {
if (success)
UtilsCpp.showInformationPopup(qsTr("Succès"), qsTr("Le carnet d'adresse CardDAV est synchronisé."), true, mainWindow)
//: "Le carnet d'adresse CardDAV est synchronisé."
UtilsCpp.showInformationPopup(qsTr("information_popup_synchronization_success_title"), qsTr("settings_contacts_carddav_synchronization_success_message"), true, mainWindow)
else
UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("Erreur de synchronisation!"), false, mainWindow)
//: "Erreur de synchronisation!"
UtilsCpp.showInformationPopup(qsTr("settings_contacts_carddav_popup_synchronization_error_title"), qsTr("settings_contacts_carddav_popup_synchronization_error_message"), false, mainWindow)
}
}
Component {
@ -50,7 +55,8 @@ AbstractSettingsLayout {
onClicked: {
var mainWin = UtilsCpp.getMainWindow()
mainWin.showConfirmationLambdaPopup("",
qsTr("Supprimer le carnet d'adresse CardDAV ?"),
//: "Supprimer le carnet d'adresse CardDAV ?"
qsTr("settings_contacts_delete_carddav_server_title"),
"",
function (confirmed) {
if (confirmed) {
@ -75,7 +81,8 @@ AbstractSettingsLayout {
DecoratedTextField {
propertyName: "displayName"
propertyOwnerGui: carddavGui
title: qsTr("Nom daffichage")
//: Nom d'affichage
title: qsTr("sip_address_display_name")
canBeEmpty: false
toValidate: true
Layout.fillWidth: true
@ -83,7 +90,8 @@ AbstractSettingsLayout {
DecoratedTextField {
propertyName: "uri"
propertyOwnerGui: carddavGui
title: qsTr("URL du serveur")
//: "URL du serveur"
title: qsTr("settings_contacts_carddav_server_url_title")
canBeEmpty: false
toValidate: true
Layout.fillWidth: true
@ -91,7 +99,7 @@ AbstractSettingsLayout {
DecoratedTextField {
propertyName: "username"
propertyOwnerGui: carddavGui
title: qsTr("Nom dutilisateur")
title: qsTr("username")
toValidate: true
Layout.fillWidth: true
}
@ -99,19 +107,21 @@ AbstractSettingsLayout {
propertyName: "password"
hidden: true
propertyOwnerGui: carddavGui
title: qsTr("Mot de passe")
title: qsTr("password")
toValidate: true
Layout.fillWidth: true
}
DecoratedTextField {
propertyName: "realm"
propertyOwnerGui: carddavGui
title: qsTr("Domaine dauthentification")
//: Domaine dauthentification
title: qsTr("settings_contacts_carddav_realm_title")
toValidate: true
Layout.fillWidth: true
}
SwitchSetting {
titleText: qsTr("Stocker ici les contacts nouvellement crées")
//: "Stocker ici les contacts nouvellement crées"
titleText: qsTr("settings_contacts_carddav_use_as_default_title")
propertyName: "storeNewFriendsInIt"
propertyOwnerGui: carddavGui
}

View file

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

View file

@ -89,7 +89,8 @@ RowLayout {
Connections {
target: modelData.core
function onSavedChanged() {
if (modelData.core.saved) UtilsCpp.showInformationPopup(qsTr("Succès"), qsTr("Les changements ont été sauvegardés"), true, mainWindow)
//: "Les changements ont été sauvegardés"
if (modelData.core.saved) UtilsCpp.showInformationPopup(qsTr("information_popup_success_title"), qsTr("information_popup_changes_saved"), true, mainWindow)
}
}
@ -110,7 +111,8 @@ RowLayout {
}
MediumButton {
Layout.alignment: Qt.AlignRight | Qt.AlignHCenter
text: qsTr("Ajouter")
//: "Ajouter"
text: qsTr("add")
style: ButtonStyle.main
visible: mainItem.showAddButton
onClicked: {

View file

@ -28,7 +28,8 @@ AbstractSettingsLayout {
Dialog {
id: deleteLogs
text: qsTr("Les traces de débogage seront supprimées. Souhaitez-vous continuer ?")
//: "Les traces de débogage seront supprimées. Souhaitez-vous continuer ?"
text: qsTr("settings_debug_clean_logs_message")
onAccepted: SettingsCpp.cleanLogs()
}
@ -38,10 +39,12 @@ AbstractSettingsLayout {
Dialog {
id: shareLogs
text: qsTr("Les traces de débogage ont été téléversées. Comment souhaitez-vous partager le lien ? ")
//: "Les traces de débogage ont été téléversées. Comment souhaitez-vous partager le lien ? "
text: qsTr("settings_debug_share_logs_message")
buttons: [
BigButton {
text: qsTr("Presse-papier")
//: "Presse-papier"
text: qsTr("settings_debug_clipboard")
style: ButtonStyle.main
onClicked: {
shareLogs.close()
@ -49,16 +52,20 @@ AbstractSettingsLayout {
}
},
BigButton {
text: qsTr("E-Mail")
//: "E-Mail"
text: qsTr("settings_debug_email")
style: ButtonStyle.main
onClicked: {
shareLogs.close()
if(!Qt.openUrlExternally(
'mailto:' + encodeURIComponent(SettingsCpp.logsEmail) +
'?subject=' + encodeURIComponent(qsTr('Traces Linphone')) +
'&body=' + encodeURIComponent(mainItem.logsUrl)
//: "Traces %1"
if(!Qt.openUrlExternally("mailto:%1%2%3%4%5".arg(encodeURIComponent(SettingsCpp.logsEmail))
.arg('?subject=').arg(encodeURIComponent(qsTr("debug_settings_trace").arg(applicationName)))
.arg('&body=').arg(encodeURIComponent(mainItem.logsUrl))
))
UtilsCpp.showInformationPopup(qsTr("Une erreur est survenue."), qsTr("Le partage par mail a échoué. Veuillez envoyer le lien %1 directement à l'adresse %2.").replace("%1",mainItem.logsUrl).replace("%2",SettingsCpp.logsEmail), false)
//: Une erreur est survenue.
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
//: "Le partage par mail a échoué. Veuillez envoyer le lien %1 directement à l'adresse %2."
qsTr("information_popup_email_sharing_failed").arg(mainItem.logsUrl).arg(SettingsCpp.logsEmail), false)
}
}
]
@ -69,12 +76,14 @@ AbstractSettingsLayout {
ColumnLayout {
spacing: Math.round(20 * DefaultStyle.dp)
SwitchSetting {
titleText: qsTr("Activer les traces de débogage")
//: "Activer les traces de débogage"
titleText: qsTr("settings_debug_enable_logs_title")
propertyName: "logsEnabled"
propertyOwner: SettingsCpp
}
SwitchSetting {
titleText: qsTr("Activer les traces de débogage intégrales")
//: "Activer les traces de débogage intégrales"
titleText: qsTr("settings_debug_enable_full_logs_title")
propertyName: "fullLogsEnabled"
propertyOwner: SettingsCpp
}
@ -83,17 +92,20 @@ AbstractSettingsLayout {
Layout.alignment: Qt.AlignRight
MediumButton {
style: ButtonStyle.tertiary
text: qsTr("Supprimer les traces")
//: "Supprimer les traces"
text: qsTr("settings_debug_delete_logs_title")
onClicked: {
deleteLogs.open()
}
}
MediumButton {
style: ButtonStyle.tertiary
text: qsTr("Partager les traces")
//: "Partager les traces"
text: qsTr("settings_debug_share_logs_title")
enabled: SettingsCpp.logsEnabled || SettingsCpp.fullLogsEnabled
onClicked: {
UtilsCpp.getMainWindow().showLoadingPopup(qsTr("Téléversement des traces en cours ..."))
//: "Téléversement des traces en cours "
UtilsCpp.getMainWindow().showLoadingPopup(qsTr("settings_debug_share_logs_loading_message"))
SettingsCpp.sendLogs()
}
}
@ -117,7 +129,8 @@ AbstractSettingsLayout {
}
ColumnLayout {
Text {
text: qsTr("Version de l'application")
//: "Version de l'application"
text: qsTr("settings_debug_app_version_title")
font: Typography.p2l
wrapMode: Text.WordWrap
color: DefaultStyle.main2_600
@ -145,7 +158,8 @@ AbstractSettingsLayout {
}
ColumnLayout {
Text {
text: qsTr("Version du SDK")
//: "Version du SDK"
text: qsTr("settings_debug_sdk_version_title")
font: Typography.p2l
wrapMode: Text.WordWrap
color: DefaultStyle.main2_600
@ -172,7 +186,9 @@ AbstractSettingsLayout {
mainItem.logsUrl = url
shareLogs.open()
} else {
UtilsCpp.showInformationPopup(qsTr("Une erreur est survenue."), qsTr("Le téléversement des traces a échoué. Vous pouvez partager les fichiers de trace directement depuis le répertoire suivant :") + SettingsCpp.logsFolder, false)
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
//: "Le téléversement des traces a échoué. Vous pouvez partager les fichiers de trace directement depuis le répertoire suivant : %1"
qsTr("settings_debug_share_logs_error").arg(SettingsCpp.logsFolder), false)
}
}
}

View file

@ -13,8 +13,8 @@ AbstractSettingsLayout {
width: parent?.width
contentModel: [
{
title: qsTr("Annuaires LDAP"),
subTitle: qsTr("Ajouter vos annuaires LDAP pour pouvoir effectuer des recherches dans la magic search bar."),
title: qsTr("settings_contacts_ldap_title"),
subTitle: qsTr("settings_contacts_ldap_subtitle"),
contentComponent: ldapParametersComponent
}
]
@ -26,9 +26,11 @@ AbstractSettingsLayout {
onSave: {
if (ldapGui.core.isValid()) {
ldapGui.core.save()
UtilsCpp.showInformationPopup(qsTr("Succès"), qsTr("L'annuaire LDAP a été sauvegardé"), true, mainWindow)
//: "L'annuaire LDAP a été sauvegardé"
UtilsCpp.showInformationPopup(qsTr("information_popup_success_title"), qsTr("settings_contacts_ldap_success_toast"), true, mainWindow)
} else {
UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("Une erreur s'est produite, la configuration LDAP n'a pas été sauvegardée !"), false, mainWindow)
//: "Une erreur s'est produite, la configuration LDAP n'a pas été sauvegardée !"
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), qsTr("settings_contacts_ldap_error_toast"), false, mainWindow)
}
}
@ -45,7 +47,8 @@ AbstractSettingsLayout {
onClicked: {
var mainWin = UtilsCpp.getMainWindow()
mainWin.showConfirmationLambdaPopup("",
qsTr("Supprimer l'annuaire LDAP ?"),
//: "Supprimer l'annuaire LDAP ?"
qsTr("settings_contacts_ldap_delete_confirmation_message"),
"",
function (confirmed) {
if (confirmed) {
@ -71,14 +74,16 @@ AbstractSettingsLayout {
id: server
propertyName: "serverUrl"
propertyOwnerGui: ldapGui
title: qsTr("URL du serveur (ne peut être vide)")
//: "URL du serveur (ne peut être vide)"
title: qsTr("settings_contacts_ldap_server_url_title")
toValidate: true
Layout.fillWidth: true
}
DecoratedTextField {
propertyName: "bindDn"
propertyOwnerGui: ldapGui
title: qsTr("Bind DN")
//: "Bind DN"
title: qsTr("settings_contacts_ldap_bind_dn_title")
toValidate: true
Layout.fillWidth: true
}
@ -86,26 +91,30 @@ AbstractSettingsLayout {
propertyName: "password"
hidden: true
propertyOwnerGui: ldapGui
title: qsTr("Mot de passe")
//: "Mot de passe"
title: qsTr("settings_contacts_ldap_password_title")
toValidate: true
Layout.fillWidth: true
}
SwitchSetting {
titleText: qsTr("Utiliser TLS")
//: "Utiliser TLS"
titleText: qsTr("settings_contacts_ldap_use_tls_title")
propertyName: "tls"
propertyOwnerGui: ldapGui
}
DecoratedTextField {
propertyName: "baseObject"
propertyOwnerGui: ldapGui
title: qsTr("Base de recherche (ne peut être vide)")
//: "Base de recherche (ne peut être vide)"
title: qsTr("settings_contacts_ldap_search_base_title")
toValidate: true
Layout.fillWidth: true
}
DecoratedTextField {
propertyName: "filter"
propertyOwnerGui: ldapGui
title: qsTr("Filtre")
//: "Filtre"
title: qsTr("settings_contacts_ldap_search_filter_title")
toValidate: true
Layout.fillWidth: true
}
@ -113,7 +122,8 @@ AbstractSettingsLayout {
propertyName: "limit"
propertyOwnerGui: ldapGui
validator: RegularExpressionValidator { regularExpression: /[0-9]+/ }
title: qsTr("Nombre maximum de résultats")
//: "Nombre maximum de résultats"
title: qsTr("settings_contacts_ldap_max_results_title")
toValidate: true
Layout.fillWidth: true
}
@ -121,14 +131,16 @@ AbstractSettingsLayout {
propertyName: "delay"
propertyOwnerGui: ldapGui
validator: RegularExpressionValidator { regularExpression: /[0-9]+/ }
title: qsTr("Délai entre 2 requêtes (en millisecondes)")
//: "Délai entre 2 requêtes (en millisecondes)"
title: qsTr("settings_contacts_ldap_request_delay_title")
toValidate: true
Layout.fillWidth: true
}
DecoratedTextField {
propertyName: "timeout"
propertyOwnerGui: ldapGui
title: qsTr("Durée maximun (en secondes)")
//: "Durée maximun (en secondes)"
title: qsTr("settings_contacts_ldap_request_timeout_title")
validator: RegularExpressionValidator { regularExpression: /[0-9]+/ }
toValidate: true
Layout.fillWidth: true
@ -136,7 +148,8 @@ AbstractSettingsLayout {
DecoratedTextField {
propertyName: "minCharacters"
propertyOwnerGui: ldapGui
title: qsTr("Nombre minimum de caractères pour la requête")
//: "Nombre minimum de caractères pour la requête"
title: qsTr("settings_contacts_ldap_min_characters_title")
validator: RegularExpressionValidator { regularExpression: /[0-9]+/ }
toValidate: true
Layout.fillWidth: true
@ -144,26 +157,30 @@ AbstractSettingsLayout {
DecoratedTextField {
propertyName: "nameAttribute"
propertyOwnerGui: ldapGui
title: qsTr("Attributs de nom")
//: "Attributs de nom"
title: qsTr("settings_contacts_ldap_name_attributes_title")
toValidate: true
Layout.fillWidth: true
}
DecoratedTextField {
propertyName: "sipAttribute"
propertyOwnerGui: ldapGui
title: qsTr("Attributs SIP")
//: "Attributs SIP"
title: qsTr("settings_contacts_ldap_sip_attributes_title")
toValidate: true
Layout.fillWidth: true
}
DecoratedTextField {
propertyName: "sipDomain"
propertyOwnerGui: ldapGui
title: qsTr("Domaine SIP")
//: "Domaine SIP"
title: qsTr("settings_contacts_ldap_sip_domain_title")
toValidate: true
Layout.fillWidth: true
}
SwitchSetting {
titleText: qsTr("Débogage")
//: "Débogage"
titleText: qsTr("settings_contacts_ldap_debug_title")
propertyName: "debug"
propertyOwnerGui: ldapGui
}

View file

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

View file

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

View file

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

View file

@ -11,27 +11,24 @@ import SettingsCpp
Item {
id: mainItem
width: Math.round(517 * DefaultStyle.dp)
readonly property real topPadding: Math.round(23 * DefaultStyle.dp)
readonly property real bottomPadding: Math.round(13 * DefaultStyle.dp)
readonly property real leftPadding: Math.round(24 * DefaultStyle.dp)
readonly property real rightPadding: Math.round(24 * DefaultStyle.dp)
readonly property real spacing: Math.round(16 * DefaultStyle.dp)
property AccountProxy accountProxy
signal addAccountRequest()
signal editAccount(AccountGui account)
signal editAccount(AccountGui account)
implicitHeight: list.contentHeight + topPadding + bottomPadding + Math.round(32 * DefaultStyle.dp) + 1 + addAccountButton.height
implicitHeight: list.contentHeight + Math.round(32 * DefaultStyle.dp) + 1 + addAccountButton.height
ColumnLayout{
id: childLayout
anchors.top: parent.top
anchors.topMargin: mainItem.topPadding
anchors.topMargin: mainItem.topPadding
anchors.left: parent.left
anchors.leftMargin: mainItem.leftPadding
anchors.leftMargin: mainItem.leftPadding
anchors.right: parent.right
anchors.rightMargin: mainItem.rightPadding
anchors.rightMargin: mainItem.rightPadding
anchors.bottom: parent.bottom
anchors.bottomMargin: mainItem.bottomPadding
anchors.bottomMargin: mainItem.bottomPadding
ListView{
id: list
Layout.preferredHeight: contentHeight

View file

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

View file

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

View file

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

View file

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

View file

@ -14,9 +14,10 @@ AbstractMainPage {
property int meetingListCount
signal returnRequested()
signal addParticipantsValidated(list<string> selectedParticipants)
noItemButtonText: qsTr("Créer une réunion")
emptyListText: qsTr("Aucune réunion")
//: "Créer une réunion"
noItemButtonText: qsTr("meetings_add")
//: "Aucune réunion"
emptyListText: qsTr("meetings_list_empty")
newItemIconSource: AppIcons.plusCircle
rightPanelColor: selectedConference ? DefaultStyle.grey_0 : DefaultStyle.grey_100
showDefaultItem: leftPanelStackView.currentItem?.objectName === "listLayout" && meetingListCount === 0
@ -73,12 +74,16 @@ AbstractMainPage {
property bool cancel: false
signal cancelRequested()
// width: Math.round(278 * DefaultStyle.dp)
text: cancel ? qsTr("Souhaitez-vous annuler et supprimer cette réunion ?") : qsTr("Souhaitez-vous supprimer cette réunion ?")
//: "Souhaitez-vous annuler et supprimer cette réunion ?"
text: cancel ? qsTr("meeting_schedule_cancel_dialog_message")
//: Souhaitez-vous supprimer cette réunion ?
: qsTr("meeting_schedule_delete_dialog_message")
buttons: [
BigButton {
visible: cancelAndDeleteConfDialog.cancel
style: ButtonStyle.main
text: qsTr("Annuler et supprimer")
//: "Annuler et supprimer"
text: qsTr("meeting_schedule_cancel_and_delete_action")
onClicked: {
cancelAndDeleteConfDialog.cancelRequested()
cancelAndDeleteConfDialog.accepted()
@ -86,7 +91,10 @@ AbstractMainPage {
}
},
BigButton {
text: cancelAndDeleteConfDialog.cancel ? qsTr("Supprimer seulement") : qsTr("Supprimer")
//: "Supprimer seulement"
text: cancelAndDeleteConfDialog.cancel ? qsTr("meeting_schedule_delete_only_action")
//: "Supprimer"
: qsTr("meeting_schedule_delete_action")
style: ButtonStyle.main
onClicked: {
cancelAndDeleteConfDialog.accepted()
@ -94,7 +102,8 @@ AbstractMainPage {
}
},
BigButton {
text: qsTr("Retour")
//: Retour
text: qsTr("back_action")
style: ButtonStyle.secondary
onClicked: {
cancelAndDeleteConfDialog.rejected()
@ -136,7 +145,8 @@ AbstractMainPage {
spacing: 0
Text {
Layout.fillWidth: true
text: qsTr("Réunions")
//: Réunions
text: qsTr("meetings_list_title")
color: DefaultStyle.main2_700
font.pixelSize: Typography.h2.pixelSize
font.weight: Typography.h2.weight
@ -159,7 +169,8 @@ AbstractMainPage {
Layout.fillWidth: true
Layout.topMargin: Math.round(18 * DefaultStyle.dp)
Layout.rightMargin: Math.round(38 * DefaultStyle.dp)
placeholderText: qsTr("Rechercher une réunion")
//: "Rechercher une réunion"
placeholderText: qsTr("meetings_search_hint")
KeyNavigation.up: conferenceList
KeyNavigation.down: conferenceList
visible: conferenceList.count !== 0 || text.length !== 0
@ -175,7 +186,10 @@ AbstractMainPage {
Layout.topMargin: Math.round(137 * DefaultStyle.dp)
Layout.fillHeight: true
Layout.alignment: Qt.AlignHCenter
text: qsTr("Aucune réunion%1").arg(searchBar.text.length !== 0 ? " correspondante" : "")
//: "Aucun résultat"
text: searchBar.text.length !== 0 ? qsTr("list_filter_no_result_found")
//: "Aucune réunion"
: qsTr("meetings_empty_list")
font {
pixelSize: Typography.h4.pixelSize
weight: Typography.h4.weight
@ -237,7 +251,8 @@ AbstractMainPage {
}
}
Text {
text: qsTr("Nouvelle réunion")
//: "Nouvelle réunion"
text: qsTr("meeting_schedule_title")
color: DefaultStyle.main2_700
font {
pixelSize: Typography.h3.pixelSize
@ -248,23 +263,26 @@ AbstractMainPage {
Item {Layout.fillWidth: true}
SmallButton {
id: createButton
text: qsTr("Créer")
text: qsTr("create")
style: ButtonStyle.main
KeyNavigation.left: backButton
KeyNavigation.down: meetingSetup
onClicked: {
if (meetingSetup.conferenceInfoGui.core.subject.length === 0) {
UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La conférence doit contenir un sujet"), false)
if (meetingSetup.conferenceInfoGui.core.subject.length === 0 || meetingSetup.conferenceInfoGui.core.participantCount === 0) {
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
//: Veuillez saisir un titre et sélectionner au moins un participant
qsTr("meeting_schedule_mandatory_field_not_filled_toast"), false)
} else if (meetingSetup.conferenceInfoGui.core.duration <= 0) {
UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La fin de la conférence doit être plus récente que son début"), false)
} else if (meetingSetup.conferenceInfoGui.core.participantCount === 0) {
UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La conférence doit contenir au moins un participant"), false)
} else {
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
//: "La fin de la conférence doit être plus récente que son début"
qsTr("meeting_schedule_duration_error_toast"), false)
} else {
meetingSetup.conferenceInfoGui.core.save()
mainWindow.showLoadingPopup(qsTr("Création de la réunion en cours ..."), true, function () {
meetingSetup.conferenceInfoGui.core.cancelCreation()
})
//: "Création de la réunion en cours "
mainWindow.showLoadingPopup(qsTr("meeting_schedule_creation_in_progress"), true, function () {
meetingSetup.conferenceInfoGui.core.cancelCreation()
})
}
}
}
@ -282,17 +300,23 @@ AbstractMainPage {
var mainWin = UtilsCpp.getMainWindow()
if (meetingSetup.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Ready) {
leftPanelStackView.pop()
UtilsCpp.showInformationPopup(qsTr("Nouvelle réunion"), qsTr("Réunion planifiée avec succès"), true)
//: "Nouvelle réunion"
UtilsCpp.showInformationPopup(qsTr("meeting_schedule_title"),
//: "Réunion planifiée avec succès"
qsTr("meeting_info_created_toast"), true)
mainWindow.closeLoadingPopup()
}
else if (meetingSetup.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.AllocationPending
|| meetingSetup.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Updating) {
mainWin.showLoadingPopup(qsTr("Création de la réunion en cours..."), true, function () {
//: Création de la réunion en cours
mainWin.showLoadingPopup(qsTr("meeting_schedule_creation_processing"), true, function () {
leftPanelStackView.pop()
})
} else {
if (meetingSetup.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Error) {
UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La création de la conférence a échoué"), false)
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
//: "Échec de création de la réunion !"
qsTr("meeting_failed_to_schedule_toast"), false)
}
mainWin.closeLoadingPopup()
}
@ -385,19 +409,19 @@ AbstractMainPage {
id: saveButton
style: ButtonStyle.main
focus: true
text: qsTr("Enregistrer")
text: qsTr("save")
KeyNavigation.left: titleText
KeyNavigation.right: backButton
KeyNavigation.down: conferenceEdit
KeyNavigation.up: conferenceEdit
onClicked: {
if (mainItem.selectedConference.core.subject.length === 0) {
UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La conférence doit contenir un sujet"), false)
if (mainItem.selectedConference.core.subject.length === 0 || mainItem.selectedConference.core.participantCount === 0) {
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
qsTr("meeting_schedule_mandatory_field_not_filled_toast"), false)
} else if (mainItem.selectedConference.core.duration <= 0) {
UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La fin de la conférence doit être plus récente que son début"), false)
} else if (mainItem.selectedConference.core.participantCount === 0) {
UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La conférence doit contenir au moins un participant"), false)
} else {
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
qsTr("meeting_schedule_duration_error_toast"), false)
} else {
mainItem.selectedConference.core.save()
}
}
@ -434,13 +458,19 @@ AbstractMainPage {
if (conferenceEdit.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Ready) {
overridenRightPanelStackView.pop()
UtilsCpp.getMainWindow().closeLoadingPopup()
UtilsCpp.showInformationPopup(qsTr("Enregistré"), qsTr("Réunion modifiée avec succès"), true)
//: "Enregistré"
UtilsCpp.showInformationPopup(qsTr("saved"),
//: "Réunion mise à jour"
qsTr("meeting_info_updated_toast"), true)
}
else if (conferenceEdit.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.AllocationPending
|| conferenceEdit.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Updating) {
UtilsCpp.getMainWindow().showLoadingPopup(qsTr("Modification de la réunion en cours..."))
//: "Modification de la réunion en cours"
UtilsCpp.getMainWindow().showLoadingPopup(qsTr("meeting_schedule_edit_in_progress"))
} else if (conferenceEdit.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Error) {
UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La modification de la conférence a échoué"), false)
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
//: "Échec de la modification de la réunion !"
qsTr("meeting_failed_to_edit_toast"), false)
UtilsCpp.getMainWindow().closeLoadingPopup()
}
}
@ -476,7 +506,8 @@ AbstractMainPage {
onClicked: container.pop()
}
Text {
text: qsTr("Ajouter des participants")
//: "Ajouter des participants"
text: qsTr("meeting_schedule_add_participants_title")
color: DefaultStyle.main1_500_main
maximumLineCount: 1
font {
@ -491,7 +522,7 @@ AbstractMainPage {
Layout.leftMargin: Math.round(11 * DefaultStyle.dp)
focus: enabled
style: ButtonStyle.main
text: qsTr("Ajouter")
text: qsTr("add")
KeyNavigation.left: addParticipantsBackButton
KeyNavigation.down: addParticipantLayout
onClicked: {
@ -500,7 +531,8 @@ AbstractMainPage {
}
}
Text {
text: qsTr("%1 participant%2 sélectionné%2").arg(addParticipantLayout.selectedParticipantsCount).arg(addParticipantLayout.selectedParticipantsCount > 1 ? "s" : "")
//: "%n participant(s) sélectionné(s)"
text: qsTr("group_call_participant_selected").arg(addParticipantLayout.selectedParticipantsCount)
color: DefaultStyle.main2_500main
Layout.leftMargin: addParticipantsBackButton.width + addParticipantsButtons.spacing
maximumLineCount: 1
@ -584,7 +616,8 @@ AbstractMainPage {
property var isMeObj: UtilsCpp.isMe(mainItem.selectedConference?.core?.organizerAddress)
property bool canCancel: isMeObj && isMeObj.value && mainItem.selectedConference?.core?.state !== LinphoneEnums.ConferenceInfoState.Cancelled
icon.source: AppIcons.trashCan
text: qsTr("Supprimer cette réunion")
//: "Supprimer la réunion"
text: qsTr("meeting_info_delete")
onClicked: {
if (mainItem.selectedConference) {
@ -653,7 +686,9 @@ AbstractMainPage {
KeyNavigation.down: joinButton
onClicked: {
UtilsCpp.copyToClipboard(mainItem.selectedConference.core.uri)
UtilsCpp.showInformationPopup(qsTr("Enregistré"), qsTr("Le lien de la réunion a été copié dans le presse-papiers"))
UtilsCpp.showInformationPopup(qsTr("saved"),
//: "Adresse de la réunion copiée"
qsTr("meeting_address_copied_to_clipboard_toast"))
}
}
}
@ -687,7 +722,8 @@ AbstractMainPage {
colorizationColor: DefaultStyle.main2_600
}
Text {
text: qsTr("Time zone: ") + (mainItem.selectedConference && mainItem.selectedConference.core ? (mainItem.selectedConference.core.timeZoneModel.displayName + ", " + mainItem.selectedConference.core.timeZoneModel.countryName) : "")
//: "Fuseau horaire"
text: "%1: %2".arg(qsTr("meeting_schedule_timezone_title")).arg(mainItem.selectedConference && mainItem.selectedConference.core ? (mainItem.selectedConference.core.timeZoneModel.displayName + ", " + mainItem.selectedConference.core.timeZoneModel.countryName) : "")
font {
pixelSize: Math.round(14 * DefaultStyle.dp)
capitalization: Font.Capitalize
@ -779,7 +815,8 @@ AbstractMainPage {
}
}
Text {
text: qsTr("Organizer")
//: "Organisateur"
text: qsTr("meeting_info_organizer_label")
visible: mainItem.selectedConference && mainItem.selectedConference.core?.organizerAddress === modelData.address
color: DefaultStyle.main2_400
font {
@ -795,7 +832,8 @@ AbstractMainPage {
id: joinButton
visible: mainItem.selectedConference && mainItem.selectedConference.core?.state !== LinphoneEnums.ConferenceInfoState.Cancelled
Layout.fillWidth: true
text: qsTr("Rejoindre la réunion")
//: "Rejoindre la réunion"
text: qsTr("meeting_info_join_title")
focus: true
KeyNavigation.up: shareNetworkButton
KeyNavigation.down: deletePopup

View file

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

View file

@ -74,7 +74,8 @@ ApplicationWindow {
spacing: Math.round(5 * DefaultStyle.dp)
width: startCallPopup.width
Text {
text: qsTr("Quelle adresse souhaitez-vous appeler ?")
//: "Choisissez un numéro ou adresse SIP"
text: qsTr("contact_dialog_pick_phone_number_or_sip_address_title")
wrapMode: Text.Wrap
Layout.fillWidth: true
font {
@ -272,7 +273,8 @@ ApplicationWindow {
font.bold: true
font.italic: true
font.pixelSize: Math.round(14 * DefaultStyle.dp)
text: parent.fps + " FPS"
// "%1 FPS"
text: qsTr("fps_counter").arg(parent.fps)
color: parent.fps < 30 ? DefaultStyle.danger_500main : DefaultStyle.main2_900
}
}

View file

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

View file

@ -10,7 +10,7 @@ import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
AbstractWindow {
id: mainWindow
// height: Math.round(982 * DefaultStyle.dp)
title: qsTr("Linphone")
title: applicationName
// TODO : handle this bool when security mode is implemented
property bool firstConnection: true
@ -31,7 +31,12 @@ AbstractWindow {
function openMainPage(connectionSucceed){
if (mainWindowStackView.currentItem.objectName !== "mainPage") mainWindowStackView.replace(mainPage, StackView.Immediate)
if (connectionSucceed) mainWindow.showInformationPopup(qsTr("Connexion réussie"), qsTr("Vous êtes connecté en mode %1").arg("interopérable"))
//: "Connexion réussie"
if (connectionSucceed) mainWindow.showInformationPopup(qsTr("information_popup_connexion_succeed_title"),
//: "Vous êtes connecté en mode %1"
qsTr("information_popup_connexion_succeed_message").arg(
//: interopérable
qsTr("interoperable")))
}
function goToCallHistory() {
openMainPage()
@ -47,16 +52,19 @@ AbstractWindow {
}
function transferCallSucceed() {
openMainPage()
mainWindow.showInformationPopup(qsTr("Appel transféré"), qsTr("Votre correspondant a été transféré au contact sélectionné"))
//: "Appel transféré"
mainWindow.showInformationPopup(qsTr("call_transfer_successful_toast_title"),
//: "Votre correspondant a été transféré au contact sélectionné"
qsTr("call_transfer_successful_toast_message"))
}
function initStackViewItem() {
if(accountProxy && accountProxy.isInitialized) {
if (accountProxy.haveAccount) openMainPage()
else if (SettingsCpp.getFirstLaunch()) mainWindowStackView.replace(welcomePage, StackView.Immediate)
else if (SettingsCpp.assistantGoDirectlyToThirdPartySipAccountLogin) mainWindowStackView.replace(sipLoginPage, StackView.Immediate)
else mainWindowStackView.replace(loginPage, StackView.Immediate)
}
}
if(accountProxy && accountProxy.isInitialized) {
if (accountProxy.haveAccount) openMainPage()
else if (SettingsCpp.getFirstLaunch()) mainWindowStackView.replace(welcomePage, StackView.Immediate)
else if (SettingsCpp.assistantGoDirectlyToThirdPartySipAccountLogin) mainWindowStackView.replace(sipLoginPage, StackView.Immediate)
else mainWindowStackView.replace(loginPage, StackView.Immediate)
}
}
function goToLogin() {
if (SettingsCpp.assistantGoDirectlyToThirdPartySipAccountLogin)
@ -93,7 +101,8 @@ AbstractWindow {
initStackViewItem()
}
function onIsSavedChanged() {
if (SettingsCpp.isSaved) UtilsCpp.showInformationPopup(qsTr("Succès"), qsTr("Les changements ont été sauvegardés"), true, mainWindow)
//: "Les changements ont été sauvegardés"
if (SettingsCpp.isSaved) UtilsCpp.showInformationPopup(qsTr("information_popup_success_title"), qsTr("information_popup_changes_saved"), true, mainWindow)
}
}
@ -122,7 +131,7 @@ AbstractWindow {
StackView {
id: mainWindowStackView
anchors.fill: parent
initialItem: splashScreen
initialItem: splashScreen
}
Component {
id: splashScreen
@ -177,14 +186,16 @@ AbstractWindow {
id: registerPage
RegisterPage {
onReturnToLogin: goToLogin()
onBrowserValidationRequested: mainWindow.showLoadingPopup(qsTr("Veuillez valider le captcha sur la page web"), true)
//: "Veuillez valider le captcha sur la page web"
onBrowserValidationRequested: mainWindow.showLoadingPopup(qsTr("captcha_validation_loading_message"), true)
Connections {
target: RegisterPageCpp
function onNewAccountCreationSucceed(withEmail, address, sipIdentityAddress) {
mainWindowStackView.push(checkingPage, {"registerWithEmail": withEmail, "address": address, "sipIdentityAddress": sipIdentityAddress})
}
function onRegisterNewAccountFailed(errorMessage) {
mainWindow.showInformationPopup(qsTr("Erreur lors de la création"), errorMessage, false)
//: "Erreur lors de la création"
mainWindow.showInformationPopup(qsTr("assistant_register_error_title"), errorMessage, false)
mainWindow.closeLoadingPopup()
}
function onTokenConversionSucceed(){ mainWindow.closeLoadingPopup()}
@ -202,11 +213,15 @@ AbstractWindow {
target: RegisterPageCpp
function onLinkingNewAccountWithCodeSucceed() {
goToLogin()
mainWindow.showInformationPopup(qsTr("Compte créé"), qsTr("Le compte a été créé avec succès. Vous pouvez maintenant vous connecter"), true)
//: "Compte créé"
mainWindow.showInformationPopup(qsTr("assistant_register_success_title"),
//: "Le compte a été créé. Vous pouvez maintenant vous connecter"
qsTr("assistant_register_success_message"), true)
}
function onLinkingNewAccountWithCodeFailed(errorMessage) {
if (errorMessage.length === 0) errorMessage = qsTr("Erreur dans le code de validation")
mainWindow.showInformationPopup(qsTr("Erreur"), errorMessage, false)
//: "Erreur dans le code de validation"
if (errorMessage.length === 0) errorMessage = qsTr("assistant_register_error_code")
mainWindow.showInformationPopup(qsTr("information_popup_error_title"), errorMessage, false)
}
}
}

View file

@ -7,7 +7,7 @@ Window {
width: 960
height: 600
visible: true
title: qsTr("Test")
title: ("Test")
ColumnLayout {
RowLayout {
ColumnLayout {
@ -134,7 +134,7 @@ Window {
TabBar {
spacing: 10
contentWidth: 400
model: [qsTr("A"), qsTr("Lot"), qsTr("Of"), qsTr("Tab"), qsTr("Buttons (which one has a very long label)"), qsTr("For"), qsTr("The"), qsTr("Tab"), qsTr("Bar"), qsTr("To"), qsTr("Not"), qsTr("Have"), qsTr("Enough"), qsTr("Space"), qsTr("To"), qsTr("Display"), qsTr("Them"), qsTr("All")]
model: [("A"), ("Lot"), ("Of"), ("Tab"), ("Buttons (which one has a very long label)"), ("For"), ("The"), ("Tab"), ("Bar"), ("To"), ("Not"), ("Have"), ("Enough"), ("Space"), ("To"), ("Display"), ("Them"), ("All")]
}
}