File indexing completed on 2024-05-12 05:47:41
0001 /* 0002 * SPDX-FileCopyrightText: 2006-2010 Peter Penz <peter.penz19@gmail.com> 0003 * SPDX-FileCopyrightText: 2006 Cvetoslav Ludmiloff <ludmiloff@gmail.com> 0004 * 0005 * SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "treeviewcontextmenu.h" 0009 0010 #include "folderspanel.h" 0011 #include "global.h" 0012 0013 #include <KConfigGroup> 0014 #include <KFileItemListProperties> 0015 #include <KIO/CopyJob> 0016 #include <KIO/DeleteOrTrashJob> 0017 #include <KIO/Paste> 0018 #include <KIO/PasteJob> 0019 #include <KJobWidgets> 0020 #include <KLocalizedString> 0021 #include <KPropertiesDialog> 0022 #include <KSharedConfig> 0023 #include <KUrlMimeData> 0024 0025 #include <QApplication> 0026 #include <QClipboard> 0027 #include <QMenu> 0028 #include <QMimeData> 0029 #include <QPointer> 0030 0031 TreeViewContextMenu::TreeViewContextMenu(FoldersPanel *parent, const KFileItem &fileInfo) 0032 : QObject(parent) 0033 , m_parent(parent) 0034 , m_fileItem(fileInfo) 0035 { 0036 } 0037 0038 TreeViewContextMenu::~TreeViewContextMenu() 0039 { 0040 } 0041 0042 void TreeViewContextMenu::open(const QPoint &pos) 0043 { 0044 QMenu *popup = new QMenu(m_parent); 0045 0046 if (!m_fileItem.isNull()) { 0047 KFileItemListProperties capabilities(KFileItemList() << m_fileItem); 0048 0049 // insert 'Cut', 'Copy' and 'Paste' 0050 QAction *cutAction = new QAction(QIcon::fromTheme(QStringLiteral("edit-cut")), i18nc("@action:inmenu", "Cut"), this); 0051 cutAction->setEnabled(capabilities.supportsMoving()); 0052 connect(cutAction, &QAction::triggered, this, &TreeViewContextMenu::cut); 0053 0054 QAction *copyAction = new QAction(QIcon::fromTheme(QStringLiteral("edit-copy")), i18nc("@action:inmenu", "Copy"), this); 0055 connect(copyAction, &QAction::triggered, this, &TreeViewContextMenu::copy); 0056 0057 const QMimeData *mimeData = QApplication::clipboard()->mimeData(); 0058 bool canPaste; 0059 const QString text = KIO::pasteActionText(mimeData, &canPaste, m_fileItem); 0060 QAction *pasteAction = new QAction(QIcon::fromTheme(QStringLiteral("edit-paste")), text, this); 0061 connect(pasteAction, &QAction::triggered, this, &TreeViewContextMenu::paste); 0062 pasteAction->setEnabled(canPaste); 0063 0064 popup->addAction(cutAction); 0065 popup->addAction(copyAction); 0066 popup->addAction(pasteAction); 0067 popup->addSeparator(); 0068 0069 // insert 'Rename' 0070 QAction *renameAction = new QAction(i18nc("@action:inmenu", "Renameā¦"), this); 0071 renameAction->setEnabled(capabilities.supportsMoving()); 0072 renameAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-rename"))); 0073 connect(renameAction, &QAction::triggered, this, &TreeViewContextMenu::rename); 0074 popup->addAction(renameAction); 0075 0076 // insert 'Move to Trash' and (optionally) 'Delete' 0077 KSharedConfig::Ptr globalConfig = KSharedConfig::openConfig(QStringLiteral("kdeglobals"), KConfig::IncludeGlobals); 0078 KConfigGroup configGroup(globalConfig, QStringLiteral("KDE")); 0079 bool showDeleteCommand = configGroup.readEntry("ShowDeleteCommand", false); 0080 0081 const QUrl url = m_fileItem.url(); 0082 if (url.isLocalFile()) { 0083 QAction *moveToTrashAction = new QAction(QIcon::fromTheme(QStringLiteral("user-trash")), i18nc("@action:inmenu", "Move to Trash"), this); 0084 const bool enableMoveToTrash = capabilities.isLocal() && capabilities.supportsMoving(); 0085 moveToTrashAction->setEnabled(enableMoveToTrash); 0086 connect(moveToTrashAction, &QAction::triggered, this, &TreeViewContextMenu::moveToTrash); 0087 popup->addAction(moveToTrashAction); 0088 } else { 0089 showDeleteCommand = true; 0090 } 0091 0092 if (showDeleteCommand) { 0093 QAction *deleteAction = new QAction(QIcon::fromTheme(QStringLiteral("edit-delete")), i18nc("@action:inmenu", "Delete"), this); 0094 deleteAction->setEnabled(capabilities.supportsDeleting()); 0095 connect(deleteAction, &QAction::triggered, this, &TreeViewContextMenu::deleteItem); 0096 popup->addAction(deleteAction); 0097 } 0098 0099 popup->addSeparator(); 0100 } 0101 0102 // insert 'Show Hidden Files' 0103 QAction *showHiddenFilesAction = new QAction(i18nc("@action:inmenu", "Show Hidden Files"), this); 0104 showHiddenFilesAction->setCheckable(true); 0105 showHiddenFilesAction->setChecked(m_parent->showHiddenFiles()); 0106 popup->addAction(showHiddenFilesAction); 0107 connect(showHiddenFilesAction, &QAction::toggled, this, &TreeViewContextMenu::setShowHiddenFiles); 0108 0109 if (!m_fileItem.isNull()) { 0110 // insert 'Limit to Home Directory' 0111 const QUrl url = m_fileItem.url(); 0112 const bool enableLimitToHomeDirectory = url.isLocalFile(); 0113 QAction *limitFoldersPanelToHomeAction = new QAction(i18nc("@action:inmenu", "Limit to Home Directory"), this); 0114 limitFoldersPanelToHomeAction->setCheckable(true); 0115 limitFoldersPanelToHomeAction->setEnabled(enableLimitToHomeDirectory); 0116 limitFoldersPanelToHomeAction->setChecked(m_parent->limitFoldersPanelToHome()); 0117 popup->addAction(limitFoldersPanelToHomeAction); 0118 connect(limitFoldersPanelToHomeAction, &QAction::toggled, this, &TreeViewContextMenu::setLimitFoldersPanelToHome); 0119 } 0120 0121 // insert 'Automatic Scrolling' 0122 QAction *autoScrollingAction = new QAction(i18nc("@action:inmenu", "Automatic Scrolling"), this); 0123 autoScrollingAction->setCheckable(true); 0124 autoScrollingAction->setChecked(m_parent->autoScrolling()); 0125 // TODO: Temporary disabled. Horizontal autoscrolling will be implemented later either 0126 // in KItemViews or manually as part of the FoldersPanel 0127 //popup->addAction(autoScrollingAction); 0128 connect(autoScrollingAction, &QAction::toggled, this, &TreeViewContextMenu::setAutoScrolling); 0129 0130 if (!m_fileItem.isNull()) { 0131 // insert 'Properties' entry 0132 QAction *propertiesAction = new QAction(i18nc("@action:inmenu", "Properties"), this); 0133 propertiesAction->setIcon(QIcon::fromTheme(QStringLiteral("document-properties"))); 0134 connect(propertiesAction, &QAction::triggered, this, &TreeViewContextMenu::showProperties); 0135 popup->addAction(propertiesAction); 0136 } 0137 0138 const QList<QAction *> customActions = m_parent->customContextMenuActions(); 0139 if (!customActions.isEmpty()) { 0140 popup->addSeparator(); 0141 for (QAction *action : customActions) { 0142 popup->addAction(action); 0143 } 0144 } 0145 0146 QPointer<QMenu> popupPtr = popup; 0147 popup->exec(pos); 0148 if (popupPtr.data()) { 0149 popupPtr.data()->deleteLater(); 0150 } 0151 } 0152 0153 void TreeViewContextMenu::populateMimeData(QMimeData *mimeData, bool cut) 0154 { 0155 QList<QUrl> kdeUrls; 0156 kdeUrls.append(m_fileItem.url()); 0157 QList<QUrl> mostLocalUrls; 0158 bool dummy; 0159 mostLocalUrls.append(m_fileItem.mostLocalUrl(&dummy)); 0160 KIO::setClipboardDataCut(mimeData, cut); 0161 KUrlMimeData::exportUrlsToPortal(mimeData); 0162 KUrlMimeData::setUrls(kdeUrls, mostLocalUrls, mimeData); 0163 } 0164 0165 void TreeViewContextMenu::cut() 0166 { 0167 QMimeData *mimeData = new QMimeData(); 0168 populateMimeData(mimeData, true); 0169 QApplication::clipboard()->setMimeData(mimeData); 0170 } 0171 0172 void TreeViewContextMenu::copy() 0173 { 0174 QMimeData *mimeData = new QMimeData(); 0175 populateMimeData(mimeData, false); 0176 QApplication::clipboard()->setMimeData(mimeData); 0177 } 0178 0179 void TreeViewContextMenu::paste() 0180 { 0181 KIO::PasteJob *job = KIO::paste(QApplication::clipboard()->mimeData(), m_fileItem.url()); 0182 KJobWidgets::setWindow(job, m_parent); 0183 } 0184 0185 void TreeViewContextMenu::rename() 0186 { 0187 m_parent->rename(m_fileItem); 0188 } 0189 0190 void TreeViewContextMenu::moveToTrash() 0191 { 0192 using Iface = KIO::AskUserActionInterface; 0193 auto *deleteJob = new KIO::DeleteOrTrashJob(QList{m_fileItem.url()}, Iface::Trash, Iface::DefaultConfirmation, m_parent); 0194 deleteJob->start(); 0195 } 0196 0197 void TreeViewContextMenu::deleteItem() 0198 { 0199 using Iface = KIO::AskUserActionInterface; 0200 auto *deleteJob = new KIO::DeleteOrTrashJob(QList{m_fileItem.url()}, Iface::Delete, Iface::DefaultConfirmation, m_parent); 0201 deleteJob->start(); 0202 } 0203 0204 void TreeViewContextMenu::showProperties() 0205 { 0206 KPropertiesDialog *dialog = new KPropertiesDialog(m_fileItem.url(), m_parent); 0207 dialog->setAttribute(Qt::WA_DeleteOnClose); 0208 dialog->show(); 0209 } 0210 0211 void TreeViewContextMenu::setShowHiddenFiles(bool show) 0212 { 0213 m_parent->setShowHiddenFiles(show); 0214 } 0215 0216 void TreeViewContextMenu::setLimitFoldersPanelToHome(bool enable) 0217 { 0218 m_parent->setLimitFoldersPanelToHome(enable); 0219 } 0220 0221 void TreeViewContextMenu::setAutoScrolling(bool enable) 0222 { 0223 m_parent->setAutoScrolling(enable); 0224 } 0225 0226 #include "moc_treeviewcontextmenu.cpp"