summaryrefslogtreecommitdiffstats
path: root/Swift
diff options
context:
space:
mode:
Diffstat (limited to 'Swift')
-rw-r--r--Swift/ChangeLog.md58
-rw-r--r--Swift/Controllers/Chat/ChatController.cpp17
-rw-r--r--Swift/Controllers/Chat/ChatController.h1
-rw-r--r--Swift/Controllers/Chat/ChatControllerBase.cpp3
-rw-r--r--Swift/Controllers/Chat/ChatsManager.cpp12
-rw-r--r--Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp105
-rw-r--r--Swift/Controllers/Storages/AvatarFileStorage.cpp31
-rwxr-xr-xSwift/Packaging/Debian/Testing/swift-distr-tests.sh16
-rw-r--r--Swift/Packaging/Debian/changelog.debian-unstable18
-rw-r--r--Swift/Packaging/Debian/debian/control.in2
-rw-r--r--Swift/Packaging/Debian/debian/copyright2
-rwxr-xr-xSwift/Packaging/Debian/debian/rules4
-rwxr-xr-xSwift/Packaging/Debian/package.sh12
-rwxr-xr-xSwift/Packaging/Debian/package_all_platforms.sh10
-rw-r--r--Swift/Packaging/Debian/update_debian_repo.sh13
-rw-r--r--Swift/Packaging/SConscript29
-rw-r--r--Swift/Packaging/WiX/include.xslt12
-rw-r--r--Swift/QtUI/QtChatTabs.cpp6
-rw-r--r--Swift/QtUI/QtChatWindow.cpp6
-rw-r--r--Swift/QtUI/QtColorToolButton.cpp1
-rw-r--r--Swift/QtUI/QtTabWidget.cpp4
-rw-r--r--Swift/QtUI/SConscript2
-rw-r--r--Swift/QtUI/Trellis/QtDynamicGridLayout.cpp2
-rw-r--r--Swift/QtUI/UserSearch/QtUserSearchWindow.cpp1
-rw-r--r--Swift/QtUI/UserSearch/QtUserSearchWindow.h3
-rw-r--r--Swift/SConscript2
-rw-r--r--Swift/Translations/swift_de.ts14
-rw-r--r--Swift/Translations/swift_nl.ts12
28 files changed, 323 insertions, 75 deletions
diff --git a/Swift/ChangeLog.md b/Swift/ChangeLog.md
index 32b5711..9152b50 100644
--- a/Swift/ChangeLog.md
+++ b/Swift/ChangeLog.md
@@ -1,3 +1,57 @@
+4.0.3 (2019-01-03)
+------------------
+- Fix handling of empty bookmark responses
+
+4.0.2 (2018-04-05)
+------------------
+- Fix versioning issue in Windows Installer process
+
+4.0.1 (2018-03-28)
+------------------
+- Allow setting vCard on servers that do not return an empty vCard on fresh accounts
+
+4.0 (2018-03-20)
+----------------
+- New chat theme including a new font
+- Support for message carbons (XEP-0280)
+- Enabled trellis mode as a default feature, allowing several tiled chats windows to be shown at once
+- Redesigned keyword highlighting
+- Improve date formatting
+- Fix Last Message Correction in multi client scenarios
+- Fix UI layout issue for translations that require right-to-left (RTL) layout
+- Fix UX issues in trellis mode
+- Improvements to font size handling in the chat theme
+- Fix display of default avatar on Windows
+- Support for automatic software updates on macOS
+- macOS releases are now code-signed
+- Support for unicode emojis on macOS
+- Add AppImage for Linux 64-bit as a supported platform
+- Improved spell checker support on Linux
+- And assorted smaller features and usability enhancements
+
+4.0-rc6 ( 2018-03-07 )
+----------------------
+- Small usability fixes in Carbons ( XEP-0280 ) handling and Windows installer
+- Fix crashes related to room invitations, layout changes, and vCard handling
+- And smaller bug fixes
+
+4.0-rc5 ( 2018-01-09 )
+----------------------
+- Fix crash during sleep on macOS
+
+4.0-rc4 ( 2018-01-04 )
+----------------------
+- Remove conflicting shortcut
+- Debian packaging fixes
+
+4.0-rc3 ( 2017-11-28 )
+----------------------
+- Fix crash in emoticon dialog
+- Fix Windows MSI installer when updating from earlier Swift version
+- Update translations ( Dutch, German )
+- Add AppImage for Linux 64-bit as a supported platform
+- And smaller bug fixes
+
4.0-rc2 ( 2017-05-22 )
----------------------
- Fix regression in chat window titles for chat rooms
@@ -10,7 +64,7 @@
- Fix Last Message Correction in multi client scenarios
- Fix display of default avatar on Windows
- Support for automatic software updates on macOS
-- Redesigned keyword highlighing
+- Redesigned keyword highlighting
- Support for unicode emojis on macOS
- Improvements to font size handling in the chat theme
- Fix UX issues in trellis mode
@@ -117,4 +171,4 @@ Yoann Blein, Catalin Badea, Pavol Babincak, Mateusz Piekos, Alexey Melnikov and
1.0 ( 2011-04-18 )
------------------
-- Initial release. \ No newline at end of file
+- Initial release.
diff --git a/Swift/Controllers/Chat/ChatController.cpp b/Swift/Controllers/Chat/ChatController.cpp
index fe8e870..40f6156 100644
--- a/Swift/Controllers/Chat/ChatController.cpp
+++ b/Swift/Controllers/Chat/ChatController.cpp
@@ -86,7 +86,7 @@ ChatController::ChatController(const JID& self, StanzaChannel* stanzaChannel, IQ
chatStateNotifier_->setContactIsOnline(theirPresence && theirPresence->getType() == Presence::Available);
startMessage += ".";
chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(startMessage), ChatWindow::DefaultDirection);
- chatWindow_->onContinuationsBroken.connect([this, startMessage]() { chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(startMessage), ChatWindow::DefaultDirection); });
+ continuationsBrokenConnection_ = chatWindow_->onContinuationsBroken.connect([this, startMessage]() { chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(startMessage), ChatWindow::DefaultDirection); });
chatWindow_->onUserTyping.connect(boost::bind(&ChatStateNotifier::setUserIsTyping, chatStateNotifier_));
chatWindow_->onUserCancelsTyping.connect(boost::bind(&ChatStateNotifier::userCancelledNewMessage, chatStateNotifier_));
chatWindow_->onFileTransferStart.connect(boost::bind(&ChatController::handleFileTransferStart, this, _1, _2));
@@ -320,6 +320,7 @@ void ChatController::handleIncomingOwnMessage(std::shared_ptr<Message> message)
if (!message->getBody().get_value_or("").empty()) {
postSendMessage(message->getBody().get_value_or(""), message);
handleStanzaAcked(message);
+ onActivity(message->getBody().get_value_or(""));
}
}
@@ -585,8 +586,20 @@ JID ChatController::messageCorrectionJID(const JID& fromJID) {
}
ChatWindow* ChatController::detachChatWindow() {
- chatWindow_->onUserTyping.disconnect(boost::bind(&ChatStateNotifier::setUserIsTyping, chatStateNotifier_));
+ continuationsBrokenConnection_.disconnect();
+ chatWindow_->onClosed.disconnect(boost::bind(&ChatController::handleWindowClosed, this));
+ chatWindow_->onInviteToChat.disconnect(boost::bind(&ChatController::handleInviteToChat, this, _1));
+ chatWindow_->onUnblockUserRequest.disconnect(boost::bind(&ChatController::handleUnblockUserRequest, this));
+ chatWindow_->onBlockUserRequest.disconnect(boost::bind(&ChatController::handleBlockUserRequest, this));
+ chatWindow_->onWhiteboardWindowShow.disconnect(boost::bind(&ChatController::handleWhiteboardWindowShow, this));
+ chatWindow_->onWhiteboardSessionCancel.disconnect(boost::bind(&ChatController::handleWhiteboardSessionCancel, this));
+ chatWindow_->onWhiteboardSessionAccept.disconnect(boost::bind(&ChatController::handleWhiteboardSessionAccept, this));
+ chatWindow_->onSendFileRequest.disconnect(boost::bind(&ChatController::handleSendFileRequest, this, _1));
+ chatWindow_->onFileTransferCancel.disconnect(boost::bind(&ChatController::handleFileTransferCancel, this, _1));
+ chatWindow_->onFileTransferAccept.disconnect(boost::bind(&ChatController::handleFileTransferAccept, this, _1, _2));
+ chatWindow_->onFileTransferStart.disconnect(boost::bind(&ChatController::handleFileTransferStart, this, _1, _2));
chatWindow_->onUserCancelsTyping.disconnect(boost::bind(&ChatStateNotifier::userCancelledNewMessage, chatStateNotifier_));
+ chatWindow_->onUserTyping.disconnect(boost::bind(&ChatStateNotifier::setUserIsTyping, chatStateNotifier_));
return ChatControllerBase::detachChatWindow();
}
diff --git a/Swift/Controllers/Chat/ChatController.h b/Swift/Controllers/Chat/ChatController.h
index d5011e4..a9093d0 100644
--- a/Swift/Controllers/Chat/ChatController.h
+++ b/Swift/Controllers/Chat/ChatController.h
@@ -113,6 +113,7 @@ namespace Swift {
boost::signals2::scoped_connection blockingOnStateChangedConnection_;
boost::signals2::scoped_connection blockingOnItemAddedConnection_;
boost::signals2::scoped_connection blockingOnItemRemovedConnection_;
+ boost::signals2::scoped_connection continuationsBrokenConnection_;
boost::optional<ChatWindow::AlertID> deliveryReceiptAlert_;
boost::optional<ChatWindow::AlertID> blockedContactAlert_;
diff --git a/Swift/Controllers/Chat/ChatControllerBase.cpp b/Swift/Controllers/Chat/ChatControllerBase.cpp
index 0fc735a..19bbf8d 100644
--- a/Swift/Controllers/Chat/ChatControllerBase.cpp
+++ b/Swift/Controllers/Chat/ChatControllerBase.cpp
@@ -58,6 +58,9 @@ void ChatControllerBase::handleContinuationsBroken() {
}
ChatWindow* ChatControllerBase::detachChatWindow() {
+ chatWindow_->onContinuationsBroken.disconnect(boost::bind(&ChatControllerBase::handleContinuationsBroken, this));
+ chatWindow_->onSendMessageRequest.disconnect(boost::bind(&ChatControllerBase::handleSendMessageRequest, this, _1, _2));
+ chatWindow_->onAllMessagesRead.disconnect(boost::bind(&ChatControllerBase::handleAllMessagesRead, this));
ChatWindow* chatWindow = chatWindow_;
chatWindow_ = nullptr;
return chatWindow;
diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp
index a6f7fe0..19400f9 100644
--- a/Swift/Controllers/Chat/ChatsManager.cpp
+++ b/Swift/Controllers/Chat/ChatsManager.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2017 Isode Limited.
+ * Copyright (c) 2010-2018 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -331,11 +331,13 @@ void ChatsManager::handleBookmarksReady() {
}
void ChatsManager::handleMUCBookmarkAdded(const MUCBookmark& bookmark) {
- std::map<JID, MUCController*>::iterator it = mucControllers_.find(bookmark.getRoom());
- if (it == mucControllers_.end() && bookmark.getAutojoin()) {
- handleJoinMUCRequest(bookmark.getRoom(), bookmark.getPassword(), bookmark.getNick(), false, false, false );
+ if (bookmark.getRoom().isBare() && !bookmark.getRoom().getNode().empty()) {
+ std::map<JID, MUCController*>::iterator it = mucControllers_.find(bookmark.getRoom());
+ if (it == mucControllers_.end() && bookmark.getAutojoin()) {
+ handleJoinMUCRequest(bookmark.getRoom(), bookmark.getPassword(), bookmark.getNick(), false, false, false );
+ }
+ chatListWindow_->addMUCBookmark(bookmark);
}
- chatListWindow_->addMUCBookmark(bookmark);
}
void ChatsManager::handleMUCBookmarkRemoved(const MUCBookmark& bookmark) {
diff --git a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
index 1502dc9..ac62942 100644
--- a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
+++ b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2017 Isode Limited.
+ * Copyright (c) 2010-2018 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -32,9 +32,12 @@
#include <Swiften/Elements/Forwarded.h>
#include <Swiften/Elements/MUCInvitationPayload.h>
#include <Swiften/Elements/MUCUserPayload.h>
+#include <Swiften/Elements/PrivateStorage.h>
+#include <Swiften/Elements/Storage.h>
#include <Swiften/FileTransfer/UnitTest/DummyFileTransferManager.h>
#include <Swiften/Jingle/JingleSessionManager.h>
#include <Swiften/MUC/MUCManager.h>
+#include <Swiften/MUC/UnitTest/MockMUC.h>
#include <Swiften/Network/DummyTimerFactory.h>
#include <Swiften/Presence/DirectedPresenceSender.h>
#include <Swiften/Presence/PresenceOracle.h>
@@ -71,7 +74,6 @@
#include <SwifTools/Notifier/Notifier.h>
#include <Swift/QtUI/QtSwiftUtil.h>
-#include <Swiften/MUC/UnitTest/MockMUC.h>
using namespace Swift;
@@ -155,6 +157,11 @@ class ChatsManagerTest : public CppUnit::TestFixture {
CPPUNIT_TEST(testImpromptuChatWindowTitle);
CPPUNIT_TEST(testStandardMUCChatWindowTitle);
+ // Bookmark tests
+ CPPUNIT_TEST(testReceivingBookmarksWithDomainJID);
+ CPPUNIT_TEST(testReceivingBookmarksWithBareJID);
+ CPPUNIT_TEST(testReceivingBookmarksWithFullJID);
+
CPPUNIT_TEST_SUITE_END();
public:
@@ -1228,6 +1235,11 @@ public:
CPPUNIT_ASSERT_EQUAL(forwardedBody, MockChatWindow::bodyFromMessage(window->lastAddedMessage_));
CPPUNIT_ASSERT_EQUAL(false, window->lastAddedMessageSenderIsSelf_);
+
+ auto recentChats = manager_->getRecentChats();
+ CPPUNIT_ASSERT_EQUAL(recentChats.size(), size_t(1));
+ CPPUNIT_ASSERT_EQUAL(recentChats[0].jid, originalMessage->getFrom().toBare());
+ CPPUNIT_ASSERT_EQUAL(recentChats[0].activity, std::string("Some further text."));
}
}
@@ -1264,6 +1276,11 @@ public:
CPPUNIT_ASSERT_EQUAL(true, window->lastAddedMessageSenderIsSelf_);
CPPUNIT_ASSERT_EQUAL(size_t(1), window->receiptChanges_.size());
CPPUNIT_ASSERT_EQUAL(ChatWindow::ReceiptRequested, window->receiptChanges_[0].second);
+
+ auto recentChats = manager_->getRecentChats();
+ CPPUNIT_ASSERT_EQUAL(recentChats.size(), size_t(1));
+ CPPUNIT_ASSERT_EQUAL(recentChats[0].jid, originalMessage->getTo().toBare());
+ CPPUNIT_ASSERT_EQUAL(recentChats[0].activity, std::string("Some text my other resource sent."));
}
// incoming carbons message for the received delivery receipt to the other resource
@@ -1280,6 +1297,12 @@ public:
CPPUNIT_ASSERT_EQUAL(size_t(2), window->receiptChanges_.size());
CPPUNIT_ASSERT_EQUAL(ChatWindow::ReceiptReceived, window->receiptChanges_[1].second);
+
+ //Delivery receipt should not change the latest recent entry. Checking for the original message.
+ auto recentChats = manager_->getRecentChats();
+ CPPUNIT_ASSERT_EQUAL(recentChats.size(), size_t(1));
+ CPPUNIT_ASSERT_EQUAL(recentChats[0].jid, messageJID.toBare());
+ CPPUNIT_ASSERT_EQUAL(recentChats[0].activity, std::string("Some text my other resource sent."));
}
}
@@ -1319,6 +1342,11 @@ public:
manager_->handleIncomingMessage(messageWrapper);
CPPUNIT_ASSERT_EQUAL(std::string(), MockChatWindow::bodyFromMessage(window->lastAddedMessage_));
CPPUNIT_ASSERT_EQUAL(false, window->lastAddedMessageSenderIsSelf_);
+
+ auto recentChats = manager_->getRecentChats();
+ CPPUNIT_ASSERT_EQUAL(recentChats.size(), size_t(1));
+ CPPUNIT_ASSERT_EQUAL(recentChats[0].jid, originalMessage->getFrom().toBare());
+ CPPUNIT_ASSERT_EQUAL(recentChats[0].activity, std::string("Some further text."));
}
}
@@ -1598,6 +1626,78 @@ public:
CPPUNIT_ASSERT_EQUAL(std::string("mucroom"), window->name_);
}
+ static std::shared_ptr<Storage> createBookmarkStorageWithJID(const JID& jid) {
+ auto storage = std::make_shared<Storage>();
+ auto room = Storage::Room();
+ room.jid = jid;
+ room.autoJoin = true;
+ storage->addRoom(room);
+ return storage;
+ }
+
+ void testReceivingBookmarksWithDomainJID() {
+ auto bookmarkRequest = std::dynamic_pointer_cast<IQ>(stanzaChannel_->sentStanzas[0]);
+ CPPUNIT_ASSERT(bookmarkRequest);
+ CPPUNIT_ASSERT_EQUAL(IQ::Get, bookmarkRequest->getType());
+
+ auto privateStorage = bookmarkRequest->getPayload<PrivateStorage>();
+ CPPUNIT_ASSERT(privateStorage);
+
+ auto storage = std::dynamic_pointer_cast<Storage>(privateStorage->getPayload());
+ CPPUNIT_ASSERT(storage);
+
+ auto response = IQ::createResult(
+ bookmarkRequest->getFrom(),
+ bookmarkRequest->getTo(),
+ bookmarkRequest->getID(),
+ std::make_shared<PrivateStorage>(createBookmarkStorageWithJID("montague.lit"))
+ );
+ stanzaChannel_->onIQReceived(response);
+ }
+
+ void testReceivingBookmarksWithBareJID() {
+ auto bookmarkRequest = std::dynamic_pointer_cast<IQ>(stanzaChannel_->sentStanzas[0]);
+ CPPUNIT_ASSERT(bookmarkRequest);
+ CPPUNIT_ASSERT_EQUAL(IQ::Get, bookmarkRequest->getType());
+
+ auto privateStorage = bookmarkRequest->getPayload<PrivateStorage>();
+ CPPUNIT_ASSERT(privateStorage);
+
+ auto storage = std::dynamic_pointer_cast<Storage>(privateStorage->getPayload());
+ CPPUNIT_ASSERT(storage);
+
+ MockChatWindow* window = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID("example@montague.lit"), uiEventStream_).Return(window);
+
+ auto response = IQ::createResult(
+ bookmarkRequest->getFrom(),
+ bookmarkRequest->getTo(),
+ bookmarkRequest->getID(),
+ std::make_shared<PrivateStorage>(createBookmarkStorageWithJID("example@montague.lit"))
+ );
+ stanzaChannel_->onIQReceived(response);
+ }
+
+ void testReceivingBookmarksWithFullJID() {
+ auto bookmarkRequest = std::dynamic_pointer_cast<IQ>(stanzaChannel_->sentStanzas[0]);
+ CPPUNIT_ASSERT(bookmarkRequest);
+ CPPUNIT_ASSERT_EQUAL(IQ::Get, bookmarkRequest->getType());
+
+ auto privateStorage = bookmarkRequest->getPayload<PrivateStorage>();
+ CPPUNIT_ASSERT(privateStorage);
+
+ auto storage = std::dynamic_pointer_cast<Storage>(privateStorage->getPayload());
+ CPPUNIT_ASSERT(storage);
+
+ auto response = IQ::createResult(
+ bookmarkRequest->getFrom(),
+ bookmarkRequest->getTo(),
+ bookmarkRequest->getID(),
+ std::make_shared<PrivateStorage>(createBookmarkStorageWithJID("example@montague.lit/someresource"))
+ );
+ stanzaChannel_->onIQReceived(response);
+ }
+
private:
std::shared_ptr<Message> makeDeliveryReceiptTestMessage(const JID& from, const std::string& id) {
std::shared_ptr<Message> message = std::make_shared<Message>();
@@ -1664,4 +1764,3 @@ private:
};
CPPUNIT_TEST_SUITE_REGISTRATION(ChatsManagerTest);
-
diff --git a/Swift/Controllers/Storages/AvatarFileStorage.cpp b/Swift/Controllers/Storages/AvatarFileStorage.cpp
index a103920..9d9b9ea 100644
--- a/Swift/Controllers/Storages/AvatarFileStorage.cpp
+++ b/Swift/Controllers/Storages/AvatarFileStorage.cpp
@@ -1,16 +1,15 @@
/*
- * Copyright (c) 2010-2016 Isode Limited.
+ * Copyright (c) 2010-2018 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/Controllers/Storages/AvatarFileStorage.h>
-#include <iostream>
-
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
+#include <Swiften/Base/Log.h>
#include <Swiften/Base/String.h>
#include <Swiften/Crypto/CryptoProvider.h>
#include <Swiften/StringCodecs/Hexify.h>
@@ -31,13 +30,13 @@ AvatarFileStorage::AvatarFileStorage(const boost::filesystem::path& avatarsDir,
jidAvatars.insert(std::make_pair(jid, r.first));
}
else if (!r.first.empty() || !r.second.empty()) {
- std::cerr << "Invalid entry in avatars file: " << r.second << std::endl;
+ SWIFT_LOG(error) << "Invalid entry in avatars file: " << r.second << std::endl;
}
}
}
}
catch (...) {
- std::cerr << "Error reading avatars file" << std::endl;
+ SWIFT_LOG(error) << "Error reading avatars file" << std::endl;
}
}
}
@@ -55,12 +54,17 @@ void AvatarFileStorage::addAvatar(const std::string& hash, const ByteArray& avat
boost::filesystem::create_directories(avatarPath.parent_path());
}
catch (const boost::filesystem::filesystem_error& e) {
- std::cerr << "ERROR: " << e.what() << std::endl;
+ SWIFT_LOG(error) << "filesystem error: " << e.what() << std::endl;
}
}
- boost::filesystem::ofstream file(avatarPath, boost::filesystem::ofstream::binary|boost::filesystem::ofstream::out);
- file.write(reinterpret_cast<const char*>(vecptr(avatar)), static_cast<std::streamsize>(avatar.size()));
- file.close();
+
+ try {
+ boost::filesystem::ofstream file(avatarPath, boost::filesystem::ofstream::binary|boost::filesystem::ofstream::out);
+ file.write(reinterpret_cast<const char*>(vecptr(avatar)), static_cast<std::streamsize>(avatar.size()));
+ }
+ catch (const boost::filesystem::filesystem_error& e) {
+ SWIFT_LOG(error) << "filesystem error: " << e.what() << std::endl;
+ }
}
boost::filesystem::path AvatarFileStorage::getAvatarPath(const std::string& hash) const {
@@ -69,7 +73,12 @@ boost::filesystem::path AvatarFileStorage::getAvatarPath(const std::string& hash
ByteArray AvatarFileStorage::getAvatar(const std::string& hash) const {
ByteArray data;
- readByteArrayFromFile(data, getAvatarPath(hash));
+ try {
+ readByteArrayFromFile(data, getAvatarPath(hash));
+ }
+ catch (const boost::filesystem::filesystem_error& e) {
+ SWIFT_LOG(error) << "filesystem error: " << e.what() << std::endl;
+ }
return data;
}
@@ -98,7 +107,7 @@ void AvatarFileStorage::saveJIDAvatars() {
file.close();
}
catch (...) {
- std::cerr << "Error writing avatars file" << std::endl;
+ SWIFT_LOG(error) << "Error writing avatars file" << std::endl;
}
}
diff --git a/Swift/Packaging/Debian/Testing/swift-distr-tests.sh b/Swift/Packaging/Debian/Testing/swift-distr-tests.sh
index 8d03282..e817974 100755
--- a/Swift/Packaging/Debian/Testing/swift-distr-tests.sh
+++ b/Swift/Packaging/Debian/Testing/swift-distr-tests.sh
@@ -40,25 +40,31 @@ arr[0,0]="ubuntu"
arr[0,1]="http://archive.ubuntu.com/ubuntu"
arr[0,2]="xenial"
-#Ubuntu yakkety
+#Ubuntu artful
arr[1,0]="ubuntu"
arr[1,1]="http://archive.ubuntu.com/ubuntu"
-arr[1,2]="yakkety"
+arr[1,2]="artful"
#Debian jessie
arr[2,0]="debian"
arr[2,1]="http://deb.debian.org/debian/"
arr[2,2]="jessie"
-#Debian sid
+#Debian stretch
arr[3,0]="debian"
arr[3,1]="http://deb.debian.org/debian/"
-arr[3,2]="sid"
+arr[3,2]="stretch"
+
+#Debian sid
+arr[4,0]="debian"
+arr[4,1]="http://deb.debian.org/debian/"
+arr[4,2]="sid"
+
DIST="$1"
RETURN_VALUE=0
-for counter in {0..3}
+for counter in {0..4}
do
# for ARCH in "amd64" "i386"
for ARCH in "amd64"
diff --git a/Swift/Packaging/Debian/changelog.debian-unstable b/Swift/Packaging/Debian/changelog.debian-unstable
index ca9ffec..f2bf2c5 100644
--- a/Swift/Packaging/Debian/changelog.debian-unstable
+++ b/Swift/Packaging/Debian/changelog.debian-unstable
@@ -1,3 +1,21 @@
+swift-im (4.0.3-1) UNRELEASED; urgency=medium
+
+ * New chat theme including a new font
+ * Support for message carbons (XEP-0280)
+ * Enabled trellis mode as a default feature, allowing several tiled chats windows to be shown at once
+ * Redesigned keyword highlighting
+ * Improve date formatting
+ * Fix Last Message Correction in multi client scenarios
+ * Fix UI layout issue for translations that require right-to-left (RTL) layout
+ * Fix UX issues in trellis mode
+ * Improvements to font size handling in the chat theme
+ * Add AppImage for Linux 64-bit as a supported platform
+ * Improved spell checker support on Linux
+ * Allow setting vCard on servers that do not return an empty vCard on fresh accounts
+ * And assorted smaller features and usability enhancements. Closes: 840151, 889062
+
+ -- Kevin Smith <kevin@kismith.co.uk> Thu, 03 Jan 2019 13:59:07 +0100
+
swift-im (3.0.4-1) unstable; urgency=low
* New upstream release
diff --git a/Swift/Packaging/Debian/debian/control.in b/Swift/Packaging/Debian/debian/control.in
index 26544e5..e779f21 100644
--- a/Swift/Packaging/Debian/debian/control.in
+++ b/Swift/Packaging/Debian/debian/control.in
@@ -3,7 +3,7 @@ Section: net
Priority: optional
Maintainer: Swift Package Maintainer <packages@swift.im>
Uploaders: Remko Tronçon <dev@el-tramo.be>, Kevin Smith <kevin@kismith.co.uk>
-Build-Depends: debhelper (>= 9), scons (>= 1.2.0), libssl-dev (>= 0.9.8g), qtbase5-dev (>= 5.0.0), qtchooser, qtbase5-dev-tools (>= 5.0.0), libqt5x11extras5-dev (>= 5.0.0), libqt5webkit5-dev (>= 5.0.0), qtmultimedia5-dev (>=5.0.0), qttools5-dev-tools (>=5.0.0), qt5-image-formats-plugins (>=5.0.0), libqt5svg5-dev (>=5.0.0), libxml2-dev (>= 2.7.6), libxss-dev (>= 1.2.0), libboost-dev (>= 1.34.1), libboost-filesystem-dev (>= 1.34.1), libboost-program-options-dev (>= 1.34.1), libboost-regex-dev (>= 1.34.1), libboost-signals-dev (>= 1.34.1), libboost-system-dev (>= 1.34.1), libboost-thread-dev (>= 1.34.1), libboost-date-time-dev (>= 1.34.1), libidn11-dev (>= 1.10), docbook-xsl (>= 1.75.0), docbook-xml (>= 4.5), xsltproc, libxml2-utils, libnatpmp-dev, libminiupnpc-dev, libsqlite3-dev, libhunspell-dev, zlib1g-dev
+Build-Depends: debhelper (>= 9), scons (>= 1.2.0), libssl-dev (>= 0.9.8g), qtbase5-dev (>= 5.0.0), qtchooser, qtbase5-dev-tools (>= 5.0.0), libqt5x11extras5-dev (>= 5.0.0), libqt5webkit5-dev (>= 5.0.0), qtmultimedia5-dev (>=5.0.0), qttools5-dev-tools (>=5.0.0), qt5-image-formats-plugins (>=5.0.0), libqt5svg5-dev (>=5.0.0), libxml2-dev (>= 2.7.6), libxss-dev (>= 1.2.0), libboost-dev (>= 1.34.1), libboost-filesystem-dev (>= 1.34.1), libboost-program-options-dev (>= 1.34.1), libboost-regex-dev (>= 1.34.1), libboost-signals-dev (>= 1.34.1), libboost-system-dev (>= 1.34.1), libboost-thread-dev (>= 1.34.1), libboost-date-time-dev (>= 1.34.1), libidn11-dev (>= 1.10), docbook-xsl (>= 1.75.0), docbook-xml (>= 4.5), xsltproc, libxml2-utils, libnatpmp-dev, libminiupnpc-dev, libsqlite3-dev, libhunspell-dev, zlib1g-dev, help2man
Standards-Version: 3.9.8
Vcs-Git: git://swift.im/swift
Vcs-Browser: http://swift.im/git/swift
diff --git a/Swift/Packaging/Debian/debian/copyright b/Swift/Packaging/Debian/debian/copyright
index a0c2c79..9219930 100644
--- a/Swift/Packaging/Debian/debian/copyright
+++ b/Swift/Packaging/Debian/debian/copyright
@@ -3,7 +3,7 @@ with help from Olly Betts <olly@survex.com>.
The upstream sources were obtained from http://swift.im.
-Copyright (C) 2010-2016 Isode Limited.
+Copyright (C) 2010-2019 Isode Limited.
Licensed under the GNU General Public License.
See /usr/share/common-licenses/GPL-3 for the full license.
diff --git a/Swift/Packaging/Debian/debian/rules b/Swift/Packaging/Debian/debian/rules
index 87c551b..ed432bb 100755
--- a/Swift/Packaging/Debian/debian/rules
+++ b/Swift/Packaging/Debian/debian/rules
@@ -4,7 +4,7 @@
export PYTHONDONTWRITEBYTECODE=1
export QT_SELECT=qt5
-SCONS_FLAGS=V=1 qt5=1 optimize=1 debug=1 allow_warnings=1 swiften_dll=1 docbook_xsl=/usr/share/xml/docbook/stylesheet/docbook-xsl docbook_xml=/usr/share/xml/docbook/schema/dtd/4.5 linkflags="$(shell dpkg-buildflags --get LDFLAGS)" ccflags="$(shell dpkg-buildflags --get CPPFLAGS) $(shell dpkg-buildflags --get CFLAGS)"
+SCONS_FLAGS=V=1 qt5=1 optimize=1 debug=1 allow_warnings=1 swiften_dll=1 help2man=1 docbook_xsl=/usr/share/xml/docbook/stylesheet/docbook-xsl docbook_xml=/usr/share/xml/docbook/schema/dtd/4.5 linkflags="$(shell dpkg-buildflags --get LDFLAGS)" ccflags="$(shell dpkg-buildflags --get CPPFLAGS) $(shell dpkg-buildflags --get CFLAGS)"
SCONS_INSTALL_BASE=$(CURDIR)/debian/tmp
SCONS_INSTALL_FLAGS=SWIFT_INSTALLDIR=$(SCONS_INSTALL_BASE)/usr SWIFTEN_INSTALLDIR=$(SCONS_INSTALL_BASE)/usr
SWIFT_INSTALLDIR=$(SCONS_INSTALL_BASE)/usr SWIFTEN_INSTALLDIR=$(SCONS_INSTALL_BASE)/usr
@@ -21,7 +21,7 @@ override_dh_clean:
override_dh_configure:
override_dh_auto_build:
- scons $(SCONS_FLAGS) $(SCONS_EXTRA_FLAGS) Swift Swiften
+ scons $(SCONS_FLAGS) $(SCONS_EXTRA_FLAGS) Swift Swiften debian/swift-im.1 debian/swiften-config.1
override_dh_auto_install:
scons $(SCONS_FLAGS) $(SCONS_EXTRA_FLAGS) $(SCONS_INSTALL_FLAGS) $(SCONS_INSTALL_BASE)
diff --git a/Swift/Packaging/Debian/package.sh b/Swift/Packaging/Debian/package.sh
index d19f5dc..62dfff0 100755
--- a/Swift/Packaging/Debian/package.sh
+++ b/Swift/Packaging/Debian/package.sh
@@ -95,18 +95,6 @@ cat $DIRNAME/debian/control.in | sed -e "s/%SWIFTEN_SOVERSION%/$SWIFTEN_SOVERSIO
rm $DIRNAME/debian/control.in
mv $DIRNAME/debian/libswiften.install $DIRNAME/debian/libswiften$SWIFTEN_SOVERSION.install
cat ../../../COPYING.thirdparty | tail -n +3 >> $DIRNAME/debian/copyright
-# Generate updated man-page if possible
-if type "help2man" > /dev/null 2>&1; then
- if [ -f ../../QtUI/swift-im ]; then
- help2man -m "Swift Manual" -S "Swift" -n "swift-im" -N ../../QtUI/swift-im > $DIRNAME/debian/swift-im.1
- fi
- if [ -f ../../../Swiften/Config/swiften-config ]; then
- help2man -m "Swift Manual" -S "swiften-config" -n "swiften-config" -N ../../../Swiften/Config/swiften-config > $DIRNAME/debian/swiften-config.1
- fi
-else
- >2& echo "Unable to generate man pages. Please ensure that help2man is installed"
- exit 1;
-fi
# Build
cd $DIRNAME
diff --git a/Swift/Packaging/Debian/package_all_platforms.sh b/Swift/Packaging/Debian/package_all_platforms.sh
index 097fe38..afd0621 100755
--- a/Swift/Packaging/Debian/package_all_platforms.sh
+++ b/Swift/Packaging/Debian/package_all_platforms.sh
@@ -24,9 +24,15 @@ export SWIFT_FORCE_LUCID="yep"
unset SWIFT_FORCE_LUCID
./package.sh
-for distro in xenial yakkety jessie sid; do
+if [ -z ${SWIFT_PACKAGE_PLATFORMS+x} ];
+then
+ platformsarray=( xenial artful jessie stretch sid )
+else
+ platformsarray=( $SWIFT_PACKAGE_PLATFORMS )
+fi
+
+for distro in "${platformsarray[@]}"; do
for arch in amd64; do
pbuilder-dist $distro $arch build *.dsc
done
done
-
diff --git a/Swift/Packaging/Debian/update_debian_repo.sh b/Swift/Packaging/Debian/update_debian_repo.sh
index d62a376..b057103 100644
--- a/Swift/Packaging/Debian/update_debian_repo.sh
+++ b/Swift/Packaging/Debian/update_debian_repo.sh
@@ -73,12 +73,23 @@ command -v reprepro >/dev/null 2>&1 || { echo >&2 "This script requires aptly bu
mkdir -p $APT_REPO_ROOT
+if [ -z ${SWIFT_PACKAGE_PLATFORMS+x} ]; then
+ platformsarray=( xenial artful jessie stretch sid )
+else
+ platformsarray=( $SWIFT_PACKAGE_PLATFORMS )
+fi
+
# distros
for full_distribution_path in $INCOMING_FOLDER/{debian,ubuntu}/*; do
distro_version=`basename $full_distribution_path`
distro_name=$(basename `dirname $full_distribution_path`)
distro_reprepro_root=${APT_REPO_ROOT}/${distro_name}/${distro_version}
+ if ! [[ $SWIFT_PACKAGE_PLATFORMS == *"$distro_version"* ]]; then
+ echo "$distro_version was not found in SWIFT_PACKAGE_PLATFORMS. Skipping..."
+ continue
+ fi
+
# ensure reprepro diretctory for this distribution version is present
if [ ! -d "$distro_preprepro_root" ]; then
echo "Create distribution repository for $distro_name/$distro_version"
@@ -89,7 +100,7 @@ for full_distribution_path in $INCOMING_FOLDER/{debian,ubuntu}/*; do
write_reprepo_conf_incoming_to_file "${distro_reprepro_root}/conf/incoming" "$full_distribution_path"
fi
- # This is workaround for https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=808558
+ # This is workaround for https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=808558
# and https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=843402
if [ "$distro_name/$distro_version" = "debian/sid" ]; then
sed -i '/dbgsym/ d' $full_distribution_path/*.changes
diff --git a/Swift/Packaging/SConscript b/Swift/Packaging/SConscript
new file mode 100644
index 0000000..3aa791f
--- /dev/null
+++ b/Swift/Packaging/SConscript
@@ -0,0 +1,29 @@
+Import("env")
+import os
+
+################################################################################
+# Build
+################################################################################
+
+if env["SCONS_STAGE"] == "build" :
+ help2man = env.WhereIs('help2man', os.environ['PATH'])
+ if help2man:
+ env['HELP2MAN'] = help2man
+ env['HELP2MANSTR'] = "HELP2MAN $TARGET"
+
+ if Dir("#/debian").exists():
+ # This is needed for debian packaging using pbuilder which expects
+ # generated man pages in this location.
+ env['HELP2MAN_DEBIAN_DIR'] = "#/debian"
+ else:
+ env['HELP2MAN_DEBIAN_DIR'] = "Debian/debian"
+
+ swiftenConfigHelp = env.Command(
+ target='$HELP2MAN_DEBIAN_DIR/swiften-config.1', source='#/Swiften/Config/swiften-config',
+ action = Action('$HELP2MAN --no-discard-stderr -m "Swift Manual" -S "swiften-config" -n "swiften-config" -N $SOURCE > $TARGET', cmdstr = "$HELP2MANSTR"))
+ swiftHelp = env.Command(
+ target='$HELP2MAN_DEBIAN_DIR/swift-im.1', source='#/Swift/QtUI/swift-im',
+ action = Action('$HELP2MAN --no-discard-stderr -m "Swift Manual" -S "Swift" -n "swift-im" -N $SOURCE > $TARGET', cmdstr = "$HELP2MANSTR"))
+ else:
+ print "Enabled help2man but help2man is not in the PATH of the current environment."
+ Exit(1)
diff --git a/Swift/Packaging/WiX/include.xslt b/Swift/Packaging/WiX/include.xslt
index ec1ad50..df86446 100644
--- a/Swift/Packaging/WiX/include.xslt
+++ b/Swift/Packaging/WiX/include.xslt
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
-<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:wix="http://schemas.microsoft.com/wix/2006/wi">
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:wix="http://schemas.microsoft.com/wix/2006/wi" xmlns="http://schemas.microsoft.com/wix/2006/wi" exclude-result-prefixes="xsl wix">
<xsl:template match='wix:Directory[@Id="Swift"]/@Id'>
<xsl:attribute name='Id'>INSTALLDIR</xsl:attribute>
@@ -11,4 +11,14 @@
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
+
+ <xsl:template match="wix:Component">
+ <xsl:copy>
+ <xsl:apply-templates select="@*"/>
+ <xsl:value-of select="concat(preceding-sibling::text(), ' ')" />
+ <RemoveFile Id="remove_{@Id}" Name="{@Id}" On="install" />
+ <xsl:apply-templates select="node()"/>
+ </xsl:copy>
+ </xsl:template>
+
</xsl:stylesheet>
diff --git a/Swift/QtUI/QtChatTabs.cpp b/Swift/QtUI/QtChatTabs.cpp
index ad95a07..f4d0d46 100644
--- a/Swift/QtUI/QtChatTabs.cpp
+++ b/Swift/QtUI/QtChatTabs.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2016 Isode Limited.
+ * Copyright (c) 2010-2017 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -18,8 +18,8 @@
#include <QMenu>
#include <QTabBar>
#include <QTabWidget>
-#include <QtGlobal>
#include <QWindow>
+#include <QtGlobal>
#include <Swiften/Base/Log.h>
@@ -112,8 +112,6 @@ void QtChatTabs::setViewMenu(QMenu* viewMenu) {
if (trellisMode_) {
viewMenu->addSeparator();
QAction* action = new QAction(tr("Change &layout"), this);
- action->setShortcutContext(Qt::ApplicationShortcut);
- action->setShortcut(QKeySequence(tr("Ctrl+Alt+L")));
connect(action, SIGNAL(triggered()), this, SLOT(handleOpenLayoutChangeDialog()));
viewMenu->addAction(action);
diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp
index 7051683..874f710 100644
--- a/Swift/QtUI/QtChatWindow.cpp
+++ b/Swift/QtUI/QtChatWindow.cpp
@@ -707,9 +707,9 @@ void QtChatWindow::handleEmojiClicked(QString emoji) {
if (isVisible()) {
input_->textCursor().insertText(emoji);
input_->setFocus();
- // The next line also deletes the emojisGrid_, as it was added to the
- // layout of the emojisMenu_.
- emojisMenu_.reset();
+ // We cannot delete the emojisGrid_
+ // Grid may not close yet and we should not try to destroy it.
+ emojisMenu_->setVisible(false);
}
}
diff --git a/Swift/QtUI/QtColorToolButton.cpp b/Swift/QtUI/QtColorToolButton.cpp
index b349a47..6452cf4 100644
--- a/Swift/QtUI/QtColorToolButton.cpp
+++ b/Swift/QtUI/QtColorToolButton.cpp
@@ -36,6 +36,7 @@ void QtColorToolButton::setColor(const QColor& color)
void QtColorToolButton::onClicked()
{
QColor c = QColorDialog::getColor(color_, this);
+ window()->raise();
if (c.isValid()) {
setColor(c);
}
diff --git a/Swift/QtUI/QtTabWidget.cpp b/Swift/QtUI/QtTabWidget.cpp
index 67e3ae9..99ef6ee 100644
--- a/Swift/QtUI/QtTabWidget.cpp
+++ b/Swift/QtUI/QtTabWidget.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2016 Isode Limited.
+ * Copyright (c) 2010-2017 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -57,7 +57,7 @@ void QtTabWidget::paintEvent(QPaintEvent * event) {
label.setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
label.setGeometry(QRect(QPoint(0,0), size()) - QMargins(10,10,10,10));
label.setWordWrap(true);
- label.setText(tr("This empty cell is a placeholder for chat windows. You can move existing chats to this cell by dragging the tab over here. You can change the number of cells via the 'Change layout' dialog under the 'View' menu or by using the %1 shortcut.").arg(QKeySequence(tr("Ctrl+Alt+L")).toString(QKeySequence::NativeText)));
+ label.setText(tr("This empty cell is a placeholder for chat windows. You can move existing chats to this cell by dragging the tab over here. You can change the number of cells via the 'Change layout' dialog under the 'View' menu."));
QPainter painter(this);
painter.drawPixmap(label.geometry().topLeft(), label.grab());
}
diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript
index 112a66e..54f0450 100644
--- a/Swift/QtUI/SConscript
+++ b/Swift/QtUI/SConscript
@@ -497,7 +497,7 @@ if env["PLATFORM"] == "win32" :
signresult = 0
for x in range (1, 4) :
print "Attemping to sign the packages [%s]" % x
- signresult = env.Execute('signtool.exe sign /fd SHA256 /f "${SIGNTOOL_KEY_PFX}" /t "${SIGNTOOL_TIMESTAMP_URL}" ' + str(target[0]))
+ signresult = env.Execute('signtool.exe sign /fd SHA256 /f "${SIGNTOOL_KEY_PFX}" /t "${SIGNTOOL_TIMESTAMP_URL}" /d "Swift Installer" ' + str(target[0]))
if signresult != 1 :
break
#If all 3 attemps to sign the package failed, stop the build.
diff --git a/Swift/QtUI/Trellis/QtDynamicGridLayout.cpp b/Swift/QtUI/Trellis/QtDynamicGridLayout.cpp
index b753ffa..2509b3f 100644
--- a/Swift/QtUI/Trellis/QtDynamicGridLayout.cpp
+++ b/Swift/QtUI/Trellis/QtDynamicGridLayout.cpp
@@ -144,7 +144,9 @@ void QtDynamicGridLayout::removeTab(int index) {
int tabIndex = -1;
QtTabWidget* tabWidget = indexToTabWidget(index, tabIndex);
if (tabWidget) {
+ QWidget* tab = tabWidget->widget(tabIndex);
tabWidget->removeTab(tabIndex);
+ tab->setParent(nullptr);
}
}
diff --git a/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp b/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp
index 8d15739..4489bc0 100644
--- a/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp
+++ b/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp
@@ -606,6 +606,7 @@ void QtUserSearchWindow::clear() {
howText = QString(tr("Who do you want to invite to the chat?"));
}
firstMultiJIDPage_->howLabel_->setText(howText);
+ firstMultiJIDPage_->groupBox->setEnabled(true);
}
clearForm();
resultsPage_->results_->setModel(nullptr);
diff --git a/Swift/QtUI/UserSearch/QtUserSearchWindow.h b/Swift/QtUI/UserSearch/QtUserSearchWindow.h
index 0714ac1..fe536ab 100644
--- a/Swift/QtUI/UserSearch/QtUserSearchWindow.h
+++ b/Swift/QtUI/UserSearch/QtUserSearchWindow.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2016 Isode Limited.
+ * Copyright (c) 2010-2018 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -8,6 +8,7 @@
#include <set>
+#include <QAbstractItemModel>
#include <QWizard>
#include <Swiften/Base/Override.h>
diff --git a/Swift/SConscript b/Swift/SConscript
index 863597a..b211435 100644
--- a/Swift/SConscript
+++ b/Swift/SConscript
@@ -19,3 +19,5 @@ if "Swift" in env["PROJECTS"] and env["BOOST_1_64_DETECTED"] and not env.get("al
#Version 1.64 has some issues with the serialization of boost::optional, see https://svn.boost.org/trac10/ticket/13050
print "Boost 1.64 has been detected. It is not recommended to use this version due to a regression within the library. Swift has been removed from the current build. You can still use this version by setting allow_boost_1_64 to true, but recent chats and highlighting rules will reset."
env["PROJECTS"].remove("Swift")
+if env["help2man"]:
+ SConscript("Packaging/SConscript") \ No newline at end of file
diff --git a/Swift/Translations/swift_de.ts b/Swift/Translations/swift_de.ts
index 46c313f..73e0ed8 100644
--- a/Swift/Translations/swift_de.ts
+++ b/Swift/Translations/swift_de.ts
@@ -2686,9 +2686,8 @@
<translation>&amp;Anordnung ändern</translation>
</message>
<message>
- <location filename="../QtUI/QtChatTabs.cpp" line="116"/>
<source>Ctrl+Alt+L</source>
- <translation>Ctrl+Alt+L</translation>
+ <translation type="vanished">Ctrl+Alt+L</translation>
</message>
<message>
<location filename="../QtUI/QtChatTabs.cpp" line="120"/>
@@ -3645,14 +3644,17 @@
<context>
<name>Swift::QtTabWidget</name>
<message>
- <location filename="../QtUI/QtTabWidget.cpp" line="60"/>
<source>This empty cell is a placeholder for chat windows. You can move existing chats to this cell by dragging the tab over here. You can change the number of cells via the &apos;Change layout&apos; dialog under the &apos;View&apos; menu or by using the %1 shortcut.</source>
- <translation>Diese leere Zelle ist ein Platzhalter für Chatfenster. Sie können bestehende Chatfenster zu dieser Zelle bewegen indem Sie das Tab hierher ziehen. Sie können die Anzahl von Zellen anhand des &quot;Anordnung ändern&quot; Dialogs im Menü &quot;Ansicht&quot; ändern oder indem Sie die Tastenkombination %1 nutzen.</translation>
+ <translation type="vanished">Diese leere Zelle ist ein Platzhalter für Chatfenster. Sie können bestehende Chatfenster zu dieser Zelle bewegen indem Sie das Tab hierher ziehen. Sie können die Anzahl von Zellen anhand des &quot;Anordnung ändern&quot; Dialogs im Menü &quot;Ansicht&quot; ändern oder indem Sie die Tastenkombination %1 nutzen.</translation>
</message>
<message>
- <location filename="../QtUI/QtTabWidget.cpp" line="60"/>
<source>Ctrl+Alt+L</source>
- <translation>Ctrl+Alt+L</translation>
+ <translation type="vanished">Ctrl+Alt+L</translation>
+ </message>
+ <message>
+ <location filename="../QtUI/QtTabWidget.cpp" line="60"/>
+ <source>This empty cell is a placeholder for chat windows. You can move existing chats to this cell by dragging the tab over here. You can change the number of cells via the &apos;Change layout&apos; dialog under the &apos;View&apos; menu.</source>
+ <translation>Diese leere Zelle ist ein Platzhalter für Chatfenster. Sie können bestehende Chatfenster zu dieser Zelle bewegen indem Sie das Tab hierher ziehen. Sie können die Anzahl von Zellen anhand des &quot;Anordnung ändern&quot; Dialogs im Menü &quot;Ansicht&quot; ändern.</translation>
</message>
</context>
<context>
diff --git a/Swift/Translations/swift_nl.ts b/Swift/Translations/swift_nl.ts
index 2aebf93..7b37e72 100644
--- a/Swift/Translations/swift_nl.ts
+++ b/Swift/Translations/swift_nl.ts
@@ -2137,10 +2137,6 @@ afbeelding</translation>
<translation>Wijzig &amp;opmaak</translation>
</message>
<message>
- <source>Ctrl+Alt+L</source>
- <translation>Ctrl+Alt+L</translation>
- </message>
- <message>
<source>Move Tab right</source>
<translation>Verplaats tab naar rechts</translation>
</message>
@@ -2874,12 +2870,8 @@ afbeelding</translation>
<context>
<name>Swift::QtTabWidget</name>
<message>
- <source>This empty cell is a placeholder for chat windows. You can move existing chats to this cell by dragging the tab over here. You can change the number of cells via the &apos;Change layout&apos; dialog under the &apos;View&apos; menu or by using the %1 shortcut.</source>
- <translation>Dit lege vak is vulling voor berichtenschermen. U kunt bestaande gesprekken naar dit vak verplaatsen door het tabje hier heen te slepen. U kunt het aantal vakken veranderen door middel van het &apos;Wijzig opmaak&apos;-scherm in het &apos;Beeld&apos;-menu of door middel van de %1 snelkoppeling.</translation>
- </message>
- <message>
- <source>Ctrl+Alt+L</source>
- <translation>Ctrl+Alt+L</translation>
+ <source>This empty cell is a placeholder for chat windows. You can move existing chats to this cell by dragging the tab over here. You can change the number of cells via the &apos;Change layout&apos; dialog under the &apos;View&apos; menu.</source>
+ <translation>Dit lege vak is vulling voor berichtenschermen. U kunt bestaande gesprekken naar dit vak verplaatsen door het tabje hier heen te slepen. U kunt het aantal vakken veranderen door middel van het &apos;Wijzig opmaak&apos;-scherm in het &apos;Beeld&apos;-menu.</translation>
</message>
</context>
<context>