diff options
Diffstat (limited to 'Swift/QtUI')
| -rw-r--r-- | Swift/QtUI/ChatList/ChatListModel.cpp | 42 | ||||
| -rw-r--r-- | Swift/QtUI/ChatList/ChatListModel.h | 4 | ||||
| -rw-r--r-- | Swift/QtUI/ChatList/QtChatListWindow.cpp | 27 | ||||
| -rw-r--r-- | Swift/QtUI/ChatList/QtChatListWindow.h | 3 | ||||
| -rw-r--r-- | Swift/QtUI/QtChatWindow.cpp | 20 | ||||
| -rw-r--r-- | Swift/QtUI/Roster/RosterModel.cpp | 11 | ||||
| -rw-r--r-- | Swift/QtUI/UserSearch/ContactListModel.cpp | 43 | ||||
| -rw-r--r-- | Swift/QtUI/UserSearch/ContactListModel.h | 7 | ||||
| -rw-r--r-- | Swift/QtUI/UserSearch/QtContactListWidget.cpp | 23 | ||||
| -rw-r--r-- | Swift/QtUI/UserSearch/QtContactListWidget.h | 9 | ||||
| -rw-r--r-- | Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.cpp | 40 | ||||
| -rw-r--r-- | Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.h | 11 | ||||
| -rw-r--r-- | Swift/QtUI/UserSearch/QtUserSearchWindow.cpp | 25 | ||||
| -rw-r--r-- | Swift/QtUI/UserSearch/QtUserSearchWindow.h | 3 |
14 files changed, 177 insertions, 91 deletions
diff --git a/Swift/QtUI/ChatList/ChatListModel.cpp b/Swift/QtUI/ChatList/ChatListModel.cpp index 7913c61..d09b0dd 100644 --- a/Swift/QtUI/ChatList/ChatListModel.cpp +++ b/Swift/QtUI/ChatList/ChatListModel.cpp @@ -1,36 +1,48 @@ /* - * Copyright (c) 2010-2011 Kevin Smith + * Copyright (c) 2010-2014 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #include <Swift/QtUI/ChatList/ChatListModel.h> +#include <QMimeData> +#include <QUrl> + #include <Swift/QtUI/ChatList/ChatListMUCItem.h> #include <Swift/QtUI/ChatList/ChatListRecentItem.h> #include <Swift/QtUI/ChatList/ChatListWhiteboardItem.h> +#include <Swift/QtUI/QtSwiftUtil.h> namespace Swift { ChatListModel::ChatListModel() : whiteboards_(NULL) { root_ = new ChatListGroupItem("", NULL, false); mucBookmarks_ = new ChatListGroupItem(tr("Bookmarked Rooms"), root_); recents_ = new ChatListGroupItem(tr("Recent Chats"), root_, false); #ifdef SWIFT_EXPERIMENTAL_WB whiteboards_ = new ChatListGroupItem(tr("Opened Whiteboards"), root_, false); root_->addItem(whiteboards_); #endif root_->addItem(recents_); root_->addItem(mucBookmarks_); } +Qt::ItemFlags ChatListModel::flags(const QModelIndex& index) const { + Qt::ItemFlags flags = QAbstractItemModel::flags(index); + if (dynamic_cast<ChatListRecentItem*>(getItemForIndex(index))) { + flags |= Qt::ItemIsDragEnabled; + } + return flags; +} + void ChatListModel::clearBookmarks() { emit layoutAboutToBeChanged(); mucBookmarks_->clear(); emit layoutChanged(); } void ChatListModel::addMUCBookmark(const Swift::MUCBookmark& bookmark) { emit layoutAboutToBeChanged(); mucBookmarks_->addItem(new ChatListMUCItem(bookmark, mucBookmarks_)); @@ -74,18 +86,46 @@ void ChatListModel::setRecents(const std::list<ChatListWindow::Chat>& recents) { emit layoutAboutToBeChanged(); recents_->clear(); foreach (const ChatListWindow::Chat chat, recents) { recents_->addItem(new ChatListRecentItem(chat, recents_)); //whiteboards_->addItem(new ChatListRecentItem(chat, whiteboards_)); } emit layoutChanged(); } +QMimeData* ChatListModel::mimeData(const QModelIndexList& indexes) const { + QMimeData* data = QAbstractItemModel::mimeData(indexes); + ChatListRecentItem *item = dynamic_cast<ChatListRecentItem*>(getItemForIndex(indexes.first())); + if (item == NULL) { + return data; + } + + QByteArray itemData; + QDataStream dataStream(&itemData, QIODevice::WriteOnly); + const ChatListWindow::Chat& chat = item->getChat(); + + QString mimeType = "application/vnd.swift.contact-jid-list"; + if (!chat.impromptuJIDs.size()) { + if (chat.isMUC) { + mimeType = "application/vnd.swift.contact-jid-muc"; + } + dataStream << P2QSTRING(chat.jid.toString()); + } else { + typedef std::map<std::string, JID> JIDMap; + foreach (const JIDMap::value_type& jid, chat.impromptuJIDs) { + dataStream << P2QSTRING(jid.second.toString()); + } + } + + data->setData(mimeType, itemData); + return data; +} + int ChatListModel::columnCount(const QModelIndex& /*parent*/) const { return 1; } ChatListItem* ChatListModel::getItemForIndex(const QModelIndex& index) const { return index.isValid() ? static_cast<ChatListItem*>(index.internalPointer()) : NULL; } QVariant ChatListModel::data(const QModelIndex& index, int role) const { diff --git a/Swift/QtUI/ChatList/ChatListModel.h b/Swift/QtUI/ChatList/ChatListModel.h index 04e369a..a15cbcd 100644 --- a/Swift/QtUI/ChatList/ChatListModel.h +++ b/Swift/QtUI/ChatList/ChatListModel.h @@ -1,11 +1,11 @@ /* - * Copyright (c) 2010-2011 Kevin Smith + * Copyright (c) 2010-2014 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #pragma once #include <QAbstractItemModel> #include <QList> @@ -13,29 +13,31 @@ #include <Swift/Controllers/UIInterfaces/ChatListWindow.h> #include <Swift/QtUI/ChatList/ChatListGroupItem.h> namespace Swift { class ChatListModel : public QAbstractItemModel { Q_OBJECT public: ChatListModel(); + Qt::ItemFlags flags(const QModelIndex& index) const; void addMUCBookmark(const MUCBookmark& bookmark); void removeMUCBookmark(const MUCBookmark& bookmark); void addWhiteboardSession(const ChatListWindow::Chat& chat); void removeWhiteboardSession(const JID& jid); int columnCount(const QModelIndex& parent = QModelIndex()) const; QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const; QModelIndex parent(const QModelIndex& index) const; int rowCount(const QModelIndex& parent = QModelIndex()) const; ChatListItem* getItemForIndex(const QModelIndex& index) const; void clearBookmarks(); void setRecents(const std::list<ChatListWindow::Chat>& recents); + QMimeData* mimeData(const QModelIndexList& indexes) const; private: ChatListGroupItem* mucBookmarks_; ChatListGroupItem* recents_; ChatListGroupItem* whiteboards_; ChatListGroupItem* root_; }; } diff --git a/Swift/QtUI/ChatList/QtChatListWindow.cpp b/Swift/QtUI/ChatList/QtChatListWindow.cpp index 4d1f19b..7455fb5 100644 --- a/Swift/QtUI/ChatList/QtChatListWindow.cpp +++ b/Swift/QtUI/ChatList/QtChatListWindow.cpp @@ -1,54 +1,56 @@ /* - * Copyright (c) 2010-2011 Kevin Smith + * Copyright (c) 2010-2014 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #include "Swift/QtUI/ChatList/QtChatListWindow.h" #include <boost/bind.hpp> -#include <QMenu> #include <QContextMenuEvent> +#include <QMenu> +#include <QMimeData> +#include <QUrl> +#include <Swift/Controllers/Settings/SettingsProvider.h> +#include <Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h> +#include <Swift/Controllers/UIEvents/EditMUCBookmarkUIEvent.h> +#include <Swift/Controllers/UIEvents/JoinMUCUIEvent.h> +#include <Swift/Controllers/UIEvents/RemoveMUCBookmarkUIEvent.h> +#include <Swift/Controllers/UIEvents/RequestChatUIEvent.h> +#include <Swift/Controllers/UIEvents/ShowWhiteboardUIEvent.h> #include <Swift/QtUI/ChatList/ChatListMUCItem.h> #include <Swift/QtUI/ChatList/ChatListRecentItem.h> #include <Swift/QtUI/ChatList/ChatListWhiteboardItem.h> #include <Swift/QtUI/QtAddBookmarkWindow.h> #include <Swift/QtUI/QtEditBookmarkWindow.h> #include <Swift/QtUI/QtUISettingConstants.h> -#include <Swift/Controllers/UIEvents/JoinMUCUIEvent.h> -#include <Swift/Controllers/UIEvents/RequestChatUIEvent.h> -#include <Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h> -#include <Swift/Controllers/UIEvents/RemoveMUCBookmarkUIEvent.h> -#include <Swift/Controllers/UIEvents/EditMUCBookmarkUIEvent.h> -#include <Swift/Controllers/UIEvents/ShowWhiteboardUIEvent.h> -#include <Swift/Controllers/Settings/SettingsProvider.h> - namespace Swift { QtChatListWindow::QtChatListWindow(UIEventStream *uiEventStream, SettingsProvider* settings, QWidget* parent) : QTreeView(parent) { eventStream_ = uiEventStream; settings_ = settings; bookmarksEnabled_ = false; model_ = new ChatListModel(); setModel(model_); delegate_ = new ChatListDelegate(settings_->getSetting(QtUISettingConstants::COMPACT_ROSTER)); setItemDelegate(delegate_); setHeaderHidden(true); #ifdef SWIFT_PLATFORM_MACOSX setAlternatingRowColors(true); #endif expandAll(); setAnimated(true); setIndentation(0); + setDragEnabled(true); setRootIsDecorated(true); setupContextMenus(); connect(this, SIGNAL(activated(const QModelIndex&)), this, SLOT(handleItemActivated(const QModelIndex&))); connect(this, SIGNAL(clicked(const QModelIndex&)), this, SLOT(handleClicked(const QModelIndex&))); settings_->onSettingChanged.connect(boost::bind(&QtChatListWindow::handleSettingChanged, this, _1)); } QtChatListWindow::~QtChatListWindow() { @@ -146,18 +148,23 @@ void QtChatListWindow::handleAddBookmark() { void QtChatListWindow::handleEditBookmark() { ChatListMUCItem* mucItem = dynamic_cast<ChatListMUCItem*>(contextMenuItem_); if (!mucItem) return; QtEditBookmarkWindow* window = new QtEditBookmarkWindow(eventStream_, mucItem->getBookmark()); window->show(); } +void QtChatListWindow::dragEnterEvent(QDragEnterEvent *event) { + if (event->mimeData()->hasUrls() && event->mimeData()->urls().size() == 1) { + event->acceptProposedAction(); + } +} void QtChatListWindow::contextMenuEvent(QContextMenuEvent* event) { QModelIndex index = indexAt(event->pos()); ChatListItem* baseItem = index.isValid() ? static_cast<ChatListItem*>(index.internalPointer()) : NULL; contextMenuItem_ = baseItem; if (!baseItem) { emptyMenu_->exec(QCursor::pos()); return; } diff --git a/Swift/QtUI/ChatList/QtChatListWindow.h b/Swift/QtUI/ChatList/QtChatListWindow.h index ef4ce0f..e218266 100644 --- a/Swift/QtUI/ChatList/QtChatListWindow.h +++ b/Swift/QtUI/ChatList/QtChatListWindow.h @@ -1,11 +1,11 @@ /* - * Copyright (c) 2010-2011 Kevin Smith + * Copyright (c) 2010-2014 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #pragma once #include <QTreeView> #include "Swift/Controllers/UIInterfaces/ChatListWindow.h" @@ -34,18 +34,19 @@ namespace Swift { private slots: void handleItemActivated(const QModelIndex&); void handleAddBookmark(); void handleEditBookmark(); void handleRemoveBookmark(); void handleClicked(const QModelIndex& index); void handleSettingChanged(const std::string& setting); protected: + void dragEnterEvent(QDragEnterEvent* event); void contextMenuEvent(QContextMenuEvent* event); private: void setupContextMenus(); bool bookmarksEnabled_; UIEventStream* eventStream_; ChatListModel* model_; ChatListDelegate* delegate_; QMenu* mucMenu_; diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp index bd7c817..d3cce6d 100644 --- a/Swift/QtUI/QtChatWindow.cpp +++ b/Swift/QtUI/QtChatWindow.cpp @@ -1,11 +1,11 @@ /* - * Copyright (c) 2010-2013 Kevin Smith + * Copyright (c) 2010-2014 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #include <Swift/QtUI/QtChatWindow.h> #include <boost/cstdint.hpp> #include <boost/lexical_cast.hpp> #include <boost/smart_ptr/make_shared.hpp> @@ -25,18 +25,19 @@ #include <QMimeData> #include <QPushButton> #include <QSplitter> #include <QString> #include <QTextDocument> #include <QTextEdit> #include <QTime> #include <QToolButton> #include <QUrl> +#include <QMimeData> #include <Swiften/Base/Log.h> #include <Swift/Controllers/Roster/ContactRosterItem.h> #include <Swift/Controllers/Roster/Roster.h> #include <Swift/Controllers/Roster/RosterItem.h> #include <Swift/Controllers/Settings/SettingsProvider.h> #include <Swift/Controllers/UIEvents/UIEventStream.h> #include <Swift/Controllers/UIEvents/SendFileUIEvent.h> @@ -534,45 +535,48 @@ void QtChatWindow::moveEvent(QMoveEvent*) { emit geometryChanged(); } void QtChatWindow::dragEnterEvent(QDragEnterEvent *event) { if (event->mimeData()->hasUrls() && event->mimeData()->urls().size() == 1) { // TODO: check whether contact actually supports file transfer if (!isMUC_) { event->acceptProposedAction(); } - } else if (event->mimeData()->hasFormat("application/vnd.swift.contact-jid")) { + } else if (event->mimeData()->hasFormat("application/vnd.swift.contact-jid-list")) { if (isMUC_ || supportsImpromptuChat_) { event->acceptProposedAction(); } } } void QtChatWindow::dropEvent(QDropEvent *event) { if (event->mimeData()->hasUrls()) { if (event->mimeData()->urls().size() == 1) { onSendFileRequest(Q2PSTRING(event->mimeData()->urls().at(0).toLocalFile())); } else { std::string messageText(Q2PSTRING(tr("Sending of multiple files at once isn't supported at this time."))); ChatMessage message; message.append(boost::make_shared<ChatTextMessagePart>(messageText)); addSystemMessage(message, DefaultDirection); } - } else if (event->mimeData()->hasFormat("application/vnd.swift.contact-jid")) { - QByteArray dataBytes = event->mimeData()->data("application/vnd.swift.contact-jid"); + } else if (event->mimeData()->hasFormat("application/vnd.swift.contact-jid-list")) { + QByteArray dataBytes = event->mimeData()->data("application/vnd.swift.contact-jid-list"); QDataStream dataStream(&dataBytes, QIODevice::ReadOnly); - QString jidString; - dataStream >> jidString; - onInviteToChat(std::vector<JID>(1, JID(Q2PSTRING(jidString)))); + std::vector<JID> invites; + while (!dataStream.atEnd()) { + QString jidString; + dataStream >> jidString; + invites.push_back(Q2PSTRING(jidString)); + } + onInviteToChat(invites); } } - void QtChatWindow::setAvailableOccupantActions(const std::vector<OccupantAction>& actions) { treeWidget_->setAvailableOccupantActions(actions); } void QtChatWindow::setSubject(const std::string& subject) { //subject_->setVisible(!subject.empty()); subject_->setText(P2QSTRING(subject)); subject_->setToolTip(P2QSTRING(subject)); subject_->setCursorPosition(0); diff --git a/Swift/QtUI/Roster/RosterModel.cpp b/Swift/QtUI/Roster/RosterModel.cpp index 2bd0d09..d8108ba 100644 --- a/Swift/QtUI/Roster/RosterModel.cpp +++ b/Swift/QtUI/Roster/RosterModel.cpp @@ -1,11 +1,11 @@ /* - * Copyright (c) 2010-2013 Kevin Smith + * Copyright (c) 2010-2014 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #include <Swift/QtUI/Roster/RosterModel.h> #include <boost/bind.hpp> #include <QColor> @@ -257,23 +257,18 @@ int RosterModel::rowCount(const QModelIndex& parent) const { QMimeData* RosterModel::mimeData(const QModelIndexList& indexes) const { QMimeData* data = QAbstractItemModel::mimeData(indexes); ContactRosterItem *item = dynamic_cast<ContactRosterItem*>(getItem(indexes.first())); if (item == NULL) { return data; } + /* only a single JID in this list */ QByteArray itemData; QDataStream dataStream(&itemData, QIODevice::WriteOnly); - - // jid, chatName, activity, statusType, avatarPath dataStream << P2QSTRING(item->getJID().toString()); - dataStream << P2QSTRING(item->getDisplayName()); - dataStream << P2QSTRING(item->getStatusText()); - dataStream << item->getSimplifiedStatusShow(); - dataStream << P2QSTRING(item->getAvatarPath().string()); - data->setData("application/vnd.swift.contact-jid", itemData); + data->setData("application/vnd.swift.contact-jid-list", itemData); return data; } } diff --git a/Swift/QtUI/UserSearch/ContactListModel.cpp b/Swift/QtUI/UserSearch/ContactListModel.cpp index 4c4a3ea..907142f 100644 --- a/Swift/QtUI/UserSearch/ContactListModel.cpp +++ b/Swift/QtUI/UserSearch/ContactListModel.cpp @@ -1,15 +1,21 @@ /* * Copyright (c) 2013 Tobias Markmann * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ +/* + * Copyright (c) 2014 Kevin Smith and Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + #include <Swift/QtUI/UserSearch/ContactListModel.h> #include <QMimeData> #include <Swiften/Base/Path.h> #include <Swiften/Base/foreach.h> #include <Swiften/Elements/StatusShow.h> #include <Swift/QtUI/QtSwiftUtil.h> @@ -76,55 +82,18 @@ QVariant ContactListModel::data(const QModelIndex& index, int role) const { if (role == Qt::EditRole) { return P2QSTRING(contact.jid.toString()); } return dataForContact(contact, role); } else { return QVariant(); } } -bool ContactListModel::dropMimeData(const QMimeData* data, Qt::DropAction /*action*/, int /*row*/, int /*column*/, const QModelIndex& /*parent*/) { - if (!data->hasFormat("application/vnd.swift.contact-jid")) { - return false; - } - - QByteArray dataBytes = data->data("application/vnd.swift.contact-jid"); - QDataStream dataStream(&dataBytes, QIODevice::ReadOnly); - QString jidString; - QString displayName; - QString statusText; - StatusShow::Type statusType; - QString avatarPath; - - dataStream >> jidString; - dataStream >> displayName; - dataStream >> statusText; - dataStream >> statusType; - dataStream >> avatarPath; - - JID jid = JID(Q2PSTRING(jidString)); - - foreach(const Contact& contact, contacts_) { - if (contact.jid == jid) { - return false; - } - } - - emit layoutAboutToBeChanged(); - contacts_.push_back(Contact(Q2PSTRING(displayName), jid, statusType, Q2PSTRING(avatarPath))); - emit layoutChanged(); - - onJIDsDropped(std::vector<JID>(1, jid)); - onListChanged(getList()); - - return true; -} - QModelIndex ContactListModel::index(int row, int column, const QModelIndex& parent) const { if (!hasIndex(row, column, parent)) { return QModelIndex(); } return boost::numeric_cast<size_t>(row) < contacts_.size() ? createIndex(row, column, (void*)&(contacts_[row])) : QModelIndex(); } QModelIndex ContactListModel::parent(const QModelIndex& index) const { diff --git a/Swift/QtUI/UserSearch/ContactListModel.h b/Swift/QtUI/UserSearch/ContactListModel.h index e7f4a0b..6ca505e 100644 --- a/Swift/QtUI/UserSearch/ContactListModel.h +++ b/Swift/QtUI/UserSearch/ContactListModel.h @@ -1,15 +1,21 @@ /* * Copyright (c) 2013 Tobias Markmann * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ +/* + * Copyright (c) 2014 Kevin Smith and Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + #pragma once #include <vector> #include <boost/bind.hpp> #include <Swiften/Base/boost_bsignals.h> #include <QAbstractItemModel> #include <Swift/Controllers/Contact.h> @@ -30,19 +36,18 @@ namespace Swift { public: ContactListModel(bool editable); void setList(const std::vector<Contact>& list); const std::vector<Contact>& getList() const; Qt::ItemFlags flags(const QModelIndex& index) const; int columnCount(const QModelIndex& parent = QModelIndex()) const; QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; - bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent); QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const; QModelIndex parent(const QModelIndex& index) const; int rowCount(const QModelIndex& parent = QModelIndex()) const; bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex()); private: QVariant dataForContact(const Contact& contact, int role) const; QIcon getPresenceIconForContact(const Contact& contact) const; diff --git a/Swift/QtUI/UserSearch/QtContactListWidget.cpp b/Swift/QtUI/UserSearch/QtContactListWidget.cpp index 90adc11..6ad1169 100644 --- a/Swift/QtUI/UserSearch/QtContactListWidget.cpp +++ b/Swift/QtUI/UserSearch/QtContactListWidget.cpp @@ -1,40 +1,42 @@ /* * Copyright (c) 2013 Tobias Markmann * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ +/* + * Copyright (c) 2014 Kevin Smith and Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + #include <Swift/QtUI/UserSearch/QtContactListWidget.h> #include <Swift/QtUI/UserSearch/ContactListModel.h> #include <Swift/QtUI/UserSearch/ContactListDelegate.h> #include <Swift/QtUI/QtUISettingConstants.h> #include <Swift/Controllers/Settings/SettingsProvider.h> #include <Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.h> #include <QHeaderView> namespace Swift { QtContactListWidget::QtContactListWidget(QWidget* parent, SettingsProvider* settings) : QTreeView(parent), settings_(settings), limited_(false) { contactListModel_ = new ContactListModel(true); setModel(contactListModel_); - connect(contactListModel_, SIGNAL(onListChanged(std::vector<Contact>)), this, SLOT(handleListChanged(std::vector<Contact>))); connect(contactListModel_, SIGNAL(onListChanged(std::vector<Contact>)), this, SIGNAL(onListChanged(std::vector<Contact>))); connect(contactListModel_, SIGNAL(onJIDsDropped(std::vector<JID>)), this, SIGNAL(onJIDsAdded(std::vector<JID>))); setSelectionMode(QAbstractItemView::SingleSelection); setSelectionBehavior(QAbstractItemView::SelectRows); - setDragEnabled(true); - setAcceptDrops(true); - setDropIndicatorShown(true); setUniformRowHeights(true); setAlternatingRowColors(true); setIndentation(0); setHeaderHidden(true); setExpandsOnDoubleClick(false); setItemsExpandable(false); setEditTriggers(QAbstractItemView::DoubleClicked); @@ -63,42 +65,29 @@ void QtContactListWidget::setList(const std::vector<Contact>& list) { contactListModel_->setList(list); } std::vector<Contact> QtContactListWidget::getList() const { return contactListModel_->getList(); } void QtContactListWidget::setMaximumNoOfContactsToOne(bool limited) { limited_ = limited; - if (limited) { - handleListChanged(getList()); - } else { - setAcceptDrops(true); - setDropIndicatorShown(true); - } } void QtContactListWidget::updateContacts(const std::vector<Contact>& contactUpdates) { std::vector<Contact> contacts = contactListModel_->getList(); foreach(const Contact& contactUpdate, contactUpdates) { for(size_t n = 0; n < contacts.size(); n++) { if (contactUpdate.jid == contacts[n].jid) { contacts[n] = contactUpdate; break; } } } contactListModel_->setList(contacts); } -void QtContactListWidget::handleListChanged(std::vector<Contact> list) { - if (limited_) { - setAcceptDrops(list.size() <= 1); - setDropIndicatorShown(list.size() <= 1); - } -} - void QtContactListWidget::handleSettingsChanged(const std::string&) { contactListDelegate_->setCompact(settings_->getSetting(QtUISettingConstants::COMPACT_ROSTER)); } } diff --git a/Swift/QtUI/UserSearch/QtContactListWidget.h b/Swift/QtUI/UserSearch/QtContactListWidget.h index f360a91..a83b47a 100644 --- a/Swift/QtUI/UserSearch/QtContactListWidget.h +++ b/Swift/QtUI/UserSearch/QtContactListWidget.h @@ -1,15 +1,21 @@ /* * Copyright (c) 2013 Tobias Markmann * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ +/* + * Copyright (c) 2014 Kevin Smith and Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + #pragma once #include <vector> #include <QTreeView> #include <Swift/Controllers/Contact.h> #include <Swiften/Base/Log.h> @@ -35,21 +41,18 @@ public: void setMaximumNoOfContactsToOne(bool limited); public slots: void updateContacts(const std::vector<Contact>& contactUpdates); signals: void onListChanged(std::vector<Contact> list); void onJIDsAdded(const std::vector<JID>& jids); -private slots: - void handleListChanged(std::vector<Contact> list); - private: void handleSettingsChanged(const std::string&); private: SettingsProvider* settings_; ContactListModel* contactListModel_; ContactListDelegate* contactListDelegate_; QtRemovableItemDelegate* removableItemDelegate_; bool limited_; diff --git a/Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.cpp b/Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.cpp index b1e9a12..360ce0a 100644 --- a/Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.cpp +++ b/Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.cpp @@ -1,20 +1,30 @@ /* * Copyright (c) 2013 Tobias Markmann * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ +/* + * Copyright (c) 2014 Kevin Smith and Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + #include "Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.h" +#include <QMessageBox> +#include <QMimeData> +#include <QUrl> + #include "Swift/QtUI/QtSwiftUtil.h" -#include <Swift/QtUI/UserSearch/QtContactListWidget.h> #include <Swift/Controllers/Settings/SettingsProvider.h> +#include <Swift/QtUI/UserSearch/QtContactListWidget.h> #include <Swift/QtUI/UserSearch/QtSuggestingJIDInput.h> namespace Swift { QtUserSearchFirstMultiJIDPage::QtUserSearchFirstMultiJIDPage(UserSearchWindow::Type type, const QString& title, SettingsProvider* settings) { setupUi(this); setTitle(title); QString introText = ""; switch (type) { @@ -33,24 +43,52 @@ QtUserSearchFirstMultiJIDPage::QtUserSearchFirstMultiJIDPage(UserSearchWindow::T contactList_ = new QtContactListWidget(this, settings); horizontalLayout_5->addWidget(contactList_); jid_ = new QtSuggestingJIDInput(this, settings); horizontalLayout_6->insertWidget(0, jid_); connect(contactList_, SIGNAL(onListChanged(std::vector<Contact>)), this, SLOT(emitCompletenessCheck())); connect(jid_, SIGNAL(editingDone()), this, SLOT(handleEditingDone())); + + setAcceptDrops(true); } bool QtUserSearchFirstMultiJIDPage::isComplete() const { return !contactList_->getList().empty(); } void QtUserSearchFirstMultiJIDPage::emitCompletenessCheck() { emit completeChanged(); } void QtUserSearchFirstMultiJIDPage::handleEditingDone() { addContactButton_->setFocus(); } +void QtUserSearchFirstMultiJIDPage::dragEnterEvent(QDragEnterEvent *event) { + if (event->mimeData()->hasFormat("application/vnd.swift.contact-jid-list") + || event->mimeData()->hasFormat("application/vnd.swift.contact-jid-muc")) { + event->acceptProposedAction(); + } +} + +void QtUserSearchFirstMultiJIDPage::dropEvent(QDropEvent *event) { + if (event->mimeData()->hasFormat("application/vnd.swift.contact-jid-list")) { + QByteArray dataBytes = event->mimeData()->data("application/vnd.swift.contact-jid-list"); + QDataStream dataStream(&dataBytes, QIODevice::ReadOnly); + std::vector<JID> jids; + while (!dataStream.atEnd()) { + QString jidString; + dataStream >> jidString; + jids.push_back(Q2PSTRING(jidString)); + } + onJIDsDropped(jids); + } else if (event->mimeData()->hasFormat("application/vnd.swift.contact-jid-muc")) { + QMessageBox* messageBox = new QMessageBox(this); + messageBox->setText(tr("You can't invite a room to chat.")); + messageBox->setWindowTitle(tr("Error inviting room to chat")); + messageBox->show(); + } +} + } diff --git a/Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.h b/Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.h index 427995e..9905f21 100644 --- a/Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.h +++ b/Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.h @@ -1,15 +1,21 @@ /* * Copyright (c) 2013 Tobias Markmann * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ +/* + * Copyright (c) 2014 Kevin Smith and Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + #pragma once #include <QWizardPage> #include <Swift/QtUI/UserSearch/ui_QtUserSearchFirstMultiJIDPage.h> #include <Swift/Controllers/UIInterfaces/UserSearchWindow.h> namespace Swift { class UserSearchModel; @@ -23,18 +29,23 @@ namespace Swift { class SettingsProvider; class QtSuggestingJIDInput; class QtUserSearchFirstMultiJIDPage : public QWizardPage, public Ui::QtUserSearchFirstMultiJIDPage { Q_OBJECT public: QtUserSearchFirstMultiJIDPage(UserSearchWindow::Type type, const QString& title, SettingsProvider* settings); virtual bool isComplete() const; + signals: + void onJIDsDropped(std::vector<JID> jid); + public slots: void emitCompletenessCheck(); void handleEditingDone(); + virtual void dragEnterEvent(QDragEnterEvent *event); + virtual void dropEvent(QDropEvent *event); public: QtContactListWidget* contactList_; QtSuggestingJIDInput* jid_; }; } diff --git a/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp b/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp index c0c7972..ec5dd39 100644 --- a/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp +++ b/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp @@ -1,11 +1,11 @@ /* - * Copyright (c) 2010-2013 Kevin Smith + * Copyright (c) 2010-2014 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #include "Swift/QtUI/UserSearch/QtUserSearchWindow.h" #include <QItemDelegate> #include <QModelIndex> #include <QWizardPage> @@ -371,32 +371,52 @@ void QtUserSearchWindow::setCanStartImpromptuChats(bool supportsImpromptu) { } } void QtUserSearchWindow::updateContacts(const std::vector<Contact>& contacts) { if (type_ != AddContact) { firstMultiJIDPage_->contactList_->updateContacts(contacts); } } +void QtUserSearchWindow::addContacts(const std::vector<Contact>& contacts) { + if (type_ != AddContact) { + /* prevent duplicate JIDs from appearing in the contact list */ + foreach (const Contact& newContact, contacts) { + bool found = false; + foreach (const Contact& oldContact, contactVector_) { + if (newContact.jid == oldContact.jid) { + found = true; + break; + } + } + if (!found) { + contactVector_.push_back(newContact); + } + } + firstMultiJIDPage_->contactList_->setList(contactVector_); + firstMultiJIDPage_->emitCompletenessCheck(); + } +} + void QtUserSearchWindow::handleAddViaSearch() { searchNext_ = true; next(); } void QtUserSearchWindow::handleListChanged(std::vector<Contact> list) { contactVector_ = list; if (type_ == ChatToContact) { firstMultiJIDPage_->groupBox->setEnabled(supportsImpromptu_ ? 1 : (contactVector_.size() < 1)); } } void QtUserSearchWindow::handleJIDsAdded(std::vector<JID> jids) { - onJIDUpdateRequested(jids); + onJIDAddRequested(jids); } void QtUserSearchWindow::setResults(const std::vector<UserSearchResult>& results) { UserSearchModel *newModel = new UserSearchModel(); newModel->setResults(results); resultsPage_->results_->setModel(newModel); resultsPage_->results_->setItemDelegate(delegate_); resultsPage_->results_->setHeaderHidden(true); delete model_; @@ -443,18 +463,19 @@ void QtUserSearchWindow::setFirstPage(QString title) { setPage(1, firstPage_); } else { firstMultiJIDPage_ = new QtUserSearchFirstMultiJIDPage(type_, title.isEmpty() ? firstMultiJIDPage_->title() : title, settings_); connect(firstMultiJIDPage_->addContactButton_, SIGNAL(clicked()), this, SLOT(addContact())); connect(firstMultiJIDPage_->jid_, SIGNAL(textEdited(QString)), this, SLOT(handleContactSuggestionRequested(QString))); firstMultiJIDPage_->jid_->onUserSelected.connect(boost::bind(&QtUserSearchWindow::addSearchedJIDToList, this, _1)); connect(firstMultiJIDPage_->addViaSearchButton_, SIGNAL(clicked()), this, SLOT(handleAddViaSearch())); connect(firstMultiJIDPage_->contactList_, SIGNAL(onListChanged(std::vector<Contact>)), this, SLOT(handleListChanged(std::vector<Contact>))); connect(firstMultiJIDPage_->contactList_, SIGNAL(onJIDsAdded(std::vector<JID>)), this, SLOT(handleJIDsAdded(std::vector<JID>))); + connect(firstMultiJIDPage_, SIGNAL(onJIDsDropped(std::vector<JID>)), this, SLOT(handleJIDsAdded(std::vector<JID>))); setPage(1, firstMultiJIDPage_); } } void QtUserSearchWindow::setSecondPage() { if (page(2) != 0) { removePage(2); } fieldsPage_ = new QtUserSearchFieldsPage(); diff --git a/Swift/QtUI/UserSearch/QtUserSearchWindow.h b/Swift/QtUI/UserSearch/QtUserSearchWindow.h index e5a9f80..941e455 100644 --- a/Swift/QtUI/UserSearch/QtUserSearchWindow.h +++ b/Swift/QtUI/UserSearch/QtUserSearchWindow.h @@ -1,11 +1,11 @@ /* - * Copyright (c) 2010 Kevin Smith + * Copyright (c) 2010-2014 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #pragma once #include <QWizard> #include <set> @@ -44,18 +44,19 @@ namespace Swift { virtual void setNameSuggestions(const std::vector<std::string>& suggestions); virtual void prepopulateJIDAndName(const JID& jid, const std::string& name); virtual void setContactSuggestions(const std::vector<Contact>& suggestions); virtual void setJIDs(const std::vector<JID> &jids); virtual void setRoomJID(const JID &roomJID); virtual std::string getReason() const; virtual std::vector<JID> getJIDs() const; virtual void setCanStartImpromptuChats(bool supportsImpromptu); virtual void updateContacts(const std::vector<Contact> &contacts); + virtual void addContacts(const std::vector<Contact>& contacts); protected: virtual int nextId() const; private slots: void handleFirstPageRadioChange(); virtual void handleCurrentChanged(int); virtual void handleAccepted(); void handleContactSuggestionRequested(const QString& text); |
Swift