From: Peter Penz Date: Fri, 25 Feb 2011 19:39:18 +0000 (+0100) Subject: Allow to configure thumbnail-plugins X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/commitdiff_plain/1b2b63eb3a01025e03ff964f187adda52c62bcb3?ds=inline Allow to configure thumbnail-plugins 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. --- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 61caec60d..a06549593 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -116,6 +116,7 @@ set(dolphin_SRCS 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 @@ -124,6 +125,8 @@ set(dolphin_SRCS 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 @@ -210,14 +213,19 @@ set(kcm_dolphinnavigation_PART_SRCS 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 diff --git a/src/settings/general/configurepreviewplugindialog.cpp b/src/settings/general/configurepreviewplugindialog.cpp new file mode 100644 index 000000000..c1a507a65 --- /dev/null +++ b/src/settings/general/configurepreviewplugindialog.cpp @@ -0,0 +1,81 @@ +/*************************************************************************** + * Copyright (C) 2011 by Peter Penz * + * * + * 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 +#include +#include +#include + +#include +#include +#include + +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(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" diff --git a/src/settings/general/configurepreviewplugindialog.h b/src/settings/general/configurepreviewplugindialog.h new file mode 100644 index 000000000..5a3f5354a --- /dev/null +++ b/src/settings/general/configurepreviewplugindialog.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * Copyright (C) 2011 by Peter Penz * + * * + * 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 + +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 diff --git a/src/settings/general/previewssettingspage.cpp b/src/settings/general/previewssettingspage.cpp index 0836aef33..679494c67 100644 --- a/src/settings/general/previewssettingspage.cpp +++ b/src/settings/general/previewssettingspage.cpp @@ -20,6 +20,7 @@ #include "previewssettingspage.h" #include "dolphin_generalsettings.h" +#include "configurepreviewplugindialog.h" #include #include @@ -30,15 +31,20 @@ #include #include +#include +#include #include #include #include -#include -#include +#include +#include +#include #include #include +#include #include +#include // default settings namespace { @@ -50,7 +56,7 @@ namespace { PreviewsSettingsPage::PreviewsSettingsPage(QWidget* parent) : SettingsPageBase(parent), m_initialized(false), - m_previewPluginsList(0), + m_listView(0), m_enabledPreviewPlugins(), m_localFileSizeBox(0), m_remoteFileSizeBox(0) @@ -62,12 +68,23 @@ PreviewsSettingsPage::PreviewsSettingsPage(QWidget* parent) : // 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); @@ -99,25 +116,26 @@ PreviewsSettingsPage::PreviewsSettingsPage(QWidget* parent) : 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); } } @@ -144,22 +162,53 @@ void PreviewsSettingsPage::restoreDefaults() 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& 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() @@ -168,7 +217,7 @@ 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); diff --git a/src/settings/general/previewssettingspage.h b/src/settings/general/previewssettingspage.h index b14aa7ab4..ef3ad267e 100644 --- a/src/settings/general/previewssettingspage.h +++ b/src/settings/general/previewssettingspage.h @@ -22,8 +22,9 @@ #include -class QListWidget; class KIntSpinBox; +class QListView; +class QModelIndex; /** * @brief Allows the configuration of file previews. @@ -50,14 +51,15 @@ protected: 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; diff --git a/src/settings/serviceitemdelegate.cpp b/src/settings/serviceitemdelegate.cpp new file mode 100644 index 000000000..3dc314631 --- /dev/null +++ b/src/settings/serviceitemdelegate.cpp @@ -0,0 +1,128 @@ +/*************************************************************************** + * Copyright (C) 2011 by Peter Penz * + * * + * 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 +#include + +#include "servicemodel.h" + +#include +#include +#include +#include + +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 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() << checkBox << configureButton; +} + +void ServiceItemDelegate::updateItemWidgets(const QList widgets, + const QStyleOptionViewItem& option, + const QPersistentModelIndex& index) const +{ + QCheckBox* checkBox = static_cast(widgets[0]); + KPushButton *configureButton = static_cast(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(focusedIndex().model()); + model->setData(focusedIndex(), checked, Qt::CheckStateRole); +} + +void ServiceItemDelegate::slotConfigureButtonClicked() +{ + emit requestServiceConfiguration(focusedIndex()); +} + +#include "serviceitemdelegate.moc" diff --git a/src/settings/serviceitemdelegate.h b/src/settings/serviceitemdelegate.h new file mode 100644 index 000000000..ea9681a5a --- /dev/null +++ b/src/settings/serviceitemdelegate.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright (C) 2011 by Peter Penz * + * * + * 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 + +/** + * @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 createItemWidgets() const; + + virtual void updateItemWidgets(const QList widgets, + const QStyleOptionViewItem& option, + const QPersistentModelIndex& index) const; + +signals: + void requestServiceConfiguration(const QModelIndex& index); + +private slots: + void slotCheckBoxClicked(bool checked); + void slotConfigureButtonClicked(); +}; + +#endif diff --git a/src/settings/servicemodel.cpp b/src/settings/servicemodel.cpp new file mode 100644 index 000000000..315b90dff --- /dev/null +++ b/src/settings/servicemodel.cpp @@ -0,0 +1,108 @@ +/*************************************************************************** + * Copyright (C) 2011 by Peter Penz * + * * + * 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" diff --git a/src/settings/servicemodel.h b/src/settings/servicemodel.h new file mode 100644 index 000000000..b8c2d5248 --- /dev/null +++ b/src/settings/servicemodel.h @@ -0,0 +1,68 @@ +/*************************************************************************** + * Copyright (C) 2011 by Peter Penz * + * * + * 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 +#include + +/** + * @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 m_items; +}; + +#endif diff --git a/src/settings/services/servicessettingspage.cpp b/src/settings/services/servicessettingspage.cpp index 21eba8d86..fbddbbfa7 100644 --- a/src/settings/services/servicessettingspage.cpp +++ b/src/settings/services/servicessettingspage.cpp @@ -33,18 +33,22 @@ #include #include +#include +#include + #include #include #include #include #include #include +#include #include ServicesSettingsPage::ServicesSettingsPage(QWidget* parent) : SettingsPageBase(parent), m_initialized(false), - m_servicesList(0), + m_listView(0), m_vcsGroupBox(0), m_vcsPluginsMap(), m_enabledVcsPlugins() @@ -56,11 +60,16 @@ ServicesSettingsPage::ServicesSettingsPage(QWidget* parent) : "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", @@ -73,7 +82,7 @@ ServicesSettingsPage::ServicesSettingsPage(QWidget* parent) : m_vcsGroupBox->hide(); topLayout->addWidget(label); - topLayout->addWidget(m_servicesList); + topLayout->addWidget(m_listView); topLayout->addWidget(downloadButton); topLayout->addWidget(m_vcsGroupBox); @@ -94,11 +103,11 @@ void ServicesSettingsPage::applySettings() 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); } @@ -128,18 +137,18 @@ void ServicesSettingsPage::applySettings() 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); @@ -147,6 +156,8 @@ void ServicesSettingsPage::showEvent(QShowEvent* event) void ServicesSettingsPage::loadServices() { + QAbstractItemModel* model = m_listView->model(); + const KConfig config("kservicemenurc", KConfig::NoGlobals); const KConfigGroup showGroup = config.group("Show"); @@ -170,12 +181,14 @@ void ServicesSettingsPage::loadServices() 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); } } } @@ -183,16 +196,20 @@ void ServicesSettingsPage::loadServices() // Load service plugins that implement the KFileItemActionPlugin interface const KService::List pluginServices = KServiceTypeTrader::self()->query("KFileItemAction/Plugin"); foreach (const KSharedPtr& 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() @@ -228,10 +245,10 @@ 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; } } diff --git a/src/settings/services/servicessettingspage.h b/src/settings/services/servicessettingspage.h index be5953c64..d2eecaefe 100644 --- a/src/settings/services/servicessettingspage.h +++ b/src/settings/services/servicessettingspage.h @@ -26,7 +26,7 @@ class QCheckBox; class QGroupBox; -class QListWidget; +class QListView; /** * @brief Page for the 'Services' settings of the Dolphin settings dialog. @@ -54,6 +54,7 @@ private slots: */ void loadServices(); +private: /** * Loads installed version control systems. */ @@ -63,7 +64,7 @@ private slots: private: bool m_initialized; - QListWidget* m_servicesList; + QListView *m_listView; QGroupBox* m_vcsGroupBox; QMap m_vcsPluginsMap; QStringList m_enabledVcsPlugins;