File indexing completed on 2024-05-12 09:47:44
0001 /*************************************************************************** 0002 * Copyright (C) 2005-2009 by Rajko Albrecht ral@alwins-world.de * 0003 * https://kde.org/applications/development/org.kde.kdesvn * 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 <QAbstractProxyModel> 0026 #include <QAction> 0027 #include <QApplication> 0028 #include <QDrag> 0029 #include <QDropEvent> 0030 #include <QMenu> 0031 #include <QMimeData> 0032 0033 #include <KIconLoader> 0034 #include <KLocalizedString> 0035 #include <KUrlMimeData> 0036 0037 void SvnTreeView::startDrag(Qt::DropActions supportedActions) 0038 { 0039 // only one dragging at time 0040 static bool isDrag = false; 0041 if (isDrag) { 0042 return; 0043 } 0044 isDrag = true; 0045 const QModelIndexList indexes = selectionModel()->selectedRows(); 0046 if (!indexes.isEmpty()) { 0047 QMimeData *data = model()->mimeData(indexes); 0048 if (data == nullptr) { 0049 isDrag = false; 0050 return; 0051 } 0052 QDrag *drag = new QDrag(this); 0053 QPixmap pixmap; 0054 if (indexes.count() == 1) { 0055 QAbstractProxyModel *proxyModel = static_cast<QAbstractProxyModel *>(model()); 0056 SvnItemModel *itemModel = static_cast<SvnItemModel *>(proxyModel->sourceModel()); 0057 const QModelIndex index = proxyModel->mapToSource(indexes.first()); 0058 0059 SvnItemModelNode *item = itemModel->nodeForIndex(index); 0060 pixmap = item->getPixmap(KIconLoader::SizeMedium, false); 0061 } else { 0062 pixmap = QIcon::fromTheme(QStringLiteral("document-multiple")).pixmap(KIconLoader::SizeMedium, KIconLoader::SizeMedium); 0063 } 0064 drag->setPixmap(pixmap); 0065 drag->setMimeData(data); 0066 drag->exec(supportedActions, Qt::IgnoreAction); 0067 } 0068 isDrag = false; 0069 } 0070 0071 void SvnTreeView::dropEvent(QDropEvent *event) 0072 { 0073 if (!event->mimeData()->hasUrls()) { 0074 return; 0075 } 0076 0077 QAbstractProxyModel *proxyModel = static_cast<QAbstractProxyModel *>(model()); 0078 0079 const QModelIndex index = indexAt(event->pos()); 0080 const QModelIndex index2(index.isValid() ? proxyModel->mapToSource(index) : QModelIndex()); 0081 0082 QMap<QString, QString> metaMap; 0083 Qt::DropAction action = event->dropAction(); 0084 const QList<QUrl> list = KUrlMimeData::urlsFromMimeData(event->mimeData(), KUrlMimeData::PreferLocalUrls, &metaMap); 0085 bool intern = false; 0086 if (metaMap.contains(QStringLiteral("kdesvn-source"))) { 0087 SvnItemModel *itemModel = static_cast<SvnItemModel *>(proxyModel->sourceModel()); 0088 QMap<QString, QString>::const_iterator it = metaMap.constFind(QStringLiteral("kdesvn-id")); 0089 if (it != metaMap.constEnd() && it.value() == itemModel->uniqueIdentifier()) { 0090 intern = true; 0091 } 0092 } 0093 0094 Qt::KeyboardModifiers modifiers = QGuiApplication::keyboardModifiers(); 0095 QMetaObject::invokeMethod(this, 0096 "doDrop", 0097 Q_ARG(QList<QUrl>, list), 0098 Q_ARG(QModelIndex, index2), 0099 Q_ARG(bool, intern), 0100 Q_ARG(Qt::DropAction, action), 0101 Q_ARG(Qt::KeyboardModifiers, modifiers)); 0102 event->acceptProposedAction(); 0103 } 0104 0105 void SvnTreeView::doDrop(const QList<QUrl> &list, const QModelIndex &parent, bool intern, Qt::DropAction action, Qt::KeyboardModifiers modifiers) 0106 { 0107 if (intern && ((modifiers & Qt::ControlModifier) == 0) && ((modifiers & Qt::ShiftModifier) == 0)) { 0108 QMenu popup; 0109 QString seq = QKeySequence(Qt::ShiftModifier).toString(); 0110 seq.chop(1); // chop superfluous '+' 0111 QAction *popupMoveAction = new QAction(i18n("&Move Here") + QLatin1Char('\t') + seq, this); 0112 popupMoveAction->setIcon(QIcon::fromTheme(QStringLiteral("go-jump"))); 0113 seq = QKeySequence(Qt::ControlModifier).toString(); 0114 seq.chop(1); 0115 QAction *popupCopyAction = new QAction(i18n("&Copy Here") + QLatin1Char('\t') + seq, this); 0116 popupCopyAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-copy"))); 0117 QAction *popupCancelAction = new QAction(i18n("C&ancel") + QLatin1Char('\t') + QKeySequence(Qt::Key_Escape).toString(), this); 0118 popupCancelAction->setIcon(QIcon::fromTheme(QStringLiteral("process-stop"))); 0119 0120 popup.addAction(popupMoveAction); 0121 popup.addAction(popupCopyAction); 0122 popup.addSeparator(); 0123 popup.addAction(popupCancelAction); 0124 QAction *result = popup.exec(QCursor::pos()); 0125 0126 if (result == popupCopyAction) { 0127 action = Qt::CopyAction; 0128 } else if (result == popupMoveAction) { 0129 action = Qt::MoveAction; 0130 } else if (result == popupCancelAction || !result) { 0131 return; 0132 } 0133 } 0134 0135 QAbstractProxyModel *proxyModel = static_cast<QAbstractProxyModel *>(model()); 0136 SvnItemModel *itemModel = static_cast<SvnItemModel *>(proxyModel->sourceModel()); 0137 QModelIndex _p; 0138 if (!parent.isValid() && (_p = rootIndex()).isValid()) { 0139 QAbstractProxyModel *proxyModel = static_cast<QAbstractProxyModel *>(model()); 0140 _p = proxyModel->mapToSource(_p); 0141 } else { 0142 _p = parent; 0143 } 0144 itemModel->dropUrls(list, action, parent.row(), parent.column(), _p, intern); 0145 } 0146 0147 #include "moc_svntreeview.cpp"