filemanager/model/foldermodel.cpp

1648 lines
46 KiB
C++
Raw Normal View History

2021-04-21 10:51:17 -07:00
/***************************************************************************
* Copyright (C) 2006 David Faure <faure@kde.org> *
* Copyright (C) 2008 Fredrik Höglund <fredrik@kde.org> *
* Copyright (C) 2008 Rafael Fernández López <ereslibre@kde.org> *
* Copyright (C) 2011 Marco Martin <mart@kde.org> *
* Copyright (C) 2014 by Eike Hein <hein@kde.org> *
* Copyright (C) 2021 Reven Martin <revenmartin@gmail.com> *
2021-09-12 04:30:01 -07:00
* Copyright (C) 2021 Reion Wong <reionwong@gmail.com> *
2021-04-21 10:51:17 -07:00
* *
* 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 . *
***************************************************************************/
2021-03-29 01:51:34 -07:00
#include "foldermodel.h"
#include "dirlister.h"
#include "../dialogs/filepropertiesdialog.h"
#include "../dialogs/createfolderdialog.h"
2021-07-29 02:38:47 -07:00
#include "../dialogs/openwithdialog.h"
2021-03-29 01:51:34 -07:00
2021-04-21 19:24:10 -07:00
#include "../helper/datehelper.h"
2021-07-28 12:30:17 -07:00
#include "../helper/filelauncher.h"
2021-04-21 19:24:10 -07:00
2021-09-05 14:39:56 -07:00
#include "../cio/cfilesizejob.h"
2021-03-29 01:51:34 -07:00
// Qt
2021-09-01 06:13:47 -07:00
#include <QSet>
2021-03-29 01:51:34 -07:00
#include <QDir>
#include <QMenu>
#include <QAction>
#include <QCollator>
2021-04-01 01:05:15 -07:00
#include <QDBusInterface>
2021-03-29 01:51:34 -07:00
#include <QStandardPaths>
#include <QApplication>
#include <QDesktopWidget>
#include <QMimeDatabase>
#include <QClipboard>
#include <QPainter>
#include <QDrag>
2021-04-01 01:05:15 -07:00
#include <QDir>
2021-05-21 00:55:58 -07:00
#include <QProcess>
2021-09-12 04:30:01 -07:00
#include <QSettings>
2021-07-28 12:30:17 -07:00
#include <QDesktopServices>
2021-03-29 01:51:34 -07:00
// Qt Quick
#include <QQuickItem>
2021-09-03 11:26:01 -07:00
#include <QQmlContext>
2021-03-29 01:51:34 -07:00
// KIO
#include <KIO/CopyJob>
#include <KIO/Job>
#include <KIO/PreviewJob>
#include <KIO/DeleteJob>
#include <KIO/DropJob>
#include <KIO/FileUndoManager>
#include <KIO/JobUiDelegate>
#include <KIO/Paste>
#include <KIO/PasteJob>
#include <KIO/RestoreJob>
#include <KUrlMimeData>
#include <KFileItemListProperties>
#include <KDesktopFile>
FolderModel::FolderModel(QObject *parent)
: QSortFilterProxyModel(parent)
, m_dirWatch(nullptr)
, m_sortMode(0)
, m_sortDesc(false)
, m_sortDirsFirst(true)
2021-09-12 04:30:01 -07:00
, m_showHiddenFiles(false)
2021-08-31 14:08:00 -07:00
, m_filterMode(NoFilter)
, m_filterPatternMatchAll(true)
2021-03-29 01:51:34 -07:00
, m_complete(false)
2021-03-29 07:53:21 -07:00
, m_isDesktop(false)
2021-09-05 14:39:56 -07:00
, m_selectedItemSize("")
2021-03-29 01:51:34 -07:00
, m_actionCollection(this)
, m_dragInProgress(false)
, m_viewAdapter(nullptr)
2021-07-28 12:30:17 -07:00
, m_mimeAppManager(MimeAppManager::self())
2021-09-05 14:39:56 -07:00
, m_sizeJob(nullptr)
2021-09-19 20:04:33 -07:00
, m_keyboardSearchManager(KeyboardSearchManager::self())
2021-03-29 01:51:34 -07:00
{
2021-09-12 04:30:01 -07:00
QSettings settings("cutefishos", qApp->applicationName());
m_showHiddenFiles = settings.value("showHiddenFiles", false).toBool();
m_dirLister = new DirLister(this);
m_dirLister->setDelayedMimeTypes(true);
m_dirLister->setAutoErrorHandlingEnabled(false, nullptr);
m_dirLister->setShowingDotFiles(m_showHiddenFiles);
2021-08-31 14:31:38 -07:00
// connect(dirLister, &DirLister::error, this, &FolderModel::notification);
2021-03-29 01:51:34 -07:00
m_dirModel = new KDirModel(this);
2021-09-12 04:30:01 -07:00
m_dirModel->setDirLister(m_dirLister);
2021-03-29 01:51:34 -07:00
m_dirModel->setDropsAllowed(KDirModel::DropOnDirectory | KDirModel::DropOnLocalExecutable);
2021-04-23 10:46:27 -07:00
m_dirModel->moveToThread(qApp->thread());
2021-03-29 01:51:34 -07:00
m_selectionModel = new QItemSelectionModel(this, this);
connect(m_selectionModel, &QItemSelectionModel::selectionChanged, this, &FolderModel::selectionChanged);
setSourceModel(m_dirModel);
setSortLocaleAware(true);
setFilterCaseSensitivity(Qt::CaseInsensitive);
setDynamicSortFilter(true);
sort(m_sortMode, m_sortDesc ? Qt::DescendingOrder : Qt::AscendingOrder);
createActions();
2021-04-01 01:05:15 -07:00
connect(this, SIGNAL(rowsInserted(QModelIndex, int, int)), SIGNAL(countChanged()));
connect(this, SIGNAL(rowsRemoved(QModelIndex, int, int)), SIGNAL(countChanged()));
connect(this, SIGNAL(modelReset()), SIGNAL(countChanged()));
2021-09-19 20:04:33 -07:00
connect(m_keyboardSearchManager, &KeyboardSearchManager::searchTextChanged,
this, &FolderModel::keyboardSearchChanged);
2021-03-29 01:51:34 -07:00
}
FolderModel::~FolderModel()
{
}
void FolderModel::classBegin()
{
}
void FolderModel::componentComplete()
{
m_complete = true;
invalidate();
}
QHash<int, QByteArray> FolderModel::roleNames() const
{
return staticRoleNames();
}
QHash<int, QByteArray> FolderModel::staticRoleNames()
{
QHash<int, QByteArray> roleNames;
roleNames[Qt::DisplayRole] = "display";
roleNames[Qt::DecorationRole] = "decoration";
roleNames[BlankRole] = "blank";
roleNames[SelectedRole] = "selected";
roleNames[IsDirRole] = "isDir";
2021-09-12 04:30:01 -07:00
roleNames[IsHiddenRole] = "isHidden";
2021-03-29 01:51:34 -07:00
roleNames[UrlRole] = "url";
2021-08-16 18:53:52 -07:00
roleNames[DisplayNameRole] = "displayName";
2021-03-29 01:51:34 -07:00
roleNames[FileNameRole] = "fileName";
2021-04-01 01:05:15 -07:00
roleNames[FileSizeRole] = "fileSize";
2021-03-29 01:51:34 -07:00
roleNames[IconNameRole] = "iconName";
roleNames[ThumbnailRole] = "thumbnail";
2021-04-01 01:05:15 -07:00
roleNames[ModifiedRole] = "modified";
2021-08-16 18:53:52 -07:00
roleNames[IsDesktopFileRole] = "desktopFile";
2021-03-29 01:51:34 -07:00
return roleNames;
}
QVariant FolderModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
KFileItem item = itemForIndex(index);
switch (role) {
case BlankRole:
return m_dragIndexes.contains(index);
case SelectedRole:
return m_selectionModel->isSelected(index);
case UrlRole:
return item.url();
2021-08-16 18:53:52 -07:00
case DisplayNameRole: {
if (item.isDesktopFile())
return "";
return item.url().fileName();
}
2021-03-30 18:22:32 -07:00
case FileNameRole: {
2021-03-29 01:51:34 -07:00
return item.url().fileName();
2021-03-30 18:22:32 -07:00
}
2021-08-16 18:53:52 -07:00
case IsDesktopFileRole: {
return item.isDesktopFile();
}
2021-09-12 04:30:01 -07:00
case IsDirRole: {
return item.isDir();
}
case IsHiddenRole: {
return item.isHidden();
}
2021-04-01 01:05:15 -07:00
case FileSizeRole: {
if (item.isDir()) {
2021-04-01 07:16:42 -07:00
QDir dir(item.url().toLocalFile());
dir.setFilter(QDir::Dirs | QDir::AllEntries | QDir::NoDotAndDotDot);
uint count = dir.count();
2021-04-01 01:05:15 -07:00
return count == 1 ? tr("%1 item").arg(count) : tr("%1 items").arg(count);
}
return KIO::convertSize(item.size());
}
2021-03-29 01:51:34 -07:00
case IconNameRole:
return item.iconName();
case ThumbnailRole: {
if (item.isLocalFile()) {
// Svg Image
if (item.mimetype() == "image/svg" ||
item.mimetype() == "image/svg+xml") {
return item.url();
}
// Support
if (isSupportThumbnails(item.mimetype())) {
return "image://thumbnailer/" + item.url().toString();
}
2021-03-29 01:51:34 -07:00
}
return QVariant();
}
2021-04-01 01:05:15 -07:00
case ModifiedRole: {
2021-04-21 19:24:10 -07:00
return DateHelper::friendlyTime(item.time(KFileItem::ModificationTime));
2021-04-01 01:05:15 -07:00
}
2021-03-29 01:51:34 -07:00
default:
break;
}
return QSortFilterProxyModel::data(index, role);
}
2021-09-19 20:04:33 -07:00
int FolderModel::indexForKeyboardSearch(const QString &text, int startFromIndex) const
{
startFromIndex = qMax(0, startFromIndex);
for (int i = startFromIndex; i < rowCount(); ++i) {
if (fileItem(i).text().startsWith(text, Qt::CaseInsensitive)) {
return i;
}
}
for (int i = 0; i < startFromIndex; ++i) {
if (fileItem(i).text().startsWith(text, Qt::CaseInsensitive)) {
return i;
}
}
return -1;
}
2021-03-29 01:51:34 -07:00
KFileItem FolderModel::itemForIndex(const QModelIndex &index) const
{
return m_dirModel->itemForIndex(mapToSource(index));
}
2021-09-19 20:04:33 -07:00
KFileItem FolderModel::fileItem(int index) const
{
if (index >= 0 && index < count()) {
return itemForIndex(FolderModel::index(index, 0));
}
return KFileItem();
}
2021-03-29 01:51:34 -07:00
QList<QUrl> FolderModel::selectedUrls() const
{
const auto indexes = m_selectionModel->selectedIndexes();
QList<QUrl> urls;
urls.reserve(indexes.count());
for (const QModelIndex &index : indexes) {
urls.append(itemForIndex(index).url());
}
return urls;
}
QString FolderModel::url() const
{
return m_url;
}
void FolderModel::setUrl(const QString &url)
{
2021-03-29 18:48:59 -07:00
if (url.isEmpty())
return;
2021-09-26 07:01:24 -07:00
QUrl resolvedNewUrl = resolve(url);
QFileInfo info(resolvedNewUrl.toLocalFile());
2021-03-29 01:51:34 -07:00
2021-08-31 14:31:38 -07:00
if (!QFile::exists(resolvedNewUrl.toLocalFile()) && !url.startsWith("trash:/")) {
emit notification(tr("The file or folder %1 does not exist.").arg(url));
return;
}
2021-09-26 07:01:24 -07:00
// TODO: selected ?
if (info.isFile()) {
resolvedNewUrl = QUrl::fromLocalFile(info.dir().path());
}
2021-03-29 01:51:34 -07:00
// Refresh this directory.
if (url == m_url) {
m_dirModel->dirLister()->updateDirectory(resolvedNewUrl);
return;
}
m_pathHistory.append(resolvedNewUrl);
beginResetModel();
2021-09-26 07:01:24 -07:00
m_url = resolvedNewUrl.toLocalFile();
2021-03-29 01:51:34 -07:00
m_dirModel->dirLister()->openUrl(resolvedNewUrl);
clearDragImages();
m_dragIndexes.clear();
endResetModel();
emit urlChanged();
emit resolvedUrlChanged();
2021-09-01 06:13:47 -07:00
// if (m_dirWatch) {
// delete m_dirWatch;
// m_dirWatch = nullptr;
// }
2021-03-29 01:51:34 -07:00
2021-09-01 06:13:47 -07:00
// if (resolvedNewUrl.isValid()) {
// m_dirWatch = new KDirWatch(this);
// m_dirWatch->addFile(resolvedNewUrl.toLocalFile() + QLatin1String("/.directory"));
// }
2021-03-29 01:51:34 -07:00
}
QUrl FolderModel::resolvedUrl() const
{
return m_dirModel->dirLister()->url();
}
QUrl FolderModel::resolve(const QString &url)
{
QUrl resolvedUrl;
if (url.startsWith(QLatin1Char('~'))) {
resolvedUrl = QUrl::fromLocalFile(QDir::homePath());
} else {
resolvedUrl = QUrl::fromUserInput(url);
}
return resolvedUrl;
}
FolderModel::Status FolderModel::status() const
{
return m_status;
}
void FolderModel::setStatus(FolderModel::Status status)
{
if (m_status != status) {
m_status = status;
emit statusChanged();
}
}
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 {
invalidateIfComplete();
sort(m_sortMode, m_sortDesc ? Qt::DescendingOrder : Qt::AscendingOrder);
setDynamicSortFilter(true);
}
emit sortModeChanged();
}
}
bool FolderModel::sortDirsFirst() const
{
return m_sortDirsFirst;
}
void FolderModel::setSortDirsFirst(bool enable)
{
if (m_sortDirsFirst != enable) {
m_sortDirsFirst = enable;
if (m_sortMode != -1 /* Unsorted */) {
invalidateIfComplete();
sort(m_sortMode, m_sortDesc ? Qt::DescendingOrder : Qt::AscendingOrder);
}
emit sortDirsFirstChanged();
}
}
2021-08-31 14:08:00 -07:00
int FolderModel::filterMode() const
{
return m_filterMode;
}
void FolderModel::setFilterMode(int filterMode)
{
if (m_filterMode != (FilterMode)filterMode) {
m_filterMode = (FilterMode)filterMode;
invalidateFilterIfComplete();
emit filterModeChanged();
}
}
QStringList FolderModel::filterMimeTypes() const
{
return m_mimeSet.values();
}
void FolderModel::setFilterMimeTypes(const QStringList &mimeList)
{
2021-09-01 06:56:26 -07:00
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
const QSet<QString> &set = QSet<QString>::fromList(mimeList);
#else
const QSet<QString> set(mimeList.constBegin(), mimeList.constEnd());
#endif
2021-08-31 14:08:00 -07:00
if (m_mimeSet != set) {
m_mimeSet = set;
invalidateFilterIfComplete();
emit filterMimeTypesChanged();
}
}
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(QLatin1Char(' '));
m_regExps.clear();
m_regExps.reserve(patterns.count());
foreach (const QString &pattern, patterns) {
QRegExp rx(pattern);
rx.setPatternSyntax(QRegExp::Wildcard);
rx.setCaseSensitivity(Qt::CaseInsensitive);
m_regExps.append(rx);
}
invalidateFilterIfComplete();
emit filterPatternChanged();
}
2021-03-29 01:51:34 -07:00
QObject *FolderModel::viewAdapter() const
{
return m_viewAdapter;
}
void FolderModel::setViewAdapter(QObject *adapter)
{
if (m_viewAdapter != adapter) {
ItemViewAdapter *viewAdapter = dynamic_cast<ItemViewAdapter *>(adapter);
m_viewAdapter = viewAdapter;
emit viewAdapterChanged();
}
}
bool FolderModel::dragging() const
{
return m_dragInProgress;
}
bool FolderModel::isDir(const QModelIndex &index, const KDirModel *dirModel) const
{
KFileItem item = dirModel->itemForIndex(index);
if (item.isDir()) {
return true;
}
return false;
}
bool FolderModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
{
const KDirModel *dirModel = static_cast<KDirModel *>(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<KFileItem>();
const KFileItem rightItem = dirModel->data(right, KDirModel::FileItemRole).value<KFileItem>();
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 long long leftTime = leftItem.entry().numberValue(KIO::UDSEntry::UDS_MODIFICATION_TIME, -1);
const long long rightTime = rightItem.entry().numberValue(KIO::UDSEntry::UDS_MODIFICATION_TIME, -1);
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);
}
Qt::DropActions FolderModel::supportedDragActions() const
{
return Qt::CopyAction | Qt::MoveAction | Qt::LinkAction;
}
Qt::DropActions FolderModel::supportedDropActions() const
{
return Qt::CopyAction | Qt::MoveAction | Qt::LinkAction;
}
KFileItem FolderModel::rootItem() const
{
return m_dirModel->dirLister()->rootItem();
}
2021-04-01 01:05:15 -07:00
int FolderModel::count() const
2021-03-29 01:51:34 -07:00
{
2021-04-01 01:05:15 -07:00
return rowCount();
2021-03-29 01:51:34 -07:00
}
2021-05-30 00:33:45 -07:00
int FolderModel::selectionCount() const
2021-03-31 19:25:20 -07:00
{
return m_selectionModel->selectedIndexes().size();
}
2021-03-29 01:51:34 -07:00
QString FolderModel::homePath() const
{
return QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
}
QString FolderModel::desktopPath() const
{
return QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
}
QAction *FolderModel::action(const QString &name) const
{
return m_actionCollection.action(name);
}
void FolderModel::up()
{
const QUrl &url = KIO::upUrl(resolvedUrl());
if (url.isValid()) {
setUrl(url.toString());
}
}
void FolderModel::goBack()
{
QUrl url = m_pathHistory.previousPath();
if (url.isEmpty())
url = resolvedUrl();
setUrl(url.toString());
}
void FolderModel::goForward()
{
QUrl url = m_pathHistory.posteriorPath();
if (url.isEmpty())
url = resolvedUrl();
setUrl(url.toString());
}
2021-08-31 13:39:44 -07:00
void FolderModel::refresh()
{
m_dirModel->dirLister()->updateDirectory(m_dirModel->dirLister()->url());
}
2021-03-29 01:51:34 -07:00
bool FolderModel::supportSetAsWallpaper(const QString &mimeType)
{
if (mimeType == "image/jpeg" || mimeType == "image/png")
return true;
return false;
}
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() const
{
return m_selectionModel->hasSelection();
}
bool FolderModel::isSelected(int row) const
{
if (row < 0)
return false;
return m_selectionModel->isSelected(index(row, 0));
}
bool FolderModel::isBlank(int row) const
{
if (row < 0) {
return true;
}
return data(index(row, 0), BlankRole).toBool();
}
void FolderModel::setSelected(int row)
{
if (row < 0)
return;
m_selectionModel->select(index(row, 0), QItemSelectionModel::Select);
}
void FolderModel::selectAll()
{
setRangeSelected(0, rowCount() - 1);
}
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::newFolder()
{
CreateFolderDialog *dlg = new CreateFolderDialog;
dlg->setPath(rootItem().url().toString());
dlg->show();
}
2021-03-29 01:51:34 -07:00
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);
}
void FolderModel::copy()
{
if (!m_selectionModel->hasSelection())
return;
if (QAction *action = m_actionCollection.action("copy"))
if (!action->isEnabled())
return;
QMimeData *mimeData = QSortFilterProxyModel::mimeData(m_selectionModel->selectedIndexes());
QApplication::clipboard()->setMimeData(mimeData);
}
void FolderModel::paste()
{
2021-06-15 21:43:43 -07:00
const QMimeData *mimeData = QApplication::clipboard()->mimeData();
bool enable = false;
// Update paste action
if (QAction *paste = m_actionCollection.action(QStringLiteral("paste"))) {
QList<QUrl> urls = KUrlMimeData::urlsFromMimeData(mimeData);
if (!urls.isEmpty()) {
if (!rootItem().isNull()) {
enable = rootItem().isWritable();
}
}
paste->setEnabled(enable);
}
2021-03-29 01:51:34 -07:00
2021-06-15 21:43:43 -07:00
if (enable) {
KIO::paste(mimeData, m_dirModel->dirLister()->url());
}
2021-03-29 01:51:34 -07:00
}
void FolderModel::cut()
{
if (!m_selectionModel->hasSelection())
return;
if (QAction *action = m_actionCollection.action("cut"))
if (!action->isEnabled())
return;
QMimeData *mimeData = QSortFilterProxyModel::mimeData(m_selectionModel->selectedIndexes());
KIO::setClipboardDataCut(mimeData, true);
QApplication::clipboard()->setMimeData(mimeData);
}
void FolderModel::openSelected()
{
if (!m_selectionModel->hasSelection())
return;
const QList<QUrl> urls = selectedUrls();
2021-03-29 07:53:21 -07:00
if (!m_isDesktop) {
if (urls.size() == 1 && KFileItem(urls.first()).isDir()) {
setUrl(urls.first().toLocalFile());
return;
}
2021-03-29 01:51:34 -07:00
}
for (const QUrl &url : urls) {
2021-07-28 12:30:17 -07:00
KFileItem item(url);
2021-07-28 12:44:29 -07:00
QString mimeType = item.mimetype();
// runnable
if (mimeType == "application/x-executable" ||
mimeType == "application/x-sharedlib" ||
mimeType == "application/x-iso9660-appimage" ||
mimeType == "application/vnd.appimage") {
QFileInfo fileInfo(url.toLocalFile());
if (!fileInfo.isExecutable()) {
QFile file(url.toLocalFile());
file.setPermissions(file.permissions() | QFile::ExeOwner | QFile::ExeUser | QFile::ExeGroup | QFile::ExeOther);
}
FileLauncher::self()->launchExecutable(url.toLocalFile());
continue;
}
2021-07-28 12:30:17 -07:00
QString defaultAppDesktopFile = m_mimeAppManager->getDefaultAppByMimeType(item.currentMimeType());
// If no default application is found,
// look for the first one of the frequently used applications.
if (defaultAppDesktopFile.isEmpty()) {
QStringList recommendApps = m_mimeAppManager->getRecommendedAppsByMimeType(item.currentMimeType());
if (recommendApps.count() > 0) {
defaultAppDesktopFile = recommendApps.first();
}
}
if (!defaultAppDesktopFile.isEmpty()) {
FileLauncher::self()->launchApp(defaultAppDesktopFile, url.toLocalFile());
continue;
}
QDesktopServices::openUrl(url);
2021-03-29 01:51:34 -07:00
}
}
2021-07-29 02:38:47 -07:00
void FolderModel::showOpenWithDialog()
{
if (!m_selectionModel->hasSelection())
return;
const QList<QUrl> urls = selectedUrls();
OpenWithDialog *dlg = new OpenWithDialog(urls.first());
dlg->show();
}
2021-03-29 01:51:34 -07:00
void FolderModel::deleteSelected()
{
if (!m_selectionModel->hasSelection()) {
return;
}
if (QAction *action = m_actionCollection.action(QStringLiteral("del"))) {
if (!action->isEnabled()) {
return;
}
}
2021-09-03 11:26:01 -07:00
KIO::DeleteJob *job = KIO::del(selectedUrls());
job->start();
2021-03-29 01:51:34 -07:00
}
void FolderModel::moveSelectedToTrash()
{
if (!m_selectionModel->hasSelection()) {
return;
}
if (QAction *action = m_actionCollection.action(QStringLiteral("trash"))) {
if (!action->isEnabled()) {
return;
}
}
const QList<QUrl> urls = selectedUrls();
KIO::JobUiDelegate uiDelegate;
if (uiDelegate.askDeleteConfirmation(urls, KIO::JobUiDelegate::Trash, KIO::JobUiDelegate::DefaultConfirmation)) {
KIO::Job *job = KIO::trash(urls);
job->uiDelegate()->setAutoErrorHandlingEnabled(true);
KIO::FileUndoManager::self()->recordJob(KIO::FileUndoManager::Trash, urls, QUrl(QStringLiteral("trash:/")), job);
}
}
void FolderModel::emptyTrash()
{
2021-05-21 00:55:58 -07:00
QProcess::startDetached("cutefish-filemanager", QStringList() << "-e");
2021-03-29 01:51:34 -07:00
}
2021-03-31 19:25:20 -07:00
void FolderModel::keyDeletePress()
{
if (!m_selectionModel->hasSelection())
return;
2021-09-03 11:26:01 -07:00
resolvedUrl().scheme() == "trash" ? openDeleteDialog() : moveSelectedToTrash();
2021-03-31 19:25:20 -07:00
}
2021-03-29 01:51:34 -07:00
void FolderModel::setDragHotSpotScrollOffset(int x, int y)
{
m_dragHotSpotScrollOffset.setX(x);
m_dragHotSpotScrollOffset.setY(y);
}
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<QImage>();
dragImage->blank = false;
m_dragImages.insert(row, dragImage);
}
void FolderModel::clearDragImages()
{
qDeleteAll(m_dragImages);
m_dragImages.clear();
}
void FolderModel::dragSelected(int x, int y)
{
if (m_dragInProgress)
return;
m_dragInProgress = true;
emit draggingChanged();
QMetaObject::invokeMethod(this, "dragSelectedInternal", Qt::QueuedConnection, Q_ARG(int, x), Q_ARG(int, y));
}
void FolderModel::setWallpaperSelected()
{
if (!m_selectionModel)
return;
QUrl url = selectedUrls().first();
if (!url.isLocalFile())
return;
2021-09-15 00:46:38 -07:00
QDBusInterface iface("com.cutefish.Settings", "/Theme",
"com.cutefish.Theme",
2021-03-29 01:51:34 -07:00
QDBusConnection::sessionBus(), nullptr);
if (iface.isValid())
iface.call("setWallpaper", url.toLocalFile());
}
void FolderModel::openContextMenu(QQuickItem *visualParent, Qt::KeyboardModifiers modifiers)
{
Q_UNUSED(modifiers);
updateActions();
const QModelIndexList indexes = m_selectionModel->selectedIndexes();
QMenu *menu = new QMenu;
// Open folder menu.
2021-03-29 01:51:34 -07:00
if (indexes.isEmpty()) {
QAction *selectAll = new QAction(tr("Select All"), this);
connect(selectAll, &QAction::triggered, this, &FolderModel::selectAll);
menu->addAction(m_actionCollection.action("newFolder"));
menu->addSeparator();
menu->addAction(m_actionCollection.action("paste"));
menu->addAction(selectAll);
if (m_actionCollection.action("terminal")->isVisible()) {
menu->addSeparator();
menu->addAction(m_actionCollection.action("terminal"));
}
if (m_isDesktop) {
menu->addAction(m_actionCollection.action("changeBackground"));
}
2021-09-16 00:01:07 -07:00
menu->addSeparator();
2021-09-12 04:30:01 -07:00
menu->addAction(m_actionCollection.action("showHidden"));
2021-03-29 01:51:34 -07:00
menu->addSeparator();
menu->addAction(m_actionCollection.action("emptyTrash"));
menu->addAction(m_actionCollection.action("properties"));
} else {
// Open the items menu.
2021-09-03 10:47:54 -07:00
// Trash items
menu->addAction(m_actionCollection.action("restore"));
2021-03-29 01:51:34 -07:00
menu->addAction(m_actionCollection.action("open"));
2021-07-29 02:38:47 -07:00
menu->addAction(m_actionCollection.action("openWith"));
2021-03-29 01:51:34 -07:00
menu->addAction(m_actionCollection.action("cut"));
menu->addAction(m_actionCollection.action("copy"));
menu->addAction(m_actionCollection.action("trash"));
menu->addAction(m_actionCollection.action("del"));
menu->addAction(m_actionCollection.action("rename"));
if (m_actionCollection.action("terminal")->isVisible()) {
menu->addSeparator();
menu->addAction(m_actionCollection.action("terminal"));
}
menu->addAction(m_actionCollection.action("wallpaper"));
menu->addSeparator();
menu->addAction(m_actionCollection.action("properties"));
}
QPoint position;
if (visualParent) {
position = visualParent->mapToGlobal(QPointF(0, visualParent->height())).toPoint();
} else {
position = QCursor::pos();
}
menu->installEventFilter(this);
menu->setAttribute(Qt::WA_TranslucentBackground);
menu->winId();
menu->popup(position);
connect(menu, &QMenu::aboutToHide, [menu]() {
menu->deleteLater();
});
}
void FolderModel::openPropertiesDialog()
{
const QModelIndexList indexes = m_selectionModel->selectedIndexes();
if (indexes.isEmpty()) {
FilePropertiesDialog *dlg = new FilePropertiesDialog(QUrl::fromLocalFile(url()));
dlg->show();
2021-03-29 01:51:34 -07:00
return;
}
KFileItemList items;
items.reserve(indexes.count());
for (const QModelIndex &index : indexes) {
KFileItem item = itemForIndex(index);
if (!item.isNull()) {
items.append(item);
}
}
FilePropertiesDialog *dlg = new FilePropertiesDialog(items);
dlg->show();
2021-03-29 01:51:34 -07:00
}
void FolderModel::openInTerminal()
{
QString url;
if (m_selectionModel->hasSelection()) {
KFileItem item = itemForIndex(m_selectionModel->selectedIndexes().first());
if (item.isDir()) {
url = item.url().toLocalFile();
}
} else {
url = rootItem().url().toLocalFile();
}
2021-07-28 12:30:17 -07:00
m_mimeAppManager->launchTerminal(url);
2021-03-29 01:51:34 -07:00
}
void FolderModel::openChangeWallpaperDialog()
{
QProcess::startDetached("cutefish-settings", QStringList() << "-m" << "background");
}
2021-09-03 11:26:01 -07:00
void FolderModel::openDeleteDialog()
{
QQuickView *view = new QQuickView;
view->setModality(Qt::ApplicationModal);
view->setFlags(Qt::Dialog);
view->setTitle(tr("File Manager"));
view->setResizeMode(QQuickView::SizeRootObjectToView);
view->setSource(QUrl("qrc:/qml/Dialogs/DeleteDialog.qml"));
view->rootContext()->setContextProperty("model", this);
view->rootContext()->setContextProperty("view", view);
connect(view, &QQuickView::visibleChanged, this, [=] {
if (!view->isVisible()) {
view->deleteLater();
}
});
view->show();
}
2021-09-05 14:39:56 -07:00
void FolderModel::updateSelectedItemsSize()
{
}
2021-09-03 10:47:54 -07:00
void FolderModel::restoreFromTrash()
{
if (!m_selectionModel->hasSelection())
return;
if (QAction *action = m_actionCollection.action("restore"))
if (!action->isVisible())
return;
KIO::RestoreJob *job = KIO::restoreFromTrash(selectedUrls());
job->start();
}
2021-03-29 01:51:34 -07:00
void FolderModel::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
{
QModelIndexList indices = selected.indexes();
indices.append(deselected.indexes());
QVector<int> 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()) {
delete m_dragImages.take(idx.row());
}
}
2021-09-05 14:39:56 -07:00
if (m_sizeJob == nullptr) {
m_sizeJob = new CFileSizeJob;
connect(m_sizeJob, &CFileSizeJob::sizeChanged, this, [=] {
m_selectedItemSize = KIO::convertSize(m_sizeJob->totalSize());
if (!m_selectionModel->hasSelection())
m_selectedItemSize = "";
emit selectedItemSizeChanged();
});
connect(m_sizeJob, &CFileSizeJob::result, this, [=] {
m_selectedItemSize = KIO::convertSize(m_sizeJob->totalSize());
if (!m_selectionModel->hasSelection())
m_selectedItemSize = "";
emit selectedItemSizeChanged();
});
}
m_sizeJob->stop();
if (!m_selectionModel->hasSelection()) {
m_sizeJob->blockSignals(true);
m_selectedItemSize = "";
emit selectedItemSizeChanged();
} else {
m_sizeJob->blockSignals(false);
m_sizeJob->start(selectedUrls());
}
2021-03-29 01:51:34 -07:00
updateActions();
2021-05-30 00:33:45 -07:00
emit selectionCountChanged();
2021-03-29 01:51:34 -07:00
}
void FolderModel::dragSelectedInternal(int x, int y)
{
if (!m_viewAdapter || !m_selectionModel->hasSelection()) {
m_dragInProgress = false;
emit draggingChanged();
return;
}
QQuickItem *item = qobject_cast<QQuickItem *>(m_viewAdapter->adapterView());
QDrag *drag = new QDrag(item);
addDragImage(drag, x, y);
m_dragIndexes = m_selectionModel->selectedIndexes();
std::sort(m_dragIndexes.begin(), m_dragIndexes.end());
// TODO: Optimize to emit contiguous groups.
emit dataChanged(m_dragIndexes.first(), m_dragIndexes.last(), QVector<int>() << BlankRole);
QModelIndexList sourceDragIndexes;
sourceDragIndexes.reserve(m_dragIndexes.count());
foreach (const QModelIndex &index, m_dragIndexes) {
sourceDragIndexes.append(mapToSource(index));
}
drag->setMimeData(m_dirModel->mimeData(sourceDragIndexes));
// Due to spring-loading (aka auto-expand), the URL might change
// while the drag is in-flight - in that case we don't want to
// unnecessarily emit dataChanged() for (possibly invalid) indices
// after it ends.
const QUrl currentUrl(m_dirModel->dirLister()->url());
item->grabMouse();
drag->exec(supportedDragActions());
item->ungrabMouse();
m_dragInProgress = false;
emit draggingChanged();
if (m_dirModel->dirLister()->url() == currentUrl) {
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<int>() << BlankRole);
}
2021-09-19 20:04:33 -07:00
}
void FolderModel::keyboardSearchChanged(const QString &text, bool searchFromNextItem)
{
Q_UNUSED(searchFromNextItem);
if (rowCount() == 0)
return;
int index;
int currentIndex = -1;
if (m_selectionModel->hasSelection()) {
currentIndex = m_selectionModel->selectedIndexes().first().row();
}
// if (searchFromNextItem) {
// index = indexForKeyboardSearch(text, (currentIndex + 1) % rowCount());
// } else {
// index = indexForKeyboardSearch(text, 0);
// }
index = indexForKeyboardSearch(text, (currentIndex + 1) % rowCount());
if (index < 0 || currentIndex == index)
return;
if (index >= 0) {
clearSelection();
setSelected(index);
}
2021-03-29 01:51:34 -07:00
}
bool FolderModel::isSupportThumbnails(const QString &mimeType) const
{
const QStringList supportsMimetypes = {"image/bmp", "image/png", "image/gif", "image/jpeg", "image/web",
2021-06-01 22:25:04 -07:00
/*"application/pdf", "application/rtf", "application/doc", "application/odf",
"audio/mpeg", "video/mp4"*/};
2021-03-29 01:51:34 -07:00
if (supportsMimetypes.contains(mimeType))
return true;
return false;
}
2021-08-31 14:08:00 -07:00
bool FolderModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
const KDirModel *dirModel = static_cast<KDirModel *>(sourceModel());
const KFileItem item = dirModel->itemForIndex(dirModel->index(sourceRow, KDirModel::Name, sourceParent));
if (m_filterMode == NoFilter) {
return true;
}
if (m_filterMode == FilterShowMatches) {
return (matchPattern(item) && matchMimeType(item));
} else {
return !(matchPattern(item) && matchMimeType(item));
}
}
bool FolderModel::matchMimeType(const KFileItem &item) const
{
if (m_mimeSet.isEmpty()) {
return false;
}
if (m_mimeSet.contains(QLatin1String("all/all")) || m_mimeSet.contains(QLatin1String("all/allfiles"))) {
return true;
}
const QString mimeType = item.determineMimeType().name();
return m_mimeSet.contains(mimeType);
}
bool FolderModel::matchPattern(const KFileItem &item) const
{
if (m_filterPatternMatchAll) {
return true;
}
const QString name = item.name();
QListIterator<QRegExp> i(m_regExps);
while (i.hasNext()) {
if (i.next().exactMatch(name)) {
return true;
}
}
return false;
}
2021-09-12 04:30:01 -07:00
bool FolderModel::showHiddenFiles() const
{
return m_showHiddenFiles;
}
void FolderModel::setShowHiddenFiles(bool showHiddenFiles)
{
if (m_showHiddenFiles != showHiddenFiles) {
m_showHiddenFiles = showHiddenFiles;
m_dirLister->setShowingDotFiles(m_showHiddenFiles);
m_dirLister->emitChanges();
QSettings settings("cutefishos", qApp->applicationName());
settings.setValue("showHiddenFiles", m_showHiddenFiles);
emit showHiddenFilesChanged();
}
}
2021-09-05 14:39:56 -07:00
QString FolderModel::selectedItemSize() const
{
return m_selectedItemSize;
}
2021-03-29 07:53:21 -07:00
bool FolderModel::isDesktop() const
{
return m_isDesktop;
}
void FolderModel::setIsDesktop(bool isDesktop)
{
if (m_isDesktop == isDesktop)
return;
m_isDesktop = isDesktop;
emit isDesktopChanged();
}
2021-03-29 01:51:34 -07:00
void FolderModel::invalidateIfComplete()
{
if (!m_complete)
return;
invalidate();
}
void FolderModel::invalidateFilterIfComplete()
{
if (!m_complete)
return;
invalidateFilter();
}
void FolderModel::createActions()
{
QAction *open = new QAction(tr("Open"), this);
connect(open, &QAction::triggered, this, &FolderModel::openSelected);
2021-07-29 02:38:47 -07:00
QAction *openWith = new QAction(tr("Open with"), this);
connect(openWith, &QAction::triggered, this, &FolderModel::showOpenWithDialog);
2021-03-29 01:51:34 -07:00
QAction *cut = new QAction(tr("Cut"), this);
connect(cut, &QAction::triggered, this, &FolderModel::cut);
QAction *copy = new QAction(tr("Copy"), this);
connect(copy, &QAction::triggered, this, &FolderModel::copy);
QAction *paste = new QAction(tr("Paste"), this);
connect(paste, &QAction::triggered, this, &FolderModel::paste);
QAction *newFolder = new QAction(tr("New Folder"), this);
connect(newFolder, &QAction::triggered, this, &FolderModel::newFolder);
2021-03-29 01:51:34 -07:00
QAction *trash = new QAction(tr("Move To Trash"), this);
connect(trash, &QAction::triggered, this, &FolderModel::moveSelectedToTrash);
QAction *emptyTrash = new QAction(tr("Empty Trash"), this);
connect(emptyTrash, &QAction::triggered, this, &FolderModel::emptyTrash);
QAction *del = new QAction(tr("Delete"), this);
2021-09-03 11:26:01 -07:00
connect(del, &QAction::triggered, this, &FolderModel::openDeleteDialog);
2021-03-29 01:51:34 -07:00
QAction *rename = new QAction(tr("Rename"), this);
connect(rename, &QAction::triggered, this, &FolderModel::requestRename);
QAction *terminal = new QAction(tr("Open in Terminal"), this);
connect(terminal, &QAction::triggered, this, &FolderModel::openInTerminal);
QAction *wallpaper = new QAction(tr("Set as Wallpaper"), this);
connect(wallpaper, &QAction::triggered, this, &FolderModel::setWallpaperSelected);
QAction *properties = new QAction(tr("Properties"), this);
QObject::connect(properties, &QAction::triggered, this, &FolderModel::openPropertiesDialog);
QAction *changeBackground = new QAction(tr("Change background"), this);
QObject::connect(changeBackground, &QAction::triggered, this, &FolderModel::openChangeWallpaperDialog);
2021-09-03 10:47:54 -07:00
QAction *restore = new QAction(tr("Restore"), this);
QObject::connect(restore, &QAction::triggered, this, &FolderModel::restoreFromTrash);
2021-09-12 04:30:01 -07:00
QAction *showHidden = new QAction(tr("Show hidden files"), this);
QObject::connect(showHidden, &QAction::triggered, this, [=] {
setShowHiddenFiles(!m_showHiddenFiles);
});
2021-03-29 01:51:34 -07:00
m_actionCollection.addAction(QStringLiteral("open"), open);
2021-07-29 02:38:47 -07:00
m_actionCollection.addAction(QStringLiteral("openWith"), openWith);
2021-03-29 01:51:34 -07:00
m_actionCollection.addAction(QStringLiteral("cut"), cut);
m_actionCollection.addAction(QStringLiteral("copy"), copy);
m_actionCollection.addAction(QStringLiteral("paste"), paste);
m_actionCollection.addAction(QStringLiteral("newFolder"), newFolder);
m_actionCollection.addAction(QStringLiteral("trash"), trash);
m_actionCollection.addAction(QStringLiteral("emptyTrash"), emptyTrash);
m_actionCollection.addAction(QStringLiteral("del"), del);
m_actionCollection.addAction(QStringLiteral("rename"), rename);
m_actionCollection.addAction(QStringLiteral("terminal"), terminal);
m_actionCollection.addAction(QStringLiteral("wallpaper"), wallpaper);
m_actionCollection.addAction(QStringLiteral("properties"), properties);
m_actionCollection.addAction(QStringLiteral("changeBackground"), changeBackground);
2021-09-03 10:47:54 -07:00
m_actionCollection.addAction(QStringLiteral("restore"), restore);
2021-09-12 04:30:01 -07:00
m_actionCollection.addAction(QStringLiteral("showHidden"), showHidden);
2021-03-29 01:51:34 -07:00
}
void FolderModel::updateActions()
{
const QModelIndexList indexes = m_selectionModel->selectedIndexes();
KFileItemList items;
QList<QUrl> urls;
bool hasRemoteFiles = false;
bool isTrashLink = false;
const bool isTrash = (resolvedUrl().scheme() == QLatin1String("trash"));
if (indexes.isEmpty()) {
items << rootItem();
} else {
items.reserve(indexes.count());
urls.reserve(indexes.count());
for (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.hasLinkType() && file.readUrl() == QLatin1String("trash:/")) {
isTrashLink = true;
}
}
2021-09-03 10:47:54 -07:00
if (QAction *openAction = m_actionCollection.action(QStringLiteral("open"))) {
openAction->setVisible(!isTrash);
}
if (QAction *copyAction = m_actionCollection.action(QStringLiteral("copy"))) {
copyAction->setVisible(!isTrash);
}
if (QAction *cutAction = m_actionCollection.action(QStringLiteral("cut"))) {
cutAction->setVisible(!isTrash);
}
if (QAction *restoreAction = m_actionCollection.action(QStringLiteral("restore"))) {
restoreAction->setVisible(items.count() >= 1 && isTrash);
}
2021-07-29 02:38:47 -07:00
if (QAction *openWith = m_actionCollection.action(QStringLiteral("openWith"))) {
2021-09-03 10:47:54 -07:00
openWith->setVisible(items.count() == 1 && !isTrash);
2021-07-29 02:38:47 -07:00
}
2021-03-29 01:51:34 -07:00
if (QAction *newFolder = m_actionCollection.action(QStringLiteral("newFolder"))) {
newFolder->setVisible(!isTrash);
newFolder->setEnabled(rootItem().isWritable());
}
if (QAction *paste = m_actionCollection.action(QStringLiteral("paste"))) {
bool enable = false;
2021-06-15 21:43:43 -07:00
const QMimeData *mimeData = QApplication::clipboard()->mimeData();
QList<QUrl> urls = KUrlMimeData::urlsFromMimeData(mimeData);
2021-03-29 01:51:34 -07:00
2021-06-15 21:43:43 -07:00
if (!urls.isEmpty()) {
if (!rootItem().isNull()) {
enable = rootItem().isWritable();
}
2021-03-29 01:51:34 -07:00
}
paste->setEnabled(enable);
}
if (QAction *rename = m_actionCollection.action(QStringLiteral("rename"))) {
rename->setEnabled(itemProperties.supportsMoving());
rename->setVisible(!isTrash);
}
if (QAction *trash = m_actionCollection.action("trash")) {
trash->setEnabled(itemProperties.supportsMoving());
trash->setVisible(!isTrash);
}
if (QAction *emptyTrash = m_actionCollection.action("emptyTrash")) {
emptyTrash->setVisible(isTrash);
}
if (QAction *del = m_actionCollection.action(QStringLiteral("del"))) {
del->setVisible(isTrash && itemProperties.supportsDeleting());
}
if (QAction *terminal = m_actionCollection.action("terminal")) {
2021-09-03 10:47:54 -07:00
terminal->setVisible(items.size() == 1 && items.first().isDir() && !isTrash);
2021-03-29 01:51:34 -07:00
}
if (QAction *terminal = m_actionCollection.action("wallpaper")) {
terminal->setVisible(items.size() == 1 && supportSetAsWallpaper(items.first().mimetype()));
}
if (QAction *properties = m_actionCollection.action("properties")) {
properties->setVisible(!isTrash);
}
2021-09-12 04:30:01 -07:00
if (QAction *showHidden = m_actionCollection.action("showHidden")) {
showHidden->setCheckable(true);
showHidden->setChecked(m_showHiddenFiles);
}
2021-03-29 01:51:34 -07:00
}
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()));
}