┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
path: root/src/views
diff options
context:
space:
mode:
authorPeter Penz <[email protected]>2010-07-24 22:08:30 +0000
committerPeter Penz <[email protected]>2010-07-24 22:08:30 +0000
commita5cf21ff06aff44cde563eaceae3c6cef452ee48 (patch)
tree3d23179b483e4c9ad5598b128c3063885fe33a30 /src/views
parent652d08c9242ed51d86dba3b2afda9d3b2e9a9cd7 (diff)
Sourcecode hierarchy cleanup: Move further files from src to src/views
svn path=/trunk/KDE/kdebase/apps/; revision=1154150
Diffstat (limited to 'src/views')
-rw-r--r--src/views/additionalinfoaccessor.cpp132
-rw-r--r--src/views/additionalinfoaccessor.h100
-rw-r--r--src/views/dolphindirlister.cpp48
-rw-r--r--src/views/dolphindirlister.h48
-rw-r--r--src/views/dolphinfileitemdelegate.cpp2
-rw-r--r--src/views/dolphinfileitemdelegate.h2
-rw-r--r--src/views/dolphinmodel.cpp445
-rw-r--r--src/views/dolphinmodel.h68
-rw-r--r--src/views/dolphinnewmenuobserver.cpp62
-rw-r--r--src/views/dolphinnewmenuobserver.h56
-rw-r--r--src/views/dolphinremoteencoding.cpp241
-rw-r--r--src/views/dolphinremoteencoding.h69
-rw-r--r--src/views/dolphinsortfilterproxymodel.cpp81
-rw-r--r--src/views/dolphinsortfilterproxymodel.h85
-rw-r--r--src/views/dolphinviewactionhandler.cpp518
-rw-r--r--src/views/dolphinviewactionhandler.h252
-rw-r--r--src/views/draganddrophelper.cpp189
-rw-r--r--src/views/draganddrophelper.h102
-rw-r--r--src/views/folderexpander.cpp141
-rw-r--r--src/views/folderexpander.h89
-rw-r--r--src/views/renamedialog.cpp132
-rw-r--r--src/views/renamedialog.h98
-rw-r--r--src/views/viewproperties.cpp310
-rw-r--r--src/views/viewproperties.h163
24 files changed, 3431 insertions, 2 deletions
diff --git a/src/views/additionalinfoaccessor.cpp b/src/views/additionalinfoaccessor.cpp
new file mode 100644
index 000000000..1b445cc99
--- /dev/null
+++ b/src/views/additionalinfoaccessor.cpp
@@ -0,0 +1,132 @@
+/***************************************************************************
+ * Copyright (C) 2010 by Peter Penz <[email protected]> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "additionalinfoaccessor.h"
+
+#include "dolphinmodel.h"
+#include <kglobal.h>
+#include <klocale.h>
+
+class AdditionalInfoAccessorSingleton
+{
+public:
+ AdditionalInfoAccessor instance;
+};
+K_GLOBAL_STATIC(AdditionalInfoAccessorSingleton, s_additionalInfoManager)
+
+AdditionalInfoAccessor& AdditionalInfoAccessor::instance()
+{
+ return s_additionalInfoManager->instance;
+}
+
+KFileItemDelegate::InformationList AdditionalInfoAccessor::keys() const
+{
+ return m_informations;
+}
+
+KFileItemDelegate::Information AdditionalInfoAccessor::keyForColumn(int columnIndex) const
+{
+ KFileItemDelegate::Information info = KFileItemDelegate::NoInformation;
+
+ switch (columnIndex) {
+ case DolphinModel::Size: info = KFileItemDelegate::Size; break;
+ case DolphinModel::ModifiedTime: info = KFileItemDelegate::ModificationTime; break;
+ case DolphinModel::Permissions: info = KFileItemDelegate::Permissions; break;
+ case DolphinModel::Owner: info = KFileItemDelegate::Owner; break;
+ case DolphinModel::Group: info = KFileItemDelegate::OwnerAndGroup; break;
+ case DolphinModel::Type: info = KFileItemDelegate::FriendlyMimeType; break;
+ case DolphinModel::LinkDest: info = KFileItemDelegate::LinkDest; break;
+ case DolphinModel::LocalPathOrUrl: info = KFileItemDelegate::LocalPathOrUrl; break;
+ default: break;
+ }
+
+ return info;
+}
+
+QString AdditionalInfoAccessor::actionCollectionName(KFileItemDelegate::Information info,
+ ActionCollectionType type) const
+{
+ QString name;
+ switch (type) {
+ case SortByType:
+ name = QLatin1String("sort_by_") + QLatin1String(m_map[info]->actionCollectionName);
+ break;
+
+ case AdditionalInfoType:
+ name = QLatin1String("show_") + QLatin1String(m_map[info]->actionCollectionName);
+ break;
+ }
+
+ return name;
+}
+
+QString AdditionalInfoAccessor::translation(KFileItemDelegate::Information info) const
+{
+ return i18nc(m_map[info]->context, m_map[info]->translation);
+}
+
+DolphinView::Sorting AdditionalInfoAccessor::sorting(KFileItemDelegate::Information info) const
+{
+ return m_map[info]->sorting;
+}
+
+int AdditionalInfoAccessor::bitValue(KFileItemDelegate::Information info) const
+{
+ return m_map[info]->bitValue;
+}
+
+AdditionalInfoAccessor::AdditionalInfoAccessor() :
+ m_informations(),
+ m_map()
+{
+ static const AdditionalInfoAccessor::AdditionalInfo additionalInfos[] = {
+ { "size", I18N_NOOP2_NOSTRIP("@label", "Size"), DolphinView::SortBySize, 1 },
+ { "date", I18N_NOOP2_NOSTRIP("@label", "Date"), DolphinView::SortByDate, 2 },
+ { "permissions", I18N_NOOP2_NOSTRIP("@label", "Permissions"), DolphinView::SortByPermissions, 4 },
+ { "owner", I18N_NOOP2_NOSTRIP("@label", "Owner"), DolphinView::SortByOwner, 8 },
+ { "group", I18N_NOOP2_NOSTRIP("@label", "Group"), DolphinView::SortByGroup, 16 },
+ { "type", I18N_NOOP2_NOSTRIP("@label", "Type"), DolphinView::SortByType, 32 },
+ { "destination", I18N_NOOP2_NOSTRIP("@label", "Link Destination"), DolphinView::SortByDestination, 64 },
+ { "path", I18N_NOOP2_NOSTRIP("@label", "Path"), DolphinView::SortByPath, 128 }
+ };
+
+ m_map.insert(KFileItemDelegate::Size, &additionalInfos[0]);
+ m_map.insert(KFileItemDelegate::ModificationTime, &additionalInfos[1]);
+ m_map.insert(KFileItemDelegate::Permissions, &additionalInfos[2]);
+ m_map.insert(KFileItemDelegate::Owner, &additionalInfos[3]);
+ m_map.insert(KFileItemDelegate::OwnerAndGroup, &additionalInfos[4]);
+ m_map.insert(KFileItemDelegate::FriendlyMimeType, &additionalInfos[5]);
+ m_map.insert(KFileItemDelegate::LinkDest, &additionalInfos[6]);
+ m_map.insert(KFileItemDelegate::LocalPathOrUrl, &additionalInfos[7]);
+
+ // The m_informations list defines all available keys and the sort order
+ // (don't use m_informations = m_map.keys(), as the order is undefined).
+ m_informations.append(KFileItemDelegate::Size);
+ m_informations.append(KFileItemDelegate::ModificationTime);
+ m_informations.append(KFileItemDelegate::Permissions);
+ m_informations.append(KFileItemDelegate::Owner);
+ m_informations.append(KFileItemDelegate::OwnerAndGroup);
+ m_informations.append(KFileItemDelegate::FriendlyMimeType);
+ m_informations.append(KFileItemDelegate::LinkDest);
+ m_informations.append(KFileItemDelegate::LocalPathOrUrl);
+}
+
+AdditionalInfoAccessor::~AdditionalInfoAccessor()
+{
+}
diff --git a/src/views/additionalinfoaccessor.h b/src/views/additionalinfoaccessor.h
new file mode 100644
index 000000000..0a3d51459
--- /dev/null
+++ b/src/views/additionalinfoaccessor.h
@@ -0,0 +1,100 @@
+/***************************************************************************
+ * Copyright (C) 2010 by Peter Penz <[email protected]> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef ADDITIONALINFOACCESSOR_H
+#define ADDITIONALINFOACCESSOR_H
+
+#include <libdolphin_export.h>
+#include <kfileitemdelegate.h>
+#include <views/dolphinview.h>
+
+#include <QList>
+#include <QMap>
+
+/**
+ * @brief Allows to access the information that is available by KFileItemDelegate::Information.
+ *
+ * The information that is available by KFileItemDelegate::Information will be shown
+ * in Dolphin the following way:
+ * - As additional columns in the details view
+ * - As additional lines in the icons view
+ * - As menu entries in the "Sort By" and "Additional Information" groups
+ * - As popup menu entries in the details view header popup
+ * - As checkable entries in the View Properties dialog
+ *
+ * The AdditionalInfoAccessor provides a central place to get all available keys,
+ * the corresponding translations, action names, etc., so that modifications or
+ * extensions in KFileItemDelegate only require adjustments in the implementation
+ * of this class.
+ */
+class LIBDOLPHINPRIVATE_EXPORT AdditionalInfoAccessor
+{
+public:
+ enum ActionCollectionType {
+ /// Action collection from "View -> Sort By"
+ SortByType,
+ /// Action collection from "View -> Additional Information"
+ AdditionalInfoType
+ };
+
+ static AdditionalInfoAccessor& instance();
+
+ /**
+ * @return List of all available information entries of KFileItemDelegate.
+ * All entries of this list are keys for accessing the corresponding
+ * data (see actionCollectionName(), translation(), bitValue()).
+ */
+ KFileItemDelegate::InformationList keys() const;
+
+ /**
+ * @return Key for the model column with the index \p columnIndex.
+ */
+ KFileItemDelegate::Information keyForColumn(int columnIndex) const;
+
+ QString actionCollectionName(KFileItemDelegate::Information info, ActionCollectionType type) const;
+
+ QString translation(KFileItemDelegate::Information info) const;
+
+ DolphinView::Sorting sorting(KFileItemDelegate::Information info) const;
+
+ /**
+ * @return Bitvalue for \p info that is stored in a ViewProperties instance.
+ */
+ int bitValue(KFileItemDelegate::Information info) const;
+
+protected:
+ AdditionalInfoAccessor();
+ virtual ~AdditionalInfoAccessor();
+ friend class AdditionalInfoAccessorSingleton;
+
+private:
+ struct AdditionalInfo {
+ const char* const actionCollectionName;
+ const char* const context;
+ const char* const translation;
+ const DolphinView::Sorting sorting;
+ const int bitValue;
+ };
+
+ KFileItemDelegate::InformationList m_informations;
+ QMap<KFileItemDelegate::Information, const AdditionalInfo*> m_map;
+};
+
+#endif
+
diff --git a/src/views/dolphindirlister.cpp b/src/views/dolphindirlister.cpp
new file mode 100644
index 000000000..2eac5522d
--- /dev/null
+++ b/src/views/dolphindirlister.cpp
@@ -0,0 +1,48 @@
+/***************************************************************************
+ * Copyright (C) 2006-2010 by Peter Penz <[email protected]> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "dolphindirlister.h"
+#include "klocale.h"
+#include <kio/jobclasses.h>
+
+DolphinDirLister::DolphinDirLister() :
+ KDirLister()
+{
+ setAutoErrorHandlingEnabled(false, 0);
+}
+
+DolphinDirLister::~DolphinDirLister()
+{
+}
+
+void DolphinDirLister::handleError(KIO::Job* job)
+{
+ if (job->error() == KIO::ERR_IS_FILE) {
+ emit urlIsFileError(url());
+ } else {
+ const QString errorString = job->errorString();
+ if (errorString.isEmpty()) {
+ emit errorMessage(i18nc("@info:status", "Unknown error."));
+ } else {
+ emit errorMessage(errorString);
+ }
+ }
+}
+
+#include "dolphindirlister.moc"
diff --git a/src/views/dolphindirlister.h b/src/views/dolphindirlister.h
new file mode 100644
index 000000000..629c335d3
--- /dev/null
+++ b/src/views/dolphindirlister.h
@@ -0,0 +1,48 @@
+/***************************************************************************
+ * Copyright (C) 2006-2009 by Peter Penz <[email protected]> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef DOLPHINDIRLISTER_H
+#define DOLPHINDIRLISTER_H
+
+#include <kdirlister.h>
+
+/**
+ * @brief Extends the class KDirLister by emitting a signal when an
+ * error occurred instead of showing an error dialog.
+ */
+class DolphinDirLister : public KDirLister
+{
+ Q_OBJECT
+
+public:
+ DolphinDirLister();
+ virtual ~DolphinDirLister();
+
+signals:
+ /** Is emitted whenever an error has occurred. */
+ void errorMessage(const QString& msg);
+
+ /** Is emitted when the URL of the directory lister represents a file. */
+ void urlIsFileError(const KUrl& url);
+
+protected:
+ virtual void handleError(KIO::Job* job);
+};
+
+#endif
diff --git a/src/views/dolphinfileitemdelegate.cpp b/src/views/dolphinfileitemdelegate.cpp
index 17447d8cb..6b706c88b 100644
--- a/src/views/dolphinfileitemdelegate.cpp
+++ b/src/views/dolphinfileitemdelegate.cpp
@@ -19,7 +19,7 @@
#include "dolphinfileitemdelegate.h"
-#include <dolphinmodel.h>
+#include "dolphinmodel.h"
#include <kfileitem.h>
#include <kicon.h>
#include <kiconloader.h>
diff --git a/src/views/dolphinfileitemdelegate.h b/src/views/dolphinfileitemdelegate.h
index 405f24916..0777571f7 100644
--- a/src/views/dolphinfileitemdelegate.h
+++ b/src/views/dolphinfileitemdelegate.h
@@ -20,8 +20,8 @@
#ifndef DOLPHINFILEITEMDELEGATE_H
#define DOLPHINFILEITEMDELEGATE_H
-#include <dolphinmodel.h>
#include <kfileitemdelegate.h>
+#include <views/dolphinmodel.h>
class QAbstractProxyModel;
diff --git a/src/views/dolphinmodel.cpp b/src/views/dolphinmodel.cpp
new file mode 100644
index 000000000..137274e0d
--- /dev/null
+++ b/src/views/dolphinmodel.cpp
@@ -0,0 +1,445 @@
+/**
+ * This file is part of the KDE project
+ * Copyright (C) 2007 Rafael Fernández López <[email protected]>
+ *
+ * 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 "dolphinmodel.h"
+
+#include "dolphinsortfilterproxymodel.h"
+
+#include "kcategorizedview.h"
+
+#include <kdatetime.h>
+#include <kdirmodel.h>
+#include <kfileitem.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kurl.h>
+#include <kuser.h>
+#include <kmimetype.h>
+#include <kstandarddirs.h>
+
+#include <QList>
+#include <QSortFilterProxyModel>
+#include <QPainter>
+#include <QPersistentModelIndex>
+#include <QDir>
+#include <QFileInfo>
+
+const char* const DolphinModel::m_others = I18N_NOOP2("@title:group Name", "Others");
+
+DolphinModel::DolphinModel(QObject* parent) :
+ KDirModel(parent),
+ m_hasVersionData(false),
+ m_revisionHash()
+{
+ setJobTransfersVisible(true);
+}
+
+DolphinModel::~DolphinModel()
+{
+}
+
+bool DolphinModel::setData(const QModelIndex& index, const QVariant& value, int role)
+{
+ if ((index.column() == DolphinModel::Version) && (role == Qt::DecorationRole)) {
+ // TODO: remove data again when items are deleted...
+
+ const QPersistentModelIndex key = index;
+ const KVersionControlPlugin::VersionState state = static_cast<KVersionControlPlugin::VersionState>(value.toInt());
+ if (m_revisionHash.value(key, KVersionControlPlugin::UnversionedVersion) != state) {
+ if (!m_hasVersionData) {
+ connect(this, SIGNAL(rowsRemoved (const QModelIndex&, int, int)),
+ this, SLOT(slotRowsRemoved(const QModelIndex&, int, int)));
+ m_hasVersionData = true;
+ }
+
+ m_revisionHash.insert(key, state);
+ emit dataChanged(index, index);
+ return true;
+ }
+ }
+
+ return KDirModel::setData(index, value, role);
+}
+
+QVariant DolphinModel::data(const QModelIndex& index, int role) const
+{
+ switch (role) {
+ case KCategorizedSortFilterProxyModel::CategoryDisplayRole:
+ return displayRoleData(index);
+
+ case KCategorizedSortFilterProxyModel::CategorySortRole:
+ return sortRoleData(index);
+
+ case Qt::DecorationRole:
+ if (index.column() == DolphinModel::Version) {
+ return m_revisionHash.value(index, KVersionControlPlugin::UnversionedVersion);
+ }
+ break;
+
+ case Qt::DisplayRole:
+ switch (index.column()) {
+ case DolphinModel::LinkDest: {
+ const KDirModel *dirModel = qobject_cast<const KDirModel*>(index.model());
+ const KFileItem item = dirModel->itemForIndex(index);
+ return item.linkDest();
+ }
+
+ case DolphinModel::LocalPathOrUrl:
+ const KDirModel *dirModel = qobject_cast<const KDirModel*>(index.model());
+ const KFileItem item = dirModel->itemForIndex(index);
+ return item.localPath();
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return KDirModel::data(index, role);
+}
+
+QVariant DolphinModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if ((orientation == Qt::Horizontal) && (role == Qt::DisplayRole)) {
+ switch (section) {
+ case DolphinModel::LinkDest:
+ return i18nc("@title::column", "Link Destination");
+ case DolphinModel::LocalPathOrUrl:
+ return i18nc("@title::column", "Path");
+ default:
+ return KDirModel::headerData(section, orientation, role);
+ }
+ }
+ return QVariant();
+}
+
+int DolphinModel::columnCount(const QModelIndex& parent) const
+{
+ return KDirModel::columnCount(parent) + (ExtraColumnCount - ColumnCount);
+}
+
+void DolphinModel::clearVersionData()
+{
+ m_revisionHash.clear();
+ m_hasVersionData = false;
+}
+
+bool DolphinModel::hasVersionData() const
+{
+ return m_hasVersionData;
+}
+
+void DolphinModel::slotRowsRemoved(const QModelIndex& parent, int start, int end)
+{
+ if (m_hasVersionData) {
+ const int column = parent.column();
+ for (int row = start; row <= end; ++row) {
+ m_revisionHash.remove(parent.child(row, column));
+ }
+ }
+}
+
+QVariant DolphinModel::displayRoleData(const QModelIndex& index) const
+{
+ QString retString;
+
+ if (!index.isValid()) {
+ return retString;
+ }
+
+ const KDirModel *dirModel = qobject_cast<const KDirModel*>(index.model());
+ KFileItem item = dirModel->itemForIndex(index);
+
+ switch (index.column()) {
+ case KDirModel::Name: {
+ // KDirModel checks columns to know to which role are
+ // we talking about
+ const QModelIndex nameIndex = index.model()->index(index.row(), KDirModel::Name, index.parent());
+ if (!nameIndex.isValid()) {
+ return retString;
+ }
+ const QVariant data = nameIndex.model()->data(nameIndex, Qt::DisplayRole);
+ const QString name = data.toString();
+ if (!name.isEmpty()) {
+ if (!item.isHidden() && name.at(0).isLetter())
+ retString = name.at(0).toUpper();
+ else if (item.isHidden()) {
+ if (name.at(0) == '.') {
+ if (name.size() > 1 && name.at(1).isLetter()) {
+ retString = name.at(1).toUpper();
+ } else {
+ retString = i18nc("@title:group Name", m_others);
+ }
+ } else {
+ retString = name.at(0).toUpper();
+ }
+ } else {
+ bool validCategory = false;
+
+ const QString str(name.toUpper());
+ const QChar* currA = str.unicode();
+ while (!currA->isNull() && !validCategory) {
+ if (currA->isLetter()) {
+ validCategory = true;
+ } else if (currA->isDigit()) {
+ return i18nc("@title:group Name", m_others);
+ } else {
+ ++currA;
+ }
+ }
+
+ retString = validCategory ? *currA : i18nc("@title:group Name", m_others);
+ }
+ }
+ break;
+ }
+
+ case KDirModel::Size: {
+ const KIO::filesize_t fileSize = !item.isNull() ? item.size() : ~0U;
+ if (!item.isNull() && item.isDir()) {
+ retString = i18nc("@title:group Size", "Folders");
+ } else if (fileSize < 5242880) {
+ retString = i18nc("@title:group Size", "Small");
+ } else if (fileSize < 10485760) {
+ retString = i18nc("@title:group Size", "Medium");
+ } else {
+ retString = i18nc("@title:group Size", "Big");
+ }
+ break;
+ }
+
+ case KDirModel::ModifiedTime: {
+ KDateTime modifiedTime = item.time(KFileItem::ModificationTime);
+ modifiedTime = modifiedTime.toLocalZone();
+
+ const QDate currentDate = KDateTime::currentLocalDateTime().date();
+ const QDate modifiedDate = modifiedTime.date();
+
+ const int daysDistance = modifiedDate.daysTo(currentDate);
+
+ int yearForCurrentWeek = 0;
+ int currentWeek = currentDate.weekNumber(&yearForCurrentWeek);
+ if (yearForCurrentWeek == currentDate.year() + 1) {
+ currentWeek = 53;
+ }
+
+ int yearForModifiedWeek = 0;
+ int modifiedWeek = modifiedDate.weekNumber(&yearForModifiedWeek);
+ if (yearForModifiedWeek == modifiedDate.year() + 1) {
+ modifiedWeek = 53;
+ }
+
+ if (currentDate.year() == modifiedDate.year() && currentDate.month() == modifiedDate.month()) {
+ if (modifiedWeek > currentWeek) {
+ // use case: modified date = 2010-01-01, current date = 2010-01-22
+ // modified week = 53, current week = 3
+ modifiedWeek = 0;
+ }
+ switch (currentWeek - modifiedWeek) {
+ case 0:
+ switch (daysDistance) {
+ case 0: retString = i18nc("@title:group Date", "Today"); break;
+ case 1: retString = i18nc("@title:group Date", "Yesterday"); break;
+ default: retString = modifiedTime.toString(i18nc("@title:group The week day name: %A", "%A"));
+ }
+ break;
+ case 1:
+ retString = i18nc("@title:group Date", "Last Week");
+ break;
+ case 2:
+ retString = i18nc("@title:group Date", "Two Weeks Ago");
+ break;
+ case 3:
+ retString = i18nc("@title:group Date", "Three Weeks Ago");
+ break;
+ case 4:
+ case 5:
+ retString = i18nc("@title:group Date", "Earlier this Month");
+ break;
+ default:
+ Q_ASSERT(false);
+ }
+ } else {
+ const QDate lastMonthDate = currentDate.addMonths(-1);
+ if (lastMonthDate.year() == modifiedDate.year() && lastMonthDate.month() == modifiedDate.month()) {
+ if (daysDistance == 1) {
+ retString = modifiedTime.toString(i18nc("@title:group Date: %B is full month name in current locale, and %Y is full year number", "Yesterday (%B, %Y)"));
+ } else if (daysDistance <= 7) {
+ retString = modifiedTime.toString(i18nc("@title:group The week day name: %A, %B is full month name in current locale, and %Y is full year number", "%A (%B, %Y)"));
+ } else if (daysDistance <= 7 * 2) {
+ retString = modifiedTime.toString(i18nc("@title:group Date: %B is full month name in current locale, and %Y is full year number", "Last Week (%B, %Y)"));
+ } else if (daysDistance <= 7 * 3) {
+ retString = modifiedTime.toString(i18nc("@title:group Date: %B is full month name in current locale, and %Y is full year number", "Two Weeks Ago (%B, %Y)"));
+ } else if (daysDistance <= 7 * 4) {
+ retString = modifiedTime.toString(i18nc("@title:group Date: %B is full month name in current locale, and %Y is full year number", "Three Weeks Ago (%B, %Y)"));
+ } else {
+ retString = modifiedTime.toString(i18nc("@title:group Date: %B is full month name in current locale, and %Y is full year number", "Earlier on %B, %Y"));
+ }
+ } else {
+ retString = modifiedTime.toString(i18nc("@title:group The month and year: %B is full month name in current locale, and %Y is full year number", "%B, %Y"));
+ }
+ }
+ break;
+ }
+
+ case KDirModel::Permissions: {
+ QString user;
+ QString group;
+ QString others;
+
+ QFileInfo info(item.url().pathOrUrl());
+
+ // set user string
+ if (info.permission(QFile::ReadUser)) {
+ user = i18nc("@item:intext Access permission, concatenated", "Read, ");
+ }
+ if (info.permission(QFile::WriteUser)) {
+ user += i18nc("@item:intext Access permission, concatenated", "Write, ");
+ }
+ if (info.permission(QFile::ExeUser)) {
+ user += i18nc("@item:intext Access permission, concatenated", "Execute, ");
+ }
+ user = user.isEmpty() ? i18nc("@item:intext Access permission, concatenated", "Forbidden") : user.mid(0, user.count() - 2);
+
+ // set group string
+ if (info.permission(QFile::ReadGroup)) {
+ group = i18nc("@item:intext Access permission, concatenated", "Read, ");
+ }
+ if (info.permission(QFile::WriteGroup)) {
+ group += i18nc("@item:intext Access permission, concatenated", "Write, ");
+ }
+ if (info.permission(QFile::ExeGroup)) {
+ group += i18nc("@item:intext Access permission, concatenated", "Execute, ");
+ }
+ group = group.isEmpty() ? i18nc("@item:intext Access permission, concatenated", "Forbidden") : group.mid(0, group.count() - 2);
+
+ // set permission string
+ if (info.permission(QFile::ReadOther)) {
+ others = i18nc("@item:intext Access permission, concatenated", "Read, ");
+ }
+ if (info.permission(QFile::WriteOther)) {
+ others += i18nc("@item:intext Access permission, concatenated", "Write, ");
+ }
+ if (info.permission(QFile::ExeOther)) {
+ others += i18nc("@item:intext Access permission, concatenated", "Execute, ");
+ }
+ others = others.isEmpty() ? i18nc("@item:intext Access permission, concatenated", "Forbidden") : others.mid(0, others.count() - 2);
+
+ retString = i18nc("@title:group Files and folders by permissions", "(User: %1) (Group: %2) (Others: %3)", user, group, others);
+ break;
+ }
+
+ case KDirModel::Owner:
+ retString = item.user();
+ break;
+
+ case KDirModel::Group:
+ retString = item.group();
+ break;
+
+ case KDirModel::Type:
+ retString = item.mimeComment();
+ break;
+
+ case DolphinModel::Version:
+ retString = "test";
+ break;
+ }
+
+ return retString;
+}
+
+QVariant DolphinModel::sortRoleData(const QModelIndex& index) const
+{
+ QVariant retVariant;
+
+ if (!index.isValid()) {
+ return retVariant;
+ }
+
+ const KDirModel *dirModel = qobject_cast<const KDirModel*>(index.model());
+ KFileItem item = dirModel->itemForIndex(index);
+
+ switch (index.column()) {
+ case KDirModel::Name: {
+ retVariant = data(index, KCategorizedSortFilterProxyModel::CategoryDisplayRole);
+ if (retVariant == i18nc("@title:group Name", m_others)) {
+ // assure that the "Others" group is always the last categorization
+ retVariant = QString('Z').append(QChar::ReplacementCharacter);
+ }
+ break;
+ }
+
+ case KDirModel::Size: {
+ const KIO::filesize_t fileSize = !item.isNull() ? item.size() : ~0U;
+ if (item.isDir()) {
+ retVariant = 0;
+ } else if (fileSize < 5242880) {
+ retVariant = 1;
+ } else if (fileSize < 10485760) {
+ retVariant = 2;
+ } else {
+ retVariant = 3;
+ }
+ break;
+ }
+
+ case KDirModel::ModifiedTime: {
+ KDateTime modifiedTime = item.time(KFileItem::ModificationTime);
+ modifiedTime = modifiedTime.toLocalZone();
+
+ const QDate currentDate = KDateTime::currentLocalDateTime().date();
+ const QDate modifiedDate = modifiedTime.date();
+
+ retVariant = -modifiedDate.daysTo(currentDate);
+ break;
+ }
+
+ case KDirModel::Permissions: {
+ QFileInfo info(item.url().pathOrUrl());
+
+ retVariant = -KDirSortFilterProxyModel::pointsForPermissions(info);
+ break;
+ }
+
+ case KDirModel::Owner:
+ retVariant = item.user();
+ break;
+
+ case KDirModel::Group:
+ retVariant = item.group();
+ break;
+
+ case KDirModel::Type:
+ if (item.isDir()) {
+ // when sorting we want folders to be placed first
+ retVariant = QString(); // krazy:exclude=nullstrassign
+ } else {
+ retVariant = item.mimeComment();
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return retVariant;
+}
diff --git a/src/views/dolphinmodel.h b/src/views/dolphinmodel.h
new file mode 100644
index 000000000..6f1b00c75
--- /dev/null
+++ b/src/views/dolphinmodel.h
@@ -0,0 +1,68 @@
+/*
+ * This file is part of the KDE project
+ * Copyright (C) 2007 Rafael Fernández López <[email protected]>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef DOLPHINMODEL_H
+#define DOLPHINMODEL_H
+
+#include <kdirmodel.h>
+#include <kversioncontrolplugin.h>
+#include <libdolphin_export.h>
+
+#include <QHash>
+#include <QPersistentModelIndex>
+
+class LIBDOLPHINPRIVATE_EXPORT DolphinModel : public KDirModel
+{
+ Q_OBJECT
+
+public:
+ enum AdditionalColumns {
+ Version = KDirModel::ColumnCount,
+ LinkDest,
+ LocalPathOrUrl,
+ ExtraColumnCount // Mandatory last entry
+ };
+
+ DolphinModel(QObject* parent = 0);
+ virtual ~DolphinModel();
+
+ virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole);
+ virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
+ virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
+ virtual int columnCount(const QModelIndex& parent = QModelIndex()) const;
+
+ void clearVersionData();
+ bool hasVersionData() const;
+
+private slots:
+ void slotRowsRemoved(const QModelIndex& parent, int start, int end);
+
+private:
+ QVariant displayRoleData(const QModelIndex& index) const;
+ QVariant sortRoleData(const QModelIndex& index) const;
+
+private:
+ bool m_hasVersionData;
+ QHash<QPersistentModelIndex, KVersionControlPlugin::VersionState> m_revisionHash;
+
+ static const char* const m_others;
+};
+
+#endif // DOLPHINMODEL_H
diff --git a/src/views/dolphinnewmenuobserver.cpp b/src/views/dolphinnewmenuobserver.cpp
new file mode 100644
index 000000000..def510c53
--- /dev/null
+++ b/src/views/dolphinnewmenuobserver.cpp
@@ -0,0 +1,62 @@
+/***************************************************************************
+ * Copyright (C) 2009 by Peter Penz <[email protected]> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "dolphinnewmenuobserver.h"
+
+#include <kglobal.h>
+#include <knewmenu.h>
+
+class DolphinNewMenuObserverSingleton
+{
+public:
+ DolphinNewMenuObserver instance;
+};
+K_GLOBAL_STATIC(DolphinNewMenuObserverSingleton, s_dolphinNewMenuObserver)
+
+DolphinNewMenuObserver& DolphinNewMenuObserver::instance()
+{
+ return s_dolphinNewMenuObserver->instance;
+}
+
+void DolphinNewMenuObserver::attach(const KNewFileMenu* menu)
+{
+ connect(menu, SIGNAL(fileCreated(const KUrl&)),
+ this, SIGNAL(itemCreated(const KUrl&)));
+ connect(menu, SIGNAL(directoryCreated(const KUrl&)),
+ this, SIGNAL(itemCreated(const KUrl&)));
+}
+
+void DolphinNewMenuObserver::detach(const KNewFileMenu* menu)
+{
+ disconnect(menu, SIGNAL(fileCreated(const KUrl&)),
+ this, SIGNAL(itemCreated(const KUrl&)));
+ disconnect(menu, SIGNAL(directoryCreated(const KUrl&)),
+ this, SIGNAL(itemCreated(const KUrl&)));
+}
+
+DolphinNewMenuObserver::DolphinNewMenuObserver() :
+ QObject(0)
+{
+}
+
+DolphinNewMenuObserver::~DolphinNewMenuObserver()
+{
+}
+
+#include "dolphinnewmenuobserver.moc"
diff --git a/src/views/dolphinnewmenuobserver.h b/src/views/dolphinnewmenuobserver.h
new file mode 100644
index 000000000..dc9010a43
--- /dev/null
+++ b/src/views/dolphinnewmenuobserver.h
@@ -0,0 +1,56 @@
+/***************************************************************************
+ * Copyright (C) 2009 by Peter Penz <[email protected]> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef DOLPHINNEWMENUOBSERVER_H
+#define DOLPHINNEWMENUOBSERVER_H
+
+#include <QObject>
+
+#include "libdolphin_export.h"
+
+class KNewFileMenu;
+class KUrl;
+
+/**
+ * @brief Allows to observe new file items that have been created
+ * by a DolphinNewMenu instance.
+ *
+ * As soon as a DolphinNewMenu instance created a new item,
+ * the observer will emit the signal itemCreated().
+ */
+class LIBDOLPHINPRIVATE_EXPORT DolphinNewMenuObserver : public QObject
+{
+ Q_OBJECT
+
+public:
+ static DolphinNewMenuObserver& instance();
+ void attach(const KNewFileMenu* menu);
+ void detach(const KNewFileMenu* menu);
+
+signals:
+ void itemCreated(const KUrl& url);
+
+private:
+ DolphinNewMenuObserver();
+ virtual ~DolphinNewMenuObserver();
+
+ friend class DolphinNewMenuObserverSingleton;
+};
+
+#endif
diff --git a/src/views/dolphinremoteencoding.cpp b/src/views/dolphinremoteencoding.cpp
new file mode 100644
index 000000000..397eaccc0
--- /dev/null
+++ b/src/views/dolphinremoteencoding.cpp
@@ -0,0 +1,241 @@
+/***************************************************************************
+ * Copyright (C) 2009 by Rahman Duran <[email protected]> *
+ * *
+ * 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 *
+ ***************************************************************************/
+
+ /*
+ * This code is largely based on the kremoteencodingplugin
+ * Copyright (c) 2003 Thiago Macieira <[email protected]>
+ * Distributed under the same terms.
+ */
+
+#include "dolphinremoteencoding.h"
+#include "dolphinviewactionhandler.h"
+
+#include <kdebug.h>
+#include <kactionmenu.h>
+#include <kactioncollection.h>
+#include <kicon.h>
+#include <klocale.h>
+#include <kglobal.h>
+#include <kmimetype.h>
+#include <kconfig.h>
+#include <kcharsets.h>
+#include <kmenu.h>
+#include <kprotocolinfo.h>
+#include <kprotocolmanager.h>
+#include <kio/slaveconfig.h>
+#include <kio/scheduler.h>
+#include <kconfiggroup.h>
+
+#define DATA_KEY QLatin1String("Charset")
+
+DolphinRemoteEncoding::DolphinRemoteEncoding(QObject* parent, DolphinViewActionHandler* actionHandler)
+ :QObject(parent),
+ m_actionHandler(actionHandler),
+ m_loaded(false),
+ m_idDefault(0)
+{
+ m_menu = new KActionMenu(KIcon("character-set"), i18n("Select Remote Charset"), this);
+ m_actionHandler->actionCollection()->addAction("change_remote_encoding", m_menu);
+ connect(m_menu->menu(), SIGNAL(aboutToShow()),
+ this, SLOT(slotAboutToShow()));
+
+ m_menu->setEnabled(false);
+ m_menu->setDelayed(false);
+}
+
+DolphinRemoteEncoding::~DolphinRemoteEncoding()
+{
+}
+
+void DolphinRemoteEncoding::slotReload()
+{
+ loadSettings();
+}
+
+void DolphinRemoteEncoding::loadSettings()
+{
+ m_loaded = true;
+ m_encodingDescriptions = KGlobal::charsets()->descriptiveEncodingNames();
+
+ fillMenu();
+}
+
+void DolphinRemoteEncoding::slotAboutToOpenUrl()
+{
+ KUrl oldURL = m_currentURL;
+ m_currentURL = m_actionHandler->currentView()->url();
+
+ if (m_currentURL.protocol() != oldURL.protocol()) {
+ // This plugin works on ftp, fish, etc.
+ // everything whose type is T_FILESYSTEM except for local files
+ if (!m_currentURL.isLocalFile() &&
+ KProtocolManager::outputType(m_currentURL) == KProtocolInfo::T_FILESYSTEM) {
+
+ m_menu->setEnabled(true);
+ loadSettings();
+ } else {
+ m_menu->setEnabled(false);
+ }
+ return;
+ }
+
+ if (m_currentURL.host() != oldURL.host()) {
+ updateMenu();
+ }
+}
+
+void DolphinRemoteEncoding::fillMenu()
+{
+ KMenu* menu = m_menu->menu();
+ menu->clear();
+
+
+ for (int i = 0; i < m_encodingDescriptions.size();i++) {
+ QAction* action = new QAction(m_encodingDescriptions.at(i), this);
+ action->setCheckable(true);
+ action->setData(i);
+ menu->addAction(action);
+ }
+ menu->addSeparator();
+
+ menu->addAction(i18n("Reload"), this, SLOT(slotReload()), 0);
+ menu->addAction(i18n("Default"), this, SLOT(slotDefault()), 0)->setCheckable(true);
+ m_idDefault = m_encodingDescriptions.size() + 2;
+
+ connect(menu, SIGNAL(triggered(QAction*)), this, SLOT(slotItemSelected(QAction*)));
+}
+
+void DolphinRemoteEncoding::updateMenu()
+{
+ if (!m_loaded) {
+ loadSettings();
+ }
+
+ // uncheck everything
+ for (int i = 0; i < m_menu->menu()->actions().count(); i++) {
+ m_menu->menu()->actions().at(i)->setChecked(false);
+ }
+
+ QString charset = KIO::SlaveConfig::self()->configData(m_currentURL.protocol(),
+ m_currentURL.host(), DATA_KEY);
+
+ if (!charset.isEmpty()) {
+ int id = 0;
+ bool isFound = false;
+ for (int i = 0; i < m_encodingDescriptions.size(); i++) {
+ if (m_encodingDescriptions.at(i).contains(charset)) {
+ isFound = true;
+ id = i;
+ break;
+ }
+ }
+
+ kDebug() << "URL=" << m_currentURL << " charset=" << charset;
+
+ if (!isFound) {
+ kWarning() << "could not find entry for charset=" << charset ;
+ } else {
+ m_menu->menu()->actions().at(id)->setChecked(true);
+ }
+ } else {
+ m_menu->menu()->actions().at(m_idDefault)->setChecked(true);
+ }
+
+}
+
+void DolphinRemoteEncoding::slotAboutToShow()
+{
+ if (!m_loaded) {
+ loadSettings();
+ }
+ updateMenu();
+}
+
+void DolphinRemoteEncoding::slotItemSelected(QAction* action)
+{
+ if (action != 0) {
+ int id = action->data().toInt();
+
+ KConfig config(("kio_" + m_currentURL.protocol() + "rc").toLatin1());
+ QString host = m_currentURL.host();
+ if (m_menu->menu()->actions().at(id)->isChecked()) {
+ QString charset = KGlobal::charsets()->encodingForName(m_encodingDescriptions.at(id));
+ KConfigGroup cg(&config, host);
+ cg.writeEntry(DATA_KEY, charset);
+ config.sync();
+
+ // Update the io-slaves...
+ updateView();
+ }
+ }
+}
+
+void DolphinRemoteEncoding::slotDefault()
+{
+ // We have no choice but delete all higher domain level
+ // settings here since it affects what will be matched.
+ KConfig config(("kio_" + m_currentURL.protocol() + "rc").toLatin1());
+
+ QStringList partList = m_currentURL.host().split('.', QString::SkipEmptyParts);
+ if (!partList.isEmpty()) {
+ partList.erase(partList.begin());
+
+ QStringList domains;
+ // Remove the exact name match...
+ domains << m_currentURL.host();
+
+ while (partList.count()) {
+ if (partList.count() == 2) {
+ if (partList[0].length() <= 2 && partList[1].length() == 2) {
+ break;
+ }
+ }
+
+ if (partList.count() == 1) {
+ break;
+ }
+
+ domains << partList.join(".");
+ partList.erase(partList.begin());
+ }
+
+ for (QStringList::const_iterator it = domains.constBegin(); it != domains.constEnd();++it) {
+ kDebug() << "Domain to remove: " << *it;
+ if (config.hasGroup(*it)) {
+ config.deleteGroup(*it);
+ } else if (config.group("").hasKey(*it)) {
+ config.group("").deleteEntry(*it); //don't know what group name is supposed to be XXX
+ }
+ }
+ }
+ config.sync();
+
+ // Update the io-slaves.
+ updateView();
+}
+
+void DolphinRemoteEncoding::updateView()
+{
+ KIO::Scheduler::emitReparseSlaveConfiguration();
+ // Reload the page with the new charset
+ m_actionHandler->currentView()->setUrl(m_currentURL);
+ m_actionHandler->currentView()->reload();
+}
+
+#include "dolphinremoteencoding.moc"
diff --git a/src/views/dolphinremoteencoding.h b/src/views/dolphinremoteencoding.h
new file mode 100644
index 000000000..54499f78b
--- /dev/null
+++ b/src/views/dolphinremoteencoding.h
@@ -0,0 +1,69 @@
+/***************************************************************************
+ * Copyright (C) 2009 by Rahman Duran <[email protected]> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef DOLPHINREMOTEENCODING_H
+#define DOLPHINREMOTEENCODING_H
+
+#include <QStringList>
+#include <QtGui/QAction>
+#include <kurl.h>
+#include "libdolphin_export.h"
+
+
+class KActionMenu;
+class DolphinViewActionHandler;
+
+/**
+ * @brief Allows to chnage character encoding for remote urls like ftp.
+ *
+ * When browsing remote url, its possible to change encoding from Tools Menu.
+ */
+
+class LIBDOLPHINPRIVATE_EXPORT DolphinRemoteEncoding: public QObject
+{
+ Q_OBJECT
+public:
+ DolphinRemoteEncoding(QObject* parent, DolphinViewActionHandler* actionHandler);
+ ~DolphinRemoteEncoding();
+
+public Q_SLOTS:
+ void slotAboutToOpenUrl();
+ void slotItemSelected(QAction* action);
+ void slotReload();
+ void slotDefault();
+
+private Q_SLOTS:
+ void slotAboutToShow();
+
+private:
+ void updateView();
+ void loadSettings();
+ void fillMenu();
+ void updateMenu();
+
+ KActionMenu* m_menu;
+ QStringList m_encodingDescriptions;
+ KUrl m_currentURL;
+ DolphinViewActionHandler* m_actionHandler;
+
+ bool m_loaded;
+ int m_idDefault;
+};
+
+#endif
diff --git a/src/views/dolphinsortfilterproxymodel.cpp b/src/views/dolphinsortfilterproxymodel.cpp
new file mode 100644
index 000000000..70256f156
--- /dev/null
+++ b/src/views/dolphinsortfilterproxymodel.cpp
@@ -0,0 +1,81 @@
+/***************************************************************************
+ * Copyright (C) 2006-2010 by Peter Penz <[email protected]> *
+ * Copyright (C) 2006 by Dominic Battre <[email protected]> *
+ * Copyright (C) 2006 by Martin Pool <[email protected]> *
+ * Copyright (C) 2007 by Rafael Fernández López <[email protected]> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "dolphinsortfilterproxymodel.h"
+
+DolphinSortFilterProxyModel::DolphinSortFilterProxyModel(QObject* parent) :
+ KDirSortFilterProxyModel(parent),
+ m_sorting(DolphinView::SortByName),
+ m_sortOrder(Qt::AscendingOrder)
+{
+}
+
+DolphinSortFilterProxyModel::~DolphinSortFilterProxyModel()
+{
+}
+
+void DolphinSortFilterProxyModel::setSorting(DolphinView::Sorting sorting)
+{
+ m_sorting = sorting;
+ KDirSortFilterProxyModel::sort(static_cast<int>(m_sorting), m_sortOrder);
+}
+
+void DolphinSortFilterProxyModel::setSortOrder(Qt::SortOrder sortOrder)
+{
+ m_sortOrder = sortOrder;
+ KDirSortFilterProxyModel::sort(static_cast<int>(m_sorting), m_sortOrder);
+}
+
+void DolphinSortFilterProxyModel::setSortFoldersFirst(bool foldersFirst)
+{
+ if (foldersFirst != sortFoldersFirst()) {
+ KDirSortFilterProxyModel::setSortFoldersFirst(foldersFirst);
+
+ // We need to make sure that the files and folders are really resorted.
+ // Without the following two lines, QSortFilterProxyModel::sort(int column, Qt::SortOrder order)
+ // would do nothing because neither the column nor the sort order have changed.
+ // TODO: remove this hack if we find a better way to force the ProxyModel to re-sort the data.
+ const Qt::SortOrder tmpSortOrder = (m_sortOrder == Qt::AscendingOrder ? Qt::DescendingOrder : Qt::AscendingOrder);
+ KDirSortFilterProxyModel::sort(static_cast<int>(m_sorting), tmpSortOrder);
+
+ // Now comes the real sorting with the old column and sort order
+ KDirSortFilterProxyModel::sort(static_cast<int>(m_sorting), m_sortOrder);
+ }
+}
+
+void DolphinSortFilterProxyModel::sort(int column, Qt::SortOrder sortOrder)
+{
+ m_sorting = sortingForColumn(column);
+ m_sortOrder = sortOrder;
+
+ emit sortingRoleChanged();
+ KDirSortFilterProxyModel::sort(static_cast<int>(m_sorting), sortOrder);
+}
+
+DolphinView::Sorting DolphinSortFilterProxyModel::sortingForColumn(int column)
+{
+ Q_ASSERT(column >= 0);
+ Q_ASSERT(column <= DolphinView::MaxSortingEnum);
+ return static_cast<DolphinView::Sorting>(column);
+}
+
+#include "dolphinsortfilterproxymodel.moc"
diff --git a/src/views/dolphinsortfilterproxymodel.h b/src/views/dolphinsortfilterproxymodel.h
new file mode 100644
index 000000000..3ae8a059c
--- /dev/null
+++ b/src/views/dolphinsortfilterproxymodel.h
@@ -0,0 +1,85 @@
+/***************************************************************************
+ * Copyright (C) 2006-2010 by Peter Penz <[email protected]> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef DOLPHINSORTFILTERPROXYMODEL_H
+#define DOLPHINSORTFILTERPROXYMODEL_H
+
+#include <views/dolphinview.h>
+#include <kdirsortfilterproxymodel.h>
+#include <libdolphin_export.h>
+
+/**
+ * @brief Acts as proxy model for DolphinModel to sort and filter
+ * KFileItems.
+ *
+ * Per default a natural sorting is done. This means that items like:
+ * - item_10.png
+ * - item_1.png
+ * - item_2.png
+ * are sorted like
+ * - item_1.png
+ * - item_2.png
+ * - item_10.png
+ */
+class LIBDOLPHINPRIVATE_EXPORT DolphinSortFilterProxyModel : public KDirSortFilterProxyModel
+{
+ Q_OBJECT
+
+public:
+ DolphinSortFilterProxyModel(QObject* parent = 0);
+ virtual ~DolphinSortFilterProxyModel();
+
+ void setSorting(DolphinView::Sorting sorting);
+ DolphinView::Sorting sorting() const;
+
+ void setSortOrder(Qt::SortOrder sortOrder);
+ Qt::SortOrder sortOrder() const;
+
+ void setSortFoldersFirst(bool foldersFirst);
+
+ /** @reimplemented */
+ virtual void sort(int column,
+ Qt::SortOrder order = Qt::AscendingOrder);
+
+ /**
+ * Helper method to get the DolphinView::Sorting type for a given
+ * column \a column. If the column is smaller 0 or greater than the
+ * available columns, DolphinView::SortByName is returned.
+ */
+ static DolphinView::Sorting sortingForColumn(int column);
+
+signals:
+ void sortingRoleChanged();
+
+private:
+ DolphinView::Sorting m_sorting:16;
+ Qt::SortOrder m_sortOrder:16;
+};
+
+inline DolphinView::Sorting DolphinSortFilterProxyModel::sorting() const
+{
+ return m_sorting;
+}
+
+inline Qt::SortOrder DolphinSortFilterProxyModel::sortOrder() const
+{
+ return m_sortOrder;
+}
+
+#endif
diff --git a/src/views/dolphinviewactionhandler.cpp b/src/views/dolphinviewactionhandler.cpp
new file mode 100644
index 000000000..d2eaa4d51
--- /dev/null
+++ b/src/views/dolphinviewactionhandler.cpp
@@ -0,0 +1,518 @@
+/***************************************************************************
+ * Copyright (C) 2008 by David Faure <[email protected]> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "dolphinviewactionhandler.h"
+
+#include "additionalinfoaccessor.h"
+#include "settings/viewpropertiesdialog.h"
+#include "views/dolphinview.h"
+#include "views/zoomlevelinfo.h"
+#include <konq_operations.h>
+
+#include <kaction.h>
+#include <kactioncollection.h>
+#include <kactionmenu.h>
+#include <kfileitemdelegate.h>
+#include <klocale.h>
+#include <knewmenu.h>
+#include <kselectaction.h>
+#include <ktoggleaction.h>
+#include <krun.h>
+#include <kpropertiesdialog.h>
+
+
+DolphinViewActionHandler::DolphinViewActionHandler(KActionCollection* collection, QObject* parent)
+ : QObject(parent),
+ m_actionCollection(collection),
+ m_currentView(0)
+{
+ Q_ASSERT(m_actionCollection);
+ createActions();
+}
+
+void DolphinViewActionHandler::setCurrentView(DolphinView* view)
+{
+ Q_ASSERT(view);
+
+ if (m_currentView)
+ disconnect(m_currentView, 0, this, 0);
+
+ m_currentView = view;
+
+ connect(view, SIGNAL(modeChanged()),
+ this, SLOT(updateViewActions()));
+ connect(view, SIGNAL(showPreviewChanged()),
+ this, SLOT(slotShowPreviewChanged()));
+ connect(view, SIGNAL(sortOrderChanged(Qt::SortOrder)),
+ this, SLOT(slotSortOrderChanged(Qt::SortOrder)));
+ connect(view, SIGNAL(sortFoldersFirstChanged(bool)),
+ this, SLOT(slotSortFoldersFirstChanged(bool)));
+ connect(view, SIGNAL(additionalInfoChanged()),
+ this, SLOT(slotAdditionalInfoChanged()));
+ connect(view, SIGNAL(categorizedSortingChanged()),
+ this, SLOT(slotCategorizedSortingChanged()));
+ connect(view, SIGNAL(showHiddenFilesChanged()),
+ this, SLOT(slotShowHiddenFilesChanged()));
+ connect(view, SIGNAL(sortingChanged(DolphinView::Sorting)),
+ this, SLOT(slotSortingChanged(DolphinView::Sorting)));
+ connect(view, SIGNAL(zoomLevelChanged(int)),
+ this, SLOT(slotZoomLevelChanged(int)));
+}
+
+DolphinView* DolphinViewActionHandler::currentView()
+{
+ return m_currentView;
+}
+
+void DolphinViewActionHandler::createActions()
+{
+ // This action doesn't appear in the GUI, it's for the shortcut only.
+ // KNewFileMenu takes care of the GUI stuff.
+ KAction* newDirAction = m_actionCollection->addAction("create_dir");
+ newDirAction->setText(i18nc("@action", "Create Folder..."));
+ newDirAction->setShortcut(Qt::Key_F10);
+ newDirAction->setIcon(KIcon("folder-new"));
+ connect(newDirAction, SIGNAL(triggered()), this, SIGNAL(createDirectory()));
+
+ // File menu
+
+ KAction* rename = m_actionCollection->addAction("rename");
+ rename->setText(i18nc("@action:inmenu File", "Rename..."));
+ rename->setShortcut(Qt::Key_F2);
+ rename->setIcon(KIcon("edit-rename"));
+ connect(rename, SIGNAL(triggered()), this, SLOT(slotRename()));
+
+ KAction* moveToTrash = m_actionCollection->addAction("move_to_trash");
+ moveToTrash->setText(i18nc("@action:inmenu File", "Move to Trash"));
+ moveToTrash->setIcon(KIcon("user-trash"));
+ moveToTrash->setShortcut(QKeySequence::Delete);
+ connect(moveToTrash, SIGNAL(triggered(Qt::MouseButtons, Qt::KeyboardModifiers)),
+ this, SLOT(slotTrashActivated(Qt::MouseButtons, Qt::KeyboardModifiers)));
+
+ KAction* deleteAction = m_actionCollection->addAction("delete");
+ deleteAction->setIcon(KIcon("edit-delete"));
+ deleteAction->setText(i18nc("@action:inmenu File", "Delete"));
+ deleteAction->setShortcut(Qt::SHIFT | Qt::Key_Delete);
+ connect(deleteAction, SIGNAL(triggered()), this, SLOT(slotDeleteItems()));
+
+ // This action is useful for being enabled when "move_to_trash" should be
+ // disabled and "delete" is enabled (e.g. non-local files), so that Key_Del
+ // can be used for deleting the file (#76016). It needs to be a separate action
+ // so that the Edit menu isn't affected.
+ KAction* deleteWithTrashShortcut = m_actionCollection->addAction("delete_shortcut");
+ // The descriptive text is just for the shortcuts editor.
+ deleteWithTrashShortcut->setText(i18nc("@action \"Move to Trash\" for non-local files, etc.", "Delete (using shortcut for Trash)"));
+ deleteWithTrashShortcut->setShortcut(QKeySequence::Delete);
+ deleteWithTrashShortcut->setEnabled(false);
+ connect(deleteWithTrashShortcut, SIGNAL(triggered()), this, SLOT(slotDeleteItems()));
+
+ KAction *propertiesAction = m_actionCollection->addAction( "properties" );
+ // Well, it's the File menu in dolphinmainwindow and the Edit menu in dolphinpart... :)
+ propertiesAction->setText( i18nc("@action:inmenu File", "Properties") );
+ propertiesAction->setIcon(KIcon("document-properties"));
+ propertiesAction->setShortcut(Qt::ALT | Qt::Key_Return);
+ connect(propertiesAction, SIGNAL(triggered()), SLOT(slotProperties()));
+
+ // View menu
+ KToggleAction* iconsAction = iconsModeAction();
+ KToggleAction* detailsAction = detailsModeAction();
+ KToggleAction* columnsAction = columnsModeAction();
+
+ KSelectAction* viewModeActions = m_actionCollection->add<KSelectAction>("view_mode");
+ viewModeActions->setText(i18nc("@action:intoolbar", "View Mode"));
+ viewModeActions->addAction(iconsAction);
+ viewModeActions->addAction(detailsAction);
+ viewModeActions->addAction(columnsAction);
+ viewModeActions->setToolBarMode(KSelectAction::MenuMode);
+ connect(viewModeActions, SIGNAL(triggered(QAction*)), this, SLOT(slotViewModeActionTriggered(QAction*)));
+
+ KStandardAction::zoomIn(this,
+ SLOT(zoomIn()),
+ m_actionCollection);
+
+ KStandardAction::zoomOut(this,
+ SLOT(zoomOut()),
+ m_actionCollection);
+
+ KToggleAction* showPreview = m_actionCollection->add<KToggleAction>("show_preview");
+ showPreview->setText(i18nc("@action:intoolbar", "Preview"));
+ showPreview->setToolTip(i18nc("@info", "Show preview of files and folders"));
+ showPreview->setIcon(KIcon("view-preview"));
+ connect(showPreview, SIGNAL(triggered(bool)), this, SLOT(togglePreview(bool)));
+
+ KToggleAction* sortDescending = m_actionCollection->add<KToggleAction>("descending");
+ sortDescending->setText(i18nc("@action:inmenu Sort", "Descending"));
+ connect(sortDescending, SIGNAL(triggered()), this, SLOT(toggleSortOrder()));
+
+ KToggleAction* sortFoldersFirst = m_actionCollection->add<KToggleAction>("folders_first");
+ sortFoldersFirst->setText(i18nc("@action:inmenu Sort", "Folders First"));
+ connect(sortFoldersFirst, SIGNAL(triggered()), this, SLOT(toggleSortFoldersFirst()));
+
+ // View -> Sort By
+ QActionGroup* sortByActionGroup = createSortByActionGroup();
+ connect(sortByActionGroup, SIGNAL(triggered(QAction*)), this, SLOT(slotSortTriggered(QAction*)));
+
+ KActionMenu* sortByActionMenu = m_actionCollection->add<KActionMenu>("sort");
+ sortByActionMenu->setText(i18nc("@action:inmenu View", "Sort By"));
+ sortByActionMenu->setDelayed(false);
+
+ foreach (QAction* action, sortByActionGroup->actions()) {
+ sortByActionMenu->addAction(action);
+ }
+ sortByActionMenu->addSeparator();
+ sortByActionMenu->addAction(sortDescending);
+ sortByActionMenu->addAction(sortFoldersFirst);
+
+ // View -> Additional Information
+ QActionGroup* additionalInfoGroup = createAdditionalInformationActionGroup();
+ connect(additionalInfoGroup, SIGNAL(triggered(QAction*)), this, SLOT(toggleAdditionalInfo(QAction*)));
+
+ KActionMenu* additionalInfoMenu = m_actionCollection->add<KActionMenu>("additional_info");
+ additionalInfoMenu->setText(i18nc("@action:inmenu View", "Additional Information"));
+ additionalInfoMenu->setDelayed(false);
+ foreach (QAction* action, additionalInfoGroup->actions()) {
+ additionalInfoMenu->addAction(action);
+ }
+
+ KToggleAction* showInGroups = m_actionCollection->add<KToggleAction>("show_in_groups");
+ showInGroups->setText(i18nc("@action:inmenu View", "Show in Groups"));
+ connect(showInGroups, SIGNAL(triggered(bool)), this, SLOT(toggleSortCategorization(bool)));
+
+ KToggleAction* showHiddenFiles = m_actionCollection->add<KToggleAction>("show_hidden_files");
+ showHiddenFiles->setText(i18nc("@action:inmenu View", "Show Hidden Files"));
+ showHiddenFiles->setShortcuts(QList<QKeySequence>() << Qt::ALT + Qt::Key_Period << Qt::Key_F8);
+ connect(showHiddenFiles, SIGNAL(triggered(bool)), this, SLOT(toggleShowHiddenFiles(bool)));
+
+ KAction* adjustViewProps = m_actionCollection->addAction("view_properties");
+ adjustViewProps->setText(i18nc("@action:inmenu View", "Adjust View Properties..."));
+ connect(adjustViewProps, SIGNAL(triggered()), this, SLOT(slotAdjustViewProperties()));
+}
+
+QActionGroup* DolphinViewActionHandler::createAdditionalInformationActionGroup()
+{
+ QActionGroup* additionalInfoGroup = new QActionGroup(m_actionCollection);
+ additionalInfoGroup->setExclusive(false);
+
+ KActionMenu* showInformationMenu = m_actionCollection->add<KActionMenu>("additional_info");
+ showInformationMenu->setText(i18nc("@action:inmenu View", "Additional Information"));
+ showInformationMenu->setDelayed(false);
+
+ const AdditionalInfoAccessor& infoAccessor = AdditionalInfoAccessor::instance();
+
+ const KFileItemDelegate::InformationList infos = infoAccessor.keys();
+ foreach (KFileItemDelegate::Information info, infos) {
+ const QString name = infoAccessor.actionCollectionName(info, AdditionalInfoAccessor::AdditionalInfoType);
+ KToggleAction* action = m_actionCollection->add<KToggleAction>(name);
+ action->setText(infoAccessor.translation(info));
+ action->setData(info);
+ action->setActionGroup(additionalInfoGroup);
+ }
+
+ return additionalInfoGroup;
+}
+
+Q_DECLARE_METATYPE(DolphinView::Sorting)
+
+QActionGroup* DolphinViewActionHandler::createSortByActionGroup()
+{
+ QActionGroup* sortByActionGroup = new QActionGroup(m_actionCollection);
+ sortByActionGroup->setExclusive(true);
+
+ KToggleAction* sortByName = m_actionCollection->add<KToggleAction>("sort_by_name");
+ sortByName->setText(i18nc("@action:inmenu Sort By", "Name"));
+ sortByName->setData(QVariant::fromValue(DolphinView::SortByName));
+ sortByActionGroup->addAction(sortByName);
+
+ const AdditionalInfoAccessor& infoAccessor = AdditionalInfoAccessor::instance();
+ const KFileItemDelegate::InformationList infos = infoAccessor.keys();
+ foreach (KFileItemDelegate::Information info, infos) {
+ const QString name = infoAccessor.actionCollectionName(info, AdditionalInfoAccessor::SortByType);
+ KToggleAction* action = m_actionCollection->add<KToggleAction>(name);
+ action->setText(infoAccessor.translation(info));
+ const DolphinView::Sorting sorting = infoAccessor.sorting(info);
+ action->setData(QVariant::fromValue(sorting));
+ sortByActionGroup->addAction(action);
+ }
+
+ return sortByActionGroup;
+}
+
+void DolphinViewActionHandler::slotViewModeActionTriggered(QAction* action)
+{
+ const DolphinView::Mode mode = action->data().value<DolphinView::Mode>();
+ m_currentView->setMode(mode);
+
+ QAction* viewModeMenu = m_actionCollection->action("view_mode");
+ viewModeMenu->setIcon(KIcon(action->icon()));
+}
+
+void DolphinViewActionHandler::slotRename()
+{
+ emit actionBeingHandled();
+ m_currentView->renameSelectedItems();
+}
+
+void DolphinViewActionHandler::slotTrashActivated(Qt::MouseButtons, Qt::KeyboardModifiers modifiers)
+{
+ emit actionBeingHandled();
+ // Note: kde3's konq_mainwindow.cpp used to check
+ // reason == KAction::PopupMenuActivation && ...
+ // but this isn't supported anymore
+ if (modifiers & Qt::ShiftModifier) {
+ m_currentView->deleteSelectedItems();
+ } else {
+ m_currentView->trashSelectedItems();
+ }
+}
+
+void DolphinViewActionHandler::slotDeleteItems()
+{
+ emit actionBeingHandled();
+ m_currentView->deleteSelectedItems();
+}
+
+void DolphinViewActionHandler::togglePreview(bool show)
+{
+ emit actionBeingHandled();
+ m_currentView->setShowPreview(show);
+}
+
+void DolphinViewActionHandler::slotShowPreviewChanged()
+{
+ // It is not enough to update the 'Show Preview' action, also
+ // the 'Zoom In' and 'Zoom Out' actions must be adapted.
+ updateViewActions();
+}
+
+QString DolphinViewActionHandler::currentViewModeActionName() const
+{
+ switch (m_currentView->mode()) {
+ case DolphinView::IconsView:
+ return "icons";
+ case DolphinView::DetailsView:
+ return "details";
+ case DolphinView::ColumnView:
+ return "columns";
+ }
+ return QString(); // can't happen
+}
+
+KActionCollection* DolphinViewActionHandler::actionCollection()
+{
+ return m_actionCollection;
+}
+
+void DolphinViewActionHandler::updateViewActions()
+{
+ QAction* viewModeAction = m_actionCollection->action(currentViewModeActionName());
+ if (viewModeAction != 0) {
+ viewModeAction->setChecked(true);
+
+ QAction* viewModeMenu = m_actionCollection->action("view_mode");
+ viewModeMenu->setIcon(KIcon(viewModeAction->icon()));
+ }
+
+ QAction* showPreviewAction = m_actionCollection->action("show_preview");
+ showPreviewAction->setChecked(m_currentView->showPreview());
+
+ slotSortOrderChanged(m_currentView->sortOrder());
+ slotSortFoldersFirstChanged(m_currentView->sortFoldersFirst());
+ slotAdditionalInfoChanged();
+ slotCategorizedSortingChanged();
+ slotSortingChanged(m_currentView->sorting());
+ slotZoomLevelChanged(m_currentView->zoomLevel());
+
+ QAction* showHiddenFilesAction = m_actionCollection->action("show_hidden_files");
+ showHiddenFilesAction->setChecked(m_currentView->showHiddenFiles());
+}
+
+void DolphinViewActionHandler::zoomIn()
+{
+ const int level = m_currentView->zoomLevel();
+ m_currentView->setZoomLevel(level + 1);
+ updateViewActions();
+}
+
+void DolphinViewActionHandler::zoomOut()
+{
+ const int level = m_currentView->zoomLevel();
+ m_currentView->setZoomLevel(level - 1);
+ updateViewActions();
+}
+
+void DolphinViewActionHandler::toggleSortOrder()
+{
+ m_currentView->toggleSortOrder();
+}
+
+void DolphinViewActionHandler::toggleSortFoldersFirst()
+{
+ m_currentView->toggleSortFoldersFirst();
+}
+
+void DolphinViewActionHandler::slotSortOrderChanged(Qt::SortOrder order)
+{
+ QAction* descending = m_actionCollection->action("descending");
+ const bool sortDescending = (order == Qt::DescendingOrder);
+ descending->setChecked(sortDescending);
+}
+
+void DolphinViewActionHandler::slotSortFoldersFirstChanged(bool foldersFirst)
+{
+ m_actionCollection->action("folders_first")->setChecked(foldersFirst);
+}
+
+void DolphinViewActionHandler::toggleAdditionalInfo(QAction* action)
+{
+ emit actionBeingHandled();
+ m_currentView->toggleAdditionalInfo(action);
+}
+
+void DolphinViewActionHandler::slotAdditionalInfoChanged()
+{
+ m_currentView->updateAdditionalInfoActions(m_actionCollection);
+}
+
+void DolphinViewActionHandler::toggleSortCategorization(bool categorizedSorting)
+{
+ m_currentView->setCategorizedSorting(categorizedSorting);
+}
+
+void DolphinViewActionHandler::slotCategorizedSortingChanged()
+{
+ QAction* showInGroupsAction = m_actionCollection->action("show_in_groups");
+ showInGroupsAction->setChecked(m_currentView->categorizedSorting());
+ showInGroupsAction->setEnabled(m_currentView->supportsCategorizedSorting());
+}
+
+void DolphinViewActionHandler::toggleShowHiddenFiles(bool show)
+{
+ emit actionBeingHandled();
+ m_currentView->setShowHiddenFiles(show);
+}
+
+void DolphinViewActionHandler::slotShowHiddenFilesChanged()
+{
+ QAction* showHiddenFilesAction = m_actionCollection->action("show_hidden_files");
+ showHiddenFilesAction->setChecked(m_currentView->showHiddenFiles());
+}
+
+
+KToggleAction* DolphinViewActionHandler::iconsModeAction()
+{
+ KToggleAction* iconsView = m_actionCollection->add<KToggleAction>("icons");
+ iconsView->setText(i18nc("@action:inmenu View Mode", "Icons"));
+ iconsView->setToolTip(i18nc("@info", "Icons view mode"));
+ iconsView->setShortcut(Qt::CTRL | Qt::Key_1);
+ iconsView->setIcon(KIcon("view-list-icons"));
+ iconsView->setData(QVariant::fromValue(DolphinView::IconsView));
+ return iconsView;
+}
+
+KToggleAction* DolphinViewActionHandler::detailsModeAction()
+{
+ KToggleAction* detailsView = m_actionCollection->add<KToggleAction>("details");
+ detailsView->setText(i18nc("@action:inmenu View Mode", "Details"));
+ detailsView->setToolTip(i18nc("@info", "Details view mode"));
+ detailsView->setShortcut(Qt::CTRL | Qt::Key_2);
+ detailsView->setIcon(KIcon("view-list-details"));
+ detailsView->setData(QVariant::fromValue(DolphinView::DetailsView));
+ return detailsView;
+}
+
+KToggleAction* DolphinViewActionHandler::columnsModeAction()
+{
+ KToggleAction* columnView = m_actionCollection->add<KToggleAction>("columns");
+ columnView->setText(i18nc("@action:inmenu View Mode", "Columns"));
+ columnView->setToolTip(i18nc("@info", "Columns view mode"));
+ columnView->setShortcut(Qt::CTRL | Qt::Key_3);
+ columnView->setIcon(KIcon("view-file-columns"));
+ columnView->setData(QVariant::fromValue(DolphinView::ColumnView));
+ return columnView;
+}
+
+void DolphinViewActionHandler::slotSortingChanged(DolphinView::Sorting sorting)
+{
+ const AdditionalInfoAccessor& infoAccessor = AdditionalInfoAccessor::instance();
+ const KFileItemDelegate::InformationList infos = infoAccessor.keys();
+
+ QAction* action = 0;
+ if (sorting == DolphinView::SortByName) {
+ action = m_actionCollection->action("sort_by_name");
+ } else {
+ foreach (const KFileItemDelegate::Information info, infos) {
+ if (sorting == infoAccessor.sorting(info)) {
+ const QString name = infoAccessor.actionCollectionName(info, AdditionalInfoAccessor::SortByType);
+ action = m_actionCollection->action(name);
+ break;
+ }
+ }
+ }
+
+ if (action != 0) {
+ action->setChecked(true);
+
+ QAction* sortByMenu = m_actionCollection->action("sort");
+ sortByMenu->setIcon(KIcon(action->icon()));
+ }
+}
+
+void DolphinViewActionHandler::slotZoomLevelChanged(int level)
+{
+ QAction* zoomInAction = m_actionCollection->action(KStandardAction::name(KStandardAction::ZoomIn));
+ if (zoomInAction != 0) {
+ zoomInAction->setEnabled(level < ZoomLevelInfo::maximumLevel());
+ }
+
+ QAction* zoomOutAction = m_actionCollection->action(KStandardAction::name(KStandardAction::ZoomOut));
+ if (zoomOutAction != 0) {
+ zoomOutAction->setEnabled(level > ZoomLevelInfo::minimumLevel());
+ }
+}
+
+void DolphinViewActionHandler::slotSortTriggered(QAction* action)
+{
+ const DolphinView::Sorting sorting = action->data().value<DolphinView::Sorting>();
+ m_currentView->setSorting(sorting);
+}
+
+void DolphinViewActionHandler::slotAdjustViewProperties()
+{
+ emit actionBeingHandled();
+ QPointer<ViewPropertiesDialog> dialog = new ViewPropertiesDialog(m_currentView);
+ dialog->exec();
+ delete dialog;
+}
+
+void DolphinViewActionHandler::slotProperties()
+{
+ KPropertiesDialog* dialog = 0;
+ const KFileItemList list = m_currentView->selectedItems();
+ if (list.isEmpty()) {
+ const KUrl url = m_currentView->url();
+ dialog = new KPropertiesDialog(url, m_currentView);
+ } else {
+ dialog = new KPropertiesDialog(list, m_currentView);
+ }
+
+ dialog->setAttribute(Qt::WA_DeleteOnClose);
+ dialog->show();
+ dialog->raise();
+ dialog->activateWindow();
+}
diff --git a/src/views/dolphinviewactionhandler.h b/src/views/dolphinviewactionhandler.h
new file mode 100644
index 000000000..05339ce37
--- /dev/null
+++ b/src/views/dolphinviewactionhandler.h
@@ -0,0 +1,252 @@
+/***************************************************************************
+ * Copyright (C) 2008 by David Faure <[email protected]> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+
+#ifndef DOLPHINVIEWACTIONHANDLER_H
+#define DOLPHINVIEWACTIONHANDLER_H
+
+#include "libdolphin_export.h"
+#include <kactionmenu.h>
+#include <kselectaction.h>
+#include "views/dolphinview.h"
+#include <QtCore/QObject>
+
+class KToggleAction;
+class QAction;
+class QActionGroup;
+class DolphinView;
+class KActionCollection;
+
+/**
+ * @short Handles all actions for DolphinView
+ *
+ * The action handler owns all the actions and slots related to DolphinView,
+ * but can the view that is acts upon can be switched to another one
+ * (this is used in the case of split views).
+ *
+ * The purpose of this class is also to share this code between DolphinMainWindow
+ * and DolphinPart.
+ *
+ * @see DolphinView
+ * @see DolphinMainWindow
+ * @see DolphinPart
+ */
+class LIBDOLPHINPRIVATE_EXPORT DolphinViewActionHandler : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit DolphinViewActionHandler(KActionCollection* collection, QObject* parent);
+
+ /**
+ * Sets the view that this action handler should work on.
+ */
+ void setCurrentView(DolphinView* view);
+
+ /**
+ * Returns the view that this action handler should work on.
+ */
+ DolphinView* currentView();
+
+ /**
+ * Returns the name of the action for the current viewmode
+ */
+ QString currentViewModeActionName() const;
+
+ /**
+ * Returns m_actionCollection
+ */
+ KActionCollection* actionCollection();
+
+public Q_SLOTS:
+ /**
+ * Update all actions in the 'View' menu, i.e. those that depend on the
+ * settings in the current view.
+ */
+ void updateViewActions();
+
+Q_SIGNALS:
+ /**
+ * Emitted by DolphinViewActionHandler when the user triggered an action.
+ * This is only used for clearining the statusbar in DolphinMainWindow.
+ */
+ void actionBeingHandled();
+
+ /**
+ * Emitted if the user requested creating a new directory by the F10 key.
+ * The receiver of the signal (DolphinMainWindow or DolphinPart) invokes
+ * the method createDirectory of their KNewFileMenu instance.
+ */
+ void createDirectory();
+
+private Q_SLOTS:
+ /**
+ * Emitted when the user requested a change of view mode
+ */
+ void slotViewModeActionTriggered(QAction*);
+
+ /**
+ * Let the user input a name for the selected item(s) and trigger
+ * a renaming afterwards.
+ */
+ void slotRename();
+
+ /**
+ * Moves the selected items of the active view to the trash.
+ * This methods adds "shift means del" handling.
+ */
+ void slotTrashActivated(Qt::MouseButtons, Qt::KeyboardModifiers);
+
+ /**
+ * Deletes the selected items of the active view.
+ */
+ void slotDeleteItems();
+
+ /**
+ * Switches between showing a preview of the file content and showing the icon.
+ */
+ void togglePreview(bool);
+
+ /** Updates the state of the 'Show preview' menu action. */
+ void slotShowPreviewChanged();
+
+ /** Increases the size of the current set view mode. */
+ void zoomIn();
+
+ /** Decreases the size of the current set view mode. */
+ void zoomOut();
+
+ /** Switches between an ascending and descending sorting order. */
+ void toggleSortOrder();
+
+ /** Switches between a separate sorting and a mixed sorting of files and folders. */
+ void toggleSortFoldersFirst();
+
+ /**
+ * Updates the state of the 'Sort Ascending/Descending' action.
+ */
+ void slotSortOrderChanged(Qt::SortOrder order);
+
+ /**
+ * Updates the state of the 'Sort Folders First' action.
+ */
+ void slotSortFoldersFirstChanged(bool foldersFirst);
+
+ /**
+ * Updates the state of the 'Sort by' actions.
+ */
+ void slotSortingChanged(DolphinView::Sorting sorting);
+
+ /**
+ * Updates the state of the 'Zoom In' and 'Zoom Out' actions.
+ */
+ void slotZoomLevelChanged(int level);
+
+ /**
+ * Switches on or off the displaying of additional information
+ * as specified by \a action.
+ */
+ void toggleAdditionalInfo(QAction* action);
+
+ /**
+ * Changes the sorting of the current view.
+ */
+ void slotSortTriggered(QAction*);
+
+ /**
+ * Updates the state of the 'Additional Information' actions.
+ */
+ void slotAdditionalInfoChanged();
+
+ /**
+ * Switches between sorting by categories or not.
+ */
+ void toggleSortCategorization(bool);
+
+ /**
+ * Updates the state of the 'Categorized sorting' menu action.
+ */
+ void slotCategorizedSortingChanged();
+
+ /**
+ * Switches between showing and hiding of hidden marked files
+ */
+ void toggleShowHiddenFiles(bool);
+
+ /**
+ * Updates the state of the 'Show hidden files' menu action.
+ */
+ void slotShowHiddenFilesChanged();
+
+ /**
+ * Opens the view properties dialog, which allows to modify the properties
+ * of the currently active view.
+ */
+ void slotAdjustViewProperties();
+
+ /**
+ * Connected to the "properties" action.
+ * Opens the properties dialog for the selected items of the
+ * active view. The properties dialog shows information
+ * like name, size and permissions.
+ */
+ void slotProperties();
+
+private:
+ /**
+ * Create all the actions.
+ * This is called only once (by the constructor)
+ */
+ void createActions();
+
+ /**
+ * Creates an action group with all the "show additional information" actions in it.
+ * Helper method for createActions();
+ */
+ QActionGroup* createAdditionalInformationActionGroup();
+
+ /**
+ * Creates an action group with all the "sort by" actions in it.
+ * Helper method for createActions();
+ */
+ QActionGroup* createSortByActionGroup();
+
+ /**
+ * Returns the "switch to icons mode" action.
+ * Helper method for createActions();
+ */
+ KToggleAction* iconsModeAction();
+
+ /**
+ * Returns the "switch to details mode" action.
+ * Helper method for createActions();
+ */
+ KToggleAction* detailsModeAction();
+
+ /**
+ * Returns the "switch to columns mode" action.
+ * Helper method for createActions();
+ */
+ KToggleAction* columnsModeAction();
+
+ KActionCollection* m_actionCollection;
+ DolphinView* m_currentView;
+};
+
+#endif /* DOLPHINVIEWACTIONHANDLER_H */
diff --git a/src/views/draganddrophelper.cpp b/src/views/draganddrophelper.cpp
new file mode 100644
index 000000000..0cca59ac4
--- /dev/null
+++ b/src/views/draganddrophelper.cpp
@@ -0,0 +1,189 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Peter Penz <[email protected]> *
+ * Copyright (C) 2007 by David Faure <[email protected]> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "draganddrophelper.h"
+
+#include <kdirmodel.h>
+#include <kfileitem.h>
+#include <kicon.h>
+#include <klocale.h>
+#include <konq_operations.h>
+
+#include "views/dolphiniconsview.h"
+#include "views/dolphinviewcontroller.h"
+
+#include <QAbstractItemView>
+#include <QAbstractProxyModel>
+#include <QtDBus>
+#include <QDrag>
+#include <QPainter>
+
+class DragAndDropHelperSingleton
+{
+public:
+ DragAndDropHelper instance;
+};
+K_GLOBAL_STATIC(DragAndDropHelperSingleton, s_dragAndDropHelper)
+
+DragAndDropHelper& DragAndDropHelper::instance()
+{
+ return s_dragAndDropHelper->instance;
+}
+
+bool DragAndDropHelper::isMimeDataSupported(const QMimeData* mimeData) const
+{
+ return mimeData->hasUrls() || mimeData->hasFormat("application/x-kde-dndextract");
+}
+
+void DragAndDropHelper::startDrag(QAbstractItemView* itemView,
+ Qt::DropActions supportedActions,
+ DolphinViewController* dolphinViewController)
+{
+ // Do not start a new drag until the previous one has been finished.
+ // This is a (possibly temporary) fix for bug #187884.
+ static bool isDragging = false;
+ if (isDragging) {
+ return;
+ }
+ isDragging = true;
+
+ const QModelIndexList indexes = itemView->selectionModel()->selectedIndexes();
+ if (!indexes.isEmpty()) {
+ QMimeData *data = itemView->model()->mimeData(indexes);
+ if (data == 0) {
+ return;
+ }
+
+ if (dolphinViewController != 0) {
+ dolphinViewController->requestToolTipHiding();
+ }
+
+ QDrag* drag = new QDrag(itemView);
+ drag->setPixmap(createDragPixmap(itemView));
+ drag->setMimeData(data);
+
+ m_dragSource = itemView;
+ drag->exec(supportedActions, Qt::IgnoreAction);
+ m_dragSource = 0;
+ }
+ isDragging = false;
+}
+
+bool DragAndDropHelper::isDragSource(QAbstractItemView* itemView) const
+{
+ return (m_dragSource != 0) && (m_dragSource == itemView);
+}
+
+void DragAndDropHelper::dropUrls(const KFileItem& destItem,
+ const KUrl& destPath,
+ QDropEvent* event,
+ QWidget* widget)
+{
+ const bool dropToItem = !destItem.isNull() && (destItem.isDir() || destItem.isDesktopFile());
+ const KUrl destination = dropToItem ? destItem.url() : destPath;
+
+ const QMimeData* mimeData = event->mimeData();
+ if (mimeData->hasFormat("application/x-kde-dndextract")) {
+ QString remoteDBusClient = mimeData->data("application/x-kde-dndextract");
+ QDBusMessage message = QDBusMessage::createMethodCall(remoteDBusClient, "/DndExtract",
+ "org.kde.DndExtract", "extractSelectedFilesTo");
+ message.setArguments(QVariantList() << destination.path());
+ QDBusConnection::sessionBus().call(message);
+ } else {
+ const KUrl::List urls = KUrl::List::fromMimeData(event->mimeData());
+ const int urlsCount = urls.count();
+ if (urlsCount == 0) {
+ // TODO: handle dropping of other data
+ } else if ((urlsCount == 1) && (urls.first() == destination)) {
+ emit errorMessage(i18nc("@info:status", "A folder cannot be dropped into itself"));
+ } else if (dropToItem) {
+ KonqOperations::doDrop(destItem, destination, event, widget);
+ } else {
+ KonqOperations::doDrop(KFileItem(), destination, event, widget);
+ }
+ }
+}
+
+DragAndDropHelper::DragAndDropHelper()
+ : m_dragSource(0)
+{
+}
+
+QPixmap DragAndDropHelper::createDragPixmap(QAbstractItemView* itemView) const
+{
+ const QModelIndexList selectedIndexes = itemView->selectionModel()->selectedIndexes();
+ Q_ASSERT(!selectedIndexes.isEmpty());
+
+ QAbstractProxyModel* proxyModel = static_cast<QAbstractProxyModel*>(itemView->model());
+ KDirModel* dirModel = static_cast<KDirModel*>(proxyModel->sourceModel());
+
+ const int itemCount = selectedIndexes.count();
+
+ // If more than one item is dragged, align the items inside a
+ // rectangular grid. The maximum grid size is limited to 5 x 5 items.
+ int xCount = 3;
+ int size = KIconLoader::SizeMedium;
+ if (itemCount > 16) {
+ xCount = 5;
+ size = KIconLoader::SizeSmall;
+ } else if (itemCount > 9) {
+ xCount = 4;
+ size = KIconLoader::SizeSmallMedium;
+ }
+
+ if (itemCount < xCount) {
+ xCount = itemCount;
+ }
+
+ int yCount = itemCount / xCount;
+ if (itemCount % xCount != 0) {
+ ++yCount;
+ }
+ if (yCount > xCount) {
+ yCount = xCount;
+ }
+
+ // Draw the selected items into the grid cells
+ QPixmap dragPixmap(xCount * size + xCount - 1, yCount * size + yCount - 1);
+ dragPixmap.fill(Qt::transparent);
+
+ QPainter painter(&dragPixmap);
+ int x = 0;
+ int y = 0;
+ foreach (const QModelIndex& selectedIndex, selectedIndexes) {
+ const QModelIndex index = proxyModel->mapToSource(selectedIndex);
+ const KFileItem item = dirModel->itemForIndex(index);
+ const QPixmap pixmap = item.pixmap(size, size);
+ painter.drawPixmap(x, y, pixmap);
+
+ x += size + 1;
+ if (x >= dragPixmap.width()) {
+ x = 0;
+ y += size + 1;
+ }
+ if (y >= dragPixmap.height()) {
+ break;
+ }
+ }
+
+ return dragPixmap;
+}
+
+#include "draganddrophelper.moc"
diff --git a/src/views/draganddrophelper.h b/src/views/draganddrophelper.h
new file mode 100644
index 000000000..3cb506c43
--- /dev/null
+++ b/src/views/draganddrophelper.h
@@ -0,0 +1,102 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Peter Penz <[email protected]> *
+ * Copyright (C) 2007 by David Faure <[email protected]> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef DRAGANDDROPHELPER_H
+#define DRAGANDDROPHELPER_H
+
+#include "libdolphin_export.h"
+#include <QObject>
+#include <QPixmap>
+
+class DolphinViewController;
+class KFileItem;
+class KUrl;
+class QDropEvent;
+class QAbstractItemView;
+class QMimeData;
+class QWidget;
+
+/**
+ * @brief Helper class for having a common drag and drop behavior.
+ *
+ * The class is used by DolphinIconsView, DolphinDetailsView,
+ * DolphinColumnView and PanelTreeView to have a consistent
+ * drag and drop behavior between all views.
+ */
+class LIBDOLPHINPRIVATE_EXPORT DragAndDropHelper : public QObject
+{
+ Q_OBJECT
+
+public:
+ static DragAndDropHelper& instance();
+
+ /**
+ * Returns true, if Dolphin supports the dragging of
+ * the given mime data.
+ */
+ bool isMimeDataSupported(const QMimeData* mimeData) const;
+
+ /**
+ * Creates a drag object for the view \a itemView for all selected items.
+ */
+ void startDrag(QAbstractItemView* itemView,
+ Qt::DropActions supportedActions,
+ DolphinViewController* dolphinViewController = 0);
+
+ /**
+ * Returns true if and only if the view \a itemView was the last view to
+ * be passed to startDrag(...), and that drag is still in progress.
+ */
+ bool isDragSource(QAbstractItemView* itemView) const;
+
+ /**
+ * Handles the dropping of URLs to the given
+ * destination. A context menu with the options
+ * 'Move Here', 'Copy Here', 'Link Here' and
+ * 'Cancel' is offered to the user.
+ * @param destItem Item of the destination (can be null, see KFileItem::isNull()).
+ * @param destPath Path of the destination.
+ * @param event Drop event.
+ * @param widget Source widget where the dragging has been started.
+ */
+ void dropUrls(const KFileItem& destItem,
+ const KUrl& destPath,
+ QDropEvent* event,
+ QWidget* widget);
+signals:
+ void errorMessage(const QString& msg);
+
+private:
+ DragAndDropHelper();
+
+ /**
+ * Creates a pixmap the contains the all icons of the items
+ * that are dragged.
+ */
+ QPixmap createDragPixmap(QAbstractItemView* itemView) const;
+
+ // The last view passed in startDrag(...), or 0 if
+ // no startDrag(...) initiated drag is in progress.
+ QAbstractItemView *m_dragSource;
+
+ friend class DragAndDropHelperSingleton;
+};
+
+#endif
diff --git a/src/views/folderexpander.cpp b/src/views/folderexpander.cpp
new file mode 100644
index 000000000..a2dfb137b
--- /dev/null
+++ b/src/views/folderexpander.cpp
@@ -0,0 +1,141 @@
+/***************************************************************************
+ * Copyright (C) 2008 by Simon St James <[email protected]> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "folderexpander.h"
+
+#include <QtCore/QTimer>
+#include <QtGui/QAbstractItemView>
+#include <QtGui/QTreeView>
+#include <QtGui/QScrollBar>
+
+#include <QtCore/QEvent>
+#include <QtGui/QDragMoveEvent>
+
+#include <QtGui/QSortFilterProxyModel>
+
+#include <kdirmodel.h>
+
+FolderExpander::FolderExpander(QAbstractItemView *view, QSortFilterProxyModel *proxyModel) :
+ QObject(view),
+ m_enabled(true),
+ m_view(view),
+ m_proxyModel(proxyModel),
+ m_autoExpandTriggerTimer(0),
+ m_autoExpandPos()
+{
+ if (m_view == 0) {
+ return;
+ }
+ if (m_proxyModel == 0) {
+ return;
+ }
+ KDirModel *m_dirModel = qobject_cast<KDirModel*>(m_proxyModel->sourceModel());
+ if (m_dirModel == 0) {
+ return;
+ }
+
+ // Initialise auto-expand timer.
+ m_autoExpandTriggerTimer = new QTimer(this);
+ m_autoExpandTriggerTimer->setSingleShot(true);
+ connect(m_autoExpandTriggerTimer, SIGNAL(timeout()),
+ this, SLOT(autoExpandTimeout()));
+
+ // The view scrolling complicates matters, so we want to
+ // be informed if they occur.
+ connect(m_view->horizontalScrollBar(), SIGNAL(valueChanged(int)),
+ this, SLOT(viewScrolled()));
+ connect(m_view->verticalScrollBar(), SIGNAL(valueChanged(int)),
+ this, SLOT(viewScrolled()));
+
+ // "Dragging" events are sent to the QAbstractItemView's viewport.
+ m_view->viewport()->installEventFilter(this);
+}
+
+void FolderExpander::setEnabled(bool enabled)
+{
+ m_enabled = enabled;
+}
+
+bool FolderExpander::enabled() const
+{
+ return m_enabled;
+}
+
+FolderExpander::~FolderExpander()
+{
+}
+
+void FolderExpander::viewScrolled()
+{
+ if (m_autoExpandTriggerTimer->isActive()) {
+ m_autoExpandTriggerTimer->start(AUTO_EXPAND_DELAY);
+ }
+}
+
+void FolderExpander::autoExpandTimeout()
+{
+ if (!m_enabled) {
+ return;
+ }
+
+ // We want to find whether the file currently being hovered over is a
+ // directory. TODO - is there a simpler way, preferably without
+ // needing to pass in m_proxyModel that has a KDirModel as its sourceModel() ... ?
+ QModelIndex proxyIndexToExpand = m_view->indexAt(m_autoExpandPos);
+ QModelIndex indexToExpand = m_proxyModel->mapToSource(proxyIndexToExpand);
+ KDirModel* m_dirModel = qobject_cast< KDirModel* >(m_proxyModel->sourceModel());
+ Q_ASSERT(m_dirModel != 0);
+ KFileItem itemToExpand = m_dirModel->itemForIndex(indexToExpand);
+
+ if (itemToExpand.isNull() || itemToExpand == m_dirModel->itemForIndex(QModelIndex())) {
+ // The second clause occurs when we are expanding the folder represented
+ // by the view, which is a case we should ignore (#182618).
+ return;
+ }
+
+ if (itemToExpand.isDir()) {
+ QTreeView* treeView = qobject_cast<QTreeView*>(m_view);
+ if ((treeView != 0) && treeView->itemsExpandable()) {
+ // Toggle expanded state of this directory.
+ treeView->setExpanded(proxyIndexToExpand, !treeView->isExpanded(proxyIndexToExpand));
+ }
+ else {
+ emit enterDir(proxyIndexToExpand);
+ }
+ }
+}
+
+bool FolderExpander::eventFilter(QObject* watched, QEvent* event)
+{
+ Q_UNUSED(watched);
+ // We're interested in reading Drag* events, but not filtering them,
+ // so always return false.
+ // We just store the position of the hover, here; actually working out
+ // what the hovered item is and whether it is expandable is done in
+ // autoExpandTimeout.
+ if (event->type() == QEvent::DragMove) {
+ QDragMoveEvent *dragMoveEvent = static_cast<QDragMoveEvent*>(event);
+ // (Re-)set the timer while we're still moving and dragging.
+ m_autoExpandTriggerTimer->start(AUTO_EXPAND_DELAY);
+ m_autoExpandPos = dragMoveEvent->pos();
+ } else if (event->type() == QEvent::DragLeave || event->type() == QEvent::Drop) {
+ m_autoExpandTriggerTimer->stop();
+ }
+ return false;
+}
diff --git a/src/views/folderexpander.h b/src/views/folderexpander.h
new file mode 100644
index 000000000..63de57f4a
--- /dev/null
+++ b/src/views/folderexpander.h
@@ -0,0 +1,89 @@
+/***************************************************************************
+ * Copyright (C) 2008 by Simon St James <[email protected]> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef FOLDEREXPANDER_H
+#define FOLDEREXPANDER_H
+
+// Needs to be exported as FoldersPanel uses it.
+#include "libdolphin_export.h"
+
+#include <QObject>
+#include <QPoint>
+
+class QAbstractItemView;
+class QTreeView;
+class QTimer;
+class QSortFilterProxyModel;
+class QModelIndex;
+
+/**
+ * Grants auto expanding functionality to the provided item view.
+ * Qt has its own auto expand mechanism, but this works only
+ * for QTreeView. Auto expanding of folders is turned on
+ * per default.
+ *
+ * If the provided view is an instance of the class QTreeView, the
+ * expansion of the directory is automatically done on hover. Otherwise
+ * the enterDir() signal is emitted and the caller needs to ensure that
+ * the requested directory is entered.
+ *
+ * The FolderExpander becomes a child of the provided view.
+ */
+class LIBDOLPHINPRIVATE_EXPORT FolderExpander : public QObject
+{
+ Q_OBJECT
+
+public:
+ FolderExpander(QAbstractItemView* view, QSortFilterProxyModel* proxyModel);
+ virtual ~FolderExpander();
+
+ void setEnabled(bool enabled);
+ bool enabled() const;
+
+signals:
+ /**
+ * Is emitted if the directory \a dirModelIndex should be entered. The
+ * signal is not emitted when a QTreeView is used, as the entering of
+ * the directory is already provided by expanding the tree node.
+ */
+ void enterDir(const QModelIndex& dirModelIndex);
+
+
+private slots:
+ void viewScrolled();
+ void autoExpandTimeout();
+
+private:
+ bool m_enabled;
+
+ QAbstractItemView* m_view;
+ QSortFilterProxyModel* m_proxyModel;
+
+ QTimer* m_autoExpandTriggerTimer;
+ QPoint m_autoExpandPos;
+
+ static const int AUTO_EXPAND_DELAY = 700;
+
+ /**
+ * Watchs the drag/move events for the view to decide
+ * whether auto expanding of a folder should be triggered.
+ */
+ bool eventFilter(QObject* watched, QEvent* event);
+};
+#endif
diff --git a/src/views/renamedialog.cpp b/src/views/renamedialog.cpp
new file mode 100644
index 000000000..39e61c464
--- /dev/null
+++ b/src/views/renamedialog.cpp
@@ -0,0 +1,132 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Peter Penz ([email protected]) *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "renamedialog.h"
+
+#include <kfileitem.h>
+#include <klineedit.h>
+#include <klocale.h>
+
+#include <QtGui/QLabel>
+#include <QtGui/QBoxLayout>
+
+RenameDialog::RenameDialog(QWidget *parent, const KFileItemList& items) :
+ KDialog(parent),
+ m_renameOneItem(false)
+{
+ const QSize minSize = minimumSize();
+ setMinimumSize(QSize(320, minSize.height()));
+
+ const int itemCount = items.count();
+ Q_ASSERT(itemCount >= 1);
+ m_renameOneItem = (itemCount == 1);
+
+ setCaption(m_renameOneItem ?
+ i18nc("@title:window", "Rename Item") :
+ i18nc("@title:window", "Rename Items"));
+ setButtons(Ok | Cancel);
+ setDefaultButton(Ok);
+
+ setButtonGuiItem(Ok, KGuiItem(i18nc("@action:button", "&Rename"), "dialog-ok-apply"));
+
+ QWidget* page = new QWidget(this);
+ setMainWidget(page);
+
+ QVBoxLayout* topLayout = new QVBoxLayout(page);
+
+ QLabel* editLabel = 0;
+ if (m_renameOneItem) {
+ m_newName = items.first().name();
+ editLabel = new QLabel(i18nc("@label:textbox", "Rename the item <filename>%1</filename> to:", m_newName),
+ page);
+ } else {
+ m_newName = i18nc("@info:status", "New name #");
+ editLabel = new QLabel(i18ncp("@label:textbox",
+ "Rename the %1 selected item to:",
+ "Rename the %1 selected items to:", itemCount),
+ page);
+ }
+
+ m_lineEdit = new KLineEdit(page);
+
+ QString fileName = items[0].url().prettyUrl();
+ QString extension = KMimeType::extractKnownExtension(fileName.toLower());
+ if (!extension.isEmpty()) {
+ extension.insert(0, '.');
+ // The first item seems to have a extension (e. g. '.jpg' or '.txt'). Now
+ // check whether all other URLs have the same extension. If this is the
+ // case, add this extension to the name suggestion.
+ for (int i = 1; i < itemCount; ++i) {
+ fileName = items[i].url().prettyUrl().toLower();
+ if (!fileName.endsWith(extension)) {
+ // at least one item does not have the same extension
+ extension.truncate(0);
+ break;
+ }
+ }
+ }
+
+ int selectionLength = m_newName.length();
+ if (!m_renameOneItem) {
+ --selectionLength; // don't select the # character
+ }
+
+ const int extensionLength = extension.length();
+ if (extensionLength > 0) {
+ if (m_renameOneItem) {
+ selectionLength -= extensionLength;
+ } else {
+ m_newName.append(extension);
+ }
+ }
+
+ m_lineEdit->setText(m_newName);
+ m_lineEdit->setSelection(0, selectionLength);
+ m_lineEdit->setFocus();
+
+ topLayout->addWidget(editLabel);
+ topLayout->addWidget(m_lineEdit);
+
+ if (!m_renameOneItem) {
+ QLabel* infoLabel = new QLabel(i18nc("@info", "(# will be replaced by ascending numbers)"), page);
+ topLayout->addWidget(infoLabel);
+ }
+}
+
+RenameDialog::~RenameDialog()
+{
+}
+
+void RenameDialog::slotButtonClicked(int button)
+{
+ if (button == Ok) {
+ m_newName = m_lineEdit->text();
+ if (m_newName.isEmpty()) {
+ m_errorString = i18nc("@info:status",
+ "The new name is empty. A name with at least one character must be entered.");
+ } else if (!m_renameOneItem && (m_newName.count('#') == 0)) {
+ m_newName.truncate(0);
+ m_errorString = i18nc("@info:status", "The name must contain at least one # character.");
+ }
+ }
+
+ KDialog::slotButtonClicked(button);
+}
+
+#include "renamedialog.moc"
diff --git a/src/views/renamedialog.h b/src/views/renamedialog.h
new file mode 100644
index 000000000..eca5f4d06
--- /dev/null
+++ b/src/views/renamedialog.h
@@ -0,0 +1,98 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Peter Penz ([email protected]) *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+#ifndef RENAMEDIALOG_H
+#define RENAMEDIALOG_H
+
+#include "libdolphin_export.h"
+
+#include <kdialog.h>
+#include <kurl.h>
+
+class KFileItem;
+class KFileItemList;
+class KLineEdit;
+
+#include <QString>
+
+/**
+ * @brief Dialog for renaming a variable number of files.
+ *
+ * The renaming is not done by the dialog, the invoker
+ * must do this itself:
+ * \code
+ * RenameDialog dialog(...);
+ * if (dialog.exec() == QDialog::Accepted) {
+ * const QString& newName = dialog.newName();
+ * if (newName.isEmpty()) {
+ * // an invalid name has been chosen, use
+ * // dialog.errorString() to tell the user about this
+ * }
+ * else {
+ * // rename items corresponding to the new name
+ * }
+ * }
+ * \endcode
+ */
+class LIBDOLPHINPRIVATE_EXPORT RenameDialog : public KDialog
+{
+ Q_OBJECT
+
+public:
+ explicit RenameDialog(QWidget *parent, const KFileItemList& items);
+ virtual ~RenameDialog();
+
+ /**
+ * Returns the new name of the items. If more than one
+ * item should be renamed, then it is assured that the # character
+ * is part of the returned string. If the returned string is empty,
+ * then RenameDialog::errorString() should be used to show the reason
+ * of having an empty string (e. g. if the # character has
+ * been deleted by the user, although more than one item should be
+ * renamed).
+ */
+ QString newName() const;
+
+ /**
+ * Returns the error string, if Dialog::newName() returned an empty string.
+ */
+ QString errorString() const;
+
+protected slots:
+ virtual void slotButtonClicked(int button);
+
+private:
+ bool m_renameOneItem;
+ KLineEdit* m_lineEdit;
+ QString m_newName;
+ QString m_errorString;
+
+ friend class RenameDialogTest; // allow access for unit testing
+};
+
+inline QString RenameDialog::newName() const
+{
+ return m_newName;
+}
+
+inline QString RenameDialog::errorString() const
+{
+ return m_errorString;
+}
+
+#endif
diff --git a/src/views/viewproperties.cpp b/src/views/viewproperties.cpp
new file mode 100644
index 000000000..3e08358f7
--- /dev/null
+++ b/src/views/viewproperties.cpp
@@ -0,0 +1,310 @@
+/***************************************************************************
+ * Copyright (C) 2006-2010 by Peter Penz <[email protected]> *
+ * Copyright (C) 2006 by Aaron J. Seigo <[email protected]> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "viewproperties.h"
+
+#include "additionalinfoaccessor.h"
+#include "dolphin_directoryviewpropertysettings.h"
+#include "dolphin_generalsettings.h"
+
+#include <kcomponentdata.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+#include <kurl.h>
+
+#include <QDate>
+#include <QFile>
+#include <QFileInfo>
+
+#include "settings/dolphinsettings.h"
+
+ViewProperties::ViewProperties(const KUrl& url) :
+ m_changedProps(false),
+ m_autoSave(true),
+ m_node(0)
+{
+ // We try and save it to the file .directory in the directory being viewed.
+ // If the directory is not writable by the user or the directory is not local,
+ // we store the properties information in a local file.
+ GeneralSettings* settings = DolphinSettings::instance().generalSettings();
+ const bool useGlobalViewProps = settings->globalViewProps();
+ if (useGlobalViewProps) {
+ m_filePath = destinationDir("global");
+ } else if (url.isLocalFile()) {
+ m_filePath = url.toLocalFile();
+ const QFileInfo info(m_filePath);
+ if (!info.isWritable()) {
+ m_filePath = destinationDir("local") + m_filePath;
+ }
+ } else {
+ m_filePath = destinationDir("remote") + m_filePath;
+ }
+
+ const QString file = m_filePath + QDir::separator() + QLatin1String(".directory");
+ m_node = new ViewPropertySettings(KSharedConfig::openConfig(file));
+
+ const bool useDefaultProps = !useGlobalViewProps &&
+ (!QFileInfo(file).exists() ||
+ (m_node->timestamp() < settings->viewPropsTimestamp()));
+ if (useDefaultProps) {
+ // If the .directory file does not exist or the timestamp is too old,
+ // use the values from the global .directory file instead, which acts
+ // as default view for new folders in this case.
+ settings->setGlobalViewProps(true);
+
+ ViewProperties defaultProps(url);
+ setDirProperties(defaultProps);
+
+ settings->setGlobalViewProps(false);
+ m_changedProps = false;
+ }
+}
+
+ViewProperties::~ViewProperties()
+{
+ if (m_changedProps && m_autoSave) {
+ save();
+ }
+
+ delete m_node;
+ m_node = 0;
+}
+
+void ViewProperties::setViewMode(DolphinView::Mode mode)
+{
+ if (m_node->viewMode() != mode) {
+ m_node->setViewMode(mode);
+ updateTimeStamp();
+ }
+}
+
+DolphinView::Mode ViewProperties::viewMode() const
+{
+ return static_cast<DolphinView::Mode>(m_node->viewMode());
+}
+
+void ViewProperties::setShowPreview(bool show)
+{
+ if (m_node->showPreview() != show) {
+ m_node->setShowPreview(show);
+ updateTimeStamp();
+ }
+}
+
+bool ViewProperties::showPreview() const
+{
+ return m_node->showPreview();
+}
+
+void ViewProperties::setShowHiddenFiles(bool show)
+{
+ if (m_node->showHiddenFiles() != show) {
+ m_node->setShowHiddenFiles(show);
+ updateTimeStamp();
+ }
+}
+
+void ViewProperties::setCategorizedSorting(bool categorized)
+{
+ if (m_node->categorizedSorting() != categorized) {
+ m_node->setCategorizedSorting(categorized);
+ updateTimeStamp();
+ }
+}
+
+bool ViewProperties::categorizedSorting() const
+{
+ return m_node->categorizedSorting();
+}
+
+bool ViewProperties::showHiddenFiles() const
+{
+ return m_node->showHiddenFiles();
+}
+
+void ViewProperties::setSorting(DolphinView::Sorting sorting)
+{
+ if (m_node->sorting() != sorting) {
+ m_node->setSorting(sorting);
+ updateTimeStamp();
+ }
+}
+
+DolphinView::Sorting ViewProperties::sorting() const
+{
+ return static_cast<DolphinView::Sorting>(m_node->sorting());
+}
+
+void ViewProperties::setSortOrder(Qt::SortOrder sortOrder)
+{
+ if (m_node->sortOrder() != sortOrder) {
+ m_node->setSortOrder(sortOrder);
+ updateTimeStamp();
+ }
+}
+
+Qt::SortOrder ViewProperties::sortOrder() const
+{
+ return static_cast<Qt::SortOrder>(m_node->sortOrder());
+}
+
+void ViewProperties::setSortFoldersFirst(bool foldersFirst)
+{
+ if (m_node->sortFoldersFirst() != foldersFirst) {
+ m_node->setSortFoldersFirst(foldersFirst);
+ updateTimeStamp();
+ }
+}
+
+bool ViewProperties::sortFoldersFirst() const
+{
+ return m_node->sortFoldersFirst();
+}
+
+void ViewProperties::setAdditionalInfo(const KFileItemDelegate::InformationList& list)
+{
+ AdditionalInfoAccessor& infoAccessor = AdditionalInfoAccessor::instance();
+
+ int infoMask = 0;
+ foreach (KFileItemDelegate::Information currentInfo, list) {
+ infoMask = infoMask | infoAccessor.bitValue(currentInfo);
+ }
+
+ const int encodedInfo = encodedAdditionalInfo(infoMask);
+ if (m_node->additionalInfo() != encodedInfo) {
+ m_node->setAdditionalInfo(encodedInfo);
+ updateTimeStamp();
+ }
+}
+
+KFileItemDelegate::InformationList ViewProperties::additionalInfo() const
+{
+ KFileItemDelegate::InformationList usedInfos;
+
+ const int decodedInfo = decodedAdditionalInfo();
+
+ AdditionalInfoAccessor& infoAccessor = AdditionalInfoAccessor::instance();
+ const KFileItemDelegate::InformationList infos = infoAccessor.keys();
+
+ foreach (const KFileItemDelegate::Information info, infos) {
+ if (decodedInfo & infoAccessor.bitValue(info)) {
+ usedInfos.append(info);
+ }
+ }
+
+ return usedInfos;
+}
+
+
+void ViewProperties::setDirProperties(const ViewProperties& props)
+{
+ setViewMode(props.viewMode());
+ setShowPreview(props.showPreview());
+ setShowHiddenFiles(props.showHiddenFiles());
+ setCategorizedSorting(props.categorizedSorting());
+ setSorting(props.sorting());
+ setSortOrder(props.sortOrder());
+ setSortFoldersFirst(props.sortFoldersFirst());
+ setAdditionalInfo(props.additionalInfo());
+}
+
+void ViewProperties::setAutoSaveEnabled(bool autoSave)
+{
+ m_autoSave = autoSave;
+}
+
+bool ViewProperties::isAutoSaveEnabled() const
+{
+ return m_autoSave;
+}
+
+void ViewProperties::updateTimeStamp()
+{
+ m_changedProps = true;
+ m_node->setTimestamp(QDateTime::currentDateTime());
+}
+
+void ViewProperties::save()
+{
+ KStandardDirs::makeDir(m_filePath);
+ m_node->writeConfig();
+ m_changedProps = false;
+}
+
+KUrl ViewProperties::mirroredDirectory()
+{
+ QString basePath = KGlobal::mainComponent().componentName();
+ basePath.append("/view_properties/");
+ return KUrl(KStandardDirs::locateLocal("data", basePath));
+}
+
+QString ViewProperties::destinationDir(const QString& subDir) const
+{
+ QString basePath = KGlobal::mainComponent().componentName();
+ basePath.append("/view_properties/").append(subDir);
+ return KStandardDirs::locateLocal("data", basePath);
+}
+
+int ViewProperties::encodedAdditionalInfo(int info) const
+{
+ int encodedInfo = m_node->additionalInfo();
+
+ switch (viewMode()) {
+ case DolphinView::DetailsView:
+ encodedInfo = (encodedInfo & 0xFFFF00) | info;
+ break;
+ case DolphinView::IconsView:
+ encodedInfo = (encodedInfo & 0xFF00FF) | (info << 8);
+ break;
+ case DolphinView::ColumnView:
+ encodedInfo = (encodedInfo & 0x00FFFF) | (info << 16);
+ break;
+ default: break;
+ }
+
+ return encodedInfo;
+}
+
+int ViewProperties::decodedAdditionalInfo() const
+{
+ int decodedInfo = m_node->additionalInfo();
+
+ switch (viewMode()) {
+ case DolphinView::DetailsView:
+ decodedInfo = decodedInfo & 0xFF;
+ if (decodedInfo == 0) {
+ // A details view without any additional info makes no sense, hence
+ // provide at least a size-info and date-info as fallback
+ AdditionalInfoAccessor& infoAccessor = AdditionalInfoAccessor::instance();
+ decodedInfo = infoAccessor.bitValue(KFileItemDelegate::Size) |
+ infoAccessor.bitValue(KFileItemDelegate::ModificationTime);
+ }
+ break;
+ case DolphinView::IconsView:
+ decodedInfo = (decodedInfo >> 8) & 0xFF;
+ break;
+ case DolphinView::ColumnView:
+ decodedInfo = (decodedInfo >> 16) & 0xFF;
+ break;
+ default: break;
+ }
+
+ return decodedInfo;
+}
diff --git a/src/views/viewproperties.h b/src/views/viewproperties.h
new file mode 100644
index 000000000..bb476dc44
--- /dev/null
+++ b/src/views/viewproperties.h
@@ -0,0 +1,163 @@
+/***************************************************************************
+ * Copyright (C) 2006-2010 by Peter Penz <[email protected]> *
+ * Copyright (C) 2006 by Aaron J. Seigo <[email protected]> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef VIEWPROPERTIES_H
+#define VIEWPROPERTIES_H
+
+#include <views/dolphinview.h>
+#include <kurl.h>
+#include <libdolphin_export.h>
+
+class ViewPropertySettings;
+/**
+ * @brief Maintains the view properties like 'view mode' or
+ * 'show hidden files' for a directory.
+ *
+ * The view properties are automatically stored as part of the file
+ * .directory inside the corresponding path. To read out the view properties
+ * just construct an instance by passing the path of the directory:
+ *
+ * \code
+ * ViewProperties props(KUrl("/home/peter/Documents"));
+ * const DolphinView::Mode mode = props.viewMode();
+ * const bool showHiddenFiles = props.isShowHiddenFilesEnabled();
+ * \endcode
+ *
+ * When modifying a view property, the '.directory' file is automatically updated
+ * inside the destructor.
+ *
+ * If no .directory file is available or the global view mode is turned on
+ * (see GeneralSettings::globalViewMode()), the values from the global .directory file
+ * are used for initialization.
+ */
+class LIBDOLPHINPRIVATE_EXPORT ViewProperties
+{
+public:
+ explicit ViewProperties(const KUrl& url);
+ virtual ~ViewProperties();
+
+ void setViewMode(DolphinView::Mode mode);
+ DolphinView::Mode viewMode() const;
+
+ void setShowPreview(bool show);
+ bool showPreview() const;
+
+ void setShowHiddenFiles(bool show);
+ bool showHiddenFiles() const;
+
+ void setCategorizedSorting(bool categorized);
+ bool categorizedSorting() const;
+
+ void setSorting(DolphinView::Sorting sorting);
+ DolphinView::Sorting sorting() const;
+
+ void setSortOrder(Qt::SortOrder sortOrder);
+ Qt::SortOrder sortOrder() const;
+
+ void setSortFoldersFirst(bool foldersFirst);
+ bool sortFoldersFirst() const;
+
+ /**
+ * Sets the additional information for the current set view-mode.
+ * Note that the additional-info property is the only property where
+ * the value is dependent from another property (in this case the view-mode).
+ */
+ void setAdditionalInfo(const KFileItemDelegate::InformationList& info);
+
+ /**
+ * Returns the additional information for the current set view-mode.
+ * Note that the additional-info property is the only property where
+ * the value is dependent from another property (in this case the view-mode).
+ */
+ KFileItemDelegate::InformationList additionalInfo() const;
+
+ /**
+ * Sets the directory properties view mode, show preview,
+ * show hidden files, sorting and sort order like
+ * set in \a props.
+ */
+ void setDirProperties(const ViewProperties& props);
+
+ /**
+ * If \a autoSave is true, the properties are automatically
+ * saved when the destructor is called. Per default autosaving
+ * is enabled.
+ */
+ void setAutoSaveEnabled(bool autoSave);
+ bool isAutoSaveEnabled() const;
+
+ void updateTimeStamp();
+
+ /**
+ * Saves the view properties for the directory specified
+ * in the constructor. The method is automatically
+ * invoked in the destructor, if
+ * ViewProperties::isAutoSaveEnabled() returns true and
+ * at least one property has been changed.
+ */
+ void save();
+
+ /**
+ * Returns the URL of the directory, where the mirrored view properties
+ * are stored into. Mirrored view properties are used if:
+ * - there is no write access for storing the view properties into
+ * the original directory
+ * - for non local directories
+ */
+ static KUrl mirroredDirectory();
+
+private:
+ /**
+ * Returns the destination directory path where the view
+ * properties are stored. \a subDir specifies the used sub
+ * directory.
+ */
+ QString destinationDir(const QString& subDir) const;
+
+ /**
+ * Returns the encoded additional information that can be stored
+ * in the .directory file. See ViewProperties::decodedAdditionalInfo()
+ * for the coding format.
+ * @param info Additional information for the current view mode.
+ */
+ int encodedAdditionalInfo(int info) const;
+
+ /**
+ * Returns the decoded additional information from the .directory
+ * file by respecting the current set view mode. The additional
+ * information from the .directory file is an integer value, where:
+ * - Byte 0 stores the additional info for the details view
+ * - Byte 1 stores the additional info for the icons view
+ * - Byte 2 stores the additional info for the column view
+ * The additional information property is the only property that is
+ * dependent from another property (in this case the view-mode).
+ */
+ int decodedAdditionalInfo() const;
+
+ Q_DISABLE_COPY(ViewProperties)
+
+private:
+ bool m_changedProps;
+ bool m_autoSave;
+ QString m_filePath;
+ ViewPropertySettings* m_node;
+};
+
+#endif