diff options
53 files changed, 306 insertions, 106 deletions
diff --git a/SwifTools/Application/UnitTest/ApplicationPathProviderTest.cpp b/SwifTools/Application/UnitTest/ApplicationPathProviderTest.cpp index 5eb0e16..e7a47a7 100644 --- a/SwifTools/Application/UnitTest/ApplicationPathProviderTest.cpp +++ b/SwifTools/Application/UnitTest/ApplicationPathProviderTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ @@ -9,6 +9,7 @@ #include <string> #include <boost/algorithm/string.hpp> +#include <Swiften/Base/Path.h> #include <SwifTools/Application/PlatformApplicationPathProvider.h> using namespace Swift; @@ -40,7 +41,7 @@ class ApplicationPathProviderTest : public CppUnit::TestFixture { void testGetExecutableDir() { boost::filesystem::path dir = testling_->getExecutableDir(); CPPUNIT_ASSERT(boost::filesystem::is_directory(dir)); - CPPUNIT_ASSERT(boost::ends_with(dir.string(), "UnitTest")); + CPPUNIT_ASSERT(boost::ends_with(pathToString(dir), "UnitTest")); } private: diff --git a/SwifTools/Application/WindowsApplicationPathProvider.cpp b/SwifTools/Application/WindowsApplicationPathProvider.cpp index 730a57a..2c61208 100644 --- a/SwifTools/Application/WindowsApplicationPathProvider.cpp +++ b/SwifTools/Application/WindowsApplicationPathProvider.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ @@ -8,6 +8,7 @@ #include <windows.h> #include <cassert> +#include <Swiften/Base/String.h> namespace Swift { @@ -17,16 +18,17 @@ WindowsApplicationPathProvider::WindowsApplicationPathProvider(const std::string } boost::filesystem::path WindowsApplicationPathProvider::getDataDir() const { - char* appDirRaw = getenv("APPDATA"); + wchar_t* appDirRaw = _wgetenv(L"APPDATA"); assert(appDirRaw); - boost::filesystem::path result(boost::filesystem::path(appDirRaw) / getApplicationName()); + boost::filesystem::path result( + boost::filesystem::path(appDirRaw) / getApplicationName()); boost::filesystem::create_directory(result); return result; } boost::filesystem::path WindowsApplicationPathProvider::getHomeDir() const { //FIXME: This should be My Documents - char* homeDirRaw = getenv("USERPROFILE"); + wchar_t* homeDirRaw = _wgetenv(L"USERPROFILE"); assert(homeDirRaw); return boost::filesystem::path(homeDirRaw); } diff --git a/SwifTools/CrashReporter.cpp b/SwifTools/CrashReporter.cpp index 67377f2..f47ab33 100644 --- a/SwifTools/CrashReporter.cpp +++ b/SwifTools/CrashReporter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012 Remko Tronçon + * Copyright (c) 2012-2013 Remko Tronçon * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ @@ -7,6 +7,7 @@ #include <SwifTools/CrashReporter.h> #include <Swiften/Base/Platform.h> +#include <Swiften/Base/Path.h> #if defined(HAVE_BREAKPAD) @@ -51,7 +52,7 @@ CrashReporter::CrashReporter(const boost::filesystem::path& path) { p = boost::make_shared<Private>(); #if defined(SWIFTEN_PLATFORM_WINDOWS) // FIXME: Need UTF8 conversion from string to wstring - std::string pathString = path.string(); + std::string pathString = pathToString(path); p->handler = boost::shared_ptr<google_breakpad::ExceptionHandler>( // Not using make_shared, because 'handleDump' seems to have problems with VC2010 new google_breakpad::ExceptionHandler( @@ -62,7 +63,7 @@ CrashReporter::CrashReporter(const boost::filesystem::path& path) { google_breakpad::ExceptionHandler::HANDLER_ALL)); // Turning it off for Mac, because it doesn't really help us //#elif defined(SWIFTEN_PLATFORM_MACOSX) -// p->handler = boost::make_shared<google_breakpad::ExceptionHandler>(path.string(), (google_breakpad::ExceptionHandler::FilterCallback) 0, handleDump, (void*) 0, true, (const char*) 0); +// p->handler = boost::make_shared<google_breakpad::ExceptionHandler>(pathToString(path), (google_breakpad::ExceptionHandler::FilterCallback) 0, handleDump, (void*) 0, true, (const char*) 0); #endif } diff --git a/SwifTools/Notifier/GNTPNotifier.cpp b/SwifTools/Notifier/GNTPNotifier.cpp index 9bc05bd..757594f 100644 --- a/SwifTools/Notifier/GNTPNotifier.cpp +++ b/SwifTools/Notifier/GNTPNotifier.cpp @@ -14,6 +14,7 @@ #include <sstream> #include <Swiften/Base/foreach.h> +#include <Swiften/Base/Path.h> #include <Swiften/Network/ConnectionFactory.h> namespace Swift { @@ -23,7 +24,7 @@ GNTPNotifier::GNTPNotifier(const std::string& name, const boost::filesystem::pat std::ostringstream message; message << "GNTP/1.0 REGISTER NONE\r\n"; message << "Application-Name: " << name << "\r\n"; - message << "Application-Icon: file://" << icon.string() << "\r\n"; + message << "Application-Icon: file://" << pathToString(icon) << "\r\n"; message << "Notifications-Count: " << getAllTypes().size() << "\r\n"; std::vector<Notifier::Type> defaultTypes = getDefaultTypes(); std::vector<Notifier::Type> allTypes = getAllTypes(); @@ -59,7 +60,7 @@ void GNTPNotifier::showMessage(Type type, const std::string& subject, const std: message << "Notification-Name: " << typeToString(type) << "\r\n"; message << "Notification-Title: " << subject << "\r\n"; message << "Notification-Text: " << description << "\r\n"; - message << "Notification-Icon: " << picture.string() << "\r\n"; + message << "Notification-Icon: " << pathToString(picture) << "\r\n"; message << "\r\n"; send(message.str()); } diff --git a/SwifTools/Notifier/GrowlNotifier.mm b/SwifTools/Notifier/GrowlNotifier.mm index c1996d9..2ababf4 100644 --- a/SwifTools/Notifier/GrowlNotifier.mm +++ b/SwifTools/Notifier/GrowlNotifier.mm @@ -65,7 +65,7 @@ GrowlNotifier::~GrowlNotifier() { void GrowlNotifier::showMessage(Type type, const std::string& subject, const std::string& description, const boost::filesystem::path& picturePath, boost::function<void()> callback) { ByteArray picture; - readByteArrayFromFile(picture, picturePath.string()); + readByteArrayFromFile(picture, picturePath); Context* context = new Context(callback); // Growl sometimes sends timeout notifications twice for the same message. We therefore need diff --git a/Swift/Controllers/Chat/ChatController.cpp b/Swift/Controllers/Chat/ChatController.cpp index 1fb45a9..f5c690c 100644 --- a/Swift/Controllers/Chat/ChatController.cpp +++ b/Swift/Controllers/Chat/ChatController.cpp @@ -285,7 +285,7 @@ void ChatController::postSendMessage(const std::string& body, boost::shared_ptr< eraseIf(unackedStanzas_, PairSecondEquals<boost::shared_ptr<Stanza>, std::string>(myLastMessageUIID_)); replaceMessage(body, myLastMessageUIID_, boost::posix_time::microsec_clock::universal_time(), HighlightAction()); } else { - myLastMessageUIID_ = addMessage(body, QT_TRANSLATE_NOOP("", "me"), true, labelsEnabled_ ? chatWindow_->getSelectedSecurityLabel().getLabel() : boost::shared_ptr<SecurityLabel>(), std::string(avatarManager_->getAvatarPath(selfJID_).string()), boost::posix_time::microsec_clock::universal_time(), HighlightAction()); + myLastMessageUIID_ = addMessage(body, QT_TRANSLATE_NOOP("", "me"), true, labelsEnabled_ ? chatWindow_->getSelectedSecurityLabel().getLabel() : boost::shared_ptr<SecurityLabel>(), avatarManager_->getAvatarPath(selfJID_), boost::posix_time::microsec_clock::universal_time(), HighlightAction()); } if (stanzaChannel_->getStreamManagementEnabled() && !myLastMessageUIID_.empty() ) { diff --git a/Swift/Controllers/Chat/ChatControllerBase.cpp b/Swift/Controllers/Chat/ChatControllerBase.cpp index e469637..621fd2d 100644 --- a/Swift/Controllers/Chat/ChatControllerBase.cpp +++ b/Swift/Controllers/Chat/ChatControllerBase.cpp @@ -18,6 +18,7 @@ #include <Swift/Controllers/Intl.h> #include <Swiften/Base/format.h> +#include <Swiften/Base/Path.h> #include <Swiften/Base/String.h> #include <Swiften/Client/StanzaChannel.h> #include <Swiften/Elements/Delay.h> @@ -179,11 +180,11 @@ void ChatControllerBase::activateChatWindow() { chatWindow_->activate(); } -std::string ChatControllerBase::addMessage(const std::string& message, const std::string& senderName, bool senderIsSelf, const boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight) { +std::string ChatControllerBase::addMessage(const std::string& message, const std::string& senderName, bool senderIsSelf, const boost::shared_ptr<SecurityLabel> label, const boost::filesystem::path& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight) { if (boost::starts_with(message, "/me ")) { - return chatWindow_->addAction(String::getSplittedAtFirst(message, ' ').second, senderName, senderIsSelf, label, avatarPath, time, highlight); + return chatWindow_->addAction(String::getSplittedAtFirst(message, ' ').second, senderName, senderIsSelf, label, pathToString(avatarPath), time, highlight); } else { - return chatWindow_->addMessage(message, senderName, senderIsSelf, label, avatarPath, time, highlight); + return chatWindow_->addMessage(message, senderName, senderIsSelf, label, pathToString(avatarPath), time, highlight); } } @@ -266,7 +267,7 @@ void ChatControllerBase::handleIncomingMessage(boost::shared_ptr<MessageEvent> m } } else { - lastMessagesUIID_[from] = addMessage(body, senderDisplayNameFromMessage(from), isIncomingMessageFromMe(message), label, std::string(avatarManager_->getAvatarPath(from).string()), timeStamp, highlight); + lastMessagesUIID_[from] = addMessage(body, senderDisplayNameFromMessage(from), isIncomingMessageFromMe(message), label, avatarManager_->getAvatarPath(from), timeStamp, highlight); } logMessage(body, from, selfJID_, timeStamp, true); diff --git a/Swift/Controllers/Chat/ChatControllerBase.h b/Swift/Controllers/Chat/ChatControllerBase.h index 84bd06a..0199142 100644 --- a/Swift/Controllers/Chat/ChatControllerBase.h +++ b/Swift/Controllers/Chat/ChatControllerBase.h @@ -10,7 +10,7 @@ #include <vector> #include <boost/shared_ptr.hpp> #include "Swiften/Base/boost_bsignals.h" -#include <boost/filesystem.hpp> +#include <boost/filesystem/path.hpp> #include <boost/optional.hpp> #include <boost/date_time/posix_time/posix_time.hpp> @@ -50,7 +50,7 @@ namespace Swift { void activateChatWindow(); virtual void setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info); void handleIncomingMessage(boost::shared_ptr<MessageEvent> message); - std::string addMessage(const std::string& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight); + std::string addMessage(const std::string& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const boost::filesystem::path& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight); void replaceMessage(const std::string& message, const std::string& id, const boost::posix_time::ptime& time, const HighlightAction& highlight); virtual void setOnline(bool online); virtual void setEnabled(bool enabled); diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp index b964bad..6bf3e5f 100644 --- a/Swift/Controllers/Chat/MUCController.cpp +++ b/Swift/Controllers/Chat/MUCController.cpp @@ -312,8 +312,7 @@ void MUCController::handleAvatarChanged(const JID& jid) { if (parting_ || !jid.equals(toJID_, JID::WithoutResource)) { return; } - std::string path = avatarManager_->getAvatarPath(jid).string(); - roster_->applyOnItems(SetAvatar(jid, path, JID::WithResource)); + roster_->applyOnItems(SetAvatar(jid, avatarManager_->getAvatarPath(jid), JID::WithResource)); } void MUCController::handleWindowClosed() { @@ -337,7 +336,7 @@ void MUCController::handleOccupantJoined(const MUCOccupant& occupant) { NickJoinPart event(occupant.getNick(), Join); appendToJoinParts(joinParts_, event); std::string groupName(roleToGroupName(occupant.getRole())); - roster_->addContact(jid, realJID, occupant.getNick(), groupName, avatarManager_->getAvatarPath(jid).string()); + roster_->addContact(jid, realJID, occupant.getNick(), groupName, avatarManager_->getAvatarPath(jid)); roster_->getGroup(groupName)->setManualSort(roleToSortName(occupant.getRole())); if (joined_) { std::string joinString; @@ -483,7 +482,7 @@ void MUCController::handleOccupantRoleChanged(const std::string& nick, const MUC realJID = occupant.getRealJID().get(); } std::string group(roleToGroupName(occupant.getRole())); - roster_->addContact(jid, realJID, nick, group, avatarManager_->getAvatarPath(jid).string()); + roster_->addContact(jid, realJID, nick, group, avatarManager_->getAvatarPath(jid)); roster_->getGroup(group)->setManualSort(roleToSortName(occupant.getRole())); chatWindow_->addSystemMessage(str(format(QT_TRANSLATE_NOOP("", "%1% is now a %2%")) % nick % roleToFriendlyName(occupant.getRole())), ChatWindow::DefaultDirection); if (nick == nick_) { @@ -830,7 +829,7 @@ void MUCController::addRecentLogs() { bool senderIsSelf = nick_ == message.getFromJID().getResource(); // the chatWindow uses utc timestamps - addMessage(message.getMessage(), senderDisplayNameFromMessage(message.getFromJID()), senderIsSelf, boost::shared_ptr<SecurityLabel>(new SecurityLabel()), std::string(avatarManager_->getAvatarPath(message.getFromJID()).string()), message.getTime() - boost::posix_time::hours(message.getOffset()), HighlightAction()); + addMessage(message.getMessage(), senderDisplayNameFromMessage(message.getFromJID()), senderIsSelf, boost::shared_ptr<SecurityLabel>(new SecurityLabel()), avatarManager_->getAvatarPath(message.getFromJID()), message.getTime() - boost::posix_time::hours(message.getOffset()), HighlightAction()); } } diff --git a/Swift/Controllers/HistoryViewController.cpp b/Swift/Controllers/HistoryViewController.cpp index 9343017..cfa2482 100644 --- a/Swift/Controllers/HistoryViewController.cpp +++ b/Swift/Controllers/HistoryViewController.cpp @@ -4,6 +4,12 @@ * See Documentation/Licenses/BSD-simplified.txt for more information. */ +/* + * Copyright (c) 2013 Remko Tronçon + * Licensed under the GNU General Public License. + * See the COPYING file for more information. + */ + #include <Swift/Controllers/HistoryViewController.h> #include <Swift/Controllers/UIInterfaces/HistoryWindowFactory.h> @@ -15,6 +21,7 @@ #include <Swiften/Avatars/AvatarManager.h> #include <Swift/Controllers/Roster/SetPresence.h> #include <Swift/Controllers/Roster/SetAvatar.h> +#include <Swiften/Base/Path.h> namespace Swift { static const std::string category[] = { "Contacts", "MUC", "Contacts" }; @@ -146,7 +153,7 @@ void HistoryViewController::handleNewMessage(const HistoryMessage& message) { // update contacts if (!contacts_[message.getType()].count(displayJID)) { - roster_->addContact(displayJID, displayJID, nickResolver_->jidToNick(displayJID), category[message.getType()], avatarManager_->getAvatarPath(displayJID).string()); + roster_->addContact(displayJID, displayJID, nickResolver_->jidToNick(displayJID), category[message.getType()], avatarManager_->getAvatarPath(displayJID)); } contacts_[message.getType()][displayJID].insert(message.getTime().date()); @@ -154,7 +161,7 @@ void HistoryViewController::handleNewMessage(const HistoryMessage& message) { void HistoryViewController::addNewMessage(const HistoryMessage& message, bool addAtTheTop) { bool senderIsSelf = message.getFromJID().toBare() == selfJID_; - std::string avatarPath = avatarManager_->getAvatarPath(message.getFromJID()).string(); + std::string avatarPath = pathToString(avatarManager_->getAvatarPath(message.getFromJID())); std::string nick = message.getType() != HistoryMessage::Groupchat ? nickResolver_->jidToNick(message.getFromJID()) : message.getFromJID().getResource(); historyWindow_->addMessage(message.getMessage(), nick, senderIsSelf, avatarPath, message.getTime(), addAtTheTop); @@ -177,7 +184,7 @@ void HistoryViewController::handleReturnPressed(const std::string& keyword) { else { nick = nickResolver_->jidToNick(jid); } - roster_->addContact(jid, jid, nick, category[type], avatarManager_->getAvatarPath(jid).string()); + roster_->addContact(jid, jid, nick, category[type], avatarManager_->getAvatarPath(jid)); Presence::ref presence = getPresence(jid, type == HistoryMessage::Groupchat); @@ -323,8 +330,7 @@ void HistoryViewController::handlePresenceChanged(Presence::ref presence) { } void HistoryViewController::handleAvatarChanged(const JID& jid) { - std::string path = avatarManager_->getAvatarPath(jid).string(); - roster_->applyOnItems(SetAvatar(jid, path)); + roster_->applyOnItems(SetAvatar(jid, avatarManager_->getAvatarPath(jid))); } Presence::ref HistoryViewController::getPresence(const JID& jid, bool isMUC) { diff --git a/Swift/Controllers/Roster/ContactRosterItem.cpp b/Swift/Controllers/Roster/ContactRosterItem.cpp index bf85167..70b4a1b 100644 --- a/Swift/Controllers/Roster/ContactRosterItem.cpp +++ b/Swift/Controllers/Roster/ContactRosterItem.cpp @@ -52,11 +52,11 @@ std::string ContactRosterItem::getIdleText() const { } } -void ContactRosterItem::setAvatarPath(const std::string& path) { +void ContactRosterItem::setAvatarPath(const boost::filesystem::path& path) { avatarPath_ = path; onDataChanged(); } -const std::string& ContactRosterItem::getAvatarPath() const { +const boost::filesystem::path& ContactRosterItem::getAvatarPath() const { return avatarPath_; } diff --git a/Swift/Controllers/Roster/ContactRosterItem.h b/Swift/Controllers/Roster/ContactRosterItem.h index fc65d6d..67a9722 100644 --- a/Swift/Controllers/Roster/ContactRosterItem.h +++ b/Swift/Controllers/Roster/ContactRosterItem.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Kevin Smith + * Copyright (c) 2010-2013 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ @@ -18,6 +18,7 @@ #include "Swiften/Base/boost_bsignals.h" #include <boost/shared_ptr.hpp> #include <boost/date_time/posix_time/ptime.hpp> +#include <boost/filesystem/path.hpp> namespace Swift { @@ -43,8 +44,8 @@ class ContactRosterItem : public RosterItem { StatusShow::Type getSimplifiedStatusShow() const; std::string getStatusText() const; std::string getIdleText() const; - void setAvatarPath(const std::string& path); - const std::string& getAvatarPath() const; + void setAvatarPath(const boost::filesystem::path& path); + const boost::filesystem::path& getAvatarPath() const; const JID& getJID() const; void setDisplayJID(const JID& jid); const JID& getDisplayJID() const; @@ -66,7 +67,7 @@ class ContactRosterItem : public RosterItem { JID jid_; JID displayJID_; boost::posix_time::ptime lastAvailableTime_; - std::string avatarPath_; + boost::filesystem::path avatarPath_; std::map<std::string, boost::shared_ptr<Presence> > presences_; boost::shared_ptr<Presence> offlinePresence_; boost::shared_ptr<Presence> shownPresence_; diff --git a/Swift/Controllers/Roster/Roster.cpp b/Swift/Controllers/Roster/Roster.cpp index 3d0ca2e..9b45b63 100644 --- a/Swift/Controllers/Roster/Roster.cpp +++ b/Swift/Controllers/Roster/Roster.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ @@ -105,7 +105,7 @@ void Roster::handleChildrenChanged(GroupRosterItem* item) { onChildrenChanged(item); } -void Roster::addContact(const JID& jid, const JID& displayJID, const std::string& name, const std::string& groupName, const std::string& avatarPath) { +void Roster::addContact(const JID& jid, const JID& displayJID, const std::string& name, const std::string& groupName, const boost::filesystem::path& avatarPath) { GroupRosterItem* group(getGroup(groupName)); ContactRosterItem *item = new ContactRosterItem(jid, displayJID, name, group); item->setAvatarPath(avatarPath); diff --git a/Swift/Controllers/Roster/Roster.h b/Swift/Controllers/Roster/Roster.h index 91a152f..a4c8b99 100644 --- a/Swift/Controllers/Roster/Roster.h +++ b/Swift/Controllers/Roster/Roster.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ @@ -28,7 +28,7 @@ class Roster { Roster(bool sortByStatus = true, bool fullJIDMapping = false); ~Roster(); - void addContact(const JID& jid, const JID& displayJID, const std::string& name, const std::string& group, const std::string& avatarPath); + void addContact(const JID& jid, const JID& displayJID, const std::string& name, const std::string& group, const boost::filesystem::path& avatarPath); void removeContact(const JID& jid); void removeContactFromGroup(const JID& jid, const std::string& group); void removeGroup(const std::string& group); diff --git a/Swift/Controllers/Roster/RosterController.cpp b/Swift/Controllers/Roster/RosterController.cpp index d09ef4c..d277799 100644 --- a/Swift/Controllers/Roster/RosterController.cpp +++ b/Swift/Controllers/Roster/RosterController.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2012 Kevin Smith + * Copyright (c) 2010-2013 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ @@ -40,6 +40,7 @@ #include <Swiften/Client/NickManager.h> #include <Swift/Controllers/Intl.h> #include <Swiften/Base/format.h> +#include <Swiften/Base/Path.h> #include <Swiften/Elements/DiscoInfo.h> #include <Swiften/Disco/EntityCapsManager.h> #include <Swiften/Jingle/JingleSessionManager.h> @@ -73,7 +74,7 @@ RosterController::RosterController(const JID& jid, XMPPRoster* xmppRoster, Avata uiEventConnection_ = uiEventStream->onUIEvent.connect(boost::bind(&RosterController::handleUIEvent, this, _1)); avatarManager_ = avatarManager; avatarManager_->onAvatarChanged.connect(boost::bind(&RosterController::handleAvatarChanged, this, _1)); - mainWindow_->setMyAvatarPath(avatarManager_->getAvatarPath(myJID_).string()); + mainWindow_->setMyAvatarPath(pathToString(avatarManager_->getAvatarPath(myJID_))); nickManager_->onOwnNickChanged.connect(boost::bind(&MainWindow::setMyNick, mainWindow_, _1)); mainWindow_->setMyJID(jid); @@ -125,11 +126,11 @@ void RosterController::handleOnJIDAdded(const JID& jid) { std::string name = nickResolver_->jidToNick(jid); if (!groups.empty()) { foreach(const std::string& group, groups) { - roster_->addContact(jid, jid, name, group, avatarManager_->getAvatarPath(jid).string()); + roster_->addContact(jid, jid, name, group, avatarManager_->getAvatarPath(jid)); } } else { - roster_->addContact(jid, jid, name, QT_TRANSLATE_NOOP("", "Contacts"), avatarManager_->getAvatarPath(jid).string()); + roster_->addContact(jid, jid, name, QT_TRANSLATE_NOOP("", "Contacts"), avatarManager_->getAvatarPath(jid)); } applyAllPresenceTo(jid); } @@ -164,7 +165,7 @@ void RosterController::handleOnJIDUpdated(const JID& jid, const std::string& old } foreach(const std::string& group, groups) { if (std::find(oldGroups.begin(), oldGroups.end(), group) == oldGroups.end()) { - roster_->addContact(jid, jid, name, group, avatarManager_->getAvatarPath(jid).string()); + roster_->addContact(jid, jid, name, group, avatarManager_->getAvatarPath(jid)); } } foreach(const std::string& group, oldGroups) { @@ -326,10 +327,10 @@ void RosterController::handleSubscriptionRequestDeclined(SubscriptionRequestEven } void RosterController::handleAvatarChanged(const JID& jid) { - std::string path = avatarManager_->getAvatarPath(jid).string(); + boost::filesystem::path path = avatarManager_->getAvatarPath(jid); roster_->applyOnItems(SetAvatar(jid, path)); if (jid.equals(myJID_, JID::WithoutResource)) { - mainWindow_->setMyAvatarPath(path); + mainWindow_->setMyAvatarPath(pathToString(path)); } } diff --git a/Swift/Controllers/Roster/SetAvatar.h b/Swift/Controllers/Roster/SetAvatar.h index 241b741..424f0b3 100644 --- a/Swift/Controllers/Roster/SetAvatar.h +++ b/Swift/Controllers/Roster/SetAvatar.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ @@ -10,6 +10,7 @@ #include "Swiften/JID/JID.h" #include "Swift/Controllers/Roster/RosterItemOperation.h" #include "Swift/Controllers/Roster/ContactRosterItem.h" +#include <boost/filesystem/path.hpp> namespace Swift { @@ -17,7 +18,7 @@ class RosterItem; class SetAvatar : public RosterItemOperation { public: - SetAvatar(const JID& jid, const std::string& path, JID::CompareType compareType = JID::WithoutResource) : RosterItemOperation(true, jid), jid_(jid), path_(path), compareType_(compareType) { + SetAvatar(const JID& jid, const boost::filesystem::path& path, JID::CompareType compareType = JID::WithoutResource) : RosterItemOperation(true, jid), jid_(jid), path_(path), compareType_(compareType) { } virtual void operator() (RosterItem* item) const { @@ -29,7 +30,7 @@ class SetAvatar : public RosterItemOperation { private: JID jid_; - std::string path_; + boost::filesystem::path path_; JID::CompareType compareType_; }; diff --git a/Swift/Controllers/Roster/TableRoster.h b/Swift/Controllers/Roster/TableRoster.h index d4612ed..f447760 100644 --- a/Swift/Controllers/Roster/TableRoster.h +++ b/Swift/Controllers/Roster/TableRoster.h @@ -12,6 +12,7 @@ #include <Swiften/JID/JID.h> #include <Swiften/Elements/StatusShow.h> +#include <boost/filesystem/path.hpp> namespace Swift { class Roster; @@ -21,13 +22,13 @@ namespace Swift { class TableRoster { public: struct Item { - Item(const std::string& name, const std::string& description, const JID& jid, StatusShow::Type status, const std::string& avatarPath) : name(name), description(description), jid(jid), status(status), avatarPath(avatarPath) { + Item(const std::string& name, const std::string& description, const JID& jid, StatusShow::Type status, const boost::filesystem::path& avatarPath) : name(name), description(description), jid(jid), status(status), avatarPath(avatarPath) { } std::string name; std::string description; JID jid; StatusShow::Type status; - std::string avatarPath; + boost::filesystem::path avatarPath; }; struct Index { diff --git a/Swift/Controllers/StatusCache.cpp b/Swift/Controllers/StatusCache.cpp index 1569e26..3444189 100644 --- a/Swift/Controllers/StatusCache.cpp +++ b/Swift/Controllers/StatusCache.cpp @@ -61,7 +61,7 @@ void StatusCache::loadRecents() { try { if (boost::filesystem::exists(path_)) { ByteArray data; - readByteArrayFromFile(data, path_.string()); + readByteArrayFromFile(data, path_); std::string stringData = byteArrayToString(data); std::vector<std::string> lines; boost::split(lines, stringData, boost::is_any_of("\n")); diff --git a/Swift/Controllers/Storages/AvatarFileStorage.cpp b/Swift/Controllers/Storages/AvatarFileStorage.cpp index 792b77b..671e0cb 100644 --- a/Swift/Controllers/Storages/AvatarFileStorage.cpp +++ b/Swift/Controllers/Storages/AvatarFileStorage.cpp @@ -69,7 +69,7 @@ boost::filesystem::path AvatarFileStorage::getAvatarPath(const std::string& hash ByteArray AvatarFileStorage::getAvatar(const std::string& hash) const { ByteArray data; - readByteArrayFromFile(data, getAvatarPath(hash).string()); + readByteArrayFromFile(data, getAvatarPath(hash)); return data; } diff --git a/Swift/Controllers/Storages/CertificateFileStorage.cpp b/Swift/Controllers/Storages/CertificateFileStorage.cpp index b5e85d2..34d1f76 100644 --- a/Swift/Controllers/Storages/CertificateFileStorage.cpp +++ b/Swift/Controllers/Storages/CertificateFileStorage.cpp @@ -24,7 +24,7 @@ bool CertificateFileStorage::hasCertificate(Certificate::ref certificate) const boost::filesystem::path certificatePath = getCertificatePath(certificate); if (boost::filesystem::exists(certificatePath)) { ByteArray data; - readByteArrayFromFile(data, certificatePath.string()); + readByteArrayFromFile(data, certificatePath); Certificate::ref storedCertificate = certificateFactory->createCertificateFromDER(data); if (storedCertificate && storedCertificate->toDER() == certificate->toDER()) { return true; diff --git a/Swift/Controllers/Storages/FileStorages.cpp b/Swift/Controllers/Storages/FileStorages.cpp index 357c213..52a5e00 100644 --- a/Swift/Controllers/Storages/FileStorages.cpp +++ b/Swift/Controllers/Storages/FileStorages.cpp @@ -10,17 +10,18 @@ #include "Swift/Controllers/Storages/CapsFileStorage.h" #include "Swift/Controllers/Storages/RosterFileStorage.h" #include <Swiften/History/SQLiteHistoryStorage.h> +#include <Swiften/Base/Path.h> namespace Swift { FileStorages::FileStorages(const boost::filesystem::path& baseDir, const JID& jid, CryptoProvider* crypto) { - std::string profile = jid.toBare(); + boost::filesystem::path profile = stringToPath(jid.toBare()); vcardStorage = new VCardFileStorage(baseDir / profile / "vcards", crypto); capsStorage = new CapsFileStorage(baseDir / "caps"); avatarStorage = new AvatarFileStorage(baseDir / "avatars", baseDir / profile / "avatars", crypto); rosterStorage = new RosterFileStorage(baseDir / profile / "roster.xml"); #ifdef SWIFT_EXPERIMENTAL_HISTORY - historyStorage = new SQLiteHistoryStorage((baseDir / "history.db").string()); + historyStorage = new SQLiteHistoryStorage(baseDir / "history.db"); #endif } diff --git a/Swift/Controllers/Storages/VCardFileStorage.cpp b/Swift/Controllers/Storages/VCardFileStorage.cpp index 633ed58..b22e235 100644 --- a/Swift/Controllers/Storages/VCardFileStorage.cpp +++ b/Swift/Controllers/Storages/VCardFileStorage.cpp @@ -14,6 +14,7 @@ #include <Swiften/Base/String.h> #include <Swiften/StringCodecs/Hexify.h> #include <Swiften/Base/foreach.h> +#include <Swiften/Base/Path.h> #include <Swiften/Crypto/CryptoProvider.h> #include "Swiften/JID/JID.h" #include "Swiften/Elements/VCard.h" @@ -66,7 +67,7 @@ boost::filesystem::path VCardFileStorage::getVCardPath(const JID& jid) const { try { std::string file(jid.toString()); String::replaceAll(file, '/', "%2f"); - return boost::filesystem::path(vcardsPath / (file + ".xml")); + return boost::filesystem::path(vcardsPath / stringToPath(file + ".xml")); } catch (const boost::filesystem::filesystem_error& e) { std::cerr << "ERROR: " << e.what() << std::endl; diff --git a/Swift/QtUI/ChatList/ChatListRecentItem.cpp b/Swift/QtUI/ChatList/ChatListRecentItem.cpp index 6c9807f..5a4d1e1 100644 --- a/Swift/QtUI/ChatList/ChatListRecentItem.cpp +++ b/Swift/QtUI/ChatList/ChatListRecentItem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 Kevin Smith + * Copyright (c) 2011-2013 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ @@ -7,6 +7,7 @@ #include <Swift/QtUI/ChatList/ChatListRecentItem.h> #include <Swift/QtUI/QtSwiftUtil.h> +#include <Swiften/Base/Path.h> namespace Swift { ChatListRecentItem::ChatListRecentItem(const ChatListWindow::Chat& chat, ChatListGroupItem* parent) : ChatListItem(parent), chat_(chat) { @@ -25,7 +26,7 @@ QVariant ChatListRecentItem::data(int role) const { case Qt::BackgroundColorRole: return backgroundColor_; case Qt::ToolTipRole: return isContact() ? toolTipString() : QVariant(); case StatusTextRole: return statusText_;*/ - case AvatarRole: return QVariant(QString(chat_.avatarPath.string().c_str())); + case AvatarRole: return QVariant(P2QSTRING(pathToString(chat_.avatarPath))); case PresenceIconRole: return getPresenceIcon(); default: return QVariant(); } diff --git a/Swift/QtUI/ChatList/ChatListWhiteboardItem.cpp b/Swift/QtUI/ChatList/ChatListWhiteboardItem.cpp index 41648b6..6791aa5 100644 --- a/Swift/QtUI/ChatList/ChatListWhiteboardItem.cpp +++ b/Swift/QtUI/ChatList/ChatListWhiteboardItem.cpp @@ -4,9 +4,16 @@ * See Documentation/Licenses/BSD-simplified.txt for more information. */ +/* + * Copyright (c) 2013 Remko Tronçon + * Licensed under the GNU General Public License. + * See the COPYING file for more information. + */ + #include <Swift/QtUI/ChatList/ChatListWhiteboardItem.h> #include <Swift/QtUI/QtSwiftUtil.h> +#include <Swiften/Base/Path.h> namespace Swift { ChatListWhiteboardItem::ChatListWhiteboardItem(const ChatListWindow::Chat& chat, ChatListGroupItem* parent) : ChatListItem(parent), chat_(chat) { @@ -25,7 +32,7 @@ namespace Swift { case Qt::BackgroundColorRole: return backgroundColor_; case Qt::ToolTipRole: return isContact() ? toolTipString() : QVariant(); case StatusTextRole: return statusText_;*/ - case AvatarRole: return QVariant(QString(chat_.avatarPath.string().c_str())); + case AvatarRole: return QVariant(P2QSTRING(pathToString(chat_.avatarPath))); case PresenceIconRole: return getPresenceIcon(); default: return QVariant(); } diff --git a/Swift/QtUI/FreeDesktopNotifier.cpp b/Swift/QtUI/FreeDesktopNotifier.cpp index 2393340..a51e482 100644 --- a/Swift/QtUI/FreeDesktopNotifier.cpp +++ b/Swift/QtUI/FreeDesktopNotifier.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ @@ -13,6 +13,7 @@ #include <QStringList> #include <QtDBus/QtDBus> #include <algorithm> +#include <Swiften/Base/Path.h> namespace Swift { @@ -43,7 +44,7 @@ void FreeDesktopNotifier::showMessage(Type type, const std::string& subject, con hints["x-canonical-append"] = QString("allowed"); msg << applicationName.c_str(); msg << quint32(0); // ID of previous notification to replace - msg << imageScaler.getScaledImage(picture, 48).string().c_str(); // Icon to display + msg << pathToString(imageScaler.getScaledImage(picture, 48)); // Icon to display msg << subject.c_str(); // Summary / Header of the message to display msg << body; // Body of the message to display msg << actions; // Actions from which the user may choose diff --git a/Swift/QtUI/QtCachedImageScaler.cpp b/Swift/QtUI/QtCachedImageScaler.cpp index 7307577..9b1709b 100644 --- a/Swift/QtUI/QtCachedImageScaler.cpp +++ b/Swift/QtUI/QtCachedImageScaler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ @@ -8,6 +8,8 @@ #include <QImage> #include <boost/lexical_cast.hpp> +#include <Swiften/Base/Path.h> +#include <Swift/QtUI/QtSwiftUtil.h> namespace Swift { @@ -15,16 +17,17 @@ QtCachedImageScaler::QtCachedImageScaler() { } boost::filesystem::path QtCachedImageScaler::getScaledImage(const boost::filesystem::path& imagePath, int size) { - boost::filesystem::path scaledImagePath(imagePath.string() + "." + boost::lexical_cast<std::string>(size)); + boost::filesystem::path scaledImagePath(imagePath); + scaledImagePath += "." + boost::lexical_cast<std::string>(size); if (!boost::filesystem::exists(scaledImagePath)) { - QImage image(imagePath.string().c_str()); + QImage image(P2QSTRING(pathToString(imagePath))); if (!image.isNull()) { if (image.width() > size || image.height() > size) { QImage scaledImage = image.scaled(size, size, Qt::KeepAspectRatio, Qt::SmoothTransformation); - scaledImage.save(QString::fromUtf8(scaledImagePath.string().c_str()), "PNG"); + scaledImage.save(P2QSTRING(pathToString(scaledImagePath)), "PNG"); } else { - image.save(QString::fromUtf8(scaledImagePath.string().c_str()), "PNG"); + image.save(P2QSTRING(pathToString(scaledImagePath)), "PNG"); } } else { diff --git a/Swift/QtUI/QtSoundPlayer.cpp b/Swift/QtUI/QtSoundPlayer.cpp index 63f76f0..3f3782d 100644 --- a/Swift/QtUI/QtSoundPlayer.cpp +++ b/Swift/QtUI/QtSoundPlayer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Kevin Smith + * Copyright (c) 2010-2013 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ @@ -9,7 +9,9 @@ #include <QSound> #include <iostream> -#include "SwifTools/Application/ApplicationPathProvider.h" +#include <SwifTools/Application/ApplicationPathProvider.h> +#include <QtSwiftUtil.h> +#include <Swiften/Base/Path.h> namespace Swift { @@ -28,10 +30,10 @@ void QtSoundPlayer::playSound(SoundEffect sound, const std::string& soundResourc void QtSoundPlayer::playSound(const std::string& soundResource) { boost::filesystem::path resourcePath = applicationPathProvider->getResourcePath(soundResource); if (boost::filesystem::exists(resourcePath)) { - QSound::play(resourcePath.string().c_str()); + QSound::play(P2QSTRING(pathToString(resourcePath))); } else if (boost::filesystem::exists(soundResource)) { - QSound::play(soundResource.c_str()); + QSound::play(P2QSTRING(soundResource)); } else { std::cerr << "Unable to find sound: " << soundResource << std::endl; diff --git a/Swift/QtUI/QtSwift.cpp b/Swift/QtUI/QtSwift.cpp index 839d079..b563c53 100644 --- a/Swift/QtUI/QtSwift.cpp +++ b/Swift/QtUI/QtSwift.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2012 Kevin Smith + * Copyright (c) 2010-2013 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ @@ -23,6 +23,7 @@ #include <QtChatWindowFactory.h> #include <QtSingleWindow.h> #include <Swiften/Base/Log.h> +#include <Swiften/Base/Path.h> #include <Swift/Controllers/Storages/CertificateFileStorageFactory.h> #include <Swift/Controllers/Storages/FileStoragesFactory.h> #include <SwifTools/Application/PlatformApplicationPathProvider.h> @@ -129,14 +130,14 @@ QtSwift::QtSwift(const po::variables_map& options) : networkFactories_(&clientMa QCoreApplication::setApplicationVersion(buildVersion); qtSettings_ = new QtSettingsProvider(); - xmlSettings_ = loadSettingsFile(P2QSTRING((Paths::getExecutablePath() / "system-settings.xml").string())); + xmlSettings_ = loadSettingsFile(P2QSTRING(pathToString(Paths::getExecutablePath() / "system-settings.xml"))); settingsHierachy_ = new SettingsProviderHierachy(); settingsHierachy_->addProviderToTopOfStack(xmlSettings_); settingsHierachy_->addProviderToTopOfStack(qtSettings_); QMap<QString, QString> emoticons; loadEmoticonsFile(":/emoticons/emoticons.txt", emoticons); - loadEmoticonsFile(P2QSTRING((Paths::getExecutablePath() / "emoticons.txt").string()), emoticons); + loadEmoticonsFile(P2QSTRING(pathToString(Paths::getExecutablePath() / "emoticons.txt")), emoticons); if (options.count("netbook-mode")) { splitter_ = new QtSingleWindow(qtSettings_); diff --git a/Swift/QtUI/Roster/RosterModel.cpp b/Swift/QtUI/Roster/RosterModel.cpp index 8f39f35..1b93047 100644 --- a/Swift/QtUI/Roster/RosterModel.cpp +++ b/Swift/QtUI/Roster/RosterModel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Kevin Smith + * Copyright (c) 2010-2013 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ @@ -16,6 +16,7 @@ #include "Swift/Controllers/Roster/ContactRosterItem.h" #include "Swift/Controllers/Roster/GroupRosterItem.h" #include <Swift/Controllers/StatusUtil.h> +#include <Swiften/Base/Path.h> #include "QtSwiftUtil.h" #include "Swift/QtUI/Roster/QtTreeWidget.h" @@ -150,7 +151,7 @@ QString RosterModel::getAvatar(RosterItem* item) const { if (!contact) { return ""; } - return QString(contact->getAvatarPath().c_str()); + return P2QSTRING(pathToString(contact->getAvatarPath())); } QString RosterModel::getStatusText(RosterItem* item) const { diff --git a/Swift/QtUI/main.cpp b/Swift/QtUI/main.cpp index 70947f5..d734713 100644 --- a/Swift/QtUI/main.cpp +++ b/Swift/QtUI/main.cpp @@ -21,6 +21,7 @@ #include <SwifTools/Application/PlatformApplicationPathProvider.h> #include <SwifTools/CrashReporter.h> #include <stdlib.h> +#include <Swiften/Base/Path.h> #include "QtSwift.h" #include "QtTranslator.h" @@ -73,14 +74,14 @@ int main(int argc, char* argv[]) { if (!someTranslationPath.empty()) { #if QT_VERSION >= 0x040800 if (vm.count("language") > 0) { - qtTranslator.load(QString(SWIFT_APPLICATION_NAME).toLower() + "_" + P2QSTRING(vm["language"].as<std::string>()), someTranslationPath.parent_path().string().c_str()); + qtTranslator.load(QString(SWIFT_APPLICATION_NAME).toLower() + "_" + P2QSTRING(vm["language"].as<std::string>()), P2QSTRING(Swift::pathToString(someTranslationPath.parent_path()))); } else { - qtTranslator.load(QLocale::system(), QString(SWIFT_APPLICATION_NAME).toLower(), "_", someTranslationPath.parent_path().string().c_str()); + qtTranslator.load(QLocale::system(), QString(SWIFT_APPLICATION_NAME).toLower(), "_", P2QSTRING(Swift::pathToString(someTranslationPath))); } #else //std::cout << "Loading " << std::string(QLocale::system().name().toUtf8()) << std::endl; - qtTranslator.load(QString(SWIFT_APPLICATION_NAME).toLower() + "_" + QLocale::system().name(), someTranslationPath.parent_path().string().c_str()); + qtTranslator.load(QString(SWIFT_APPLICATION_NAME).toLower() + "_" + QLocale::system().name(), P2QSTRING(Swift::pathToString(someTranslationPath))); #endif } app.installTranslator(&qtTranslator); diff --git a/Swiften/Base/ByteArray.cpp b/Swiften/Base/ByteArray.cpp index d6b5c97..466db5f 100644 --- a/Swiften/Base/ByteArray.cpp +++ b/Swiften/Base/ByteArray.cpp @@ -7,14 +7,14 @@ #include <Swiften/Base/ByteArray.h> #include <boost/numeric/conversion/cast.hpp> -#include <fstream> +#include <boost/filesystem/fstream.hpp> namespace Swift { static const int BUFFER_SIZE = 4096; -void readByteArrayFromFile(ByteArray& data, const std::string& file) { - std::ifstream input(file.c_str(), std::ios_base::in|std::ios_base::binary); +void readByteArrayFromFile(ByteArray& data, const boost::filesystem::path& file) { + boost::filesystem::ifstream input(file, std::ios_base::in|std::ios_base::binary); while (input.good()) { size_t oldSize = data.size(); data.resize(oldSize + BUFFER_SIZE); diff --git a/Swiften/Base/ByteArray.h b/Swiften/Base/ByteArray.h index 8688aab..133b75f 100644 --- a/Swiften/Base/ByteArray.h +++ b/Swiften/Base/ByteArray.h @@ -10,6 +10,7 @@ #include <string> #include <Swiften/Base/API.h> +#include <boost/filesystem/path.hpp> namespace Swift { typedef std::vector<unsigned char> ByteArray; @@ -41,6 +42,6 @@ namespace Swift { SWIFTEN_API std::string byteArrayToString(const ByteArray& b); - SWIFTEN_API void readByteArrayFromFile(ByteArray&, const std::string& file); + SWIFTEN_API void readByteArrayFromFile(ByteArray&, const boost::filesystem::path& file); } diff --git a/Swiften/Base/Path.cpp b/Swiften/Base/Path.cpp new file mode 100644 index 0000000..2a49676 --- /dev/null +++ b/Swiften/Base/Path.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2013 Remko Tronçon + * Licensed under the GNU General Public License. + * See the COPYING file for more information. + */ + +#include <Swiften/Base/Path.h> + +#include <Swiften/Base/Platform.h> +#include <Swiften/Base/String.h> + +using namespace Swift; + +boost::filesystem::path Swift::stringToPath(const std::string& path) { +#ifdef SWIFTEN_PLATFORM_WINDOWS + return boost::filesystem::path(convertStringToWString(path)); +#else + return boost::filesystem::path(path); +#endif +} + +std::string Swift::pathToString(const boost::filesystem::path& path) { +#ifdef SWIFTEN_PLATFORM_WINDOWS + return convertWStringToString(path.native()); +#else + return path.native(); +#endif +} diff --git a/Swiften/Base/Path.h b/Swiften/Base/Path.h new file mode 100644 index 0000000..ea99be9 --- /dev/null +++ b/Swiften/Base/Path.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2013 Remko Tronçon + * Licensed under the GNU General Public License. + * See the COPYING file for more information. + */ + +#pragma once + +#include <Swiften/Base/API.h> +#include <boost/filesystem/path.hpp> +#include <string> + +namespace Swift { + /** + * Creates a path for the given UTF-8 encoded string. + * This works independently of global locale settings. + */ + SWIFTEN_API boost::filesystem::path stringToPath(const std::string&); + + /** + * Returns the UTF-8 representation of the given path + * This works independently of global locale settings. + */ + SWIFTEN_API std::string pathToString(const boost::filesystem::path&); +} + + diff --git a/Swiften/Base/Paths.cpp b/Swiften/Base/Paths.cpp index d434cc1..8ad1159 100644 --- a/Swiften/Base/Paths.cpp +++ b/Swiften/Base/Paths.cpp @@ -36,10 +36,11 @@ boost::filesystem::path Paths::getExecutablePath() { return boost::filesystem::path(std::string(reinterpret_cast<const char*>(vecptr(path)), path.size()).c_str()).parent_path(); } #elif defined(SWIFTEN_PLATFORM_WINDOWS) - ByteArray data; + std::vector<wchar_t> data; data.resize(2048); - GetModuleFileName(NULL, reinterpret_cast<char*>(vecptr(data)), data.size()); - return boost::filesystem::path(std::string(reinterpret_cast<const char*>(vecptr(data)), data.size()).c_str()).parent_path(); + GetModuleFileNameW(NULL, vecptr(data), data.size()); + return boost::filesystem::path( + std::wstring(vecptr(data), data.size())).parent_path(); #endif return boost::filesystem::path(); } diff --git a/Swiften/Base/SConscript b/Swiften/Base/SConscript index b56db8c..4956fba 100644 --- a/Swiften/Base/SConscript +++ b/Swiften/Base/SConscript @@ -7,6 +7,7 @@ objects = swiften_env.SwiftenObject([ "SafeAllocator.cpp", "Error.cpp", "Log.cpp", + "Path.cpp", "Paths.cpp", "String.cpp", "IDGenerator.cpp", diff --git a/Swiften/Base/String.cpp b/Swiften/Base/String.cpp index 242b8e5..40ea2e1 100644 --- a/Swiften/Base/String.cpp +++ b/Swiften/Base/String.cpp @@ -1,15 +1,21 @@ /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ +#include <Swiften/Base/Platform.h> + #include <cassert> #include <algorithm> #include <sstream> #include <iomanip> +#ifdef SWIFTEN_PLATFORM_WINDOWS +#include <windows.h> +#endif #include <Swiften/Base/String.h> +#include <Swiften/Base/ByteArray.h> namespace Swift { @@ -113,4 +119,35 @@ int String::convertHexStringToInt(const std::string& s) { return h; } + +#ifdef SWIFTEN_PLATFORM_WINDOWS +std::string convertWStringToString(const std::wstring& s) { + int utf8Size = WideCharToMultiByte(CP_UTF8, 0, s.c_str(), -1, NULL, 0, NULL, NULL); + if (utf8Size < 0) { + throw std::runtime_error("Conversion error"); + } + std::vector<char> utf8Data(utf8Size); + int result = WideCharToMultiByte( + CP_UTF8, 0, s.c_str(), -1, vecptr(utf8Data), utf8Data.size(), NULL, NULL); + if (result < 0) { + throw std::runtime_error("Conversion error"); + } + return std::string(vecptr(utf8Data), utf8Size-1 /* trailing 0 character */); +} + +std::wstring convertStringToWString(const std::string& s) { + int utf16Size = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, NULL, 0); + if (utf16Size < 0) { + throw std::runtime_error("Conversion error"); + } + std::vector<wchar_t> utf16Data(utf16Size); + int result = MultiByteToWideChar( + CP_UTF8, 0, s.c_str(), -1, vecptr(utf16Data), utf16Data.size()); + if (result < 0) { + throw std::runtime_error("Conversion error"); + } + return std::wstring(vecptr(utf16Data), utf16Size-1 /* trailing 0 character */); +} +#endif + } diff --git a/Swiften/Base/String.h b/Swiften/Base/String.h index 5ce6c3d..5a5642e 100644 --- a/Swiften/Base/String.h +++ b/Swiften/Base/String.h @@ -11,6 +11,7 @@ #include <sstream> #include <Swiften/Base/API.h> +#include <Swiften/Base/Platform.h> #define SWIFTEN_STRING_TO_CFSTRING(a) \ CFStringCreateWithBytes(NULL, reinterpret_cast<const UInt8*>(a.c_str()), a.size(), kCFStringEncodingUTF8, false) @@ -32,8 +33,14 @@ namespace Swift { std::string convertIntToHexString(int h); int convertHexStringToInt(const std::string& s); + } +#ifdef SWIFTEN_PLATFORM_WINDOWS + SWIFTEN_API std::string convertWStringToString(const std::wstring& s); + SWIFTEN_API std::wstring convertStringToWString(const std::string& s); +#endif + class SWIFTEN_API makeString { public: template <typename T> makeString& operator<<(T const& v) { diff --git a/Swiften/Base/UnitTest/PathTest.cpp b/Swiften/Base/UnitTest/PathTest.cpp new file mode 100644 index 0000000..f5f99e7 --- /dev/null +++ b/Swiften/Base/UnitTest/PathTest.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2013 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#include <Swiften/Base/Path.h> +#include <Swiften/Base/Platform.h> + +using namespace Swift; + +class PathTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(PathTest); + CPPUNIT_TEST(testStringToPath); + CPPUNIT_TEST(testPathToString); + CPPUNIT_TEST_SUITE_END(); + + public: + void testStringToPath() { +#ifdef SWIFTEN_PLATFORM_WINDOWS + CPPUNIT_ASSERT(std::wstring(L"tron\xe7on") == stringToPath("tron\xc3\xa7on").native()); +#else + CPPUNIT_ASSERT_EQUAL(std::string("tron\xc3\xa7on"), stringToPath("tron\xc3\xa7on").native()); +#endif + } + + void testPathToString() { + CPPUNIT_ASSERT_EQUAL(std::string("tron\xc3\xa7on"), pathToString(stringToPath("tron\xc3\xa7on"))); + } +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(PathTest); + diff --git a/Swiften/Base/UnitTest/StringTest.cpp b/Swiften/Base/UnitTest/StringTest.cpp index b29f331..ffca98a 100644 --- a/Swiften/Base/UnitTest/StringTest.cpp +++ b/Swiften/Base/UnitTest/StringTest.cpp @@ -9,6 +9,7 @@ #include <string> #include <Swiften/Base/String.h> +#include <Swiften/Base/Platform.h> using namespace Swift; @@ -24,6 +25,10 @@ class StringTest : public CppUnit::TestFixture { CPPUNIT_TEST(testReplaceAll_ConsecutiveChars); CPPUNIT_TEST(testReplaceAll_MatchingReplace); CPPUNIT_TEST(testSplit); +#ifdef SWIFTEN_PLATFORM_WINDOWS + CPPUNIT_TEST(testConvertWStringToString); + CPPUNIT_TEST(testConvertStringToWString); +#endif CPPUNIT_TEST_SUITE_END(); public: @@ -109,6 +114,16 @@ class StringTest : public CppUnit::TestFixture { CPPUNIT_ASSERT_EQUAL(std::string("def"), result[1]); CPPUNIT_ASSERT_EQUAL(std::string("ghi"), result[2]); } + +#ifdef SWIFTEN_PLATFORM_WINDOWS + void testConvertWStringToString() { + CPPUNIT_ASSERT_EQUAL(std::string("tron\xc3\xa7on"), convertWStringToString(std::wstring(L"tron\xe7on"))); + } + + void testConvertStringToWString() { + CPPUNIT_ASSERT(std::wstring(L"tron\xe7on") == convertStringToWString(std::string("tron\xc3\xa7on"))); + } +#endif }; CPPUNIT_TEST_SUITE_REGISTRATION(StringTest); diff --git a/Swiften/Config/SConscript b/Swiften/Config/SConscript index 27dfc2e..837884b 100644 --- a/Swiften/Config/SConscript +++ b/Swiften/Config/SConscript @@ -37,12 +37,18 @@ config_flags += cStringVariable(swiften_env, "LIBFLAGS", libflags) config_env = env.Clone() # Create a local copy of Paths.cpp to avoid a Swiften dependency -config_env.Install(".", "#/Swiften/Base/Paths.cpp") +config_env.Install(".", [ + "#/Swiften/Base/Paths.cpp", + "#/Swiften/Base/Path.cpp", + "#/Swiften/Base/String.cpp", +]) config_env.UseFlags(config_env["BOOST_FLAGS"]) config_env.UseFlags(config_env["PLATFORM_FLAGS"]) config_env.WriteVal("swiften-config.h", config_env.Value(config_flags)) swiften_config = config_env.Program("swiften-config", [ "Paths.cpp", + "Path.cpp", + "String.cpp", "swiften-config.cpp" ]) diff --git a/Swiften/Config/swiften-config.cpp b/Swiften/Config/swiften-config.cpp index 89df9cd..778134d 100644 --- a/Swiften/Config/swiften-config.cpp +++ b/Swiften/Config/swiften-config.cpp @@ -16,6 +16,7 @@ #include <Swiften/Base/Platform.h> #include <Swiften/Base/Paths.h> +#include <Swiften/Base/Path.h> #include <Swiften/Version.h> #include "swiften-config.h" @@ -90,12 +91,12 @@ int main(int argc, char* argv[]) { for(size_t i = 0; i < libs.size(); ++i) { if (inPlace) { std::string lib = libs[i]; - boost::replace_all(lib, "#", topSourcePath.string()); + boost::replace_all(lib, "#", pathToString(topSourcePath)); libs[i] = lib; } else { std::string lib = libs[i]; - boost::replace_all(lib, "#", (topInstallPath / "lib").string()); + boost::replace_all(lib, "#", pathToString(topInstallPath / "lib")); boost::erase_all(lib, "/Swiften"); libs[i] = lib; } @@ -103,12 +104,12 @@ int main(int argc, char* argv[]) { for(size_t i = 0; i < cflags.size(); ++i) { if (inPlace) { std::string cflag = cflags[i]; - boost::replace_all(cflag, "#", topSourcePath.string()); + boost::replace_all(cflag, "#", pathToString(topSourcePath)); cflags[i] = cflag; } else { std::string cflag = cflags[i]; - boost::replace_all(cflag, "#", (topInstallPath / "include").string()); + boost::replace_all(cflag, "#", pathToString(topInstallPath / "include")); cflags[i] = cflag; } } diff --git a/Swiften/Entity/PayloadPersister.cpp b/Swiften/Entity/PayloadPersister.cpp index 729d36a..ace7b4a 100644 --- a/Swiften/Entity/PayloadPersister.cpp +++ b/Swiften/Entity/PayloadPersister.cpp @@ -42,7 +42,7 @@ boost::shared_ptr<Payload> PayloadPersister::loadPayload(const boost::filesystem try { if (boost::filesystem::exists(path)) { ByteArray data; - readByteArrayFromFile(data, path.string()); + readByteArrayFromFile(data, path); boost::shared_ptr<PayloadParser> parser(createParser()); PayloadParserTester tester(parser.get()); tester.parse(byteArrayToString(data)); diff --git a/Swiften/Examples/SendFile/SendFile.cpp b/Swiften/Examples/SendFile/SendFile.cpp index ff49149..b056842 100644 --- a/Swiften/Examples/SendFile/SendFile.cpp +++ b/Swiften/Examples/SendFile/SendFile.cpp @@ -64,7 +64,7 @@ class FileSender { client->sendPresence(Presence::create()); //ByteArray fileData; - //readByteArrayFromFile(fileData, file.string()); + //readByteArrayFromFile(fileData, file); // gather file information /*StreamInitiationFileInfo fileInfo; diff --git a/Swiften/FileTransfer/FileTransferManagerImpl.cpp b/Swiften/FileTransfer/FileTransferManagerImpl.cpp index e6c4796..b832d7e 100644 --- a/Swiften/FileTransfer/FileTransferManagerImpl.cpp +++ b/Swiften/FileTransfer/FileTransferManagerImpl.cpp @@ -18,6 +18,7 @@ #include <Swiften/Base/foreach.h> #include <Swiften/Base/Log.h> +#include <Swiften/Base/Path.h> #include "Swiften/Disco/EntityCapsProvider.h" #include <Swiften/JID/JID.h> #include <Swiften/Elements/StreamInitiationFileInfo.h> @@ -130,7 +131,7 @@ OutgoingFileTransfer::ref FileTransferManagerImpl::createOutgoingFileTransfer( #if BOOST_FILESYSTEM_VERSION == 2 // TODO: Delete this when boost 1.44 becomes a minimum requirement, and we no longer need v2 std::string filename = filepath.filename(); #else - std::string filename = filepath.filename().string(); + std::string filename = pathToString(filepath.filename()); #endif boost::uintmax_t sizeInBytes = boost::filesystem::file_size(filepath); diff --git a/Swiften/History/SQLiteHistoryStorage.cpp b/Swiften/History/SQLiteHistoryStorage.cpp index 2da389a..dda8766 100644 --- a/Swiften/History/SQLiteHistoryStorage.cpp +++ b/Swiften/History/SQLiteHistoryStorage.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ @@ -11,6 +11,7 @@ #include <sqlite3.h> #include <Swiften/History/SQLiteHistoryStorage.h> #include <boost/date_time/gregorian/gregorian.hpp> +#include <Swiften/Base/Path.h> inline std::string getEscapedString(const std::string& s) { std::string result(s); @@ -25,12 +26,12 @@ inline std::string getEscapedString(const std::string& s) { namespace Swift { -SQLiteHistoryStorage::SQLiteHistoryStorage(const std::string& file) : db_(0) { +SQLiteHistoryStorage::SQLiteHistoryStorage(const boost::filesystem::path& file) : db_(0) { thread_ = new boost::thread(boost::bind(&SQLiteHistoryStorage::run, this)); - sqlite3_open(file.c_str(), &db_); + sqlite3_open(pathToString(file).c_str(), &db_); if (!db_) { - std::cerr << "Error opening database " << file << std::endl; + std::cerr << "Error opening database " << pathToString(file) << std::endl; } char* errorMessage; diff --git a/Swiften/History/SQLiteHistoryStorage.h b/Swiften/History/SQLiteHistoryStorage.h index 524247d..2c1ba7a 100644 --- a/Swiften/History/SQLiteHistoryStorage.h +++ b/Swiften/History/SQLiteHistoryStorage.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010-2013 Remko Tronçon * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ @@ -11,13 +11,14 @@ #include <Swiften/Base/API.h> #include <Swiften/History/HistoryStorage.h> #include <boost/thread.hpp> +#include <boost/filesystem/path.hpp> struct sqlite3; namespace Swift { class SWIFTEN_API SQLiteHistoryStorage : public HistoryStorage { public: - SQLiteHistoryStorage(const std::string& file); + SQLiteHistoryStorage(const boost::filesystem::path& file); ~SQLiteHistoryStorage(); void addMessage(const HistoryMessage& message); diff --git a/Swiften/QA/StorageTest/VCardFileStorageTest.cpp b/Swiften/QA/StorageTest/VCardFileStorageTest.cpp index 7667176..4145696 100644 --- a/Swiften/QA/StorageTest/VCardFileStorageTest.cpp +++ b/Swiften/QA/StorageTest/VCardFileStorageTest.cpp @@ -49,7 +49,7 @@ class VCardFileStorageTest : public CppUnit::TestFixture { boost::filesystem::path vcardFile(vcardsPath / "alice@wonderland.lit%2fTeaRoom.xml"); CPPUNIT_ASSERT(boost::filesystem::exists(vcardFile)); ByteArray data; - data.readFromFile(vcardFile.string()); + data.readFromFile(vcardFile); CPPUNIT_ASSERT(boost::starts_with(data.toString(), "<vCard xmlns=\"vcard-temp\">")); } diff --git a/Swiften/QA/TLSTest/CertificateTest.cpp b/Swiften/QA/TLSTest/CertificateTest.cpp index 6932881..2fa4c04 100644 --- a/Swiften/QA/TLSTest/CertificateTest.cpp +++ b/Swiften/QA/TLSTest/CertificateTest.cpp @@ -32,7 +32,7 @@ class CertificateTest : public CppUnit::TestFixture { public: void setUp() { pathProvider = new PlatformApplicationPathProvider("FileReadBytestreamTest"); - readByteArrayFromFile(certificateData, (pathProvider->getExecutableDir() / "jabber_org.crt").string()); + readByteArrayFromFile(certificateData, (pathProvider->getExecutableDir() / "jabber_org.crt")); certificateFactory = new CERTIFICATE_FACTORY(); } diff --git a/Swiften/SConscript b/Swiften/SConscript index 1cb3543..aab9984 100644 --- a/Swiften/SConscript +++ b/Swiften/SConscript @@ -308,6 +308,7 @@ if env["SCONS_STAGE"] == "build" : File("Base/UnitTest/DateTimeTest.cpp"), File("Base/UnitTest/ByteArrayTest.cpp"), File("Base/UnitTest/URLTest.cpp"), + File("Base/UnitTest/PathTest.cpp"), File("Chat/UnitTest/ChatStateNotifierTest.cpp"), # File("Chat/UnitTest/ChatStateTrackerTest.cpp"), File("Client/UnitTest/ClientSessionTest.cpp"), diff --git a/Swiften/TLS/PKCS12Certificate.h b/Swiften/TLS/PKCS12Certificate.h index 2f70456..2d4c2e5 100644 --- a/Swiften/TLS/PKCS12Certificate.h +++ b/Swiften/TLS/PKCS12Certificate.h @@ -8,13 +8,14 @@ #include <Swiften/Base/SafeByteArray.h> #include <Swiften/TLS/CertificateWithKey.h> +#include <boost/filesystem/path.hpp> namespace Swift { class PKCS12Certificate : public Swift::CertificateWithKey { public: PKCS12Certificate() {} - PKCS12Certificate(const std::string& filename, const SafeByteArray& password) : password_(password) { + PKCS12Certificate(const boost::filesystem::path& filename, const SafeByteArray& password) : password_(password) { readByteArrayFromFile(data_, filename); } diff --git a/Swiftob/LuaCommands.cpp b/Swiftob/LuaCommands.cpp index d27c131..c2478cd 100644 --- a/Swiftob/LuaCommands.cpp +++ b/Swiftob/LuaCommands.cpp @@ -15,6 +15,7 @@ #include <Swiften/Client/Client.h> #include <Swiften/Network/TimerFactory.h> #include <boost/filesystem/operations.hpp> +#include <Swiften/Base/Path.h> #include <Swiftob/Commands.h> @@ -414,7 +415,7 @@ void LuaCommands::loadScript(boost::filesystem::path filePath) { std::string filename = filePath.filename().string(); #endif filename += ".storage"; - boost::filesystem::path storagePath(boost::filesystem::path(path_) / filename); + boost::filesystem::path storagePath(boost::filesystem::path(path_) / stringToPath(filename)); Storage* storage = new Storage(storagePath); lua_pushlightuserdata(lua, storage); lua_setfield(lua, LUA_REGISTRYINDEX, STORAGE); diff --git a/Swiftob/Storage.cpp b/Swiftob/Storage.cpp index 141be9f..5311d82 100644 --- a/Swiftob/Storage.cpp +++ b/Swiftob/Storage.cpp @@ -25,7 +25,7 @@ Storage::Storage(const boost::filesystem::path& path) : settingsPath_(path) { void Storage::load() { if (boost::filesystem::exists(settingsPath_)) { Swift::ByteArray data; - Swift::readByteArrayFromFile(data, settingsPath_.string()); + Swift::readByteArrayFromFile(data, settingsPath_); foreach (std::string line, Swift::String::split(Swift::byteArrayToString(data), '\n')) { std::pair<std::string, std::string> pair = Swift::String::getSplittedAtFirst(line, '\t'); settings_[pair.first] = pair.second; |