mirror of
https://bitbucket.org/smil3y/kde-workspace.git
synced 2025-02-24 10:52:51 +00:00
2314 lines
80 KiB
C++
2314 lines
80 KiB
C++
/*
|
|
* Copyright © 2008, 2009 Fredrik Höglund <fredrik@kde.org>
|
|
* Copyright © 2008 Rafael Fernández López <ereslibre@kde.org>
|
|
*
|
|
* 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 "folderview.h"
|
|
|
|
#include <QClipboard>
|
|
#include <QDesktopWidget>
|
|
#include <QGraphicsLinearLayout>
|
|
#include <QGraphicsView>
|
|
#include <QtGui/qgraphicssceneevent.h>
|
|
#include <QImageReader>
|
|
#include <QItemSelectionModel>
|
|
|
|
#include <KAction>
|
|
#include <KBookmarkManager>
|
|
#include <KConfigDialog>
|
|
#include <KDebug>
|
|
#include <KDesktopFile>
|
|
#include <KDirModel>
|
|
#include <KFileItemDelegate>
|
|
#include <kfileplacesmodel.h>
|
|
#include <kfilepreviewgenerator.h>
|
|
#include <KGlobalSettings>
|
|
#include <KProtocolInfo>
|
|
#include <KStandardShortcut>
|
|
#include <KStringHandler>
|
|
#include <KTemporaryFile>
|
|
#include <KStandardDirs>
|
|
#include <KMenu>
|
|
#include <KServiceTypeTrader>
|
|
|
|
#include <kio/copyjob.h>
|
|
#include <kio/fileundomanager.h>
|
|
#include <kio/paste.h>
|
|
#include <kfileitemactions.h>
|
|
#include <kfileitemlistproperties.h>
|
|
#include <knewfilemenu.h>
|
|
#include <konqmimedata.h>
|
|
#include <konq_operations.h>
|
|
#include <konq_popupmenu.h>
|
|
|
|
#include <limits.h>
|
|
|
|
|
|
#include <Plasma/Corona>
|
|
#include <Plasma/PaintUtils>
|
|
#include <Plasma/Theme>
|
|
#include <Plasma/ToolTipManager>
|
|
#include <Plasma/Wallpaper>
|
|
#include <Plasma/WindowEffects>
|
|
#include <Plasma/Applet>
|
|
|
|
#include "dialog.h"
|
|
#include "folderviewadapter.h"
|
|
#include "iconwidget.h"
|
|
#include "label.h"
|
|
#include "previewpluginsmodel.h"
|
|
#include "proxymodel.h"
|
|
#include "listview.h"
|
|
#include <kcompletionbox.h>
|
|
|
|
|
|
K_EXPORT_PLASMA_APPLET(folderview, FolderView)
|
|
|
|
Q_DECLARE_METATYPE(Qt::SortOrder)
|
|
Q_DECLARE_METATYPE(ProxyModel::FilterMode)
|
|
Q_DECLARE_METATYPE(IconView::Flow)
|
|
Q_DECLARE_METATYPE(IconView::Layout)
|
|
Q_DECLARE_METATYPE(IconView::Alignment)
|
|
Q_DECLARE_METATYPE(FolderView::LabelType)
|
|
|
|
MimeModel::MimeModel(QObject *parent)
|
|
: QStringListModel(parent)
|
|
{
|
|
m_mimetypes = KMimeType::allMimeTypes();
|
|
}
|
|
|
|
QVariant MimeModel::data(const QModelIndex &index, int role) const
|
|
{
|
|
if (!index.isValid()) {
|
|
return QVariant();
|
|
}
|
|
|
|
KMimeType *mime = static_cast<KMimeType*>(index.internalPointer());
|
|
|
|
if (!mime) {
|
|
return QVariant();
|
|
}
|
|
|
|
switch (role) {
|
|
case Qt::DisplayRole: {
|
|
if (!mime->comment().isEmpty()) {
|
|
QString description;
|
|
if (mime->patterns().count()) {
|
|
description = mime->patterns().join(", ");
|
|
} else {
|
|
description = mime->name();
|
|
}
|
|
return QString("%1 (%2)").arg(mime->comment()).arg(description);
|
|
} else {
|
|
return mime->name();
|
|
}
|
|
}
|
|
case Qt::DecorationRole:
|
|
return KIcon(mime->iconName());
|
|
case Qt::CheckStateRole:
|
|
return m_state[mime];
|
|
default:
|
|
return QStringListModel::data(index, role);
|
|
}
|
|
}
|
|
|
|
Qt::ItemFlags MimeModel::flags(const QModelIndex &index) const
|
|
{
|
|
Qt::ItemFlags itemFlags = QStringListModel::flags(index);
|
|
itemFlags &= ~Qt::ItemIsEditable;
|
|
if (!index.isValid()) {
|
|
return itemFlags;
|
|
}
|
|
return itemFlags | Qt::ItemIsUserCheckable;
|
|
}
|
|
|
|
QModelIndex MimeModel::index(int row, int column, const QModelIndex &parent) const
|
|
{
|
|
if (parent.isValid() || row >= m_mimetypes.count()) {
|
|
return QModelIndex();
|
|
}
|
|
return createIndex(row, column, (void*) m_mimetypes[row].data());
|
|
}
|
|
|
|
int MimeModel::rowCount(const QModelIndex &parent) const
|
|
{
|
|
if (parent.isValid()) {
|
|
return 0;
|
|
}
|
|
return m_mimetypes.count();
|
|
}
|
|
|
|
bool MimeModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
|
{
|
|
if (!index.isValid()) {
|
|
return false;
|
|
}
|
|
|
|
if (role == Qt::CheckStateRole) {
|
|
KMimeType *mime = static_cast<KMimeType*>(index.internalPointer());
|
|
m_state[mime] = (Qt::CheckState) value.toInt();
|
|
emit dataChanged(index, index);
|
|
return true;
|
|
}
|
|
|
|
return QStringListModel::setData(index, value, role);
|
|
}
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
ProxyMimeModel::ProxyMimeModel(QObject *parent)
|
|
: QSortFilterProxyModel(parent)
|
|
{
|
|
}
|
|
|
|
void ProxyMimeModel::setSourceModel(QAbstractItemModel *sourceModel)
|
|
{
|
|
QSortFilterProxyModel::setSourceModel(sourceModel);
|
|
sort(0);
|
|
}
|
|
|
|
void ProxyMimeModel::setFilter(const QString &filter)
|
|
{
|
|
m_filter = filter;
|
|
invalidateFilter();
|
|
}
|
|
|
|
bool ProxyMimeModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
|
|
{
|
|
KMimeType *leftPtr = static_cast<KMimeType*>(left.internalPointer());
|
|
KMimeType *rightPtr = static_cast<KMimeType*>(right.internalPointer());
|
|
|
|
if (!leftPtr) {
|
|
return true;
|
|
} else if (!rightPtr) {
|
|
return false;
|
|
}
|
|
|
|
return KStringHandler::naturalCompare(leftPtr->comment(), rightPtr->comment()) < 0;
|
|
}
|
|
|
|
bool ProxyMimeModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
|
|
{
|
|
QModelIndex sourceIndex = sourceModel()->index(source_row, 0, source_parent);
|
|
KMimeType *mime = static_cast<KMimeType*>(sourceIndex.internalPointer());
|
|
if (!mime) {
|
|
return false;
|
|
}
|
|
|
|
if (m_filter.isEmpty()) {
|
|
return true;
|
|
}
|
|
|
|
const bool fastRet = mime->comment().contains(m_filter, Qt::CaseInsensitive) ||
|
|
((!mime->patterns().count() || mime->comment().isEmpty()) && mime->name().contains(m_filter, Qt::CaseInsensitive));
|
|
|
|
if (fastRet) {
|
|
return true;
|
|
}
|
|
|
|
foreach (const QString &pattern, mime->patterns()) {
|
|
if (pattern.contains(m_filter, Qt::CaseInsensitive)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// Proxy model for KFilePlacesModel that filters out hidden items.
|
|
class PlacesFilterModel : public QSortFilterProxyModel
|
|
{
|
|
public:
|
|
PlacesFilterModel(QObject *parent = 0) : QSortFilterProxyModel(parent) {}
|
|
bool filterAcceptsRow(int row, const QModelIndex &parent) const {
|
|
KFilePlacesModel *model = static_cast<KFilePlacesModel*>(sourceModel());
|
|
const QModelIndex index = model->index(row, 0, parent);
|
|
return !model->isHidden(index);
|
|
}
|
|
};
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
RemoteWallpaperSetter::RemoteWallpaperSetter(const KUrl &url, FolderView *containment)
|
|
: QObject(containment)
|
|
{
|
|
const QString suffix = QFileInfo(url.fileName()).suffix();
|
|
|
|
KTemporaryFile file;
|
|
file.setPrefix(KGlobal::dirs()->saveLocation("wallpaper"));
|
|
file.setSuffix(QString(".") + suffix);
|
|
file.setAutoRemove(false);
|
|
|
|
if (file.open()) {
|
|
KIO::FileCopyJob *job = KIO::file_copy(url, KUrl::fromPath(file.fileName()), -1, KIO::Overwrite);
|
|
connect(job, SIGNAL(result(KJob*)), SLOT(result(KJob*)));
|
|
} else {
|
|
deleteLater();
|
|
}
|
|
}
|
|
|
|
void RemoteWallpaperSetter::result(KJob *job)
|
|
{
|
|
if (!job->error()) {
|
|
FolderView *containment = static_cast<FolderView*>(parent());
|
|
KIO::FileCopyJob *copyJob = static_cast<KIO::FileCopyJob*>(job);
|
|
containment->setWallpaper(copyJob->destUrl());
|
|
}
|
|
deleteLater();
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
static QString sortOrderEnumToString(Qt::SortOrder order)
|
|
{
|
|
if (order == Qt::AscendingOrder) {
|
|
return "ascending";
|
|
} else {
|
|
return "descending";
|
|
}
|
|
}
|
|
|
|
static Qt::SortOrder sortOrderStringToEnum(const QString& order)
|
|
{
|
|
if (order == "ascending") {
|
|
return Qt::AscendingOrder;
|
|
} else {
|
|
return Qt::DescendingOrder;
|
|
}
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
FolderView::FolderView(QObject *parent, const QVariantList &args)
|
|
: Plasma::Containment(parent, args),
|
|
m_previewGenerator(nullptr),
|
|
m_placesModel(nullptr),
|
|
m_itemActions(new KFileItemActions(this)),
|
|
m_openWithAction(nullptr),
|
|
m_iconView(nullptr),
|
|
m_listView(nullptr),
|
|
m_label(nullptr),
|
|
m_iconWidget(nullptr),
|
|
m_dialog(nullptr),
|
|
m_newMenu(nullptr),
|
|
m_actionCollection(this),
|
|
m_networkManager(nullptr)
|
|
{
|
|
setAspectRatioMode(Plasma::IgnoreAspectRatio);
|
|
setHasConfigurationInterface(true);
|
|
setAcceptHoverEvents(true);
|
|
setAcceptDrops(true);
|
|
|
|
m_dirModel = new KDirModel(this);
|
|
m_dirModel->setDropsAllowed(KDirModel::DropOnDirectory | KDirModel::DropOnLocalExecutable);
|
|
|
|
m_model = new ProxyModel(this);
|
|
m_model->setSourceModel(m_dirModel);
|
|
m_model->setSortLocaleAware(true);
|
|
m_model->setFilterCaseSensitivity(Qt::CaseInsensitive);
|
|
|
|
m_delegate = new KFileItemDelegate(this);
|
|
m_selectionModel = new QItemSelectionModel(m_model, this);
|
|
|
|
// we are not calling setUrl here since m_dirLister does not exist
|
|
if (args.count() > 0) {
|
|
m_url = KUrl(args.value(0).toString());
|
|
}
|
|
|
|
resize(600, 400);
|
|
|
|
// As we use some part of konqueror libkonq must be added to have translations
|
|
KGlobal::locale()->insertCatalog("libkonq");
|
|
}
|
|
|
|
void FolderView::init()
|
|
{
|
|
Containment::init();
|
|
setContainmentType(DesktopContainment);
|
|
|
|
// Find out about icon and font settings changes
|
|
connect(KGlobalSettings::self(), SIGNAL(kdisplayFontChanged()), SLOT(fontSettingsChanged()));
|
|
connect(KGlobalSettings::self(), SIGNAL(iconChanged(int)), SLOT(iconSettingsChanged(int)));
|
|
connect(KGlobalSettings::self(), SIGNAL(mouseChanged()), SLOT(clickSettingsChanged()));
|
|
|
|
// Find out about theme changes
|
|
connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), SLOT(plasmaThemeChanged()));
|
|
|
|
// Find out about network availability changes
|
|
m_networkManager = new KNetworkManager(this);
|
|
connect(
|
|
m_networkManager, SIGNAL(statusChanged(KNetworkManager::KNetworkStatus)),
|
|
this, SLOT(networkStatusChanged(KNetworkManager::KNetworkStatus))
|
|
);
|
|
|
|
// Find out which thumbnail plugins are enabled by default
|
|
QStringList enabledByDefault;
|
|
const KService::List plugins = KServiceTypeTrader::self()->query(QLatin1String("ThumbCreator"));
|
|
foreach (const KSharedPtr<KService>& service, plugins) {
|
|
const bool enabled = service->property("X-KDE-PluginInfo-EnabledByDefault", QVariant::Bool).toBool();
|
|
if (enabled) {
|
|
enabledByDefault << service->desktopEntryName();
|
|
}
|
|
}
|
|
|
|
KConfigGroup cg = config();
|
|
m_customLabel = cg.readEntry("customLabel", "");
|
|
m_customIconSize = cg.readEntry("customIconSize", 0);
|
|
m_showPreviews = cg.readEntry("showPreviews", true);
|
|
m_drawShadows = cg.readEntry("drawShadows", true);
|
|
m_numTextLines = cg.readEntry("numTextLines", 2);
|
|
m_textColor = cg.readEntry("textColor", QColor(Qt::transparent));
|
|
m_iconsLocked = cg.readEntry("iconsLocked", false);
|
|
m_alignToGrid = cg.readEntry("alignToGrid", false);
|
|
m_clickToView = cg.readEntry("clickForFolderPreviews", true);
|
|
m_previewPlugins = cg.readEntry("previewPlugins", enabledByDefault);
|
|
m_sortDirsFirst = cg.readEntry("sortDirsFirst", true);
|
|
m_sortColumn = cg.readEntry("sortColumn", int(KDirModel::Name));
|
|
m_sortOrder = sortOrderStringToEnum(cg.readEntry("sortOrder", "ascending"));
|
|
m_filterFiles = cg.readEntry("filterFiles", "*");
|
|
m_filterType = static_cast<ProxyModel::FilterMode>(cg.readEntry("filter", static_cast<int>(ProxyModel::NoFilter)));
|
|
m_filterFilesMimeList = cg.readEntry("mimeFilter", QStringList());
|
|
m_labelType = static_cast<FolderView::LabelType>(cg.readEntry("labelType", static_cast<int>(FolderView::None)));
|
|
m_showSelectionMarker = KGlobalSettings::singleClick();
|
|
|
|
m_layout = isContainment() ? IconView::Columns : IconView::Rows;
|
|
m_alignment = layoutDirection() == Qt::LeftToRight ? IconView::Left : IconView::Right;
|
|
m_layout = static_cast<IconView::Layout>(cg.readEntry("layout", static_cast<int>(m_layout)));
|
|
m_alignment = static_cast<IconView::Alignment>(cg.readEntry("alignment", static_cast<int>(m_alignment)));
|
|
|
|
m_model->setFilterMode(m_filterType);
|
|
m_model->setMimeTypeFilterList(m_filterFilesMimeList);
|
|
m_model->setFileNameFilter(m_filterFiles);
|
|
m_model->setSortDirectoriesFirst(m_sortDirsFirst);
|
|
m_model->setDynamicSortFilter(m_sortColumn != int(FolderView::Unsorted));
|
|
m_model->sort(m_sortColumn != int(FolderView::Unsorted) ? m_sortColumn : KDirModel::Name, m_sortOrder);
|
|
|
|
m_dirLister = new DirLister(this);
|
|
m_dirLister->setAutoErrorHandlingEnabled(false, 0);
|
|
|
|
m_dirModel->setDirLister(m_dirLister);
|
|
|
|
if (m_url.isValid()) {
|
|
// this means that we were passed a URL via the args list in the constructor
|
|
// we need to set it and save it in the config file
|
|
setUrl(m_url);
|
|
KConfigGroup cg = config();
|
|
cg.writeEntry("url", m_url);
|
|
} else {
|
|
QString path = QDir::homePath();
|
|
if (isContainment()) {
|
|
const QString desktopPath = KGlobalSettings::desktopPath();
|
|
const QDir desktopFolder(desktopPath);
|
|
|
|
if (desktopPath != QDir::homePath() && desktopFolder.exists()) {
|
|
path = desktopPath;
|
|
}
|
|
}
|
|
setUrl(cg.readEntry("url", KUrl(path)));
|
|
}
|
|
|
|
createActions();
|
|
|
|
if (isContainment()) {
|
|
setupIconView();
|
|
|
|
// Set a low Z value so applets don't end up below the icon view
|
|
m_iconView->setZValue(INT_MIN);
|
|
}
|
|
|
|
// Set the associated application
|
|
KService::List offers = KFileItemActions::associatedApplications(QStringList() << "inode/directory", QString());
|
|
if (!offers.isEmpty()) {
|
|
setAssociatedApplication(offers.first()->exec());
|
|
setAssociatedApplicationUrls(KUrl::List() << m_url);
|
|
|
|
// contextualActions() includes KFileItemActions::preferredOpenWithAction(),
|
|
// so we'll hide the one Plasma provides.
|
|
if (QAction *runAction = action("run associated application")) {
|
|
runAction->setVisible(false);
|
|
}
|
|
}
|
|
|
|
/*
|
|
TODO Mark the cut icons as cut
|
|
connect(QApplication::clipboard(), SIGNAL(dataChanged()), SLOT(clipboardDataChanged()));
|
|
*/
|
|
}
|
|
|
|
void FolderView::networkStatusChanged(const KNetworkManager::KNetworkStatus status)
|
|
{
|
|
if (!KProtocolInfo::protocolIsLocal(m_url.protocol())) {
|
|
if (status == KNetworkManager::ConnectedStatus) {
|
|
m_dirLister->openUrl(m_url);
|
|
} else {
|
|
QString networkStatus(i18n("Network is not reachable"));
|
|
showMessage(KIcon("dialog-warning"), networkStatus, Plasma::ButtonOk);
|
|
}
|
|
}
|
|
}
|
|
|
|
void FolderView::configChanged()
|
|
{
|
|
KConfigGroup cg = config();
|
|
|
|
//Declare some variables that are used afterwards
|
|
bool needReload = false;
|
|
bool preserveIconPositions = false;
|
|
|
|
const FolderView::LabelType labelType = static_cast<FolderView::LabelType>(cg.readEntry("labelType", static_cast<int>(m_labelType)));
|
|
if (labelType != m_labelType) {
|
|
m_labelType = labelType;
|
|
needReload = true;
|
|
}
|
|
|
|
//Reload m_customLabel values
|
|
const QString label = cg.readEntry("customLabel", m_customLabel);
|
|
if (label != m_customLabel) {
|
|
m_customLabel = label;
|
|
needReload = true;
|
|
}
|
|
|
|
//Reload m_customIconSize values
|
|
m_customIconSize = cg.readEntry("customIconSize", m_customIconSize);
|
|
if (m_customIconSize != iconSize().width()) {
|
|
needReload = true;
|
|
}
|
|
|
|
m_drawShadows = cg.readEntry("drawShadows", m_drawShadows);
|
|
m_clickToView = cg.readEntry("clickForFolderPreviews", m_clickToView);
|
|
m_numTextLines = cg.readEntry("numTextLines", m_numTextLines);
|
|
m_alignToGrid = cg.readEntry("alignToGrid", m_alignToGrid);
|
|
|
|
if (QAction *action = m_actionCollection.action("auto_align")) {
|
|
action->setChecked(m_alignToGrid);
|
|
}
|
|
|
|
m_iconsLocked = cg.readEntry("iconsLocked", m_iconsLocked);
|
|
if (QAction *action = m_actionCollection.action("lock_icons")) {
|
|
action->setChecked(m_iconsLocked);
|
|
}
|
|
|
|
const QColor color = cg.readEntry("textColor", m_textColor);
|
|
if (color != m_textColor) {
|
|
m_textColor = color;
|
|
needReload = true;
|
|
preserveIconPositions = true;
|
|
}
|
|
|
|
const bool showPreviews = cg.readEntry("showPreviews", m_showPreviews);
|
|
if (showPreviews != m_showPreviews) {
|
|
m_showPreviews = showPreviews;
|
|
|
|
//As disabling the previews will force a rearrangement, we need to manually
|
|
//save and restore the icons positions
|
|
|
|
//Enable/disable the previews
|
|
m_previewGenerator->setPreviewShown(m_showPreviews);
|
|
if (m_iconView)
|
|
m_iconView->update(m_iconView->visibleArea());
|
|
if (m_listView)
|
|
m_listView->update(m_listView->visibleArea());
|
|
}
|
|
|
|
m_previewPlugins = cg.readEntry("previewPlugins", m_previewPlugins);
|
|
|
|
if (m_previewGenerator && m_previewPlugins != m_previewGenerator->enabledPlugins()) {
|
|
m_previewGenerator->setEnabledPlugins(m_previewPlugins);
|
|
|
|
//Changing the preview plugins will also need a reload to work, so we need to preserve
|
|
//the icons position
|
|
needReload = true;
|
|
preserveIconPositions = true;
|
|
}
|
|
|
|
const bool sortDirsFirst = cg.readEntry("sortDirsFirst", m_sortDirsFirst);
|
|
if (sortDirsFirst != m_sortDirsFirst) {
|
|
m_sortDirsFirst = sortDirsFirst;
|
|
|
|
m_model->setSortDirectoriesFirst(m_sortDirsFirst);
|
|
if (m_sortColumn != int(FolderView::Unsorted)) {
|
|
m_model->invalidate();
|
|
}
|
|
|
|
if (QAction *action = m_actionCollection.action("dirs_first")) {
|
|
action->setChecked(m_sortDirsFirst);
|
|
}
|
|
}
|
|
|
|
const int sortColumn = cg.readEntry("sortColumn", m_sortColumn);
|
|
const Qt::SortOrder sortOrder = sortOrderStringToEnum(cg.readEntry("sortOrder", sortOrderEnumToString(m_sortOrder)));
|
|
if ((m_sortColumn != sortColumn) || (m_sortOrder != sortOrder)) {
|
|
m_sortColumn = sortColumn;
|
|
m_sortOrder = sortOrder;
|
|
if (m_sortColumn != int(FolderView::Unsorted)) {
|
|
m_model->invalidate();
|
|
m_model->sort(m_sortColumn, m_sortOrder);
|
|
m_model->setDynamicSortFilter(true);
|
|
} else if (m_iconView) {
|
|
m_iconView->setCustomLayout(true);
|
|
m_model->setDynamicSortFilter(false);
|
|
}
|
|
updateSortActionsState();
|
|
}
|
|
|
|
const IconView::Layout layout = static_cast<IconView::Layout>(cg.readEntry("layout", static_cast<int>(m_layout)));
|
|
const IconView::Alignment alignment = static_cast<IconView::Alignment>(cg.readEntry("alignment", static_cast<int>(m_alignment)));
|
|
if ((m_layout != layout) || (m_alignment != alignment)) {
|
|
m_layout = layout;
|
|
m_alignment = alignment;
|
|
updateFlowActionsState();
|
|
}
|
|
|
|
const ProxyModel::FilterMode filterType = static_cast<ProxyModel::FilterMode>(cg.readEntry("filter", static_cast<int>(m_filterType)));
|
|
if (filterType != m_filterType) {
|
|
m_filterType = filterType;
|
|
m_model->setFilterMode(m_filterType);
|
|
needReload = true;
|
|
}
|
|
|
|
const QString filterFiles = cg.readEntry("filterFiles", m_filterFiles);
|
|
if (filterFiles != m_filterFiles) {
|
|
m_filterFiles = filterFiles;
|
|
m_model->setFileNameFilter(m_filterFiles);
|
|
needReload = true;
|
|
}
|
|
|
|
const QStringList mimeFilter = cg.readEntry("mimeFilter", m_filterFilesMimeList);
|
|
if (mimeFilter != m_filterFilesMimeList) {
|
|
m_filterFilesMimeList = mimeFilter;
|
|
m_model->setMimeTypeFilterList(m_filterFilesMimeList);
|
|
needReload = true;
|
|
}
|
|
|
|
const KUrl url = cg.readEntry("url", m_url);
|
|
if (url != m_url) {
|
|
m_url = url;
|
|
needReload = true;
|
|
}
|
|
|
|
if (m_iconView) {
|
|
updateIconViewState();
|
|
}
|
|
|
|
if (m_listView) {
|
|
updateListViewState();
|
|
}
|
|
|
|
if (needReload) {
|
|
//Manually save and restore the icon positions if we need it
|
|
if (preserveIconPositions && m_iconView) {
|
|
m_iconView->setIconPositionsData(m_iconView->iconPositionsData());
|
|
}
|
|
|
|
setUrl(m_url);
|
|
}
|
|
}
|
|
|
|
FolderView::~FolderView()
|
|
{
|
|
delete m_dialog;
|
|
delete m_newMenu;
|
|
}
|
|
|
|
void FolderView::saveState(KConfigGroup &config) const
|
|
{
|
|
Containment::saveState(config);
|
|
saveIconPositions();
|
|
}
|
|
|
|
void FolderView::addUrls(const KUrl::List& urls)
|
|
{
|
|
KIO::CopyJob *job;
|
|
|
|
foreach (KUrl url, urls) {
|
|
job = KIO::link(url.url(), m_url);
|
|
KIO::FileUndoManager::self()->recordCopyJob(job);
|
|
}
|
|
}
|
|
|
|
void FolderView::createConfigurationInterface(KConfigDialog *parent)
|
|
{
|
|
QWidget *widgetFilter = new QWidget();
|
|
QWidget *widgetDisplay = new QWidget();
|
|
QWidget *widgetLocation = new QWidget();
|
|
uiFilter.setupUi(widgetFilter);
|
|
uiDisplay.setupUi(widgetDisplay);
|
|
uiLocation.setupUi(widgetLocation);
|
|
|
|
if (!m_placesModel) {
|
|
m_placesModel = new KFilePlacesModel(this);
|
|
}
|
|
|
|
PlacesFilterModel *placesFilter = new PlacesFilterModel(parent);
|
|
placesFilter->setSourceModel(m_placesModel);
|
|
uiLocation.placesCombo->setModel(placesFilter);
|
|
|
|
QString desktopPath = KGlobalSettings::desktopPath();
|
|
QDir desktopFolder(desktopPath);
|
|
|
|
const bool desktopVisible = desktopPath != QDir::homePath() && desktopFolder.exists();
|
|
uiLocation.showDesktopFolder->setVisible(desktopVisible);
|
|
|
|
if (desktopVisible && m_url == KUrl(desktopPath)) {
|
|
uiLocation.showDesktopFolder->setChecked(true);
|
|
uiLocation.placesCombo->setEnabled(false);
|
|
uiLocation.lineEdit->setEnabled(false);
|
|
} else {
|
|
QModelIndex index;
|
|
for (int i = 0; i < placesFilter->rowCount(); i++) {
|
|
const KUrl url = m_placesModel->url(placesFilter->mapToSource(placesFilter->index(i, 0)));
|
|
if (url.equals(m_url, KUrl::RemoveTrailingSlash)) {
|
|
index = placesFilter->index(i, 0);
|
|
break;
|
|
}
|
|
}
|
|
if (index.isValid()) {
|
|
uiLocation.placesCombo->setCurrentIndex(index.row());
|
|
uiLocation.showPlace->setChecked(true);
|
|
uiLocation.lineEdit->setEnabled(false);
|
|
} else {
|
|
uiLocation.showCustomFolder->setChecked(true);
|
|
uiLocation.lineEdit->setUrl(m_url);
|
|
uiLocation.placesCombo->setEnabled(false);
|
|
}
|
|
}
|
|
|
|
uiLocation.lineEdit->setMode(KFile::Directory);
|
|
uiFilter.filterFilesPattern->setText(m_filterFiles);
|
|
|
|
MimeModel *mimeModel = new MimeModel(uiFilter.filterFilesList);
|
|
ProxyMimeModel *pMimeModel = new ProxyMimeModel(uiFilter.filterFilesList);
|
|
pMimeModel->setSourceModel(mimeModel);
|
|
uiFilter.filterFilesList->setModel(pMimeModel);
|
|
|
|
uiLocation.titleCombo->addItem(i18n("None"), QVariant::fromValue(FolderView::None));
|
|
uiLocation.titleCombo->addItem(i18n("Default"), QVariant::fromValue(FolderView::PlaceName));
|
|
uiLocation.titleCombo->addItem(i18n("Full Path"), QVariant::fromValue(FolderView::FullPath));
|
|
uiLocation.titleCombo->addItem(i18n("Custom title"), QVariant::fromValue(FolderView::Custom));
|
|
|
|
if (m_labelType == FolderView::Custom) {
|
|
uiLocation.titleEdit->setEnabled(true);
|
|
uiLocation.titleEdit->setText(m_customLabel);
|
|
} else {
|
|
uiLocation.titleEdit->setEnabled(false);
|
|
}
|
|
|
|
// The label is not shown when the applet is acting as a containment,
|
|
// so don't confuse the user by making it editable.
|
|
if (isContainment()) {
|
|
uiLocation.titleLabel->hide();
|
|
uiLocation.titleCombo->hide();
|
|
uiLocation.titleEdit->hide();
|
|
}
|
|
|
|
const QList<int> iconSizes = QList<int>() << 16 << 22 << 32 << 48 << 64 << 128;
|
|
uiDisplay.sizeSlider->setRange(0, iconSizes.size() - 1);
|
|
uiDisplay.sizeSlider->setValue(iconSizes.indexOf(iconSize().width()));
|
|
|
|
// Only add "Unsorted" as an option when we're showing an icon view, since the list view
|
|
// doesn't allow the user to rearrange the icons.
|
|
if (m_iconView && m_sortColumn == int(FolderView::Unsorted)) {
|
|
QAction *unsorted = m_actionCollection.action("unsorted");
|
|
if (unsorted) {
|
|
uiDisplay.sortCombo->addItem(KGlobal::locale()->removeAcceleratorMarker(unsorted->text()), unsorted->data());
|
|
}
|
|
}
|
|
|
|
addActionGroupToCombo(m_sortingGroup, uiDisplay.sortCombo);
|
|
addActionGroupToCombo(m_layoutGroup, uiDisplay.layoutCombo);
|
|
addActionGroupToCombo(m_alignmentGroup, uiDisplay.alignmentCombo);
|
|
|
|
uiFilter.filterCombo->addItem(i18n("Show All Files"), QVariant::fromValue(ProxyModel::NoFilter));
|
|
uiFilter.filterCombo->addItem(i18n("Show Files Matching"), QVariant::fromValue(ProxyModel::FilterShowMatches));
|
|
uiFilter.filterCombo->addItem(i18n("Hide Files Matching"), QVariant::fromValue(ProxyModel::FilterHideMatches));
|
|
|
|
uiDisplay.alignToGrid->setChecked(m_alignToGrid);
|
|
uiDisplay.clickToView->setChecked(m_clickToView);
|
|
uiDisplay.lockInPlace->setChecked(m_iconsLocked);
|
|
uiDisplay.drawShadows->setChecked(m_drawShadows);
|
|
uiDisplay.showPreviews->setChecked(m_showPreviews);
|
|
uiDisplay.previewsAdvanced->setEnabled(m_showPreviews);
|
|
uiDisplay.sortDescending->setChecked(m_sortOrder == Qt::DescendingOrder);
|
|
uiDisplay.foldersFirst->setChecked(m_sortDirsFirst);
|
|
uiDisplay.numLinesEdit->setValue(m_numTextLines);
|
|
uiDisplay.colorButton->setColor(textColor());
|
|
|
|
setCurrentItem(uiDisplay.sortCombo, m_sortColumn);
|
|
setCurrentItem(uiDisplay.layoutCombo, m_layout);
|
|
setCurrentItem(uiDisplay.alignmentCombo, m_alignment);
|
|
setCurrentItem(uiLocation.titleCombo, m_labelType);
|
|
setCurrentItem(uiFilter.filterCombo, m_filterType);
|
|
|
|
filterChanged(uiFilter.filterCombo->currentIndex());
|
|
|
|
if (m_filterFilesMimeList.count()) {
|
|
for (int i = 0; i < pMimeModel->rowCount(); i++) {
|
|
const QModelIndex index = pMimeModel->index(i, 0);
|
|
const KMimeType *mime = static_cast<KMimeType*>(pMimeModel->mapToSource(index).internalPointer());
|
|
if (mime && m_filterFilesMimeList.contains(mime->name())) {
|
|
m_filterFilesMimeList.removeAll(mime->name());
|
|
uiFilter.filterFilesList->model()->setData(index, Qt::Checked, Qt::CheckStateRole);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Hide the icon arrangement controls when we're not acting as a containment,
|
|
// since this option doesn't make much sense in the applet.
|
|
if (!isContainment()) {
|
|
uiDisplay.layoutLabel->hide();
|
|
uiDisplay.layoutCombo->hide();
|
|
uiDisplay.alignmentLabel->hide();
|
|
uiDisplay.alignmentCombo->hide();
|
|
}
|
|
|
|
parent->addPage(widgetLocation, i18nc("Title of the page that lets the user choose which location should the folderview show", "Location"), "folder");
|
|
parent->addPage(widgetDisplay, i18nc("Title of the page that lets the user choose how the folderview should be shown", "Icons"), "preferences-desktop-icons");
|
|
parent->addPage(widgetFilter, i18nc("Title of the page that lets the user choose how to filter the folderview contents", "Filter"), "view-filter");
|
|
|
|
connect(parent, SIGNAL(applyClicked()), this, SLOT(configAccepted()));
|
|
connect(parent, SIGNAL(okClicked()), this, SLOT(configAccepted()));
|
|
|
|
connect(uiFilter.searchMimetype, SIGNAL(textChanged(QString)), pMimeModel, SLOT(setFilter(QString)));
|
|
connect(uiLocation.showPlace, SIGNAL(toggled(bool)), uiLocation.placesCombo, SLOT(setEnabled(bool)));
|
|
connect(uiLocation.showCustomFolder, SIGNAL(toggled(bool)), uiLocation.lineEdit, SLOT(setEnabled(bool)));
|
|
connect(uiLocation.titleCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(setTitleEditEnabled(int)));
|
|
connect(uiFilter.filterCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(filterChanged(int)));
|
|
connect(uiFilter.selectAll, SIGNAL(clicked(bool)), this, SLOT(selectAllMimetypes()));
|
|
connect(uiFilter.deselectAll, SIGNAL(clicked(bool)), this, SLOT(deselectAllMimeTypes()));
|
|
connect(uiDisplay.previewsAdvanced, SIGNAL(clicked()), this, SLOT(showPreviewConfigDialog()));
|
|
connect(uiDisplay.showPreviews, SIGNAL(toggled(bool)), uiDisplay.previewsAdvanced, SLOT(setEnabled(bool)));
|
|
|
|
connect(uiDisplay.layoutCombo, SIGNAL(currentIndexChanged(int)), parent, SLOT(settingsModified()));
|
|
connect(uiDisplay.alignmentCombo, SIGNAL(currentIndexChanged(int)), parent, SLOT(settingsModified()));
|
|
connect(uiDisplay.sortCombo, SIGNAL(currentIndexChanged(int)), parent, SLOT(settingsModified()));
|
|
connect(uiDisplay.sizeSlider, SIGNAL(valueChanged(int)), parent, SLOT(settingsModified()));
|
|
connect(uiDisplay.showPreviews, SIGNAL(toggled(bool)), parent, SLOT(settingsModified()));
|
|
connect(uiDisplay.lockInPlace, SIGNAL(toggled(bool)), parent, SLOT(settingsModified()));
|
|
connect(uiDisplay.alignToGrid, SIGNAL(toggled(bool)), parent, SLOT(settingsModified()));
|
|
connect(uiDisplay.clickToView, SIGNAL(toggled(bool)), parent, SLOT(settingsModified()));
|
|
connect(uiDisplay.sortDescending, SIGNAL(toggled(bool)), parent, SLOT(settingsModified()));
|
|
connect(uiDisplay.foldersFirst, SIGNAL(toggled(bool)), parent, SLOT(settingsModified()));
|
|
connect(uiDisplay.numLinesEdit, SIGNAL(valueChanged(int)), parent, SLOT(settingsModified()));
|
|
connect(uiDisplay.colorButton, SIGNAL(changed(QColor)), parent, SLOT(settingsModified()));
|
|
connect(uiDisplay.drawShadows, SIGNAL(toggled(bool)), parent, SLOT(settingsModified()));
|
|
|
|
connect(uiFilter.filterCombo, SIGNAL(currentIndexChanged(int)), parent, SLOT(settingsModified()));
|
|
connect(uiFilter.filterFilesPattern, SIGNAL(textChanged(QString)), parent, SLOT(settingsModified()));
|
|
connect(uiFilter.filterFilesList->model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), parent, SLOT(settingsModified()));
|
|
|
|
connect(uiLocation.showDesktopFolder, SIGNAL(toggled(bool)), parent, SLOT(settingsModified()));
|
|
connect(uiLocation.showPlace, SIGNAL(toggled(bool)), parent, SLOT(settingsModified()));
|
|
connect(uiLocation.titleCombo, SIGNAL(currentIndexChanged(int)), parent, SLOT(settingsModified()));
|
|
connect(uiLocation.titleEdit, SIGNAL(textChanged(QString)), parent, SLOT(settingsModified()));
|
|
connect(uiLocation.showCustomFolder, SIGNAL(toggled(bool)), parent, SLOT(settingsModified()));
|
|
connect(uiLocation.placesCombo, SIGNAL(currentIndexChanged(int)), parent, SLOT(settingsModified()));
|
|
connect(uiLocation.lineEdit, SIGNAL(textChanged(QString)), parent, SLOT(settingsModified()));
|
|
}
|
|
|
|
void FolderView::configAccepted()
|
|
{
|
|
KUrl url;
|
|
|
|
if (uiLocation.showDesktopFolder->isChecked()) {
|
|
url = KUrl(KGlobalSettings::desktopPath());
|
|
} else if (uiLocation.showPlace->isChecked()) {
|
|
PlacesFilterModel *filter = static_cast<PlacesFilterModel*>(uiLocation.placesCombo->model());
|
|
KFilePlacesModel *model = static_cast<KFilePlacesModel*>(filter->sourceModel());
|
|
url = model->url(filter->mapToSource(filter->index(uiLocation.placesCombo->currentIndex(), 0)));
|
|
} else {
|
|
url = uiLocation.lineEdit->url();
|
|
}
|
|
|
|
if (url.isEmpty()) {
|
|
url = KUrl(QDir::homePath());
|
|
}
|
|
|
|
KConfigGroup cg = config();
|
|
|
|
cg.writeEntry("drawShadows", uiDisplay.drawShadows->isChecked());
|
|
|
|
cg.writeEntry("showPreviews", uiDisplay.showPreviews->isChecked());
|
|
|
|
if (m_previewGenerator && m_previewPlugins != m_previewGenerator->enabledPlugins()) {
|
|
cg.writeEntry("previewPlugins", m_previewPlugins);
|
|
}
|
|
|
|
const QColor defaultColor = isContainment() ? Qt::white
|
|
: Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor);
|
|
const QColor color = uiDisplay.colorButton->color();
|
|
if ((m_textColor != Qt::transparent && color != m_textColor) ||
|
|
(m_textColor == Qt::transparent && color != defaultColor))
|
|
{
|
|
cg.writeEntry("textColor", color);
|
|
}
|
|
|
|
cg.writeEntry("numTextLines", uiDisplay.numLinesEdit->value());
|
|
|
|
const QList<int> iconSizes = QList<int>() << 16 << 22 << 32 << 48 << 64 << 128;
|
|
const int size = iconSizes.at(uiDisplay.sizeSlider->value());
|
|
cg.writeEntry("customIconSize", size);
|
|
|
|
const int sortColumn = uiDisplay.sortCombo->itemData(uiDisplay.sortCombo->currentIndex()).toInt();
|
|
cg.writeEntry("sortColumn", sortColumn);
|
|
|
|
const Qt::SortOrder order = uiDisplay.sortDescending->isChecked() ? Qt::DescendingOrder : Qt::AscendingOrder;
|
|
cg.writeEntry("sortOrder", sortOrderEnumToString(order));
|
|
|
|
const bool dirsFirst = uiDisplay.foldersFirst->isChecked();
|
|
cg.writeEntry("sortDirsFirst", dirsFirst);
|
|
|
|
const IconView::Layout layout = uiDisplay.layoutCombo->itemData(uiDisplay.layoutCombo->currentIndex()).value<IconView::Layout>();
|
|
cg.writeEntry("layout", static_cast<int>(layout));
|
|
|
|
const IconView::Alignment alignment = uiDisplay.alignmentCombo->itemData(uiDisplay.alignmentCombo->currentIndex()).value<IconView::Alignment>();
|
|
cg.writeEntry("alignment", static_cast<int>(alignment));
|
|
|
|
cg.writeEntry("alignToGrid", uiDisplay.alignToGrid->isChecked());
|
|
cg.writeEntry("clickForFolderPreviews", uiDisplay.clickToView->isChecked());
|
|
cg.writeEntry("iconsLocked", uiDisplay.lockInPlace->isChecked());
|
|
|
|
cg.writeEntry("url", url);
|
|
cg.writeEntry("filterFiles", uiFilter.filterFilesPattern->text());
|
|
|
|
const ProxyModel::FilterMode filterMode =
|
|
uiFilter.filterCombo->itemData(uiFilter.filterCombo->currentIndex()).value<ProxyModel::FilterMode>();
|
|
cg.writeEntry("filter", static_cast<int>(filterMode));
|
|
|
|
const FolderView::LabelType labelType =
|
|
uiLocation.titleCombo->itemData(uiLocation.titleCombo->currentIndex()).value<FolderView::LabelType>();
|
|
QString customTitle;
|
|
if (labelType == FolderView::Custom) {
|
|
customTitle = uiLocation.titleEdit->text();
|
|
} else {
|
|
customTitle.clear();
|
|
}
|
|
cg.writeEntry("labelType", static_cast<int>(labelType));
|
|
cg.writeEntry("customLabel", customTitle);
|
|
|
|
// Now, we have to iterate over all items (not only the filtered ones). For that reason we have
|
|
// to ask the source model, not the proxy model.
|
|
QStringList selectedItems;
|
|
ProxyMimeModel *proxyModel = static_cast<ProxyMimeModel*>(uiFilter.filterFilesList->model());
|
|
for (int i = 0; i < proxyModel->sourceModel()->rowCount(); i++) {
|
|
const QModelIndex index = proxyModel->sourceModel()->index(i, 0);
|
|
if (index.model()->data(index, Qt::CheckStateRole).toInt() == Qt::Checked) {
|
|
KMimeType *mime = static_cast<KMimeType*>(index.internalPointer());
|
|
if (mime) {
|
|
selectedItems << mime->name();
|
|
}
|
|
}
|
|
}
|
|
cg.writeEntry("mimeFilter", selectedItems);
|
|
|
|
m_delayedSaveTimer.start(5000, this);
|
|
emit configNeedsSaving();
|
|
}
|
|
|
|
void FolderView::setWallpaper(const KUrl &url)
|
|
{
|
|
if (!url.isLocalFile()) {
|
|
return;
|
|
}
|
|
|
|
const QString wallpaper = url.toLocalFile();
|
|
Plasma::Wallpaper::ResizeMethod resizeMethod = Plasma::Wallpaper::MaxpectResize;
|
|
|
|
// Try to read the image size without loading the image
|
|
QImageReader reader(wallpaper);
|
|
QSize size = reader.size();
|
|
|
|
if (!size.isEmpty()) {
|
|
if (size.width() < geometry().width() / 2 && size.height() < geometry().height() / 2) {
|
|
// If the image size is less than a quarter of the size of the containment,
|
|
// center it instead of scaling it.
|
|
resizeMethod = Plasma::Wallpaper::CenteredResize;
|
|
} else {
|
|
// Permit up to 10% of the image to be cropped in either dimension as a result of scaling.
|
|
size.scale(geometry().size().toSize(), Qt::KeepAspectRatioByExpanding);
|
|
if (size.width() / geometry().width() < 1.1 && size.height() / geometry().height() < 1.1) {
|
|
resizeMethod = Plasma::Wallpaper::ScaledAndCroppedResize;
|
|
} else {
|
|
resizeMethod = Plasma::Wallpaper::MaxpectResize;
|
|
}
|
|
}
|
|
}
|
|
|
|
KConfigGroup cg = config();
|
|
cg = KConfigGroup(&cg, "Wallpaper");
|
|
cg = KConfigGroup(&cg, "image");
|
|
|
|
QStringList userWallpapers = cg.readEntry("userswallpapers", QStringList());
|
|
if (!userWallpapers.contains(wallpaper)) {
|
|
userWallpapers.append(wallpaper);
|
|
cg.writeEntry("userswallpapers", userWallpapers);
|
|
}
|
|
|
|
cg.writeEntry("wallpaper", wallpaper);
|
|
cg.writeEntry("wallpaperposition", int(resizeMethod));
|
|
cg.sync();
|
|
|
|
Plasma::Containment::setWallpaper("image", "SingleImage");
|
|
}
|
|
|
|
void FolderView::showPreviewConfigDialog()
|
|
{
|
|
QWidget *widget = new QWidget;
|
|
uiPreviewConfig.setupUi(widget);
|
|
|
|
PreviewPluginsModel *model = new PreviewPluginsModel(this);
|
|
model->setCheckedPlugins(m_previewPlugins);
|
|
|
|
uiPreviewConfig.listView->setModel(model);
|
|
|
|
KDialog *dialog = new KDialog;
|
|
dialog->setMainWidget(widget);
|
|
|
|
if (dialog->exec() == KDialog::Accepted) {
|
|
m_previewPlugins = model->checkedPlugins();
|
|
}
|
|
|
|
delete widget;
|
|
delete dialog;
|
|
delete model;
|
|
}
|
|
|
|
QColor FolderView::textColor() const
|
|
{
|
|
if (m_textColor != Qt::transparent) {
|
|
return m_textColor;
|
|
}
|
|
|
|
// Default to white text on the desktop
|
|
if (isContainment()) {
|
|
return Qt::white;
|
|
}
|
|
|
|
return Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor);
|
|
}
|
|
|
|
void FolderView::updateListViewState()
|
|
{
|
|
QPalette palette = m_listView->palette();
|
|
palette.setColor(QPalette::Text, m_textColor != Qt::transparent ? m_textColor :
|
|
Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor));
|
|
m_listView->setPalette(palette);
|
|
|
|
const QFont font = Plasma::Theme::defaultTheme()->font(Plasma::Theme::DesktopFont);
|
|
if (m_listView->font() != font) {
|
|
m_listView->setFont(font);
|
|
}
|
|
m_listView->setDrawShadows(m_drawShadows);
|
|
m_listView->setIconSize(iconSize());
|
|
m_listView->setWordWrap(m_numTextLines > 1);
|
|
m_listView->setTextLineCount(m_numTextLines);
|
|
}
|
|
|
|
void FolderView::updateIconViewState()
|
|
{
|
|
QPalette palette = m_iconView->palette();
|
|
palette.setColor(QPalette::Text, textColor());
|
|
m_iconView->setPalette(palette);
|
|
|
|
m_iconView->setDrawShadows(m_drawShadows);
|
|
m_iconView->setIconSize(iconSize());
|
|
m_iconView->setTextLineCount(m_numTextLines);
|
|
m_iconView->setLayout(m_layout);
|
|
m_iconView->setAlignment(m_alignment);
|
|
m_iconView->setWordWrap(m_numTextLines > 1);
|
|
m_iconView->setAlignToGrid(m_alignToGrid);
|
|
m_iconView->setIconsMoveable(!m_iconsLocked);
|
|
m_iconView->setClickToViewFolders(m_clickToView);
|
|
m_iconView->setShowSelectionMarker(m_showSelectionMarker);
|
|
|
|
if (m_label) {
|
|
m_label->setPalette(palette);
|
|
m_label->setDrawShadow(m_drawShadows);
|
|
}
|
|
// make popup inherit file preview settings:
|
|
m_iconView->setPopupPreviewSettings(m_showPreviews, m_previewPlugins);
|
|
}
|
|
|
|
void FolderView::addActions(AbstractItemView *view)
|
|
{
|
|
view->addAction(m_actionCollection.action("rename"));
|
|
view->addAction(m_actionCollection.action("cut"));
|
|
view->addAction(m_actionCollection.action("undo"));
|
|
view->addAction(m_actionCollection.action("copy"));
|
|
view->addAction(m_actionCollection.action("paste"));
|
|
view->addAction(m_actionCollection.action("pasteto"));
|
|
view->addAction(m_actionCollection.action("refresh"));
|
|
view->addAction(m_actionCollection.action("trash"));
|
|
view->addAction(m_actionCollection.action("del"));
|
|
}
|
|
|
|
void FolderView::addActionGroupToCombo(QActionGroup* group, QComboBox* combo)
|
|
{
|
|
if (group && combo) {
|
|
foreach (QAction *action, group->actions()) {
|
|
combo->addItem(KGlobal::locale()->removeAcceleratorMarker(action->text()), action->data());
|
|
}
|
|
}
|
|
}
|
|
|
|
// We can not use QComboBox::findData() since in qt4, comparing QVariant's containing
|
|
// enums (user types) fails even if the enums contained in the QVariant's are equal
|
|
template <typename T>
|
|
void FolderView::setCurrentItem(QComboBox* combo, T current)
|
|
{
|
|
if (!combo)
|
|
return;
|
|
|
|
for (int i = 0; i < combo->count(); i++) {
|
|
if (current == combo->itemData(i).value<T>()) {
|
|
combo->setCurrentIndex(i);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void FolderView::setupIconView()
|
|
{
|
|
if (m_iconView) {
|
|
return;
|
|
}
|
|
|
|
m_iconView = new IconView(this);
|
|
|
|
const QStringList data = config().readEntry("savedPositions", QStringList());
|
|
m_iconView->setIconPositionsData(data);
|
|
|
|
m_iconView->setModel(m_model);
|
|
m_iconView->setItemDelegate(m_delegate);
|
|
m_iconView->setSelectionModel(m_selectionModel);
|
|
m_iconView->setFont(Plasma::Theme::defaultTheme()->font(Plasma::Theme::DesktopFont));
|
|
|
|
// Add widget specific actions with shortcuts to the view
|
|
addActions(m_iconView);
|
|
|
|
if (!isContainment() ) {
|
|
m_label = new Label(this);
|
|
m_label->setText(m_titleText);
|
|
|
|
QFont font = Plasma::Theme::defaultTheme()->font(Plasma::Theme::DesktopFont);
|
|
font.setPointSize(font.pointSize() + 1);
|
|
font.setBold(true);
|
|
m_label->setFont(font);
|
|
}
|
|
|
|
updateIconViewState();
|
|
|
|
connect(m_iconView, SIGNAL(activated(QModelIndex)), SLOT(activated(QModelIndex)));
|
|
connect(m_iconView, SIGNAL(indexesMoved(QModelIndexList)), SLOT(indexesMoved(QModelIndexList)));
|
|
connect(m_iconView, SIGNAL(contextMenuRequest(QWidget*,QPoint)), SLOT(contextMenuRequest(QWidget*,QPoint)));
|
|
connect(m_iconView, SIGNAL(busy(bool)), SLOT(setBusy(bool)));
|
|
|
|
FolderViewAdapter *adapter = new FolderViewAdapter(m_iconView);
|
|
m_previewGenerator = new KFilePreviewGenerator(adapter, m_model);
|
|
m_previewGenerator->setPreviewShown(m_showPreviews);
|
|
m_previewGenerator->setEnabledPlugins(m_previewPlugins);
|
|
|
|
QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Vertical, this);
|
|
layout->setContentsMargins(0, 0, 0, 0);
|
|
layout->setSpacing(0);
|
|
if (m_label && (m_labelType != FolderView::None)) {
|
|
layout->addItem(m_label);
|
|
}
|
|
layout->addItem(m_iconView);
|
|
|
|
setLayout(layout);
|
|
}
|
|
|
|
void FolderView::fontSettingsChanged()
|
|
{
|
|
QFont font = Plasma::Theme::defaultTheme()->font(Plasma::Theme::DesktopFont);
|
|
|
|
if (m_iconView) {
|
|
m_iconView->setFont(font);
|
|
}
|
|
|
|
if (m_label) {
|
|
font.setPointSize(font.pointSize() + 1);
|
|
font.setBold(true);
|
|
m_label->setFont(font);
|
|
}
|
|
}
|
|
|
|
void FolderView::iconSettingsChanged(int group)
|
|
{
|
|
if (group == KIconLoader::Desktop && m_iconView) {
|
|
const int size = (m_customIconSize != 0) ?
|
|
m_customIconSize : KIconLoader::global()->currentSize(KIconLoader::Desktop);
|
|
|
|
m_iconView->setIconSize(QSize(size, size));
|
|
m_iconView->markAreaDirty(m_iconView->visibleArea());
|
|
m_iconView->update();
|
|
} else if (group == KIconLoader::Panel && m_listView) {
|
|
const int size = (m_customIconSize != 0) ?
|
|
m_customIconSize : KIconLoader::global()->currentSize(KIconLoader::Panel);
|
|
|
|
m_listView->setIconSize(QSize(size, size));
|
|
m_listView->markAreaDirty(m_listView->visibleArea());
|
|
m_listView->update();
|
|
|
|
updateGeometry();
|
|
}
|
|
}
|
|
|
|
void FolderView::clickSettingsChanged()
|
|
{
|
|
if (m_iconView) {
|
|
m_iconView->setShowSelectionMarker(KGlobalSettings::singleClick());
|
|
}
|
|
}
|
|
|
|
void FolderView::plasmaThemeChanged()
|
|
{
|
|
if (m_textColor != Qt::transparent) {
|
|
return;
|
|
}
|
|
|
|
if (m_iconView) {
|
|
QPalette palette = m_iconView->palette();
|
|
palette.setColor(QPalette::Text, textColor());
|
|
m_iconView->setPalette(palette);
|
|
}
|
|
|
|
if (m_listView) {
|
|
updateListViewState();
|
|
}
|
|
|
|
if (m_label) {
|
|
QPalette palette = m_label->palette();
|
|
palette.setColor(QPalette::Text, textColor());
|
|
m_label->setPalette(palette);
|
|
}
|
|
}
|
|
|
|
/*
|
|
// TODO Mark the cut icons as cut, but test performance!
|
|
void FolderView::clipboardDataChanged()
|
|
{
|
|
const QMimeData *mimeData = QApplication::clipboard()->mimeData();
|
|
if (KonqMimeData::decodeIsCutSelection(mimeData)) {
|
|
KUrl::List urls = KUrl::List::fromMimeData(mimeData);
|
|
.. marking items as cut code would go here ..
|
|
}
|
|
}
|
|
*/
|
|
|
|
void FolderView::saveIconPositions() const
|
|
{
|
|
if (!m_iconView) {
|
|
return;
|
|
}
|
|
|
|
const QStringList data = m_iconView->iconPositionsData();
|
|
if (!data.isEmpty()) {
|
|
config().writeEntry("savedPositions", data);
|
|
} else {
|
|
config().deleteEntry("savedPositions");
|
|
}
|
|
}
|
|
|
|
void FolderView::paintInterface(QPainter *painter, const QStyleOptionGraphicsItem *option, const QRect &contentRect)
|
|
{
|
|
Q_UNUSED(painter)
|
|
Q_UNUSED(option)
|
|
Q_UNUSED(contentRect)
|
|
}
|
|
|
|
void FolderView::constraintsEvent(Plasma::Constraints constraints)
|
|
{
|
|
if (constraints & Plasma::FormFactorConstraint) {
|
|
if (isContainment()) {
|
|
setBackgroundHints(Applet::NoBackground);
|
|
} else if (formFactor() == Plasma::Planar || formFactor() == Plasma::MediaCenter) {
|
|
setBackgroundHints(Applet::TranslucentBackground);
|
|
}
|
|
|
|
if (formFactor() == Plasma::Planar || formFactor() == Plasma::MediaCenter) {
|
|
// Clean up the icon widget
|
|
const bool wasIconified = m_iconWidget != 0;
|
|
if (wasIconified) {
|
|
disconnect(m_dirModel->dirLister(), SIGNAL(newItems(KFileItemList)), this, SLOT(updateIconWidget()));
|
|
disconnect(m_dirModel->dirLister(), SIGNAL(itemsDeleted(KFileItemList)), this, SLOT(updateIconWidget()));
|
|
disconnect(m_dirModel->dirLister(), SIGNAL(clear()), this, SLOT(updateIconWidget()));
|
|
}
|
|
|
|
delete m_iconWidget;
|
|
delete m_dialog;
|
|
m_iconWidget = 0;
|
|
m_dialog = 0;
|
|
m_listView = 0;
|
|
|
|
if (!isContainment()) {
|
|
// Give the applet a sane size
|
|
setupIconView();
|
|
}
|
|
|
|
if (wasIconified) {
|
|
// if we're coming out of an iconified state, let's reset to a reasonable sane state
|
|
// NOTE: usually one NEVER resizes outside of the constructor as that overrides the
|
|
// user settings, but in this case we are changing applet state completely and there
|
|
// is no user state for size in that case for folderview (by defintion)
|
|
resize(600, 400);
|
|
}
|
|
setAspectRatioMode(Plasma::IgnoreAspectRatio);
|
|
} else if (!m_iconWidget) {
|
|
// Clean up the icon view
|
|
delete m_label;
|
|
delete m_iconView;
|
|
m_label = 0;
|
|
m_iconView = 0;
|
|
|
|
// Set up the icon widget
|
|
m_iconWidget = new IconWidget(this);
|
|
m_iconWidget->setModel(m_dirModel);
|
|
m_iconWidget->setIcon(m_icon.isNull() ? KIcon("folder-blue") : m_icon);
|
|
connect(m_iconWidget, SIGNAL(clicked()), SLOT(iconWidgetClicked()));
|
|
|
|
updateIconWidget();
|
|
|
|
// We need to update the tooltip (and maybe the icon) when the contents of the folder changes
|
|
connect(m_dirModel->dirLister(), SIGNAL(newItems(KFileItemList)), SLOT(updateIconWidget()));
|
|
connect(m_dirModel->dirLister(), SIGNAL(itemsDeleted(KFileItemList)), SLOT(updateIconWidget()));
|
|
connect(m_dirModel->dirLister(), SIGNAL(clear()), SLOT(updateIconWidget()));
|
|
|
|
m_listView = new ListView;
|
|
m_listView->setItemDelegate(m_delegate);
|
|
m_listView->setModel(m_model);
|
|
m_listView->setSelectionModel(m_selectionModel);
|
|
|
|
// Add widget specific actions with shortcuts to the view
|
|
addActions(m_listView);
|
|
|
|
connect(m_listView, SIGNAL(activated(QModelIndex)), SLOT(activated(QModelIndex)));
|
|
connect(m_listView, SIGNAL(contextMenuRequest(QWidget*,QPoint)), SLOT(contextMenuRequest(QWidget*,QPoint)));
|
|
|
|
FolderViewAdapter *adapter = new FolderViewAdapter(m_listView);
|
|
m_previewGenerator = new KFilePreviewGenerator(adapter, m_model);
|
|
m_previewGenerator->setPreviewShown(m_showPreviews);
|
|
m_previewGenerator->setEnabledPlugins(m_previewPlugins);
|
|
|
|
updateListViewState();
|
|
|
|
m_dialog = new Dialog;
|
|
m_dialog->setGraphicsWidget(m_listView); // Ownership is transferred to the scene in the dialog
|
|
|
|
QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(this);
|
|
layout->setContentsMargins(0, 0, 0, 0);
|
|
layout->setSpacing(0);
|
|
layout->addItem(m_iconWidget);
|
|
|
|
setLayout(layout);
|
|
int iconSize = IconSize(KIconLoader::Panel);
|
|
setPreferredSize(QSizeF(iconSize, iconSize));
|
|
setAspectRatioMode(Plasma::ConstrainedSquare);
|
|
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
|
}
|
|
}
|
|
|
|
if (constraints & Plasma::ScreenConstraint) {
|
|
Plasma::Corona *c = corona();
|
|
disconnect(c, SIGNAL(availableScreenRegionChanged()), this, SLOT(updateScreenRegion()));
|
|
if (isContainment() && screen() > -1) {
|
|
updateScreenRegion();
|
|
connect(c, SIGNAL(availableScreenRegionChanged()), this, SLOT(updateScreenRegion()));
|
|
}
|
|
}
|
|
}
|
|
|
|
void FolderView::updateScreenRegion()
|
|
{
|
|
if (!m_iconView) {
|
|
return;
|
|
}
|
|
|
|
Plasma::Corona *c = corona();
|
|
if (!c) {
|
|
return;
|
|
}
|
|
|
|
const QRect screenRect = c->screenGeometry(screen());
|
|
QRect availRect;
|
|
//FIXME: a pretty horrible hack, but there we go; should do something more elegant in 4.5
|
|
if (c->metaObject()->indexOfSlot("availableScreenRect(int)") != -1) {
|
|
QMetaObject::invokeMethod(c, "availableScreenRect",
|
|
Qt::DirectConnection, Q_RETURN_ARG(QRect, availRect), Q_ARG(int, screen()));
|
|
|
|
// Workaround for bug 294795. Some kind of memory corruption error can lead to
|
|
// availRect.bottom() being set to 0 after availableScreenRect returns. If this
|
|
// happens, use qdesktopwidget instead.
|
|
if (availRect.bottom() == 0) {
|
|
availRect = QApplication::desktop()->availableGeometry(screen());
|
|
}
|
|
} else {
|
|
kDebug() << "using qdesktopwidget";
|
|
availRect = QApplication::desktop()->availableGeometry(screen());
|
|
}
|
|
|
|
m_iconView->setContentsMargins(availRect.x() - screenRect.x(),
|
|
availRect.y() - screenRect.y(),
|
|
screenRect.right() - availRect.right(),
|
|
screenRect.bottom() - availRect.bottom());
|
|
}
|
|
|
|
void FolderView::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
|
|
{
|
|
if (isContainment()) {
|
|
Containment::dragEnterEvent(event);
|
|
}
|
|
}
|
|
|
|
void FolderView::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
|
|
{
|
|
if (isContainment()) {
|
|
QGraphicsItem *item = scene()->itemAt(event->scenePos());
|
|
if (item == m_iconView) {
|
|
event->setAccepted(true);
|
|
} else {
|
|
Containment::dragMoveEvent(event);
|
|
}
|
|
}
|
|
}
|
|
|
|
void FolderView::dropEvent(QGraphicsSceneDragDropEvent *event)
|
|
{
|
|
if (isContainment()) {
|
|
Containment::dropEvent(event);
|
|
}
|
|
}
|
|
|
|
void FolderView::setUrl(const KUrl &url)
|
|
{
|
|
m_url = url;
|
|
setAssociatedApplicationUrls(KUrl::List() << m_url);
|
|
|
|
if (KProtocolInfo::protocolIsLocal(m_url.protocol())) {
|
|
m_dirLister->openUrl(m_url);
|
|
} else if (m_networkManager->status() != KNetworkManager::ConnectedStatus) {
|
|
QString networkStatus(i18n("Network is not reachable"));
|
|
showMessage(KIcon("dialog-warning"), networkStatus, Plasma::ButtonOk);
|
|
} else {
|
|
m_dirLister->openUrl(m_url);
|
|
}
|
|
|
|
// Only parse desktop files when sorting if we're showing the desktop folder
|
|
m_model->setParseDesktopFiles(m_url == KUrl(KGlobalSettings::desktopPath()));
|
|
setAppletTitle();
|
|
}
|
|
|
|
void FolderView::setAppletTitle()
|
|
{
|
|
if (m_labelType == FolderView::None) {
|
|
m_titleText.clear();
|
|
} else if (m_labelType == FolderView::FullPath) {
|
|
m_titleText = m_url.path();
|
|
} else if (m_labelType == FolderView::PlaceName) {
|
|
if (m_url == KUrl(KGlobalSettings::desktopPath())) {
|
|
m_titleText = i18n("Desktop Folder");
|
|
} else {
|
|
m_titleText = m_url.pathOrUrl();
|
|
|
|
if (!m_placesModel) {
|
|
m_placesModel = new KFilePlacesModel(this);
|
|
}
|
|
const QModelIndex index = m_placesModel->closestItem(m_url);
|
|
if (index.isValid()) {
|
|
m_titleText = m_titleText.right(m_titleText.length() - m_placesModel->url(index).pathOrUrl().length());
|
|
|
|
if (!m_titleText.isEmpty()) {
|
|
if (m_titleText.at(0) == '/') {
|
|
m_titleText.remove(0, 1);
|
|
}
|
|
|
|
if (layoutDirection() == Qt::RightToLeft) {
|
|
m_titleText.prepend(" < ");
|
|
} else {
|
|
m_titleText.prepend(" > ");
|
|
}
|
|
}
|
|
|
|
m_titleText.prepend(m_placesModel->text(index));
|
|
}
|
|
}
|
|
} else {
|
|
m_titleText = m_customLabel;
|
|
}
|
|
kDebug() << "WORKING WITH" << m_labelType << m_customLabel << "WE GOT" << m_titleText;
|
|
|
|
if (m_labelType == FolderView::None) {
|
|
if (m_label) {
|
|
m_label->hide();
|
|
}
|
|
recreateLayout();
|
|
} else {
|
|
if (m_label) {
|
|
m_label->setText(m_titleText);
|
|
m_label->show();
|
|
}
|
|
recreateLayout();
|
|
}
|
|
updateIconWidget();
|
|
}
|
|
|
|
void FolderView::recreateLayout()
|
|
{
|
|
QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Vertical, this);
|
|
layout->setContentsMargins(0, 0, 0, 0);
|
|
layout->setSpacing(0);
|
|
if (m_labelType != FolderView::None) {
|
|
layout->addItem(m_label);
|
|
}
|
|
layout->addItem(m_iconView);
|
|
|
|
setLayout(layout);
|
|
}
|
|
|
|
void FolderView::createActions()
|
|
{
|
|
KIO::FileUndoManager *manager = KIO::FileUndoManager::self();
|
|
|
|
// Remove the Shift+Delete shortcut from the cut action, since it's used for deleting files
|
|
KAction *cut = KStandardAction::cut(this, SLOT(cut()), this);
|
|
QKeySequence cutShortcut = cut->shortcut();
|
|
static const int shiftdelete = (Qt::SHIFT | Qt::Key_Delete);
|
|
if (cutShortcut[0] == shiftdelete) {
|
|
cutShortcut = QKeySequence(cutShortcut[1]);
|
|
}
|
|
if (cutShortcut[0] == shiftdelete) {
|
|
cutShortcut = QKeySequence();
|
|
}
|
|
cut->setShortcut(cutShortcut);
|
|
cut->setShortcutContext(Qt::WidgetShortcut);
|
|
|
|
KAction *copy = KStandardAction::copy(this, SLOT(copy()), this);
|
|
copy->setShortcutContext(Qt::WidgetShortcut);
|
|
|
|
KAction *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, SIGNAL(undoTextChanged(QString)), SLOT(undoTextChanged(QString)));
|
|
|
|
KAction *paste = KStandardAction::paste(this, SLOT(paste()), this);
|
|
paste->setShortcutContext(Qt::WidgetShortcut);
|
|
|
|
QString actionText = KIO::pasteActionText();
|
|
if (!actionText.isEmpty()) {
|
|
paste->setText(actionText);
|
|
} else {
|
|
paste->setEnabled(false);
|
|
}
|
|
|
|
KAction *pasteTo = KStandardAction::paste(this, SLOT(pasteTo()), this);
|
|
pasteTo->setEnabled(false); // Only enabled during popupMenu()
|
|
pasteTo->setShortcutContext(Qt::WidgetShortcut);
|
|
|
|
KAction *reload = new KAction(i18n("&Reload"), this);
|
|
connect(reload, SIGNAL(triggered()), SLOT(refreshIcons()));
|
|
|
|
KAction *refresh = new KAction(isContainment() ? i18n("&Refresh Desktop") : i18n("&Refresh View"), this);
|
|
refresh->setShortcut(KStandardShortcut::reload());
|
|
refresh->setShortcutContext(Qt::WidgetShortcut);
|
|
if (isContainment()) {
|
|
refresh->setIcon(KIcon("user-desktop"));
|
|
}
|
|
connect(refresh, SIGNAL(triggered()), SLOT(refreshIcons()));
|
|
|
|
KAction *rename = new KAction(KIcon("edit-rename"), i18n("&Rename"), this);
|
|
rename->setShortcut(Qt::Key_F2);
|
|
rename->setShortcutContext(Qt::WidgetShortcut);
|
|
connect(rename, SIGNAL(triggered()), SLOT(renameSelectedIcon()));
|
|
|
|
KAction *trash = new KAction(KIcon("user-trash"), i18n("&Move to Trash"), this);
|
|
trash->setShortcut(Qt::Key_Delete);
|
|
trash->setShortcutContext(Qt::WidgetShortcut);
|
|
connect(trash, SIGNAL(triggered(Qt::MouseButtons,Qt::KeyboardModifiers)),
|
|
SLOT(moveToTrash(Qt::MouseButtons,Qt::KeyboardModifiers)));
|
|
|
|
KAction *emptyTrash = new KAction(KIcon("trash-empty"), i18n("&Empty Trash Bin"), this);
|
|
KConfig trashConfig("trashrc", KConfig::SimpleConfig);
|
|
emptyTrash->setEnabled(!trashConfig.group("Status").readEntry("Empty", true));
|
|
connect(emptyTrash, SIGNAL(triggered()), SLOT(emptyTrashBin()));
|
|
|
|
KAction *del = new KAction(i18n("&Delete"), this);
|
|
del->setIcon(KIcon("edit-delete"));
|
|
del->setShortcut(Qt::SHIFT + Qt::Key_Delete);
|
|
del->setShortcutContext(Qt::WidgetShortcut);
|
|
connect(del, SIGNAL(triggered()), SLOT(deleteSelectedIcons()));
|
|
|
|
m_actionCollection.addAction("cut", cut);
|
|
m_actionCollection.addAction("undo", undo);
|
|
m_actionCollection.addAction("copy", copy);
|
|
m_actionCollection.addAction("paste", paste);
|
|
m_actionCollection.addAction("pasteto", pasteTo);
|
|
m_actionCollection.addAction("reload", reload);
|
|
m_actionCollection.addAction("refresh", refresh);
|
|
m_actionCollection.addAction("rename", rename);
|
|
m_actionCollection.addAction("trash", trash);
|
|
m_actionCollection.addAction("del", del);
|
|
m_actionCollection.addAction("empty_trash", emptyTrash);
|
|
|
|
KAction *alignToGrid = new KAction(i18n("Align to Grid"), this);
|
|
alignToGrid->setCheckable(true);
|
|
alignToGrid->setChecked(m_alignToGrid);
|
|
connect(alignToGrid, SIGNAL(toggled(bool)), SLOT(toggleAlignToGrid(bool)));
|
|
|
|
KAction *lockIcons = new KAction(i18nc("Icons on the desktop", "Lock in Place"), this);
|
|
lockIcons->setCheckable(true);
|
|
lockIcons->setChecked(m_iconsLocked);
|
|
connect(lockIcons, SIGNAL(toggled(bool)), SLOT(toggleIconsLocked(bool)));
|
|
|
|
m_layoutGroup = new QActionGroup(this);
|
|
connect(m_layoutGroup, SIGNAL(triggered(QAction*)), SLOT(layoutChanged(QAction*)));
|
|
QAction *layoutRows = m_layoutGroup->addAction(i18nc("Arrange icons in", "Rows"));
|
|
QAction *layoutColumns = m_layoutGroup->addAction(i18nc("Arrange icons in", "Columns"));
|
|
|
|
layoutRows->setCheckable(true);
|
|
layoutRows->setData(QVariant::fromValue(IconView::Rows));
|
|
|
|
layoutColumns->setCheckable(true);
|
|
layoutColumns->setData(QVariant::fromValue(IconView::Columns));
|
|
|
|
m_alignmentGroup = new QActionGroup(this);
|
|
connect(m_alignmentGroup, SIGNAL(triggered(QAction*)), SLOT(alignmentChanged(QAction*)));
|
|
QAction *alignLeft = m_alignmentGroup->addAction(i18nc("Align icons", "Left"));
|
|
QAction *alignRight = m_alignmentGroup->addAction(i18nc("Align icons", "Right"));
|
|
|
|
alignLeft->setCheckable(true);
|
|
alignLeft->setData(QVariant::fromValue(IconView::Left));
|
|
|
|
alignRight->setCheckable(true);
|
|
alignRight->setData(QVariant::fromValue(IconView::Right));
|
|
|
|
KAction *unsorted = new KAction(i18nc("Sort icons", "Unsorted"), this);
|
|
unsorted->setData(int(FolderView::Unsorted));
|
|
|
|
m_sortingGroup = new QActionGroup(this);
|
|
connect(m_sortingGroup, SIGNAL(triggered(QAction*)), SLOT(sortingChanged(QAction*)));
|
|
QAction *sortByName = m_sortingGroup->addAction(i18nc("Sort icons by", "Name"));
|
|
QAction *sortBySize = m_sortingGroup->addAction(i18nc("Sort icons by", "Size"));
|
|
QAction *sortByType = m_sortingGroup->addAction(i18nc("Sort icons by", "Type"));
|
|
QAction *sortByDate = m_sortingGroup->addAction(i18nc("Sort icons by", "Date"));
|
|
|
|
sortByName->setCheckable(true);
|
|
sortByName->setData(int(KDirModel::Name));
|
|
|
|
sortBySize->setCheckable(true);
|
|
sortBySize->setData(int(KDirModel::Size));
|
|
|
|
sortByType->setCheckable(true);
|
|
sortByType->setData(int(KDirModel::Type));
|
|
|
|
sortByDate->setCheckable(true);
|
|
sortByDate->setData(int(KDirModel::ModifiedTime));
|
|
|
|
KAction *sortDescending = new KAction(i18nc("Sort icons", "Descending"), this);
|
|
sortDescending->setCheckable(true);
|
|
sortDescending->setChecked(m_sortOrder == Qt::DescendingOrder);
|
|
connect(sortDescending, SIGNAL(toggled(bool)), SLOT(toggleSortDescending(bool)));
|
|
|
|
KAction *dirsFirst = new KAction(i18nc("Sort icons", "Folders First"), this);
|
|
dirsFirst->setCheckable(true);
|
|
dirsFirst->setChecked(m_sortDirsFirst);
|
|
connect(dirsFirst, SIGNAL(toggled(bool)), SLOT(toggleDirectoriesFirst(bool)));
|
|
|
|
QMenu *arrangeMenu = new QMenu(i18n("Arrange In"));
|
|
arrangeMenu->addAction(layoutRows);
|
|
arrangeMenu->addAction(layoutColumns);
|
|
|
|
QMenu *alignMenu = new QMenu(i18n("Align"));
|
|
alignMenu->addAction(alignLeft);
|
|
alignMenu->addAction(alignRight);
|
|
|
|
QMenu *sortMenu = new QMenu(i18n("Sort By"));
|
|
sortMenu->addAction(sortByName);
|
|
sortMenu->addAction(sortBySize);
|
|
sortMenu->addAction(sortByType);
|
|
sortMenu->addAction(sortByDate);
|
|
sortMenu->addSeparator();
|
|
sortMenu->addAction(sortDescending);
|
|
sortMenu->addAction(dirsFirst);
|
|
|
|
QMenu *iconsMenu = new QMenu;
|
|
iconsMenu->addMenu(arrangeMenu);
|
|
iconsMenu->addMenu(alignMenu);
|
|
iconsMenu->addMenu(sortMenu);
|
|
iconsMenu->addSeparator();
|
|
iconsMenu->addAction(alignToGrid);
|
|
iconsMenu->addAction(lockIcons);
|
|
|
|
QAction *iconsMenuAction = new KAction(i18n("Icons"), this);
|
|
iconsMenuAction->setIcon(KIcon("preferences-desktop-icons"));
|
|
iconsMenuAction->setMenu(iconsMenu);
|
|
|
|
// Create the new menu
|
|
m_newMenu = new KNewFileMenu(&m_actionCollection, "new_menu", QApplication::desktop());
|
|
m_newMenu->setModal(false);
|
|
|
|
connect(m_newMenu->menu(), SIGNAL(aboutToShow()), this, SLOT(aboutToShowCreateNew()));
|
|
|
|
m_actionCollection.addAction("lock_icons", lockIcons);
|
|
m_actionCollection.addAction("auto_align", alignToGrid);
|
|
m_actionCollection.addAction("sort_desc", sortDescending);
|
|
m_actionCollection.addAction("dirs_first", dirsFirst);
|
|
m_actionCollection.addAction("icons_menu", iconsMenuAction);
|
|
m_actionCollection.addAction("layout_rows", layoutRows);
|
|
m_actionCollection.addAction("layout_columns", layoutColumns);
|
|
m_actionCollection.addAction("align_left", alignLeft);
|
|
m_actionCollection.addAction("align_right", alignRight);
|
|
m_actionCollection.addAction("unsorted", unsorted);
|
|
m_actionCollection.addAction("sort_name", sortByName);
|
|
m_actionCollection.addAction("sort_size", sortBySize);
|
|
m_actionCollection.addAction("sort_type", sortByType);
|
|
m_actionCollection.addAction("sort_date", sortByDate);
|
|
|
|
updateFlowActionsState();
|
|
updateSortActionsState();
|
|
}
|
|
|
|
void FolderView::updatePasteAction()
|
|
{
|
|
if (QAction *paste = m_actionCollection.action("paste")) {
|
|
const QString pasteText = KIO::pasteActionText();
|
|
if (pasteText.isEmpty()) {
|
|
paste->setText(i18n("&Paste"));
|
|
paste->setEnabled(false);
|
|
} else {
|
|
paste->setText(pasteText);
|
|
paste->setEnabled(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
QList<QAction*> FolderView::contextualActions()
|
|
{
|
|
QList<QAction*> actions;
|
|
|
|
KFileItem rootItem = m_model->itemForIndex(QModelIndex());
|
|
if (!rootItem.isNull()) {
|
|
if (QAction *action = m_actionCollection.action("new_menu")) {
|
|
actions.append(action);
|
|
QAction *separator = new QAction(this);
|
|
separator->setSeparator(true);
|
|
actions.append(separator);
|
|
}
|
|
|
|
actions.append(m_actionCollection.action("undo"));
|
|
if (QAction *paste = m_actionCollection.action("paste")) {
|
|
updatePasteAction();
|
|
actions.append(paste);
|
|
}
|
|
|
|
QAction *separator = new QAction(this);
|
|
separator->setSeparator(true);
|
|
actions.append(separator);
|
|
|
|
if (m_iconView) {
|
|
if (QAction *iconsMenu = m_actionCollection.action("icons_menu")) {
|
|
actions.append(iconsMenu);
|
|
}
|
|
}
|
|
|
|
actions.append(m_actionCollection.action("refresh"));
|
|
|
|
// Create a new KFileItem to prevent the target URL in the root item
|
|
// from being used. In this case we want the configured URL instead.
|
|
KFileItemListProperties itemList(KFileItemList() << KFileItem(m_url));
|
|
m_itemActions->setItemListProperties(itemList);
|
|
|
|
// FIXME: The actions instanciated by KFileItemActions::preferredOpenWithAction()
|
|
// (see below) are eventually deleted in its constructor, but it would be better
|
|
// to find a way to not keep them around rather than just to hide them.
|
|
if (m_openWithAction) {
|
|
m_openWithAction->setVisible(false);
|
|
}
|
|
|
|
// Add an action for opening the folder in the preferred application.
|
|
m_openWithAction = m_itemActions->preferredOpenWithAction(QString());
|
|
actions.append(m_openWithAction);
|
|
|
|
if (m_url.protocol() == "trash") {
|
|
KConfig trashConfig("trashrc", KConfig::SimpleConfig);
|
|
m_actionCollection.action("empty_trash")->setEnabled(!trashConfig.group("Status")
|
|
.readEntry("Empty", true));
|
|
actions.append(m_actionCollection.action("empty_trash"));
|
|
}
|
|
|
|
separator = new QAction(this);
|
|
separator->setSeparator(true);
|
|
actions.append(separator);
|
|
}
|
|
|
|
return actions;
|
|
}
|
|
|
|
void FolderView::aboutToShowCreateNew()
|
|
{
|
|
if (m_newMenu) {
|
|
m_newMenu->checkUpToDate();
|
|
m_newMenu->setPopupFiles(m_url);
|
|
}
|
|
}
|
|
|
|
KUrl::List FolderView::selectedUrls(bool forTrash) const
|
|
{
|
|
KUrl::List urls;
|
|
foreach (const QModelIndex &index, m_selectionModel->selectedIndexes())
|
|
{
|
|
KFileItem item = m_model->itemForIndex(index);
|
|
|
|
if (forTrash) {
|
|
// Prefer the local URL if there is one, since we can't trash remote URL's
|
|
const QString path = item.localPath();
|
|
if (!path.isEmpty()) {
|
|
urls.append(path);
|
|
} else {
|
|
urls.append(item.url());
|
|
}
|
|
} else {
|
|
urls.append(item.url());
|
|
}
|
|
}
|
|
return urls;
|
|
}
|
|
|
|
void FolderView::copy()
|
|
{
|
|
QMimeData *mimeData = m_model->mimeData(m_selectionModel->selectedIndexes());
|
|
QApplication::clipboard()->setMimeData(mimeData);
|
|
}
|
|
|
|
void FolderView::cut()
|
|
{
|
|
QMimeData *mimeData = m_model->mimeData(m_selectionModel->selectedIndexes());
|
|
KonqMimeData::addIsCutSelection(mimeData, true);
|
|
QApplication::clipboard()->setMimeData(mimeData);
|
|
}
|
|
|
|
void FolderView::paste()
|
|
{
|
|
KonqOperations::doPaste(QApplication::desktop(), m_url);
|
|
}
|
|
|
|
void FolderView::pasteTo()
|
|
{
|
|
const KUrl::List urls = selectedUrls(false);
|
|
Q_ASSERT(urls.count() == 1);
|
|
KonqOperations::doPaste(QApplication::desktop(), urls.first());
|
|
}
|
|
|
|
void FolderView::refreshIcons()
|
|
{
|
|
m_dirModel->dirLister()->updateDirectory();
|
|
}
|
|
|
|
void FolderView::toggleIconsLocked(bool locked)
|
|
{
|
|
m_iconsLocked = locked;
|
|
|
|
if (m_iconView) {
|
|
m_iconView->setIconsMoveable(!locked);
|
|
}
|
|
if (isUserConfiguring()) {
|
|
uiDisplay.lockInPlace->setChecked(locked);
|
|
}
|
|
|
|
config().writeEntry("iconsLocked", locked);
|
|
emit configNeedsSaving();
|
|
}
|
|
|
|
void FolderView::toggleAlignToGrid(bool align)
|
|
{
|
|
m_alignToGrid = align;
|
|
|
|
if (m_iconView) {
|
|
m_iconView->setAlignToGrid(align);
|
|
}
|
|
if (isUserConfiguring()) {
|
|
uiDisplay.alignToGrid->setChecked(align);
|
|
}
|
|
|
|
config().writeEntry("alignToGrid", align);
|
|
emit configNeedsSaving();
|
|
|
|
m_delayedSaveTimer.start(5000, this);
|
|
}
|
|
|
|
void FolderView::toggleClickToViewFolders(bool enable)
|
|
{
|
|
m_clickToView = enable;
|
|
|
|
if (m_iconView) {
|
|
m_iconView->setClickToViewFolders(enable);
|
|
}
|
|
if (isUserConfiguring()) {
|
|
uiDisplay.clickToView->setChecked(enable);
|
|
}
|
|
|
|
config().writeEntry("clickForFolderPreviews", enable);
|
|
emit configNeedsSaving();
|
|
|
|
m_delayedSaveTimer.start(5000, this);
|
|
}
|
|
|
|
void FolderView::toggleSortDescending(bool enable)
|
|
{
|
|
m_sortOrder = enable ? Qt::DescendingOrder : Qt::AscendingOrder;
|
|
|
|
m_model->invalidate();
|
|
m_model->sort(m_sortColumn, m_sortOrder);
|
|
m_model->setDynamicSortFilter(true);
|
|
if (isUserConfiguring()) {
|
|
uiDisplay.sortDescending->setChecked(enable);
|
|
}
|
|
|
|
config().writeEntry("sortOrder", sortOrderEnumToString(m_sortOrder));
|
|
emit configNeedsSaving();
|
|
|
|
m_delayedSaveTimer.start(5000, this);
|
|
}
|
|
|
|
void FolderView::toggleDirectoriesFirst(bool enable)
|
|
{
|
|
m_sortDirsFirst = enable;
|
|
|
|
m_model->setSortDirectoriesFirst(m_sortDirsFirst);
|
|
if (m_sortColumn != int(FolderView::Unsorted)) {
|
|
m_model->invalidate();
|
|
}
|
|
if (isUserConfiguring()) {
|
|
uiDisplay.foldersFirst->setChecked(enable);
|
|
}
|
|
|
|
config().writeEntry("sortDirsFirst", m_sortDirsFirst);
|
|
emit configNeedsSaving();
|
|
|
|
m_delayedSaveTimer.start(5000, this);
|
|
}
|
|
|
|
void FolderView::layoutChanged(QAction* action)
|
|
{
|
|
const IconView::Layout layout = action->data().value<IconView::Layout>();
|
|
|
|
if (layout != m_layout) {
|
|
m_layout = layout;
|
|
if (m_iconView) {
|
|
m_iconView->setLayout(m_layout);
|
|
}
|
|
if (isUserConfiguring()) {
|
|
setCurrentItem(uiDisplay.layoutCombo, m_layout);
|
|
}
|
|
config().writeEntry("layout", static_cast<int>(m_layout));
|
|
emit configNeedsSaving();
|
|
m_delayedSaveTimer.start(5000, this);
|
|
}
|
|
}
|
|
|
|
void FolderView::alignmentChanged(QAction* action)
|
|
{
|
|
const IconView::Alignment alignment = action->data().value<IconView::Alignment>();
|
|
|
|
if (alignment != m_alignment) {
|
|
m_alignment = alignment;
|
|
if (m_iconView) {
|
|
m_iconView->setAlignment(m_alignment);
|
|
}
|
|
if (isUserConfiguring()) {
|
|
setCurrentItem(uiDisplay.alignmentCombo, m_alignment);
|
|
}
|
|
config().writeEntry("alignment", static_cast<int>(m_alignment));
|
|
emit configNeedsSaving();
|
|
m_delayedSaveTimer.start(5000, this);
|
|
}
|
|
}
|
|
|
|
void FolderView::sortingChanged(QAction *action)
|
|
{
|
|
const int column = action->data().toInt();
|
|
|
|
if (column != m_sortColumn) {
|
|
m_model->invalidate();
|
|
m_model->sort(column, m_sortOrder);
|
|
m_model->setDynamicSortFilter(true);
|
|
m_sortColumn = column;
|
|
if (isUserConfiguring()) {
|
|
setCurrentItem(uiDisplay.sortCombo, m_sortColumn);
|
|
}
|
|
config().writeEntry("sortColumn", m_sortColumn);
|
|
emit configNeedsSaving();
|
|
m_delayedSaveTimer.start(5000, this);
|
|
}
|
|
}
|
|
|
|
void FolderView::updateFlowActionsState()
|
|
{
|
|
foreach (QAction *action, m_layoutGroup->actions()) {
|
|
action->setChecked(action->data().value<IconView::Layout>() == m_layout);
|
|
}
|
|
foreach (QAction *action, m_alignmentGroup->actions()) {
|
|
action->setChecked(action->data().value<IconView::Alignment>() == m_alignment);
|
|
}
|
|
}
|
|
|
|
void FolderView::updateSortActionsState()
|
|
{
|
|
foreach (QAction *action, m_sortingGroup->actions()) {
|
|
action->setChecked(action->data() == int(m_sortColumn));
|
|
}
|
|
}
|
|
|
|
|
|
void FolderView::filterChanged(int index)
|
|
{
|
|
const ProxyModel::FilterMode filterMode = uiFilter.filterCombo->itemData(index).value<ProxyModel::FilterMode>();
|
|
const bool filterActive = (filterMode != ProxyModel::NoFilter);
|
|
|
|
uiFilter.filterFilesPattern->setEnabled(filterActive);
|
|
uiFilter.searchMimetype->setEnabled(filterActive);
|
|
uiFilter.filterFilesList->setEnabled(filterActive);
|
|
uiFilter.selectAll->setEnabled(filterActive);
|
|
uiFilter.deselectAll->setEnabled(filterActive);
|
|
if (filterActive) {
|
|
selectAllMimetypes();
|
|
}
|
|
}
|
|
|
|
void FolderView::selectAllMimetypes()
|
|
{
|
|
toggleAllMimetypes(Qt::Checked);
|
|
}
|
|
|
|
void FolderView::deselectAllMimeTypes()
|
|
{
|
|
toggleAllMimetypes(Qt::Unchecked);
|
|
}
|
|
|
|
void FolderView::toggleAllMimetypes(Qt::CheckState state)
|
|
{
|
|
for (int i = 0; i < uiFilter.filterFilesList->model()->rowCount(); i++) {
|
|
const QModelIndex index = uiFilter.filterFilesList->model()->index(i, 0);
|
|
uiFilter.filterFilesList->model()->setData(index, state, Qt::CheckStateRole);
|
|
}
|
|
}
|
|
|
|
void FolderView::moveToTrash(Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers)
|
|
{
|
|
Q_UNUSED(buttons)
|
|
if (m_iconView && m_iconView->renameInProgress()) {
|
|
return;
|
|
}
|
|
|
|
KonqOperations::Operation op = (modifiers & Qt::ShiftModifier) ?
|
|
KonqOperations::DEL : KonqOperations::TRASH;
|
|
|
|
KonqOperations::del(QApplication::desktop(), op, selectedUrls(op == KonqOperations::TRASH));
|
|
}
|
|
|
|
void FolderView::deleteSelectedIcons()
|
|
{
|
|
if (m_iconView && m_iconView->renameInProgress()) {
|
|
return;
|
|
}
|
|
|
|
KonqOperations::del(QApplication::desktop(), KonqOperations::DEL, selectedUrls(false));
|
|
}
|
|
|
|
void FolderView::renameSelectedIcon()
|
|
{
|
|
if (m_iconView) {
|
|
m_iconView->renameSelectedIcon();
|
|
}
|
|
}
|
|
|
|
void FolderView::emptyTrashBin()
|
|
{
|
|
KonqOperations::emptyTrash(QApplication::desktop());
|
|
}
|
|
|
|
void FolderView::undoTextChanged(const QString &text)
|
|
{
|
|
if (QAction *action = m_actionCollection.action("undo")) {
|
|
action->setText(text);
|
|
}
|
|
}
|
|
|
|
void FolderView::activated(const QModelIndex &index)
|
|
{
|
|
const KFileItem item = m_model->itemForIndex(index);
|
|
item.run();
|
|
|
|
if (m_dialog && m_dialog->isVisible()) {
|
|
Plasma::WindowEffects::slideWindow(m_dialog, location());
|
|
m_dialog->hide();
|
|
}
|
|
}
|
|
|
|
void FolderView::indexesMoved(const QModelIndexList &indexes)
|
|
{
|
|
Q_UNUSED(indexes)
|
|
|
|
// If the user has rearranged the icons, the view is no longer sorted
|
|
if (m_sortColumn != int(FolderView::Unsorted)) {
|
|
m_sortColumn = int(FolderView::Unsorted);
|
|
m_model->setDynamicSortFilter(false);
|
|
updateSortActionsState();
|
|
|
|
if (isUserConfiguring()) {
|
|
QAction *unsorted = m_actionCollection.action("unsorted");
|
|
if (unsorted) {
|
|
uiDisplay.sortCombo->addItem(KGlobal::locale()->removeAcceleratorMarker(unsorted->text()), unsorted->data());
|
|
}
|
|
setCurrentItem(uiDisplay.sortCombo, int(FolderView::Unsorted));
|
|
}
|
|
|
|
config().writeEntry("sortColumn", m_sortColumn);
|
|
emit configNeedsSaving();
|
|
m_delayedSaveTimer.start(5000, this);
|
|
}
|
|
}
|
|
|
|
void FolderView::contextMenuRequest(QWidget *widget, const QPoint &screenPos)
|
|
{
|
|
showContextMenu(widget, screenPos, m_selectionModel->selectedIndexes());
|
|
}
|
|
|
|
void FolderView::showContextMenu(QWidget *widget, const QPoint &pos, const QModelIndexList &indexes)
|
|
{
|
|
if (indexes.isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
KFileItemList items;
|
|
bool hasRemoteFiles = false;
|
|
bool isTrashLink = false;
|
|
|
|
foreach (const QModelIndex &index, indexes) {
|
|
KFileItem item = m_model->itemForIndex(index);
|
|
if (!item.isNull()) {
|
|
hasRemoteFiles |= item.localPath().isEmpty();
|
|
items.append(item);
|
|
}
|
|
}
|
|
|
|
// 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() == "Link" && file.readUrl() == "trash:/") {
|
|
isTrashLink = true;
|
|
}
|
|
}
|
|
|
|
QAction* pasteTo = m_actionCollection.action("pasteto");
|
|
if (pasteTo) {
|
|
if (QAction *paste = m_actionCollection.action("paste")) {
|
|
updatePasteAction();
|
|
pasteTo->setEnabled(paste->isEnabled());
|
|
pasteTo->setText(paste->text());
|
|
}
|
|
}
|
|
|
|
QList<QAction*> editActions;
|
|
editActions.append(m_actionCollection.action("rename"));
|
|
|
|
KConfigGroup configGroup(KGlobal::config(), "KDE");
|
|
bool showDeleteCommand = configGroup.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("trash"));
|
|
} else {
|
|
showDeleteCommand = true;
|
|
}
|
|
}
|
|
if (showDeleteCommand) {
|
|
editActions.append(m_actionCollection.action("del"));
|
|
}
|
|
|
|
KonqPopupMenu::ActionGroupMap actionGroups;
|
|
actionGroups.insert("editactions", editActions);
|
|
|
|
KonqPopupMenu::PopupFlags flags = KonqPopupMenu::ShowNewWindow;
|
|
flags |= KonqPopupMenu::ShowProperties;
|
|
flags |= KonqPopupMenu::ShowUrlOperations;
|
|
|
|
// m_newMenu can be NULL here but KonqPopupMenu does handle this.
|
|
KonqPopupMenu *contextMenu = new KonqPopupMenu(items, m_url, m_actionCollection, m_newMenu,
|
|
flags, widget,
|
|
KBookmarkManager::userBookmarksManager(),
|
|
actionGroups);
|
|
|
|
contextMenu->exec(pos);
|
|
delete contextMenu;
|
|
|
|
if (pasteTo) {
|
|
pasteTo->setEnabled(false);
|
|
}
|
|
}
|
|
|
|
void FolderView::updateIconWidget()
|
|
{
|
|
if (!m_iconWidget) {
|
|
return;
|
|
}
|
|
|
|
if (!m_placesModel) {
|
|
m_placesModel = new KFilePlacesModel(this);
|
|
}
|
|
|
|
const QModelIndex index = m_placesModel->closestItem(m_url);
|
|
|
|
// TODO: Custom icon
|
|
|
|
KFileItem item = m_dirModel->itemForIndex(QModelIndex());
|
|
if (!item.isNull() && item.iconName() != "inode-directory") {
|
|
m_icon = KIcon(item.iconName(), 0, item.overlays());
|
|
} else if (m_url == KUrl(KGlobalSettings::desktopPath())) {
|
|
m_icon = KIcon("user-desktop");
|
|
} else if (m_url.protocol() == "trash") {
|
|
m_icon = m_model->rowCount() > 0 ? KIcon("user-trash-full") : KIcon("user-trash");
|
|
} else if (index.isValid()) {
|
|
m_icon = m_placesModel->icon(index);
|
|
} else {
|
|
m_icon = KIcon("folder-blue");
|
|
}
|
|
|
|
m_iconWidget->setIcon(m_icon);
|
|
m_iconWidget->update();
|
|
|
|
int nFolders = 0;
|
|
int nFiles = 0;
|
|
for (int row = 0; row < m_model->rowCount(); row++) {
|
|
const QModelIndex index = m_model->index(row, 0);
|
|
KFileItem item = m_model->itemForIndex(index);
|
|
if (item.isDir()) {
|
|
nFolders++;
|
|
} else {
|
|
nFiles++;
|
|
}
|
|
}
|
|
|
|
const QString str1 = i18ncp("Inserted as %1 in the message below.", "1 folder", "%1 folders", nFolders);
|
|
const QString str2 = i18ncp("Inserted as %2 in the message below.", "1 file", "%1 files", nFiles);
|
|
|
|
QString subText;
|
|
if (nFolders > 0) {
|
|
subText = i18nc("%1 and %2 are the messages translated above.", "%1, %2.", str1, str2);
|
|
} else {
|
|
subText = i18np("1 file.", "%1 files.", nFiles);
|
|
}
|
|
|
|
// Update the tooltip
|
|
Plasma::ToolTipContent data;
|
|
data.setMainText(m_titleText);
|
|
data.setSubText(subText);
|
|
data.setImage(m_icon);
|
|
Plasma::ToolTipManager::self()->setContent(m_iconWidget, data);
|
|
}
|
|
|
|
void FolderView::iconWidgetClicked()
|
|
{
|
|
Plasma::WindowEffects::slideWindow(m_dialog, location());
|
|
if (m_dialog->isVisible()) {
|
|
m_dialog->hide();
|
|
} else {
|
|
m_dialog->show(this);
|
|
}
|
|
}
|
|
|
|
QSize FolderView::iconSize() const
|
|
{
|
|
const int defaultSize = KIconLoader::global()->currentSize(m_listView ? KIconLoader::Panel : KIconLoader::Desktop);
|
|
const int size = (m_customIconSize != 0) ? m_customIconSize : defaultSize;
|
|
return QSize(size, size);
|
|
}
|
|
|
|
void FolderView::timerEvent(QTimerEvent *event)
|
|
{
|
|
if (event->timerId() == m_delayedSaveTimer.timerId()) {
|
|
m_delayedSaveTimer.stop();
|
|
saveIconPositions();
|
|
emit configNeedsSaving();
|
|
}
|
|
|
|
Containment::timerEvent(event);
|
|
}
|
|
|
|
QSizeF FolderView::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
|
|
{
|
|
if (which == Qt::PreferredSize) {
|
|
QSizeF size;
|
|
|
|
switch (formFactor()) {
|
|
case Plasma::Planar:
|
|
case Plasma::MediaCenter:
|
|
if (!constraint.isEmpty()) {
|
|
size = QSizeF(600, 400).boundedTo(constraint);
|
|
} else {
|
|
size = QSizeF(600, 400);
|
|
}
|
|
break;
|
|
case Plasma::Horizontal:
|
|
case Plasma::Vertical: {
|
|
const int iconSize = IconSize(KIconLoader::Panel);
|
|
size = QSizeF(iconSize, iconSize);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return size;
|
|
}
|
|
|
|
return Containment::sizeHint(which, constraint);
|
|
|
|
}
|
|
|
|
void FolderView::setTitleEditEnabled(int index)
|
|
{
|
|
if (uiLocation.titleCombo->itemData(index).value<FolderView::LabelType>() == FolderView::Custom) {
|
|
uiLocation.titleEdit->setEnabled(true);
|
|
uiLocation.titleEdit->setFocus();
|
|
} else {
|
|
uiLocation.titleEdit->setEnabled(false);
|
|
}
|
|
}
|
|
|
|
#include "moc_folderview.cpp"
|