File indexing completed on 2024-05-12 17:16:18
0001 /*************************************************************************** 0002 * Copyright (C) 2005-2009 by Rajko Albrecht ral@alwins-world.de * 0003 * http://kdesvn.alwins-world.de/ * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License * 0016 * along with this program; if not, write to the * 0017 * Free Software Foundation, Inc., * 0018 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 0019 ***************************************************************************/ 0020 0021 #include "svntreeview.h" 0022 #include "models/svnitemmodel.h" 0023 #include "models/svnitemnode.h" 0024 0025 #include <QDrag> 0026 #include <QAbstractProxyModel> 0027 #include <QDropEvent> 0028 #include <QApplication> 0029 #include <QAction> 0030 #include <QMenu> 0031 #include <QMimeData> 0032 0033 #include <KIconLoader> 0034 #include <KLocalizedString> 0035 #include <KUrlMimeData> 0036 0037 SvnTreeView::SvnTreeView(QWidget *parent) 0038 : QTreeView(parent) 0039 { 0040 0041 } 0042 0043 SvnTreeView::~SvnTreeView() 0044 { 0045 } 0046 0047 void SvnTreeView::startDrag(Qt::DropActions supportedActions) 0048 { 0049 // only one dragging at time 0050 static bool isDrag = false; 0051 if (isDrag) { 0052 return; 0053 } 0054 isDrag = true; 0055 const QModelIndexList indexes = selectionModel()->selectedRows(); 0056 if (!indexes.isEmpty()) { 0057 QMimeData *data = model()->mimeData(indexes); 0058 if (data == nullptr) { 0059 isDrag = false; 0060 return; 0061 } 0062 QDrag *drag = new QDrag(this); 0063 QPixmap pixmap; 0064 if (indexes.count() == 1) { 0065 QAbstractProxyModel *proxyModel = static_cast<QAbstractProxyModel *>(model()); 0066 SvnItemModel *itemModel = static_cast<SvnItemModel *>(proxyModel->sourceModel()); 0067 const QModelIndex index = proxyModel->mapToSource(indexes.first()); 0068 0069 SvnItemModelNode *item = itemModel->nodeForIndex(index); 0070 pixmap = item->getPixmap(KIconLoader::SizeMedium, false); 0071 } else { 0072 pixmap = QIcon::fromTheme(QStringLiteral("document-multiple")).pixmap(KIconLoader::SizeMedium, KIconLoader::SizeMedium); 0073 } 0074 drag->setPixmap(pixmap); 0075 drag->setMimeData(data); 0076 drag->exec(supportedActions, Qt::IgnoreAction); 0077 } 0078 isDrag = false; 0079 } 0080 0081 void SvnTreeView::dropEvent(QDropEvent *event) 0082 { 0083 if (!event->mimeData()->hasUrls()) { 0084 return; 0085 } 0086 0087 QAbstractProxyModel *proxyModel = static_cast<QAbstractProxyModel *>(model()); 0088 0089 const QModelIndex index = indexAt(event->pos()); 0090 const QModelIndex index2(index.isValid() ? proxyModel->mapToSource(index) : QModelIndex()); 0091 0092 QMap<QString, QString> metaMap; 0093 Qt::DropAction action = event->dropAction(); 0094 const QList<QUrl> list = KUrlMimeData::urlsFromMimeData(event->mimeData(), KUrlMimeData::PreferLocalUrls, &metaMap); 0095 bool intern = false; 0096 if (metaMap.contains(QStringLiteral("kdesvn-source"))) { 0097 SvnItemModel *itemModel = static_cast<SvnItemModel *>(proxyModel->sourceModel()); 0098 QMap<QString, QString>::const_iterator it = metaMap.constFind(QStringLiteral("kdesvn-id")); 0099 if (it != metaMap.constEnd() && it.value() == itemModel->uniqueIdentifier()) { 0100 intern = true; 0101 } 0102 } 0103 0104 Qt::KeyboardModifiers modifiers = QGuiApplication::keyboardModifiers(); 0105 QMetaObject::invokeMethod(this, "doDrop", 0106 Q_ARG(QList<QUrl>, list), 0107 Q_ARG(QModelIndex, index2), 0108 Q_ARG(bool, intern), 0109 Q_ARG(Qt::DropAction, action), 0110 Q_ARG(Qt::KeyboardModifiers, modifiers) 0111 ); 0112 event->acceptProposedAction(); 0113 } 0114 0115 void SvnTreeView::doDrop(const QList<QUrl> &list, const QModelIndex &parent, bool intern, Qt::DropAction action, Qt::KeyboardModifiers modifiers) 0116 { 0117 if (intern && ((modifiers & Qt::ControlModifier) == 0) && 0118 ((modifiers & Qt::ShiftModifier) == 0)) { 0119 0120 QMenu popup; 0121 QString seq = QKeySequence(Qt::ShiftModifier).toString(); 0122 seq.chop(1); // chop superfluous '+' 0123 QAction *popupMoveAction = new QAction(i18n("&Move Here") + QLatin1Char('\t') + seq, this); 0124 popupMoveAction->setIcon(QIcon::fromTheme(QStringLiteral("go-jump"))); 0125 seq = QKeySequence(Qt::ControlModifier).toString(); 0126 seq.chop(1); 0127 QAction *popupCopyAction = new QAction(i18n("&Copy Here") + QLatin1Char('\t') + seq, this); 0128 popupCopyAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-copy"))); 0129 QAction *popupCancelAction = new QAction(i18n("C&ancel") + QLatin1Char('\t') + QKeySequence(Qt::Key_Escape).toString(), this); 0130 popupCancelAction->setIcon(QIcon::fromTheme(QStringLiteral("process-stop"))); 0131 0132 popup.addAction(popupMoveAction); 0133 popup.addAction(popupCopyAction); 0134 popup.addSeparator(); 0135 popup.addAction(popupCancelAction); 0136 QAction *result = popup.exec(QCursor::pos()); 0137 0138 if (result == popupCopyAction) { 0139 action = Qt::CopyAction; 0140 } else if (result == popupMoveAction) { 0141 action = Qt::MoveAction; 0142 } else if (result == popupCancelAction || !result) { 0143 return; 0144 } 0145 } 0146 0147 QAbstractProxyModel *proxyModel = static_cast<QAbstractProxyModel *>(model()); 0148 SvnItemModel *itemModel = static_cast<SvnItemModel *>(proxyModel->sourceModel()); 0149 QModelIndex _p; 0150 if (!parent.isValid() && (_p = rootIndex()).isValid()) { 0151 QAbstractProxyModel *proxyModel = static_cast<QAbstractProxyModel *>(model()); 0152 _p = proxyModel->mapToSource(_p); 0153 } else { 0154 _p = parent; 0155 } 0156 itemModel->dropUrls(list, action, parent.row(), parent.column(), _p, intern); 0157 }