Adjust the preview-settings to allow users to configure thumbnail-plugins. For consistency also the service-settings have been adjusted to use the ServiceModel and ServiceItemDelegate.
search/dolphinsearchbox.cpp
search/dolphinsearchinformation.cpp
settings/general/behaviorsettingspage.cpp
+ settings/general/configurepreviewplugindialog.cpp
settings/general/contextmenusettingspage.cpp
settings/general/generalsettingspage.cpp
settings/general/previewssettingspage.cpp
settings/navigation/navigationsettingspage.cpp
settings/services/servicessettingspage.cpp
settings/settingspagebase.cpp
+ settings/serviceitemdelegate.cpp
+ settings/servicemodel.cpp
settings/startup/startupsettingspage.cpp
settings/trash/trashsettingspage.cpp
settings/viewmodes/columnviewsettingspage.cpp
set(kcm_dolphinservices_PART_SRCS
settings/kcm/kcmdolphinservices.cpp
settings/services/servicessettingspage.cpp
- settings/settingspagebase.cpp)
+ settings/settingspagebase.cpp
+ settings/serviceitemdelegate.cpp
+ settings/servicemodel.cpp)
set(kcm_dolphingeneral_PART_SRCS
settings/kcm/kcmdolphingeneral.cpp
settings/general/behaviorsettingspage.cpp
settings/general/previewssettingspage.cpp
+ settings/general/configurepreviewplugindialog.cpp
settings/general/contextmenusettingspage.cpp
- settings/settingspagebase.cpp)
+ settings/settingspagebase.cpp
+ settings/serviceitemdelegate.cpp
+ settings/servicemodel.cpp)
kde4_add_kcfg_files(kcm_dolphinviewmodes_PART_SRCS
settings/dolphin_columnmodesettings.kcfgc
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com> *
+ * *
+ * 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 "configurepreviewplugindialog.h"
+
+#include <KLibrary>
+#include <KLocale>
+#include <KIO/NetAccess>
+#include <kio/thumbcreator.h>
+
+#include <QApplication>
+#include <QDir>
+#include <QVBoxLayout>
+
+ConfigurePreviewPluginDialog::ConfigurePreviewPluginDialog(const QString& pluginName,
+ const QString& desktopEntryName,
+ QWidget* parent) :
+ KDialog(parent),
+ m_configurationWidget(0),
+ m_previewPlugin(0)
+{
+ KLibrary library(desktopEntryName);
+ if (library.load()) {
+ newCreator create = (newCreator)library.resolveFunction("new_creator");
+ if (create) {
+ m_previewPlugin = dynamic_cast<ThumbCreatorV2*>(create());
+ }
+ }
+
+ setCaption(i18nc("@title:window", "Configure Preview for %1", pluginName));
+ setMinimumWidth(400);
+ setButtons(Ok | Cancel);
+ setDefaultButton(Ok);
+
+ QWidget* mainWidget = new QWidget(this);
+ mainWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
+ QVBoxLayout* layout = new QVBoxLayout(mainWidget);
+ if (m_previewPlugin) {
+ m_configurationWidget = m_previewPlugin->createConfigurationWidget();
+ layout->addWidget(m_configurationWidget);
+ }
+ layout->addStretch(1);
+
+ setMainWidget(mainWidget);
+
+ connect(this, SIGNAL(okClicked()), this, SLOT(slotOk()));
+}
+
+ConfigurePreviewPluginDialog::~ConfigurePreviewPluginDialog()
+{
+}
+
+void ConfigurePreviewPluginDialog::slotOk()
+{
+ m_previewPlugin->writeConfiguration(m_configurationWidget);
+ // TODO: It would be great having a mechanism to tell PreviewJob that only previews
+ // for a specific MIME-type should be regenerated. As this is not available yet we
+ // delete the whole thumbnails directory.
+ QApplication::changeOverrideCursor(Qt::BusyCursor);
+ KIO::NetAccess::del(QDir::homePath() + "/.thumbnails/", this);
+ QApplication::restoreOverrideCursor();
+
+}
+
+#include "configurepreviewplugindialog.moc"
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com> *
+ * *
+ * 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 CONFIGUREPREVIEWPLUGINDIALOG_H
+#define CONFIGUREPREVIEWPLUGINDIALOG_H
+
+#include <KDialog>
+
+class ThumbCreatorV2;
+
+/**
+ * @brief Dialog for configuring preview-plugins.
+ */
+class ConfigurePreviewPluginDialog : public KDialog
+{
+ Q_OBJECT
+
+public:
+ /**
+ * @param pluginName User visible name of the plugin
+ * @param desktopEntryName The name of the plugin that is noted in the desktopentry.
+ * Is used to instantiate the plugin to get the configuration
+ * widget.
+ * @param parent Parent widget.
+ */
+ explicit ConfigurePreviewPluginDialog(const QString& pluginName,
+ const QString& desktopEntryName,
+ QWidget* parent = 0);
+ virtual ~ConfigurePreviewPluginDialog();
+
+private slots:
+ void slotOk();
+
+private:
+ QWidget* m_configurationWidget;
+ ThumbCreatorV2* m_previewPlugin;
+};
+
+#endif
#include "previewssettingspage.h"
#include "dolphin_generalsettings.h"
+#include "configurepreviewplugindialog.h"
#include <KConfigGroup>
#include <KDialog>
#include <KService>
#include <settings/dolphinsettings.h>
+#include <settings/serviceitemdelegate.h>
+#include <settings/servicemodel.h>
#include <QCheckBox>
#include <QGroupBox>
#include <QLabel>
-#include <QListWidget>
-#include <QRadioButton>
+#include <QListView>
+#include <QPainter>
+#include <QScrollBar>
#include <QShowEvent>
#include <QSlider>
+#include <QSortFilterProxyModel>
#include <QGridLayout>
+#include <QVBoxLayout>
// default settings
namespace {
PreviewsSettingsPage::PreviewsSettingsPage(QWidget* parent) :
SettingsPageBase(parent),
m_initialized(false),
- m_previewPluginsList(0),
+ m_listView(0),
m_enabledPreviewPlugins(),
m_localFileSizeBox(0),
m_remoteFileSizeBox(0)
// Create group box "Show previews for:"
QGroupBox* listBox = new QGroupBox(i18nc("@title:group", "Show previews for"), this);
- m_previewPluginsList = new QListWidget(this);
- m_previewPluginsList->setSortingEnabled(true);
- m_previewPluginsList->setSelectionMode(QAbstractItemView::NoSelection);
+ m_listView = new QListView(this);
+
+ ServiceItemDelegate* delegate = new ServiceItemDelegate(m_listView, m_listView);
+ connect(delegate, SIGNAL(requestServiceConfiguration(QModelIndex)),
+ this, SLOT(configureService(QModelIndex)));
+
+ ServiceModel* serviceModel = new ServiceModel(this);
+ QSortFilterProxyModel* proxyModel = new QSortFilterProxyModel(this);
+ proxyModel->setSourceModel(serviceModel);
+ proxyModel->setSortRole(Qt::DisplayRole);
+
+ m_listView->setModel(proxyModel);
+ m_listView->setItemDelegate(delegate);
+ m_listView->setVerticalScrollMode(QListView::ScrollPerPixel);
QVBoxLayout* listBoxLayout = new QVBoxLayout(listBox);
- listBoxLayout->addWidget(m_previewPluginsList);
+ listBoxLayout->addWidget(m_listView);
// Create group box "Don't create previews for"
QGroupBox* fileSizeBox = new QGroupBox(i18nc("@title:group", "Do not create previews for"), this);
loadSettings();
- connect(m_previewPluginsList, SIGNAL(itemClicked(QListWidgetItem*)), this, SIGNAL(changed()));
+ connect(m_listView, SIGNAL(clicked(QModelIndex)), this, SIGNAL(changed()));
connect(m_localFileSizeBox, SIGNAL(valueChanged(int)), this, SIGNAL(changed()));
connect(m_remoteFileSizeBox, SIGNAL(valueChanged(int)), this, SIGNAL(changed()));
}
-
PreviewsSettingsPage::~PreviewsSettingsPage()
{
}
void PreviewsSettingsPage::applySettings()
{
- const int count = m_previewPluginsList->count();
- if (count > 0) {
+ const QAbstractItemModel* model = m_listView->model();
+ const int rowCount = model->rowCount();
+ if (rowCount > 0) {
m_enabledPreviewPlugins.clear();
- for (int i = 0; i < count; ++i) {
- const QListWidgetItem* item = m_previewPluginsList->item(i);
- if (item->checkState() == Qt::Checked) {
- const QString enabledPlugin = item->data(Qt::UserRole).toString();
+ for (int i = 0; i < rowCount; ++i) {
+ const QModelIndex index = model->index(i, 0);
+ const bool checked = model->data(index, Qt::CheckStateRole).toBool();
+ if (checked) {
+ const QString enabledPlugin = model->data(index, Qt::UserRole).toString();
m_enabledPreviewPlugins.append(enabledPlugin);
}
}
void PreviewsSettingsPage::showEvent(QShowEvent* event)
{
if (!event->spontaneous() && !m_initialized) {
- QMetaObject::invokeMethod(this, "loadPreviewPlugins", Qt::QueuedConnection);
+ loadPreviewPlugins();
m_initialized = true;
}
SettingsPageBase::showEvent(event);
}
+void PreviewsSettingsPage::configureService(const QModelIndex& index)
+{
+ const QAbstractItemModel* model = index.model();
+ const QString pluginName = model->data(index).toString();
+ const QString desktopEntryName = model->data(index, ServiceModel::DesktopEntryNameRole).toString();
+
+ ConfigurePreviewPluginDialog* dialog = new ConfigurePreviewPluginDialog(pluginName, desktopEntryName, this);
+ dialog->setAttribute(Qt::WA_DeleteOnClose);
+ dialog->show();
+}
+
void PreviewsSettingsPage::loadPreviewPlugins()
{
+ QAbstractItemModel* model = m_listView->model();
+
const KService::List plugins = KServiceTypeTrader::self()->query(QLatin1String("ThumbCreator"));
foreach (const KSharedPtr<KService>& service, plugins) {
- QListWidgetItem* item = new QListWidgetItem(service->name(),
- m_previewPluginsList);
- item->setData(Qt::UserRole, service->desktopEntryName());
+ const bool configurable = service->property("Configurable", QVariant::Bool).toBool();
const bool show = m_enabledPreviewPlugins.contains(service->desktopEntryName());
- item->setCheckState(show ? Qt::Checked : Qt::Unchecked);
+ if (service->desktopEntryName() == QLatin1String("jpegrotatedthumbnail")) {
+ // Before KDE SC 4.7 thumbnail plugins where not configurable and in addition to
+ // the jpegthumbnail-plugin a jpegrotatedthumbnail-plugin was offered. Make this
+ // plugin obsolete for users that updated from a previous KDE SC version:
+ if (show) {
+ m_enabledPreviewPlugins.removeOne(service->desktopEntryName());
+ KConfigGroup globalConfig(KGlobal::config(), QLatin1String("PreviewSettings"));
+ globalConfig.writeEntry("Plugins", m_enabledPreviewPlugins);
+ globalConfig.sync();
+ }
+ continue;
+ }
+
+ model->insertRow(0);
+ const QModelIndex index = model->index(0, 0);
+ model->setData(index, show, Qt::CheckStateRole);
+ model->setData(index, configurable, ServiceModel::ConfigurableRole);
+ model->setData(index, service->name(), Qt::DisplayRole);
+ model->setData(index, service->desktopEntryName(), ServiceModel::DesktopEntryNameRole);
}
+
+ model->sort(Qt::DisplayRole);
}
void PreviewsSettingsPage::loadSettings()
m_enabledPreviewPlugins = globalConfig.readEntry("Plugins", QStringList()
<< QLatin1String("directorythumbnail")
<< QLatin1String("imagethumbnail")
- << QLatin1String("jpegrotatedthumbnail"));
+ << QLatin1String("jpegthumbnail"));
const int maxLocalByteSize = globalConfig.readEntry("MaximumSize", MaxLocalPreviewSize * 1024 * 1024);
const int maxLocalMByteSize = maxLocalByteSize / (1024 * 1024);
#include <settings/settingspagebase.h>
-class QListWidget;
class KIntSpinBox;
+class QListView;
+class QModelIndex;
/**
* @brief Allows the configuration of file previews.
virtual void showEvent(QShowEvent* event);
private slots:
- void loadPreviewPlugins();
+ void configureService(const QModelIndex& index);
private:
+ void loadPreviewPlugins();
void loadSettings();
private:
bool m_initialized;
- QListWidget* m_previewPluginsList;
+ QListView *m_listView;
QStringList m_enabledPreviewPlugins;
KIntSpinBox* m_localFileSizeBox;
KIntSpinBox* m_remoteFileSizeBox;
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com> *
+ * *
+ * 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 "serviceitemdelegate.h"
+
+#include <KDebug>
+#include <KPushButton>
+
+#include "servicemodel.h"
+
+#include <QAbstractItemView>
+#include <QCheckBox>
+#include <QModelIndex>
+#include <QPainter>
+
+ServiceItemDelegate::ServiceItemDelegate(QAbstractItemView* itemView, QObject* parent) :
+ KWidgetItemDelegate(itemView, parent)
+{
+}
+
+ServiceItemDelegate::~ServiceItemDelegate()
+{
+}
+
+QSize ServiceItemDelegate::sizeHint(const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ Q_UNUSED(index);
+
+ const QStyle *style = itemView()->style();
+ const int buttonHeight = style->pixelMetric(QStyle::PM_ButtonMargin) * 2 +
+ style->pixelMetric(QStyle::PM_ButtonIconSize);
+ const int fontHeight = option.fontMetrics.height();
+ return QSize(100, qMax(buttonHeight, fontHeight));
+}
+
+void ServiceItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option,
+ const QModelIndex& index) const
+{
+ Q_UNUSED(index);
+ painter->save();
+
+ itemView()->style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter);
+
+ if (option.state & QStyle::State_Selected) {
+ painter->setPen(option.palette.highlightedText().color());
+ }
+
+ painter->restore();
+}
+
+QList<QWidget*> ServiceItemDelegate::createItemWidgets() const
+{
+ QCheckBox* checkBox = new QCheckBox();
+ connect(checkBox, SIGNAL(clicked(bool)), this, SLOT(slotCheckBoxClicked(bool)));
+
+ KPushButton* configureButton = new KPushButton();
+ connect(configureButton, SIGNAL(clicked()), this, SLOT(slotConfigureButtonClicked()));
+
+ return QList<QWidget*>() << checkBox << configureButton;
+}
+
+void ServiceItemDelegate::updateItemWidgets(const QList<QWidget*> widgets,
+ const QStyleOptionViewItem& option,
+ const QPersistentModelIndex& index) const
+{
+ QCheckBox* checkBox = static_cast<QCheckBox*>(widgets[0]);
+ KPushButton *configureButton = static_cast<KPushButton*>(widgets[1]);
+
+ const int itemHeight = sizeHint(option, index).height();
+
+ // Update the checkbox showing the service name and icon
+ const QAbstractItemModel* model = index.model();
+ checkBox->setText(model->data(index).toString());
+ const QString iconName = model->data(index, Qt::DecorationRole).toString();
+ if (!iconName.isEmpty()) {
+ checkBox->setIcon(KIcon(iconName));
+ }
+ checkBox->setChecked(model->data(index, Qt::CheckStateRole).toBool());
+
+ const bool configurable = model->data(index, ServiceModel::ConfigurableRole).toBool();
+
+ int checkBoxWidth = option.rect.width();
+ if (configurable) {
+ checkBoxWidth -= configureButton->sizeHint().width();
+ }
+ checkBox->resize(checkBoxWidth, checkBox->sizeHint().height());
+ checkBox->move(0, (itemHeight - checkBox->height()) / 2);
+
+ // Update the configuration button
+ if (configurable) {
+ configureButton->setEnabled(checkBox->isChecked());
+ configureButton->setIcon(KIcon("configure"));
+ configureButton->resize(configureButton->sizeHint());
+ configureButton->move(option.rect.right() - configureButton->width(),
+ (itemHeight - configureButton->height()) / 2);
+ }
+ configureButton->setVisible(configurable);
+}
+
+void ServiceItemDelegate::slotCheckBoxClicked(bool checked)
+{
+ QAbstractItemModel* model = const_cast<QAbstractItemModel*>(focusedIndex().model());
+ model->setData(focusedIndex(), checked, Qt::CheckStateRole);
+}
+
+void ServiceItemDelegate::slotConfigureButtonClicked()
+{
+ emit requestServiceConfiguration(focusedIndex());
+}
+
+#include "serviceitemdelegate.moc"
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com> *
+ * *
+ * 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 SERVICEITEMDELEGATE_H
+#define SERVICEITEMDELEGATE_H
+
+#include <KWidgetItemDelegate>
+
+/**
+ * @brief Widget item delegate for a service that can be enabled or disabled.
+ *
+ * Additionally it is possible to configure a service.
+ * @see ServiceModel
+ */
+class ServiceItemDelegate : public KWidgetItemDelegate
+{
+ Q_OBJECT
+
+public:
+ explicit ServiceItemDelegate(QAbstractItemView* itemView, QObject* parent = 0);
+ virtual ~ServiceItemDelegate();
+
+ virtual QSize sizeHint(const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+
+ virtual void paint(QPainter* painter, const QStyleOptionViewItem& option,
+ const QModelIndex& index) const;
+
+ virtual QList<QWidget*> createItemWidgets() const;
+
+ virtual void updateItemWidgets(const QList<QWidget*> widgets,
+ const QStyleOptionViewItem& option,
+ const QPersistentModelIndex& index) const;
+
+signals:
+ void requestServiceConfiguration(const QModelIndex& index);
+
+private slots:
+ void slotCheckBoxClicked(bool checked);
+ void slotConfigureButtonClicked();
+};
+
+#endif
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com> *
+ * *
+ * 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 "servicemodel.h"
+
+ServiceModel::ServiceModel(QObject* parent) :
+ QAbstractListModel(parent),
+ m_items()
+{
+}
+
+ServiceModel::~ServiceModel()
+{
+}
+
+bool ServiceModel::insertRows(int row, int count, const QModelIndex& parent)
+{
+ if (row > rowCount()) {
+ return false;
+ }
+
+ if (count <= 0) {
+ count = 1;
+ }
+
+ beginInsertRows(parent, row, row + count - 1);
+ for (int i = 0; i < count; ++i) {
+ ServiceItem item;
+ item.checked = false;
+ item.configurable = false;
+ m_items.insert(row, item);
+ }
+ endInsertRows();
+
+ return true;
+}
+
+bool ServiceModel::setData(const QModelIndex& index, const QVariant& value, int role)
+{
+ const int row = index.row();
+ if (row >= rowCount()) {
+ return false;
+ }
+
+ switch (role) {
+ case Qt::CheckStateRole:
+ m_items[row].checked = value.toBool();
+ break;
+ case ConfigurableRole:
+ m_items[row].configurable = value.toBool();
+ break;
+ case Qt::DecorationRole:
+ m_items[row].icon = value.toString();
+ break;
+ case Qt::DisplayRole:
+ m_items[row].text = value.toString();
+ break;
+ case DesktopEntryNameRole:
+ m_items[row].desktopEntryName = value.toString();
+ break;
+ default:
+ return false;
+ }
+
+ emit dataChanged(index, index);
+ return true;
+}
+
+QVariant ServiceModel::data(const QModelIndex& index, int role) const
+{
+ const int row = index.row();
+ if (row < rowCount()) {
+ switch (role) {
+ case ConfigurableRole: return m_items[row].configurable;
+ case Qt::CheckStateRole: return m_items[row].checked;
+ case Qt::DecorationRole: return m_items[row].icon;
+ case Qt::DisplayRole: return m_items[row].text;
+ case DesktopEntryNameRole: return m_items[row].desktopEntryName;
+ default: break;
+ }
+ }
+
+ return QVariant();
+}
+
+int ServiceModel::rowCount(const QModelIndex& parent) const
+{
+ Q_UNUSED(parent);
+ return m_items.count();
+}
+
+#include "servicemodel.moc"
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com> *
+ * *
+ * 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 SERVICEMODEL_H
+#define SERVICEMODEL_H
+
+#include <QAbstractListModel>
+#include <QList>
+
+/**
+ * @brief Provides a simple model for enabling/disabling services
+ *
+ * The following roles are supported:
+ * - Qt::DisplayRole: Name of the service
+ * - Qt::DecorationRole: Icon name of the service
+ * - Qt::CheckStateRole: Specifies whether the service is enabled
+ * - ServiceModel::DesktopEntryNameRole: Name of the desktop-entry of the service
+ * - ServiceModel::Configurable: Specifies whether the service is configurable by the user
+ */
+class ServiceModel : public QAbstractListModel
+{
+ Q_OBJECT
+
+public:
+ enum Role
+ {
+ DesktopEntryNameRole = Qt::UserRole,
+ ConfigurableRole
+ };
+
+ explicit ServiceModel(QObject* parent = 0);
+ virtual ~ServiceModel();
+
+ virtual bool insertRows(int row, int count, const QModelIndex & parent = QModelIndex());
+ 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 int rowCount(const QModelIndex& parent = QModelIndex()) const;
+
+ private:
+ struct ServiceItem
+ {
+ bool checked;
+ bool configurable;
+ QString icon;
+ QString text;
+ QString desktopEntryName;
+ };
+
+ QList<ServiceItem> m_items;
+};
+
+#endif
#include <KServiceTypeTrader>
#include <KStandardDirs>
+#include <settings/serviceitemdelegate.h>
+#include <settings/servicemodel.h>
+
#include <QCheckBox>
#include <QGridLayout>
#include <QGroupBox>
#include <QLabel>
#include <QListWidget>
#include <QPushButton>
+#include <QSortFilterProxyModel>
#include <QShowEvent>
ServicesSettingsPage::ServicesSettingsPage(QWidget* parent) :
SettingsPageBase(parent),
m_initialized(false),
- m_servicesList(0),
+ m_listView(0),
m_vcsGroupBox(0),
m_vcsPluginsMap(),
m_enabledVcsPlugins()
"be shown in the context menu:"), this);
label->setWordWrap(true);
- m_servicesList = new QListWidget(this);
- m_servicesList->setSortingEnabled(true);
- m_servicesList->setSelectionMode(QAbstractItemView::NoSelection);
- connect(m_servicesList, SIGNAL(itemClicked(QListWidgetItem*)),
- this, SIGNAL(changed()));
+ m_listView = new QListView(this);
+ ServiceItemDelegate* delegate = new ServiceItemDelegate(m_listView, m_listView);
+ ServiceModel* serviceModel = new ServiceModel(this);
+ QSortFilterProxyModel* proxyModel = new QSortFilterProxyModel(this);
+ proxyModel->setSourceModel(serviceModel);
+ proxyModel->setSortRole(Qt::DisplayRole);
+ m_listView->setModel(proxyModel);
+ m_listView->setItemDelegate(delegate);
+ m_listView->setVerticalScrollMode(QListView::ScrollPerPixel);
+ connect(m_listView, SIGNAL(clicked(QModelIndex)), this, SIGNAL(changed()));
KNS3::Button* downloadButton = new KNS3::Button(i18nc("@action:button", "Download New Services..."),
"servicemenu.knsrc",
m_vcsGroupBox->hide();
topLayout->addWidget(label);
- topLayout->addWidget(m_servicesList);
+ topLayout->addWidget(m_listView);
topLayout->addWidget(downloadButton);
topLayout->addWidget(m_vcsGroupBox);
KConfig config("kservicemenurc", KConfig::NoGlobals);
KConfigGroup showGroup = config.group("Show");
- const int count = m_servicesList->count();
- for (int i = 0; i < count; ++i) {
- QListWidgetItem* item = m_servicesList->item(i);
- const bool show = (item->checkState() == Qt::Checked);
- const QString service = item->data(Qt::UserRole).toString();
+ const QAbstractItemModel* model = m_listView->model();
+ for (int i = 0; i < model->rowCount(); ++i) {
+ const QModelIndex index = model->index(i, 0);
+ const bool show = model->data(index, Qt::CheckStateRole).toBool();
+ const QString service = model->data(index, ServiceModel::DesktopEntryNameRole).toString();
showGroup.writeEntry(service, show);
}
void ServicesSettingsPage::restoreDefaults()
{
- const int count = m_servicesList->count();
- for (int i = 0; i < count; ++i) {
- QListWidgetItem* item = m_servicesList->item(i);
- item->setCheckState(Qt::Checked);
+ QAbstractItemModel* model = m_listView->model();
+ for (int i = 0; i < model->rowCount(); ++i) {
+ const QModelIndex index = model->index(i, 0);
+ model->setData(index, true, Qt::CheckStateRole);
}
}
void ServicesSettingsPage::showEvent(QShowEvent* event)
{
if (!event->spontaneous() && !m_initialized) {
- QMetaObject::invokeMethod(this, "loadServices", Qt::QueuedConnection);
- QMetaObject::invokeMethod(this, "loadVersionControlSystems", Qt::QueuedConnection);
+ loadServices();
+ loadVersionControlSystems();
m_initialized = true;
}
SettingsPageBase::showEvent(event);
void ServicesSettingsPage::loadServices()
{
+ QAbstractItemModel* model = m_listView->model();
+
const KConfig config("kservicemenurc", KConfig::NoGlobals);
const KConfigGroup showGroup = config.group("Show");
const QString itemName = subMenuName.isEmpty()
? action.text()
: i18nc("@item:inmenu", "%1: %2", subMenuName, action.text());
- QListWidgetItem* item = new QListWidgetItem(KIcon(action.icon()),
- itemName,
- m_servicesList);
- item->setData(Qt::UserRole, serviceName);
const bool show = showGroup.readEntry(serviceName, true);
- item->setCheckState(show ? Qt::Checked : Qt::Unchecked);
+
+ model->insertRow(0);
+ const QModelIndex index = model->index(0, 0);
+ model->setData(index, action.icon(), Qt::DecorationRole);
+ model->setData(index, show, Qt::CheckStateRole);
+ model->setData(index, itemName, Qt::DisplayRole);
+ model->setData(index, serviceName, ServiceModel::DesktopEntryNameRole);
}
}
}
// Load service plugins that implement the KFileItemActionPlugin interface
const KService::List pluginServices = KServiceTypeTrader::self()->query("KFileItemAction/Plugin");
foreach (const KSharedPtr<KService>& service, pluginServices) {
- const QString serviceName = service->desktopEntryName();
- if (!isInServicesList(serviceName)) {
- QListWidgetItem* item = new QListWidgetItem(KIcon(service->icon()),
- service->name(),
- m_servicesList);
- item->setData(Qt::UserRole, serviceName);
- const bool show = showGroup.readEntry(serviceName, true);
- item->setCheckState(show ? Qt::Checked : Qt::Unchecked);
+ const QString desktopEntryName = service->desktopEntryName();
+ if (!isInServicesList(desktopEntryName)) {
+ const bool show = showGroup.readEntry(desktopEntryName, true);
+
+ model->insertRow(0);
+ const QModelIndex index = model->index(0, 0);
+ model->setData(index, service->icon(), Qt::DecorationRole);
+ model->setData(index, show, Qt::CheckStateRole);
+ model->setData(index, service->name(), Qt::DisplayRole);
+ model->setData(index, desktopEntryName, ServiceModel::DesktopEntryNameRole);
}
}
+
+ model->sort(Qt::DisplayRole);
}
void ServicesSettingsPage::loadVersionControlSystems()
bool ServicesSettingsPage::isInServicesList(const QString& service) const
{
- const int count = m_servicesList->count();
- for (int i = 0; i < count; ++i) {
- QListWidgetItem* item = m_servicesList->item(i);
- if (item->data(Qt::UserRole).toString() == service) {
+ QAbstractItemModel* model = m_listView->model();
+ for (int i = 0; i < model->rowCount(); ++i) {
+ const QModelIndex index = model->index(i, 0);
+ if (model->data(index, ServiceModel::DesktopEntryNameRole).toString() == service) {
return true;
}
}
class QCheckBox;
class QGroupBox;
-class QListWidget;
+class QListView;
/**
* @brief Page for the 'Services' settings of the Dolphin settings dialog.
*/
void loadServices();
+private:
/**
* Loads installed version control systems.
*/
private:
bool m_initialized;
- QListWidget* m_servicesList;
+ QListView *m_listView;
QGroupBox* m_vcsGroupBox;
QMap<QString, QCheckBox*> m_vcsPluginsMap;
QStringList m_enabledVcsPlugins;