summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swift/Controllers')
-rw-r--r--Swift/Controllers/Chat/ChatController.cpp27
-rw-r--r--Swift/Controllers/Chat/ChatControllerBase.cpp50
-rw-r--r--Swift/Controllers/Chat/MUCController.cpp123
-rw-r--r--Swift/Controllers/Chat/MUCSearchController.h1
-rw-r--r--Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp16
-rw-r--r--Swift/Controllers/Intl.h12
-rw-r--r--Swift/Controllers/MainController.cpp69
-rw-r--r--Swift/Controllers/PresenceNotifier.cpp3
-rw-r--r--Swift/Controllers/Roster/RosterController.cpp10
-rw-r--r--Swift/Controllers/SConscript2
-rw-r--r--Swift/Controllers/StatusUtil.cpp25
-rw-r--r--Swift/Controllers/StatusUtil.h16
-rw-r--r--Swift/Controllers/Translator.cpp28
-rw-r--r--Swift/Controllers/Translator.h27
14 files changed, 291 insertions, 118 deletions
diff --git a/Swift/Controllers/Chat/ChatController.cpp b/Swift/Controllers/Chat/ChatController.cpp
index e4ad9c8..6e7825f 100644
--- a/Swift/Controllers/Chat/ChatController.cpp
+++ b/Swift/Controllers/Chat/ChatController.cpp
@@ -9,6 +9,8 @@
#include <boost/bind.hpp>
#include <stdio.h>
+#include <Swift/Controllers/Intl.h>
+#include <Swiften/Base/format.h>
#include "Swiften/Avatars/AvatarManager.h"
#include "Swiften/Chat/ChatStateNotifier.h"
#include "Swiften/Chat/ChatStateTracker.h"
@@ -18,6 +20,7 @@
#include "Swift/Controllers/UIInterfaces/ChatWindowFactory.h"
#include "Swiften/Client/NickResolver.h"
#include "Swift/Controllers/XMPPEvents/EventController.h"
+#include <Swift/Controllers/StatusUtil.h>
namespace Swift {
@@ -37,16 +40,16 @@ ChatController::ChatController(const JID& self, StanzaChannel* stanzaChannel, IQ
nickResolver_->onNickChanged.connect(boost::bind(&ChatController::handleContactNickChanged, this, _1, _2));
std::string nick = nickResolver_->jidToNick(toJID_);
chatWindow_->setName(nick);
- std::string startMessage("Starting chat with " + nick);
+ std::string startMessage;
Presence::ref theirPresence;
if (isInMUC) {
- startMessage += " in chatroom " + contact.toBare().toString();
+ startMessage = str(format(QT_TRANSLATE_NOOP("", "Starting chat with %1% in chatroom %2%")) % nick % contact.toBare().toString());
theirPresence = presenceOracle->getLastPresence(contact);
} else {
- startMessage += " - " + contact.toBare().toString();
+ startMessage = str(format(QT_TRANSLATE_NOOP("", "Starting chat with %1% - %2%")) % nick % contact.toBare().toString());
theirPresence = contact.isBare() ? presenceOracle->getHighestPriorityPresence(contact.toBare()) : presenceOracle->getLastPresence(contact);
}
- startMessage += ": " + StatusShow::typeToFriendlyName(theirPresence ? theirPresence->getShow() : StatusShow::None);
+ startMessage += ": " + statusShowTypeToFriendlyName(theirPresence ? theirPresence->getShow() : StatusShow::None);
if (theirPresence && !theirPresence->getStatus().empty()) {
startMessage += " (" + theirPresence->getStatus() + ")";
}
@@ -109,7 +112,7 @@ void ChatController::preSendMessageRequest(boost::shared_ptr<Message> message) {
}
void ChatController::postSendMessage(const std::string& body, boost::shared_ptr<Stanza> sentStanza) {
- std::string id = addMessage(body, "me", true, labelsEnabled_ ? chatWindow_->getSelectedSecurityLabel() : boost::optional<SecurityLabel>(), std::string(avatarManager_->getAvatarPath(selfJID_).string()), boost::posix_time::microsec_clock::universal_time());
+ std::string id = addMessage(body, QT_TRANSLATE_NOOP("", "me"), true, labelsEnabled_ ? chatWindow_->getSelectedSecurityLabel() : boost::optional<SecurityLabel>(), std::string(avatarManager_->getAvatarPath(selfJID_).string()), boost::posix_time::microsec_clock::universal_time());
if (stanzaChannel_->getStreamManagementEnabled()) {
chatWindow_->setAckState(id, ChatWindow::Pending);
unackedStanzas_[sentStanza] = id;
@@ -148,19 +151,23 @@ std::string ChatController::senderDisplayNameFromMessage(const JID& from) {
std::string ChatController::getStatusChangeString(boost::shared_ptr<Presence> presence) {
std::string nick = senderDisplayNameFromMessage(presence->getFrom());
- std::string response = nick;
+ std::string response;
if (!presence || presence->getType() == Presence::Unavailable || presence->getType() == Presence::Error) {
- response += " has gone offline";
+ response = QT_TRANSLATE_NOOP("", "%1% has gone offline");
} else if (presence->getType() == Presence::Available) {
StatusShow::Type show = presence->getShow();
if (show == StatusShow::Online || show == StatusShow::FFC) {
- response += " has become available";
+ response = QT_TRANSLATE_NOOP("", "%1% has become available");
} else if (show == StatusShow::Away || show == StatusShow::XA) {
- response += " has gone away";
+ response = QT_TRANSLATE_NOOP("", "%1% has gone away");
} else if (show == StatusShow::DND) {
- response += " is now busy";
+ response = QT_TRANSLATE_NOOP("", "%1% is now busy");
}
}
+ if (!response.empty()) {
+ response = str(format(response) % nick);
+ }
+
if (!presence->getStatus().empty()) {
response += " (" + presence->getStatus() + ")";
}
diff --git a/Swift/Controllers/Chat/ChatControllerBase.cpp b/Swift/Controllers/Chat/ChatControllerBase.cpp
index f70ec81..a970d88 100644
--- a/Swift/Controllers/Chat/ChatControllerBase.cpp
+++ b/Swift/Controllers/Chat/ChatControllerBase.cpp
@@ -13,6 +13,8 @@
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/algorithm/string.hpp>
+#include <Swift/Controllers/Intl.h>
+#include <Swiften/Base/format.h>
#include "Swiften/Base/String.h"
#include "Swiften/Client/StanzaChannel.h"
#include "Swiften/Elements/Delay.h"
@@ -51,7 +53,7 @@ void ChatControllerBase::createDayChangeTimer() {
void ChatControllerBase::handleDayChangeTick() {
dateChangeTimer_->stop();
boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
- chatWindow_->addSystemMessage("The day is now " + std::string(boost::posix_time::to_iso_extended_string(now)).substr(0,10));
+ chatWindow_->addSystemMessage(str(format(QT_TRANSLATE_NOOP("", "The day is now %1%")) % std::string(boost::posix_time::to_iso_extended_string(now)).substr(0,10)));
dayTicked();
createDayChangeTimer();
}
@@ -188,34 +190,34 @@ void ChatControllerBase::handleIncomingMessage(boost::shared_ptr<MessageEvent> m
}
std::string ChatControllerBase::getErrorMessage(boost::shared_ptr<ErrorPayload> error) {
- std::string defaultMessage = "Error sending message";
+ std::string defaultMessage = QT_TRANSLATE_NOOP("", "Error sending message");
if (!error->getText().empty()) {
return error->getText();
}
else {
switch (error->getCondition()) {
- case ErrorPayload::BadRequest: return "Bad request"; break;
- case ErrorPayload::Conflict: return "Conflict"; break;
- case ErrorPayload::FeatureNotImplemented: return "This feature is not implemented"; break;
- case ErrorPayload::Forbidden: return "Forbidden"; break;
- case ErrorPayload::Gone: return "Recipient can no longer be contacted"; break;
- case ErrorPayload::InternalServerError: return "Internal server error"; break;
- case ErrorPayload::ItemNotFound: return "Item not found"; break;
- case ErrorPayload::JIDMalformed: return "JID Malformed"; break;
- case ErrorPayload::NotAcceptable: return "Message was rejected"; break;
- case ErrorPayload::NotAllowed: return "Not allowed"; break;
- case ErrorPayload::NotAuthorized: return "Not authorized"; break;
- case ErrorPayload::PaymentRequired: return "Payment is required"; break;
- case ErrorPayload::RecipientUnavailable: return "Recipient is unavailable."; break;
- case ErrorPayload::Redirect: return "Redirect"; break;
- case ErrorPayload::RegistrationRequired: return "Registration required"; break;
- case ErrorPayload::RemoteServerNotFound: return "Recipient's server not found."; break;
- case ErrorPayload::RemoteServerTimeout: return "Remote server timeout"; break;
- case ErrorPayload::ResourceConstraint: return "The server is low on resources"; break;
- case ErrorPayload::ServiceUnavailable: return "The service is unavailable"; break;
- case ErrorPayload::SubscriptionRequired: return "A subscription is required"; break;
- case ErrorPayload::UndefinedCondition: return "Undefined condition"; break;
- case ErrorPayload::UnexpectedRequest: return "Unexpected request"; break;
+ case ErrorPayload::BadRequest: return QT_TRANSLATE_NOOP("", "Bad request"); break;
+ case ErrorPayload::Conflict: return QT_TRANSLATE_NOOP("", "Conflict"); break;
+ case ErrorPayload::FeatureNotImplemented: return QT_TRANSLATE_NOOP("", "This feature is not implemented"); break;
+ case ErrorPayload::Forbidden: return QT_TRANSLATE_NOOP("", "Forbidden"); break;
+ case ErrorPayload::Gone: return QT_TRANSLATE_NOOP("", "Recipient can no longer be contacted"); break;
+ case ErrorPayload::InternalServerError: return QT_TRANSLATE_NOOP("", "Internal server error"); break;
+ case ErrorPayload::ItemNotFound: return QT_TRANSLATE_NOOP("", "Item not found"); break;
+ case ErrorPayload::JIDMalformed: return QT_TRANSLATE_NOOP("", "JID Malformed"); break;
+ case ErrorPayload::NotAcceptable: return QT_TRANSLATE_NOOP("", "Message was rejected"); break;
+ case ErrorPayload::NotAllowed: return QT_TRANSLATE_NOOP("", "Not allowed"); break;
+ case ErrorPayload::NotAuthorized: return QT_TRANSLATE_NOOP("", "Not authorized"); break;
+ case ErrorPayload::PaymentRequired: return QT_TRANSLATE_NOOP("", "Payment is required"); break;
+ case ErrorPayload::RecipientUnavailable: return QT_TRANSLATE_NOOP("", "Recipient is unavailable"); break;
+ case ErrorPayload::Redirect: return QT_TRANSLATE_NOOP("", "Redirect"); break;
+ case ErrorPayload::RegistrationRequired: return QT_TRANSLATE_NOOP("", "Registration required"); break;
+ case ErrorPayload::RemoteServerNotFound: return QT_TRANSLATE_NOOP("", "Recipient's server not found"); break;
+ case ErrorPayload::RemoteServerTimeout: return QT_TRANSLATE_NOOP("", "Remote server timeout"); break;
+ case ErrorPayload::ResourceConstraint: return QT_TRANSLATE_NOOP("", "The server is low on resources"); break;
+ case ErrorPayload::ServiceUnavailable: return QT_TRANSLATE_NOOP("", "The service is unavailable"); break;
+ case ErrorPayload::SubscriptionRequired: return QT_TRANSLATE_NOOP("", "A subscription is required"); break;
+ case ErrorPayload::UndefinedCondition: return QT_TRANSLATE_NOOP("", "Undefined condition"); break;
+ case ErrorPayload::UnexpectedRequest: return QT_TRANSLATE_NOOP("", "Unexpected request"); break;
}
}
return defaultMessage;
diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp
index 765c49d..ce8c946 100644
--- a/Swift/Controllers/Chat/MUCController.cpp
+++ b/Swift/Controllers/Chat/MUCController.cpp
@@ -10,6 +10,8 @@
#include <boost/regex.hpp>
#include <boost/algorithm/string.hpp>
+#include <Swift/Controllers/Intl.h>
+#include <Swiften/Base/format.h>
#include "Swiften/Network/Timer.h"
#include "Swiften/Network/TimerFactory.h"
#include "Swiften/Base/foreach.h"
@@ -109,7 +111,7 @@ void MUCController::rejoin() {
void MUCController::handleJoinTimeoutTick() {
receivedActivity();
- chatWindow_->addSystemMessage("Room " + toJID_.toString() + " is not responding. This operation may never complete");
+ chatWindow_->addSystemMessage(str(format(QT_TRANSLATE_NOOP("", "Room %1% is not responding. This operation may never complete.")) % toJID_.toString()));
}
void MUCController::receivedActivity() {
@@ -120,17 +122,38 @@ void MUCController::receivedActivity() {
void MUCController::handleJoinFailed(boost::shared_ptr<ErrorPayload> error) {
receivedActivity();
- std::string errorMessage = "Unable to join this room";
+ std::string errorMessage = QT_TRANSLATE_NOOP("", "Unable to join this room");
std::string rejoinNick;
if (error) {
switch (error->getCondition()) {
- case ErrorPayload::Conflict: rejoinNick = nick_ + "_"; errorMessage += " as " + nick_ + ", retrying as " + rejoinNick; break;
- case ErrorPayload::JIDMalformed: errorMessage += ", no nickname specified";break;
- case ErrorPayload::NotAuthorized: errorMessage += ", a password needed";break;
- case ErrorPayload::RegistrationRequired: errorMessage += ", only members may join"; break;
- case ErrorPayload::Forbidden: errorMessage += ", you are banned from the room"; break;
- case ErrorPayload::ServiceUnavailable: errorMessage += ", the room is full";break;
- case ErrorPayload::ItemNotFound: errorMessage += ", the room does not exist";break;
+ case ErrorPayload::Conflict:
+ rejoinNick = nick_ + "_";
+ errorMessage = str(format(QT_TRANSLATE_NOOP("", "Unable to join this room as %1%, retrying as %2%")) % nick_ % rejoinNick);
+ break;
+ case ErrorPayload::JIDMalformed:
+ errorMessage += ": ";
+ errorMessage += QT_TRANSLATE_NOOP("", "No nickname specified");
+ break;
+ case ErrorPayload::NotAuthorized:
+ errorMessage += ": ";
+ errorMessage += QT_TRANSLATE_NOOP("", "A password needed");
+ break;
+ case ErrorPayload::RegistrationRequired:
+ errorMessage += ": ";
+ errorMessage += QT_TRANSLATE_NOOP("", "Only members may join");
+ break;
+ case ErrorPayload::Forbidden:
+ errorMessage += ": ";
+ errorMessage += QT_TRANSLATE_NOOP("", "You are banned from the room");
+ break;
+ case ErrorPayload::ServiceUnavailable:
+ errorMessage += ": ";
+ errorMessage += QT_TRANSLATE_NOOP("", "The room is full");
+ break;
+ case ErrorPayload::ItemNotFound:
+ errorMessage += ": ";
+ errorMessage += QT_TRANSLATE_NOOP("", "The room does not exist");
+ break;
default: break;
}
@@ -147,7 +170,7 @@ void MUCController::handleJoinFailed(boost::shared_ptr<ErrorPayload> error) {
void MUCController::handleJoinComplete(const std::string& nick) {
receivedActivity();
joined_ = true;
- std::string joinMessage = "You have joined room " + toJID_.toString() + " as " + nick;
+ std::string joinMessage = str(format(QT_TRANSLATE_NOOP("", "You have joined room %1% as %2%")) % toJID_.toString() % nick);
nick_ = nick;
chatWindow_->addSystemMessage(joinMessage);
clearPresenceQueue();
@@ -185,13 +208,14 @@ void MUCController::handleOccupantJoined(const MUCOccupant& occupant) {
appendToJoinParts(joinParts_, event);
roster_->addContact(jid, realJID, occupant.getNick(), roleToGroupName(occupant.getRole()), avatarManager_->getAvatarPath(jid).string());
if (joined_) {
- std::string joinString = occupant.getNick() + " has joined the room";
+ std::string joinString;
MUCOccupant::Role role = occupant.getRole();
if (role != MUCOccupant::NoRole && role != MUCOccupant::Participant) {
- joinString += " as a " + roleToFriendlyName(role);
-
+ joinString = str(format(QT_TRANSLATE_NOOP("", "%1% has joined the room as a %2%.")) % occupant.getNick() % roleToFriendlyName(role));
+ }
+ else {
+ joinString = str(format(QT_TRANSLATE_NOOP("", "%1% has joined the room.")) % occupant.getNick());
}
- joinString += ".";
if (shouldUpdateJoinParts()) {
updateJoinParts();
} else {
@@ -216,9 +240,9 @@ void MUCController::clearPresenceQueue() {
std::string MUCController::roleToFriendlyName(MUCOccupant::Role role) {
switch (role) {
- case MUCOccupant::Moderator: return "moderator";
- case MUCOccupant::Participant: return "participant";
- case MUCOccupant::Visitor: return "visitor";
+ case MUCOccupant::Moderator: return QT_TRANSLATE_NOOP("", "moderator");
+ case MUCOccupant::Participant: return QT_TRANSLATE_NOOP("", "participant");
+ case MUCOccupant::Visitor: return QT_TRANSLATE_NOOP("", "visitor");
case MUCOccupant::NoRole: return "";
}
return "";
@@ -257,7 +281,7 @@ void MUCController::preHandleIncomingMessage(boost::shared_ptr<MessageEvent> mes
joined_ = true;
if (!message->getSubject().empty() && message->getBody().empty()) {
- chatWindow_->addSystemMessage("The room subject is now: " + message->getSubject());
+ chatWindow_->addSystemMessage(str(format(QT_TRANSLATE_NOOP("", "The room subject is now: %1%")) % message->getSubject()));;
doneGettingHistory_ = true;
}
@@ -280,16 +304,16 @@ void MUCController::handleOccupantRoleChanged(const std::string& nick, const MUC
realJID = occupant.getRealJID().get();
}
roster_->addContact(jid, realJID, nick, roleToGroupName(occupant.getRole()), avatarManager_->getAvatarPath(jid).string());
- chatWindow_->addSystemMessage(nick + " is now a " + roleToFriendlyName(occupant.getRole()));
+ chatWindow_->addSystemMessage(str(format(QT_TRANSLATE_NOOP("", "%1% is now a %2%")) % nick % roleToFriendlyName(occupant.getRole())));
}
std::string MUCController::roleToGroupName(MUCOccupant::Role role) {
std::string result;
switch (role) {
- case MUCOccupant::Moderator: result = "Moderators"; break;
- case MUCOccupant::Participant: result = "Participants"; break;
- case MUCOccupant::Visitor: result = "Visitors"; break;
- case MUCOccupant::NoRole: result = "Occupants"; break;
+ case MUCOccupant::Moderator: result = QT_TRANSLATE_NOOP("", "Moderators"); break;
+ case MUCOccupant::Participant: result = QT_TRANSLATE_NOOP("", "Participants"); break;
+ case MUCOccupant::Visitor: result = QT_TRANSLATE_NOOP("", "Visitors"); break;
+ case MUCOccupant::NoRole: result = QT_TRANSLATE_NOOP("", "Occupants"); break;
default: assert(false);
}
return result;
@@ -303,7 +327,7 @@ void MUCController::setOnline(bool online) {
processUserPart();
} else {
if (shouldJoinOnReconnect_) {
- chatWindow_->addSystemMessage("Trying to join room " + toJID_.toString());
+ chatWindow_->addSystemMessage(str(format(QT_TRANSLATE_NOOP("", "Trying to join room %1%")) % toJID_.toString()));
if (loginCheckTimer_) {
loginCheckTimer_->start();
}
@@ -332,7 +356,7 @@ void MUCController::handleOccupantLeft(const MUCOccupant& occupant, MUC::Leaving
appendToJoinParts(joinParts_, event);
currentOccupants_.erase(occupant.getNick());
completer_->removeWord(occupant.getNick());
- std::string partMessage = (occupant.getNick() != nick_) ? occupant.getNick() + " has left the room" : "You have left the room";
+ std::string partMessage = (occupant.getNick() != nick_) ? str(format(QT_TRANSLATE_NOOP("", "%1% has left the room")) % occupant.getNick()) : QT_TRANSLATE_NOOP("", "You have left the room");
if (!reason.empty()) {
partMessage += " (" + reason + ")";
}
@@ -406,7 +430,7 @@ std::string MUCController::concatenateListOfNames(const std::vector<NickJoinPart
if (i < joinParts.size() - 1) {
result += ", ";
} else {
- result += " and ";
+ result += QT_TRANSLATE_NOOP("", " and ");
}
}
NickJoinPart event = joinParts[i];
@@ -424,17 +448,45 @@ std::string MUCController::generateJoinPartString(const std::vector<NickJoinPart
std::string result;
std::vector<JoinPart> populatedEvents;
for (size_t i = 0; i < 4; i++) {
- std::string eventString = concatenateListOfNames(sorted[i]);
- if (!eventString.empty()) {
- std::string haveHas = sorted[i].size() > 1 ? " have" : " has";
+ std::string names = concatenateListOfNames(sorted[i]);
+ if (!names.empty()) {
+ std::string eventString;
switch (i) {
- case Join: eventString += haveHas + " joined";break;
- case Part: eventString += haveHas + " left";break;
- case JoinThenPart: eventString += " joined then left";break;
- case PartThenJoin: eventString += " left then rejoined";break;
+ case Join:
+ if (sorted[i].size() > 1) {
+ eventString = QT_TRANSLATE_NOOP("", "%1% have joined the room");
+ }
+ else {
+ eventString = QT_TRANSLATE_NOOP("", "%1% has joined the room");
+ }
+ break;
+ case Part:
+ if (sorted[i].size() > 1) {
+ eventString = QT_TRANSLATE_NOOP("", "%1% have left the room");
+ }
+ else {
+ eventString = QT_TRANSLATE_NOOP("", "%1% has left the room");
+ }
+ break;
+ case JoinThenPart:
+ if (sorted[i].size() > 1) {
+ eventString = QT_TRANSLATE_NOOP("", "%1% have joined then left the room");
+ }
+ else {
+ eventString = QT_TRANSLATE_NOOP("", "%1% has joined then left the room");
+ }
+ break;
+ case PartThenJoin:
+ if (sorted[i].size() > 1) {
+ eventString = QT_TRANSLATE_NOOP("", "%1% have left then rejoined the room");
+ }
+ else {
+ eventString = QT_TRANSLATE_NOOP("", "%1% has left then rejoined the room");
+ }
+ break;
}
populatedEvents.push_back(static_cast<JoinPart>(i));
- eventStrings[i] = eventString;
+ eventStrings[i] = str(boost::format(eventString) % names);
}
}
for (size_t i = 0; i < populatedEvents.size(); i++) {
@@ -442,12 +494,11 @@ std::string MUCController::generateJoinPartString(const std::vector<NickJoinPart
if (i < populatedEvents.size() - 1) {
result += ", ";
} else {
- result += " and ";
+ result += QT_TRANSLATE_NOOP("", " and ");
}
}
result += eventStrings[populatedEvents[i]];
}
- result += " the room.";
return result;
}
diff --git a/Swift/Controllers/Chat/MUCSearchController.h b/Swift/Controllers/Chat/MUCSearchController.h
index b348886..c8040ed 100644
--- a/Swift/Controllers/Chat/MUCSearchController.h
+++ b/Swift/Controllers/Chat/MUCSearchController.h
@@ -16,7 +16,6 @@
#include "Swiften/JID/JID.h"
#include "Swift/Controllers/UIEvents/UIEvent.h"
-#include "Swift/Controllers/Chat/MUCSearchController.h"
#include "Swift/Controllers/Settings/SettingsProvider.h"
#include "Swiften/Elements/DiscoInfo.h"
#include "Swiften/Elements/DiscoItems.h"
diff --git a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp
index 7c7a8b9..e66fa9e 100644
--- a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp
+++ b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp
@@ -200,25 +200,25 @@ public:
void testJoinPartStringContructionSimple() {
std::vector<NickJoinPart> list;
list.push_back(NickJoinPart("Kev", Join));
- CPPUNIT_ASSERT_EQUAL(std::string("Kev has joined the room."), MUCController::generateJoinPartString(list));
+ CPPUNIT_ASSERT_EQUAL(std::string("Kev has joined the room"), MUCController::generateJoinPartString(list));
list.push_back(NickJoinPart("Remko", Part));
- CPPUNIT_ASSERT_EQUAL(std::string("Kev has joined and Remko has left the room."), MUCController::generateJoinPartString(list));
+ CPPUNIT_ASSERT_EQUAL(std::string("Kev has joined the room and Remko has left the room"), MUCController::generateJoinPartString(list));
list.push_back(NickJoinPart("Bert", Join));
- CPPUNIT_ASSERT_EQUAL(std::string("Kev and Bert have joined and Remko has left the room."), MUCController::generateJoinPartString(list));
+ CPPUNIT_ASSERT_EQUAL(std::string("Kev and Bert have joined the room and Remko has left the room"), MUCController::generateJoinPartString(list));
list.push_back(NickJoinPart("Ernie", Join));
- CPPUNIT_ASSERT_EQUAL(std::string("Kev, Bert and Ernie have joined and Remko has left the room."), MUCController::generateJoinPartString(list));
+ CPPUNIT_ASSERT_EQUAL(std::string("Kev, Bert and Ernie have joined the room and Remko has left the room"), MUCController::generateJoinPartString(list));
}
void testJoinPartStringContructionMixed() {
std::vector<NickJoinPart> list;
list.push_back(NickJoinPart("Kev", JoinThenPart));
- CPPUNIT_ASSERT_EQUAL(std::string("Kev joined then left the room."), MUCController::generateJoinPartString(list));
+ CPPUNIT_ASSERT_EQUAL(std::string("Kev has joined then left the room"), MUCController::generateJoinPartString(list));
list.push_back(NickJoinPart("Remko", Part));
- CPPUNIT_ASSERT_EQUAL(std::string("Remko has left and Kev joined then left the room."), MUCController::generateJoinPartString(list));
+ CPPUNIT_ASSERT_EQUAL(std::string("Remko has left the room and Kev has joined then left the room"), MUCController::generateJoinPartString(list));
list.push_back(NickJoinPart("Bert", PartThenJoin));
- CPPUNIT_ASSERT_EQUAL(std::string("Remko has left, Kev joined then left and Bert left then rejoined the room."), MUCController::generateJoinPartString(list));
+ CPPUNIT_ASSERT_EQUAL(std::string("Remko has left the room, Kev has joined then left the room and Bert has left then rejoined the room"), MUCController::generateJoinPartString(list));
list.push_back(NickJoinPart("Ernie", JoinThenPart));
- CPPUNIT_ASSERT_EQUAL(std::string("Remko has left, Kev and Ernie joined then left and Bert left then rejoined the room."), MUCController::generateJoinPartString(list));
+ CPPUNIT_ASSERT_EQUAL(std::string("Remko has left the room, Kev and Ernie have joined then left the room and Bert has left then rejoined the room"), MUCController::generateJoinPartString(list));
}
private:
diff --git a/Swift/Controllers/Intl.h b/Swift/Controllers/Intl.h
new file mode 100644
index 0000000..3ed664d
--- /dev/null
+++ b/Swift/Controllers/Intl.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2011 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <Swift/Controllers/Translator.h>
+
+#define QT_TRANSLATE_NOOP(context, text) \
+ Swift::Translator::getInstance()->translate(text, context)
diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp
index 1257845..6263636 100644
--- a/Swift/Controllers/MainController.cpp
+++ b/Swift/Controllers/MainController.cpp
@@ -10,8 +10,11 @@
#include <boost/lexical_cast.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/smart_ptr/make_shared.hpp>
+#include <string>
#include <stdlib.h>
+#include <Swiften/Base/format.h>
+#include <Swift/Controllers/Intl.h>
#include <Swift/Controllers/UIInterfaces/UIFactory.h>
#include "Swiften/Network/TimerFactory.h"
#include "Swift/Controllers/BuildVersion.h"
@@ -41,7 +44,6 @@
#include "SwifTools/Dock/Dock.h"
#include "SwifTools/Notifier/TogglableNotifier.h"
#include "Swiften/Base/foreach.h"
-#include <string>
#include "Swiften/Client/Client.h"
#include "Swiften/Presence/PresenceSender.h"
#include "Swiften/Elements/ChatState.h"
@@ -432,36 +434,35 @@ void MainController::handleDisconnected(const boost::optional<ClientError>& erro
std::string message;
std::string certificateErrorMessage;
switch(error->getType()) {
- case ClientError::UnknownError: message = "Unknown Error"; break;
- case ClientError::DomainNameResolveError: message = "Unable to find server"; break;
- case ClientError::ConnectionError: message = "Error connecting to server"; break;
- case ClientError::ConnectionReadError: message = "Error while receiving server data"; break;
- case ClientError::ConnectionWriteError: message = "Error while sending data to the server"; break;
- case ClientError::XMLError: message = "Error parsing server data"; break;
- case ClientError::AuthenticationFailedError: message = "Login/password invalid"; break;
- case ClientError::CompressionFailedError: message = "Error while compressing stream"; break;
- case ClientError::ServerVerificationFailedError: message = "Server verification failed"; break;
- case ClientError::NoSupportedAuthMechanismsError: message = "Authentication mechanisms not supported"; break;
- case ClientError::UnexpectedElementError: message = "Unexpected response"; break;
- case ClientError::ResourceBindError: message = "Error binding resource"; break;
- case ClientError::SessionStartError: message = "Error starting session"; break;
- case ClientError::StreamError: message = "Stream error"; break;
- case ClientError::TLSError: message = "Encryption error"; break;
- case ClientError::ClientCertificateLoadError: message = "Error loading certificate (Invalid password?)"; break;
- case ClientError::ClientCertificateError: message = "Certificate not authorized"; break;
-
- case ClientError::UnknownCertificateError: certificateErrorMessage = "Unknown certificate"; break;
- case ClientError::CertificateExpiredError: certificateErrorMessage = "Certificate has expired"; break;
- case ClientError::CertificateNotYetValidError: certificateErrorMessage = "Certificate is not yet valid"; break;
- case ClientError::CertificateSelfSignedError: certificateErrorMessage = "Certificate is self-signed"; break;
- case ClientError::CertificateRejectedError: certificateErrorMessage = "Certificate has been rejected"; break;
- case ClientError::CertificateUntrustedError: certificateErrorMessage = "Certificate is not trusted"; break;
- case ClientError::InvalidCertificatePurposeError: certificateErrorMessage = "Certificate cannot be used for encryptig your connection"; break;
- case ClientError::CertificatePathLengthExceededError: certificateErrorMessage = "Certificate path length constraint exceeded"; break;
- case ClientError::InvalidCertificateSignatureError: certificateErrorMessage = "Invalid certificate signature"; break;
- case ClientError::InvalidCAError: certificateErrorMessage = "Invalid Certificate Authority"; break;
- case ClientError::InvalidServerIdentityError: certificateErrorMessage = "Certificate does not match the host identity"; break;
-
+ case ClientError::UnknownError: message = QT_TRANSLATE_NOOP("", "Unknown Error"); break;
+ case ClientError::DomainNameResolveError: message = QT_TRANSLATE_NOOP("", "Unable to find server"); break;
+ case ClientError::ConnectionError: message = QT_TRANSLATE_NOOP("", "Error connecting to server"); break;
+ case ClientError::ConnectionReadError: message = QT_TRANSLATE_NOOP("", "Error while receiving server data"); break;
+ case ClientError::ConnectionWriteError: message = QT_TRANSLATE_NOOP("", "Error while sending data to the server"); break;
+ case ClientError::XMLError: message = QT_TRANSLATE_NOOP("", "Error parsing server data"); break;
+ case ClientError::AuthenticationFailedError: message = QT_TRANSLATE_NOOP("", "Login/password invalid"); break;
+ case ClientError::CompressionFailedError: message = QT_TRANSLATE_NOOP("", "Error while compressing stream"); break;
+ case ClientError::ServerVerificationFailedError: message = QT_TRANSLATE_NOOP("", "Server verification failed"); break;
+ case ClientError::NoSupportedAuthMechanismsError: message = QT_TRANSLATE_NOOP("", "Authentication mechanisms not supported"); break;
+ case ClientError::UnexpectedElementError: message = QT_TRANSLATE_NOOP("", "Unexpected response"); break;
+ case ClientError::ResourceBindError: message = QT_TRANSLATE_NOOP("", "Error binding resource"); break;
+ case ClientError::SessionStartError: message = QT_TRANSLATE_NOOP("", "Error starting session"); break;
+ case ClientError::StreamError: message = QT_TRANSLATE_NOOP("", "Stream error"); break;
+ case ClientError::TLSError: message = QT_TRANSLATE_NOOP("", "Encryption error"); break;
+ case ClientError::ClientCertificateLoadError: message = QT_TRANSLATE_NOOP("", "Error loading certificate (Invalid password?)"); break;
+ case ClientError::ClientCertificateError: message = QT_TRANSLATE_NOOP("", "Certificate not authorized"); break;
+
+ case ClientError::UnknownCertificateError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Unknown certificate"); break;
+ case ClientError::CertificateExpiredError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate has expired"); break;
+ case ClientError::CertificateNotYetValidError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate is not yet valid"); break;
+ case ClientError::CertificateSelfSignedError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate is self-signed"); break;
+ case ClientError::CertificateRejectedError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate has been rejected"); break;
+ case ClientError::CertificateUntrustedError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate is not trusted"); break;
+ case ClientError::InvalidCertificatePurposeError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate cannot be used for encryptig your connection"); break;
+ case ClientError::CertificatePathLengthExceededError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate path length constraint exceeded"); break;
+ case ClientError::InvalidCertificateSignatureError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Invalid certificate signature"); break;
+ case ClientError::InvalidCAError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Invalid Certificate Authority"); break;
+ case ClientError::InvalidServerIdentityError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate does not match the host identity"); break;
}
bool forceReconnectAfterCertificateTrust = false;
if (!certificateErrorMessage.empty()) {
@@ -471,7 +472,7 @@ void MainController::handleDisconnected(const boost::optional<ClientError>& erro
forceReconnectAfterCertificateTrust = true;
}
else {
- message = "Certificate error";
+ message = QT_TRANSLATE_NOOP("", "Certificate error");
}
}
@@ -485,10 +486,10 @@ void MainController::handleDisconnected(const boost::optional<ClientError>& erro
logout();
setReconnectTimer();
if (lastDisconnectError_) {
- message = "Reconnect to " + jid_.getDomain() + " failed: " + message + ". Will retry in " + boost::lexical_cast<std::string>(timeBeforeNextReconnect_) + " seconds.";
+ message = str(format(QT_TRANSLATE_NOOP("", "Reconnect to %1% failed: %2%. Will retry in %3% seconds.")) % jid_.getDomain() % message % boost::lexical_cast<std::string>(timeBeforeNextReconnect_));
lastDisconnectError_->conclude();
} else {
- message = "Disconnected from " + jid_.getDomain() + ": " + message;
+ message = str(format(QT_TRANSLATE_NOOP("", "Disconnected from %1%: %2%.")) % jid_.getDomain() % message);
}
lastDisconnectError_ = boost::shared_ptr<ErrorEvent>(new ErrorEvent(JID(jid_.getDomain()), message));
eventController_->handleIncomingEvent(lastDisconnectError_);
diff --git a/Swift/Controllers/PresenceNotifier.cpp b/Swift/Controllers/PresenceNotifier.cpp
index 3d5d71e..e7b25bf 100644
--- a/Swift/Controllers/PresenceNotifier.cpp
+++ b/Swift/Controllers/PresenceNotifier.cpp
@@ -15,6 +15,7 @@
#include "Swiften/Presence/PresenceOracle.h"
#include "Swiften/Network/TimerFactory.h"
#include "Swiften/Client/NickResolver.h"
+#include <Swift/Controllers/StatusUtil.h>
namespace Swift {
@@ -98,7 +99,7 @@ void PresenceNotifier::handleNotificationActivated(JID jid) {
std::string PresenceNotifier::getStatusType(const JID& jid) const {
Presence::ref presence = presenceOracle->getLastPresence(jid);
if (presence) {
- return StatusShow::typeToFriendlyName(presence->getShow());
+ return statusShowTypeToFriendlyName(presence->getShow());
}
else {
return "Unavailable";
diff --git a/Swift/Controllers/Roster/RosterController.cpp b/Swift/Controllers/Roster/RosterController.cpp
index e03a8d4..8a0fd53 100644
--- a/Swift/Controllers/Roster/RosterController.cpp
+++ b/Swift/Controllers/Roster/RosterController.cpp
@@ -37,6 +37,8 @@
#include "Swift/Controllers/UIEvents/RenameGroupUIEvent.h"
#include "Swift/Controllers/UIEvents/ToggleShowOfflineUIEvent.h"
#include <Swiften/Client/NickManager.h>
+#include <Swift/Controllers/Intl.h>
+#include <Swiften/Base/format.h>
namespace Swift {
@@ -121,7 +123,7 @@ void RosterController::handleOnJIDAdded(const JID& jid) {
}
}
else {
- roster_->addContact(jid, jid, name, "Contacts", avatarManager_->getAvatarPath(jid).string());
+ roster_->addContact(jid, jid, name, QT_TRANSLATE_NOOP("", "Contacts"), avatarManager_->getAvatarPath(jid).string());
}
applyAllPresenceTo(jid);
}
@@ -147,7 +149,7 @@ void RosterController::handleOnJIDUpdated(const JID& jid, const std::string& old
std::vector<std::string> groups = xmppRoster_->getGroupsForJID(jid);
std::vector<std::string> oldGroups = passedOldGroups;
std::string name = nickResolver_->jidToNick(jid);
- std::string contactsGroup = "Contacts";
+ std::string contactsGroup = QT_TRANSLATE_NOOP("", "Contacts");
if (oldGroups.empty()) {
oldGroups.push_back(contactsGroup);
}
@@ -208,7 +210,7 @@ void RosterController::handleUIEvent(boost::shared_ptr<UIEvent> event) {
std::vector<XMPPRosterItem> items = xmppRoster_->getItems();
std::string group = renameGroupEvent->getGroup();
// FIXME: We should handle contacts groups specially to avoid clashes
- if (group == "Contacts") {
+ if (group == QT_TRANSLATE_NOOP("", "Contacts")) {
group = "";
}
foreach(XMPPRosterItem& item, items) {
@@ -245,7 +247,7 @@ void RosterController::handleRosterSetError(ErrorPayload::ref error, boost::shar
if (!error) {
return;
}
- std::string text = "Server " + myJID_.getDomain() + " rejected roster change to item '" + rosterPayload->getItems()[0].getJID().toString() + "'";
+ std::string text = str(format(QT_TRANSLATE_NOOP("", "Server %1% rejected roster change to item '%2%'")) % myJID_.getDomain() % rosterPayload->getItems()[0].getJID().toString());
if (!error->getText().empty()) {
text += ": " + error->getText();
}
diff --git a/Swift/Controllers/SConscript b/Swift/Controllers/SConscript
index c563c7b..61da9fb 100644
--- a/Swift/Controllers/SConscript
+++ b/Swift/Controllers/SConscript
@@ -52,6 +52,8 @@ if env["SCONS_STAGE"] == "build" :
"CertificateStorageFactory.cpp",
"CertificateStorage.cpp",
"CertificateFileStorage.cpp",
+ "StatusUtil.cpp",
+ "Translator.cpp",
])
env.Append(UNITTEST_SOURCES = [
diff --git a/Swift/Controllers/StatusUtil.cpp b/Swift/Controllers/StatusUtil.cpp
new file mode 100644
index 0000000..fd1fea3
--- /dev/null
+++ b/Swift/Controllers/StatusUtil.cpp
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2011 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <Swift/Controllers/StatusUtil.h>
+
+#include <Swift/Controllers/Intl.h>
+
+namespace Swift {
+
+std::string statusShowTypeToFriendlyName(StatusShow::Type type) {
+ switch (type) {
+ case StatusShow::Online: return QT_TRANSLATE_NOOP("", "Available");
+ case StatusShow::FFC: return QT_TRANSLATE_NOOP("", "Available");
+ case StatusShow::Away: return QT_TRANSLATE_NOOP("", "Away");
+ case StatusShow::XA: return QT_TRANSLATE_NOOP("", "Away");
+ case StatusShow::DND: return QT_TRANSLATE_NOOP("", "Busy");
+ case StatusShow::None: return QT_TRANSLATE_NOOP("", "Offline");
+ }
+ return "";
+}
+
+}
diff --git a/Swift/Controllers/StatusUtil.h b/Swift/Controllers/StatusUtil.h
new file mode 100644
index 0000000..dddee92
--- /dev/null
+++ b/Swift/Controllers/StatusUtil.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2011 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <string>
+
+#include <Swiften/Elements/StatusShow.h>
+
+namespace Swift {
+ std::string statusShowTypeToFriendlyName(StatusShow::Type type);
+}
+
diff --git a/Swift/Controllers/Translator.cpp b/Swift/Controllers/Translator.cpp
new file mode 100644
index 0000000..82fc46e
--- /dev/null
+++ b/Swift/Controllers/Translator.cpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2011 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <Swift/Controllers/Translator.h>
+
+#include <cassert>
+
+namespace Swift {
+
+struct DefaultTranslator : public Translator {
+ virtual std::string translate(const std::string& text, const std::string&) {
+ return text;
+ }
+} defaultTranslator;
+
+Translator* Translator::translator = &defaultTranslator;
+
+Translator::~Translator() {
+}
+
+void Translator::setInstance(Translator* t) {
+ translator = t;
+}
+
+}
diff --git a/Swift/Controllers/Translator.h b/Swift/Controllers/Translator.h
new file mode 100644
index 0000000..ac4407d
--- /dev/null
+++ b/Swift/Controllers/Translator.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2011 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <string>
+
+namespace Swift {
+ class Translator {
+ public:
+ virtual ~Translator();
+
+ virtual std::string translate(const std::string& text, const std::string& context) = 0;
+
+ static void setInstance(Translator* translator);
+
+ static Translator* getInstance() {
+ return translator;
+ }
+
+ private:
+ static Translator* translator;
+ };
+}