Prepare view-engine for non-KFileItem usecase

Up to now the view-engine only provided a model-implementation that
supports file-items. The view-engine always had been designed to be able
to work with any kind of model, so now a KStandardItemModel is available.
The plan is to convert the places panel to the new view-engine. It should
be no problem to fix this until the feature freeze - in the worst case
the places-panel code could be reverted while still keeping the
KStandardItemModel changes.
This commit is contained in:
Peter Penz 2012-04-21 21:28:16 +02:00
parent 8426b7846f
commit 2069c20021
41 changed files with 2969 additions and 2142 deletions

View file

@ -32,6 +32,10 @@ set(dolphinprivate_LIB_SRCS
kitemviews/kitemlistview.cpp
kitemviews/kitemlistwidget.cpp
kitemviews/kitemmodelbase.cpp
kitemviews/kstandarditem.cpp
kitemviews/kstandarditemlistview.cpp
kitemviews/kstandarditemlistwidget.cpp
kitemviews/kstandarditemmodel.cpp
kitemviews/private/kfileitemclipboard.cpp
kitemviews/private/kfileitemmodeldirlister.cpp
kitemviews/private/kfileitemmodelsortalgorithm.cpp
@ -52,7 +56,7 @@ set(dolphinprivate_LIB_SRCS
settings/viewpropertiesdialog.cpp
settings/viewpropsprogressinfo.cpp
views/dolphinfileitemlistwidget.cpp
views/dolphinitemlistcontainer.cpp
views/dolphinitemlistview.cpp
views/dolphinnewfilemenuobserver.cpp
views/dolphinplacesmodel.cpp
views/dolphinremoteencoding.cpp

View file

@ -1847,17 +1847,17 @@ void DolphinMainWindow::setupDockWidgets()
QList<QAction*> placesActions;
placesActions.append(separator);
placesActions.append(lockLayoutAction);
placesPanel->addActions(placesActions);
placesPanel->setModel(DolphinPlacesModel::instance());
placesPanel->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
//placesPanel->addActions(placesActions);
//placesPanel->setModel(DolphinPlacesModel::instance());
//placesPanel->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
placesDock->setWidget(placesPanel);
QAction* placesAction = placesDock->toggleViewAction();
createPanelAction(KIcon("bookmarks"), Qt::Key_F9, placesAction, "show_places_panel");
addDockWidget(Qt::LeftDockWidgetArea, placesDock);
connect(placesPanel, SIGNAL(urlChanged(KUrl,Qt::MouseButtons)),
this, SLOT(handlePlacesClick(KUrl,Qt::MouseButtons)));
//connect(placesPanel, SIGNAL(urlChanged(KUrl,Qt::MouseButtons)),
// this, SLOT(handlePlacesClick(KUrl,Qt::MouseButtons)));
connect(this, SIGNAL(urlChanged(KUrl)),
placesPanel, SLOT(setUrl(KUrl)));
connect(placesDock, SIGNAL(visibilityChanged(bool)),

View file

@ -43,8 +43,7 @@ namespace {
}
KFileItemListView::KFileItemListView(QGraphicsWidget* parent) :
KItemListView(parent),
m_itemLayout(IconsLayout),
KStandardItemListView(parent),
m_modelRolesUpdater(0),
m_updateVisibleIndexRangeTimer(0),
m_updateIconSizeTimer(0)
@ -52,8 +51,6 @@ KFileItemListView::KFileItemListView(QGraphicsWidget* parent) :
setAcceptDrops(true);
setScrollOrientation(Qt::Vertical);
setWidgetCreator(new KItemListWidgetCreator<KFileItemListWidget>());
setGroupHeaderCreator(new KItemListGroupHeaderCreator<KFileItemListGroupHeader>());
m_updateVisibleIndexRangeTimer = new QTimer(this);
m_updateVisibleIndexRangeTimer->setSingleShot(true);
@ -65,25 +62,26 @@ KFileItemListView::KFileItemListView(QGraphicsWidget* parent) :
m_updateIconSizeTimer->setInterval(ShortInterval);
connect(m_updateIconSizeTimer, SIGNAL(timeout()), this, SLOT(updateIconSize()));
setVisibleRoles(QList<QByteArray>() << "name");
setVisibleRoles(QList<QByteArray>() << "text");
}
KFileItemListView::~KFileItemListView()
{
// The group headers are children of the widgets created by
// widgetCreator(). So it is mandatory to delete the group headers
// first.
delete groupHeaderCreator();
delete widgetCreator();
delete m_modelRolesUpdater;
m_modelRolesUpdater = 0;
}
void KFileItemListView::setPreviewsShown(bool show)
{
if (m_modelRolesUpdater) {
if (!m_modelRolesUpdater) {
return;
}
if (m_modelRolesUpdater->previewsShown() != show) {
beginTransaction();
m_modelRolesUpdater->setPreviewsShown(show);
onPreviewsShownChanged(show);
endTransaction();
}
}
@ -104,26 +102,6 @@ bool KFileItemListView::enlargeSmallPreviews() const
return m_modelRolesUpdater ? m_modelRolesUpdater->enlargeSmallPreviews() : false;
}
void KFileItemListView::setItemLayout(Layout layout)
{
if (m_itemLayout != layout) {
const bool updateRoles = (m_itemLayout == DetailsLayout || layout == DetailsLayout);
m_itemLayout = layout;
if (updateRoles) {
// The details-layout requires some invisible roles that
// must be added to the model if the new layout is "details".
// If the old layout was "details" the roles will get removed.
applyRolesToModel();
}
updateLayoutOfVisibleItems();
}
}
KFileItemListView::Layout KFileItemListView::itemLayout() const
{
return m_itemLayout;
}
void KFileItemListView::setEnabledPlugins(const QStringList& list)
{
if (m_modelRolesUpdater) {
@ -207,52 +185,53 @@ QPixmap KFileItemListView::createDragPixmap(const QSet<int>& indexes) const
return dragPixmap;
}
void KFileItemListView::initializeItemListWidget(KItemListWidget* item)
KItemListWidgetCreatorBase* KFileItemListView::defaultWidgetCreator() const
{
KFileItemListWidget* fileItemListWidget = static_cast<KFileItemListWidget*>(item);
switch (m_itemLayout) {
case IconsLayout: fileItemListWidget->setLayout(KFileItemListWidget::IconsLayout); break;
case CompactLayout: fileItemListWidget->setLayout(KFileItemListWidget::CompactLayout); break;
case DetailsLayout: fileItemListWidget->setLayout(KFileItemListWidget::DetailsLayout); break;
default: Q_ASSERT(false); break;
}
fileItemListWidget->setSupportsItemExpanding(supportsItemExpanding());
return new KItemListWidgetCreator<KFileItemListWidget>();
}
bool KFileItemListView::itemSizeHintUpdateRequired(const QSet<QByteArray>& changedRoles) const
KItemListGroupHeaderCreatorBase* KFileItemListView::defaultGroupHeaderCreator() const
{
// Even if the icons have a different size they are always aligned within
// the area defined by KItemStyleOption.iconSize and hence result in no
// change of the item-size.
const bool containsIconName = changedRoles.contains("iconName");
const bool containsIconPixmap = changedRoles.contains("iconPixmap");
const int count = changedRoles.count();
return new KItemListGroupHeaderCreator<KFileItemListGroupHeader>();
}
const bool iconChanged = (containsIconName && containsIconPixmap && count == 2) ||
(containsIconName && count == 1) ||
(containsIconPixmap && count == 1);
return !iconChanged;
void KFileItemListView::onPreviewsShownChanged(bool shown)
{
Q_UNUSED(shown);
}
void KFileItemListView::onItemLayoutChanged(ItemLayout current, ItemLayout previous)
{
if (previous == DetailsLayout || current == DetailsLayout) {
// The details-layout requires some invisible roles that
// must be added to the model if the new layout is "details".
// If the old layout was "details" the roles will get removed.
applyRolesToModel();
}
KStandardItemListView::onItemLayoutChanged(current, previous);
triggerVisibleIndexRangeUpdate();
}
void KFileItemListView::onModelChanged(KItemModelBase* current, KItemModelBase* previous)
{
Q_UNUSED(previous);
Q_ASSERT(qobject_cast<KFileItemModel*>(current));
KStandardItemListView::onModelChanged(current, previous);
delete m_modelRolesUpdater;
m_modelRolesUpdater = new KFileItemModelRolesUpdater(static_cast<KFileItemModel*>(current), this);
m_modelRolesUpdater->setIconSize(availableIconSize());
m_modelRolesUpdater = 0;
applyRolesToModel();
if (current) {
m_modelRolesUpdater = new KFileItemModelRolesUpdater(static_cast<KFileItemModel*>(current), this);
m_modelRolesUpdater->setIconSize(availableIconSize());
applyRolesToModel();
}
}
void KFileItemListView::onScrollOrientationChanged(Qt::Orientation current, Qt::Orientation previous)
{
Q_UNUSED(current);
Q_UNUSED(previous);
updateLayoutOfVisibleItems();
KStandardItemListView::onScrollOrientationChanged(current, previous);
triggerVisibleIndexRangeUpdate();
}
void KFileItemListView::onItemSizeChanged(const QSizeF& current, const QSizeF& previous)
@ -264,39 +243,42 @@ void KFileItemListView::onItemSizeChanged(const QSizeF& current, const QSizeF& p
void KFileItemListView::onScrollOffsetChanged(qreal current, qreal previous)
{
Q_UNUSED(current);
Q_UNUSED(previous);
KStandardItemListView::onScrollOffsetChanged(current, previous);
triggerVisibleIndexRangeUpdate();
}
void KFileItemListView::onVisibleRolesChanged(const QList<QByteArray>& current, const QList<QByteArray>& previous)
{
Q_UNUSED(current);
Q_UNUSED(previous);
KStandardItemListView::onVisibleRolesChanged(current, previous);
applyRolesToModel();
}
void KFileItemListView::onStyleOptionChanged(const KItemListStyleOption& current, const KItemListStyleOption& previous)
{
Q_UNUSED(current);
Q_UNUSED(previous);
KStandardItemListView::onStyleOptionChanged(current, previous);
triggerIconSizeUpdate();
}
void KFileItemListView::onSupportsItemExpandingChanged(bool supportsExpanding)
{
Q_UNUSED(supportsExpanding);
applyRolesToModel();
updateLayoutOfVisibleItems();
KStandardItemListView::onSupportsItemExpandingChanged(supportsExpanding);
triggerVisibleIndexRangeUpdate();
}
void KFileItemListView::onTransactionBegin()
{
m_modelRolesUpdater->setPaused(true);
if (m_modelRolesUpdater) {
m_modelRolesUpdater->setPaused(true);
}
}
void KFileItemListView::onTransactionEnd()
{
if (!m_modelRolesUpdater) {
return;
}
// Only unpause the model-roles-updater if no timer is active. If one
// timer is still active the model-roles-updater will be unpaused later as
// soon as the timer has been exceeded.
@ -309,13 +291,13 @@ void KFileItemListView::onTransactionEnd()
void KFileItemListView::resizeEvent(QGraphicsSceneResizeEvent* event)
{
KItemListView::resizeEvent(event);
KStandardItemListView::resizeEvent(event);
triggerVisibleIndexRangeUpdate();
}
void KFileItemListView::slotItemsRemoved(const KItemRangeList& itemRanges)
{
KItemListView::slotItemsRemoved(itemRanges);
KStandardItemListView::slotItemsRemoved(itemRanges);
updateTimersInterval();
}
@ -326,7 +308,7 @@ void KFileItemListView::slotSortRoleChanged(const QByteArray& current, const QBy
applyRolesToModel();
}
KItemListView::slotSortRoleChanged(current, previous);
KStandardItemListView::slotSortRoleChanged(current, previous);
}
void KFileItemListView::triggerVisibleIndexRangeUpdate()
@ -391,18 +373,6 @@ void KFileItemListView::updateIconSize()
updateTimersInterval();
}
void KFileItemListView::updateLayoutOfVisibleItems()
{
if (!model()) {
return;
}
foreach (KItemListWidget* widget, visibleItemListWidgets()) {
initializeItemListWidget(widget);
}
triggerVisibleIndexRangeUpdate();
}
void KFileItemListView::updateTimersInterval()
{
if (!model()) {
@ -434,7 +404,7 @@ void KFileItemListView::applyRolesToModel()
QSet<QByteArray> roles = visibleRoles().toSet();
roles.insert("iconPixmap");
roles.insert("iconName");
roles.insert("name");
roles.insert("text");
roles.insert("isDir");
if (supportsItemExpanding()) {
roles.insert("isExpanded");
@ -453,7 +423,7 @@ QSize KFileItemListView::availableIconSize() const
{
const KItemListStyleOption& option = styleOption();
const int iconSize = option.iconSize;
if (m_itemLayout == IconsLayout) {
if (itemLayout() == IconsLayout) {
const int maxIconWidth = itemSize().width() - 2 * option.padding;
return QSize(maxIconWidth, iconSize);
}

View file

@ -22,7 +22,7 @@
#include <libdolphin_export.h>
#include <kitemviews/kitemlistview.h>
#include <kitemviews/kstandarditemlistview.h>
class KFileItemModelRolesUpdater;
class QTimer;
@ -36,18 +36,11 @@ class QTimer;
* KItemListView::setWidgetCreator() and KItemListView::setGroupHeaderCreator()
* to apply customized generators.
*/
class LIBDOLPHINPRIVATE_EXPORT KFileItemListView : public KItemListView
class LIBDOLPHINPRIVATE_EXPORT KFileItemListView : public KStandardItemListView
{
Q_OBJECT
public:
enum Layout
{
IconsLayout,
CompactLayout,
DetailsLayout
};
KFileItemListView(QGraphicsWidget* parent = 0);
virtual ~KFileItemListView();
@ -62,9 +55,6 @@ public:
void setEnlargeSmallPreviews(bool enlarge);
bool enlargeSmallPreviews() const;
void setItemLayout(Layout layout);
Layout itemLayout() const;
/**
* Sets the list of enabled thumbnail plugins that are used for previews.
* Per default all plugins enabled in the KConfigGroup "PreviewSettings"
@ -86,8 +76,10 @@ public:
virtual QPixmap createDragPixmap(const QSet<int>& indexes) const;
protected:
virtual void initializeItemListWidget(KItemListWidget* item);
virtual bool itemSizeHintUpdateRequired(const QSet<QByteArray>& changedRoles) const;
virtual KItemListWidgetCreatorBase* defaultWidgetCreator() const;
virtual KItemListGroupHeaderCreatorBase* defaultGroupHeaderCreator() const;
virtual void onPreviewsShownChanged(bool shown);
virtual void onItemLayoutChanged(ItemLayout current, ItemLayout previous);
virtual void onModelChanged(KItemModelBase* current, KItemModelBase* previous);
virtual void onScrollOrientationChanged(Qt::Orientation current, Qt::Orientation previous);
virtual void onItemSizeChanged(const QSizeF& current, const QSizeF& previous);
@ -111,7 +103,6 @@ private slots:
void updateIconSize();
private:
void updateLayoutOfVisibleItems();
void updateTimersInterval();
/**
@ -130,8 +121,6 @@ private:
QSize availableIconSize() const;
private:
Layout m_itemLayout;
KFileItemModelRolesUpdater* m_modelRolesUpdater;
QTimer* m_updateVisibleIndexRangeTimer;
QTimer* m_updateIconSizeTimer;

File diff suppressed because it is too large Load diff

View file

@ -22,188 +22,30 @@
#include <libdolphin_export.h>
#include <kitemviews/kitemlistwidget.h>
#include <kitemviews/kstandarditemlistwidget.h>
#include <QPixmap>
#include <QPointF>
#include <QStaticText>
class LIBDOLPHINPRIVATE_EXPORT KFileItemListWidgetInformant : public KStandardItemListWidgetInformant
{
public:
KFileItemListWidgetInformant();
virtual ~KFileItemListWidgetInformant();
class KItemListRoleEditor;
class KItemListStyleOption;
class KItemListView;
protected:
virtual QString roleText(const QByteArray& role, const QHash<QByteArray, QVariant>& values) const;
};
class LIBDOLPHINPRIVATE_EXPORT KFileItemListWidget : public KItemListWidget
class LIBDOLPHINPRIVATE_EXPORT KFileItemListWidget : public KStandardItemListWidget
{
Q_OBJECT
public:
enum Layout
{
IconsLayout,
CompactLayout,
DetailsLayout
};
KFileItemListWidget(QGraphicsItem* parent);
KFileItemListWidget(KItemListWidgetInformant* informant, QGraphicsItem* parent);
virtual ~KFileItemListWidget();
void setLayout(Layout layout);
Layout layout() const;
void setSupportsItemExpanding(bool supportsItemExpanding);
bool supportsItemExpanding() const;
virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0);
virtual QRectF iconRect() const;
virtual QRectF textRect() const;
virtual QRectF textFocusRect() const;
virtual QRectF expansionToggleRect() const;
virtual QRectF selectionToggleRect() const;
/**
* Implementation of KItemListWidgetCreatorBase::itemSizeHint() when
* using the KItemListWidgetCreator-template.
*
* @see KItemListView
*/
static QSizeF itemSizeHint(int index, const KItemListView* view);
/**
* Implementation of KItemListWidgetCreatorBase::preferredRoleColumnWidth() when
* using the KItemListWidgetCreator-template.
*
* @see KItemListView
*/
static qreal preferredRoleColumnWidth(const QByteArray& role, int index, const KItemListView* view);
static KItemListWidgetInformant* createInformant();
protected:
/**
* Invalidates the cache which results in calling KFileItemListWidget::refreshCache() as
* soon as the item need to gets repainted.
*/
void invalidateCache();
/**
* Is called if the cache got invalidated by KFileItemListWidget::invalidateCache().
* The default implementation is empty.
*/
virtual void refreshCache();
void setTextColor(const QColor& color);
QColor textColor() const;
void setOverlay(const QPixmap& overlay);
QPixmap overlay() const;
virtual void dataChanged(const QHash<QByteArray, QVariant>& current, const QSet<QByteArray>& roles = QSet<QByteArray>());
virtual void visibleRolesChanged(const QList<QByteArray>& current, const QList<QByteArray>& previous);
virtual void columnWidthChanged(const QByteArray& role, qreal current, qreal previous);
virtual void styleOptionChanged(const KItemListStyleOption& current, const KItemListStyleOption& previous);
virtual void hoveredChanged(bool hovered);
virtual void selectedChanged(bool selected);
virtual void siblingsInformationChanged(const QBitArray& current, const QBitArray& previous);
virtual void editedRoleChanged(const QByteArray& current, const QByteArray& previous);
virtual void resizeEvent(QGraphicsSceneResizeEvent* event);
virtual void showEvent(QShowEvent* event);
virtual void hideEvent(QHideEvent* event);
private slots:
void slotCutItemsChanged();
void slotRoleEditingCanceled(int index, const QByteArray& role, const QVariant& value);
void slotRoleEditingFinished(int index, const QByteArray& role, const QVariant& value);
private:
/**
* Typedefinitions for roles that require a special handling
* and must be accessible in a fast way. The mapping of a
* QByteArray role to the type is done by KFileItemListWidget::roleType().
*/
enum RoleType {
Name,
Size,
Date,
Rating,
Generic // Mandatory last entry
};
void triggerCacheRefreshing();
void updateExpansionArea();
void updatePixmapCache();
void updateTextsCache();
void updateIconsLayoutTextCache();
void updateCompactLayoutTextCache();
void updateDetailsLayoutTextCache();
void updateAdditionalInfoTextColor();
void drawPixmap(QPainter* painter, const QPixmap& pixmap);
void drawSiblingsInformation(QPainter* painter);
QRectF roleEditingRect(const QByteArray &role) const;
static QPixmap pixmapForIcon(const QString& name, int size);
static void applyCutEffect(QPixmap& pixmap);
static void applyHiddenEffect(QPixmap& pixmap);
static RoleType roleType(const QByteArray& role);
/**
* @return Preferred size of the rating-image based on the given
* style-option. The height of the font is taken as
* reference.
*/
static QSizeF preferredRatingSize(const KItemListStyleOption& option);
/**
* @return Horizontal padding in pixels that is added to the required width of
* a column to display the content.
*/
static qreal columnPadding(const KItemListStyleOption& option);
/**
* @return Shown string for the role \p role of the item with the values \p values.
*/
static QString roleText(const QByteArray& role, const QHash<QByteArray, QVariant>& values);
private:
bool m_isCut;
bool m_isHidden;
bool m_isExpandable;
bool m_supportsItemExpanding;
bool m_dirtyLayout;
bool m_dirtyContent;
QSet<QByteArray> m_dirtyContentRoles;
Layout m_layout;
QPointF m_pixmapPos;
QPixmap m_pixmap;
QSize m_scaledPixmapSize;
QRectF m_iconRect; // Cache for KItemListWidget::iconRect()
QPixmap m_hoverPixmap; // Cache for modified m_pixmap when hovering the item
struct TextInfo
{
QPointF pos;
QStaticText staticText;
};
QHash<QByteArray, TextInfo*> m_textInfo;
QRectF m_textRect;
QList<QByteArray> m_sortedVisibleRoles;
QRectF m_expansionArea;
QColor m_customTextColor;
QColor m_additionalInfoTextColor;
QPixmap m_overlay;
QPixmap m_rating;
KItemListRoleEditor* m_roleEditor;
virtual bool isRoleRightAligned(const QByteArray& role) const;
};
#endif

View file

@ -35,7 +35,7 @@
// #define KFILEITEMMODEL_DEBUG
KFileItemModel::KFileItemModel(QObject* parent) :
KItemModelBase("name", parent),
KItemModelBase("text", parent),
m_dirLister(0),
m_naturalSorting(KGlobalSettings::naturalSorting()),
m_sortDirsFirst(true),
@ -77,7 +77,7 @@ KFileItemModel::KFileItemModel(QObject* parent) :
resetRoles();
m_requestRole[NameRole] = true;
m_requestRole[IsDirRole] = true;
m_roles.insert("name");
m_roles.insert("text");
m_roles.insert("isDir");
// For slow KIO-slaves like used for searching it makes sense to show results periodically even
@ -253,12 +253,12 @@ int KFileItemModel::indexForKeyboardSearch(const QString& text, int startFromInd
{
startFromIndex = qMax(0, startFromIndex);
for (int i = startFromIndex; i < count(); ++i) {
if (data(i)["name"].toString().startsWith(text, Qt::CaseInsensitive)) {
if (data(i)["text"].toString().startsWith(text, Qt::CaseInsensitive)) {
return i;
}
}
for (int i = 0; i < startFromIndex; ++i) {
if (data(i)["name"].toString().startsWith(text, Qt::CaseInsensitive)) {
if (data(i)["text"].toString().startsWith(text, Qt::CaseInsensitive)) {
return i;
}
}
@ -1165,7 +1165,7 @@ QHash<QByteArray, QVariant> KFileItemModel::retrieveData(const KFileItem& item)
}
if (m_requestRole[NameRole]) {
data.insert("name", item.text());
data.insert("text", item.text());
}
if (m_requestRole[SizeRole]) {
@ -1523,7 +1523,7 @@ QList<QPair<int, QVariant> > KFileItemModel::nameRoleGroups() const
continue;
}
const QString name = m_itemData.at(i)->values.value("name").toString();
const QString name = m_itemData.at(i)->values.value("text").toString();
// Use the first character of the name as group indication
QChar newFirstChar = name.at(0).toUpper();
@ -1873,7 +1873,7 @@ const KFileItemModel::RoleInfoMap* KFileItemModel::rolesInfoMap(int& count)
static const RoleInfoMap rolesInfoMap[] = {
// | role | roleType | role translation | group translation | requires Nepomuk | requires indexer
{ 0, NoRole, 0, 0, 0, 0, false, false },
{ "name", NameRole, I18N_NOOP2_NOSTRIP("@label", "Name"), 0, 0, false, false },
{ "text", NameRole, I18N_NOOP2_NOSTRIP("@label", "Name"), 0, 0, false, false },
{ "size", SizeRole, I18N_NOOP2_NOSTRIP("@label", "Size"), 0, 0, false, false },
{ "date", DateRole, I18N_NOOP2_NOSTRIP("@label", "Date"), 0, 0, false, false },
{ "type", TypeRole, I18N_NOOP2_NOSTRIP("@label", "Type"), 0, 0, false, false },

View file

@ -108,7 +108,7 @@ public:
virtual bool supportsDropping(int index) const;
/** @reimp */
virtual QString roleDescription(const QByteArray& typeForRole) const;
virtual QString roleDescription(const QByteArray& role) const;
/** @reimp */
virtual QList<QPair<int, QVariant> > groups() const;

View file

@ -67,8 +67,6 @@ void KItemListContainerViewport::wheelEvent(QWheelEvent* event)
event->ignore();
}
KItemListContainer::KItemListContainer(KItemListController* controller, QWidget* parent) :
QAbstractScrollArea(parent),
m_controller(controller),
@ -77,20 +75,32 @@ KItemListContainer::KItemListContainer(KItemListController* controller, QWidget*
{
Q_ASSERT(controller);
controller->setParent(this);
initialize();
}
KItemListContainer::KItemListContainer(QWidget* parent) :
QAbstractScrollArea(parent),
m_controller(0),
m_horizontalSmoothScroller(0),
m_verticalSmoothScroller(0)
{
initialize();
QGraphicsView* graphicsView = new KItemListContainerViewport(new QGraphicsScene(this), this);
setViewport(graphicsView);
m_horizontalSmoothScroller = new KItemListSmoothScroller(horizontalScrollBar(), this);
m_verticalSmoothScroller = new KItemListSmoothScroller(verticalScrollBar(), this);
if (controller->model()) {
slotModelChanged(controller->model(), 0);
}
if (controller->view()) {
slotViewChanged(controller->view(), 0);
}
connect(controller, SIGNAL(modelChanged(KItemModelBase*,KItemModelBase*)),
this, SLOT(slotModelChanged(KItemModelBase*,KItemModelBase*)));
connect(controller, SIGNAL(viewChanged(KItemListView*,KItemListView*)),
this, SLOT(slotViewChanged(KItemListView*,KItemListView*)));
}
KItemListContainer::~KItemListContainer()
{
// Don't rely on the QObject-order to delete the controller, otherwise
// the QGraphicsScene might get deleted before the view.
delete m_controller;
m_controller = 0;
}
KItemListController* KItemListContainer::controller() const
@ -98,6 +108,33 @@ KItemListController* KItemListContainer::controller() const
return m_controller;
}
void KItemListContainer::setEnabledFrame(bool enable)
{
QGraphicsView* graphicsView = qobject_cast<QGraphicsView*>(viewport());
if (enable) {
setFrameShape(QFrame::StyledPanel);
graphicsView->setPalette(palette());
graphicsView->viewport()->setAutoFillBackground(true);
} else {
setFrameShape(QFrame::NoFrame);
// Make the background of the container transparent and apply the window-text color
// to the text color, so that enough contrast is given for all color
// schemes
QPalette p = graphicsView->palette();
p.setColor(QPalette::Active, QPalette::Text, p.color(QPalette::Active, QPalette::WindowText));
p.setColor(QPalette::Inactive, QPalette::Text, p.color(QPalette::Inactive, QPalette::WindowText));
p.setColor(QPalette::Disabled, QPalette::Text, p.color(QPalette::Disabled, QPalette::WindowText));
graphicsView->setPalette(p);
graphicsView->viewport()->setAutoFillBackground(false);
}
}
bool KItemListContainer::enabledFrame() const
{
const QGraphicsView* graphicsView = qobject_cast<QGraphicsView*>(viewport());
return graphicsView->autoFillBackground();
}
void KItemListContainer::keyPressEvent(QKeyEvent* event)
{
// TODO: We should find a better way to handle the key press events in the view.
@ -355,29 +392,4 @@ void KItemListContainer::updateScrollOffsetScrollBarPolicy()
}
}
void KItemListContainer::initialize()
{
if (m_controller) {
if (m_controller->model()) {
slotModelChanged(m_controller->model(), 0);
}
if (m_controller->view()) {
slotViewChanged(m_controller->view(), 0);
}
} else {
m_controller = new KItemListController(this);
}
connect(m_controller, SIGNAL(modelChanged(KItemModelBase*,KItemModelBase*)),
this, SLOT(slotModelChanged(KItemModelBase*,KItemModelBase*)));
connect(m_controller, SIGNAL(viewChanged(KItemListView*,KItemListView*)),
this, SLOT(slotViewChanged(KItemListView*,KItemListView*)));
QGraphicsView* graphicsView = new KItemListContainerViewport(new QGraphicsScene(this), this);
setViewport(graphicsView);
m_horizontalSmoothScroller = new KItemListSmoothScroller(horizontalScrollBar(), this);
m_verticalSmoothScroller = new KItemListSmoothScroller(verticalScrollBar(), this);
}
#include "kitemlistcontainer.moc"

View file

@ -37,6 +37,8 @@ class QPropertyAnimation;
/**
* @brief Provides a QWidget based scrolling view for a KItemListController.
*
* The model and view are maintained by the KItemListController.
*
* @see KItemListController
*/
class LIBDOLPHINPRIVATE_EXPORT KItemListContainer : public QAbstractScrollArea
@ -44,12 +46,19 @@ class LIBDOLPHINPRIVATE_EXPORT KItemListContainer : public QAbstractScrollArea
Q_OBJECT
public:
/**
* @param controller Controller that maintains the model and the view.
* The KItemListContainer takes ownership of the controller
* (the parent will be set to the KItemListContainer).
* @param parent Optional parent widget.
*/
explicit KItemListContainer(KItemListController* controller, QWidget* parent = 0);
KItemListContainer(QWidget* parent = 0);
virtual ~KItemListContainer();
KItemListController* controller() const;
void setEnabledFrame(bool enable);
bool enabledFrame() const;
protected:
virtual void keyPressEvent(QKeyEvent* event);
virtual void showEvent(QShowEvent* event);
@ -66,7 +75,6 @@ private slots:
void updateItemOffsetScrollBar();
private:
void initialize();
void updateGeometries();
void updateSmoothScrollers(Qt::Orientation orientation);

View file

@ -41,7 +41,7 @@
#include <QMimeData>
#include <QTimer>
KItemListController::KItemListController(QObject* parent) :
KItemListController::KItemListController(KItemModelBase* model, KItemListView* view, QObject* parent) :
QObject(parent),
m_singleClickActivation(KGlobalSettings::singleClick()),
m_selectionTogglePressed(false),
@ -65,10 +65,20 @@ KItemListController::KItemListController(QObject* parent) :
m_autoActivationTimer->setSingleShot(true);
m_autoActivationTimer->setInterval(-1);
connect(m_autoActivationTimer, SIGNAL(timeout()), this, SLOT(slotAutoActivationTimeout()));
setModel(model);
setView(view);
}
KItemListController::~KItemListController()
{
setView(0);
delete m_view;
m_view = 0;
setModel(0);
delete m_model;
m_model = 0;
}
void KItemListController::setModel(KItemModelBase* model)
@ -79,6 +89,9 @@ void KItemListController::setModel(KItemModelBase* model)
KItemModelBase* oldModel = m_model;
m_model = model;
if (m_model) {
m_model->setParent(this);
}
if (m_view) {
m_view->setModel(m_model);
@ -116,6 +129,7 @@ void KItemListController::setView(KItemListView* view)
m_view->setController(this);
m_view->setModel(m_model);
connect(m_view, SIGNAL(scrollOffsetChanged(qreal,qreal)), this, SLOT(slotViewScrollOffsetChanged(qreal,qreal)));
updateExtendedSelectionRegion();
}
emit viewChanged(m_view, oldView);
@ -129,6 +143,7 @@ KItemListView* KItemListController::view() const
void KItemListController::setSelectionBehavior(SelectionBehavior behavior)
{
m_selectionBehavior = behavior;
updateExtendedSelectionRegion();
}
KItemListController::SelectionBehavior KItemListController::selectionBehavior() const
@ -1159,4 +1174,16 @@ qreal KItemListController::keyboardAnchorPos(int index) const
return 0;
}
void KItemListController::updateExtendedSelectionRegion()
{
if (m_view) {
const bool extend = (m_selectionBehavior != MultiSelection);
KItemListStyleOption option = m_view->styleOption();
if (option.extendedSelectionRegion != extend) {
option.extendedSelectionRegion = extend;
m_view->setStyleOption(option);
}
}
}
#include "kitemlistcontroller.moc"

View file

@ -72,7 +72,12 @@ public:
MultiSelection
};
KItemListController(QObject* parent = 0);
/**
* @param model Model of the controller. The ownership is passed to the controller.
* @param view View of the controller. The ownership is passed to the controller.
* @param parent Optional parent object.
*/
KItemListController(KItemModelBase* model, KItemListView* view, QObject* parent = 0);
virtual ~KItemListController();
void setModel(KItemModelBase* model);
@ -261,6 +266,13 @@ private:
*/
qreal keyboardAnchorPos(int index) const;
/**
* Dependent on the selection-behavior the extendedSelectionRegion-property
* of the KItemListStyleOption from the view should be adjusted: If no
* rubberband selection is used the property should be enabled.
*/
void updateExtendedSelectionRegion();
private:
bool m_singleClickActivation;
bool m_selectionTogglePressed;

View file

@ -26,10 +26,10 @@ KItemListStyleOption::KItemListStyleOption() :
font(),
fontMetrics(QFont()),
palette(),
padding(0),
horizontalMargin(0),
verticalMargin(0),
iconSize(KIconLoader::SizeMedium),
padding(-1),
horizontalMargin(-1),
verticalMargin(-1),
iconSize(-1),
extendedSelectionRegion(false),
maxTextSize()
{

View file

@ -22,6 +22,7 @@
#include "kitemlistview.h"
#include <KDebug>
#include "kitemlistcontroller.h"
#include "kitemlistheader.h"
#include "kitemlistselectionmanager.h"
@ -33,8 +34,6 @@
#include "private/kitemlistviewlayouter.h"
#include "private/kitemlistviewanimation.h"
#include <KDebug>
#include <QCursor>
#include <QGraphicsSceneMouseEvent>
#include <QPainter>
@ -113,93 +112,19 @@ KItemListView::KItemListView(QGraphicsWidget* parent) :
KItemListView::~KItemListView()
{
// The group headers are children of the widgets created by
// widgetCreator(). So it is mandatory to delete the group headers
// first.
delete m_groupHeaderCreator;
m_groupHeaderCreator = 0;
delete m_widgetCreator;
m_widgetCreator = 0;
delete m_sizeHintResolver;
m_sizeHintResolver = 0;
}
void KItemListView::setScrollOrientation(Qt::Orientation orientation)
{
const Qt::Orientation previousOrientation = m_layouter->scrollOrientation();
if (orientation == previousOrientation) {
return;
}
m_layouter->setScrollOrientation(orientation);
m_animation->setScrollOrientation(orientation);
m_sizeHintResolver->clearCache();
if (m_grouped) {
QMutableHashIterator<KItemListWidget*, KItemListGroupHeader*> it (m_visibleGroups);
while (it.hasNext()) {
it.next();
it.value()->setScrollOrientation(orientation);
}
updateGroupHeaderHeight();
}
doLayout(NoAnimation);
onScrollOrientationChanged(orientation, previousOrientation);
emit scrollOrientationChanged(orientation, previousOrientation);
}
Qt::Orientation KItemListView::scrollOrientation() const
{
return m_layouter->scrollOrientation();
}
void KItemListView::setItemSize(const QSizeF& size)
{
const QSizeF previousSize = m_itemSize;
if (size == previousSize) {
return;
}
// Skip animations when the number of rows or columns
// are changed in the grid layout. Although the animation
// engine can handle this usecase, it looks obtrusive.
const bool animate = !changesItemGridLayout(m_layouter->size(),
size,
m_layouter->itemMargin());
const bool alternateBackgroundsChanged = (m_visibleRoles.count() > 1) &&
(( m_itemSize.isEmpty() && !size.isEmpty()) ||
(!m_itemSize.isEmpty() && size.isEmpty()));
m_itemSize = size;
if (alternateBackgroundsChanged) {
// For an empty item size alternate backgrounds are drawn if more than
// one role is shown. Assure that the backgrounds for visible items are
// updated when changing the size in this context.
updateAlternateBackgrounds();
}
if (size.isEmpty()) {
if (m_headerWidget->automaticColumnResizing()) {
updatePreferredColumnWidths();
} else {
// Only apply the changed height and respect the header widths
// set by the user
const qreal currentWidth = m_layouter->itemSize().width();
const QSizeF newSize(currentWidth, size.height());
m_layouter->setItemSize(newSize);
}
} else {
m_layouter->setItemSize(size);
}
m_sizeHintResolver->clearCache();
doLayout(animate ? Animation : NoAnimation);
onItemSizeChanged(size, previousSize);
}
QSizeF KItemListView::itemSize() const
{
return m_itemSize;
}
void KItemListView::setScrollOffset(qreal offset)
{
if (offset < 0) {
@ -354,62 +279,39 @@ KItemModelBase* KItemListView::model() const
void KItemListView::setWidgetCreator(KItemListWidgetCreatorBase* widgetCreator)
{
if (m_widgetCreator) {
delete m_widgetCreator;
}
m_widgetCreator = widgetCreator;
}
KItemListWidgetCreatorBase* KItemListView::widgetCreator() const
{
if (!m_widgetCreator) {
m_widgetCreator = defaultWidgetCreator();
}
return m_widgetCreator;
}
void KItemListView::setGroupHeaderCreator(KItemListGroupHeaderCreatorBase* groupHeaderCreator)
{
if (m_groupHeaderCreator) {
delete m_groupHeaderCreator;
}
m_groupHeaderCreator = groupHeaderCreator;
}
KItemListGroupHeaderCreatorBase* KItemListView::groupHeaderCreator() const
{
if (!m_groupHeaderCreator) {
m_groupHeaderCreator = defaultGroupHeaderCreator();
}
return m_groupHeaderCreator;
}
void KItemListView::setStyleOption(const KItemListStyleOption& option)
QSizeF KItemListView::itemSize() const
{
const KItemListStyleOption previousOption = m_styleOption;
m_styleOption = option;
bool animate = true;
const QSizeF margin(option.horizontalMargin, option.verticalMargin);
if (margin != m_layouter->itemMargin()) {
// Skip animations when the number of rows or columns
// are changed in the grid layout. Although the animation
// engine can handle this usecase, it looks obtrusive.
animate = !changesItemGridLayout(m_layouter->size(),
m_layouter->itemSize(),
margin);
m_layouter->setItemMargin(margin);
}
if (m_grouped) {
updateGroupHeaderHeight();
}
if (animate && previousOption.maxTextSize != option.maxTextSize) {
// Animating a change of the maximum text size just results in expensive
// temporary eliding and clipping operations and does not look good visually.
animate = false;
}
QHashIterator<int, KItemListWidget*> it(m_visibleItems);
while (it.hasNext()) {
it.next();
it.value()->setStyleOption(option);
}
m_sizeHintResolver->clearCache();
m_layouter->markAsDirty();
doLayout(animate ? Animation : NoAnimation);
onStyleOptionChanged(option, previousOption);
return m_itemSize;
}
const KItemListStyleOption& KItemListView::styleOption() const
@ -519,7 +421,7 @@ int KItemListView::lastVisibleIndex() const
QSizeF KItemListView::itemSizeHint(int index) const
{
return m_widgetCreator->itemSizeHint(index, this);
return widgetCreator()->itemSizeHint(index, this);
}
void KItemListView::setSupportsItemExpanding(bool supportsExpanding)
@ -709,6 +611,134 @@ void KItemListView::paint(QPainter* painter, const QStyleOptionGraphicsItem* opt
}
}
void KItemListView::setItemSize(const QSizeF& size)
{
const QSizeF previousSize = m_itemSize;
if (size == previousSize) {
return;
}
// Skip animations when the number of rows or columns
// are changed in the grid layout. Although the animation
// engine can handle this usecase, it looks obtrusive.
const bool animate = !changesItemGridLayout(m_layouter->size(),
size,
m_layouter->itemMargin());
const bool alternateBackgroundsChanged = (m_visibleRoles.count() > 1) &&
(( m_itemSize.isEmpty() && !size.isEmpty()) ||
(!m_itemSize.isEmpty() && size.isEmpty()));
m_itemSize = size;
if (alternateBackgroundsChanged) {
// For an empty item size alternate backgrounds are drawn if more than
// one role is shown. Assure that the backgrounds for visible items are
// updated when changing the size in this context.
updateAlternateBackgrounds();
}
if (size.isEmpty()) {
if (m_headerWidget->automaticColumnResizing()) {
updatePreferredColumnWidths();
} else {
// Only apply the changed height and respect the header widths
// set by the user
const qreal currentWidth = m_layouter->itemSize().width();
const QSizeF newSize(currentWidth, size.height());
m_layouter->setItemSize(newSize);
}
} else {
m_layouter->setItemSize(size);
}
m_sizeHintResolver->clearCache();
doLayout(animate ? Animation : NoAnimation);
onItemSizeChanged(size, previousSize);
}
void KItemListView::setStyleOption(const KItemListStyleOption& option)
{
const KItemListStyleOption previousOption = m_styleOption;
m_styleOption = option;
bool animate = true;
const QSizeF margin(option.horizontalMargin, option.verticalMargin);
if (margin != m_layouter->itemMargin()) {
// Skip animations when the number of rows or columns
// are changed in the grid layout. Although the animation
// engine can handle this usecase, it looks obtrusive.
animate = !changesItemGridLayout(m_layouter->size(),
m_layouter->itemSize(),
margin);
m_layouter->setItemMargin(margin);
}
if (m_grouped) {
updateGroupHeaderHeight();
}
if (animate && previousOption.maxTextSize != option.maxTextSize) {
// Animating a change of the maximum text size just results in expensive
// temporary eliding and clipping operations and does not look good visually.
animate = false;
}
QHashIterator<int, KItemListWidget*> it(m_visibleItems);
while (it.hasNext()) {
it.next();
it.value()->setStyleOption(option);
}
m_sizeHintResolver->clearCache();
m_layouter->markAsDirty();
doLayout(animate ? Animation : NoAnimation);
onStyleOptionChanged(option, previousOption);
}
void KItemListView::setScrollOrientation(Qt::Orientation orientation)
{
const Qt::Orientation previousOrientation = m_layouter->scrollOrientation();
if (orientation == previousOrientation) {
return;
}
m_layouter->setScrollOrientation(orientation);
m_animation->setScrollOrientation(orientation);
m_sizeHintResolver->clearCache();
if (m_grouped) {
QMutableHashIterator<KItemListWidget*, KItemListGroupHeader*> it (m_visibleGroups);
while (it.hasNext()) {
it.next();
it.value()->setScrollOrientation(orientation);
}
updateGroupHeaderHeight();
}
doLayout(NoAnimation);
onScrollOrientationChanged(orientation, previousOrientation);
emit scrollOrientationChanged(orientation, previousOrientation);
}
Qt::Orientation KItemListView::scrollOrientation() const
{
return m_layouter->scrollOrientation();
}
KItemListWidgetCreatorBase* KItemListView::defaultWidgetCreator() const
{
return 0;
}
KItemListGroupHeaderCreatorBase* KItemListView::defaultGroupHeaderCreator() const
{
return 0;
}
void KItemListView::initializeItemListWidget(KItemListWidget* item)
{
Q_UNUSED(item);
@ -728,8 +758,13 @@ void KItemListView::onControllerChanged(KItemListController* current, KItemListC
void KItemListView::onModelChanged(KItemModelBase* current, KItemModelBase* previous)
{
Q_UNUSED(current);
Q_UNUSED(previous);
m_sizeHintResolver->clearCache();
const int itemCount = current->count();
if (itemCount > 0) {
m_sizeHintResolver->itemsInserted(0, itemCount);
}
}
void KItemListView::onScrollOrientationChanged(Qt::Orientation current, Qt::Orientation previous)
@ -1205,7 +1240,7 @@ void KItemListView::slotAnimationFinished(QGraphicsWidget* widget,
// by m_visibleWidgets and must be deleted manually after the animation has
// been finished.
recycleGroupHeaderForWidget(itemListWidget);
m_widgetCreator->recycle(itemListWidget);
widgetCreator()->recycle(itemListWidget);
break;
}
@ -1713,7 +1748,7 @@ void KItemListView::emitOffsetChanges()
KItemListWidget* KItemListView::createWidget(int index)
{
KItemListWidget* widget = m_widgetCreator->create(this);
KItemListWidget* widget = widgetCreator()->create(this);
widget->setFlag(QGraphicsItem::ItemStacksBehindParent);
m_visibleItems.insert(index, widget);
@ -1733,7 +1768,7 @@ void KItemListView::recycleWidget(KItemListWidget* widget)
m_visibleItems.remove(index);
m_visibleCells.remove(index);
m_widgetCreator->recycle(widget);
widgetCreator()->recycle(widget);
}
void KItemListView::setWidgetIndex(KItemListWidget* widget, int index)
@ -1813,7 +1848,7 @@ void KItemListView::updateGroupHeaderForWidget(KItemListWidget* widget)
KItemListGroupHeader* groupHeader = m_visibleGroups.value(widget);
if (!groupHeader) {
groupHeader = m_groupHeaderCreator->create(this);
groupHeader = groupHeaderCreator()->create(this);
groupHeader->setParentItem(widget);
m_visibleGroups.insert(widget, groupHeader);
connect(widget, SIGNAL(geometryChanged()), this, SLOT(slotGeometryOfGroupHeaderParentChanged()));
@ -1859,7 +1894,7 @@ void KItemListView::recycleGroupHeaderForWidget(KItemListWidget* widget)
KItemListGroupHeader* header = m_visibleGroups.value(widget);
if (header) {
header->setParentItem(0);
m_groupHeaderCreator->recycle(header);
groupHeaderCreator()->recycle(header);
m_visibleGroups.remove(widget);
disconnect(widget, SIGNAL(geometryChanged()), this, SLOT(slotGeometryOfGroupHeaderParentChanged()));
}
@ -1960,6 +1995,7 @@ QHash<QByteArray, qreal> KItemListView::preferredColumnWidths(const KItemRangeLi
// Calculate the preferred column withs for each item and ignore values
// smaller than the width for showing the headline unclipped.
const KItemListWidgetCreatorBase* creator = widgetCreator();
int calculatedItemCount = 0;
bool maxTimeExceeded = false;
foreach (const KItemRange& itemRange, itemRanges) {
@ -1969,7 +2005,7 @@ QHash<QByteArray, qreal> KItemListView::preferredColumnWidths(const KItemRangeLi
for (int i = startIndex; i <= endIndex; ++i) {
foreach (const QByteArray& visibleRole, visibleRoles()) {
qreal maxWidth = widths.value(visibleRole, 0);
const qreal width = m_widgetCreator->preferredRoleColumnWidth(visibleRole, i, this);
const qreal width = creator->preferredRoleColumnWidth(visibleRole, i, this);
maxWidth = qMax(width, maxWidth);
widths.insert(visibleRole, maxWidth);
}
@ -2071,6 +2107,9 @@ void KItemListView::applyAutomaticColumnWidths()
{
Q_ASSERT(m_itemSize.isEmpty());
Q_ASSERT(m_headerWidget->automaticColumnResizing());
if (m_visibleRoles.isEmpty()) {
return;
}
// Calculate the maximum size of an item by considering the
// visible role sizes and apply them to the layouter. If the

View file

@ -42,6 +42,7 @@ class KItemListRubberBand;
class KItemListViewAnimation;
class KItemListViewLayouter;
class KItemListWidget;
class KItemListWidgetInformant;
class KItemListWidgetCreatorBase;
class KItemListViewCreatorBase;
class QTimer;
@ -53,11 +54,8 @@ class QTimer;
* a GraphicsItem. Each visible item is represented by a KItemListWidget.
*
* The created view must be applied to the KItemListController with
* KItemListController::setView(). For showing a custom model it is not
* mandatory to derive from KItemListView, all that is necessary is
* to set a widget-creator that is capable to create KItemListWidgets
* showing the model items. A widget-creator can be set with
* KItemListView::setWidgetCreator().
* KItemListController::setView() or with the constructor of
* KItemListController.
*
* @see KItemListWidget
* @see KItemModelBase
@ -73,17 +71,6 @@ public:
KItemListView(QGraphicsWidget* parent = 0);
virtual ~KItemListView();
/**
* If the scroll-orientation is vertical, the items are ordered
* from top to bottom (= default setting). If the scroll-orientation
* is horizontal, the items are ordered from left to right.
*/
void setScrollOrientation(Qt::Orientation orientation);
Qt::Orientation scrollOrientation() const;
void setItemSize(const QSizeF& size);
QSizeF itemSize() const;
/**
* Offset of the scrollbar that represents the scroll-orientation
* (see setScrollOrientation()).
@ -145,17 +132,27 @@ public:
* <code>
* itemListView->setWidgetCreator(new KItemListWidgetCreator<X>());
* </code>
* Note that the ownership of the widget creator is not transferred to
* the item-list view: One instance of a widget creator might get shared
* by several item-list view instances.
* The ownership of the widget creator is transferred to
* the item-list view.
**/
void setWidgetCreator(KItemListWidgetCreatorBase* widgetCreator);
KItemListWidgetCreatorBase* widgetCreator() const;
/**
* Sets the creator that creates a group header. Usually it is sufficient
* to implement a custom header widget X derived from KItemListGroupHeader and
* set the creator by:
* <code>
* itemListView->setGroupHeaderCreator(new KItemListGroupHeaderCreator<X>());
* </code>
* The ownership of the gropup header creator is transferred to
* the item-list view.
**/
void setGroupHeaderCreator(KItemListGroupHeaderCreatorBase* groupHeaderCreator);
KItemListGroupHeaderCreatorBase* groupHeaderCreator() const;
void setStyleOption(const KItemListStyleOption& option);
QSizeF itemSize() const;
const KItemListStyleOption& styleOption() const;
/** @reimp */
@ -313,6 +310,33 @@ signals:
void roleEditingFinished(int index, const QByteArray& role, const QVariant& value);
protected:
void setItemSize(const QSizeF& size);
void setStyleOption(const KItemListStyleOption& option);
/**
* If the scroll-orientation is vertical, the items are ordered
* from top to bottom (= default setting). If the scroll-orientation
* is horizontal, the items are ordered from left to right.
*/
void setScrollOrientation(Qt::Orientation orientation);
Qt::Orientation scrollOrientation() const;
/**
* Factory method for creating a default widget-creator. The method will be used
* in case if setWidgetCreator() has not been set by the application.
* @return New instance of the widget-creator that should be used per
* default.
*/
virtual KItemListWidgetCreatorBase* defaultWidgetCreator() const;
/**
* Factory method for creating a default group-header-creator. The method will be used
* in case if setGroupHeaderCreator() has not been set by the application.
* @return New instance of the group-header-creator that should be used per
* default.
*/
virtual KItemListGroupHeaderCreatorBase* defaultGroupHeaderCreator() const;
/**
* Is called when creating a new KItemListWidget instance and allows derived
* classes to do a custom initialization.
@ -656,8 +680,8 @@ private:
KItemListController* m_controller;
KItemModelBase* m_model;
QList<QByteArray> m_visibleRoles;
KItemListWidgetCreatorBase* m_widgetCreator;
KItemListGroupHeaderCreatorBase* m_groupHeaderCreator;
mutable KItemListWidgetCreatorBase* m_widgetCreator;
mutable KItemListGroupHeaderCreatorBase* m_groupHeaderCreator;
KItemListStyleOption m_styleOption;
QHash<int, KItemListWidget*> m_visibleItems;
@ -747,18 +771,12 @@ public:
/**
* @brief Template class for creating KItemListWidgets.
*
* The template class must provide the following two static methods:
* - QSizeF itemSizeHint(int index, const KItemListView* view)
* - preferredRoleColumnWidth(const QByteArray& role, int index, const KItemListView* view)
* Those static methods are used as implementation for
* KItemListWidgetCreatorBase::itemSizeHint() and
* KItemListWidgetCreatorBase::preferedRoleColumnWidth().
*/
template <class T>
class KItemListWidgetCreator : public KItemListWidgetCreatorBase
{
public:
KItemListWidgetCreator();
virtual ~KItemListWidgetCreator();
virtual KItemListWidget* create(KItemListView* view);
@ -768,11 +786,20 @@ public:
virtual qreal preferredRoleColumnWidth(const QByteArray& role,
int index,
const KItemListView* view) const;
private:
KItemListWidgetInformant* m_informant;
};
template <class T>
KItemListWidgetCreator<T>::KItemListWidgetCreator() :
m_informant(T::createInformant())
{
}
template <class T>
KItemListWidgetCreator<T>::~KItemListWidgetCreator()
{
delete m_informant;
}
template <class T>
@ -780,7 +807,7 @@ KItemListWidget* KItemListWidgetCreator<T>::create(KItemListView* view)
{
KItemListWidget* widget = static_cast<KItemListWidget*>(popRecycleableWidget());
if (!widget) {
widget = new T(view);
widget = new T(m_informant, view);
addCreatedWidget(widget);
}
return widget;
@ -789,7 +816,7 @@ KItemListWidget* KItemListWidgetCreator<T>::create(KItemListView* view)
template<class T>
QSizeF KItemListWidgetCreator<T>::itemSizeHint(int index, const KItemListView* view) const
{
return T::itemSizeHint(index, view);
return m_informant->itemSizeHint(index, view);
}
template<class T>
@ -797,7 +824,7 @@ qreal KItemListWidgetCreator<T>::preferredRoleColumnWidth(const QByteArray& role
int index,
const KItemListView* view) const
{
return T::preferredRoleColumnWidth(role, index, view);
return m_informant->preferredRoleColumnWidth(role, index, view);
}
/**

View file

@ -35,8 +35,17 @@
#include <QPropertyAnimation>
#include <QStyleOption>
KItemListWidget::KItemListWidget(QGraphicsItem* parent) :
KItemListWidgetInformant::KItemListWidgetInformant()
{
}
KItemListWidgetInformant::~KItemListWidgetInformant()
{
}
KItemListWidget::KItemListWidget(KItemListWidgetInformant* informant, QGraphicsItem* parent) :
QGraphicsWidget(parent, 0),
m_informant(informant),
m_index(-1),
m_selected(false),
m_current(false),

View file

@ -32,8 +32,30 @@
#include <QStyle>
class KItemListSelectionToggle;
class KItemListView;
class QPropertyAnimation;
/**
* @brief Provides information for creating an instance of KItemListWidget.
*
* KItemListView only creates KItemListWidget instances for the visible
* area. For calculating the required size of all items the expected
* size for the invisible items must be accessible. KItemListWidgetInformant
* provides this information.
*/
class LIBDOLPHINPRIVATE_EXPORT KItemListWidgetInformant
{
public:
KItemListWidgetInformant();
virtual ~KItemListWidgetInformant();
virtual QSizeF itemSizeHint(int index, const KItemListView* view) const = 0;
virtual qreal preferredRoleColumnWidth(const QByteArray& role,
int index,
const KItemListView* view) const = 0;
};
/**
* @brief Widget that shows a visible item from the model.
*
@ -46,7 +68,7 @@ class LIBDOLPHINPRIVATE_EXPORT KItemListWidget : public QGraphicsWidget
Q_OBJECT
public:
KItemListWidget(QGraphicsItem* parent);
KItemListWidget(KItemListWidgetInformant* informant, QGraphicsItem* parent);
virtual ~KItemListWidget();
void setIndex(int index);
@ -176,6 +198,8 @@ protected:
*/
qreal hoverOpacity() const;
const KItemListWidgetInformant* informant() const;
private slots:
void slotHoverAnimationFinished();
@ -188,6 +212,7 @@ private:
private:
Q_PROPERTY(qreal hoverOpacity READ hoverOpacity WRITE setHoverOpacity)
KItemListWidgetInformant* m_informant;
int m_index;
bool m_selected;
bool m_current;
@ -208,6 +233,12 @@ private:
QByteArray m_editedRole;
};
inline const KItemListWidgetInformant* KItemListWidget::informant() const
{
return m_informant;
}
#endif

View file

@ -0,0 +1,100 @@
/***************************************************************************
* Copyright (C) 2012 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 "kstandarditem.h"
KStandardItem::KStandardItem(KStandardItem* parent) :
m_text(),
m_icon(),
m_group(),
m_parent(parent),
m_children(),
m_model(0)
{
}
KStandardItem::KStandardItem(const QString& text, KStandardItem* parent) :
m_text(text),
m_icon(),
m_group(),
m_parent(parent),
m_children(),
m_model(0)
{
}
KStandardItem::KStandardItem(const QIcon& icon, const QString& text, KStandardItem* parent) :
m_text(text),
m_icon(icon),
m_group(),
m_parent(parent),
m_children(),
m_model(0)
{
}
KStandardItem::~KStandardItem()
{
}
void KStandardItem::setText(const QString& text)
{
m_text = text;
}
QString KStandardItem::text() const
{
return m_text;
}
void KStandardItem::setIcon(const QIcon& icon)
{
m_icon = icon;
}
QIcon KStandardItem::icon() const
{
return m_icon;
}
void KStandardItem::setGroup(const QString& group)
{
m_group = group;
}
QString KStandardItem::group() const
{
return m_group;
}
void KStandardItem::setParent(KStandardItem* parent)
{
// TODO: not implemented yet
m_parent = parent;
}
KStandardItem* KStandardItem::parent() const
{
return m_parent;
}
QList<KStandardItem*> KStandardItem::children() const
{
return m_children;
}

View file

@ -0,0 +1,72 @@
/***************************************************************************
* Copyright (C) 2012 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 KSTANDARDITEM_H
#define KSTANDARDITEM_H
#include <libdolphin_export.h>
#include <QIcon>
#include <QList>
class KStandardItemModel;
/**
* @brief Represents and item of KStandardItemModel.
*
* Provides setter- and getter-methods for most commonly
* used properties.
*/
class LIBDOLPHINPRIVATE_EXPORT KStandardItem
{
public:
explicit KStandardItem(KStandardItem* parent = 0);
explicit KStandardItem(const QString& text, KStandardItem* parent = 0);
KStandardItem(const QIcon& icon, const QString& text, KStandardItem* parent = 0);
virtual ~KStandardItem();
void setText(const QString& text);
QString text() const;
void setIcon(const QIcon& icon);
QIcon icon() const;
void setGroup(const QString& group);
QString group() const;
void setParent(KStandardItem* parent);
KStandardItem* parent() const;
QList<KStandardItem*> children() const;
private:
QString m_text;
QIcon m_icon;
QString m_group;
KStandardItem* m_parent;
QList<KStandardItem*> m_children;
KStandardItemModel* m_model;
friend class KStandardItemModel;
};
#endif

View file

@ -0,0 +1,191 @@
/***************************************************************************
* Copyright (C) 2012 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 "kstandarditemlistview.h"
#include <KDebug>
#include <KIconLoader>
#include "kstandarditemlistwidget.h"
KStandardItemListView::KStandardItemListView(QGraphicsWidget* parent) :
KItemListView(parent),
m_itemLayout(DetailsLayout)
{
setAcceptDrops(true);
setScrollOrientation(Qt::Vertical);
setVisibleRoles(QList<QByteArray>() << "text");
}
KStandardItemListView::~KStandardItemListView()
{
}
void KStandardItemListView::setItemLayout(ItemLayout layout)
{
if (m_itemLayout == layout) {
return;
}
beginTransaction();
const ItemLayout previous = m_itemLayout;
m_itemLayout = layout;
switch (layout) {
case IconsLayout:
setScrollOrientation(Qt::Vertical);
setSupportsItemExpanding(false);
break;
case DetailsLayout:
setScrollOrientation(Qt::Vertical);
setSupportsItemExpanding(true);
break;
case CompactLayout:
setScrollOrientation(Qt::Horizontal);
setSupportsItemExpanding(false);
break;
default:
Q_ASSERT(false);
break;
}
onItemLayoutChanged(layout, previous);
endTransaction();
}
KStandardItemListView::ItemLayout KStandardItemListView::itemLayout() const
{
return m_itemLayout;
}
KItemListWidgetCreatorBase* KStandardItemListView::defaultWidgetCreator() const
{
return new KItemListWidgetCreator<KStandardItemListWidget>();
}
KItemListGroupHeaderCreatorBase* KStandardItemListView::defaultGroupHeaderCreator() const
{
return 0; // TODO: new KItemListGroupHeaderCreator<KStandardItemListGroupHeader>()
}
void KStandardItemListView::initializeItemListWidget(KItemListWidget* item)
{
KStandardItemListWidget* standardItemListWidget = qobject_cast<KStandardItemListWidget*>(item);
Q_ASSERT(standardItemListWidget);
switch (itemLayout()) {
case IconsLayout: standardItemListWidget->setLayout(KStandardItemListWidget::IconsLayout); break;
case CompactLayout: standardItemListWidget->setLayout(KStandardItemListWidget::CompactLayout); break;
case DetailsLayout: standardItemListWidget->setLayout(KStandardItemListWidget::DetailsLayout); break;
default: Q_ASSERT(false); break;
}
standardItemListWidget->setSupportsItemExpanding(supportsItemExpanding());
}
bool KStandardItemListView::itemSizeHintUpdateRequired(const QSet<QByteArray>& changedRoles) const
{
// Even if the icons have a different size they are always aligned within
// the area defined by KItemStyleOption.iconSize and hence result in no
// change of the item-size.
const bool containsIconName = changedRoles.contains("iconName");
const bool containsIconPixmap = changedRoles.contains("iconPixmap");
const int count = changedRoles.count();
const bool iconChanged = (containsIconName && containsIconPixmap && count == 2) ||
(containsIconName && count == 1) ||
(containsIconPixmap && count == 1);
return !iconChanged;
}
void KStandardItemListView::onItemLayoutChanged(ItemLayout current, ItemLayout previous)
{
Q_UNUSED(current);
Q_UNUSED(previous);
updateLayoutOfVisibleItems();
}
void KStandardItemListView::onScrollOrientationChanged(Qt::Orientation current, Qt::Orientation previous)
{
Q_UNUSED(current);
Q_UNUSED(previous);
updateLayoutOfVisibleItems();
}
void KStandardItemListView::onSupportsItemExpandingChanged(bool supportsExpanding)
{
Q_UNUSED(supportsExpanding);
updateLayoutOfVisibleItems();
}
void KStandardItemListView::polishEvent()
{
switch (m_itemLayout) {
case IconsLayout: applyDefaultStyleOption(KIconLoader::SizeMedium, 2, 4, 8); break;
case CompactLayout: applyDefaultStyleOption(KIconLoader::SizeSmall, 2, 8, 0); break;
case DetailsLayout: applyDefaultStyleOption(KIconLoader::SizeSmall, 2, 0, 0); break;
default: Q_ASSERT(false); break;
}
QGraphicsWidget::polishEvent();
}
void KStandardItemListView::applyDefaultStyleOption(int iconSize,
int padding,
int horizontalMargin,
int verticalMargin)
{
KItemListStyleOption option = styleOption();
bool changed = false;
if (option.iconSize < 0) {
option.iconSize = iconSize;
changed = true;
}
if (option.padding < 0) {
option.padding = padding;
changed = true;
}
if (option.horizontalMargin < 0) {
option.horizontalMargin = horizontalMargin;
changed = true;
}
if (option.verticalMargin < 0) {
option.verticalMargin = verticalMargin;
changed = true;
}
if (changed) {
setStyleOption(option);
}
}
void KStandardItemListView::updateLayoutOfVisibleItems()
{
if (model()) {
foreach (KItemListWidget* widget, visibleItemListWidgets()) {
initializeItemListWidget(widget);
}
}
}
#include "kstandarditemlistview.moc"

View file

@ -0,0 +1,81 @@
/***************************************************************************
* Copyright (C) 2012 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 KSTANDARDITEMLISTVIEW_H
#define KSTANDARDITEMLISTVIEW_H
#include <libdolphin_export.h>
#include <kitemviews/kitemlistview.h>
/**
* @brief Provides layouts for icons-, compact- and details-view.
*
* Together with the KStandardItemModel lists for standard usecases
* can be created in a straight forward way.
*
* Example code:
* <code>
* KStandardItemListView* view = new KStandardItemListView();
* KStandardItemModel* model = new KStandardItemModel();
* model->appendItem(new KStandardItem("Item 1"));
* model->appendItem(new KStandardItem("Item 2"));
* KItemListController* controller = new KItemListController(model, view);
* KItemListContainer* container = new KItemListContainer(controller, parentWidget);
* </code>
*/
class LIBDOLPHINPRIVATE_EXPORT KStandardItemListView : public KItemListView
{
Q_OBJECT
public:
enum ItemLayout
{
IconsLayout,
CompactLayout,
DetailsLayout
};
KStandardItemListView(QGraphicsWidget* parent = 0);
virtual ~KStandardItemListView();
void setItemLayout(ItemLayout layout);
ItemLayout itemLayout() const;
protected:
virtual KItemListWidgetCreatorBase* defaultWidgetCreator() const;
virtual KItemListGroupHeaderCreatorBase* defaultGroupHeaderCreator() const;
virtual void initializeItemListWidget(KItemListWidget* item);
virtual bool itemSizeHintUpdateRequired(const QSet<QByteArray>& changedRoles) const;
virtual void onItemLayoutChanged(ItemLayout current, ItemLayout previous);
virtual void onScrollOrientationChanged(Qt::Orientation current, Qt::Orientation previous);
virtual void onSupportsItemExpandingChanged(bool supportsExpanding);
virtual void polishEvent();
private:
void applyDefaultStyleOption(int iconSize, int padding, int horizontalMargin, int verticalMargin);
void updateLayoutOfVisibleItems();
private:
ItemLayout m_itemLayout;
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,218 @@
/***************************************************************************
* Copyright (C) 2012 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 KSTANDARDITEMLISTWIDGET_H
#define KSTANDARDITEMLISTWIDGET_H
#include <libdolphin_export.h>
#include <kitemviews/kitemlistwidget.h>
#include <QPixmap>
#include <QPointF>
#include <QStaticText>
class KItemListRoleEditor;
class KItemListStyleOption;
class KItemListView;
class LIBDOLPHINPRIVATE_EXPORT KStandardItemListWidgetInformant : public KItemListWidgetInformant
{
public:
KStandardItemListWidgetInformant();
virtual ~KStandardItemListWidgetInformant();
virtual QSizeF itemSizeHint(int index, const KItemListView* view) const;
virtual qreal preferredRoleColumnWidth(const QByteArray& role,
int index,
const KItemListView* view) const;
protected:
/**
* @return String representation of the role \a role. The representation of
* a role might depend on other roles, so the values of all roles
* are passed as parameter.
*/
virtual QString roleText(const QByteArray& role,
const QHash<QByteArray, QVariant>& values) const;
friend class KStandardItemListWidget; // Accesses roleText()
};
/**
* @brief Itemlist widget implementation for KStandardItemView and KStandardItemModel.
*/
class LIBDOLPHINPRIVATE_EXPORT KStandardItemListWidget : public KItemListWidget
{
Q_OBJECT
public:
enum Layout
{
IconsLayout,
CompactLayout,
DetailsLayout
};
KStandardItemListWidget(KItemListWidgetInformant* informant, QGraphicsItem* parent);
virtual ~KStandardItemListWidget();
void setLayout(Layout layout);
Layout layout() const;
void setSupportsItemExpanding(bool supportsItemExpanding);
bool supportsItemExpanding() const;
virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0);
virtual QRectF iconRect() const;
virtual QRectF textRect() const;
virtual QRectF textFocusRect() const;
virtual QRectF expansionToggleRect() const;
virtual QRectF selectionToggleRect() const;
static KItemListWidgetInformant* createInformant();
protected:
/**
* Invalidates the cache which results in calling KStandardItemListWidget::refreshCache() as
* soon as the item need to gets repainted.
*/
void invalidateCache();
/**
* Is called if the cache got invalidated by KStandardItemListWidget::invalidateCache().
* The default implementation is empty.
*/
virtual void refreshCache();
/**
* @return True if the give role should be right aligned when showing it inside a column.
* Per default false is returned.
*/
virtual bool isRoleRightAligned(const QByteArray& role) const;
void setTextColor(const QColor& color);
QColor textColor() const;
void setOverlay(const QPixmap& overlay);
QPixmap overlay() const;
/**
* @see KStandardItemListWidgetInformant::roleText().
*/
QString roleText(const QByteArray& role, const QHash<QByteArray, QVariant>& values) const;
virtual void dataChanged(const QHash<QByteArray, QVariant>& current, const QSet<QByteArray>& roles = QSet<QByteArray>());
virtual void visibleRolesChanged(const QList<QByteArray>& current, const QList<QByteArray>& previous);
virtual void columnWidthChanged(const QByteArray& role, qreal current, qreal previous);
virtual void styleOptionChanged(const KItemListStyleOption& current, const KItemListStyleOption& previous);
virtual void hoveredChanged(bool hovered);
virtual void selectedChanged(bool selected);
virtual void siblingsInformationChanged(const QBitArray& current, const QBitArray& previous);
virtual void editedRoleChanged(const QByteArray& current, const QByteArray& previous);
virtual void resizeEvent(QGraphicsSceneResizeEvent* event);
virtual void showEvent(QShowEvent* event);
virtual void hideEvent(QHideEvent* event);
private slots:
void slotCutItemsChanged();
void slotRoleEditingCanceled(int index, const QByteArray& role, const QVariant& value);
void slotRoleEditingFinished(int index, const QByteArray& role, const QVariant& value);
private:
void triggerCacheRefreshing();
void updateExpansionArea();
void updatePixmapCache();
void updateTextsCache();
void updateIconsLayoutTextCache();
void updateCompactLayoutTextCache();
void updateDetailsLayoutTextCache();
void updateAdditionalInfoTextColor();
void drawPixmap(QPainter* painter, const QPixmap& pixmap);
void drawSiblingsInformation(QPainter* painter);
QRectF roleEditingRect(const QByteArray &role) const;
static QPixmap pixmapForIcon(const QString& name, int size);
static void applyCutEffect(QPixmap& pixmap);
static void applyHiddenEffect(QPixmap& pixmap);
/**
* @return Preferred size of the rating-image based on the given
* style-option. The height of the font is taken as
* reference.
*/
static QSizeF preferredRatingSize(const KItemListStyleOption& option);
/**
* @return Horizontal padding in pixels that is added to the required width of
* a column to display the content.
*/
static qreal columnPadding(const KItemListStyleOption& option);
private:
bool m_isCut;
bool m_isHidden;
bool m_isExpandable;
bool m_supportsItemExpanding;
bool m_dirtyLayout;
bool m_dirtyContent;
QSet<QByteArray> m_dirtyContentRoles;
Layout m_layout;
QPointF m_pixmapPos;
QPixmap m_pixmap;
QSize m_scaledPixmapSize;
QRectF m_iconRect; // Cache for KItemListWidget::iconRect()
QPixmap m_hoverPixmap; // Cache for modified m_pixmap when hovering the item
struct TextInfo
{
QPointF pos;
QStaticText staticText;
};
QHash<QByteArray, TextInfo*> m_textInfo;
QRectF m_textRect;
QList<QByteArray> m_sortedVisibleRoles;
QRectF m_expansionArea;
QColor m_customTextColor;
QColor m_additionalInfoTextColor;
QPixmap m_overlay;
QPixmap m_rating;
KItemListRoleEditor* m_roleEditor;
friend class KStandardItemListWidgetInformant; // Accesses private static methods to be able to
// share a common layout calculation
};
#endif

View file

@ -0,0 +1,128 @@
/***************************************************************************
* Copyright (C) 2012 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 "kstandarditemmodel.h"
#include "kstandarditem.h"
KStandardItemModel::KStandardItemModel(QObject* parent) :
KItemModelBase(parent),
m_items(),
m_indexesForItems()
{
}
KStandardItemModel::~KStandardItemModel()
{
}
void KStandardItemModel::insertItem(int index, KStandardItem* item)
{
if (!m_indexesForItems.contains(item) && !item->m_model) {
m_items.insert(index, item);
m_indexesForItems.insert(item, index);
item->m_model = this;
// TODO: no hierarchical items are handled yet
}
}
void KStandardItemModel::appendItem(KStandardItem *item)
{
insertItem(m_items.count(), item);
}
void KStandardItemModel::removeItem(KStandardItem* item)
{
const int index = m_indexesForItems.value(item, -1);
if (index >= 0) {
m_items.removeAt(index);
m_indexesForItems.remove(item);
delete item;
// TODO: no hierarchical items are handled yet
}
}
KStandardItem* KStandardItemModel::item(int index) const
{
if (index < 0 || index >= m_items.count()) {
return 0;
}
return m_items[index];
}
int KStandardItemModel::index(const KStandardItem* item) const
{
return m_indexesForItems.value(item, -1);
}
int KStandardItemModel::count() const
{
return m_items.count();
}
QHash<QByteArray, QVariant> KStandardItemModel::data(int index) const
{
// TODO: Ugly hack
QHash<QByteArray, QVariant> values;
const KStandardItem* item = m_items[index];
values.insert("text", item->text());
values.insert("iconName", item->icon().name());
return values;
}
bool KStandardItemModel::setData(int index, const QHash<QByteArray, QVariant>& values)
{
Q_UNUSED(values);
if (index < 0 || index >= count()) {
return false;
}
return true;
}
QMimeData* KStandardItemModel::createMimeData(const QSet<int>& indexes) const
{
Q_UNUSED(indexes);
return 0;
}
int KStandardItemModel::indexForKeyboardSearch(const QString& text, int startFromIndex) const
{
Q_UNUSED(text);
Q_UNUSED(startFromIndex);
return -1;
}
bool KStandardItemModel::supportsDropping(int index) const
{
Q_UNUSED(index);
return false;
}
QString KStandardItemModel::roleDescription(const QByteArray& role) const
{
Q_UNUSED(role);
return QString();
}
QList<QPair<int, QVariant> > KStandardItemModel::groups() const
{
return QList<QPair<int, QVariant> >();
}
#include "kstandarditemmodel.moc"

View file

@ -0,0 +1,68 @@
/***************************************************************************
* Copyright (C) 2012 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 KSTANDARDITEMMODEL_H
#define KSTANDARDITEMMODEL_H
#include <libdolphin_export.h>
#include <kitemviews/kitemmodelbase.h>
#include <QHash>
#include <QList>
class KStandardItem;
/**
* @brief Model counterpart for KStandardItemView.
*
* Allows to add items to the model in an easy way by the
* class KStandardItem.
*
* @see KStandardItem
*/
class LIBDOLPHINPRIVATE_EXPORT KStandardItemModel : public KItemModelBase
{
Q_OBJECT
public:
explicit KStandardItemModel(QObject* parent = 0);
virtual ~KStandardItemModel();
void insertItem(int index, KStandardItem* item);
void appendItem(KStandardItem* item);
void removeItem(KStandardItem* item);
KStandardItem* item(int index) const;
int index(const KStandardItem* item) const;
virtual int count() const;
virtual QHash<QByteArray, QVariant> data(int index) const;
virtual bool setData(int index, const QHash<QByteArray, QVariant>& values);
virtual QMimeData* createMimeData(const QSet<int>& indexes) const;
virtual int indexForKeyboardSearch(const QString& text, int startFromIndex = 0) const;
virtual bool supportsDropping(int index) const;
virtual QString roleDescription(const QByteArray& role) const;
virtual QList<QPair<int, QVariant> > groups() const;
private:
QList<KStandardItem*> m_items;
QHash<const KStandardItem*, int> m_indexesForItems;
};
#endif

View file

@ -48,7 +48,8 @@
FoldersPanel::FoldersPanel(QWidget* parent) :
Panel(parent),
m_updateCurrentItem(false),
m_controller(0)
m_controller(0),
m_model(0)
{
setLayoutDirection(Qt::LeftToRight);
}
@ -67,7 +68,7 @@ FoldersPanel::~FoldersPanel()
void FoldersPanel::setShowHiddenFiles(bool show)
{
FoldersPanelSettings::setHiddenFilesShown(show);
fileItemModel()->setShowHiddenFiles(show);
m_model->setShowHiddenFiles(show);
}
bool FoldersPanel::showHiddenFiles() const
@ -88,8 +89,8 @@ bool FoldersPanel::autoScrolling() const
void FoldersPanel::rename(const KFileItem& item)
{
const int index = fileItemModel()->index(item);
m_controller->view()->editRole(index, "name");
const int index = m_model->index(item);
m_controller->view()->editRole(index, "text");
}
bool FoldersPanel::urlChanged()
@ -115,21 +116,10 @@ void FoldersPanel::showEvent(QShowEvent* event)
}
if (!m_controller) {
// Postpone the creating of the dir lister to the first show event.
// This assures that no performance and memory overhead is given when the TreeView is not
// used at all (see FoldersPanel::setUrl()).
// Postpone the creating of the controller to the first show event.
// This assures that no performance and memory overhead is given when the folders panel is not
// used at all and stays invisible.
KFileItemListView* view = new KFileItemListView();
view->setWidgetCreator(new KItemListWidgetCreator<KFileItemListWidget>());
KItemListStyleOption styleOption = view->styleOption();
styleOption.padding = 2;
styleOption.iconSize = KIconLoader::SizeSmall;
styleOption.extendedSelectionRegion = true;
view->setStyleOption(styleOption);
const qreal itemHeight = qMax(int(KIconLoader::SizeSmall), styleOption.fontMetrics.height());
view->setItemSize(QSizeF(-1, itemHeight + 2 * styleOption.padding));
view->setItemLayout(KFileItemListView::DetailsLayout);
view->setSupportsItemExpanding(true);
// Set the opacity to 0 initially. The opacity will be increased after the loading of the initial tree
// has been finished in slotLoadingCompleted(). This prevents an unnecessary animation-mess when
@ -139,17 +129,14 @@ void FoldersPanel::showEvent(QShowEvent* event)
connect(view, SIGNAL(roleEditingFinished(int,QByteArray,QVariant)),
this, SLOT(slotRoleEditingFinished(int,QByteArray,QVariant)));
KFileItemModel* model = new KFileItemModel(this);
model->setShowDirectoriesOnly(true);
model->setShowHiddenFiles(FoldersPanelSettings::hiddenFilesShown());
m_model = new KFileItemModel(this);
m_model->setShowDirectoriesOnly(true);
m_model->setShowHiddenFiles(FoldersPanelSettings::hiddenFilesShown());
// Use a QueuedConnection to give the view the possibility to react first on the
// finished loading.
connect(model, SIGNAL(directoryLoadingCompleted()), this, SLOT(slotLoadingCompleted()), Qt::QueuedConnection);
connect(m_model, SIGNAL(directoryLoadingCompleted()), this, SLOT(slotLoadingCompleted()), Qt::QueuedConnection);
KItemListContainer* container = new KItemListContainer(this);
m_controller = container->controller();
m_controller->setView(view);
m_controller->setModel(model);
m_controller = new KItemListController(m_model, view, this);
m_controller->setSelectionBehavior(KItemListController::SingleSelection);
m_controller->setAutoActivationDelay(750);
m_controller->setSingleClickActivation(true);
@ -160,21 +147,8 @@ void FoldersPanel::showEvent(QShowEvent* event)
connect(m_controller, SIGNAL(viewContextMenuRequested(QPointF)), this, SLOT(slotViewContextMenuRequested(QPointF)));
connect(m_controller, SIGNAL(itemDropEvent(int,QGraphicsSceneDragDropEvent*)), this, SLOT(slotItemDropEvent(int,QGraphicsSceneDragDropEvent*)));
// TODO: Check whether it makes sense to make an explicit API for KItemListContainer
// to make the background transparent.
container->setFrameShape(QFrame::NoFrame);
QGraphicsView* graphicsView = qobject_cast<QGraphicsView*>(container->viewport());
if (graphicsView) {
// Make the background of the container transparent and apply the window-text color
// to the text color, so that enough contrast is given for all color
// schemes
QPalette p = graphicsView->palette();
p.setColor(QPalette::Active, QPalette::Text, p.color(QPalette::Active, QPalette::WindowText));
p.setColor(QPalette::Inactive, QPalette::Text, p.color(QPalette::Inactive, QPalette::WindowText));
p.setColor(QPalette::Disabled, QPalette::Text, p.color(QPalette::Disabled, QPalette::WindowText));
graphicsView->setPalette(p);
graphicsView->viewport()->setAutoFillBackground(false);
}
KItemListContainer* container = new KItemListContainer(m_controller, this);
container->setEnabledFrame(false);
QVBoxLayout* layout = new QVBoxLayout(this);
layout->setMargin(0);
@ -197,7 +171,7 @@ void FoldersPanel::keyPressEvent(QKeyEvent* event)
void FoldersPanel::slotItemActivated(int index)
{
const KFileItem item = fileItemModel()->fileItem(index);
const KFileItem item = m_model->fileItem(index);
if (!item.isNull()) {
emit changeUrl(item.url(), Qt::LeftButton);
}
@ -205,7 +179,7 @@ void FoldersPanel::slotItemActivated(int index)
void FoldersPanel::slotItemMiddleClicked(int index)
{
const KFileItem item = fileItemModel()->fileItem(index);
const KFileItem item = m_model->fileItem(index);
if (!item.isNull()) {
emit changeUrl(item.url(), Qt::MiddleButton);
}
@ -215,7 +189,7 @@ void FoldersPanel::slotItemContextMenuRequested(int index, const QPointF& pos)
{
Q_UNUSED(pos);
const KFileItem fileItem = fileItemModel()->fileItem(index);
const KFileItem fileItem = m_model->fileItem(index);
QWeakPointer<TreeViewContextMenu> contextMenu = new TreeViewContextMenu(this, fileItem);
contextMenu.data()->open();
@ -238,7 +212,7 @@ void FoldersPanel::slotViewContextMenuRequested(const QPointF& pos)
void FoldersPanel::slotItemDropEvent(int index, QGraphicsSceneDragDropEvent* event)
{
if (index >= 0) {
KFileItem destItem = fileItemModel()->fileItem(index);
KFileItem destItem = m_model->fileItem(index);
if (destItem.isNull()) {
return;
}
@ -255,8 +229,8 @@ void FoldersPanel::slotItemDropEvent(int index, QGraphicsSceneDragDropEvent* eve
void FoldersPanel::slotRoleEditingFinished(int index, const QByteArray& role, const QVariant& value)
{
if (role == "name") {
const KFileItem item = fileItemModel()->fileItem(index);
if (role == "text") {
const KFileItem item = m_model->fileItem(index);
const QString newName = value.toString();
if (!newName.isEmpty() && newName != item.text() && newName != QLatin1String(".") && newName != QLatin1String("..")) {
KonqOperations::rename(this, item.url(), newName);
@ -280,7 +254,7 @@ void FoldersPanel::slotLoadingCompleted()
return;
}
const int index = fileItemModel()->index(url());
const int index = m_model->index(url());
updateCurrentItem(index);
m_updateCurrentItem = false;
}
@ -311,18 +285,17 @@ void FoldersPanel::loadTree(const KUrl& url)
baseUrl.setPath(QString('/'));
}
KFileItemModel* model = fileItemModel();
if (model->directory() != baseUrl) {
if (m_model->directory() != baseUrl) {
m_updateCurrentItem = true;
model->refreshDirectory(baseUrl);
m_model->refreshDirectory(baseUrl);
}
const int index = model->index(url);
const int index = m_model->index(url);
if (index >= 0) {
updateCurrentItem(index);
} else {
m_updateCurrentItem = true;
model->expandParentDirectories(url);
m_model->expandParentDirectories(url);
// slotLoadingCompleted() will be invoked after the model has
// expanded the url
}
@ -338,9 +311,4 @@ void FoldersPanel::updateCurrentItem(int index)
m_controller->view()->scrollToItem(index);
}
KFileItemModel* FoldersPanel::fileItemModel() const
{
return static_cast<KFileItemModel*>(m_controller->model());
}
#include "folderspanel.moc"

View file

@ -96,11 +96,10 @@ private:
*/
void updateCurrentItem(int index);
KFileItemModel* fileItemModel() const;
private:
bool m_updateCurrentItem;
KItemListController* m_controller;
KFileItemModel* m_model;
};
#endif // FOLDERSPANEL_H

View file

@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (C) 2008 by Peter Penz <peter.penz19@gmail.com> *
* Copyright (C) 2008-2012 by Peter Penz <peter.penz19@gmail.com> *
* Copyright (C) 2010 by Christian Muehlhaeuser <muesli@gmail.com> *
* *
* This program is free software; you can redistribute it and/or modify *
@ -20,29 +20,64 @@
#include "placespanel.h"
#include <KFileItem>
#include <konq_operations.h>
#include <KIcon>
#include <kitemviews/kitemlistcontainer.h>
#include <kitemviews/kitemlistcontroller.h>
#include <kitemviews/kstandarditem.h>
#include <kitemviews/kstandarditemlistview.h>
#include <kitemviews/kstandarditemmodel.h>
#include <views/draganddrophelper.h>
#include <QVBoxLayout>
#include <QShowEvent>
PlacesPanel::PlacesPanel(QWidget* parent) :
KFilePlacesView(parent),
m_mouseButtons(Qt::NoButton)
Panel(parent),
m_controller(0),
m_model(0)
{
setDropOnPlaceEnabled(true);
connect(this, SIGNAL(urlsDropped(KUrl,QDropEvent*,QWidget*)),
this, SLOT(slotUrlsDropped(KUrl,QDropEvent*,QWidget*)));
connect(this, SIGNAL(urlChanged(KUrl)),
this, SLOT(emitExtendedUrlChangedSignal(KUrl)));
}
PlacesPanel::~PlacesPanel()
{
}
void PlacesPanel::mousePressEvent(QMouseEvent* event)
bool PlacesPanel::urlChanged()
{
m_mouseButtons = event->buttons();
KFilePlacesView::mousePressEvent(event);
return true;
}
void PlacesPanel::showEvent(QShowEvent* event)
{
if (event->spontaneous()) {
Panel::showEvent(event);
return;
}
if (!m_controller) {
// Postpone the creating of the controller to the first show event.
// This assures that no performance and memory overhead is given when the folders panel is not
// used at all and stays invisible.
KStandardItemListView* view = new KStandardItemListView();
m_model = new KStandardItemModel(this);
m_model->appendItem(new KStandardItem("Temporary"));
m_model->appendItem(new KStandardItem("out of"));
m_model->appendItem(new KStandardItem("order. Press"));
m_model->appendItem(new KStandardItem("F9 and use"));
m_model->appendItem(new KStandardItem("the left icon"));
m_model->appendItem(new KStandardItem("of the location"));
m_model->appendItem(new KStandardItem("bar instead."));
m_controller = new KItemListController(m_model, view, this);
KItemListContainer* container = new KItemListContainer(m_controller, this);
container->setEnabledFrame(false);
QVBoxLayout* layout = new QVBoxLayout(this);
layout->setMargin(0);
layout->addWidget(container);
}
Panel::showEvent(event);
}
void PlacesPanel::slotUrlsDropped(const KUrl& dest, QDropEvent* event, QWidget* parent)
@ -51,9 +86,4 @@ void PlacesPanel::slotUrlsDropped(const KUrl& dest, QDropEvent* event, QWidget*
DragAndDropHelper::dropUrls(KFileItem(), dest, event);
}
void PlacesPanel::emitExtendedUrlChangedSignal(const KUrl& url)
{
emit urlChanged(url, m_mouseButtons);
}
#include "placespanel.moc"

View file

@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (C) 2008 by Peter Penz <peter.penz19@gmail.com> *
* Copyright (C) 2008-2012 by Peter Penz <peter.penz19@gmail.com> *
* Copyright (C) 2010 by Christian Muehlhaeuser <muesli@gmail.com> *
* *
* This program is free software; you can redistribute it and/or modify *
@ -21,12 +21,15 @@
#ifndef PLACESPANEL_H
#define PLACESPANEL_H
#include <kfileplacesview.h>
#include <panels/panel.h>
class KItemListController;
class KStandardItemModel;
/**
* @brief Combines bookmarks and mounted devices as list.
*/
class PlacesPanel : public KFilePlacesView
class PlacesPanel : public Panel
{
Q_OBJECT
@ -34,18 +37,16 @@ public:
PlacesPanel(QWidget* parent);
virtual ~PlacesPanel();
signals:
void urlChanged(const KUrl& url, Qt::MouseButtons buttons);
protected:
virtual void mousePressEvent(QMouseEvent* event);
virtual bool urlChanged();
virtual void showEvent(QShowEvent* event);
private slots:
void slotUrlsDropped(const KUrl& dest, QDropEvent* event, QWidget* parent);
void emitExtendedUrlChangedSignal(const KUrl& url);
private:
Qt::MouseButtons m_mouseButtons;
KItemListController* m_controller;
KStandardItemModel* m_model;
};
#endif // PLACESPANEL_H

View file

@ -297,7 +297,7 @@ void ViewPropertiesDialog::configureAdditionalInfo()
// makes no sense and leads to a usability problem as no viewport area is available
// anymore. Hence as fallback provide at least a size and date column.
visibleRoles.clear();
visibleRoles.append("name");
visibleRoles.append("text");
visibleRoles.append("size");
visibleRoles.append("date");
m_viewProps->setVisibleRoles(visibleRoles);

View file

@ -114,13 +114,13 @@ void KFileItemModelTest::testDefaultRoles()
{
const QSet<QByteArray> roles = m_model->roles();
QCOMPARE(roles.count(), 2);
QVERIFY(roles.contains("name"));
QVERIFY(roles.contains("text"));
QVERIFY(roles.contains("isDir"));
}
void KFileItemModelTest::testDefaultSortRole()
{
QCOMPARE(m_model->sortRole(), QByteArray("name"));
QCOMPARE(m_model->sortRole(), QByteArray("text"));
QStringList files;
files << "c.txt" << "a.txt" << "b.txt";
@ -131,9 +131,9 @@ void KFileItemModelTest::testDefaultSortRole()
QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout));
QCOMPARE(m_model->count(), 3);
QCOMPARE(m_model->data(0)["name"].toString(), QString("a.txt"));
QCOMPARE(m_model->data(1)["name"].toString(), QString("b.txt"));
QCOMPARE(m_model->data(2)["name"].toString(), QString("c.txt"));
QCOMPARE(m_model->data(0)["text"].toString(), QString("a.txt"));
QCOMPARE(m_model->data(1)["text"].toString(), QString("b.txt"));
QCOMPARE(m_model->data(2)["text"].toString(), QString("c.txt"));
}
void KFileItemModelTest::testDefaultGroupedSorting()
@ -269,7 +269,7 @@ void KFileItemModelTest::testSetDataWithModifiedSortRole()
// Changing the value of a sort-role must result in
// a reordering of the items.
QCOMPARE(m_model->sortRole(), QByteArray("name"));
QCOMPARE(m_model->sortRole(), QByteArray("text"));
QStringList files;
files << "a.txt" << "b.txt" << "c.txt";
@ -572,7 +572,7 @@ void KFileItemModelTest::testSorting()
QDateTime now = QDateTime::currentDateTime();
QSet<QByteArray> roles;
roles.insert("name");
roles.insert("text");
roles.insert("isExpanded");
roles.insert("isExpandable");
roles.insert("expandedParentsCount");
@ -601,7 +601,7 @@ void KFileItemModelTest::testSorting()
QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout));
// Default: Sort by Name, ascending
QCOMPARE(m_model->sortRole(), QByteArray("name"));
QCOMPARE(m_model->sortRole(), QByteArray("text"));
QCOMPARE(m_model->sortOrder(), Qt::AscendingOrder);
QVERIFY(m_model->sortDirectoriesFirst());
QVERIFY(!m_model->showHiddenFiles());
@ -611,7 +611,7 @@ void KFileItemModelTest::testSorting()
// Sort by Name, ascending, 'Sort Folders First' disabled
m_model->setSortDirectoriesFirst(false);
QCOMPARE(m_model->sortRole(), QByteArray("name"));
QCOMPARE(m_model->sortRole(), QByteArray("text"));
QCOMPARE(m_model->sortOrder(), Qt::AscendingOrder);
QCOMPARE(itemsInModel(), QStringList() << "a" << "b" << "c" << "c-1" << "c-2" << "c-3" << "d" << "e");
QCOMPARE(spyItemsMoved.count(), 1);
@ -620,7 +620,7 @@ void KFileItemModelTest::testSorting()
// Sort by Name, descending
m_model->setSortDirectoriesFirst(true);
m_model->setSortOrder(Qt::DescendingOrder);
QCOMPARE(m_model->sortRole(), QByteArray("name"));
QCOMPARE(m_model->sortRole(), QByteArray("text"));
QCOMPARE(m_model->sortOrder(), Qt::DescendingOrder);
QCOMPARE(itemsInModel(), QStringList() << "c" << "c-2" << "c-3" << "c-1" << "e" << "d" << "b" << "a");
QCOMPARE(spyItemsMoved.count(), 2);
@ -654,7 +654,7 @@ void KFileItemModelTest::testSorting()
QCOMPARE(spyItemsMoved.takeFirst().at(1).value<QList<int> >(), QList<int>() << 2 << 4 << 5 << 3 << 0 << 1 << 6 << 7);
// Sort by Name, ascending, 'Sort Folders First' disabled
m_model->setSortRole("name");
m_model->setSortRole("text");
QCOMPARE(m_model->sortOrder(), Qt::AscendingOrder);
QVERIFY(!m_model->sortDirectoriesFirst());
QCOMPARE(itemsInModel(), QStringList() << "a" << "b" << "c" << "c-1" << "c-2" << "c-3" << "d" << "e");
@ -800,7 +800,7 @@ QStringList KFileItemModelTest::itemsInModel() const
{
QStringList items;
for (int i = 0; i < m_model->count(); i++) {
items << m_model->data(i).value("name").toString();
items << m_model->data(i).value("text").toString();
}
return items;
}

View file

@ -33,7 +33,7 @@ namespace {
const int DefaultTimeout = 2000;
};
Q_DECLARE_METATYPE(KFileItemListView::Layout);
Q_DECLARE_METATYPE(KFileItemListView::ItemLayout);
Q_DECLARE_METATYPE(Qt::Orientation);
Q_DECLARE_METATYPE(KItemListController::SelectionBehavior);
Q_DECLARE_METATYPE(QSet<int>);
@ -79,15 +79,13 @@ void KItemListControllerTest::initTestCase()
m_testDir = new TestDir();
m_model = new KFileItemModel();
m_container = new KItemListContainer();
m_view = new KFileItemListView();
m_controller = new KItemListController(m_model, m_view, this);
m_container = new KItemListContainer(m_controller);
m_controller = m_container->controller();
m_controller->setSelectionBehavior(KItemListController::MultiSelection);
m_selectionManager = m_controller->selectionManager();
m_view = new KFileItemListView();
m_controller->setView(m_view);
m_controller->setModel(m_model);
QStringList files;
files
<< "a1" << "a2" << "a3"
@ -106,15 +104,8 @@ void KItemListControllerTest::initTestCase()
void KItemListControllerTest::cleanupTestCase()
{
delete m_view;
m_view = 0;
delete m_container;
m_container = 0;
m_controller = 0;
delete m_model;
m_model = 0;
delete m_testDir;
m_testDir = 0;
@ -187,15 +178,15 @@ Q_DECLARE_METATYPE(QList<keyPressViewStatePair>);
*/
void KItemListControllerTest::testKeyboardNavigation_data()
{
QTest::addColumn<KFileItemListView::Layout>("layout");
QTest::addColumn<KFileItemListView::ItemLayout>("layout");
QTest::addColumn<Qt::Orientation>("scrollOrientation");
QTest::addColumn<int>("columnCount");
QTest::addColumn<KItemListController::SelectionBehavior>("selectionBehavior");
QTest::addColumn<bool>("groupingEnabled");
QTest::addColumn<QList<QPair<KeyPress, ViewState> > >("testList");
QList<KFileItemListView::Layout> layoutList;
QHash<KFileItemListView::Layout, QString> layoutNames;
QList<KFileItemListView::ItemLayout> layoutList;
QHash<KFileItemListView::ItemLayout, QString> layoutNames;
layoutList.append(KFileItemListView::IconsLayout);
layoutNames[KFileItemListView::IconsLayout] = "Icons";
layoutList.append(KFileItemListView::CompactLayout);
@ -219,7 +210,7 @@ void KItemListControllerTest::testKeyboardNavigation_data()
groupingEnabledList.append(true);
groupingEnabledNames[true] = "grouping enabled";
foreach (KFileItemListView::Layout layout, layoutList) {
foreach (KFileItemListView::ItemLayout layout, layoutList) {
// The following settings depend on the layout.
// Note that 'columns' are actually 'rows' in
// Compact layout.
@ -443,7 +434,7 @@ void KItemListControllerTest::testKeyboardNavigation_data()
*/
void KItemListControllerTest::testKeyboardNavigation()
{
QFETCH(KFileItemListView::Layout, layout);
QFETCH(KFileItemListView::ItemLayout, layout);
QFETCH(Qt::Orientation, scrollOrientation);
QFETCH(int, columnCount);
QFETCH(KItemListController::SelectionBehavior, selectionBehavior);

View file

@ -26,8 +26,9 @@
#include <KDebug>
DolphinFileItemListWidget::DolphinFileItemListWidget(QGraphicsItem* parent) :
KFileItemListWidget(parent)
DolphinFileItemListWidget::DolphinFileItemListWidget(KItemListWidgetInformant* informant,
QGraphicsItem* parent) :
KFileItemListWidget(informant, parent)
{
}

View file

@ -36,7 +36,7 @@ class LIBDOLPHINPRIVATE_EXPORT DolphinFileItemListWidget : public KFileItemListW
Q_OBJECT
public:
DolphinFileItemListWidget(QGraphicsItem* parent);
DolphinFileItemListWidget(KItemListWidgetInformant* informant, QGraphicsItem* parent);
virtual ~DolphinFileItemListWidget();
protected:

View file

@ -17,13 +17,12 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include "dolphinitemlistcontainer.h"
#include "dolphinitemlistview.h"
#include "dolphin_generalsettings.h"
#include "dolphin_iconsmodesettings.h"
#include "dolphin_detailsmodesettings.h"
#include "dolphin_compactmodesettings.h"
#include "dolphinfileitemlistwidget.h"
#include <kitemviews/kfileitemlistview.h>
@ -38,59 +37,20 @@
#include "zoomlevelinfo.h"
DolphinItemListContainer::DolphinItemListContainer(QWidget* parent) :
KItemListContainer(parent),
m_zoomLevel(0),
m_fileItemListView(0)
DolphinItemListView::DolphinItemListView(QGraphicsWidget* parent) :
KFileItemListView(parent),
m_zoomLevel(0)
{
controller()->setModel(new KFileItemModel(this));
m_fileItemListView = new KFileItemListView();
controller()->setView(m_fileItemListView);
m_fileItemListView->setWidgetCreator(new KItemListWidgetCreator<DolphinFileItemListWidget>());
m_fileItemListView->setEnabledSelectionToggles(GeneralSettings::showSelectionToggle());
m_fileItemListView->setEnlargeSmallPreviews(GeneralSettings::enlargeSmallPreviews());
updateAutoActivationDelay();
updateFont();
updateGridSize();
}
DolphinItemListContainer::~DolphinItemListContainer()
DolphinItemListView::~DolphinItemListView()
{
writeSettings();
controller()->setView(0);
delete m_fileItemListView;
m_fileItemListView = 0;
}
void DolphinItemListContainer::setPreviewsShown(bool show)
{
beginTransaction();
m_fileItemListView->setPreviewsShown(show);
updateGridSize();
endTransaction();
}
bool DolphinItemListContainer::previewsShown() const
{
return m_fileItemListView->previewsShown();
}
void DolphinItemListContainer::setVisibleRoles(const QList<QByteArray>& roles)
{
m_fileItemListView->setVisibleRoles(roles);
updateGridSize();
}
QList<QByteArray> DolphinItemListContainer::visibleRoles() const
{
return m_fileItemListView->visibleRoles();
}
void DolphinItemListContainer::setZoomLevel(int level)
void DolphinItemListView::setZoomLevel(int level)
{
if (level < ZoomLevelInfo::minimumLevel()) {
level = ZoomLevelInfo::minimumLevel();
@ -116,76 +76,24 @@ void DolphinItemListContainer::setZoomLevel(int level)
updateGridSize();
}
int DolphinItemListContainer::zoomLevel() const
int DolphinItemListView::zoomLevel() const
{
return m_zoomLevel;
}
void DolphinItemListContainer::setItemLayout(KFileItemListView::Layout layout)
{
if (layout == itemLayout()) {
return;
}
beginTransaction();
m_fileItemListView->setItemLayout(layout);
switch (layout) {
case KFileItemListView::IconsLayout:
m_fileItemListView->setScrollOrientation(Qt::Vertical);
m_fileItemListView->setHeaderVisible(false);
m_fileItemListView->setSupportsItemExpanding(false);
break;
case KFileItemListView::DetailsLayout:
m_fileItemListView->setScrollOrientation(Qt::Vertical);
m_fileItemListView->setHeaderVisible(true);
m_fileItemListView->setSupportsItemExpanding(DetailsModeSettings::expandableFolders());
break;
case KFileItemListView::CompactLayout:
m_fileItemListView->setScrollOrientation(Qt::Horizontal);
m_fileItemListView->setHeaderVisible(false);
m_fileItemListView->setSupportsItemExpanding(false);
break;
default:
Q_ASSERT(false);
break;
}
updateFont();
updateGridSize();
endTransaction();
}
KFileItemListView::Layout DolphinItemListContainer::itemLayout() const
{
return m_fileItemListView->itemLayout();
}
void DolphinItemListContainer::beginTransaction()
{
m_fileItemListView->beginTransaction();
}
void DolphinItemListContainer::endTransaction()
{
m_fileItemListView->endTransaction();
}
void DolphinItemListContainer::readSettings()
void DolphinItemListView::readSettings()
{
ViewModeSettings settings(viewMode());
settings.readConfig();
beginTransaction();
m_fileItemListView->setEnabledSelectionToggles(GeneralSettings::showSelectionToggle());
setEnabledSelectionToggles(GeneralSettings::showSelectionToggle());
const bool expandableFolders = (itemLayout() && KFileItemListView::DetailsLayout) &&
DetailsModeSettings::expandableFolders();
m_fileItemListView->setSupportsItemExpanding(expandableFolders);
setSupportsItemExpanding(expandableFolders);
updateAutoActivationDelay();
updateFont();
updateGridSize();
@ -194,26 +102,59 @@ void DolphinItemListContainer::readSettings()
<< "directorythumbnail"
<< "imagethumbnail"
<< "jpegthumbnail");
m_fileItemListView->setEnabledPlugins(plugins);
setEnabledPlugins(plugins);
endTransaction();
}
void DolphinItemListContainer::writeSettings()
void DolphinItemListView::writeSettings()
{
IconsModeSettings::self()->writeConfig();
CompactModeSettings::self()->writeConfig();
DetailsModeSettings::self()->writeConfig();
}
void DolphinItemListContainer::updateGridSize()
KItemListWidgetCreatorBase* DolphinItemListView::defaultWidgetCreator() const
{
return new KItemListWidgetCreator<DolphinFileItemListWidget>();
}
void DolphinItemListView::onItemLayoutChanged(ItemLayout current, ItemLayout previous)
{
Q_UNUSED(previous);
if (current == DetailsLayout) {
setSupportsItemExpanding(DetailsModeSettings::expandableFolders());
setHeaderVisible(true);
} else {
setHeaderVisible(false);
}
updateFont();
updateGridSize();
}
void DolphinItemListView::onPreviewsShownChanged(bool shown)
{
Q_UNUSED(shown);
updateGridSize();
}
void DolphinItemListView::onVisibleRolesChanged(const QList<QByteArray>& current,
const QList<QByteArray>& previous)
{
KFileItemListView::onVisibleRolesChanged(current, previous);
updateGridSize();
}
void DolphinItemListView::updateGridSize()
{
const ViewModeSettings settings(viewMode());
// Calculate the size of the icon
const int iconSize = previewsShown() ? settings.previewSize() : settings.iconSize();
m_zoomLevel = ZoomLevelInfo::zoomLevelForIconSize(QSize(iconSize, iconSize));
KItemListStyleOption styleOption = m_fileItemListView->styleOption();
KItemListStyleOption option = styleOption();
const int padding = 2;
int horizontalMargin = 0;
@ -241,13 +182,13 @@ void DolphinItemListContainer::updateGridSize()
itemWidth = iconSize + padding * 2;
}
itemHeight = padding * 3 + iconSize + styleOption.fontMetrics.lineSpacing();
itemHeight = padding * 3 + iconSize + option.fontMetrics.lineSpacing();
if (IconsModeSettings::maximumTextLines() > 0) {
// A restriction is given for the maximum number of textlines (0 means
// having no restriction)
const int additionalInfoCount = m_fileItemListView->visibleRoles().count() - 1;
const int additionalInfoCount = visibleRoles().count() - 1;
const int maxAdditionalLines = additionalInfoCount + IconsModeSettings::maximumTextLines();
maxTextSize.rheight() = styleOption.fontMetrics.lineSpacing() * maxAdditionalLines;
maxTextSize.rheight() = option.fontMetrics.lineSpacing() * maxAdditionalLines;
}
horizontalMargin = 4;
@ -255,14 +196,14 @@ void DolphinItemListContainer::updateGridSize()
break;
}
case KFileItemListView::CompactLayout: {
itemWidth = padding * 4 + iconSize + styleOption.fontMetrics.height() * 5;
const int textLinesCount = m_fileItemListView->visibleRoles().count();
itemHeight = padding * 2 + qMax(iconSize, textLinesCount * styleOption.fontMetrics.lineSpacing());
itemWidth = padding * 4 + iconSize + option.fontMetrics.height() * 5;
const int textLinesCount = visibleRoles().count();
itemHeight = padding * 2 + qMax(iconSize, textLinesCount * option.fontMetrics.lineSpacing());
if (CompactModeSettings::maximumTextWidthIndex() > 0) {
// A restriction is given for the maximum width of the text (0 means
// having no restriction)
maxTextSize.rwidth() = styleOption.fontMetrics.height() * 10 *
maxTextSize.rwidth() = option.fontMetrics.height() * 10 *
CompactModeSettings::maximumTextWidthIndex();
}
@ -271,7 +212,7 @@ void DolphinItemListContainer::updateGridSize()
}
case KFileItemListView::DetailsLayout: {
itemWidth = -1;
itemHeight = padding * 2 + qMax(iconSize, styleOption.fontMetrics.lineSpacing());
itemHeight = padding * 2 + qMax(iconSize, option.fontMetrics.lineSpacing());
break;
}
default:
@ -282,20 +223,20 @@ void DolphinItemListContainer::updateGridSize()
}
// Apply the calculated values
styleOption.padding = padding;
styleOption.horizontalMargin = horizontalMargin;
styleOption.verticalMargin = verticalMargin;
styleOption.iconSize = iconSize;
styleOption.maxTextSize = maxTextSize;
m_fileItemListView->beginTransaction();
m_fileItemListView->setStyleOption(styleOption);
m_fileItemListView->setItemSize(QSizeF(itemWidth, itemHeight));
m_fileItemListView->endTransaction();
option.padding = padding;
option.horizontalMargin = horizontalMargin;
option.verticalMargin = verticalMargin;
option.iconSize = iconSize;
option.maxTextSize = maxTextSize;
beginTransaction();
setStyleOption(option);
setItemSize(QSizeF(itemWidth, itemHeight));
endTransaction();
}
void DolphinItemListContainer::updateFont()
void DolphinItemListView::updateFont()
{
KItemListStyleOption styleOption = m_fileItemListView->styleOption();
KItemListStyleOption option = styleOption();
const ViewModeSettings settings(viewMode());
@ -304,19 +245,13 @@ void DolphinItemListContainer::updateFont()
font.setWeight(settings.fontWeight());
font.setPointSizeF(settings.fontSize());
styleOption.font = font;
styleOption.fontMetrics = QFontMetrics(font);
option.font = font;
option.fontMetrics = QFontMetrics(font);
m_fileItemListView->setStyleOption(styleOption);
setStyleOption(option);
}
void DolphinItemListContainer::updateAutoActivationDelay()
{
const int delay = GeneralSettings::autoExpandFolders() ? 750 : -1;
controller()->setAutoActivationDelay(delay);
}
ViewModeSettings::ViewMode DolphinItemListContainer::viewMode() const
ViewModeSettings::ViewMode DolphinItemListView::viewMode() const
{
ViewModeSettings::ViewMode mode;
@ -332,4 +267,4 @@ ViewModeSettings::ViewMode DolphinItemListContainer::viewMode() const
return mode;
}
#include "dolphinitemlistcontainer.moc"
#include "dolphinitemlistview.moc"

View file

@ -17,11 +17,10 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#ifndef DOLPHINITEMLISTCONTAINER_H
#define DOLPHINITEMLISTCONTAINER_H
#ifndef DOLPHINITEMLISTVIEW_H
#define DOLPHINITEMLISTVIEW_H
#include <kitemviews/kfileitemlistview.h>
#include <kitemviews/kitemlistcontainer.h>
#include <settings/viewmodes/viewmodesettings.h>
#include <libdolphin_export.h>
@ -29,57 +28,41 @@
class KFileItemListView;
/**
* @brief Extends KItemListContainer by Dolphin specific properties.
* @brief Dolphin specific view-implementation.
*
* The view and model for KFileItems are created automatically when
* instantating KItemListContainer.
*
* The Dolphin settings of the icons-, compact- and details-view are
* converted internally to properties that can be used to configure e.g.
* the item-size and visible roles of the KItemListView.
* Offers zoom-level support and takes care for translating
* the view-properties into the corresponding KItemListView
* properties.
*/
class LIBDOLPHINPRIVATE_EXPORT DolphinItemListContainer : public KItemListContainer
class LIBDOLPHINPRIVATE_EXPORT DolphinItemListView : public KFileItemListView
{
Q_OBJECT
public:
explicit DolphinItemListContainer(QWidget* parent = 0);
virtual ~DolphinItemListContainer();
void setPreviewsShown(bool show);
bool previewsShown() const;
void setVisibleRoles(const QList<QByteArray>& roles);
QList<QByteArray> visibleRoles() const;
explicit DolphinItemListView(QGraphicsWidget* parent = 0);
virtual ~DolphinItemListView();
void setZoomLevel(int level);
int zoomLevel() const;
void setItemLayout(KFileItemListView::Layout layout);
KFileItemListView::Layout itemLayout() const;
void beginTransaction();
void endTransaction();
void readSettings();
void writeSettings();
protected:
virtual KItemListWidgetCreatorBase* defaultWidgetCreator() const;
virtual void onItemLayoutChanged(ItemLayout current, ItemLayout previous);
virtual void onPreviewsShownChanged(bool shown);
virtual void onVisibleRolesChanged(const QList<QByteArray>& current,
const QList<QByteArray>& previous);
private:
void updateGridSize();
void updateFont();
/**
* Updates the auto activation delay of the itemlist controller
* dependent on the 'autoExpand' setting from the general settings.
*/
void updateAutoActivationDelay();
ViewModeSettings::ViewMode viewMode() const;
private:
int m_zoomLevel;
KFileItemListView* m_fileItemListView;
};
#endif

View file

@ -42,6 +42,7 @@
#include <KLocale>
#include <kitemviews/kfileitemmodel.h>
#include <kitemviews/kfileitemlistview.h>
#include <kitemviews/kitemlistcontainer.h>
#include <kitemviews/kitemlistheader.h>
#include <kitemviews/kitemlistselectionmanager.h>
#include <kitemviews/kitemlistview.h>
@ -62,7 +63,7 @@
#include "dolphinnewfilemenuobserver.h"
#include "dolphin_detailsmodesettings.h"
#include "dolphin_generalsettings.h"
#include "dolphinitemlistcontainer.h"
#include "dolphinitemlistview.h"
#include "draganddrophelper.h"
#include "renamedialog.h"
#include "versioncontrol/versioncontrolobserver.h"
@ -90,6 +91,8 @@ DolphinView::DolphinView(const KUrl& url, QWidget* parent) :
m_mode(DolphinView::IconsView),
m_visibleRoles(),
m_topLayout(0),
m_model(0),
m_view(0),
m_container(0),
m_toolTipManager(0),
m_selectionChangedTimer(0),
@ -115,14 +118,23 @@ DolphinView::DolphinView(const KUrl& url, QWidget* parent) :
connect(m_selectionChangedTimer, SIGNAL(timeout()),
this, SLOT(emitSelectionChangedSignal()));
m_container = new DolphinItemListContainer(this);
m_container->setVisibleRoles(QList<QByteArray>() << "name");
m_model = new KFileItemModel(this);
m_view = new DolphinItemListView();
m_view->setEnabledSelectionToggles(GeneralSettings::showSelectionToggle());
m_view->setEnlargeSmallPreviews(GeneralSettings::enlargeSmallPreviews());
m_view->setVisibleRoles(QList<QByteArray>() << "text");
applyModeToView();
KItemListController* controller = new KItemListController(m_model, m_view, this);
const int delay = GeneralSettings::autoExpandFolders() ? 750 : -1;
controller->setAutoActivationDelay(delay);
m_container = new KItemListContainer(controller, this);
m_container->installEventFilter(this);
setFocusProxy(m_container);
connect(m_container->horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(hideToolTip()));
connect(m_container->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(hideToolTip()));
KItemListController* controller = m_container->controller();
controller->setSelectionBehavior(KItemListController::MultiSelection);
connect(controller, SIGNAL(itemActivated(int)), this, SLOT(slotItemActivated(int)));
connect(controller, SIGNAL(itemsActivated(QSet<int>)), this, SLOT(slotItemsActivated(QSet<int>)));
@ -136,30 +148,28 @@ DolphinView::DolphinView(const KUrl& url, QWidget* parent) :
connect(controller, SIGNAL(itemDropEvent(int,QGraphicsSceneDragDropEvent*)), this, SLOT(slotItemDropEvent(int,QGraphicsSceneDragDropEvent*)));
connect(controller, SIGNAL(modelChanged(KItemModelBase*,KItemModelBase*)), this, SLOT(slotModelChanged(KItemModelBase*,KItemModelBase*)));
KFileItemModel* model = fileItemModel();
connect(model, SIGNAL(directoryLoadingStarted()), this, SLOT(slotDirectoryLoadingStarted()));
connect(model, SIGNAL(directoryLoadingCompleted()), this, SLOT(slotDirectoryLoadingCompleted()));
connect(model, SIGNAL(directoryLoadingProgress(int)), this, SIGNAL(directoryLoadingProgress(int)));
connect(model, SIGNAL(directorySortingProgress(int)), this, SIGNAL(directorySortingProgress(int)));
connect(model, SIGNAL(itemsChanged(KItemRangeList,QSet<QByteArray>)),
connect(m_model, SIGNAL(directoryLoadingStarted()), this, SLOT(slotDirectoryLoadingStarted()));
connect(m_model, SIGNAL(directoryLoadingCompleted()), this, SLOT(slotDirectoryLoadingCompleted()));
connect(m_model, SIGNAL(directoryLoadingProgress(int)), this, SIGNAL(directoryLoadingProgress(int)));
connect(m_model, SIGNAL(directorySortingProgress(int)), this, SIGNAL(directorySortingProgress(int)));
connect(m_model, SIGNAL(itemsChanged(KItemRangeList,QSet<QByteArray>)),
this, SLOT(slotItemsChanged()));
connect(model, SIGNAL(itemsRemoved(KItemRangeList)), this, SIGNAL(itemCountChanged()));
connect(model, SIGNAL(itemsInserted(KItemRangeList)), this, SIGNAL(itemCountChanged()));
connect(model, SIGNAL(infoMessage(QString)), this, SIGNAL(infoMessage(QString)));
connect(model, SIGNAL(errorMessage(QString)), this, SIGNAL(errorMessage(QString)));
connect(model, SIGNAL(directoryRedirection(KUrl,KUrl)), this, SLOT(slotDirectoryRedirection(KUrl,KUrl)));
connect(m_model, SIGNAL(itemsRemoved(KItemRangeList)), this, SIGNAL(itemCountChanged()));
connect(m_model, SIGNAL(itemsInserted(KItemRangeList)), this, SIGNAL(itemCountChanged()));
connect(m_model, SIGNAL(infoMessage(QString)), this, SIGNAL(infoMessage(QString)));
connect(m_model, SIGNAL(errorMessage(QString)), this, SIGNAL(errorMessage(QString)));
connect(m_model, SIGNAL(directoryRedirection(KUrl,KUrl)), this, SLOT(slotDirectoryRedirection(KUrl,KUrl)));
KItemListView* view = controller->view();
view->installEventFilter(this);
connect(view, SIGNAL(sortOrderChanged(Qt::SortOrder,Qt::SortOrder)),
m_view->installEventFilter(this);
connect(m_view, SIGNAL(sortOrderChanged(Qt::SortOrder,Qt::SortOrder)),
this, SLOT(slotSortOrderChangedByHeader(Qt::SortOrder,Qt::SortOrder)));
connect(view, SIGNAL(sortRoleChanged(QByteArray,QByteArray)),
connect(m_view, SIGNAL(sortRoleChanged(QByteArray,QByteArray)),
this, SLOT(slotSortRoleChangedByHeader(QByteArray,QByteArray)));
connect(view, SIGNAL(visibleRolesChanged(QList<QByteArray>,QList<QByteArray>)),
connect(m_view, SIGNAL(visibleRolesChanged(QList<QByteArray>,QList<QByteArray>)),
this, SLOT(slotVisibleRolesChangedByHeader(QList<QByteArray>,QList<QByteArray>)));
connect(view, SIGNAL(roleEditingFinished(int,QByteArray,QVariant)),
connect(m_view, SIGNAL(roleEditingFinished(int,QByteArray,QVariant)),
this, SLOT(slotRoleEditingFinished(int,QByteArray,QVariant)));
connect(view->header(), SIGNAL(columnWidthChanged(QByteArray,qreal,qreal)),
connect(m_view->header(), SIGNAL(columnWidthChanged(QByteArray,qreal,qreal)),
this, SLOT(slotHeaderColumnWidthChanged(QByteArray,qreal,qreal)));
KItemListSelectionManager* selectionManager = controller->selectionManager();
@ -169,7 +179,7 @@ DolphinView::DolphinView(const KUrl& url, QWidget* parent) :
m_toolTipManager = new ToolTipManager(this);
m_versionControlObserver = new VersionControlObserver(this);
m_versionControlObserver->setModel(model);
m_versionControlObserver->setModel(m_model);
connect(m_versionControlObserver, SIGNAL(infoMessage(QString)), this, SIGNAL(infoMessage(QString)));
connect(m_versionControlObserver, SIGNAL(errorMessage(QString)), this, SIGNAL(errorMessage(QString)));
connect(m_versionControlObserver, SIGNAL(operationCompletedMessage(QString)), this, SIGNAL(operationCompletedMessage(QString)));
@ -248,19 +258,18 @@ void DolphinView::setPreviewsShown(bool show)
ViewProperties props(url());
props.setPreviewsShown(show);
m_container->setPreviewsShown(show);
m_view->setPreviewsShown(show);
emit previewsShownChanged(show);
}
bool DolphinView::previewsShown() const
{
return m_container->previewsShown();
return m_view->previewsShown();
}
void DolphinView::setHiddenFilesShown(bool show)
{
KFileItemModel* model = fileItemModel();
if (model->showHiddenFiles() == show) {
if (m_model->showHiddenFiles() == show) {
return;
}
@ -271,13 +280,13 @@ void DolphinView::setHiddenFilesShown(bool show)
ViewProperties props(url());
props.setHiddenFilesShown(show);
model->setShowHiddenFiles(show);
m_model->setShowHiddenFiles(show);
emit hiddenFilesShownChanged(show);
}
bool DolphinView::hiddenFilesShown() const
{
return fileItemModel()->showHiddenFiles();
return m_model->showHiddenFiles();
}
void DolphinView::setGroupedSorting(bool grouped)
@ -297,18 +306,17 @@ void DolphinView::setGroupedSorting(bool grouped)
bool DolphinView::groupedSorting() const
{
return fileItemModel()->groupedSorting();
return m_model->groupedSorting();
}
KFileItemList DolphinView::items() const
{
KFileItemList list;
const KFileItemModel* model = fileItemModel();
const int itemCount = model->count();
const int itemCount = m_model->count();
list.reserve(itemCount);
for (int i = 0; i < itemCount; ++i) {
list.append(model->fileItem(i));
list.append(m_model->fileItem(i));
}
return list;
@ -316,12 +324,11 @@ KFileItemList DolphinView::items() const
int DolphinView::itemsCount() const
{
return fileItemModel()->count();
return m_model->count();
}
KFileItemList DolphinView::selectedItems() const
{
const KFileItemModel* model = fileItemModel();
const KItemListSelectionManager* selectionManager = m_container->controller()->selectionManager();
const QSet<int> selectedIndexes = selectionManager->selectedItems();
@ -329,7 +336,7 @@ KFileItemList DolphinView::selectedItems() const
QSetIterator<int> it(selectedIndexes);
while (it.hasNext()) {
const int index = it.next();
selectedItems.append(model->fileItem(index));
selectedItems.append(m_model->fileItem(index));
}
return selectedItems;
}
@ -355,11 +362,10 @@ void DolphinView::selectItems(const QRegExp& pattern, bool enabled)
const KItemListSelectionManager::SelectionMode mode = enabled
? KItemListSelectionManager::Select
: KItemListSelectionManager::Deselect;
const KFileItemModel* model = fileItemModel();
KItemListSelectionManager* selectionManager = m_container->controller()->selectionManager();
for (int index = 0; index < model->count(); index++) {
const KFileItem item = model->fileItem(index);
for (int index = 0; index < m_model->count(); index++) {
const KFileItem item = m_model->fileItem(index);
if (pattern.exactMatch(item.text())) {
// An alternative approach would be to store the matching items in a QSet<int> and
// select them in one go after the loop, but we'd need a new function
@ -373,7 +379,7 @@ void DolphinView::selectItems(const QRegExp& pattern, bool enabled)
void DolphinView::setZoomLevel(int level)
{
const int oldZoomLevel = zoomLevel();
m_container->setZoomLevel(level);
m_view->setZoomLevel(level);
if (zoomLevel() != oldZoomLevel) {
emit zoomLevelChanged(zoomLevel(), oldZoomLevel);
}
@ -381,7 +387,7 @@ void DolphinView::setZoomLevel(int level)
int DolphinView::zoomLevel() const
{
return m_container->zoomLevel();
return m_view->zoomLevel();
}
void DolphinView::setSortRole(const QByteArray& role)
@ -406,8 +412,7 @@ void DolphinView::setSortOrder(Qt::SortOrder order)
Qt::SortOrder DolphinView::sortOrder() const
{
KItemModelBase* model = fileItemModel();
return model->sortOrder();
return m_model->sortOrder();
}
void DolphinView::setSortFoldersFirst(bool foldersFirst)
@ -419,8 +424,7 @@ void DolphinView::setSortFoldersFirst(bool foldersFirst)
bool DolphinView::sortFoldersFirst() const
{
KFileItemModel* model = fileItemModel();
return model->sortDirectoriesFirst();
return m_model->sortDirectoriesFirst();
}
void DolphinView::setVisibleRoles(const QList<QByteArray>& roles)
@ -431,7 +435,7 @@ void DolphinView::setVisibleRoles(const QList<QByteArray>& roles)
props.setVisibleRoles(roles);
m_visibleRoles = roles;
m_container->setVisibleRoles(roles);
m_view->setVisibleRoles(roles);
emit visibleRolesChanged(m_visibleRoles, previousRoles);
}
@ -460,18 +464,21 @@ void DolphinView::reload()
void DolphinView::stopLoading()
{
fileItemModel()->cancelDirectoryLoading();
m_model->cancelDirectoryLoading();
}
void DolphinView::readSettings()
{
const int oldZoomLevel = m_container->zoomLevel();
const int oldZoomLevel = m_view->zoomLevel();
GeneralSettings::self()->readConfig();
m_container->readSettings();
m_view->readSettings();
applyViewProperties();
const int newZoomLevel = m_container->zoomLevel();
const int delay = GeneralSettings::autoExpandFolders() ? 750 : -1;
m_container->controller()->setAutoActivationDelay(delay);
const int newZoomLevel = m_view->zoomLevel();
if (newZoomLevel != oldZoomLevel) {
emit zoomLevelChanged(newZoomLevel, oldZoomLevel);
}
@ -480,17 +487,17 @@ void DolphinView::readSettings()
void DolphinView::writeSettings()
{
GeneralSettings::self()->writeConfig();
m_container->writeSettings();
m_view->writeSettings();
}
void DolphinView::setNameFilter(const QString& nameFilter)
{
fileItemModel()->setNameFilter(nameFilter);
m_model->setNameFilter(nameFilter);
}
QString DolphinView::nameFilter() const
{
return fileItemModel()->nameFilter();
return m_model->nameFilter();
}
QString DolphinView::statusBarText() const
@ -551,7 +558,7 @@ QList<QAction*> DolphinView::versionControlActions(const KFileItemList& items) c
QList<QAction*> actions;
if (items.isEmpty()) {
const KFileItem item = fileItemModel()->rootItem();
const KFileItem item = m_model->rootItem();
actions = m_versionControlObserver->actions(KFileItemList() << item);
} else {
actions = m_versionControlObserver->actions(items);
@ -575,7 +582,7 @@ void DolphinView::setUrl(const KUrl& url)
// applying the view properties, otherwise expensive operations
// might be done on the existing items although they get cleared
// anyhow afterwards by loadDirectory().
fileItemModel()->clear();
m_model->clear();
applyViewProperties();
loadDirectory(url);
@ -585,13 +592,13 @@ void DolphinView::setUrl(const KUrl& url)
void DolphinView::selectAll()
{
KItemListSelectionManager* selectionManager = m_container->controller()->selectionManager();
selectionManager->setSelected(0, fileItemModel()->count());
selectionManager->setSelected(0, m_model->count());
}
void DolphinView::invertSelection()
{
KItemListSelectionManager* selectionManager = m_container->controller()->selectionManager();
selectionManager->setSelected(0, fileItemModel()->count(), KItemListSelectionManager::Toggle);
selectionManager->setSelected(0, m_model->count(), KItemListSelectionManager::Toggle);
}
void DolphinView::clearSelection()
@ -607,8 +614,8 @@ void DolphinView::renameSelectedItems()
}
if (items.count() == 1) {
const int index = fileItemModel()->index(items.first());
m_container->controller()->view()->editRole(index, "name");
const int index = m_model->index(items.first());
m_container->controller()->view()->editRole(index, "text");
} else {
RenameDialog* dialog = new RenameDialog(this, items);
dialog->setAttribute(Qt::WA_DeleteOnClose);
@ -683,19 +690,19 @@ bool DolphinView::eventFilter(QObject* watched, QEvent* event)
break;
case QEvent::GraphicsSceneDragEnter:
if (watched == m_container->controller()->view()) {
if (watched == m_view) {
m_dragging = true;
}
break;
case QEvent::GraphicsSceneDragLeave:
if (watched == m_container->controller()->view()) {
if (watched == m_view) {
m_dragging = false;
}
break;
case QEvent::GraphicsSceneDrop:
if (watched == m_container->controller()->view()) {
if (watched == m_view) {
m_dragging = false;
}
default:
@ -731,7 +738,7 @@ void DolphinView::activate()
void DolphinView::slotItemActivated(int index)
{
const KFileItem item = fileItemModel()->fileItem(index);
const KFileItem item = m_model->fileItem(index);
if (!item.isNull()) {
emit itemActivated(item);
}
@ -743,11 +750,10 @@ void DolphinView::slotItemsActivated(const QSet<int>& indexes)
KFileItemList items;
KFileItemModel* model = fileItemModel();
QSetIterator<int> it(indexes);
while (it.hasNext()) {
const int index = it.next();
items.append(model->fileItem(index));
items.append(m_model->fileItem(index));
}
foreach (const KFileItem& item, items) {
@ -761,7 +767,7 @@ void DolphinView::slotItemsActivated(const QSet<int>& indexes)
void DolphinView::slotItemMiddleClicked(int index)
{
const KFileItem item = fileItemModel()->fileItem(index);
const KFileItem item = m_model->fileItem(index);
if (item.isDir() || isTabsForFilesEnabled()) {
emit tabRequested(item.url());
}
@ -769,7 +775,7 @@ void DolphinView::slotItemMiddleClicked(int index)
void DolphinView::slotItemContextMenuRequested(int index, const QPointF& pos)
{
const KFileItem item = fileItemModel()->fileItem(index);
const KFileItem item = m_model->fileItem(index);
emit requestContextMenu(pos.toPoint(), item, url(), QList<QAction*>());
}
@ -803,12 +809,12 @@ void DolphinView::slotHeaderContextMenuRequested(const QPointF& pos)
// Add all roles to the menu that can be shown or hidden by the user
const QList<KFileItemModel::RoleInfo> rolesInfo = KFileItemModel::rolesInformation();
foreach (const KFileItemModel::RoleInfo& info, rolesInfo) {
if (info.role == "name") {
// It should not be possible to hide the "name" role
if (info.role == "text") {
// It should not be possible to hide the "text" role
continue;
}
const QString text = fileItemModel()->roleDescription(info.role);
const QString text = m_model->roleDescription(info.role);
QAction* action = 0;
if (info.group.isEmpty()) {
action = menu->addAction(text);
@ -895,14 +901,14 @@ void DolphinView::slotHeaderColumnWidthChanged(const QByteArray& role, qreal cur
{
Q_UNUSED(previous);
const QList<QByteArray> visibleRoles = m_container->visibleRoles();
const QList<QByteArray> visibleRoles = m_view->visibleRoles();
ViewProperties props(url());
QList<int> columnWidths = props.headerColumnWidths();
if (columnWidths.count() != visibleRoles.count()) {
columnWidths.clear();
columnWidths.reserve(visibleRoles.count());
const KItemListHeader* header = m_container->controller()->view()->header();
const KItemListHeader* header = m_view->header();
foreach (const QByteArray& role, visibleRoles) {
const int width = header->columnWidth(role);
columnWidths.append(width);
@ -918,7 +924,7 @@ void DolphinView::slotHeaderColumnWidthChanged(const QByteArray& role, qreal cur
void DolphinView::slotItemHovered(int index)
{
const KFileItem item = fileItemModel()->fileItem(index);
const KFileItem item = m_model->fileItem(index);
if (GeneralSettings::showToolTips() && !m_dragging) {
QRectF itemRect = m_container->controller()->view()->itemContextRect(index);
@ -941,11 +947,11 @@ void DolphinView::slotItemUnhovered(int index)
void DolphinView::slotItemDropEvent(int index, QGraphicsSceneDragDropEvent* event)
{
KUrl destUrl;
KFileItem destItem = fileItemModel()->fileItem(index);
KFileItem destItem = m_model->fileItem(index);
if (destItem.isNull() || (!destItem.isDir() && !destItem.isDesktopFile())) {
// Use the URL of the view as drop target if the item is no directory
// or desktop-file
destItem = fileItemModel()->rootItem();
destItem = m_model->rootItem();
destUrl = url();
} else {
// The item represents a directory or desktop-file
@ -973,13 +979,16 @@ void DolphinView::slotModelChanged(KItemModelBase* current, KItemModelBase* prev
{
if (previous != 0) {
disconnect(previous, SIGNAL(directoryLoadingCompleted()), this, SLOT(slotDirectoryLoadingCompleted()));
m_versionControlObserver->setModel(0);
}
Q_ASSERT(qobject_cast<KFileItemModel*>(current));
connect(current, SIGNAL(loadingCompleted()), this, SLOT(slotDirectoryLoadingCompleted()));
if (current) {
Q_ASSERT(qobject_cast<KFileItemModel*>(current));
connect(current, SIGNAL(loadingCompleted()), this, SLOT(slotDirectoryLoadingCompleted()));
KFileItemModel* fileItemModel = static_cast<KFileItemModel*>(current);
m_versionControlObserver->setModel(fileItemModel);
KFileItemModel* fileItemModel = static_cast<KFileItemModel*>(current);
m_versionControlObserver->setModel(fileItemModel);
}
}
void DolphinView::slotMouseButtonPressed(int itemIndex, Qt::MouseButtons buttons)
@ -1034,8 +1043,7 @@ void DolphinView::updateSortOrder(Qt::SortOrder order)
ViewProperties props(url());
props.setSortOrder(order);
KItemModelBase* model = fileItemModel();
model->setSortOrder(order);
m_model->setSortOrder(order);
emit sortOrderChanged(order);
}
@ -1045,8 +1053,7 @@ void DolphinView::updateSortFoldersFirst(bool foldersFirst)
ViewProperties props(url());
props.setSortFoldersFirst(foldersFirst);
KFileItemModel* model = fileItemModel();
model->setSortDirectoriesFirst(foldersFirst);
m_model->setSortDirectoriesFirst(foldersFirst);
emit sortFoldersFirstChanged(foldersFirst);
}
@ -1082,7 +1089,7 @@ void DolphinView::restoreState(QDataStream& stream)
// Restore expanded folders (only relevant for the details view - will be ignored by the view in other view modes)
QSet<KUrl> urls;
stream >> urls;
fileItemModel()->restoreExpandedDirectories(urls);
m_model->restoreExpandedDirectories(urls);
}
void DolphinView::saveState(QDataStream& stream)
@ -1090,7 +1097,7 @@ void DolphinView::saveState(QDataStream& stream)
// Save the current item that has the keyboard focus
const int currentIndex = m_container->controller()->selectionManager()->currentItem();
if (currentIndex != -1) {
KFileItem item = fileItemModel()->fileItem(currentIndex);
KFileItem item = m_model->fileItem(currentIndex);
Q_ASSERT(!item.isNull()); // If the current index is valid a item must exist
KUrl currentItemUrl = item.url();
stream << currentItemUrl;
@ -1104,12 +1111,12 @@ void DolphinView::saveState(QDataStream& stream)
stream << QPoint(x, y);
// Save expanded folders (only relevant for the details view - the set will be empty in other view modes)
stream << fileItemModel()->expandedDirectories();
stream << m_model->expandedDirectories();
}
KFileItem DolphinView::rootItem() const
{
return fileItemModel()->rootItem();
return m_model->rootItem();
}
void DolphinView::observeCreatedItem(const KUrl& url)
@ -1147,7 +1154,7 @@ void DolphinView::updateViewState()
{
if (m_currentItemUrl != KUrl()) {
KItemListSelectionManager* selectionManager = m_container->controller()->selectionManager();
const int currentIndex = fileItemModel()->index(m_currentItemUrl);
const int currentIndex = m_model->index(m_currentItemUrl);
if (currentIndex != -1) {
selectionManager->setCurrentItem(currentIndex);
} else {
@ -1170,10 +1177,9 @@ void DolphinView::updateViewState()
KItemListSelectionManager* selectionManager = m_container->controller()->selectionManager();
QSet<int> selectedItems = selectionManager->selectedItems();
const KFileItemModel* model = fileItemModel();
foreach (const KUrl& url, m_selectedUrls) {
const int index = model->index(url);
const int index = m_model->index(url);
if (index >= 0) {
selectedItems.insert(index);
}
@ -1195,10 +1201,9 @@ void DolphinView::calculateItemCount(int& fileCount,
int& folderCount,
KIO::filesize_t& totalFileSize) const
{
const KFileItemModel* model = fileItemModel();
const int itemCount = model->count();
const int itemCount = m_model->count();
for (int i = 0; i < itemCount; ++i) {
const KFileItem item = model->fileItem(i);
const KFileItem item = m_model->fileItem(i);
if (item.isDir()) {
++folderCount;
} else {
@ -1258,7 +1263,7 @@ void DolphinView::slotItemsChanged()
void DolphinView::slotSortOrderChangedByHeader(Qt::SortOrder current, Qt::SortOrder previous)
{
Q_UNUSED(previous);
Q_ASSERT(fileItemModel()->sortOrder() == current);
Q_ASSERT(m_model->sortOrder() == current);
ViewProperties props(url());
props.setSortOrder(current);
@ -1269,7 +1274,7 @@ void DolphinView::slotSortOrderChangedByHeader(Qt::SortOrder current, Qt::SortOr
void DolphinView::slotSortRoleChangedByHeader(const QByteArray& current, const QByteArray& previous)
{
Q_UNUSED(previous);
Q_ASSERT(fileItemModel()->sortRole() == current);
Q_ASSERT(m_model->sortRole() == current);
ViewProperties props(url());
props.setSortRole(current);
@ -1295,8 +1300,8 @@ void DolphinView::slotVisibleRolesChangedByHeader(const QList<QByteArray>& curre
void DolphinView::slotRoleEditingFinished(int index, const QByteArray& role, const QVariant& value)
{
if (role == "name") {
const KFileItem item = fileItemModel()->fileItem(index);
if (role == "text") {
const KFileItem item = m_model->fileItem(index);
const QString newName = value.toString();
if (!newName.isEmpty() && newName != item.text() && newName != QLatin1String(".") && newName != QLatin1String("..")) {
KonqOperations::rename(this, item.url(), newName);
@ -1304,11 +1309,6 @@ void DolphinView::slotRoleEditingFinished(int index, const QByteArray& role, con
}
}
KFileItemModel* DolphinView::fileItemModel() const
{
return static_cast<KFileItemModel*>(m_container->controller()->model());
}
void DolphinView::loadDirectory(const KUrl& url, bool reload)
{
if (!url.isValid()) {
@ -1321,20 +1321,18 @@ void DolphinView::loadDirectory(const KUrl& url, bool reload)
return;
}
KFileItemModel* model = fileItemModel();
if (reload) {
model->refreshDirectory(url);
m_model->refreshDirectory(url);
} else {
model->loadDirectory(url);
m_model->loadDirectory(url);
}
}
void DolphinView::applyViewProperties()
{
m_container->beginTransaction();
m_view->beginTransaction();
const ViewProperties props(url());
KFileItemModel* model = fileItemModel();
const Mode mode = props.viewMode();
if (m_mode != mode) {
@ -1344,49 +1342,43 @@ void DolphinView::applyViewProperties()
// Changing the mode might result in changing
// the zoom level. Remember the old zoom level so
// that zoomLevelChanged() can get emitted.
const int oldZoomLevel = m_container->zoomLevel();
switch (m_mode) {
case IconsView: m_container->setItemLayout(KFileItemListView::IconsLayout); break;
case CompactView: m_container->setItemLayout(KFileItemListView::CompactLayout); break;
case DetailsView: m_container->setItemLayout(KFileItemListView::DetailsLayout); break;
default: Q_ASSERT(false); break;
}
const int oldZoomLevel = m_view->zoomLevel();
applyModeToView();
emit modeChanged(m_mode, previousMode);
if (m_container->zoomLevel() != oldZoomLevel) {
emit zoomLevelChanged(m_container->zoomLevel(), oldZoomLevel);
if (m_view->zoomLevel() != oldZoomLevel) {
emit zoomLevelChanged(m_view->zoomLevel(), oldZoomLevel);
}
}
const bool hiddenFilesShown = props.hiddenFilesShown();
if (hiddenFilesShown != model->showHiddenFiles()) {
model->setShowHiddenFiles(hiddenFilesShown);
if (hiddenFilesShown != m_model->showHiddenFiles()) {
m_model->setShowHiddenFiles(hiddenFilesShown);
emit hiddenFilesShownChanged(hiddenFilesShown);
}
const bool groupedSorting = props.groupedSorting();
if (groupedSorting != model->groupedSorting()) {
model->setGroupedSorting(groupedSorting);
if (groupedSorting != m_model->groupedSorting()) {
m_model->setGroupedSorting(groupedSorting);
emit groupedSortingChanged(groupedSorting);
}
const QByteArray sortRole = props.sortRole();
if (sortRole != model->sortRole()) {
model->setSortRole(sortRole);
if (sortRole != m_model->sortRole()) {
m_model->setSortRole(sortRole);
emit sortRoleChanged(sortRole);
}
const Qt::SortOrder sortOrder = props.sortOrder();
if (sortOrder != model->sortOrder()) {
model->setSortOrder(sortOrder);
if (sortOrder != m_model->sortOrder()) {
m_model->setSortOrder(sortOrder);
emit sortOrderChanged(sortOrder);
}
const bool sortFoldersFirst = props.sortFoldersFirst();
if (sortFoldersFirst != model->sortDirectoriesFirst()) {
model->setSortDirectoriesFirst(sortFoldersFirst);
if (sortFoldersFirst != m_model->sortDirectoriesFirst()) {
m_model->setSortDirectoriesFirst(sortFoldersFirst);
emit sortFoldersFirstChanged(sortFoldersFirst);
}
@ -1394,15 +1386,15 @@ void DolphinView::applyViewProperties()
if (visibleRoles != m_visibleRoles) {
const QList<QByteArray> previousVisibleRoles = m_visibleRoles;
m_visibleRoles = visibleRoles;
m_container->setVisibleRoles(visibleRoles);
m_view->setVisibleRoles(visibleRoles);
emit visibleRolesChanged(m_visibleRoles, previousVisibleRoles);
}
const bool previewsShown = props.previewsShown();
if (previewsShown != m_container->previewsShown()) {
if (previewsShown != m_view->previewsShown()) {
const int oldZoomLevel = zoomLevel();
m_container->setPreviewsShown(previewsShown);
m_view->setPreviewsShown(previewsShown);
emit previewsShownChanged(previewsShown);
// Changing the preview-state might result in a changed zoom-level
@ -1429,7 +1421,17 @@ void DolphinView::applyViewProperties()
}
}
m_container->endTransaction();
m_view->endTransaction();
}
void DolphinView::applyModeToView()
{
switch (m_mode) {
case IconsView: m_view->setItemLayout(KFileItemListView::IconsLayout); break;
case CompactView: m_view->setItemLayout(KFileItemListView::CompactLayout); break;
case DetailsView: m_view->setItemLayout(KFileItemListView::DetailsLayout); break;
default: Q_ASSERT(false); break;
}
}
void DolphinView::pasteToUrl(const KUrl& url)
@ -1457,11 +1459,10 @@ KUrl::List DolphinView::simplifiedSelectedUrls() const
QMimeData* DolphinView::selectionMimeData() const
{
const KFileItemModel* model = fileItemModel();
const KItemListSelectionManager* selectionManager = m_container->controller()->selectionManager();
const QSet<int> selectedIndexes = selectionManager->selectedItems();
return model->createMimeData(selectedIndexes);
return m_model->createMimeData(selectedIndexes);
}
void DolphinView::markPastedUrlsAsSelected(const QMimeData* mimeData)
@ -1480,7 +1481,7 @@ void DolphinView::updateWritableState()
const bool wasFolderWritable = m_isFolderWritable;
m_isFolderWritable = true;
const KFileItem item = fileItemModel()->rootItem();
const KFileItem item = m_model->rootItem();
if (!item.isNull()) {
KFileItemListProperties capabilities(KFileItemList() << item);
m_isFolderWritable = capabilities.supportsWriting();

View file

@ -39,10 +39,11 @@
typedef KIO::FileUndoManager::CommandType CommandType;
class DolphinItemListContainer;
class DolphinItemListView;
class KAction;
class KActionCollection;
class KFileItemModel;
class KItemListContainer;
class KItemModelBase;
class KUrl;
class ToolTipManager;
@ -659,8 +660,6 @@ private slots:
void calculateItemCount(int& fileCount, int& folderCount, KIO::filesize_t& totalFileSize) const;
private:
KFileItemModel* fileItemModel() const;
void loadDirectory(const KUrl& url, bool reload = false);
/**
@ -669,6 +668,12 @@ private:
*/
void applyViewProperties();
/**
* Applies the m_mode property to the corresponding
* itemlayout-property of the KItemListView.
*/
void applyModeToView();
/**
* Helper method for DolphinView::paste() and DolphinView::pasteIntoFolder().
* Pastes the clipboard data into the URL \a url.
@ -716,7 +721,9 @@ private:
QVBoxLayout* m_topLayout;
DolphinItemListContainer* m_container;
KFileItemModel* m_model;
DolphinItemListView* m_view;
KItemListContainer* m_container;
ToolTipManager* m_toolTipManager;

View file

@ -246,8 +246,8 @@ QActionGroup* DolphinViewActionHandler::createFileItemRolesActionGroup(const QSt
const QList<KFileItemModel::RoleInfo> rolesInfo = KFileItemModel::rolesInformation();
foreach (const KFileItemModel::RoleInfo& info, rolesInfo) {
if (!isSortGroup && info.role == "name") {
// It should not be possible to hide the "name" role
if (!isSortGroup && info.role == "text") {
// It should not be possible to hide the "text" role
continue;
}

View file

@ -33,8 +33,9 @@
#include <QFileInfo>
namespace {
const int CurrentViewPropertiesVersion = 2;
const int AdditionalInfoViewPropertiesVersion = 1;
const int NameRolePropertiesVersion = 2;
const int CurrentViewPropertiesVersion = 3;
// String representation to mark the additional properties of
// the details view as customized by the user. See
@ -256,7 +257,7 @@ QList<QByteArray> ViewProperties::visibleRoles() const
// is accepted.
QList<QByteArray> roles;
roles.append("name");
roles.append("text");
// Iterate through all stored keys and append all roles that match to
// the curren view mode.
@ -264,16 +265,19 @@ QList<QByteArray> ViewProperties::visibleRoles() const
const int prefixLength = prefix.length();
QStringList visibleRoles = m_node->visibleRoles();
if (visibleRoles.isEmpty() && m_node->version() <= AdditionalInfoViewPropertiesVersion) {
const int version = m_node->version();
if (visibleRoles.isEmpty() && version <= AdditionalInfoViewPropertiesVersion) {
// Convert the obsolete additionalInfo-property from older versions into the
// visibleRoles-property
visibleRoles = const_cast<ViewProperties*>(this)->convertAdditionalInfo();
} else if (version <= NameRolePropertiesVersion) {
visibleRoles = const_cast<ViewProperties*>(this)->convertNameRole();
}
foreach (const QString& visibleRole, visibleRoles) {
if (visibleRole.startsWith(prefix)) {
const QByteArray role = visibleRole.right(visibleRole.length() - prefixLength).toLatin1();
if (role != "name") {
if (role != "text") {
roles.append(role);
}
}
@ -281,7 +285,7 @@ QList<QByteArray> ViewProperties::visibleRoles() const
// For the details view the size and date should be shown per default
// until the additional information has been explicitly changed by the user
const bool useDefaultValues = roles.count() == 1 // "name"
const bool useDefaultValues = roles.count() == 1 // "text"
&& (m_node->viewMode() == DolphinView::DetailsView)
&& !visibleRoles.contains(CustomizedDetailsString);
if (useDefaultValues) {
@ -403,6 +407,23 @@ QStringList ViewProperties::convertAdditionalInfo()
return visibleRoles;
}
QStringList ViewProperties::convertNameRole()
{
QStringList visibleRoles = m_node->visibleRoles();
for (int i = 0; i < visibleRoles.count(); ++i) {
if (visibleRoles[i].endsWith("_name")) {
const int leftLength = visibleRoles[i].length() - 5;
visibleRoles[i] = visibleRoles[i].left(leftLength) + "_text";
}
}
m_node->setVisibleRoles(visibleRoles);
update();
return visibleRoles;
}
bool ViewProperties::isPartOfHome(const QString& filePath)
{
// For performance reasons cache the path in a static QString

View file

@ -142,11 +142,18 @@ private:
/**
* Provides backward compatibility with .directory files created with
* Dolphin < 2.1: Converts the old additionalInfo-property into
* Dolphin < 2.0: Converts the old additionalInfo-property into
* the visibleRoles-property and clears the additionalInfo-property.
*/
QStringList convertAdditionalInfo();
/**
* Provides backward compatibility with .directory files created with
* Dolphin < 2.1: Converts the old name-role "name" to the generic
* role "text".
*/
QStringList convertNameRole();
/**
* Returns true, if \a filePath is part of the home-path (see QDir::homePath()).
*/