diff --git a/containments/desktop/plugins/folder/CMakeLists.txt b/containments/desktop/plugins/folder/CMakeLists.txt index 55d3119fb..6a766a925 100644 --- a/containments/desktop/plugins/folder/CMakeLists.txt +++ b/containments/desktop/plugins/folder/CMakeLists.txt @@ -1,39 +1,37 @@ include_directories(plasmaquick) -include_directories(internallibkonq) set(folderplugin_SRCS directorypicker.cpp foldermodel.cpp folderplugin.cpp itemviewadapter.cpp labelgenerator.cpp menuhelper.cpp mimetypesmodel.cpp placesmodel.cpp positioner.cpp previewpluginsmodel.cpp rubberband.cpp subdialog.cpp textfix.cpp viewpropertiesmenu.cpp wheelinterceptor.cpp - internallibkonq/konq_popupmenu.cpp shortcut.cpp ) install(FILES qmldir DESTINATION ${QML_INSTALL_DIR}/org/kde/private/desktopcontainment/folder) add_library(folderplugin SHARED ${folderplugin_SRCS}) target_link_libraries(folderplugin Qt5::Core Qt5::Qml Qt5::Quick KF5::KIOCore KF5::KIOWidgets KF5::KIOFileWidgets KF5::I18n KF5::PlasmaQuick KF5::ConfigGui) install(TARGETS folderplugin DESTINATION ${QML_INSTALL_DIR}/org/kde/private/desktopcontainment/folder) diff --git a/containments/desktop/plugins/folder/foldermodel.cpp b/containments/desktop/plugins/folder/foldermodel.cpp index 9e88aa99a..ed8d6f35c 100644 --- a/containments/desktop/plugins/folder/foldermodel.cpp +++ b/containments/desktop/plugins/folder/foldermodel.cpp @@ -1,1466 +1,1519 @@ /*************************************************************************** * Copyright (C) 2006 David Faure * * Copyright (C) 2008 Fredrik Höglund * * Copyright (C) 2008 Rafael Fernández López * * Copyright (C) 2011 Marco Martin * * Copyright (C) 2014 by Eike Hein * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ #include "foldermodel.h" #include "itemviewadapter.h" #include "positioner.h" #include #include #include #include #include #include #include +#include #include #include #include #include #include #include #include -#include "internallibkonq/konq_popupmenu.h" #include #include #include -#include #include +#include #include #include #include #include #include #include #include #include #include #include +#include #include #include +#include #include #include #include #include #include #include #include #include #include DirLister::DirLister(QObject *parent) : KDirLister(parent) { } DirLister:: ~DirLister() { } void DirLister::handleError(KIO::Job *job) { if (!autoErrorHandlingEnabled()) { emit error(job->errorString()); return; } KDirLister::handleError(job); } FolderModel::FolderModel(QObject *parent) : QSortFilterProxyModel(parent), m_dirWatch(nullptr), m_dragInProgress(false), m_previewGenerator(0), m_viewAdapter(0), m_actionCollection(this), m_newMenu(0), m_fileItemActions(0), m_usedByContainment(false), m_locked(true), m_sortMode(0), m_sortDesc(false), m_sortDirsFirst(true), m_parseDesktopFiles(false), m_previews(false), m_filterMode(NoFilter), m_filterPatternMatchAll(true) { DirLister *dirLister = new DirLister(this); dirLister->setDelayedMimeTypes(true); dirLister->setAutoErrorHandlingEnabled(false, 0); connect(dirLister, &DirLister::error, this, &FolderModel::dirListFailed); connect(dirLister, &KCoreDirLister::itemsDeleted, this, &FolderModel::evictFromIsDirCache); m_dirModel = new KDirModel(this); m_dirModel->setDirLister(dirLister); m_dirModel->setDropsAllowed(KDirModel::DropOnDirectory | KDirModel::DropOnLocalExecutable); m_selectionModel = new QItemSelectionModel(this, this); connect(m_selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(selectionChanged(QItemSelection,QItemSelection))); setSourceModel(m_dirModel); setSortLocaleAware(true); setFilterCaseSensitivity(Qt::CaseInsensitive); setDynamicSortFilter(true); sort(m_sortMode, m_sortDesc ? Qt::DescendingOrder : Qt::AscendingOrder); setSupportedDragActions(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction); createActions(); } FolderModel::~FolderModel() { } QHash< int, QByteArray > FolderModel::roleNames() const { return staticRoleNames(); } QHash< int, QByteArray > FolderModel::staticRoleNames() { QHash roleNames; roleNames[Qt::DisplayRole] = "display"; roleNames[Qt::DecorationRole] = "decoration"; roleNames[BlankRole] = "blank"; roleNames[SelectedRole] = "selected"; roleNames[IsDirRole] = "isDir"; roleNames[UrlRole] = "url"; roleNames[LinkDestinationUrl] = "linkDestinationUrl"; roleNames[SizeRole] = "size"; roleNames[TypeRole] = "type"; return roleNames; } QString FolderModel::url() const { return m_url; } void FolderModel::setUrl(const QString& url) { const QUrl &resolvedUrl = resolve(url); if (url == m_url) { m_dirModel->dirLister()->updateDirectory(resolvedUrl); return; } beginResetModel(); m_url = url; m_isDirCache.clear(); m_dirModel->dirLister()->openUrl(resolvedUrl); clearDragImages(); endResetModel(); emit urlChanged(); emit resolvedUrlChanged(); m_errorString.clear(); emit errorStringChanged(); if (m_dirWatch) { delete m_dirWatch; } if (resolvedUrl.isLocalFile()) { m_dirWatch = new KDirWatch(this); connect(m_dirWatch, &KDirWatch::created, this, &FolderModel::iconNameChanged); connect(m_dirWatch, &KDirWatch::dirty, this, &FolderModel::iconNameChanged); m_dirWatch->addFile(resolvedUrl.toLocalFile() + QLatin1String("/.directory")); } emit iconNameChanged(); } QUrl FolderModel::resolvedUrl() const { return m_dirModel->dirLister()->url(); } QUrl FolderModel::resolve(const QString& url) { QUrl resolvedUrl; if (url.startsWith('~')) { resolvedUrl = QUrl::fromLocalFile(KShell::tildeExpand(url)); } else { resolvedUrl = QUrl::fromUserInput(url); } return resolvedUrl; } QString FolderModel::iconName() const { const KFileItem rootItem(m_dirModel->dirLister()->url()); if (!rootItem.isFinalIconKnown()) { rootItem.determineMimeType(); } return rootItem.iconName(); } QString FolderModel::errorString() const { return m_errorString; } bool FolderModel::usedByContainment() const { return m_usedByContainment; } void FolderModel::setUsedByContainment(bool used) { if (m_usedByContainment != used) { m_usedByContainment = used; QAction *action = m_actionCollection.action(QStringLiteral("refresh")); if (action) { action->setText(m_usedByContainment ? i18n("&Refresh Desktop") : i18n("&Refresh View")); action->setIcon(m_usedByContainment ? QIcon::fromTheme(QStringLiteral("user-desktop")) : QIcon::fromTheme(QStringLiteral("view-refresh"))); } emit usedByContainmentChanged(); } } bool FolderModel::locked() const { return m_locked; } void FolderModel::setLocked(bool locked) { if (m_locked != locked) { m_locked = locked; emit lockedChanged(); } } void FolderModel::dirListFailed(const QString& error) { m_errorString = error; emit errorStringChanged(); } int FolderModel::sortMode() const { return m_sortMode; } void FolderModel::setSortMode(int mode) { if (m_sortMode != mode) { m_sortMode = mode; if (mode == -1 /* Unsorted */) { setDynamicSortFilter(false); } else { invalidate(); sort(m_sortMode, m_sortDesc ? Qt::DescendingOrder : Qt::AscendingOrder); setDynamicSortFilter(true); } emit sortModeChanged(); } } bool FolderModel::sortDesc() const { return m_sortDesc; } void FolderModel::setSortDesc(bool desc) { if (m_sortDesc != desc) { m_sortDesc = desc; if (m_sortMode != -1 /* Unsorted */) { invalidate(); sort(m_sortMode, m_sortDesc ? Qt::DescendingOrder : Qt::AscendingOrder); } emit sortDescChanged(); } } bool FolderModel::sortDirsFirst() const { return m_sortDirsFirst; } void FolderModel::setSortDirsFirst(bool enable) { if (m_sortDirsFirst != enable) { m_sortDirsFirst = enable; if (m_sortMode != -1 /* Unsorted */) { invalidate(); sort(m_sortMode, m_sortDesc ? Qt::DescendingOrder : Qt::AscendingOrder); } emit sortDirsFirstChanged(); } } bool FolderModel::parseDesktopFiles() const { return m_parseDesktopFiles; } void FolderModel::setParseDesktopFiles(bool enable) { if (m_parseDesktopFiles != enable) { m_parseDesktopFiles = enable; emit parseDesktopFilesChanged(); } } QObject* FolderModel::viewAdapter() const { return m_viewAdapter; } void FolderModel::setViewAdapter(QObject* adapter) { if (m_viewAdapter != adapter) { KAbstractViewAdapter *abstractViewAdapter = dynamic_cast(adapter); m_viewAdapter = abstractViewAdapter; if (m_viewAdapter && !m_previewGenerator) { m_previewGenerator = new KFilePreviewGenerator(abstractViewAdapter, this); m_previewGenerator->setPreviewShown(m_previews); m_previewGenerator->setEnabledPlugins(m_previewPlugins); } emit viewAdapterChanged(); } } bool FolderModel::previews() const { return m_previews; } void FolderModel::setPreviews(bool previews) { if (m_previews != previews) { m_previews = previews; if (m_previewGenerator) { m_previewGenerator->setPreviewShown(m_previews); } emit previewsChanged(); } } QStringList FolderModel::previewPlugins() const { return m_previewPlugins; } void FolderModel::setPreviewPlugins(const QStringList& previewPlugins) { if (m_previewPlugins != previewPlugins) { m_previewPlugins = previewPlugins; if (m_previewGenerator) { m_previewGenerator->setPreviewShown(false); m_previewGenerator->setEnabledPlugins(m_previewPlugins); m_previewGenerator->setPreviewShown(true); } emit previewPluginsChanged(); } } int FolderModel::filterMode() const { return m_filterMode; } void FolderModel::setFilterMode(int filterMode) { if (m_filterMode != (FilterMode)filterMode) { m_filterMode = (FilterMode)filterMode; invalidateFilter(); emit filterModeChanged(); } } QString FolderModel::filterPattern() const { return m_filterPattern; } void FolderModel::setFilterPattern(const QString &pattern) { if (m_filterPattern == pattern) { return; } m_filterPattern = pattern; m_filterPatternMatchAll = (pattern == QLatin1String("*")); const QStringList patterns = pattern.split(' '); m_regExps.clear(); foreach (const QString &pattern, patterns) { QRegExp rx(pattern); rx.setPatternSyntax(QRegExp::Wildcard); rx.setCaseSensitivity(Qt::CaseInsensitive); m_regExps.append(rx); } invalidateFilter(); emit filterPatternChanged(); } QStringList FolderModel::filterMimeTypes() const { return m_mimeSet.toList(); } void FolderModel::setFilterMimeTypes(const QStringList &mimeList) { const QSet &set = QSet::fromList(mimeList); if (m_mimeSet != set) { m_mimeSet = set; invalidateFilter(); emit filterMimeTypesChanged(); } } void FolderModel::up() { const QUrl &up = KIO::upUrl(resolvedUrl()); if (up.isValid()) { setUrl(up.toString()); } } void FolderModel::cd(int row) { if (row < 0) { return; } KFileItem item = itemForIndex(index(row, 0)); if (item.isDir()) { setUrl(item.url().toString()); } } void FolderModel::run(int row) { if (row < 0) { return; } KFileItem item = itemForIndex(index(row, 0)); QUrl url(item.targetUrl()); // FIXME TODO: This can go once we depend on a KIO w/ fe1f50caaf2. if (url.scheme().isEmpty()) { url.setScheme(QStringLiteral("file")); } new KRun(url, 0); } void FolderModel::rename(int row, const QString& name) { if (row < 0) { return; } QModelIndex idx = index(row, 0); m_dirModel->setData(mapToSource(idx), name, Qt::EditRole); } int FolderModel::fileExtensionBoundary(int row) { const QModelIndex idx = index(row, 0); const QString &name = data(idx, Qt::DisplayRole).toString(); int boundary = name.length(); if (data(idx, IsDirRole).toBool()) { return boundary; } QMimeDatabase db; const QString &ext = db.suffixForFileName(name); if (ext.isEmpty()) { boundary = name.lastIndexOf(QLatin1Char('.')); if (boundary < 1) { boundary = name.length(); } } else { boundary -= ext.length() + 1; } return boundary; } bool FolderModel::hasSelection() { return m_selectionModel->hasSelection(); } bool FolderModel::isSelected(int row) { if (row < 0) { return false; } return m_selectionModel->isSelected(index(row, 0)); } void FolderModel::setSelected(int row) { if (row < 0) { return; } m_selectionModel->select(index(row, 0), QItemSelectionModel::Select); } void FolderModel::toggleSelected(int row) { if (row < 0) { return; } m_selectionModel->select(index(row, 0), QItemSelectionModel::Toggle); } void FolderModel::setRangeSelected(int anchor, int to) { if (anchor < 0 || to < 0) { return; } QItemSelection selection(index(anchor, 0), index(to, 0)); m_selectionModel->select(selection, QItemSelectionModel::ClearAndSelect); } void FolderModel::updateSelection(const QVariantList &rows, bool toggle) { QItemSelection newSelection; int iRow = -1; foreach (const QVariant &row, rows) { iRow = row.toInt(); if (iRow < 0) { return; } const QModelIndex &idx = index(iRow, 0); newSelection.select(idx, idx); } if (toggle) { QItemSelection pinnedSelection = m_pinnedSelection; pinnedSelection.merge(newSelection, QItemSelectionModel::Toggle); m_selectionModel->select(pinnedSelection, QItemSelectionModel::ClearAndSelect); } else { m_selectionModel->select(newSelection, QItemSelectionModel::ClearAndSelect); } } void FolderModel::clearSelection() { if (m_selectionModel->hasSelection()) { m_selectionModel->clear(); } } void FolderModel::pinSelection() { m_pinnedSelection = m_selectionModel->selection(); } void FolderModel::unpinSelection() { m_pinnedSelection = QItemSelection(); } void FolderModel::addItemDragImage(int row, int x, int y, int width, int height, const QVariant &image) { if (row < 0) { return; } delete m_dragImages.take(row); DragImage *dragImage = new DragImage(); dragImage->row = row; dragImage->rect = QRect(x, y, width, height); dragImage->image = image.value(); dragImage->blank = false; m_dragImages.insert(row, dragImage); } void FolderModel::clearDragImages() { if (!m_dragImages.isEmpty()) { foreach (DragImage *image, m_dragImages) { delete image; } m_dragImages.clear(); } } void FolderModel::setDragHotSpotScrollOffset(int x, int y) { m_dragHotSpotScrollOffset.setX(x); m_dragHotSpotScrollOffset.setY(y); } QPoint FolderModel::dragCursorOffset(int row) { if (!m_dragImages.contains(row)) { return QPoint(-1, -1); } return m_dragImages.value(row)->cursorOffset; } void FolderModel::addDragImage(QDrag *drag, int x, int y) { if (!drag || m_dragImages.isEmpty()) { return; } QRegion region; foreach (DragImage *image, m_dragImages) { image->blank = isBlank(image->row); image->rect.translate(-m_dragHotSpotScrollOffset.x(), -m_dragHotSpotScrollOffset.y()); if (!image->blank && !image->image.isNull()) { region = region.united(image->rect); } } QRect rect = region.boundingRect(); QPoint offset = rect.topLeft(); rect.translate(-offset.x(), -offset.y()); QImage dragImage(rect.size(), QImage::Format_RGBA8888); dragImage.fill(Qt::transparent); QPainter painter(&dragImage); QPoint pos; foreach (DragImage *image, m_dragImages) { if (!image->blank && !image->image.isNull()) { pos = image->rect.translated(-offset.x(), -offset.y()).topLeft(); image->cursorOffset.setX(pos.x() - (x - offset.x())); image->cursorOffset.setY(pos.y() - (y - offset.y())); painter.drawImage(pos, image->image); } // FIXME HACK: Operate on copy. image->rect.translate(m_dragHotSpotScrollOffset.x(), m_dragHotSpotScrollOffset.y()); } drag->setPixmap(QPixmap::fromImage(dragImage)); drag->setHotSpot(QPoint(x - offset.x(), y - offset.y())); } void FolderModel::dragSelected(int x, int y) { // Avoid starting a drag synchronously in a mouse handler or interferes with // child event filtering in parent items (and thus e.g. press-and-hold hand- // ling in a containment). QMetaObject::invokeMethod(this, "dragSelectedInternal", Qt::QueuedConnection, Q_ARG(int, x), Q_ARG(int, y)); } void FolderModel::dragSelectedInternal(int x, int y) { if (!m_viewAdapter || !m_selectionModel->hasSelection()) { return; } ItemViewAdapter *adapter = qobject_cast(m_viewAdapter); QQuickItem *item = qobject_cast(adapter->adapterView()); QDrag *drag = new QDrag(item); addDragImage(drag, x, y); m_dragIndexes = m_selectionModel->selectedIndexes(); qSort(m_dragIndexes.begin(), m_dragIndexes.end()); // TODO: Optimize to emit contiguous groups. emit dataChanged(m_dragIndexes.first(), m_dragIndexes.last(), QVector() << BlankRole); QModelIndexList sourceDragIndexes; foreach (const QModelIndex &index, m_dragIndexes) { sourceDragIndexes.append(mapToSource(index)); } drag->setMimeData(m_dirModel->mimeData(sourceDragIndexes)); item->grabMouse(); m_dragInProgress = true; drag->exec(supportedDragActions()); m_dragInProgress = false; item->ungrabMouse(); const QModelIndex first(m_dragIndexes.first()); const QModelIndex last(m_dragIndexes.last()); m_dragIndexes.clear(); // TODO: Optimize to emit contiguous groups. emit dataChanged(first, last, QVector() << BlankRole); } void FolderModel::drop(QQuickItem *target, QObject* dropEvent, int row) { QMimeData *mimeData = qobject_cast(dropEvent->property("mimeData").value()); if (!mimeData) { return; } if (m_dragInProgress && row == -1) { if (m_locked || mimeData->urls().isEmpty()) { return; } setSortMode(-1); emit move(dropEvent->property("x").toInt(), dropEvent->property("y").toInt(), mimeData->urls()); return; } QModelIndex idx; KFileItem item; if (row > -1 && row < rowCount()) { idx = index(row, 0); item = itemForIndex(idx); } if (item.isNull() && mimeData->hasFormat(QStringLiteral("application/x-kde-ark-dndextract-service")) && mimeData->hasFormat(QStringLiteral("application/x-kde-ark-dndextract-path"))) { const QString remoteDBusClient = mimeData->data(QStringLiteral("application/x-kde-ark-dndextract-service")); const QString remoteDBusPath = mimeData->data(QStringLiteral("application/x-kde-ark-dndextract-path")); QDBusMessage message = QDBusMessage::createMethodCall(remoteDBusClient, remoteDBusPath, QStringLiteral("org.kde.ark.DndExtract"), QStringLiteral("extractSelectedFilesTo")); message.setArguments(QVariantList() << m_dirModel->dirLister()->url().adjusted(QUrl::PreferLocalFile).toString()); QDBusConnection::sessionBus().call(message); return; } if (idx.isValid() && !(flags(idx) & Qt::ItemIsDropEnabled)) { return; } QPoint pos; pos.setX(dropEvent->property("x").toInt()); pos.setY(dropEvent->property("y").toInt()); pos = target->mapToScene(pos).toPoint(); pos = target->window()->mapToGlobal(pos); Qt::DropAction proposedAction((Qt::DropAction)dropEvent->property("proposedAction").toInt()); Qt::DropActions possibleActions(dropEvent->property("possibleActions").toInt()); Qt::MouseButtons buttons(dropEvent->property("buttons").toInt()); Qt::KeyboardModifiers modifiers(dropEvent->property("modifiers").toInt()); QDropEvent ev(pos, possibleActions, mimeData, buttons, modifiers); ev.setDropAction(proposedAction); QUrl dropTargetUrl; if (item.isNull()) { dropTargetUrl = m_dirModel->dirLister()->url(); } else if (m_parseDesktopFiles && item.isDesktopFile()) { const KDesktopFile file(item.targetUrl().path()); if (file.readType() == QLatin1String("Link")) { dropTargetUrl = QUrl(file.readUrl()); } else { dropTargetUrl = item.mostLocalUrl(); } } else { dropTargetUrl = item.mostLocalUrl(); } KIO::DropJob *dropJob = KIO::drop(&ev, dropTargetUrl); dropJob->ui()->setAutoErrorHandlingEnabled(true); } void FolderModel::dropCwd(QObject* dropEvent) { QMimeData *mimeData = qobject_cast(dropEvent->property("mimeData").value()); if (!mimeData) { return; } if (mimeData->hasFormat(QStringLiteral("application/x-kde-ark-dndextract-service")) && mimeData->hasFormat(QStringLiteral("application/x-kde-ark-dndextract-path"))) { const QString remoteDBusClient = mimeData->data(QStringLiteral("application/x-kde-ark-dndextract-service")); const QString remoteDBusPath = mimeData->data(QStringLiteral("application/x-kde-ark-dndextract-path")); QDBusMessage message = QDBusMessage::createMethodCall(remoteDBusClient, remoteDBusPath, QStringLiteral("org.kde.ark.DndExtract"), QStringLiteral("extractSelectedFilesTo")); message.setArguments(QVariantList() << m_dirModel->dirLister()->url().adjusted(QUrl::PreferLocalFile).toString()); QDBusConnection::sessionBus().call(message); } else { Qt::DropAction proposedAction((Qt::DropAction)dropEvent->property("proposedAction").toInt()); Qt::DropActions possibleActions(dropEvent->property("possibleActions").toInt()); Qt::MouseButtons buttons(dropEvent->property("buttons").toInt()); Qt::KeyboardModifiers modifiers(dropEvent->property("modifiers").toInt()); QDropEvent ev(QPoint(), possibleActions, mimeData, buttons, modifiers); ev.setDropAction(proposedAction); KIO::DropJob *dropJob = KIO::drop(&ev, m_dirModel->dirLister()->url().adjusted(QUrl::PreferLocalFile)); dropJob->ui()->setAutoErrorHandlingEnabled(true); } } void FolderModel::selectionChanged(QItemSelection selected, QItemSelection deselected) { QModelIndexList indices = selected.indexes(); indices.append(deselected.indexes()); QVector roles; roles.append(SelectedRole); foreach(const QModelIndex index, indices) { emit dataChanged(index, index, roles); } if (!m_selectionModel->hasSelection()) { clearDragImages(); } else { foreach (const QModelIndex &idx, deselected.indexes()) { if (m_dragImages.contains(idx.row())) { DragImage *image = m_dragImages.value(idx.row()); delete image; m_dragImages.remove(idx.row()); } } } } bool FolderModel::isBlank(int row) const { if (row < 0) { return true; } return data(index(row, 0), BlankRole).toBool(); } QVariant FolderModel::data(const QModelIndex& index, int role) const { if (!index.isValid()) { return QVariant(); } if (role == BlankRole) { return m_dragIndexes.contains(index); } else if (role == SelectedRole) { return m_selectionModel->isSelected(index); } else if (role == IsDirRole) { const QUrl &url = data(index, UrlRole).value(); if (m_isDirCache.contains(url)) { return m_isDirCache[url]; } else { return isDir(mapToSource(index), m_dirModel); } } else if (role == UrlRole) { return itemForIndex(index).url(); } else if (role == LinkDestinationUrl) { const KFileItem item = itemForIndex(index); if (m_parseDesktopFiles && item.isDesktopFile()) { const KDesktopFile file(item.targetUrl().path()); if (file.readType() == QLatin1String("Link")) { return file.readUrl(); } } return item.url(); } else if (role == SizeRole) { bool isDir = data(index, IsDirRole).toBool(); if (!isDir) { return m_dirModel->data(mapToSource(QSortFilterProxyModel::index(index.row(), 1)), Qt::DisplayRole); } } else if (role == TypeRole) { return m_dirModel->data(mapToSource(QSortFilterProxyModel::index(index.row(), 6)), Qt::DisplayRole); } else if (role == FileNameRole) { return itemForIndex(index).url().fileName(); } return QSortFilterProxyModel::data(index, role); } int FolderModel::indexForUrl(const QUrl& url) const { return mapFromSource(m_dirModel->indexForUrl(url)).row(); } KFileItem FolderModel::itemForIndex(const QModelIndex &index) const { return m_dirModel->itemForIndex(mapToSource(index)); } bool FolderModel::isDir(const QModelIndex &index, const KDirModel *dirModel) const { KFileItem item = dirModel->itemForIndex(index); if (item.isDir()) { return true; } if (m_parseDesktopFiles && item.isDesktopFile()) { // Check if the desktop file is a link to a directory KDesktopFile file(item.targetUrl().path()); if (file.readType() == QLatin1String("Link")) { const QUrl url(file.readUrl()); if (url.isLocalFile()) { QT_STATBUF buf; const QString path = url.adjusted(QUrl::StripTrailingSlash).toLocalFile(); if (QT_STAT(QFile::encodeName(path).constData(), &buf) == 0) { return S_ISDIR(buf.st_mode); } } else if (!m_isDirCache.contains(item.url()) && KProtocolInfo::protocolClass(url.scheme()) == QStringLiteral(":local")) { KIO::StatJob *job = KIO::stat(url, KIO::HideProgressInfo); job->setProperty("org.kde.plasma.folder_url", item.url()); job->setSide(KIO::StatJob::SourceSide); job->setDetails(0); connect(job, &KJob::result, this, &FolderModel::statResult); } } } return false; } void FolderModel::statResult(KJob *job) { KIO::StatJob *statJob = static_cast(job); const QUrl &url = statJob->property("org.kde.plasma.folder_url").value(); const QModelIndex &idx = index(indexForUrl(url), 0); if (idx.isValid()) { m_isDirCache[url] = statJob->statResult().isDir(); emit dataChanged(idx, idx, QVector() << IsDirRole); } } void FolderModel::evictFromIsDirCache(const KFileItemList& items) { foreach (const KFileItem &item, items) { m_isDirCache.remove(item.url()); } } bool FolderModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { const KDirModel *dirModel = static_cast(sourceModel()); if (m_sortDirsFirst || left.column() == KDirModel::Size) { bool leftIsDir = isDir(left, dirModel); bool rightIsDir = isDir(right, dirModel); if (leftIsDir && !rightIsDir) { return (sortOrder() == Qt::AscendingOrder); } if (!leftIsDir && rightIsDir) { return (sortOrder() == Qt::DescendingOrder); } } const KFileItem leftItem = dirModel->data(left, KDirModel::FileItemRole).value(); const KFileItem rightItem = dirModel->data(right, KDirModel::FileItemRole).value(); const int column = left.column(); int result = 0; switch (column) { case KDirModel::Size: { if (isDir(left, dirModel) && isDir(right, dirModel)) { const int leftChildCount = dirModel->data(left, KDirModel::ChildCountRole).toInt(); const int rightChildCount = dirModel->data(right, KDirModel::ChildCountRole).toInt(); if (leftChildCount < rightChildCount) result = -1; else if (leftChildCount > rightChildCount) result = +1; } else { const KIO::filesize_t leftSize = leftItem.size(); const KIO::filesize_t rightSize = rightItem.size(); if (leftSize < rightSize) result = -1; else if (leftSize > rightSize) result = +1; } break; } case KDirModel::ModifiedTime: { const QDateTime leftTime = leftItem.time(KFileItem::ModificationTime); const QDateTime rightTime = rightItem.time(KFileItem::ModificationTime); if (leftTime < rightTime) result = -1; else if (leftTime > rightTime) result = +1; break; } case KDirModel::Type: result = QString::compare(dirModel->data(left, Qt::DisplayRole).toString(), dirModel->data(right, Qt::DisplayRole).toString()); break; default: break; } if (result != 0) return result < 0; QCollator collator; result = collator.compare(leftItem.text(), rightItem.text()); if (result != 0) return result < 0; result = collator.compare(leftItem.name(), rightItem.name()); if (result != 0) return result < 0; return QString::compare(leftItem.url().url(), rightItem.url().url(), Qt::CaseSensitive); } inline bool FolderModel::matchMimeType(const KFileItem &item) const { if (m_mimeSet.isEmpty()) { return false; } if (m_mimeSet.contains(QStringLiteral("all/all")) || m_mimeSet.contains(QStringLiteral("all/allfiles"))) { return true; } const QString mimeType = item.determineMimeType().name(); return m_mimeSet.contains(mimeType); } inline bool FolderModel::matchPattern(const KFileItem &item) const { if (m_filterPatternMatchAll) { return true; } const QString name = item.name(); QListIterator i(m_regExps); while (i.hasNext()) { if (i.next().exactMatch(name)) { return true; } } return false; } bool FolderModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { if (m_filterMode == NoFilter) { return true; } const KDirModel *dirModel = static_cast(sourceModel()); const KFileItem item = dirModel->itemForIndex(dirModel->index(sourceRow, KDirModel::Name, sourceParent)); if (m_filterMode == FilterShowMatches) { return (matchPattern(item) && matchMimeType(item)); } else { return !(matchPattern(item) && matchMimeType(item)); } } void FolderModel::createActions() { KIO::FileUndoManager *manager = KIO::FileUndoManager::self(); QAction *cut = KStandardAction::cut(this, SLOT(cut()), this); QAction *copy = KStandardAction::copy(this, SLOT(copy()), this); QAction *undo = KStandardAction::undo(manager, SLOT(undo()), this); undo->setEnabled(manager->undoAvailable()); undo->setShortcutContext(Qt::WidgetShortcut); connect(manager, SIGNAL(undoAvailable(bool)), undo, SLOT(setEnabled(bool))); connect(manager, &KIO::FileUndoManager::undoTextChanged, this, &FolderModel::undoTextChanged); QAction *paste = KStandardAction::paste(this, SLOT(paste()), this); QAction *pasteTo = KStandardAction::paste(this, SLOT(pasteTo()), this); QAction *reload = new QAction(i18n("&Reload"), this); connect(reload, &QAction::triggered, this, &FolderModel::refresh); QAction *refresh = new QAction(QIcon::fromTheme(QStringLiteral("view-refresh")), i18n("&Refresh View"), this); connect(refresh, &QAction::triggered, this, &FolderModel::refresh); QAction *rename = new QAction(QIcon::fromTheme(QStringLiteral("edit-rename")), i18n("&Rename"), this); connect(rename, &QAction::triggered, this, &FolderModel::requestRename); QAction *trash = new QAction(QIcon::fromTheme(QStringLiteral("user-trash")), i18n("&Move to Trash"), this); connect(trash, &QAction::triggered, this, &FolderModel::moveSelectedToTrash); QAction *emptyTrash = new QAction(QIcon::fromTheme(QStringLiteral("trash-empty")), i18n("&Empty Trash Bin"), this); connect(emptyTrash, &QAction::triggered, this, &FolderModel::emptyTrashBin); QAction *del = new QAction(QIcon::fromTheme(QStringLiteral("edit-delete")), i18n("&Delete"), this); connect(del, &QAction::triggered, this, &FolderModel::deleteSelected); + QAction *actOpen = new QAction(QIcon::fromTheme(QStringLiteral("window-new")), i18n("&Open"), this); + connect(actOpen, &QAction::triggered, this, &FolderModel::openSelected); + + m_actionCollection.addAction(QStringLiteral("open"), actOpen); m_actionCollection.addAction(QStringLiteral("cut"), cut); m_actionCollection.addAction(QStringLiteral("undo"), undo); m_actionCollection.addAction(QStringLiteral("copy"), copy); m_actionCollection.addAction(QStringLiteral("paste"), paste); m_actionCollection.addAction(QStringLiteral("pasteto"), pasteTo); m_actionCollection.addAction(QStringLiteral("reload"), reload); m_actionCollection.addAction(QStringLiteral("refresh"), refresh); m_actionCollection.addAction(QStringLiteral("rename"), rename); m_actionCollection.addAction(QStringLiteral("trash"), trash); m_actionCollection.addAction(QStringLiteral("del"), del); m_actionCollection.addAction(QStringLiteral("emptyTrash"), emptyTrash); m_newMenu = new KNewFileMenu(&m_actionCollection, QStringLiteral("newMenu"), QApplication::desktop()); m_newMenu->setModal(false); + + m_copyToMenu = new KFileCopyToMenu(Q_NULLPTR); } QAction* FolderModel::action(const QString &name) const { return m_actionCollection.action(name); } QObject* FolderModel::newMenu() const { return m_newMenu->menu(); } void FolderModel::updateActions() { if (m_newMenu) { m_newMenu->checkUpToDate(); m_newMenu->setPopupFiles(m_dirModel->dirLister()->url()); } QAction *emptyTrash = m_actionCollection.action(QStringLiteral("emptyTrash")); if (emptyTrash) { if (resolvedUrl() == QUrl(QStringLiteral("trash:/"))) { emptyTrash->setVisible(true); KConfig trashConfig(QStringLiteral("trashrc"), KConfig::SimpleConfig); emptyTrash->setEnabled(!trashConfig.group("Status").readEntry("Empty", true)); } else { emptyTrash->setVisible(false); } } QAction *paste = m_actionCollection.action(QStringLiteral("paste")); if (paste) { bool enable = false; const QString pasteText = KIO::pasteActionText(QApplication::clipboard()->mimeData(), &enable, m_dirModel->dirLister()->rootItem()); if (enable) { paste->setText(pasteText); paste->setEnabled(true); } else { paste->setText(i18n("&Paste")); paste->setEnabled(false); } QAction* pasteTo = m_actionCollection.action(QStringLiteral("pasteto")); if (pasteTo) { pasteTo->setEnabled(paste->isEnabled()); pasteTo->setText(paste->text()); } } } void FolderModel::openContextMenu() { QModelIndexList indexes = m_selectionModel->selectedIndexes(); if (m_usedByContainment && !KAuthorized::authorize(QStringLiteral("action/kdesktop_rmb"))) { return; } updateActions(); - QMenu *menu = 0; + QMenu *menu = new QMenu(); + if (!m_fileItemActions) { + m_fileItemActions = new KFileItemActions(this); + m_fileItemActions->setParentWidget(QApplication::desktop()); + } if (indexes.isEmpty()) { - menu = new QMenu(); menu->addAction(m_actionCollection.action(QStringLiteral("newMenu"))); menu->addSeparator(); menu->addAction(m_actionCollection.action(QStringLiteral("paste"))); menu->addAction(m_actionCollection.action(QStringLiteral("undo"))); menu->addAction(m_actionCollection.action(QStringLiteral("refresh"))); menu->addAction(m_actionCollection.action(QStringLiteral("emptyTrash"))); menu->addSeparator(); - if (!m_fileItemActions) { - m_fileItemActions = new KFileItemActions(this); - } - - KFileItemListProperties itemList(KFileItemList() << m_dirModel->dirLister()->rootItem()); - m_fileItemActions->setItemListProperties(itemList); + KFileItemListProperties itemProperties(KFileItemList() << m_dirModel->dirLister()->rootItem()); + m_fileItemActions->setItemListProperties(itemProperties); menu->addAction(m_fileItemActions->preferredOpenWithAction(QString())); } else { KFileItemList items; + QList urls; bool hasRemoteFiles = false; bool isTrashLink = false; + items.reserve(indexes.count()); + urls.reserve(indexes.count()); foreach (const QModelIndex &index, indexes) { KFileItem item = itemForIndex(index); if (!item.isNull()) { hasRemoteFiles |= item.localPath().isEmpty(); items.append(item); + urls.append(item.url()); } } + KFileItemListProperties itemProperties(items); // Check if we're showing the menu for the trash link if (items.count() == 1 && items.at(0).isDesktopFile()) { KDesktopFile file(items.at(0).localPath()); if (file.readType() == QLatin1String("Link") && file.readUrl() == QLatin1String("trash:/")) { isTrashLink = true; } } - QList editActions; - editActions.append(m_actionCollection.action(QStringLiteral("rename"))); + // Start adding the actions: + menu->addAction(m_actionCollection.action(QStringLiteral("open"))); + menu->addSeparator(); + if (itemProperties.supportsDeleting()) { + menu->addAction(m_actionCollection.action(QStringLiteral("cut"))); + } + menu->addAction(m_actionCollection.action(QStringLiteral("copy"))); + + if (itemProperties.isDirectory() && itemProperties.supportsWriting()) { + menu->addAction(m_actionCollection.action(QStringLiteral("pasteto"))); + } + + menu->addAction(m_actionCollection.action(QStringLiteral("rename"))); KSharedConfig::Ptr globalConfig = KSharedConfig::openConfig(QStringLiteral("kdeglobals"), KConfig::NoGlobals); KConfigGroup cg(globalConfig, "KDE"); bool showDeleteCommand = cg.readEntry("ShowDeleteCommand", false); // Don't add the "Move to Trash" action if we're showing the menu for the trash link if (!isTrashLink) { if (!hasRemoteFiles) { - editActions.append(m_actionCollection.action(QStringLiteral("trash"))); + menu->addAction(m_actionCollection.action(QStringLiteral("trash"))); } else { showDeleteCommand = true; } } if (showDeleteCommand) { - editActions.append(m_actionCollection.action(QStringLiteral("del"))); + menu->addAction(m_actionCollection.action(QStringLiteral("del"))); } - KonqPopupMenu::ActionGroupMap actionGroups; - actionGroups.insert(KonqPopupMenu::EditActions, editActions); + // "Open with" actions + m_fileItemActions->setItemListProperties(itemProperties); + m_fileItemActions->addOpenWithActionsTo(menu); + // Service actions + m_fileItemActions->addServiceActionsTo(menu); + menu->addSeparator(); + // Plugin actions +#if KIO_VERSION >= QT_VERSION_CHECK(5, 27, 0) + m_fileItemActions->addPluginActionsTo(menu); +#endif + + // Copy To, Move To + KSharedConfig::Ptr dolphin = KSharedConfig::openConfig(QStringLiteral("dolphinrc")); + if (KConfigGroup(dolphin, "General").readEntry("ShowCopyMoveMenu", false)) { + m_copyToMenu->setUrls(urls); + m_copyToMenu->setReadOnly(!itemProperties.supportsMoving()); + m_copyToMenu->addActionsTo(menu); + menu->addSeparator(); + } - KonqPopupMenu::Flags flags = KonqPopupMenu::ShowProperties; - flags |= KonqPopupMenu::ShowUrlOperations; - flags |= KonqPopupMenu::ShowNewWindow; + // Properties + if (KPropertiesDialog::canDisplay(items)) { + QAction *act = new QAction(menu); + act->setText(i18n("&Properties")); + QObject::connect(act, &QAction::triggered, [this, items]() { + KPropertiesDialog::showDialog(items, Q_NULLPTR, false /*non modal*/); + }); + menu->addAction(act); + } - KonqPopupMenu *popupMenu = new KonqPopupMenu(items, m_dirModel->dirLister()->url(), m_actionCollection, flags, QApplication::desktop()); - popupMenu->setNewFileMenu(m_newMenu); - popupMenu->setBookmarkManager(KBookmarkManager::userBookmarksManager()); - popupMenu->setActionGroups(actionGroups); - connect(popupMenu, &QMenu::aboutToHide, [popupMenu]() { popupMenu->deleteLater(); }); - menu = popupMenu; } menu->popup(QCursor::pos()); + connect(menu, &QMenu::aboutToHide, [menu]() { menu->deleteLater(); }); } void FolderModel::linkHere(const QUrl &sourceUrl) { KIO::CopyJob *job = KIO::link(sourceUrl, m_dirModel->dirLister()->url()); KIO::FileUndoManager::self()->recordCopyJob(job); } QList FolderModel::selectedUrls(bool forTrash) const { QList urls; foreach (const QModelIndex &index, m_selectionModel->selectedIndexes()) { KFileItem item = itemForIndex(index); if (forTrash) { // Prefer the local URL if there is one, since we can't trash remote URL's urls.append(item.mostLocalUrl()); } else { urls.append(item.url()); } } return urls; } void FolderModel::copy() { if (!m_selectionModel->hasSelection()) { return; } QMimeData *mimeData = QSortFilterProxyModel::mimeData(m_selectionModel->selectedIndexes()); QApplication::clipboard()->setMimeData(mimeData); } void FolderModel::cut() { if (!m_selectionModel->hasSelection()) { return; } QMimeData *mimeData = QSortFilterProxyModel::mimeData(m_selectionModel->selectedIndexes()); KIO::setClipboardDataCut(mimeData, true); QApplication::clipboard()->setMimeData(mimeData); } void FolderModel::paste() { KIO::paste(QApplication::clipboard()->mimeData(), m_dirModel->dirLister()->url()); } void FolderModel::pasteTo() { const QList urls = selectedUrls(false); Q_ASSERT(urls.count() == 1); KIO::paste(QApplication::clipboard()->mimeData(), urls.first()); } void FolderModel::refresh() { m_errorString.clear(); emit errorStringChanged(); m_dirModel->dirLister()->updateDirectory(m_dirModel->dirLister()->url()); } void FolderModel::moveSelectedToTrash() { if (!m_selectionModel->hasSelection()) { return; } const QList urls = selectedUrls(true); KIO::JobUiDelegate uiDelegate; if (uiDelegate.askDeleteConfirmation(urls, KIO::JobUiDelegate::Trash, KIO::JobUiDelegate::DefaultConfirmation)) { KIO::Job* job = KIO::trash(urls); job->ui()->setAutoErrorHandlingEnabled(true); KIO::FileUndoManager::self()->recordJob(KIO::FileUndoManager::Trash, urls, QUrl(QStringLiteral("trash:/")), job); } } void FolderModel::deleteSelected() { if (!m_selectionModel->hasSelection()) { return; } const QList urls = selectedUrls(false); KIO::JobUiDelegate uiDelegate; if (uiDelegate.askDeleteConfirmation(urls, KIO::JobUiDelegate::Delete, KIO::JobUiDelegate::DefaultConfirmation)) { KIO::Job* job = KIO::del(urls); job->ui()->setAutoErrorHandlingEnabled(true); } } +void FolderModel::openSelected() +{ + if (!m_selectionModel->hasSelection()) { + return; + } + + const QList urls = selectedUrls(false); + for (const QUrl &url : urls) { + (void) new KRun(url, Q_NULLPTR); + } +} + void FolderModel::emptyTrashBin() { KIO::JobUiDelegate uiDelegate; uiDelegate.setWindow(QApplication::desktop()); if (uiDelegate.askDeleteConfirmation(QList(), KIO::JobUiDelegate::EmptyTrash, KIO::JobUiDelegate::DefaultConfirmation)) { KIO::Job* job = KIO::emptyTrash(); job->ui()->setAutoErrorHandlingEnabled(true); } } void FolderModel::undoTextChanged(const QString &text) { if (QAction *action = m_actionCollection.action(QStringLiteral("undo"))) { action->setText(text); } } diff --git a/containments/desktop/plugins/folder/foldermodel.h b/containments/desktop/plugins/folder/foldermodel.h index 0e31b1eb9..844f8dcad 100644 --- a/containments/desktop/plugins/folder/foldermodel.h +++ b/containments/desktop/plugins/folder/foldermodel.h @@ -1,286 +1,289 @@ /*************************************************************************** * Copyright (C) 2008 Fredrik Höglund * * Copyright (C) 2011 Marco Martin * * Copyright (C) 2014 by Eike Hein * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ #ifndef FOLDERMODEL_H #define FOLDERMODEL_H #include #include #include #include #include #include #include #include #include #include #include #include class QDrag; class QItemSelectionModel; class QQuickItem; +class KFileCopyToMenu; class KActionCollection; class KDirModel; class KDirWatch; class KFileItem; class KFileItemActions; class KJob; class KNewFileMenu; class DirLister : public KDirLister { Q_OBJECT public: DirLister(QObject *parent = 0); ~DirLister(); Q_SIGNALS: void error(const QString &string); protected: void handleError(KIO::Job *job); }; class FolderModel : public QSortFilterProxyModel { Q_OBJECT Q_PROPERTY(QString url READ url WRITE setUrl NOTIFY urlChanged) Q_PROPERTY(QString iconName READ iconName NOTIFY iconNameChanged) Q_PROPERTY(QUrl resolvedUrl READ resolvedUrl NOTIFY resolvedUrlChanged) Q_PROPERTY(QString errorString READ errorString NOTIFY errorStringChanged) Q_PROPERTY(bool usedByContainment READ usedByContainment WRITE setUsedByContainment NOTIFY usedByContainmentChanged) Q_PROPERTY(bool locked READ locked WRITE setLocked NOTIFY lockedChanged) Q_PROPERTY(int sortMode READ sortMode WRITE setSortMode NOTIFY sortModeChanged) Q_PROPERTY(bool sortDesc READ sortDesc WRITE setSortDesc NOTIFY sortDescChanged) Q_PROPERTY(bool sortDirsFirst READ sortDirsFirst WRITE setSortDirsFirst NOTIFY sortDirsFirstChanged) Q_PROPERTY(bool parseDesktopFiles READ parseDesktopFiles WRITE setParseDesktopFiles NOTIFY parseDesktopFilesChanged) Q_PROPERTY(QObject* viewAdapter READ viewAdapter WRITE setViewAdapter NOTIFY viewAdapterChanged) Q_PROPERTY(bool previews READ previews WRITE setPreviews NOTIFY previewsChanged) Q_PROPERTY(QStringList previewPlugins READ previewPlugins WRITE setPreviewPlugins NOTIFY previewPluginsChanged) Q_PROPERTY(int filterMode READ filterMode WRITE setFilterMode NOTIFY filterModeChanged) Q_PROPERTY(QString filterPattern READ filterPattern WRITE setFilterPattern NOTIFY filterPatternChanged) Q_PROPERTY(QStringList filterMimeTypes READ filterMimeTypes WRITE setFilterMimeTypes NOTIFY filterMimeTypesChanged) Q_PROPERTY(QObject* newMenu READ newMenu CONSTANT) public: enum DataRole { BlankRole = Qt::UserRole + 1, SelectedRole, IsDirRole, UrlRole, LinkDestinationUrl, SizeRole, TypeRole, FileNameRole }; enum FilterMode { NoFilter = 0, FilterShowMatches, FilterHideMatches }; FolderModel(QObject *parent = 0); ~FolderModel(); QHash roleNames() const; static QHash staticRoleNames(); QString url() const; void setUrl(const QString &url); QString iconName() const; QUrl resolvedUrl() const; Q_INVOKABLE QUrl resolve(const QString& url); QString errorString() const; bool usedByContainment() const; void setUsedByContainment(bool used); bool locked() const; void setLocked(bool locked); int sortMode() const; void setSortMode(int mode); bool sortDesc() const; void setSortDesc(bool desc); bool sortDirsFirst() const; void setSortDirsFirst(bool enable); bool parseDesktopFiles() const; void setParseDesktopFiles(bool enable); QObject* viewAdapter() const; void setViewAdapter(QObject *adapter); bool previews() const; void setPreviews(bool previews); QStringList previewPlugins() const; void setPreviewPlugins(const QStringList &previewPlugins); int filterMode() const; void setFilterMode(int filterMode); QString filterPattern() const; void setFilterPattern(const QString &pattern); QStringList filterMimeTypes() const; void setFilterMimeTypes(const QStringList &mimeList); Q_INVOKABLE void up(); Q_INVOKABLE void cd(int row); Q_INVOKABLE void run(int row); Q_INVOKABLE void rename(int row, const QString &name); Q_INVOKABLE int fileExtensionBoundary(int row); Q_INVOKABLE bool hasSelection(); Q_INVOKABLE bool isSelected(int row); Q_INVOKABLE void setSelected(int row); Q_INVOKABLE void toggleSelected(int row); Q_INVOKABLE void setRangeSelected(int anchor, int to); Q_INVOKABLE void updateSelection(const QVariantList &rows, bool toggle); Q_INVOKABLE void clearSelection(); Q_INVOKABLE void pinSelection(); Q_INVOKABLE void unpinSelection(); Q_INVOKABLE void addItemDragImage(int row, int x, int y, int width, int height, const QVariant &image); Q_INVOKABLE void clearDragImages(); Q_INVOKABLE void setDragHotSpotScrollOffset(int x, int y); // FIXME TODO: Propify. Q_INVOKABLE QPoint dragCursorOffset(int row); Q_INVOKABLE void dragSelected(int x, int y); Q_INVOKABLE void drop(QQuickItem *target, QObject *dropEvent, int row); Q_INVOKABLE void dropCwd(QObject *dropEvent); Q_INVOKABLE bool isBlank(int row) const; Q_INVOKABLE QAction* action(const QString& name) const; QObject* newMenu() const; Q_INVOKABLE void updateActions(); Q_INVOKABLE void openContextMenu(); Q_INVOKABLE void linkHere(const QUrl &sourceUrl); QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; int indexForUrl(const QUrl &url) const; KFileItem itemForIndex(const QModelIndex &index) const; bool isDir(const QModelIndex &index, const KDirModel *dirModel) const; bool lessThan(const QModelIndex &left, const QModelIndex &right) const; Q_INVOKABLE void paste(); Q_INVOKABLE void copy(); Q_INVOKABLE void cut(); Q_INVOKABLE void deleteSelected(); + Q_INVOKABLE void openSelected(); Q_SIGNALS: void urlChanged() const; void iconNameChanged() const; void resolvedUrlChanged() const; void errorStringChanged() const; void usedByContainmentChanged() const; void lockedChanged() const; void sortModeChanged() const; void sortDescChanged() const; void sortDirsFirstChanged() const; void parseDesktopFilesChanged() const; void viewAdapterChanged(); void previewsChanged() const; void previewPluginsChanged() const; void filterModeChanged() const; void filterPatternChanged() const; void filterMimeTypesChanged() const; void requestRename() const; void move(int x, int y, QList urls); protected: bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const; bool matchMimeType(const KFileItem &item) const; bool matchPattern(const KFileItem &item) const; private Q_SLOTS: void dragSelectedInternal(int x, int y); void dirListFailed(const QString &error); void statResult(KJob *job); void evictFromIsDirCache(const KFileItemList &items); void selectionChanged(QItemSelection selected, QItemSelection deselected); void pasteTo(); void refresh(); void moveSelectedToTrash(); void emptyTrashBin(); void undoTextChanged(const QString &text); private: struct DragImage { int row; QRect rect; QPoint cursorOffset; QImage image; bool blank; }; void createActions(); void updatePasteAction(); void addDragImage(QDrag *drag, int x, int y); QList selectedUrls(bool forTrash) const; KDirModel *m_dirModel; KDirWatch *m_dirWatch; QString m_url; QHash m_isDirCache; QItemSelectionModel *m_selectionModel; QItemSelection m_pinnedSelection; QModelIndexList m_dragIndexes; QHash m_dragImages; QPoint m_dragHotSpotScrollOffset; bool m_dragInProgress; QPointer m_previewGenerator; QPointer m_viewAdapter; KActionCollection m_actionCollection; KNewFileMenu *m_newMenu; KFileItemActions *m_fileItemActions; + KFileCopyToMenu *m_copyToMenu; QString m_errorString; bool m_usedByContainment; bool m_locked; int m_sortMode; // FIXME TODO: Enumify. bool m_sortDesc; bool m_sortDirsFirst; bool m_parseDesktopFiles; bool m_previews; QStringList m_previewPlugins; FilterMode m_filterMode; QString m_filterPattern; bool m_filterPatternMatchAll; QSet m_mimeSet; QList m_regExps; }; #endif diff --git a/containments/desktop/plugins/folder/internallibkonq/README_internallibkonq.txt b/containments/desktop/plugins/folder/internallibkonq/README_internallibkonq.txt deleted file mode 100644 index 2d2409cca..000000000 --- a/containments/desktop/plugins/folder/internallibkonq/README_internallibkonq.txt +++ /dev/null @@ -1,16 +0,0 @@ -The internallibkonq/ folder contains a subset of the libkonq -library originally from kde-baseapps.git. - -This was added here temporarily to avoid a dependency of -plasma-desktop on kde-baseapps. - -The long-term plan is to split up libkonq and distribute its -useful parts over various parts of KDE Frameworks 5, and then -eliminate this duplication. - -DO NOT MODIFY this copy of the library to avoid divergence -from the upstream source. Any patches need to be applied to -kde-baseapps first. - -Signed of by: David Faure , library maintainer - Kevin Ottens , KF5 coordinator \ No newline at end of file diff --git a/containments/desktop/plugins/folder/internallibkonq/konq_popupmenu.cpp b/containments/desktop/plugins/folder/internallibkonq/konq_popupmenu.cpp deleted file mode 100644 index b15f6e926..000000000 --- a/containments/desktop/plugins/folder/internallibkonq/konq_popupmenu.cpp +++ /dev/null @@ -1,597 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 1998-2008 David Faure - Copyright (C) 2001 Holger Freyther - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "konq_popupmenu.h" - -#include - -#include -#include "kfileitemactions.h" -#include "kabstractfileitemactionplugin.h" -#include "kpropertiesdialog.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -/* - Test cases: - iconview file: background - iconview file: file (with and without servicemenus) - iconview file: directory - iconview remote protocol (e.g. ftp: or fish:) - iconview trash:/ - sidebar directory tree - sidebar Devices / Hard Disc - khtml background - khtml link - khtml image (www.kde.org RMB on K logo) - khtmlimage (same as above, then choose View image, then RMB) - selected text in khtml - embedded katepart - folder on the desktop - trash link on the desktop - trashed file or directory - application .desktop file - Then the same after uninstalling kdeaddons/konq-plugins (arkplugin in particular) -*/ - -class KonqPopupMenuPrivate -{ -public: - KonqPopupMenuPrivate(KonqPopupMenu *qq, KActionCollection &actions, QWidget *parentWidget) - : q(qq), - m_parentWidget(parentWidget), - m_popupFlags(KonqPopupMenu::DefaultPopupItems), - m_pMenuNew(0), - m_copyToMenu(parentWidget), - m_bookmarkManager(0), - m_actions(actions) - { - } - - ~KonqPopupMenuPrivate() - { - qDeleteAll(m_ownActions); - } - - void addNamedAction(const char *name); - void addGroup(KonqPopupMenu::ActionGroup group); - void addPlugins(); - void populate(); - void aboutToShow(); - - void slotPopupNewDir(); - void slotPopupNewView(); - void slotPopupEmptyTrashBin(); - void slotConfigTrashBin(); - void slotPopupRestoreTrashedItems(); - void slotPopupAddToBookmark(); - void slotPopupMimeType(); - void slotPopupProperties(); - void slotShowOriginalFile(); - - KonqPopupMenu *q; - QWidget *m_parentWidget; - QString m_urlTitle; - KonqPopupMenu::Flags m_popupFlags; - KNewFileMenu *m_pMenuNew; - QUrl m_sViewURL; - KFileItemListProperties m_popupItemProperties; - KFileItemActions m_menuActions; - KFileCopyToMenu m_copyToMenu; - KBookmarkManager *m_bookmarkManager; - KActionCollection &m_actions; - QList m_ownActions; - KonqPopupMenu::ActionGroupMap m_actionGroups; -}; - -////////////////// - -KonqPopupMenu::KonqPopupMenu(const KFileItemList &items, - const QUrl &viewURL, - KActionCollection &actions, - Flags popupFlags, - QWidget *parentWidget) - : QMenu(parentWidget), - d(new KonqPopupMenuPrivate(this, actions, parentWidget)) -{ - d->m_sViewURL = viewURL; - d->m_popupItemProperties.setItems(items); - d->m_menuActions.setParentWidget(parentWidget); - d->m_popupFlags = popupFlags; - - connect(this, &QMenu::aboutToShow, this, [this]() { d->aboutToShow(); }); -} - -void KonqPopupMenuPrivate::addNamedAction(const char *name) -{ - QAction *act = m_actions.action(QString::fromLatin1(name)); - if (act) { - q->addAction(act); - } -} - -void KonqPopupMenuPrivate::aboutToShow() -{ - populate(); - KAcceleratorManager::manage(q); -} - -void KonqPopupMenuPrivate::populate() -{ - Q_ASSERT(m_popupItemProperties.items().count() >= 1); - - bool bTrashIncluded = false; - - const KFileItemList lstItems = m_popupItemProperties.items(); - QList lstUrls; - lstUrls.reserve(lstItems.count()); - for (const KFileItem &item : lstItems) { - const QUrl url = item.url(); - lstUrls.append(url); - if (!bTrashIncluded && ((url.scheme() == QLatin1String("trash") && url.path().length() <= 1))) { - bTrashIncluded = true; - } - } - - const bool isDirectory = m_popupItemProperties.isDirectory(); - const bool sReading = m_popupItemProperties.supportsReading(); - bool sDeleting = (m_popupFlags & KonqPopupMenu::NoDeletion) == 0 - && m_popupItemProperties.supportsDeleting(); - const bool sWriting = m_popupItemProperties.supportsWriting(); - const bool sMoving = sDeleting && m_popupItemProperties.supportsMoving(); - - QUrl url = m_sViewURL.adjusted(QUrl::NormalizePathSegments); - - bool isTrashLink = false; - bool isCurrentTrash = false; - bool currentDir = false; - bool isSymLink = false; - bool isSymLinkInSameDir = false; // true for "ln -s foo bar", false for links to foo/sub or /foo - - //check if url is current directory - if (lstItems.count() == 1) { - KFileItem firstPopupItem(lstItems.first()); - if (firstPopupItem.isLink()) { - isSymLink = true; - isSymLinkInSameDir = !firstPopupItem.linkDest().contains(QLatin1Char('/')); - } - QUrl firstPopupURL(firstPopupItem.url().adjusted(QUrl::NormalizePathSegments)); - //kDebug(1203) << "View path is " << url.url(); - //kDebug(1203) << "First popup path is " << firstPopupURL.url(); - currentDir = (firstPopupURL.matches(url, QUrl::StripTrailingSlash)); - if (firstPopupItem.isDesktopFile()) { - KDesktopFile desktopFile(firstPopupItem.localPath()); - const KConfigGroup cfg = desktopFile.desktopGroup(); - isTrashLink = cfg.readEntry("Type") == QLatin1String("Link") - && cfg.readEntry("URL") == QLatin1String("trash:/"); - } - - if (isTrashLink) { - sDeleting = false; - } - - // isCurrentTrash: popup on trash:/ itself, or on the trash.desktop link - isCurrentTrash = (firstPopupURL.scheme() == QLatin1String("trash") && firstPopupURL.path().length() <= 1) - || isTrashLink; - } - - const bool isIntoTrash = (url.scheme() == QLatin1String("trash")) && !isCurrentTrash; // trashed file, not trash:/ itself - - const bool bIsLink = (m_popupFlags & KonqPopupMenu::IsLink); - - //kDebug() << "isLocal=" << isLocal << " url=" << url << " isCurrentTrash=" << isCurrentTrash << " isIntoTrash=" << isIntoTrash << " bTrashIncluded=" << bTrashIncluded; - - ////////////////////////////////////////////////////////////////////////// - - addGroup(KonqPopupMenu::TopActions); // used e.g. for ShowMenuBar. includes a separator at the end - - QAction *act; - - QAction *actNewWindow = 0; - -#if 0 // TODO in the desktop code itself. - if ((flags & KonqPopupMenu::ShowProperties) && isOnDesktop && - !KAuthorized::authorizeKAction("editable_desktop_icons")) { - flags &= ~KonqPopupMenu::ShowProperties; // remove flag - } -#endif - - // Either 'newview' is in the actions we're given (probably in the tabhandling group) - // or we need to insert it ourselves (e.g. for the desktop). - // In the first case, actNewWindow must remain 0. - if (((m_popupFlags & KonqPopupMenu::ShowNewWindow) != 0) && sReading) { - const QString openStr = i18n("&Open"); - actNewWindow = new QAction(m_parentWidget /*for status tips*/); - m_ownActions.append(actNewWindow); - actNewWindow->setIcon(QIcon::fromTheme(QStringLiteral("window-new"))); - actNewWindow->setText(openStr); - QObject::connect(actNewWindow, &QAction::triggered, [this]() { - slotPopupNewView(); - }); - } - - if (isDirectory && sWriting && !isCurrentTrash) { // A dir, and we can create things into it - const bool mkdirRequested = m_popupFlags & KonqPopupMenu::ShowCreateDirectory; - if ((currentDir || mkdirRequested) && m_pMenuNew) { // Current dir -> add the "new" menu - // As requested by KNewFileMenu : - m_pMenuNew->checkUpToDate(); - m_pMenuNew->setPopupFiles(m_popupItemProperties.urlList()); - - q->addAction(m_pMenuNew); - q->addSeparator(); - } else if (mkdirRequested) { - QAction *actNewDir = new QAction(m_parentWidget); - m_ownActions.append(actNewDir); - actNewDir->setIcon(QIcon::fromTheme(QStringLiteral("folder-new"))); - actNewDir->setText(i18n("Create &Folder...")); - QObject::connect(actNewDir, &QAction::triggered, [this]() { - slotPopupNewDir(); - }); - q->addAction(actNewDir); - q->addSeparator(); - } - } else if (isIntoTrash) { - // Trashed item, offer restoring - act = new QAction(m_parentWidget /*for status tips*/); - m_ownActions.append(act); - act->setText(i18n("&Restore")); - //PORT QT5 act->setHelpText(i18n("Restores this file or directory, back to the location where it was deleted from initially")); - QObject::connect(act, &QAction::triggered, [this]() { - slotPopupRestoreTrashedItems(); - }); - q->addAction(act); - } - - if (m_popupFlags & KonqPopupMenu::ShowNavigationItems) { - if (m_popupFlags & KonqPopupMenu::ShowUp) { - addNamedAction("go_up"); - } - addNamedAction("go_back"); - addNamedAction("go_forward"); - if (m_popupFlags & KonqPopupMenu::ShowReload) { - addNamedAction("reload"); - } - q->addSeparator(); - } - - if (!currentDir && isSymLink && !isSymLinkInSameDir) { - // #65151: offer to open the target's parent dir - act = new QAction(m_parentWidget); - m_ownActions.append(act); - act->setText(isDirectory ? i18n("Show Original Directory") : i18n("Show Original File")); - //PORT TO QT5 act->setHelpText(i18n("Opens a new file manager window showing the target of this link, in its parent directory.")); - QObject::connect(act, &QAction::triggered, [this]() { - slotShowOriginalFile(); - }); - q->addAction(act); - } - - // "open in new window" is either provided by us, or by the tabhandling group - if (actNewWindow) { - q->addAction(actNewWindow); - q->addSeparator(); - } - addGroup(KonqPopupMenu::TabHandlingActions); // includes a separator at the end - - if (m_popupFlags & KonqPopupMenu::ShowUrlOperations) { - if (!currentDir && sReading) { - if (sDeleting) { - addNamedAction("cut"); - } - addNamedAction("copy"); - } - - if (isDirectory && sWriting) { - if (currentDir) { - addNamedAction("paste"); - } else { - addNamedAction("pasteto"); - } - } - } - if (isCurrentTrash) { - act = new QAction(m_parentWidget); - m_ownActions.append(act); - act->setIcon(QIcon::fromTheme(QStringLiteral("trash-empty"))); - act->setText(i18n("&Empty Trash Bin")); - KConfig trashConfig(QStringLiteral("trashrc"), KConfig::SimpleConfig); - act->setEnabled(!trashConfig.group("Status").readEntry("Empty", true)); - QObject::connect(act, &QAction::triggered, [this]() { - slotPopupEmptyTrashBin(); - }); - q->addAction(act); - } - if (isCurrentTrash) { - act = new QAction(m_parentWidget); - m_ownActions.append(act); - act->setIcon(QIcon::fromTheme(QStringLiteral("trash-empty"))); - act->setText(i18n("&Configure Trash Bin")); - QObject::connect(act, &QAction::triggered, [this]() { - slotConfigTrashBin(); - }); - q->addAction(act); - } - - // This is used by KHTML, see khtml_popupmenu.rc (copy, selectAll, searchProvider etc.) - // and by DolphinPart (rename, trash, delete) - addGroup(KonqPopupMenu::EditActions); - - if (m_popupFlags & KonqPopupMenu::ShowTextSelectionItems) { - // OK, we have to stop here. - - // Anything else that is provided by the part - addGroup(KonqPopupMenu::CustomActions); - return; - } - - if (!isCurrentTrash && !isIntoTrash && (m_popupFlags & KonqPopupMenu::ShowBookmark)) { - QString caption; - if (currentDir) { - const bool httpPage = m_sViewURL.scheme().startsWith(QLatin1String("http"), Qt::CaseInsensitive); - if (httpPage) { - caption = i18n("&Bookmark This Page"); - } else { - caption = i18n("&Bookmark This Location"); - } - } else if (isDirectory) { - caption = i18n("&Bookmark This Folder"); - } else if (bIsLink) { - caption = i18n("&Bookmark This Link"); - } else { - caption = i18n("&Bookmark This File"); - } - - act = new QAction(m_parentWidget); - m_ownActions.append(act); - act->setObjectName(QLatin1String("bookmark_add")); // for unittest - act->setIcon(QIcon::fromTheme(QStringLiteral("bookmark-new"))); - act->setText(caption); - QObject::connect(act, &QAction::triggered, [this]() { - slotPopupAddToBookmark(); - }); - if (lstItems.count() > 1) { - act->setEnabled(false); - } - if (KAuthorized::authorizeKAction(QStringLiteral("bookmarks"))) { - q->addAction(act); - } - if (bIsLink) { - addGroup(KonqPopupMenu::LinkActions); // see khtml - } - } - - // "Open With" actions - - m_menuActions.setItemListProperties(m_popupItemProperties); - - if (sReading) { - m_menuActions.addOpenWithActionsTo(q, QStringLiteral("DesktopEntryName != 'kfmclient' and DesktopEntryName != 'kfmclient_dir' and DesktopEntryName != 'kfmclient_html'")); - - QList previewActions = m_actionGroups.value(KonqPopupMenu::PreviewActions); - if (!previewActions.isEmpty()) { - if (previewActions.count() == 1) { - q->addAction(previewActions.first()); - } else { - QMenu *subMenu = new QMenu(i18n("Preview In"), q); - subMenu->menuAction()->setObjectName(QLatin1String("preview_submenu")); // for the unittest - q->addMenu(subMenu); - subMenu->addActions(previewActions); - } - } - } - - // Second block, builtin + user - m_menuActions.addServiceActionsTo(q); - - q->addSeparator(); - - // Use the Dolphin setting for showing the "Copy To" and "Move To" actions - KSharedConfig::Ptr dolphin = KSharedConfig::openConfig(QStringLiteral("dolphinrc")); - - // CopyTo/MoveTo menus - if (m_popupFlags & KonqPopupMenu::ShowUrlOperations && - KConfigGroup(dolphin, "General").readEntry("ShowCopyMoveMenu", false)) { - - m_copyToMenu.setUrls(lstUrls); - m_copyToMenu.setReadOnly(sMoving == false); - m_copyToMenu.addActionsTo(q); - q->addSeparator(); - } - - if (!isCurrentTrash && !isIntoTrash && sReading && - (m_popupFlags & KonqPopupMenu::NoPlugins) == 0) { - addPlugins(); // now it's time to add plugins - } - - if ((m_popupFlags & KonqPopupMenu::ShowProperties) && KPropertiesDialog::canDisplay(lstItems)) { - act = new QAction(m_parentWidget); - m_ownActions.append(act); - act->setObjectName(QLatin1String("properties")); // for unittest - act->setText(i18n("&Properties")); - QObject::connect(act, &QAction::triggered, [this]() { - slotPopupProperties(); - }); - q->addAction(act); - } - - while (!q->actions().isEmpty() && - q->actions().last()->isSeparator()) { - delete q->actions().last(); - } - - // Anything else that is provided by the part - addGroup(KonqPopupMenu::CustomActions); - - QObject::connect(&m_menuActions, &KFileItemActions::openWithDialogAboutToBeShown, q, &KonqPopupMenu::openWithDialogAboutToBeShown); -} - -KonqPopupMenu::~KonqPopupMenu() -{ - delete d; - //kDebug(1203) << "~KonqPopupMenu leave"; -} - -void KonqPopupMenu::setNewFileMenu(KNewFileMenu *newMenu) -{ - d->m_pMenuNew = newMenu; -} - -void KonqPopupMenu::setBookmarkManager(KBookmarkManager *manager) -{ - d->m_bookmarkManager = manager; -} - -void KonqPopupMenu::setActionGroups(const KonqPopupMenu::ActionGroupMap &actionGroups) -{ - d->m_actionGroups = actionGroups; -} - -void KonqPopupMenu::setURLTitle(const QString &urlTitle) -{ - d->m_urlTitle = urlTitle; -} - -void KonqPopupMenuPrivate::slotPopupNewView() -{ - Q_FOREACH (const QUrl &url, m_popupItemProperties.urlList()) { - (void) new KRun(url, m_parentWidget); - } -} - -void KonqPopupMenuPrivate::slotPopupNewDir() -{ - m_pMenuNew->createDirectory(); -} - -void KonqPopupMenuPrivate::slotPopupEmptyTrashBin() -{ - KIO::JobUiDelegate uiDelegate; - uiDelegate.setWindow(m_parentWidget); - if (uiDelegate.askDeleteConfirmation(QList(), KIO::JobUiDelegate::EmptyTrash, KIO::JobUiDelegate::DefaultConfirmation)) { - KIO::Job *job = KIO::emptyTrash(); - KJobWidgets::setWindow(job, m_parentWidget); - job->ui()->setAutoErrorHandlingEnabled(true); // or connect to the result signal - } -} - -void KonqPopupMenuPrivate::slotConfigTrashBin() -{ - KRun::run(QStringLiteral("kcmshell5 kcmtrash"), QList(), m_parentWidget); -} - -void KonqPopupMenuPrivate::slotPopupRestoreTrashedItems() -{ - KIO::RestoreJob *job = KIO::restoreFromTrash(m_popupItemProperties.urlList()); - KJobWidgets::setWindow(job, m_parentWidget); - job->uiDelegate()->setAutoErrorHandlingEnabled(true); -} - -void KonqPopupMenuPrivate::slotPopupAddToBookmark() -{ - KBookmarkGroup root; - if (m_popupItemProperties.urlList().count() == 1) { - const QUrl url = m_popupItemProperties.urlList().first(); - const QString title = m_urlTitle.isEmpty() ? url.toDisplayString() : m_urlTitle; - KBookmarkDialog dlg(m_bookmarkManager, m_parentWidget); - dlg.addBookmark(title, url, QString()); - } else { - root = m_bookmarkManager->root(); - Q_FOREACH (const QUrl &url, m_popupItemProperties.urlList()) { - root.addBookmark(url.toDisplayString(), url, QString()); - } - m_bookmarkManager->emitChanged(root); - } -} - -void KonqPopupMenuPrivate::slotPopupMimeType() -{ - KMimeTypeEditor::editMimeType(m_popupItemProperties.mimeType(), m_parentWidget); -} - -void KonqPopupMenuPrivate::slotPopupProperties() -{ - KPropertiesDialog::showDialog(m_popupItemProperties.items(), m_parentWidget, false); -} - -void KonqPopupMenuPrivate::addGroup(KonqPopupMenu::ActionGroup group) -{ - q->addActions(m_actionGroups.value(group)); -} - -void KonqPopupMenuPrivate::addPlugins() -{ - QString commonMimeType = m_popupItemProperties.mimeType(); - if (commonMimeType.isEmpty()) { - commonMimeType = QLatin1String("application/octet-stream"); - } - - const KService::List fileItemPlugins = KMimeTypeTrader::self()->query(commonMimeType, QStringLiteral("KFileItemAction/Plugin"), QStringLiteral("exist Library")); - if (!fileItemPlugins.isEmpty()) { - const KConfig config(QStringLiteral("kservicemenurc"), KConfig::NoGlobals); - const KConfigGroup showGroup = config.group("Show"); - - foreach (const auto &service, fileItemPlugins) { - if (!showGroup.readEntry(service->desktopEntryName(), true)) { - // The plugin has been disabled - continue; - } - - KAbstractFileItemActionPlugin *abstractPlugin = service->createInstance(); - if (abstractPlugin) { - abstractPlugin->setParent(q); - q->addActions(abstractPlugin->actions(m_popupItemProperties, m_parentWidget)); - } - } - } -} - -void KonqPopupMenuPrivate::slotShowOriginalFile() -{ - const KFileItem item = m_popupItemProperties.items().first(); - QUrl destUrl = QUrl::fromLocalFile(item.linkDest()); - - if (!destUrl.isValid()) { - return; - } - - KIO::highlightInFileManager({destUrl}); -} diff --git a/containments/desktop/plugins/folder/internallibkonq/konq_popupmenu.h b/containments/desktop/plugins/folder/internallibkonq/konq_popupmenu.h deleted file mode 100644 index c4aa01991..000000000 --- a/containments/desktop/plugins/folder/internallibkonq/konq_popupmenu.h +++ /dev/null @@ -1,149 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 1998-2016 David Faure - Copyright (C) 2001 Holger Freyther - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __konqpopupmenu_h -#define __konqpopupmenu_h - -#include - -#include - -class KFileItemList; -class KNewFileMenu; -class KFileItemActions; - -class KActionCollection; -class KBookmarkManager; -class KonqPopupMenuPrivate; -class QUrl; - -/** - * This class implements the popup menu for URLs in file managers. - * - * The recommended usage is to use QMenu::popup() to avoid modal popupmenus. - * - * Either reuse the instance, or delete it after use with - * connect(menu, &QMenu::aboutToHide, [menu]() { menu->deleteLater(); }); - * - * Users of KonqPopupMenu include: konqueror, kfind, the folderview desktop plasmoid. - */ -class LIBKONQ_EXPORT KonqPopupMenu : public QMenu -{ - Q_OBJECT -public: - - /** - * Each action group is inserted into the context menu at a specific position. - * "editactions" for actions related text editing, - * "linkactions" for actions related to hyperlinks, - * "partactions" for any other actions provided by the part - */ - enum ActionGroup { - TopActions, ///< actions to be shown at the top of the context menu, like "show menu bar" - TabHandlingActions, ///< actions for tab handling, like "open in new tab" - EditActions, ///< move to trash, delete, etc. - PreviewActions, ///< actions related to viewing the selected file with an embedded viewer - CustomActions, ///< group for more custom actions, such as those provided by KParts components - LinkActions ///< actions related to handling of hyperlinks, only shown if the IsLink flag is set - }; - - typedef QMap > ActionGroupMap; - - /** - * Set of flags to ask for some items in the popup menu. - */ - enum Flag { - DefaultPopupItems = 0x0000, ///< default value, no additional menu item - ShowNavigationItems = 0x0001, ///< show "back" and "forward" (usually done when clicking the background of the view, but not an item) - ShowUp = 0x0002, ///< show "up" (same thing, but not over e.g. HTTP). Requires ShowNavigationItems. - ShowReload = 0x0004, ///< show "reload" (usually done when clicking the background of the view, but not an item) - ShowBookmark = 0x0008, ///< show "add to bookmarks" (usually not done on the local filesystem) - ShowCreateDirectory = 0x0010, ///< show "create directory" (usually only done on the background of the view, or - /// in hierarchical views like directory trees, where the new dir would be visible) - ShowTextSelectionItems = 0x0020, ///< set when selecting text, for a popup that only contains text-related items. - NoDeletion = 0x0040, ///< "cut" not allowed (e.g. parent dir not writeable). - /// (this is only needed if the protocol itself supports deletion, unlike e.g. HTTP) - IsLink = 0x0080, ///< show "Bookmark This Link" and other link-related actions (LinkActions group) - ShowUrlOperations = 0x0100, ///< show copy, paste, as well as cut if NoDeletion is not set. - ShowProperties = 0x0200, ///< show "Properties" action (usually done by directory views) - ShowNewWindow = 0x0400, ///< Show "Open in new window" action - NoPlugins = 0x0800 ///< Disable plugins - mostly for the unittest - }; - Q_DECLARE_FLAGS(Flags, Flag) - - /** - * Constructor - * @param items the list of file items the popupmenu should be shown for - * @param viewURL the URL shown in the view, to test for RMB click on view background - * @param actions list of actions the caller wants to see in the menu - * @param newMenu "New" menu, shared with the File menu, in konqueror - * @param flags flags which control which items to show in the popupmenu - * @param parentWidget the widget we're showing this popup for. Helps destroying - * the popup if the widget is destroyed before the popup. - * - * The actions to pass in the action collection are : - * go_back, go_forward, go_up, reload, cut, copy, paste, pasteto - * The others items are automatically inserted. - */ - KonqPopupMenu(const KFileItemList &items, - const QUrl &viewURL, - KActionCollection &actions, - Flags flags, - QWidget *parentWidget = 0); - - /** - * Don't forget to destroy the object - */ - ~KonqPopupMenu(); - - /** - * Sets the "New file" menu instance. This allows to share it with the menubar. - */ - void setNewFileMenu(KNewFileMenu *newMenu); - - /** - * Sets the bookmark manager for the "add to bookmark" action. - * Only used if ShowBookmark is set - */ - void setBookmarkManager(KBookmarkManager *manager); - - /** - * Sets the additional actions to show in the context menu - */ - void setActionGroups(const ActionGroupMap &actionGroups); - - /** - * Set the title of the URL, when the popupmenu is opened for a single URL. - * This is used if the user chooses to add a bookmark for this URL. - */ - void setURLTitle(const QString &urlTitle); - -Q_SIGNALS: - /** - * Emitted before the "Open With" dialog is shown - * This is used e.g in folderview to close the folder peek popups on invoking the "Open With" menu action - */ - void openWithDialogAboutToBeShown(); - -private: - KonqPopupMenuPrivate *d; -}; - -#endif diff --git a/containments/desktop/plugins/folder/internallibkonq/libkonq_export.h b/containments/desktop/plugins/folder/internallibkonq/libkonq_export.h deleted file mode 100644 index 4a733b447..000000000 --- a/containments/desktop/plugins/folder/internallibkonq/libkonq_export.h +++ /dev/null @@ -1,2 +0,0 @@ -#define LIBKONQ_EXPORT -