[SCM] ktp-contact-list packaging branch, master, updated. debian/15.12.1-2-1070-g6c56f91
Maximiliano Curia
maxy at moszumanska.debian.org
Sat May 28 00:08:24 UTC 2016
Gitweb-URL: http://git.debian.org/?p=pkg-kde/applications/ktp-contact-list.git;a=commitdiff;h=264e6b1
The following commit has been merged in the master branch:
commit 264e6b1037adf41ce5c245eb695c3c4099c7ba2d
Author: Dominik Cermak <d.cermak at arcor.de>
Date: Sun Dec 25 20:06:23 2011 +0100
Support drag and drop file transfer
Now one can drop a file (or more) on a contact to start the file
transfer.
Additionally all drag and drop related code moved from the model to
here.
FEATURE: 28856
REVIEW: 103520
---
contact-list-widget.cpp | 234 +++++++++++++++++++++++++++++++++++++++++++++++-
contact-list-widget.h | 16 +++-
contact-list-widget_p.h | 8 +-
3 files changed, 252 insertions(+), 6 deletions(-)
diff --git a/contact-list-widget.cpp b/contact-list-widget.cpp
index 3d43624..7ebb38f 100644
--- a/contact-list-widget.cpp
+++ b/contact-list-widget.cpp
@@ -44,6 +44,13 @@
#include <QHeaderView>
#include <QLabel>
+#include <QApplication>
+#include <QDropEvent>
+#include <QDragMoveEvent>
+#include <QDragEnterEvent>
+#include <QDragLeaveEvent>
+#include <QPainter>
+#include <QPixmap>
#include "contact-delegate.h"
#include "contact-delegate-compact.h"
@@ -489,9 +496,16 @@ void ContactListWidget::startFileTransferChannel(ContactModelItem *contactItem)
}
QDateTime now = QDateTime::currentDateTime();
- Q_FOREACH (const QString &filename, filenames) {
- QFileInfo fileinfo(filename);
+ requestFileTransferChannels(account, contact, filenames, now);
+}
+
+void ContactListWidget::requestFileTransferChannels(const Tp::AccountPtr& account,
+ const Tp::ContactPtr& contact,
+ const QStringList& filenames,
+ const QDateTime& userActionTime)
+{
+ Q_FOREACH (const QString &filename, filenames) {
kDebug() << "Filename:" << filename;
kDebug() << "Content type:" << KMimeType::findByFileContent(filename)->name();
@@ -500,12 +514,13 @@ void ContactListWidget::startFileTransferChannel(ContactModelItem *contactItem)
Tp::PendingChannelRequest* channelRequest = account->createFileTransfer(contact,
fileTransferProperties,
- now,
+ userActionTime,
PREFERRED_FILETRANSFER_HANDLER);
connect(channelRequest, SIGNAL(finished(Tp::PendingOperation*)),
SIGNAL(genericOperationFinished(Tp::PendingOperation*)));
}
+
}
void ContactListWidget::onNewGroupModelItemsInserted(const QModelIndex& index, int start, int end)
@@ -568,3 +583,216 @@ void ContactListWidget::setFilterString(const QString& string)
d->modelFilter->setShowOfflineUsers(!string.isEmpty());
d->modelFilter->setFilterString(string);
}
+
+void ContactListWidget::setDropIndicatorRect(const QRect &rect)
+{
+ Q_D(ContactListWidget);
+
+ if (d->dropIndicatorRect != rect) {
+ d->dropIndicatorRect = rect;
+ viewport()->update();
+ }
+}
+
+void ContactListWidget::mousePressEvent(QMouseEvent *event)
+{
+ Q_D(ContactListWidget);
+
+ QTreeView::mousePressEvent(event);
+
+ QModelIndex index = indexAt(event->pos());
+ d->shouldDrag = false;
+
+ // if no contact, no drag
+ if (!index.data(AccountsModel::ItemRole).canConvert<ContactModelItem*>()) {
+ return;
+ }
+
+ if (event->button() == Qt::LeftButton) {
+ d->shouldDrag = true;
+ d->dragStartPosition = event->pos();
+ }
+}
+
+void ContactListWidget::mouseMoveEvent(QMouseEvent *event)
+{
+ Q_D(ContactListWidget);
+
+ QTreeView::mouseMoveEvent(event);
+
+ QModelIndex index = indexAt(event->pos());
+
+ if (!(event->buttons() & Qt::LeftButton)) {
+ return;
+ }
+
+ if (!d->shouldDrag) {
+ return;
+ }
+
+ if ((event->pos() - d->dragStartPosition).manhattanLength() < QApplication::startDragDistance()) {
+ return;
+ }
+
+ QMimeData *mimeData = new QMimeData;
+ QByteArray encodedData;
+ QDataStream stream(&encodedData, QIODevice::WriteOnly);
+
+ if (index.isValid()) {
+ ContactModelItem *contactItem = index.data(AccountsModel::ItemRole).value<ContactModelItem*>();
+ //We put a contact ID and its account ID to the stream, so we can later recreate the contact using AccountsModel
+ stream << contactItem->contact().data()->id() << d->model->accountForContactItem(contactItem).data()->objectPath();
+ }
+
+ mimeData->setData("application/vnd.telepathy.contact", encodedData);
+ QPixmap dragIndicator = QPixmap::grabWidget(this, visualRect(index).adjusted(3,3,3,3));
+
+ QDrag *drag = new QDrag(this);
+ drag->setMimeData(mimeData);
+ drag->setPixmap(dragIndicator);
+
+ drag->exec(Qt::CopyAction);
+}
+
+void ContactListWidget::dropEvent(QDropEvent *event)
+{
+ Q_D(ContactListWidget);
+
+ QModelIndex index = indexAt(event->pos());
+
+ if (event->mimeData()->hasUrls()) {
+ kDebug() << "It's a file!";
+
+ ContactModelItem* contactItem = index.data(AccountsModel::ItemRole).value<ContactModelItem*>();
+ Q_ASSERT(contactItem);
+
+ Tp::ContactPtr contact = contactItem->contact();
+
+ kDebug() << "Requesting file transfer for contact" << contact->alias();
+
+ Tp::AccountPtr account = d->model->accountForContactItem(contactItem);
+
+ QStringList filenames;
+ Q_FOREACH (const QUrl &url, event->mimeData()->urls()) {
+ filenames << url.toLocalFile();
+ }
+
+ if (filenames.isEmpty()) {
+ return;
+ }
+
+ QDateTime now = QDateTime::currentDateTime();
+ requestFileTransferChannels(account, contact, filenames, now);
+
+ event->acceptProposedAction();
+ } else if (event->mimeData()->hasFormat("application/vnd.telepathy.contact")) {
+ kDebug() << "It's a contact!";
+
+ QByteArray encodedData = event->mimeData()->data("application/vnd.telepathy.contact");
+ QDataStream stream(&encodedData, QIODevice::ReadOnly);
+ QList<ContactModelItem*> contacts;
+
+ while (!stream.atEnd()) {
+ QString contact;
+ QString account;
+
+ //get contact and account out of the stream
+ stream >> contact >> account;
+
+ Tp::AccountPtr accountPtr = d->model->accountPtrForPath(account);
+
+ //casted pointer is checked below, before first use
+ contacts.append(qobject_cast<ContactModelItem*>(d->model->contactItemForId(accountPtr->uniqueIdentifier(), contact)));
+ }
+
+ Q_FOREACH (ContactModelItem *contact, contacts) {
+ Q_ASSERT(contact);
+ QString group;
+ if (index.data(AccountsModel::ItemRole).canConvert<GroupsModelItem*>()) {
+ // contact is dropped on a group, so take it's name
+ group = index.data(GroupsModel::GroupNameRole).toString();
+ } else {
+ // contact is dropped on another contact, so take it's parents (group) name
+ group = index.parent().data(GroupsModel::GroupNameRole).toString();
+ }
+
+ kDebug() << contact->contact().data()->alias() << "added to group" << group;
+
+ Tp::PendingOperation *op = contact->contact().data()->addToGroup(group);
+
+ connect(op, SIGNAL(finished(Tp::PendingOperation*)),
+ this, SIGNAL(genericOperationFinished(Tp::PendingOperation*)));
+ }
+ event->acceptProposedAction();
+ } else {
+ event->ignore();
+ }
+
+ setDropIndicatorRect(QRect());
+}
+
+void ContactListWidget::dragEnterEvent(QDragEnterEvent *event)
+{
+ if (event->mimeData()->hasUrls()) {
+ bool accepted = true;
+ // check if one of the urls isn't a local file and abort if so
+ Q_FOREACH (const QUrl& url, event->mimeData()->urls()) {
+ if (!QFileInfo(url.toLocalFile()).isFile()) {
+ accepted = false;
+ }
+ }
+
+ if (accepted) {
+ event->acceptProposedAction();
+ } else {
+ event->ignore();
+ }
+ } else if (event->mimeData()->hasFormat("application/vnd.telepathy.contact")) {
+ event->acceptProposedAction();
+ } else {
+ event->ignore();
+ }
+}
+
+void ContactListWidget::dragMoveEvent(QDragMoveEvent *event)
+{
+ Q_D(ContactListWidget);
+
+ QModelIndex index = indexAt(event->pos());
+ setDropIndicatorRect(QRect());
+
+ // urls can be dropped on a contact with file transfer capability,
+ // contacts can be dropped either on a group or on another contact if GroupsModel is used
+ if (event->mimeData()->hasUrls() && index.data(AccountsModel::FileTransferCapabilityRole).toBool()) {
+ event->acceptProposedAction();
+ setDropIndicatorRect(visualRect(index));
+ } else if (event->mimeData()->hasFormat("application/vnd.telepathy.contact") &&
+ d->modelFilter->sourceModel() == d->groupsModel &&
+ (index.data(AccountsModel::ItemRole).canConvert<GroupsModelItem*>() ||
+ index.data(AccountsModel::ItemRole).canConvert<ContactModelItem*>())) {
+ event->acceptProposedAction();
+ setDropIndicatorRect(visualRect(index));
+ } else {
+ event->ignore();
+ }
+}
+
+void ContactListWidget::dragLeaveEvent(QDragLeaveEvent *event)
+{
+ Q_UNUSED(event);
+ setDropIndicatorRect(QRect());
+}
+
+void ContactListWidget::paintEvent(QPaintEvent *event)
+{
+ Q_D(ContactListWidget);
+
+ QTreeView::paintEvent(event);
+ if (!d->dropIndicatorRect.isNull()) {
+ QStyleOption option;
+ option.init(this);
+ option.rect = d->dropIndicatorRect.adjusted(0,0,-1,-1);
+ QPainter painter(viewport());
+ style()->drawPrimitive(QStyle::PE_IndicatorItemViewItemDrop, &option, &painter, this);
+ }
+}
diff --git a/contact-list-widget.h b/contact-list-widget.h
index 85cac2a..067fc12 100644
--- a/contact-list-widget.h
+++ b/contact-list-widget.h
@@ -77,9 +77,23 @@ Q_SIGNALS:
void accountManagerReady(Tp::PendingOperation* op);
void genericOperationFinished(Tp::PendingOperation* op);
+protected:
+ void setDropIndicatorRect(const QRect &rect);
+ virtual void mousePressEvent(QMouseEvent *event);
+ virtual void mouseMoveEvent(QMouseEvent *event);
+ virtual void paintEvent(QPaintEvent *event);
+ virtual void dropEvent(QDropEvent *event);
+ virtual void dragEnterEvent(QDragEnterEvent *event);
+ virtual void dragMoveEvent(QDragMoveEvent *event);
+ virtual void dragLeaveEvent(QDragLeaveEvent *event);
+
private:
- friend class ContextMenu;
+ void requestFileTransferChannels(const Tp::AccountPtr& account,
+ const Tp::ContactPtr& contact,
+ const QStringList& filenames,
+ const QDateTime& userActionTime);
+ friend class ContextMenu;
ContactListWidgetPrivate * const d_ptr;
};
diff --git a/contact-list-widget_p.h b/contact-list-widget_p.h
index 9f99146..a7c22f5 100644
--- a/contact-list-widget_p.h
+++ b/contact-list-widget_p.h
@@ -35,7 +35,8 @@ public:
groupsModel(0),
modelFilter(0),
delegate(0),
- compactDelegate(0) {}
+ compactDelegate(0),
+ shouldDrag(false) {}
AccountsModel *model;
GroupsModel *groupsModel;
@@ -43,6 +44,9 @@ public:
Tp::AccountManagerPtr accountManager;
ContactDelegate *delegate;
ContactDelegateCompact *compactDelegate;
+ QRect dropIndicatorRect;
+ QPoint dragStartPosition;
+ bool shouldDrag;
};
-#endif //CONTACT_LIST_WIDGET_P_H
\ No newline at end of file
+#endif //CONTACT_LIST_WIDGET_P_H
--
ktp-contact-list packaging
More information about the pkg-kde-commits
mailing list