┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--COPYING.DOC (renamed from COPYING-DOCS)0
-rw-r--r--src/CMakeLists.txt13
-rw-r--r--src/dolphin.desktop2
-rw-r--r--src/dolphincategorydrawer.h2
-rw-r--r--src/dolphincolumnview.cpp14
-rw-r--r--src/dolphincolumnwidget.cpp113
-rw-r--r--src/dolphincolumnwidget.h33
-rw-r--r--src/dolphindetailsview.cpp28
-rw-r--r--src/dolphindetailsview.h14
-rw-r--r--src/dolphiniconsview.cpp20
-rw-r--r--src/dolphiniconsview.h1
-rw-r--r--src/dolphinpart.desktop1
-rw-r--r--src/dolphinpart.rc2
-rw-r--r--src/dolphinui.rc2
-rw-r--r--src/dolphinview.cpp144
-rw-r--r--src/dolphinview.h56
-rw-r--r--src/generalviewsettingspage.cpp5
-rw-r--r--src/iconmanager.cpp197
-rw-r--r--src/iconmanager.h111
-rw-r--r--src/kcategorizedview.cpp1596
-rw-r--r--src/kcategorizedview.h119
-rw-r--r--src/kcategorizedview_p.h164
-rw-r--r--src/kcategorydrawer.cpp118
-rw-r--r--src/kcategorydrawer.h52
-rw-r--r--src/main.cpp2
-rw-r--r--src/renamedialog.cpp4
-rw-r--r--src/viewpropertiesdialog.cpp2
27 files changed, 444 insertions, 2371 deletions
diff --git a/COPYING-DOCS b/COPYING.DOC
index 4a0fe1c8d..4a0fe1c8d 100644
--- a/COPYING-DOCS
+++ b/COPYING.DOC
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index f9902dc66..bd2d37812 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -2,6 +2,8 @@
add_subdirectory( pics )
add_subdirectory( tests )
+macro_optional_find_package(Soprano)
+
include_directories( ${KDE4_INCLUDE_DIR} ${QT_INCLUDES} ${BLITZ_INCLUDES} )
if (Soprano_FOUND)
include_directories( ${SOPRANO_INCLUDE_DIR} )
@@ -15,18 +17,17 @@ set(dolphinprivate_LIB_SRCS
dolphiniconsview.cpp
dolphincolumnview.cpp
dolphincolumnwidget.cpp
+ dolphindropcontroller.cpp
+ dolphinsortfilterproxymodel.cpp
draganddrophelper.cpp
- kcategorizedview.cpp
- kcategorydrawer.cpp
dolphinmodel.cpp
dolphinsettings.cpp
dolphincategorydrawer.cpp
- viewproperties.cpp
- dolphinsortfilterproxymodel.cpp
- renamedialog.cpp
dolphinview.cpp
+ iconmanager.cpp
ratingpainter.cpp
- dolphindropcontroller.cpp
+ renamedialog.cpp
+ viewproperties.cpp
)
kde4_add_kcfg_files(dolphinprivate_LIB_SRCS
diff --git a/src/dolphin.desktop b/src/dolphin.desktop
index cb80c824a..ab9765115 100644
--- a/src/dolphin.desktop
+++ b/src/dolphin.desktop
@@ -2,6 +2,7 @@
Name=Dolphin
Name[ar]=الدولفين
Name[hi]=डॉल्फ़िन
+Name[kn]=ಡಾಲ್ಫಿನ್
Name[ne]=डल्फिन
Name[pa]=ਡਾਲਫਿਨ
Name[sr]=Делфин
@@ -39,6 +40,7 @@ GenericName[it]=Gestione file
GenericName[ja]=ファイルマネージャ
GenericName[kk]=Файл менеджері
GenericName[km]=កម្មវិធី​គ្រប់គ្រង​ឯកសារ
+GenericName[kn]=ಕಡತ ವ್ಯವಸ್ಥಾಪಕ
GenericName[ko]=파일 관리자
GenericName[ku]=Rêveberê Pelan
GenericName[lv]=Failu pārvaldnieks
diff --git a/src/dolphincategorydrawer.h b/src/dolphincategorydrawer.h
index ea70a922b..1cccc620e 100644
--- a/src/dolphincategorydrawer.h
+++ b/src/dolphincategorydrawer.h
@@ -21,7 +21,7 @@
#ifndef DOLPHINCATEGORYDRAWER_H
#define DOLPHINCATEGORYDRAWER_H
-#include "kcategorydrawer.h"
+#include <kcategorydrawer.h>
#include <QStyleOption>
#include <QModelIndex>
diff --git a/src/dolphincolumnview.cpp b/src/dolphincolumnview.cpp
index bfbc5d9f1..82d571724 100644
--- a/src/dolphincolumnview.cpp
+++ b/src/dolphincolumnview.cpp
@@ -393,8 +393,12 @@ void DolphinColumnView::updateColumnsBackground(bool active)
m_active = active;
// dim the background of the viewport
- QPalette palette;
- palette.setColor(viewport()->backgroundRole(), QColor(0, 0, 0, 0));
+ const QPalette::ColorRole role = viewport()->backgroundRole();
+ QColor background = viewport()->palette().color(role);
+ background.setAlpha(0); // make background transparent
+
+ QPalette palette = viewport()->palette();
+ palette.setColor(role, background);
viewport()->setPalette(palette);
foreach (DolphinColumnWidget* column, m_columns) {
@@ -503,8 +507,9 @@ void DolphinColumnView::assureVisibleActiveColumn()
} else {
m_animation->setFrameRange(-m_contentX, -newContentX);
}
- if(m_animation->state() != QTimeLine::Running)
+ if (m_animation->state() != QTimeLine::Running) {
m_animation->start();
+ }
} else if (x < 0) {
const int newContentX = m_contentX - x;
if (isRightToLeft()) {
@@ -512,8 +517,9 @@ void DolphinColumnView::assureVisibleActiveColumn()
} else {
m_animation->setFrameRange(-m_contentX, -newContentX);
}
- if(m_animation->state() != QTimeLine::Running)
+ if (m_animation->state() != QTimeLine::Running) {
m_animation->start();
+ }
}
}
diff --git a/src/dolphincolumnwidget.cpp b/src/dolphincolumnwidget.cpp
index fcda0676a..3bb1f36c2 100644
--- a/src/dolphincolumnwidget.cpp
+++ b/src/dolphincolumnwidget.cpp
@@ -37,6 +37,8 @@
#include <kmimetyperesolver.h>
#include <konqmimedata.h>
+#include "iconmanager.h"
+
#include <QApplication>
#include <QClipboard>
#include <QPainter>
@@ -47,7 +49,6 @@ DolphinColumnWidget::DolphinColumnWidget(QWidget* parent,
const KUrl& url) :
QListView(parent),
m_active(true),
- m_showPreview(false),
m_view(columnView),
m_url(url),
m_childUrl(),
@@ -56,7 +57,7 @@ DolphinColumnWidget::DolphinColumnWidget(QWidget* parent,
m_dirLister(0),
m_dolphinModel(0),
m_proxyModel(0),
- m_previewJob(0),
+ m_iconManager(0),
m_dragging(false),
m_dropRect()
{
@@ -107,8 +108,6 @@ DolphinColumnWidget::DolphinColumnWidget(QWidget* parent,
m_dirLister->setDelayedMimeTypes(true);
const bool showHiddenFiles = m_view->m_controller->dolphinView()->showHiddenFiles();
m_dirLister->setShowingDotFiles(showHiddenFiles);
- connect(m_dirLister, SIGNAL(newItems(const KFileItemList&)),
- this, SLOT(generatePreviews(const KFileItemList&)));
m_dolphinModel = new DolphinModel(this);
m_dolphinModel->setDirLister(m_dirLister);
@@ -120,6 +119,8 @@ DolphinColumnWidget::DolphinColumnWidget(QWidget* parent,
setModel(m_proxyModel);
new KMimeTypeResolver(this, m_dolphinModel);
+ m_iconManager = new IconManager(this, m_proxyModel);
+ m_iconManager->setShowPreview(m_view->m_controller->dolphinView()->showPreview());
m_dirLister->openUrl(url, KDirLister::NoFlags);
}
@@ -131,11 +132,6 @@ DolphinColumnWidget::~DolphinColumnWidget()
delete m_dolphinModel;
m_dolphinModel = 0;
m_dirLister = 0; // deleted by m_dolphinModel
-
- if (m_previewJob != 0) {
- m_previewJob->kill();
- m_previewJob = 0;
- }
}
void DolphinColumnWidget::setDecorationSize(const QSize& size)
@@ -176,20 +172,24 @@ void DolphinColumnWidget::setShowHiddenFiles(bool show)
void DolphinColumnWidget::setShowPreview(bool show)
{
- if (show != m_showPreview) {
- m_dirLister->stop();
- m_dirLister->openUrl(m_url, KDirLister::Reload);
- }
+ m_iconManager->setShowPreview(show);
+
+ m_dirLister->stop();
+ m_dirLister->openUrl(m_url, KDirLister::Reload);
}
void DolphinColumnWidget::updateBackground()
{
- QColor color = KColorScheme(QPalette::Active, KColorScheme::View).background().color();
- if (!m_active || !m_view->m_active) {
- color.setAlpha(150);
- }
+ // TODO: The alpha-value 150 is copied from DolphinView::setActive(). When
+ // cleaning up the cut-indication of DolphinColumnWidget with the code from
+ // DolphinView a common helper-class should be available which can be shared
+ // by all view implementations -> no hardcoded value anymore
+ const QPalette::ColorRole role = viewport()->backgroundRole();
+ QColor color = viewport()->palette().color(role);
+ color.setAlpha((m_active && m_view->m_active) ? 255 : 150);
+
QPalette palette = viewport()->palette();
- palette.setColor(viewport()->backgroundRole(), color);
+ palette.setColor(role, color);
viewport()->setPalette(palette);
update();
@@ -359,51 +359,6 @@ void DolphinColumnWidget::triggerItem(const QModelIndex& index)
m_view->m_controller->triggerItem(item);
}
-void DolphinColumnWidget::generatePreviews(const KFileItemList& items)
-{
- // TODO: same implementation as in DolphinView; create helper class
- // for generatePreviews(), showPreview() and isCutItem()
-
- if (m_view->m_controller->dolphinView()->showPreview()) {
- if (m_previewJob != 0) {
- m_previewJob->kill();
- m_previewJob = 0;
- }
-
- m_previewJob = KIO::filePreview(items, 128);
- connect(m_previewJob, SIGNAL(gotPreview(const KFileItem&, const QPixmap&)),
- this, SLOT(replaceIcon(const KFileItem&, const QPixmap&)));
- connect(m_previewJob, SIGNAL(finished(KJob*)),
- this, SLOT(slotPreviewJobFinished(KJob*)));
- }
-}
-
-void DolphinColumnWidget::replaceIcon(const KFileItem& item, const QPixmap& pixmap)
-{
- // TODO: same implementation as in DolphinView; create helper class
- // for generatePreviews(), showPreview() and isCutItem()
-
- Q_ASSERT(!item.isNull());
- const bool showPreview = m_view->m_controller->dolphinView()->showPreview();
- if (!showPreview || (item.url().directory() != m_dirLister->url().path())) {
- // the preview job is still working on items of an older URL, hence
- // the item is not part of the directory model anymore
- return;
- }
-
- const QModelIndex idx = m_dolphinModel->indexForItem(item);
- if (idx.isValid() && (idx.column() == 0)) {
- const QMimeData* mimeData = QApplication::clipboard()->mimeData();
- if (KonqMimeData::decodeIsCutSelection(mimeData) && isCutItem(item)) {
- KIconEffect iconEffect;
- const QPixmap cutPixmap = iconEffect.apply(pixmap, KIconLoader::Desktop, KIconLoader::DisabledState);
- m_dolphinModel->setData(idx, QIcon(cutPixmap), Qt::DecorationRole);
- } else {
- m_dolphinModel->setData(idx, QIcon(pixmap), Qt::DecorationRole);
- }
- }
-}
-
void DolphinColumnWidget::slotEntered(const QModelIndex& index)
{
const QModelIndex dirIndex = m_proxyModel->mapToSource(index);
@@ -411,12 +366,6 @@ void DolphinColumnWidget::slotEntered(const QModelIndex& index)
m_view->m_controller->emitItemEntered(item);
}
-void DolphinColumnWidget::slotPreviewJobFinished(KJob* job)
-{
- Q_ASSERT(job == m_previewJob);
- m_previewJob = 0;
-}
-
void DolphinColumnWidget::activate()
{
setFocus(Qt::OtherFocusReason);
@@ -432,6 +381,9 @@ void DolphinColumnWidget::activate()
this, SLOT(triggerItem(const QModelIndex&)));
}
+ if (selectionModel() && selectionModel()->currentIndex().isValid())
+ selectionModel()->setCurrentIndex(selectionModel()->currentIndex(), QItemSelectionModel::SelectCurrent);
+
updateBackground();
}
@@ -450,31 +402,12 @@ void DolphinColumnWidget::deactivate()
this, SLOT(triggerItem(const QModelIndex&)));
}
+ const QModelIndex current = selectionModel()->currentIndex();
selectionModel()->clear();
+ selectionModel()->setCurrentIndex(current, QItemSelectionModel::NoUpdate);
updateBackground();
}
-bool DolphinColumnWidget::isCutItem(const KFileItem& item) const
-{
- // TODO: same implementation as in DolphinView; create helper class
- // for generatePreviews(), showPreview() and isCutItem()
-
- const QMimeData* mimeData = QApplication::clipboard()->mimeData();
- const KUrl::List cutUrls = KUrl::List::fromMimeData(mimeData);
-
- const KUrl& itemUrl = item.url();
- KUrl::List::const_iterator it = cutUrls.begin();
- const KUrl::List::const_iterator end = cutUrls.end();
- while (it != end) {
- if (*it == itemUrl) {
- return true;
- }
- ++it;
- }
-
- return false;
-}
-
KFileItem DolphinColumnWidget::itemForIndex(const QModelIndex& index) const
{
const QModelIndex dirIndex = m_proxyModel->mapToSource(index);
diff --git a/src/dolphincolumnwidget.h b/src/dolphincolumnwidget.h
index 870246269..de14576e7 100644
--- a/src/dolphincolumnwidget.h
+++ b/src/dolphincolumnwidget.h
@@ -30,15 +30,12 @@
class DolphinColumnView;
class DolphinModel;
class DolphinSortFilterProxyModel;
+class IconManager;
class KDirLister;
class KJob;
class KFileItem;
class KFileItemList;
class QPixmap;
-namespace KIO
-{
- class PreviewJob;
-}
/**
* Represents one column inside the DolphinColumnView and has been
@@ -118,27 +115,8 @@ private slots:
*/
void triggerItem(const QModelIndex& index);
- /**
- * Generates a preview image for each file item in \a items.
- * The current preview settings (maximum size, 'Show Preview' menu)
- * are respected.
- */
- void generatePreviews(const KFileItemList& items);
-
- /**
- * Replaces the icon of the item \a item by the preview pixmap
- * \a pixmap.
- */
- void replaceIcon(const KFileItem& item, const QPixmap& pixmap);
-
void slotEntered(const QModelIndex& index);
- /**
- * Is invoked when the preview job has been finished and
- * set m_previewJob to 0.
- */
- void slotPreviewJobFinished(KJob* job);
-
private:
/** Used by DolphinColumnWidget::setActive(). */
void activate();
@@ -146,17 +124,10 @@ private:
/** Used by DolphinColumnWidget::setActive(). */
void deactivate();
- /**
- * Returns true, if the item \a item has been cut into
- * the clipboard.
- */
- bool isCutItem(const KFileItem& item) const;
-
KFileItem itemForIndex(const QModelIndex& index) const;
private:
bool m_active;
- bool m_showPreview;
DolphinColumnView* m_view;
KUrl m_url; // URL of the directory that is shown
KUrl m_childUrl; // URL of the next column that is shown
@@ -168,7 +139,7 @@ private:
DolphinModel* m_dolphinModel;
DolphinSortFilterProxyModel* m_proxyModel;
- KIO::PreviewJob* m_previewJob;
+ IconManager* m_iconManager;
bool m_dragging; // TODO: remove this property when the issue #160611 is solved in Qt 4.4
QRect m_dropRect; // TODO: remove this property when the issue #160611 is solved in Qt 4.4
diff --git a/src/dolphindetailsview.cpp b/src/dolphindetailsview.cpp
index 4fdb76e1a..6b15f1c41 100644
--- a/src/dolphindetailsview.cpp
+++ b/src/dolphindetailsview.cpp
@@ -43,6 +43,7 @@
DolphinDetailsView::DolphinDetailsView(QWidget* parent, DolphinController* controller) :
QTreeView(parent),
+ m_autoResize(true),
m_controller(controller),
m_font(),
m_decorationSize(),
@@ -76,6 +77,10 @@ DolphinDetailsView::DolphinDetailsView(QWidget* parent, DolphinController* contr
headerView->setContextMenuPolicy(Qt::CustomContextMenu);
connect(headerView, SIGNAL(customContextMenuRequested(const QPoint&)),
this, SLOT(configureColumns(const QPoint&)));
+ connect(headerView, SIGNAL(sectionResized(int, int, int)),
+ this, SLOT(slotHeaderSectionResized(int, int, int)));
+ connect(headerView, SIGNAL(sectionHandleDoubleClicked(int)),
+ this, SLOT(disableAutoResizing()));
connect(parent, SIGNAL(sortingChanged(DolphinView::Sorting)),
this, SLOT(setSortIndicatorSection(DolphinView::Sorting)));
@@ -345,13 +350,7 @@ void DolphinDetailsView::keyPressEvent(QKeyEvent* event)
void DolphinDetailsView::resizeEvent(QResizeEvent* event)
{
QTreeView::resizeEvent(event);
-
- // TODO: There seems to be no easy way to find out whether the resize event
- // has been triggered because of resizing the window or by adjusting the column-width
- // by a left mouse-click (the columns should only be resized automatically when the window
- // size is adjusted). The following workaround works well, but it should be
- // considered solving this in a more transparent way.
- if (!(QApplication::mouseButtons() & Qt::LeftButton)) {
+ if (m_autoResize) {
resizeColumns();
}
}
@@ -494,6 +493,21 @@ void DolphinDetailsView::updateColumnVisibility()
resizeColumns();
}
+void DolphinDetailsView::slotHeaderSectionResized(int logicalIndex, int oldSize, int newSize)
+{
+ Q_UNUSED(logicalIndex);
+ Q_UNUSED(oldSize);
+ Q_UNUSED(newSize);
+ if (QApplication::mouseButtons() & Qt::LeftButton) {
+ disableAutoResizing();
+ }
+}
+
+void DolphinDetailsView::disableAutoResizing()
+{
+ m_autoResize = false;
+}
+
bool DolphinDetailsView::isZoomInPossible() const
{
DetailsModeSettings* settings = DolphinSettings::instance().detailsModeSettings();
diff --git a/src/dolphindetailsview.h b/src/dolphindetailsview.h
index 086121f7a..a9201d8b3 100644
--- a/src/dolphindetailsview.h
+++ b/src/dolphindetailsview.h
@@ -118,6 +118,18 @@ private slots:
void updateColumnVisibility();
+ /**
+ * Disables the automatical resizing of columns, if the user has resized the columns
+ * with the mouse.
+ */
+ void slotHeaderSectionResized(int logicalIndex, int oldSize, int newSize);
+
+ /**
+ * Disables the automatical resizing of the columns. Per default all columns
+ * are resized to use the maximum available width of the view as good as possible.
+ */
+ void disableAutoResizing();
+
private:
bool isZoomInPossible() const;
bool isZoomOutPossible() const;
@@ -143,6 +155,8 @@ private:
void resizeColumns();
private:
+ bool m_autoResize; // if true, the columns are resized automatically to the available width
+
DolphinController* m_controller;
QFont m_font;
diff --git a/src/dolphiniconsview.cpp b/src/dolphiniconsview.cpp
index 553cdcfe6..21debe745 100644
--- a/src/dolphiniconsview.cpp
+++ b/src/dolphiniconsview.cpp
@@ -33,6 +33,7 @@
#include <QApplication>
#include <QPainter>
#include <QPoint>
+#include <QScrollBar>
DolphinIconsView::DolphinIconsView(QWidget* parent, DolphinController* controller) :
KCategorizedView(parent),
@@ -285,6 +286,25 @@ void DolphinIconsView::keyPressEvent(QKeyEvent* event)
}
}
+void DolphinIconsView::wheelEvent(QWheelEvent* event)
+{
+ KCategorizedView::wheelEvent(event);
+
+ // if the icons are aligned left to right, the vertical wheel event should
+ // be applied to the horizontal scrollbar
+ const IconsModeSettings* settings = DolphinSettings::instance().iconsModeSettings();
+ const bool scrollHorizontal = (event->orientation() == Qt::Vertical) &&
+ (settings->arrangement() == QListView::LeftToRight);
+ if (scrollHorizontal) {
+ QWheelEvent horizEvent(event->pos(),
+ event->delta(),
+ event->buttons(),
+ event->modifiers(),
+ Qt::Horizontal);
+ QApplication::sendEvent(horizontalScrollBar(), &horizEvent);
+ }
+}
+
void DolphinIconsView::triggerItem(const QModelIndex& index)
{
m_controller->triggerItem(itemForIndex(index));
diff --git a/src/dolphiniconsview.h b/src/dolphiniconsview.h
index 06c417868..edc2475d4 100644
--- a/src/dolphiniconsview.h
+++ b/src/dolphiniconsview.h
@@ -62,6 +62,7 @@ protected:
virtual void dropEvent(QDropEvent* event);
virtual void paintEvent(QPaintEvent* event);
virtual void keyPressEvent(QKeyEvent* event);
+ virtual void wheelEvent(QWheelEvent* event);
private slots:
void triggerItem(const QModelIndex& index);
diff --git a/src/dolphinpart.desktop b/src/dolphinpart.desktop
index 9f5e6bad5..5ca1d79c6 100644
--- a/src/dolphinpart.desktop
+++ b/src/dolphinpart.desktop
@@ -23,6 +23,7 @@ Name[it]=Componente Dolphin
Name[ja]=Dolphin パート
Name[kk]=Dolphin бөлшегі
Name[km]=ផ្នែក​របស់ Dolphin
+Name[kn]=ಡಾಲ್ಫಿನ್ ಭಾಗ
Name[ko]=Dolphin 부분
Name[ku]=Parçeyê Bibîne
Name[lv]=Dolphin daļa
diff --git a/src/dolphinpart.rc b/src/dolphinpart.rc
index 35bde506e..2e3f63e5c 100644
--- a/src/dolphinpart.rc
+++ b/src/dolphinpart.rc
@@ -13,7 +13,7 @@
</Menu>
<Menu name="view">
<Menu name="sort">
- <text context="@title:menu">Sort by</text>
+ <text context="@title:menu">Sort By</text>
<Action name="sort_by_name" />
<Action name="sort_by_size" />
<Action name="sort_by_date" />
diff --git a/src/dolphinui.rc b/src/dolphinui.rc
index 1763aefda..8aaddcd26 100644
--- a/src/dolphinui.rc
+++ b/src/dolphinui.rc
@@ -23,7 +23,7 @@
<Action name="columns" />
</Menu>
<Menu name="sort">
- <text context="@title:menu">Sort by</text>
+ <text context="@title:menu">Sort By</text>
<Action name="sort_by_name" />
<Action name="sort_by_size" />
<Action name="sort_by_date" />
diff --git a/src/dolphinview.cpp b/src/dolphinview.cpp
index ddb7185f0..09dd153a0 100644
--- a/src/dolphinview.cpp
+++ b/src/dolphinview.cpp
@@ -33,16 +33,16 @@
#include <kcolorscheme.h>
#include <kdirlister.h>
#include <kfileitemdelegate.h>
-#include <klocale.h>
#include <kiconeffect.h>
+#include <klocale.h>
#include <kio/deletejob.h>
#include <kio/netaccess.h>
#include <kio/previewjob.h>
#include <kjob.h>
#include <kmenu.h>
#include <kmimetyperesolver.h>
-#include <konqmimedata.h>
#include <konq_operations.h>
+#include <konqmimedata.h>
#include <kurl.h>
#include "dolphindropcontroller.h"
@@ -52,10 +52,11 @@
#include "dolphinsortfilterproxymodel.h"
#include "dolphindetailsview.h"
#include "dolphiniconsview.h"
-#include "renamedialog.h"
-#include "viewproperties.h"
#include "dolphinsettings.h"
#include "dolphin_generalsettings.h"
+#include "iconmanager.h"
+#include "renamedialog.h"
+#include "viewproperties.h"
DolphinView::DolphinView(QWidget* parent,
const KUrl& url,
@@ -78,21 +79,15 @@ DolphinView::DolphinView(QWidget* parent,
m_dolphinModel(dolphinModel),
m_dirLister(dirLister),
m_proxyModel(proxyModel),
- m_previewJob(0)
+ m_iconManager(0)
{
setFocusPolicy(Qt::StrongFocus);
m_topLayout = new QVBoxLayout(this);
m_topLayout->setSpacing(0);
m_topLayout->setMargin(0);
- QClipboard* clipboard = QApplication::clipboard();
- connect(clipboard, SIGNAL(dataChanged()),
- this, SLOT(updateCutItems()));
-
connect(m_dirLister, SIGNAL(completed()),
this, SLOT(updateCutItems()));
- connect(m_dirLister, SIGNAL(newItems(const KFileItemList&)),
- this, SLOT(generatePreviews(const KFileItemList&)));
m_controller = new DolphinController(this);
m_controller->setUrl(url);
@@ -131,10 +126,6 @@ DolphinView::DolphinView(QWidget* parent,
DolphinView::~DolphinView()
{
- if (m_previewJob != 0) {
- m_previewJob->kill();
- m_previewJob = 0;
- }
}
const KUrl& DolphinView::url() const
@@ -246,7 +237,7 @@ void DolphinView::setShowPreview(bool show)
props.setShowPreview(show);
m_showPreview = show;
-
+ m_iconManager->setShowPreview(show);
emit showPreviewChanged();
loadDirectory(viewPropsUrl, true);
@@ -575,45 +566,6 @@ void DolphinView::triggerItem(const KFileItem& item)
emit itemTriggered(item); // caught by DolphinViewContainer or DolphinPart
}
-void DolphinView::generatePreviews(const KFileItemList& items)
-{
- if (m_controller->dolphinView()->showPreview()) {
- if (m_previewJob != 0) {
- m_previewJob->kill();
- m_previewJob = 0;
- }
-
- m_previewJob = KIO::filePreview(items, 128);
- connect(m_previewJob, SIGNAL(gotPreview(const KFileItem&, const QPixmap&)),
- this, SLOT(replaceIcon(const KFileItem&, const QPixmap&)));
- connect(m_previewJob, SIGNAL(finished(KJob*)),
- this, SLOT(slotPreviewJobFinished(KJob*)));
- }
-}
-
-void DolphinView::replaceIcon(const KFileItem& item, const QPixmap& pixmap)
-{
- Q_ASSERT(!item.isNull());
- if (!m_showPreview || (item.url().directory() != m_dirLister->url().path())) {
- // the preview has been deactivated in the meanwhile or the preview
- // job is still working on items of an older URL, hence
- // the item is not part of the directory model anymore
- return;
- }
-
- const QModelIndex idx = m_dolphinModel->indexForItem(item);
- if (idx.isValid() && (idx.column() == 0)) {
- const QMimeData* mimeData = QApplication::clipboard()->mimeData();
- if (KonqMimeData::decodeIsCutSelection(mimeData) && isCutItem(item)) {
- KIconEffect iconEffect;
- const QPixmap cutPixmap = iconEffect.apply(pixmap, KIconLoader::Desktop, KIconLoader::DisabledState);
- m_dolphinModel->setData(idx, QIcon(cutPixmap), Qt::DecorationRole);
- } else {
- m_dolphinModel->setData(idx, QIcon(pixmap), Qt::DecorationRole);
- }
- }
-}
-
void DolphinView::emitSelectionChangedSignal()
{
emit selectionChanged(DolphinView::selectedItems());
@@ -631,7 +583,6 @@ void DolphinView::loadDirectory(const KUrl& url, bool reload)
return;
}
- m_cutItemsCache.clear();
m_loadingDirectory = true;
m_dirLister->stop();
@@ -714,6 +665,7 @@ void DolphinView::applyViewProperties(const KUrl& url)
const bool showPreview = props.showPreview();
if (showPreview != m_showPreview) {
m_showPreview = showPreview;
+ m_iconManager->setShowPreview(showPreview);
emit showPreviewChanged();
}
}
@@ -819,25 +771,6 @@ void DolphinView::emitContentsMoved()
}
}
-void DolphinView::updateCutItems()
-{
- // restore the icons of all previously selected items to the
- // original state...
- QList<CutItem>::const_iterator it = m_cutItemsCache.begin();
- QList<CutItem>::const_iterator end = m_cutItemsCache.end();
- while (it != end) {
- const QModelIndex index = m_dolphinModel->indexForUrl((*it).url);
- if (index.isValid()) {
- m_dolphinModel->setData(index, QIcon((*it).pixmap), Qt::DecorationRole);
- }
- ++it;
- }
- m_cutItemsCache.clear();
-
- // ... and apply an item effect to all currently cut items
- applyCutItemEffect();
-}
-
void DolphinView::showHoverInformation(const KFileItem& item)
{
if (hasSelection() || !m_active) {
@@ -854,7 +787,6 @@ void DolphinView::clearHoverInformation()
}
}
-
void DolphinView::createView()
{
deleteView();
@@ -900,6 +832,9 @@ void DolphinView::createView()
view->setSelectionMode(QAbstractItemView::ExtendedSelection);
new KMimeTypeResolver(view, m_dolphinModel);
+ m_iconManager = new IconManager(view, m_proxyModel);
+ m_iconManager->setShowPreview(m_showPreview);
+
m_topLayout->insertWidget(1, view);
connect(view->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
@@ -922,6 +857,7 @@ void DolphinView::deleteView()
m_detailsView = 0;
m_columnView = 0;
m_fileItemDelegate = 0;
+ m_iconManager = 0;
}
}
@@ -954,42 +890,6 @@ bool DolphinView::isCutItem(const KFileItem& item) const
return false;
}
-void DolphinView::applyCutItemEffect()
-{
- const QMimeData* mimeData = QApplication::clipboard()->mimeData();
- if (!KonqMimeData::decodeIsCutSelection(mimeData)) {
- return;
- }
-
- KFileItemList items(m_dirLister->items());
- KFileItemList::const_iterator it = items.begin();
- const KFileItemList::const_iterator end = items.end();
- while (it != end) {
- const KFileItem item = *it;
- if (isCutItem(item)) {
- const QModelIndex index = m_dolphinModel->indexForItem(item);
- const QVariant value = m_dolphinModel->data(index, Qt::DecorationRole);
- if (value.type() == QVariant::Icon) {
- const QIcon icon(qvariant_cast<QIcon>(value));
- QPixmap pixmap = icon.pixmap(128, 128);
-
- // remember current pixmap for the item to be able
- // to restore it when other items get cut
- CutItem cutItem;
- cutItem.url = item.url();
- cutItem.pixmap = pixmap;
- m_cutItemsCache.append(cutItem);
-
- // apply icon effect to the cut item
- KIconEffect iconEffect;
- pixmap = iconEffect.apply(pixmap, KIconLoader::Desktop, KIconLoader::DisabledState);
- m_dolphinModel->setData(index, QIcon(pixmap), Qt::DecorationRole);
- }
- }
- ++it;
- }
-}
-
KToggleAction* DolphinView::iconsModeAction(KActionCollection* actionCollection)
{
KToggleAction* iconsView = actionCollection->add<KToggleAction>("icons");
@@ -1053,19 +953,14 @@ void DolphinView::renameSelectedItems()
Q_ASSERT(newName.contains('#'));
// iterate through all selected items and rename them...
- const int replaceIndex = newName.indexOf('#');
- Q_ASSERT(replaceIndex >= 0);
int index = 1;
-
- KFileItemList::const_iterator it = items.begin();
- const KFileItemList::const_iterator end = items.end();
- while (it != end) {
- const KUrl& oldUrl = (*it).url();
+ foreach (KFileItem item, items) {
+ const KUrl& oldUrl = item.url();
QString number;
number.setNum(index++);
- QString name(newName);
- name.replace(replaceIndex, 1, number);
+ QString name = newName;
+ name.replace('#', number);
if (oldUrl.fileName() != name) {
KUrl newUrl = oldUrl;
@@ -1073,7 +968,6 @@ void DolphinView::renameSelectedItems()
KonqOperations::rename(this, oldUrl, newUrl);
emit doingOperation(KonqFileUndoManager::RENAME);
}
- ++it;
}
}
} else {
@@ -1132,12 +1026,6 @@ void DolphinView::slotDeleteFileFinished(KJob* job)
}
}
-void DolphinView::slotPreviewJobFinished(KJob* job)
-{
- Q_ASSERT(job == m_previewJob);
- m_previewJob = 0;
-}
-
void DolphinView::cutSelectedItems()
{
QMimeData* mimeData = new QMimeData();
diff --git a/src/dolphinview.h b/src/dolphinview.h
index 60e29b4d5..fa5b18471 100644
--- a/src/dolphinview.h
+++ b/src/dolphinview.h
@@ -38,24 +38,21 @@
#include <QListView>
#include <QWidget>
-class KAction;
-class KToggleAction;
class DolphinController;
-class KDirLister;
-class KFileItemDelegate;
-class KUrl;
-class DolphinModel;
class DolphinColumnView;
class DolphinDetailsView;
class DolphinIconsView;
class DolphinMainWindow;
+class DolphinModel;
class DolphinSortFilterProxyModel;
+class IconManager;
+class KAction;
+class KDirLister;
+class KFileItemDelegate;
+class KUrl;
+class KToggleAction;
class QModelIndex;
class ViewProperties;
-namespace KIO
-{
- class PreviewJob;
-}
/**
* @short Represents a view for the directory content.
@@ -526,19 +523,6 @@ private slots:
*/
void triggerItem(const KFileItem& index);
- /**
- * Generates a preview image for each file item in \a items.
- * The current preview settings (maximum size, 'Show Preview' menu)
- * are respected.
- */
- void generatePreviews(const KFileItemList& items);
-
- /**
- * Replaces the icon of the item \a item by the preview pixmap
- * \a pixmap.
- */
- void replaceIcon(const KFileItem& item, const QPixmap& pixmap);
-
void emitSelectionChangedSignal();
/**
@@ -587,9 +571,6 @@ private slots:
*/
void emitContentsMoved();
- /** Applies an item effect to all cut items of the clipboard. */
- void updateCutItems();
-
/**
* Updates the status bar to show hover information for the
* item \a item. If currently other items are selected,
@@ -610,12 +591,6 @@ private slots:
*/
void slotDeleteFileFinished(KJob* job);
- /**
- * Is invoked when the preview job has been finished and
- * set m_previewJob to 0.
- */
- void slotPreviewJobFinished(KJob* job);
-
private:
void loadDirectory(const KUrl& url, bool reload = false);
@@ -654,9 +629,6 @@ private:
*/
bool isCutItem(const KFileItem& item) const;
- /** Applies an item effect to all cut items. */
- void applyCutItemEffect();
-
/**
* Returns true, if the ColumnView is activated. As the column view
* requires some special handling for iterating through directories,
@@ -668,16 +640,6 @@ private:
}
private:
- /**
- * Remembers the original pixmap for an item before
- * the cut effect is applied.
- */
- struct CutItem
- {
- KUrl url;
- QPixmap pixmap;
- };
-
bool m_active;
bool m_showPreview;
bool m_loadingDirectory;
@@ -698,9 +660,7 @@ private:
KDirLister* m_dirLister;
DolphinSortFilterProxyModel* m_proxyModel;
- KIO::PreviewJob* m_previewJob;
-
- QList<CutItem> m_cutItemsCache;
+ IconManager* m_iconManager;
KUrl m_rootUrl;
};
diff --git a/src/generalviewsettingspage.cpp b/src/generalviewsettingspage.cpp
index 2d815d3d2..b9fbc17be 100644
--- a/src/generalviewsettingspage.cpp
+++ b/src/generalviewsettingspage.cpp
@@ -71,7 +71,7 @@ GeneralViewSettingsPage::GeneralViewSettingsPage(DolphinMainWindow* mainWindow,
KHBox* vBox = new KHBox(previewBox);
vBox->setSpacing(spacing);
- QLabel* maxFileSize = new QLabel(i18nc("@label:slider", "Maximum file size:"), vBox);
+ new QLabel(i18nc("@label:slider", "Maximum file size:"), vBox);
m_maxPreviewSize = new QSlider(Qt::Horizontal, vBox);
m_spinBox = new QSpinBox(vBox);
@@ -154,6 +154,9 @@ void GeneralViewSettingsPage::loadSettings()
m_maxPreviewSize->setTickPosition(QSlider::TicksBelow);
KConfigGroup globalConfig(KGlobal::config(), "PreviewSettings");
+ // TODO: The default value of 5 MB must match with the default value inside
+ // kdelibs/kio/kio/previewjob.cpp. Maybe a static getter method in PreviewJob
+ // should be added for getting the default size?
const int maxByteSize = globalConfig.readEntry("MaximumSize", 5 * 1024 * 1024 /* 5 MB */);
int maxMByteSize = maxByteSize / (1024 * 1024);
if (maxMByteSize < 1) {
diff --git a/src/iconmanager.cpp b/src/iconmanager.cpp
new file mode 100644
index 000000000..a5e72eabf
--- /dev/null
+++ b/src/iconmanager.cpp
@@ -0,0 +1,197 @@
+/***************************************************************************
+ * Copyright (C) 2008 by Peter Penz <[email protected]> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "iconmanager.h"
+
+#include "dolphinmodel.h"
+#include "dolphinsortfilterproxymodel.h"
+
+#include <kiconeffect.h>
+#include <kio/previewjob.h>
+#include <kdebug.h>
+#include <kdirlister.h>
+#include <konqmimedata.h>
+
+#include <QApplication>
+#include <QAbstractItemView>
+#include <QClipboard>
+#include <QIcon>
+
+IconManager::IconManager(QAbstractItemView* parent, DolphinSortFilterProxyModel* model) :
+ QObject(parent),
+ m_showPreview(false),
+ m_view(parent),
+ m_previewJobs(),
+ m_dolphinModel(0),
+ m_proxyModel(model),
+ m_cutItemsCache()
+{
+ m_dolphinModel = static_cast<DolphinModel*>(m_proxyModel->sourceModel());
+ connect(m_dolphinModel->dirLister(), SIGNAL(newItems(const KFileItemList&)),
+ this, SLOT(generatePreviews(const KFileItemList&)));
+
+ QClipboard* clipboard = QApplication::clipboard();
+ connect(clipboard, SIGNAL(dataChanged()),
+ this, SLOT(updateCutItems()));
+}
+
+IconManager::~IconManager()
+{
+ foreach (KJob* job, m_previewJobs) {
+ Q_ASSERT(job != 0);
+ job->kill();
+ }
+ m_previewJobs.clear();
+}
+
+
+void IconManager::setShowPreview(bool show)
+{
+ if (m_showPreview != show) {
+ m_showPreview = show;
+ m_cutItemsCache.clear();
+ updateCutItems();
+ }
+}
+
+void IconManager::generatePreviews(const KFileItemList& items)
+{
+ if (!m_showPreview) {
+ return;
+ }
+
+ const QRect visibleArea = m_view->viewport()->rect();
+
+ // Order the items in a way that the preview for the visible items
+ // is generated first, as this improves the feeled performance a lot.
+ KFileItemList orderedItems;
+ foreach (KFileItem item, items) {
+ const QModelIndex dirIndex = m_dolphinModel->indexForItem(item);
+ const QModelIndex proxyIndex = m_proxyModel->mapFromSource(dirIndex);
+ const QRect itemRect = m_view->visualRect(proxyIndex);
+ if (itemRect.intersects(visibleArea)) {
+ orderedItems.insert(0, item);
+ } else {
+ orderedItems.append(item);
+ }
+ }
+
+ KIO::PreviewJob* job = KIO::filePreview(orderedItems, 128);
+ connect(job, SIGNAL(gotPreview(const KFileItem&, const QPixmap&)),
+ this, SLOT(replaceIcon(const KFileItem&, const QPixmap&)));
+ connect(job, SIGNAL(finished(KJob*)),
+ this, SLOT(slotPreviewJobFinished(KJob*)));
+
+ m_previewJobs.append(job);
+}
+
+void IconManager::replaceIcon(const KFileItem& item, const QPixmap& pixmap)
+{
+ Q_ASSERT(!item.isNull());
+ KDirLister* dirLister = m_dolphinModel->dirLister();
+ if (!m_showPreview || (item.url().directory() != dirLister->url().path())) {
+ // the preview has been canceled in the meanwhile or the preview
+ // job is still working on items of an older URL, hence
+ // the item is not part of the directory model anymore
+ return;
+ }
+
+ const QModelIndex idx = m_dolphinModel->indexForItem(item);
+ if (idx.isValid() && (idx.column() == 0)) {
+ const QMimeData* mimeData = QApplication::clipboard()->mimeData();
+ if (KonqMimeData::decodeIsCutSelection(mimeData) && isCutItem(item)) {
+ KIconEffect iconEffect;
+ const QPixmap cutPixmap = iconEffect.apply(pixmap, KIconLoader::Desktop, KIconLoader::DisabledState);
+ m_dolphinModel->setData(idx, QIcon(cutPixmap), Qt::DecorationRole);
+ } else {
+ m_dolphinModel->setData(idx, QIcon(pixmap), Qt::DecorationRole);
+ }
+ }
+}
+
+void IconManager::slotPreviewJobFinished(KJob* job)
+{
+ const int index = m_previewJobs.indexOf(job);
+ m_previewJobs.removeAt(index);
+}
+
+void IconManager::updateCutItems()
+{
+ // restore the icons of all previously selected items to the
+ // original state...
+ foreach (CutItem cutItem, m_cutItemsCache) {
+ const QModelIndex index = m_dolphinModel->indexForUrl(cutItem.url);
+ if (index.isValid()) {
+ m_dolphinModel->setData(index, QIcon(cutItem.pixmap), Qt::DecorationRole);
+ }
+ }
+ m_cutItemsCache.clear();
+
+ // ... and apply an item effect to all currently cut items
+ applyCutItemEffect();
+}
+
+bool IconManager::isCutItem(const KFileItem& item) const
+{
+ const QMimeData* mimeData = QApplication::clipboard()->mimeData();
+ const KUrl::List cutUrls = KUrl::List::fromMimeData(mimeData);
+
+ const KUrl& itemUrl = item.url();
+ foreach (KUrl url, cutUrls) {
+ if (url == itemUrl) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void IconManager::applyCutItemEffect()
+{
+ const QMimeData* mimeData = QApplication::clipboard()->mimeData();
+ if (!KonqMimeData::decodeIsCutSelection(mimeData)) {
+ return;
+ }
+
+ const KFileItemList items(m_dolphinModel->dirLister()->items());
+ foreach (KFileItem item, items) {
+ if (isCutItem(item)) {
+ const QModelIndex index = m_dolphinModel->indexForItem(item);
+ const QVariant value = m_dolphinModel->data(index, Qt::DecorationRole);
+ if (value.type() == QVariant::Icon) {
+ const QIcon icon(qvariant_cast<QIcon>(value));
+ QPixmap pixmap = icon.pixmap(128, 128);
+
+ // remember current pixmap for the item to be able
+ // to restore it when other items get cut
+ CutItem cutItem;
+ cutItem.url = item.url();
+ cutItem.pixmap = pixmap;
+ m_cutItemsCache.append(cutItem);
+
+ // apply icon effect to the cut item
+ KIconEffect iconEffect;
+ pixmap = iconEffect.apply(pixmap, KIconLoader::Desktop, KIconLoader::DisabledState);
+ m_dolphinModel->setData(index, QIcon(pixmap), Qt::DecorationRole);
+ }
+ }
+ }
+}
+
+#include "iconmanager.moc"
diff --git a/src/iconmanager.h b/src/iconmanager.h
new file mode 100644
index 000000000..2636c81c6
--- /dev/null
+++ b/src/iconmanager.h
@@ -0,0 +1,111 @@
+/***************************************************************************
+ * Copyright (C) 2008 by Peter Penz <[email protected]> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef ICONMANAGER_H
+#define ICONMANAGER_H
+
+#include <kfileitem.h>
+#include <kurl.h>
+
+#include <QList>
+#include <QObject>
+#include <QPixmap>
+
+class DolphinModel;
+class DolphinSortFilterProxyModel;
+class KJob;
+class QAbstractItemView;
+
+/**
+ * @brief Manages the icon state of a directory model.
+ *
+ * Per default a preview is generated for each item.
+ * Additionally the clipboard is checked for cut items.
+ * The icon state for cut items gets dimmed automatically.
+ */
+class IconManager : public QObject
+{
+ Q_OBJECT
+
+public:
+ IconManager(QAbstractItemView* parent, DolphinSortFilterProxyModel* model);
+ virtual ~IconManager();
+ void setShowPreview(bool show);
+ bool showPreview() const;
+
+private slots:
+ /**
+ * Generates a preview image for each file item in \a items.
+ * The current preview settings (maximum size, 'Show Preview' menu)
+ * are respected.
+ */
+ void generatePreviews(const KFileItemList& items);
+
+ /**
+ * Replaces the icon of the item \a item by the preview pixmap
+ * \a pixmap.
+ */
+ void replaceIcon(const KFileItem& item, const QPixmap& pixmap);
+
+ /**
+ * Is invoked when the preview job has been finished and
+ * set m_previewJob to 0.
+ */
+ void slotPreviewJobFinished(KJob* job);
+
+ /** Synchronizes the item icon with the clipboard of cut items. */
+ void updateCutItems();
+
+private:
+ /**
+ * Returns true, if the item \a item has been cut into
+ * the clipboard.
+ */
+ bool isCutItem(const KFileItem& item) const;
+
+ /** Applies an item effect to all cut items. */
+ void applyCutItemEffect();
+
+private:
+ /**
+ * Remembers the original pixmap for an item before
+ * the cut effect is applied.
+ */
+ struct CutItem
+ {
+ KUrl url;
+ QPixmap pixmap;
+ };
+
+ bool m_showPreview;
+
+ QAbstractItemView* m_view;
+ QList<KJob*> m_previewJobs;
+ DolphinModel* m_dolphinModel;
+ DolphinSortFilterProxyModel* m_proxyModel;
+
+ QList<CutItem> m_cutItemsCache;
+};
+
+inline bool IconManager::showPreview() const
+{
+ return m_showPreview;
+}
+
+#endif
diff --git a/src/kcategorizedview.cpp b/src/kcategorizedview.cpp
deleted file mode 100644
index 648a712a5..000000000
--- a/src/kcategorizedview.cpp
+++ /dev/null
@@ -1,1596 +0,0 @@
-/**
- * This file is part of the KDE project
- * Copyright (C) 2007 Rafael Fernández López <[email protected]>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "kcategorizedview.h"
-#include "kcategorizedview_p.h"
-
-#include <math.h> // trunc on C99 compliant systems
-#include <kdefakes.h> // trunc for not C99 compliant systems
-
-#include <QPainter>
-#include <QScrollBar>
-#include <QPaintEvent>
-
-#include <kstyle.h>
-
-#include "kcategorydrawer.h"
-#include "kcategorizedsortfilterproxymodel.h"
-
-// By defining DOLPHIN_DRAGANDDROP the custom drag and drop implementation of
-// KCategorizedView is bypassed to have a consistent drag and drop look for all
-// views. Hopefully transparent pixmaps for drag objects will be supported in
-// Qt 4.4, so that this workaround can be skipped.
-#define DOLPHIN_DRAGANDDROP
-
-KCategorizedView::Private::Private(KCategorizedView *listView)
- : listView(listView)
- , categoryDrawer(0)
- , biggestItemSize(QSize(0, 0))
- , mouseButtonPressed(false)
- , rightMouseButtonPressed(false)
- , isDragging(false)
- , dragLeftViewport(false)
- , proxyModel(0)
-{
-}
-
-KCategorizedView::Private::~Private()
-{
-}
-
-const QModelIndexList &KCategorizedView::Private::intersectionSet(const QRect &rect)
-{
- QModelIndex index;
- QRect indexVisualRect;
-
- intersectedIndexes.clear();
-
- int itemHeight;
-
- if (listView->gridSize().isEmpty())
- {
- itemHeight = biggestItemSize.height();
- }
- else
- {
- itemHeight = listView->gridSize().height();
- }
-
- // Lets find out where we should start
- int top = proxyModel->rowCount() - 1;
- int bottom = 0;
- int middle = (top + bottom) / 2;
- while (bottom <= top)
- {
- middle = (top + bottom) / 2;
-
- index = proxyModel->index(middle, 0);
- indexVisualRect = visualRect(index);
- // We need the whole height (not only the visualRect). This will help us to update
- // all needed indexes correctly (ereslibre)
- indexVisualRect.setHeight(indexVisualRect.height() + (itemHeight - indexVisualRect.height()));
-
- if (qMax(indexVisualRect.topLeft().y(),
- indexVisualRect.bottomRight().y()) < qMin(rect.topLeft().y(),
- rect.bottomRight().y()))
- {
- bottom = middle + 1;
- }
- else
- {
- top = middle - 1;
- }
- }
-
- for (int i = middle; i < proxyModel->rowCount(); i++)
- {
- index = proxyModel->index(i, 0);
- indexVisualRect = visualRect(index);
-
- if (rect.intersects(indexVisualRect))
- intersectedIndexes.append(index);
-
- // If we passed next item, stop searching for hits
- if (qMax(rect.bottomRight().y(), rect.topLeft().y()) <
- qMin(indexVisualRect.topLeft().y(),
- indexVisualRect.bottomRight().y()))
- break;
- }
-
- return intersectedIndexes;
-}
-
-QRect KCategorizedView::Private::visualRectInViewport(const QModelIndex &index) const
-{
- if (!index.isValid())
- return QRect();
-
- QString curCategory = elementsInfo[index.row()].category;
-
- QRect retRect;
-
- if (listView->layoutDirection() == Qt::LeftToRight)
- {
- retRect = QRect(listView->spacing(), listView->spacing() * 2 +
- categoryDrawer->categoryHeight(index, listView->viewOptions()), 0, 0);
- }
- else
- {
- retRect = QRect(listView->viewport()->width() - listView->spacing(), listView->spacing() * 2 +
- categoryDrawer->categoryHeight(index, listView->viewOptions()), 0, 0);
- }
-
- int viewportWidth = listView->viewport()->width() - listView->spacing();
-
- int itemHeight;
- int itemWidth;
-
- if (listView->gridSize().isEmpty())
- {
- itemHeight = biggestItemSize.height();
- itemWidth = biggestItemSize.width();
- }
- else
- {
- itemHeight = listView->gridSize().height();
- itemWidth = listView->gridSize().width();
- }
-
- int itemWidthPlusSeparation = listView->spacing() + itemWidth;
- int elementsPerRow = viewportWidth / itemWidthPlusSeparation;
- if (!elementsPerRow)
- elementsPerRow++;
-
- int column = elementsInfo[index.row()].relativeOffsetToCategory % elementsPerRow;
- int row = elementsInfo[index.row()].relativeOffsetToCategory / elementsPerRow;
-
- if (listView->layoutDirection() == Qt::LeftToRight)
- {
- retRect.setLeft(retRect.left() + column * listView->spacing() +
- column * itemWidth);
- }
- else
- {
- retRect.setLeft(retRect.right() - column * listView->spacing() -
- column * itemWidth - itemWidth);
-
- retRect.setRight(retRect.right() - column * listView->spacing() -
- column * itemWidth);
- }
-
- foreach (const QString &category, categories)
- {
- if (category == curCategory)
- break;
-
- float rows = (float) ((float) categoriesIndexes[category].count() /
- (float) elementsPerRow);
-
- int rowsInt = categoriesIndexes[category].count() / elementsPerRow;
-
- if (rows - trunc(rows)) rowsInt++;
-
- retRect.setTop(retRect.top() +
- (rowsInt * itemHeight) +
- categoryDrawer->categoryHeight(index, listView->viewOptions()) +
- listView->spacing() * 2);
-
- if (listView->gridSize().isEmpty())
- {
- retRect.setTop(retRect.top() +
- (rowsInt * listView->spacing()));
- }
- }
-
- if (listView->gridSize().isEmpty())
- {
- retRect.setTop(retRect.top() + row * listView->spacing() +
- (row * itemHeight));
- }
- else
- {
- retRect.setTop(retRect.top() + (row * itemHeight));
- }
-
- retRect.setWidth(itemWidth);
-
- QModelIndex heightIndex = proxyModel->index(index.row(), 0);
- if (listView->gridSize().isEmpty())
- {
- retRect.setHeight(listView->sizeHintForIndex(heightIndex).height());
- }
- else
- {
- retRect.setHeight(qMin(listView->sizeHintForIndex(heightIndex).height(),
- listView->gridSize().height()));
- }
-
- return retRect;
-}
-
-QRect KCategorizedView::Private::visualCategoryRectInViewport(const QString &category)
- const
-{
- QRect retRect(listView->spacing(),
- listView->spacing(),
- listView->viewport()->width() - listView->spacing() * 2,
- 0);
-
- if (!proxyModel->rowCount() || !categories.contains(category))
- return QRect();
-
- QModelIndex index = proxyModel->index(0, 0, QModelIndex());
-
- int viewportWidth = listView->viewport()->width() - listView->spacing();
-
- int itemHeight;
- int itemWidth;
-
- if (listView->gridSize().isEmpty())
- {
- itemHeight = biggestItemSize.height();
- itemWidth = biggestItemSize.width();
- }
- else
- {
- itemHeight = listView->gridSize().height();
- itemWidth = listView->gridSize().width();
- }
-
- int itemWidthPlusSeparation = listView->spacing() + itemWidth;
- int elementsPerRow = viewportWidth / itemWidthPlusSeparation;
-
- if (!elementsPerRow)
- elementsPerRow++;
-
- foreach (const QString &itCategory, categories)
- {
- if (itCategory == category)
- break;
-
- float rows = (float) ((float) categoriesIndexes[itCategory].count() /
- (float) elementsPerRow);
- int rowsInt = categoriesIndexes[itCategory].count() / elementsPerRow;
-
- if (rows - trunc(rows)) rowsInt++;
-
- retRect.setTop(retRect.top() +
- (rowsInt * itemHeight) +
- categoryDrawer->categoryHeight(index, listView->viewOptions()) +
- listView->spacing() * 2);
-
- if (listView->gridSize().isEmpty())
- {
- retRect.setTop(retRect.top() +
- (rowsInt * listView->spacing()));
- }
- }
-
- retRect.setHeight(categoryDrawer->categoryHeight(index, listView->viewOptions()));
-
- return retRect;
-}
-
-// We're sure elementsPosition doesn't contain index
-const QRect &KCategorizedView::Private::cacheIndex(const QModelIndex &index)
-{
- QRect rect = visualRectInViewport(index);
- elementsPosition[index.row()] = rect;
-
- return elementsPosition[index.row()];
-}
-
-// We're sure categoriesPosition doesn't contain category
-const QRect &KCategorizedView::Private::cacheCategory(const QString &category)
-{
- QRect rect = visualCategoryRectInViewport(category);
- categoriesPosition[category] = rect;
-
- return categoriesPosition[category];
-}
-
-const QRect &KCategorizedView::Private::cachedRectIndex(const QModelIndex &index)
-{
- if (elementsPosition.contains(index.row())) // If we have it cached
- { // return it
- return elementsPosition[index.row()];
- }
- else // Otherwise, cache it
- { // and return it
- return cacheIndex(index);
- }
-}
-
-const QRect &KCategorizedView::Private::cachedRectCategory(const QString &category)
-{
- if (categoriesPosition.contains(category)) // If we have it cached
- { // return it
- return categoriesPosition[category];
- }
- else // Otherwise, cache it and
- { // return it
- return cacheCategory(category);
- }
-}
-
-QRect KCategorizedView::Private::visualRect(const QModelIndex &index)
-{
- QRect retRect = cachedRectIndex(index);
- int dx = -listView->horizontalOffset();
- int dy = -listView->verticalOffset();
- retRect.adjust(dx, dy, dx, dy);
-
- return retRect;
-}
-
-QRect KCategorizedView::Private::categoryVisualRect(const QString &category)
-{
- QRect retRect = cachedRectCategory(category);
- int dx = -listView->horizontalOffset();
- int dy = -listView->verticalOffset();
- retRect.adjust(dx, dy, dx, dy);
-
- return retRect;
-}
-
-void KCategorizedView::Private::drawNewCategory(const QModelIndex &index,
- int sortRole,
- const QStyleOption &option,
- QPainter *painter)
-{
- if (!index.isValid())
- {
- return;
- }
-
- QStyleOption optionCopy = option;
- const QString category = proxyModel->data(index, KCategorizedSortFilterProxyModel::CategoryDisplayRole).toString();
-
- optionCopy.state &= ~QStyle::State_Selected;
-
- if ((listView->selectionMode() != SingleSelection) && (listView->selectionMode() != NoSelection)) {
- if ((category == hoveredCategory) && !mouseButtonPressed)
- {
- optionCopy.state |= QStyle::State_MouseOver;
- }
- else if ((category == hoveredCategory) && mouseButtonPressed)
- {
- QPoint initialPressPosition = listView->viewport()->mapFromGlobal(QCursor::pos());
- initialPressPosition.setY(initialPressPosition.y() + listView->verticalOffset());
- initialPressPosition.setX(initialPressPosition.x() + listView->horizontalOffset());
-
- if (initialPressPosition == this->initialPressPosition)
- {
- optionCopy.state |= QStyle::State_Selected;
- }
- }
- }
-
- categoryDrawer->drawCategory(index,
- sortRole,
- optionCopy,
- painter);
-}
-
-
-void KCategorizedView::Private::updateScrollbars()
-{
- // find the last index in the last category
- QModelIndex lastIndex = categoriesIndexes.isEmpty() ? QModelIndex() : categoriesIndexes[categories.last()].last();
-
- int lastItemBottom = cachedRectIndex(lastIndex).top() +
- listView->spacing() + (listView->gridSize().isEmpty() ? biggestItemSize.height() : listView->gridSize().height()) - listView->viewport()->height();
-
- listView->horizontalScrollBar()->setRange(0, 0);
-
- listView->verticalScrollBar()->setSingleStep(listView->viewport()->height() / 10);
- listView->verticalScrollBar()->setPageStep(listView->viewport()->height());
- listView->verticalScrollBar()->setRange(0, lastItemBottom);
-}
-
-void KCategorizedView::Private::drawDraggedItems(QPainter *painter)
-{
- QStyleOptionViewItemV3 option = listView->viewOptions();
- option.state &= ~QStyle::State_MouseOver;
- foreach (const QModelIndex &index, listView->selectionModel()->selectedIndexes())
- {
- const int dx = mousePosition.x() - initialPressPosition.x() + listView->horizontalOffset();
- const int dy = mousePosition.y() - initialPressPosition.y() + listView->verticalOffset();
-
- option.rect = visualRect(index);
- option.rect.adjust(dx, dy, dx, dy);
-
- if (option.rect.intersects(listView->viewport()->rect()))
- {
- listView->itemDelegate(index)->paint(painter, option, index);
- }
- }
-}
-
-void KCategorizedView::Private::layoutChanged(bool forceItemReload)
-{
- if ((listView->viewMode() == KCategorizedView::IconMode) && proxyModel &&
- categoryDrawer && proxyModel->isCategorizedModel() &&
- ((forceItemReload ||
- (modelSortRole != proxyModel->sortRole()) ||
- (modelSortColumn != proxyModel->sortColumn()) ||
- (modelSortOrder != proxyModel->sortOrder()) ||
- (modelLastRowCount != proxyModel->rowCount()) ||
- (modelCategorized != proxyModel->isCategorizedModel()))))
- {
- // Force the view to update all elements
- listView->rowsInsertedArtifficial(QModelIndex(), 0, proxyModel->rowCount() - 1);
-
- if (!forceItemReload)
- {
- modelSortRole = proxyModel->sortRole();
- modelSortColumn = proxyModel->sortColumn();
- modelSortOrder = proxyModel->sortOrder();
- modelLastRowCount = proxyModel->rowCount();
- modelCategorized = proxyModel->isCategorizedModel();
- }
- }
- else if ((listView->viewMode() == KCategorizedView::IconMode) && proxyModel &&
- categoryDrawer && proxyModel->isCategorizedModel())
- {
- updateScrollbars();
- }
-}
-
-void KCategorizedView::Private::drawDraggedItems()
-{
- QRect rectToUpdate;
- QRect currentRect;
- foreach (const QModelIndex &index, listView->selectionModel()->selectedIndexes())
- {
- int dx = mousePosition.x() - initialPressPosition.x() + listView->horizontalOffset();
- int dy = mousePosition.y() - initialPressPosition.y() + listView->verticalOffset();
-
- currentRect = visualRect(index);
- currentRect.adjust(dx, dy, dx, dy);
-
- if (currentRect.intersects(listView->viewport()->rect()))
- {
- rectToUpdate = rectToUpdate.united(currentRect);
- }
- }
-
- listView->viewport()->update(lastDraggedItemsRect.united(rectToUpdate));
-
- lastDraggedItemsRect = rectToUpdate;
-}
-
-
-//==============================================================================
-
-
-KCategorizedView::KCategorizedView(QWidget *parent)
- : QListView(parent)
- , d(new Private(this))
-{
-}
-
-KCategorizedView::~KCategorizedView()
-{
- delete d;
-}
-
-void KCategorizedView::setGridSize(const QSize &size)
-{
- QListView::setGridSize(size);
-
- d->layoutChanged(true);
-}
-
-void KCategorizedView::setModel(QAbstractItemModel *model)
-{
- d->lastSelection = QItemSelection();
- d->forcedSelectionPosition = 0;
- d->elementsInfo.clear();
- d->elementsPosition.clear();
- d->categoriesIndexes.clear();
- d->categoriesPosition.clear();
- d->categories.clear();
- d->intersectedIndexes.clear();
- d->modelIndexList.clear();
- d->hovered = QModelIndex();
- d->mouseButtonPressed = false;
- d->rightMouseButtonPressed = false;
-
- if (d->proxyModel)
- {
- QObject::disconnect(d->proxyModel,
- SIGNAL(layoutChanged()),
- this, SLOT(slotLayoutChanged()));
-
- QObject::disconnect(d->proxyModel,
- SIGNAL(dataChanged(QModelIndex,QModelIndex)),
- this, SLOT(slotLayoutChanged()));
-
- QObject::disconnect(d->proxyModel,
- SIGNAL(rowsRemoved(QModelIndex,int,int)),
- this, SLOT(rowsRemoved(QModelIndex,int,int)));
- }
-
- QListView::setModel(model);
-
- d->proxyModel = dynamic_cast<KCategorizedSortFilterProxyModel*>(model);
-
- if (d->proxyModel)
- {
- d->modelSortRole = d->proxyModel->sortRole();
- d->modelSortColumn = d->proxyModel->sortColumn();
- d->modelSortOrder = d->proxyModel->sortOrder();
- d->modelLastRowCount = d->proxyModel->rowCount();
- d->modelCategorized = d->proxyModel->isCategorizedModel();
-
- QObject::connect(d->proxyModel,
- SIGNAL(layoutChanged()),
- this, SLOT(slotLayoutChanged()));
-
- QObject::connect(d->proxyModel,
- SIGNAL(dataChanged(QModelIndex,QModelIndex)),
- this, SLOT(slotLayoutChanged()));
-
- QObject::connect(d->proxyModel,
- SIGNAL(rowsRemoved(QModelIndex,int,int)),
- this, SLOT(rowsRemoved(QModelIndex,int,int)));
-
- if (d->proxyModel->rowCount())
- {
- d->layoutChanged(true);
- }
- }
- else
- {
- d->modelCategorized = false;
- }
-}
-
-QRect KCategorizedView::visualRect(const QModelIndex &index) const
-{
- if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel ||
- !d->categoryDrawer || !d->proxyModel->isCategorizedModel())
- {
- return QListView::visualRect(index);
- }
-
- if (!qobject_cast<const QSortFilterProxyModel*>(index.model()))
- {
- return d->visualRect(d->proxyModel->mapFromSource(index));
- }
-
- return d->visualRect(index);
-}
-
-KCategoryDrawer *KCategorizedView::categoryDrawer() const
-{
- return d->categoryDrawer;
-}
-
-void KCategorizedView::setCategoryDrawer(KCategoryDrawer *categoryDrawer)
-{
- d->lastSelection = QItemSelection();
- d->forcedSelectionPosition = 0;
- d->elementsInfo.clear();
- d->elementsPosition.clear();
- d->categoriesIndexes.clear();
- d->categoriesPosition.clear();
- d->categories.clear();
- d->intersectedIndexes.clear();
- d->modelIndexList.clear();
- d->hovered = QModelIndex();
- d->mouseButtonPressed = false;
- d->rightMouseButtonPressed = false;
-
- if (!categoryDrawer && d->proxyModel)
- {
- QObject::disconnect(d->proxyModel,
- SIGNAL(layoutChanged()),
- this, SLOT(slotLayoutChanged()));
-
- QObject::disconnect(d->proxyModel,
- SIGNAL(dataChanged(QModelIndex,QModelIndex)),
- this, SLOT(slotLayoutChanged()));
-
- QObject::disconnect(d->proxyModel,
- SIGNAL(rowsRemoved(QModelIndex,int,int)),
- this, SLOT(rowsRemoved(QModelIndex,int,int)));
- }
- else if (categoryDrawer && d->proxyModel)
- {
- QObject::connect(d->proxyModel,
- SIGNAL(layoutChanged()),
- this, SLOT(slotLayoutChanged()));
-
- QObject::connect(d->proxyModel,
- SIGNAL(dataChanged(QModelIndex,QModelIndex)),
- this, SLOT(slotLayoutChanged()));
-
- QObject::connect(d->proxyModel,
- SIGNAL(rowsRemoved(QModelIndex,int,int)),
- this, SLOT(rowsRemoved(QModelIndex,int,int)));
- }
-
- d->categoryDrawer = categoryDrawer;
-
- if (categoryDrawer)
- {
- if (d->proxyModel)
- {
- if (d->proxyModel->rowCount())
- {
- d->layoutChanged(true);
- }
- }
- }
- else
- {
- updateGeometries();
- }
-}
-
-QModelIndex KCategorizedView::indexAt(const QPoint &point) const
-{
- if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel ||
- !d->categoryDrawer || !d->proxyModel->isCategorizedModel())
- {
- return QListView::indexAt(point);
- }
-
- QModelIndex index;
-
- QModelIndexList item = d->intersectionSet(QRect(point, point));
-
- if (item.count() == 1)
- {
- index = item[0];
- }
-
- return index;
-}
-
-void KCategorizedView::reset()
-{
- QListView::reset();
-
- d->lastSelection = QItemSelection();
- d->forcedSelectionPosition = 0;
- d->elementsInfo.clear();
- d->elementsPosition.clear();
- d->categoriesIndexes.clear();
- d->categoriesPosition.clear();
- d->categories.clear();
- d->intersectedIndexes.clear();
- d->modelIndexList.clear();
- d->hovered = QModelIndex();
- d->biggestItemSize = QSize(0, 0);
- d->mouseButtonPressed = false;
- d->rightMouseButtonPressed = false;
-}
-
-void KCategorizedView::paintEvent(QPaintEvent *event)
-{
- if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel ||
- !d->categoryDrawer || !d->proxyModel->isCategorizedModel())
- {
- QListView::paintEvent(event);
- return;
- }
-
- QStyleOptionViewItemV3 option = viewOptions();
- option.widget = this;
- if (wordWrap())
- {
- option.features |= QStyleOptionViewItemV2::WrapText;
- }
-
- QPainter painter(viewport());
- QRect area = event->rect();
- const bool focus = (hasFocus() || viewport()->hasFocus()) &&
- currentIndex().isValid();
- const QStyle::State state = option.state;
- const bool enabled = (state & QStyle::State_Enabled) != 0;
-
- painter.save();
-
- QModelIndexList dirtyIndexes = d->intersectionSet(area);
- foreach (const QModelIndex &index, dirtyIndexes)
- {
- option.state = state;
- option.rect = visualRect(index);
-
- if (selectionModel() && selectionModel()->isSelected(index))
- {
- option.state |= QStyle::State_Selected;
- }
-
- if (enabled)
- {
- QPalette::ColorGroup cg;
- if ((d->proxyModel->flags(index) & Qt::ItemIsEnabled) == 0)
- {
- option.state &= ~QStyle::State_Enabled;
- cg = QPalette::Disabled;
- }
- else
- {
- cg = QPalette::Normal;
- }
- option.palette.setCurrentColorGroup(cg);
- }
-
- if (focus && currentIndex() == index)
- {
- option.state |= QStyle::State_HasFocus;
- if (this->state() == EditingState)
- option.state |= QStyle::State_Editing;
- }
-
- // we are only interested to give the mouse over feedback when no
- // dragging is happening (ereslibre)
- if ((index == d->hovered) && !d->mouseButtonPressed &&
- (this->state() == QAbstractItemView::NoState))
- option.state |= QStyle::State_MouseOver;
- else
- option.state &= ~QStyle::State_MouseOver;
-
- itemDelegate(index)->paint(&painter, option, index);
- }
-
- // Redraw categories
- QStyleOptionViewItem otherOption;
- bool intersectedInThePast = false;
- foreach (const QString &category, d->categories)
- {
- otherOption = option;
- otherOption.rect = d->categoryVisualRect(category);
- otherOption.state &= ~QStyle::State_MouseOver;
-
- if (otherOption.rect.intersects(area))
- {
- intersectedInThePast = true;
-
- QModelIndex indexToDraw = d->proxyModel->index(d->categoriesIndexes[category][0].row(), d->proxyModel->sortColumn());
-
- d->drawNewCategory(indexToDraw,
- d->proxyModel->sortRole(), otherOption, &painter);
- }
- else if (intersectedInThePast)
- {
- break; // the visible area has been finished, we don't need to keep asking, the rest won't intersect
- // this is doable because we know that categories are correctly ordered on the list
- }
- }
-
- if ((selectionMode() != SingleSelection) && (selectionMode() != NoSelection))
- {
- if (d->mouseButtonPressed && !d->isDragging)
- {
- QPoint start, end, initialPressPosition;
-
- initialPressPosition = d->initialPressPosition;
-
- initialPressPosition.setY(initialPressPosition.y() - verticalOffset());
- initialPressPosition.setX(initialPressPosition.x() - horizontalOffset());
-
- if (d->initialPressPosition.x() > d->mousePosition.x() ||
- d->initialPressPosition.y() > d->mousePosition.y())
- {
- start = d->mousePosition;
- end = initialPressPosition;
- }
- else
- {
- start = initialPressPosition;
- end = d->mousePosition;
- }
-
- QStyleOptionRubberBand yetAnotherOption;
- yetAnotherOption.initFrom(this);
- yetAnotherOption.shape = QRubberBand::Rectangle;
- yetAnotherOption.opaque = false;
- yetAnotherOption.rect = QRect(start, end).intersected(viewport()->rect().adjusted(-16, -16, 16, 16));
- painter.save();
- style()->drawControl(QStyle::CE_RubberBand, &yetAnotherOption, &painter);
- painter.restore();
- }
- }
-
- if (d->isDragging && !d->dragLeftViewport)
- {
- painter.setOpacity(0.5);
- d->drawDraggedItems(&painter);
- }
-
- painter.restore();
-}
-
-void KCategorizedView::resizeEvent(QResizeEvent *event)
-{
- QListView::resizeEvent(event);
-
- // Clear the items positions cache
- d->elementsPosition.clear();
- d->categoriesPosition.clear();
- d->forcedSelectionPosition = 0;
-
- if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel ||
- !d->categoryDrawer || !d->proxyModel->isCategorizedModel())
- {
- return;
- }
-
- d->updateScrollbars();
-}
-
-void KCategorizedView::setSelection(const QRect &rect,
- QItemSelectionModel::SelectionFlags flags)
-{
- if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel ||
- !d->categoryDrawer || !d->proxyModel->isCategorizedModel())
- {
- QListView::setSelection(rect, flags);
- return;
- }
-
- if (!flags)
- return;
-
- if (flags & QItemSelectionModel::Clear)
- {
- selectionModel()->clear();
- d->lastSelection.clear();
- }
-
- QModelIndexList dirtyIndexes = d->intersectionSet(rect);
-
- // no items affected, just leave
- if (!dirtyIndexes.count())
- {
- selectionModel()->select(d->lastSelection, QItemSelectionModel::SelectCurrent);
-
- return;
- }
-
- QModelIndex topLeft;
- QModelIndex bottomRight;
-
- if (d->mouseButtonPressed || d->rightMouseButtonPressed) // selection with click + drag
- {
- QItemSelection selection;
-
- QModelIndex prev = dirtyIndexes[0];
- QModelIndex first = prev;
- foreach (const QModelIndex &index, dirtyIndexes)
- {
- // we have a different interval. non-contiguous items
- if ((index.row() - prev.row()) > 1) {
- selection << QItemSelectionRange(first, prev);
-
- first = index;
- }
-
- prev = index;
- }
-
- selection << QItemSelectionRange(first, prev);
-
- if (flags & QItemSelectionModel::Current)
- {
- if (rect.topLeft() == rect.bottomRight())
- {
- selectionModel()->setCurrentIndex(indexAt(rect.topLeft()), QItemSelectionModel::NoUpdate);
- }
-
- selection.merge(d->lastSelection, flags);
- }
- else
- {
- selection.merge(selectionModel()->selection(), flags);
-
- selectionModel()->select(selection, QItemSelectionModel::SelectCurrent);
-
- return;
- }
-
- selectionModel()->select(selection, flags);
- }
- else // selection with click + keyboard keys
- {
- QModelIndex topLeftIndex = indexAt(QPoint(rect.topLeft().x(),
- rect.topLeft().y()));
- QModelIndex bottomRightIndex = indexAt(QPoint(rect.bottomRight().x(),
- rect.bottomRight().y()));
-
- // keyboard selection comes "upside down". Let's normalize it
- if (topLeftIndex.row() > bottomRightIndex.row())
- {
- QModelIndex auxIndex = topLeftIndex;
- topLeftIndex = bottomRightIndex;
- bottomRightIndex = auxIndex;
- }
-
- int viewportWidth = viewport()->width() - spacing();
- int itemWidth;
-
- if (gridSize().isEmpty())
- {
- itemWidth = d->biggestItemSize.width();
- }
- else
- {
- itemWidth = gridSize().width();
- }
-
- int itemWidthPlusSeparation = spacing() + itemWidth;
- int elementsPerRow = viewportWidth / itemWidthPlusSeparation;
- if (!elementsPerRow)
- elementsPerRow++;
-
- QModelIndexList theoricDirty(dirtyIndexes);
- dirtyIndexes.clear();
- int first = model()->rowCount();
- int last = 0;
-
- foreach (const QModelIndex &index, theoricDirty)
- {
- if ((index.row() < first) &&
- ((((topLeftIndex.row() / elementsPerRow) == (index.row() / elementsPerRow)) &&
- ((topLeftIndex.row() % elementsPerRow) <= (index.row() % elementsPerRow))) ||
- (topLeftIndex.row() / elementsPerRow) != (index.row() / elementsPerRow)))
- {
- first = index.row();
- topLeft = index;
- }
-
- if ((index.row() > last) &&
- ((((bottomRightIndex.row() / elementsPerRow) == (index.row() / elementsPerRow)) &&
- ((bottomRightIndex.row() % elementsPerRow) >= (index.row() % elementsPerRow))) ||
- (bottomRightIndex.row() / elementsPerRow) != (index.row() / elementsPerRow)))
- {
- last = index.row();
- bottomRight = index;
- }
- }
-
- for (int i = first; i <= last; i++)
- {
- dirtyIndexes << model()->index(i, theoricDirty[0].column(), theoricDirty[0].parent());
- }
-
- QItemSelection selection(topLeft, bottomRight);
-
- selectionModel()->select(selection, flags);
- }
-}
-
-void KCategorizedView::mouseMoveEvent(QMouseEvent *event)
-{
- QListView::mouseMoveEvent(event);
-
- if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel ||
- !d->categoryDrawer || !d->proxyModel->isCategorizedModel())
- {
- return;
- }
-
- QModelIndexList item = d->intersectionSet(QRect(event->pos(), event->pos()));
-
- if (item.count() == 1)
- {
- d->hovered = item[0];
- }
- else
- {
- d->hovered = QModelIndex();
- }
-
- const QString previousHoveredCategory = d->hoveredCategory;
-
- d->mousePosition = event->pos();
- d->hoveredCategory = QString();
-
- // Redraw categories
- foreach (const QString &category, d->categories)
- {
- if (d->categoryVisualRect(category).intersects(QRect(event->pos(), event->pos())))
- {
- d->hoveredCategory = category;
- viewport()->update(d->categoryVisualRect(category));
- }
- else if ((category == previousHoveredCategory) &&
- (!d->categoryVisualRect(previousHoveredCategory).intersects(QRect(event->pos(), event->pos()))))
- {
- viewport()->update(d->categoryVisualRect(category));
- }
- }
-
- QRect rect;
- if (d->mouseButtonPressed && !d->isDragging)
- {
- QPoint start, end, initialPressPosition;
-
- initialPressPosition = d->initialPressPosition;
-
- initialPressPosition.setY(initialPressPosition.y() - verticalOffset());
- initialPressPosition.setX(initialPressPosition.x() - horizontalOffset());
-
- if (d->initialPressPosition.x() > d->mousePosition.x() ||
- d->initialPressPosition.y() > d->mousePosition.y())
- {
- start = d->mousePosition;
- end = initialPressPosition;
- }
- else
- {
- start = initialPressPosition;
- end = d->mousePosition;
- }
-
- rect = QRect(start, end).adjusted(-16, -16, 16, 16);
- rect = rect.united(QRect(start, end).adjusted(16, 16, -16, -16)).intersected(viewport()->rect());
-
- viewport()->update(rect);
- }
-}
-
-void KCategorizedView::mousePressEvent(QMouseEvent *event)
-{
- d->dragLeftViewport = false;
-
- if (event->button() == Qt::LeftButton)
- {
- d->mouseButtonPressed = true;
-
- d->initialPressPosition = event->pos();
- d->initialPressPosition.setY(d->initialPressPosition.y() +
- verticalOffset());
- d->initialPressPosition.setX(d->initialPressPosition.x() +
- horizontalOffset());
- }
- else if (event->button() == Qt::RightButton)
- {
- d->rightMouseButtonPressed = true;
- }
-
- QListView::mousePressEvent(event);
-
- d->lastSelection = selectionModel()->selection();
-
- viewport()->update(d->categoryVisualRect(d->hoveredCategory));
-}
-
-void KCategorizedView::mouseReleaseEvent(QMouseEvent *event)
-{
- d->mouseButtonPressed = false;
- d->rightMouseButtonPressed = false;
-
- QListView::mouseReleaseEvent(event);
-
- if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel ||
- !d->categoryDrawer || !d->proxyModel->isCategorizedModel())
- {
- return;
- }
-
- QPoint initialPressPosition = viewport()->mapFromGlobal(QCursor::pos());
- initialPressPosition.setY(initialPressPosition.y() + verticalOffset());
- initialPressPosition.setX(initialPressPosition.x() + horizontalOffset());
-
- if ((selectionMode() != SingleSelection) && (selectionMode() != NoSelection) &&
- (initialPressPosition == d->initialPressPosition))
- {
- foreach(const QString &category, d->categories)
- {
- if (d->categoryVisualRect(category).contains(event->pos()))
- {
- QItemSelection selection = selectionModel()->selection();
- QModelIndexList indexList = d->categoriesIndexes[category];
-
- foreach (const QModelIndex &index, indexList)
- {
- QModelIndex selectIndex = index.model()->index(index.row(), 0);
-
- selection << QItemSelectionRange(selectIndex);
- }
-
- selectionModel()->select(selection, QItemSelectionModel::SelectCurrent);
-
- break;
- }
- }
- }
-
- QRect rect;
- if (!d->isDragging)
- {
- QPoint start, end, initialPressPosition;
-
- initialPressPosition = d->initialPressPosition;
-
- initialPressPosition.setY(initialPressPosition.y() - verticalOffset());
- initialPressPosition.setX(initialPressPosition.x() - horizontalOffset());
-
- if (d->initialPressPosition.x() > d->mousePosition.x() ||
- d->initialPressPosition.y() > d->mousePosition.y())
- {
- start = d->mousePosition;
- end = initialPressPosition;
- }
- else
- {
- start = initialPressPosition;
- end = d->mousePosition;
- }
-
- rect = QRect(start, end).adjusted(-16, -16, 16, 16);
- rect = rect.united(QRect(start, end).adjusted(16, 16, -16, -16)).intersected(viewport()->rect());
-
- viewport()->update(rect);
- }
-
- if (d->hovered.isValid())
- viewport()->update(visualRect(d->hovered));
- else if (!d->hoveredCategory.isEmpty())
- viewport()->update(d->categoryVisualRect(d->hoveredCategory));
-}
-
-void KCategorizedView::leaveEvent(QEvent *event)
-{
- d->hovered = QModelIndex();
- d->hoveredCategory = QString();
-
- QListView::leaveEvent(event);
-}
-
-void KCategorizedView::startDrag(Qt::DropActions supportedActions)
-{
- // FIXME: QAbstractItemView does far better here since it sets the
- // pixmap of selected icons to the dragging cursor, but it sets a non
- // ARGB window so it is no transparent. Use QAbstractItemView when
- // this is fixed on Qt.
- // QAbstractItemView::startDrag(supportedActions);
-#if !defined(DOLPHIN_DRAGANDDROP)
- QListView::startDrag(supportedActions);
-#endif
-
- d->isDragging = false;
- d->mouseButtonPressed = false;
- d->rightMouseButtonPressed = false;
-
- viewport()->update(d->lastDraggedItemsRect);
-}
-
-void KCategorizedView::dragMoveEvent(QDragMoveEvent *event)
-{
- d->mousePosition = event->pos();
-
- if (d->mouseButtonPressed)
- {
- d->isDragging = true;
- }
- else
- {
- d->isDragging = false;
- }
-
- d->dragLeftViewport = false;
-
-#if defined(DOLPHIN_DRAGANDDROP)
- QAbstractItemView::dragMoveEvent(event);
-#else
- QListView::dragMoveEvent(event);
-#endif
-
- if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel ||
- !d->categoryDrawer || !d->proxyModel->isCategorizedModel())
- {
- return;
- }
-
- d->drawDraggedItems();
-}
-
-void KCategorizedView::dragLeaveEvent(QDragLeaveEvent *event)
-{
- d->dragLeftViewport = true;
-
-#if defined(DOLPHIN_DRAGANDDROP)
- QAbstractItemView::dragLeaveEvent(event);
-#else
- QListView::dragLeaveEvent(event);
-#endif
-}
-
-void KCategorizedView::dropEvent(QDropEvent *event)
-{
-#if defined(DOLPHIN_DRAGANDDROP)
- QAbstractItemView::dropEvent(event);
-#else
- QListView::dropEvent(event);
-#endif
-}
-
-QModelIndex KCategorizedView::moveCursor(CursorAction cursorAction,
- Qt::KeyboardModifiers modifiers)
-{
- if ((viewMode() != KCategorizedView::IconMode) ||
- !d->proxyModel ||
- !d->categoryDrawer ||
- d->categories.isEmpty() ||
- !d->proxyModel->isCategorizedModel()
- )
- {
- return QListView::moveCursor(cursorAction, modifiers);
- }
-
- int viewportWidth = viewport()->width() - spacing();
- int itemWidth;
-
- if (gridSize().isEmpty())
- {
- itemWidth = d->biggestItemSize.width();
- }
- else
- {
- itemWidth = gridSize().width();
- }
-
- int itemWidthPlusSeparation = spacing() + itemWidth;
- int elementsPerRow = viewportWidth / itemWidthPlusSeparation;
- if (!elementsPerRow)
- elementsPerRow++;
-
- QModelIndex current = selectionModel()->currentIndex();
-
- if (!current.isValid())
- {
- if (cursorAction == MoveEnd)
- {
- current = model()->index(model()->rowCount() - 1, 0, QModelIndex());
- d->forcedSelectionPosition = d->elementsInfo[current.row()].relativeOffsetToCategory % elementsPerRow;
- }
- else
- {
- current = model()->index(0, 0, QModelIndex());
- d->forcedSelectionPosition = 0;
- }
-
- return current;
- }
- else if (!current.isValid())
- {
- return QModelIndex();
- }
-
- QString lastCategory = d->categories.first();
- QString theCategory = d->categories.first();
- QString afterCategory = d->categories.first();
-
- bool hasToBreak = false;
- foreach (const QString &category, d->categories)
- {
- if (hasToBreak)
- {
- afterCategory = category;
-
- break;
- }
-
- if (category == d->elementsInfo[current.row()].category)
- {
- theCategory = category;
-
- hasToBreak = true;
- }
-
- if (!hasToBreak)
- {
- lastCategory = category;
- }
- }
-
- switch (cursorAction)
- {
- case QAbstractItemView::MoveUp: {
- if (d->elementsInfo[current.row()].relativeOffsetToCategory >= elementsPerRow)
- {
- int indexToMove = current.row();
- indexToMove -= qMin(((d->elementsInfo[current.row()].relativeOffsetToCategory) + d->forcedSelectionPosition), elementsPerRow - d->forcedSelectionPosition + (d->elementsInfo[current.row()].relativeOffsetToCategory % elementsPerRow));
-
- return d->proxyModel->index(indexToMove, 0);
- }
- else
- {
- int lastCategoryLastRow = (d->categoriesIndexes[lastCategory].count() - 1) % elementsPerRow;
- int indexToMove = current.row() - d->elementsInfo[current.row()].relativeOffsetToCategory;
-
- if (d->forcedSelectionPosition >= lastCategoryLastRow)
- {
- indexToMove -= 1;
- }
- else
- {
- indexToMove -= qMin((lastCategoryLastRow - d->forcedSelectionPosition + 1), d->forcedSelectionPosition + elementsPerRow + 1);
- }
-
- return d->proxyModel->index(indexToMove, 0);
- }
- }
-
- case QAbstractItemView::MoveDown: {
- if (d->elementsInfo[current.row()].relativeOffsetToCategory < (d->categoriesIndexes[theCategory].count() - 1 - ((d->categoriesIndexes[theCategory].count() - 1) % elementsPerRow)))
- {
- int indexToMove = current.row();
- indexToMove += qMin(elementsPerRow, d->categoriesIndexes[theCategory].count() - 1 - d->elementsInfo[current.row()].relativeOffsetToCategory);
-
- return d->proxyModel->index(indexToMove, 0);
- }
- else
- {
- int afterCategoryLastRow = qMin(elementsPerRow, d->categoriesIndexes[afterCategory].count());
- int indexToMove = current.row() + (d->categoriesIndexes[theCategory].count() - d->elementsInfo[current.row()].relativeOffsetToCategory);
-
- if (d->forcedSelectionPosition >= afterCategoryLastRow)
- {
- indexToMove += afterCategoryLastRow - 1;
- }
- else
- {
- indexToMove += qMin(d->forcedSelectionPosition, elementsPerRow);
- }
-
- return d->proxyModel->index(indexToMove, 0);
- }
- }
-
- case QAbstractItemView::MoveLeft:
- if (layoutDirection() == Qt::RightToLeft)
- {
- if (!(d->elementsInfo[current.row() + 1].relativeOffsetToCategory % elementsPerRow))
- return current;
-
- d->forcedSelectionPosition = d->elementsInfo[current.row() + 1].relativeOffsetToCategory % elementsPerRow;
-
-#if 0 //follow qt view behavior. lateral movements won't change visual row
- if (d->forcedSelectionPosition < 0)
- d->forcedSelectionPosition = (d->categoriesIndexes[theCategory].count() - 1) % elementsPerRow;
-#endif
-
- return d->proxyModel->index(current.row() + 1, 0);
- }
-
- if (!(d->elementsInfo[current.row()].relativeOffsetToCategory % elementsPerRow))
- return current;
-
- d->forcedSelectionPosition = d->elementsInfo[current.row() - 1].relativeOffsetToCategory % elementsPerRow;
-
-#if 0 //follow qt view behavior. lateral movements won't change visual row
- if (d->forcedSelectionPosition < 0)
- d->forcedSelectionPosition = (d->categoriesIndexes[theCategory].count() - 1) % elementsPerRow;
-#endif
-
- return d->proxyModel->index(current.row() - 1, 0);
-
- case QAbstractItemView::MoveRight:
- if (layoutDirection() == Qt::RightToLeft)
- {
- if (!(d->elementsInfo[current.row()].relativeOffsetToCategory % elementsPerRow))
- return current;
-
- d->forcedSelectionPosition = d->elementsInfo[current.row() - 1].relativeOffsetToCategory % elementsPerRow;
-
-#if 0 //follow qt view behavior. lateral movements won't change visual row
- if (d->forcedSelectionPosition < 0)
- d->forcedSelectionPosition = (d->categoriesIndexes[theCategory].count() - 1) % elementsPerRow;
-#endif
-
- return d->proxyModel->index(current.row() - 1, 0);
- }
-
- if (!(d->elementsInfo[current.row() + 1].relativeOffsetToCategory % elementsPerRow))
- return current;
-
- d->forcedSelectionPosition = d->elementsInfo[current.row() + 1].relativeOffsetToCategory % elementsPerRow;
-
-#if 0 //follow qt view behavior. lateral movements won't change visual row
- if (d->forcedSelectionPosition < 0)
- d->forcedSelectionPosition = (d->categoriesIndexes[theCategory].count() - 1) % elementsPerRow;
-#endif
-
- return d->proxyModel->index(current.row() + 1, 0);
-
- default:
- break;
- }
-
- return QListView::moveCursor(cursorAction, modifiers);
-}
-
-void KCategorizedView::rowsInserted(const QModelIndex &parent,
- int start,
- int end)
-{
- QListView::rowsInserted(parent, start, end);
-
- if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel ||
- !d->categoryDrawer || !d->proxyModel->isCategorizedModel())
- {
- d->forcedSelectionPosition = 0;
- d->elementsInfo.clear();
- d->elementsPosition.clear();
- d->categoriesIndexes.clear();
- d->categoriesPosition.clear();
- d->categories.clear();
- d->intersectedIndexes.clear();
- d->modelIndexList.clear();
- d->hovered = QModelIndex();
- d->biggestItemSize = QSize(0, 0);
- d->mouseButtonPressed = false;
- d->rightMouseButtonPressed = false;
-
- return;
- }
-
- rowsInsertedArtifficial(parent, start, end);
-}
-
-void KCategorizedView::rowsInsertedArtifficial(const QModelIndex &parent,
- int start,
- int end)
-{
- Q_UNUSED(parent);
-
- d->forcedSelectionPosition = 0;
- d->elementsInfo.clear();
- d->elementsPosition.clear();
- d->categoriesIndexes.clear();
- d->categoriesPosition.clear();
- d->categories.clear();
- d->intersectedIndexes.clear();
- d->modelIndexList.clear();
- d->hovered = QModelIndex();
- d->biggestItemSize = QSize(0, 0);
- d->mouseButtonPressed = false;
- d->rightMouseButtonPressed = false;
-
- if (start > end || end < 0 || start < 0 || !d->proxyModel->rowCount())
- {
- return;
- }
-
- // Add all elements mapped to the source model and explore categories
- QString prevCategory = d->proxyModel->data(d->proxyModel->index(0, d->proxyModel->sortColumn()), KCategorizedSortFilterProxyModel::CategoryDisplayRole).toString();
- QString lastCategory = prevCategory;
- QModelIndexList modelIndexList;
- struct Private::ElementInfo elementInfo;
- int offset = -1;
- for (int k = 0; k < d->proxyModel->rowCount(); ++k)
- {
- QModelIndex index = d->proxyModel->index(k, d->proxyModel->sortColumn());
- QModelIndex indexSize = d->proxyModel->index(k, 0);
-
- d->biggestItemSize = QSize(qMax(sizeHintForIndex(indexSize).width(),
- d->biggestItemSize.width()),
- qMax(sizeHintForIndex(indexSize).height(),
- d->biggestItemSize.height()));
-
- d->modelIndexList << index;
-
- lastCategory = d->proxyModel->data(index, KCategorizedSortFilterProxyModel::CategoryDisplayRole).toString();
-
- elementInfo.category = lastCategory;
-
- if (prevCategory != lastCategory)
- {
- offset = 0;
- d->categoriesIndexes.insert(prevCategory, modelIndexList);
- d->categories << prevCategory;
- modelIndexList.clear();
- }
- else
- {
- offset++;
- }
-
- elementInfo.relativeOffsetToCategory = offset;
-
- modelIndexList << index;
- prevCategory = lastCategory;
-
- d->elementsInfo.insert(index.row(), elementInfo);
- }
-
- d->categoriesIndexes.insert(prevCategory, modelIndexList);
- d->categories << prevCategory;
-
- d->updateScrollbars();
-
- // FIXME: We need to safely save the last selection. This is on my TODO
- // list (ereslibre).
- selectionModel()->clear();
-}
-
-void KCategorizedView::rowsRemoved(const QModelIndex &parent,
- int start,
- int end)
-{
- if ((viewMode() == KCategorizedView::IconMode) && d->proxyModel &&
- d->categoryDrawer && d->proxyModel->isCategorizedModel())
- {
- // Force the view to update all elements
- rowsInsertedArtifficial(QModelIndex(), 0, d->proxyModel->rowCount() - 1);
- }
-}
-
-void KCategorizedView::updateGeometries()
-{
- if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel ||
- !d->categoryDrawer || !d->proxyModel->isCategorizedModel())
- {
- QListView::updateGeometries();
- return;
- }
-
- // Avoid QListView::updateGeometries(), since it will try to set another
- // range to our scroll bars, what we don't want (ereslibre)
- QAbstractItemView::updateGeometries();
-}
-
-void KCategorizedView::slotLayoutChanged()
-{
- d->layoutChanged();
-}
-
-void KCategorizedView::currentChanged(const QModelIndex &current,
- const QModelIndex &previous)
-{
- // We need to update the forcedSelectionPosition property in order to correctly
- // navigate after with keyboard using up & down keys
-
- int viewportWidth = viewport()->width() - spacing();
-
- int itemHeight;
- int itemWidth;
-
- if (gridSize().isEmpty())
- {
- itemHeight = d->biggestItemSize.height();
- itemWidth = d->biggestItemSize.width();
- }
- else
- {
- itemHeight = gridSize().height();
- itemWidth = gridSize().width();
- }
-
- int itemWidthPlusSeparation = spacing() + itemWidth;
- int elementsPerRow = viewportWidth / itemWidthPlusSeparation;
- if (!elementsPerRow)
- elementsPerRow++;
-
- if (d->mouseButtonPressed || d->rightMouseButtonPressed)
- d->forcedSelectionPosition = d->elementsInfo[current.row()].relativeOffsetToCategory % elementsPerRow;
-
- QListView::currentChanged(current, previous);
-}
-
-#include "kcategorizedview.moc"
diff --git a/src/kcategorizedview.h b/src/kcategorizedview.h
deleted file mode 100644
index 015433ae3..000000000
--- a/src/kcategorizedview.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/**
- * This file is part of the KDE project
- * Copyright (C) 2007 Rafael Fernández López <[email protected]>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef KCATEGORIZEDVIEW_H
-#define KCATEGORIZEDVIEW_H
-
-#include <QtGui/QListView>
-
-#include <libdolphin_export.h>
-
-class KCategoryDrawer;
-
-/**
- * @short Item view for listing items
- *
- * KCategorizedView allows you to use it as it were a QListView. You can add an
- * itemCategorizer to it, so your items became categorized depending on the
- * KItemCategorizer inherited class rules.
- *
- * @see KItemCategorizer, KSortFilterProxyModel
- *
- * @author Rafael Fernández López <[email protected]>
- */
-class LIBDOLPHINPRIVATE_EXPORT KCategorizedView
- : public QListView
-{
- Q_OBJECT
-
-public:
- KCategorizedView(QWidget *parent = 0);
-
- ~KCategorizedView();
-
- virtual void setModel(QAbstractItemModel *model);
-
- void setGridSize(const QSize &size);
-
- virtual QRect visualRect(const QModelIndex &index) const;
-
- KCategoryDrawer *categoryDrawer() const;
-
- void setCategoryDrawer(KCategoryDrawer *categoryDrawer);
-
- virtual QModelIndex indexAt(const QPoint &point) const;
-
-public Q_SLOTS:
- virtual void reset();
-
-protected:
- virtual void paintEvent(QPaintEvent *event);
-
- virtual void resizeEvent(QResizeEvent *event);
-
- virtual void setSelection(const QRect &rect,
- QItemSelectionModel::SelectionFlags flags);
-
- virtual void mouseMoveEvent(QMouseEvent *event);
-
- virtual void mousePressEvent(QMouseEvent *event);
-
- virtual void mouseReleaseEvent(QMouseEvent *event);
-
- virtual void leaveEvent(QEvent *event);
-
- virtual void startDrag(Qt::DropActions supportedActions);
-
- virtual void dragMoveEvent(QDragMoveEvent *event);
-
- virtual void dragLeaveEvent(QDragLeaveEvent *event);
-
- virtual void dropEvent(QDropEvent *event);
-
- virtual QModelIndex moveCursor(CursorAction cursorAction,
- Qt::KeyboardModifiers modifiers);
-
-protected Q_SLOTS:
- virtual void rowsInserted(const QModelIndex &parent,
- int start,
- int end);
-
- virtual void rowsInsertedArtifficial(const QModelIndex &parent,
- int start,
- int end);
-
- virtual void rowsRemoved(const QModelIndex &parent,
- int start,
- int end);
-
- virtual void updateGeometries();
-
- virtual void slotLayoutChanged();
-
- virtual void currentChanged(const QModelIndex &current,
- const QModelIndex &previous);
-
-
-private:
- class Private;
- Private *d;
-};
-
-#endif // KCATEGORIZEDVIEW_H
diff --git a/src/kcategorizedview_p.h b/src/kcategorizedview_p.h
deleted file mode 100644
index a18854ba3..000000000
--- a/src/kcategorizedview_p.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/**
- * This file is part of the KDE project
- * Copyright (C) 2007 Rafael Fernández López <[email protected]>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef KCATEGORIZEDVIEW_P_H
-#define KCATEGORIZEDVIEW_P_H
-
-class KCategorizedSortFilterProxyModel;
-class KCategoryDrawer;
-
-/**
- * @internal
- */
-class KCategorizedView::Private
-{
-public:
- Private(KCategorizedView *listView);
- ~Private();
-
-
- // Methods
-
- /**
- * Returns the list of items that intersects with @p rect
- */
- const QModelIndexList &intersectionSet(const QRect &rect);
-
- /**
- * Gets the item rect in the viewport for @p index
- */
- QRect visualRectInViewport(const QModelIndex &index) const;
-
- /**
- * Returns the category rect in the viewport for @p category
- */
- QRect visualCategoryRectInViewport(const QString &category) const;
-
- /**
- * Caches and returns the rect that corresponds to @p index
- */
- const QRect &cacheIndex(const QModelIndex &index);
-
- /**
- * Caches and returns the rect that corresponds to @p category
- */
- const QRect &cacheCategory(const QString &category);
-
- /**
- * Returns the rect that corresponds to @p index
- * @note If the rect is not cached, it becomes cached
- */
- const QRect &cachedRectIndex(const QModelIndex &index);
-
- /**
- * Returns the rect that corresponds to @p category
- * @note If the rect is not cached, it becomes cached
- */
- const QRect &cachedRectCategory(const QString &category);
-
- /**
- * Returns the visual rect (taking in count x and y offsets) for @p index
- * @note If the rect is not cached, it becomes cached
- */
- QRect visualRect(const QModelIndex &index);
-
- /**
- * Returns the visual rect (taking in count x and y offsets) for @p category
- * @note If the rect is not cached, it becomes cached
- */
- QRect categoryVisualRect(const QString &category);
-
- /**
- * This method will draw a new category represented by index
- * @param index on the rect specified by @p option.rect, with
- * painter @p painter
- */
- void drawNewCategory(const QModelIndex &index,
- int sortRole,
- const QStyleOption &option,
- QPainter *painter);
-
- /**
- * This method will update scrollbars ranges. Called when our model changes
- * or when the view is resized
- */
- void updateScrollbars();
-
- /**
- * This method will draw dragged items in the painting operation
- */
- void drawDraggedItems(QPainter *painter);
-
- /**
- * This method will determine which rect needs to be updated because of a
- * dragging operation
- */
- void drawDraggedItems();
-
- void layoutChanged(bool forceItemReload = false);
-
-
- // Attributes
-
- struct ElementInfo
- {
- QString category;
- int relativeOffsetToCategory;
- };
-
- // Basic data
- KCategorizedView *listView;
- KCategoryDrawer *categoryDrawer;
- QSize biggestItemSize;
-
- // Behavior data
- bool mouseButtonPressed;
- bool rightMouseButtonPressed;
- bool isDragging;
- bool dragLeftViewport;
- QModelIndex hovered;
- QString hoveredCategory;
- QPoint initialPressPosition;
- QPoint mousePosition;
- int forcedSelectionPosition;
-
- // Cache data
- // We cannot merge some of them into structs because it would affect
- // performance
- QHash<int, struct ElementInfo> elementsInfo;
- QHash<int, QRect> elementsPosition;
- QHash<QString, QModelIndexList> categoriesIndexes;
- QHash<QString, QRect> categoriesPosition;
- QStringList categories;
- QModelIndexList intersectedIndexes;
- QRect lastDraggedItemsRect;
- int modelSortRole;
- int modelSortColumn;
- int modelLastRowCount;
- bool modelCategorized;
- Qt::SortOrder modelSortOrder;
- QItemSelection lastSelection;
-
- // Attributes for speed reasons
- KCategorizedSortFilterProxyModel *proxyModel;
- QModelIndexList modelIndexList;
-};
-
-#endif // KCATEGORIZEDVIEW_P_H
diff --git a/src/kcategorydrawer.cpp b/src/kcategorydrawer.cpp
deleted file mode 100644
index 6d82bf96b..000000000
--- a/src/kcategorydrawer.cpp
+++ /dev/null
@@ -1,118 +0,0 @@
-/**
- * This file is part of the KDE project
- * Copyright (C) 2007 Rafael Fernández López <[email protected]>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "kcategorydrawer.h"
-
-#include <QPainter>
-#include <QStyleOption>
-
-#include <kiconloader.h>
-#include <kcategorizedsortfilterproxymodel.h>
-
-KCategoryDrawer::KCategoryDrawer()
-{
-}
-
-KCategoryDrawer::~KCategoryDrawer()
-{
-}
-
-void KCategoryDrawer::drawCategory(const QModelIndex &index,
- int /*sortRole*/,
- const QStyleOption &option,
- QPainter *painter) const
-{
- const QString category = index.model()->data(index, KCategorizedSortFilterProxyModel::CategoryDisplayRole).toString();
-
- QColor color;
-
- if (option.state & QStyle::State_Selected)
- {
- color = option.palette.color(QPalette::HighlightedText);
- }
- else
- {
- color = option.palette.color(QPalette::Text);
- }
-
- painter->save();
- painter->setRenderHint(QPainter::Antialiasing);
-
- if (option.state & QStyle::State_Selected)
- {
- QColor selected = option.palette.color(QPalette::Highlight);
-
- QLinearGradient gradient(option.rect.topLeft(),
- option.rect.bottomRight());
- gradient.setColorAt(option.direction == Qt::LeftToRight ? 0
- : 1, selected);
- gradient.setColorAt(option.direction == Qt::LeftToRight ? 1
- : 0, Qt::transparent);
-
- painter->fillRect(option.rect, gradient);
- }
- else if (option.state & QStyle::State_MouseOver)
- {
- QColor hover = option.palette.color(QPalette::Highlight).light();
- hover.setAlpha(88);
-
- QLinearGradient gradient(option.rect.topLeft(),
- option.rect.bottomRight());
- gradient.setColorAt(option.direction == Qt::LeftToRight ? 0
- : 1, hover);
- gradient.setColorAt(option.direction == Qt::LeftToRight ? 1
- : 0, Qt::transparent);
-
- painter->fillRect(option.rect, gradient);
- }
-
- QFont painterFont = painter->font();
- painterFont.setWeight(QFont::Bold);
- QFontMetrics metrics(painterFont);
- painter->setFont(painterFont);
-
- QRect lineRect(option.rect.left(),
- option.rect.bottom() - 1,
- option.rect.width(),
- 1);
-
- QLinearGradient gradient(option.rect.topLeft(),
- option.rect.bottomRight());
- gradient.setColorAt(option.direction == Qt::LeftToRight ? 0
- : 1, color);
- gradient.setColorAt(option.direction == Qt::LeftToRight ? 1
- : 0, Qt::transparent);
-
- painter->fillRect(lineRect, gradient);
-
- painter->setPen(color);
-
- painter->drawText(option.rect, Qt::AlignVCenter | Qt::AlignLeft,
- metrics.elidedText(category, Qt::ElideRight, option.rect.width()));
-
- painter->restore();
-}
-
-int KCategoryDrawer::categoryHeight(const QModelIndex &index, const QStyleOption &option) const
-{
- Q_UNUSED(index);
-
- return option.fontMetrics.height() + 4 /* 3 separator; 1 gradient */;
-}
diff --git a/src/kcategorydrawer.h b/src/kcategorydrawer.h
deleted file mode 100644
index 6af0d73cd..000000000
--- a/src/kcategorydrawer.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * This file is part of the KDE project
- * Copyright (C) 2007 Rafael Fernández López <[email protected]>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef KCATEGORYDRAWER_H
-#define KCATEGORYDRAWER_H
-
-#include <libdolphin_export.h>
-
-class QPainter;
-class QModelIndex;
-class QStyleOption;
-
-class LIBDOLPHINPRIVATE_EXPORT KCategoryDrawer
-{
-public:
- KCategoryDrawer();
-
- virtual ~KCategoryDrawer();
-
- /**
- * This method purpose is to draw a category represented by the given
- * @param index with the given @param sortRole sorting role
- *
- * @note This method will be called one time per category, always with the
- * first element in that category
- */
- virtual void drawCategory(const QModelIndex &index,
- int sortRole,
- const QStyleOption &option,
- QPainter *painter) const;
-
- virtual int categoryHeight(const QModelIndex &index, const QStyleOption &option) const;
-};
-
-#endif // KCATEGORYDRAWER_H
diff --git a/src/main.cpp b/src/main.cpp
index 803f7677b..a7857272a 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -33,7 +33,7 @@ int main(int argc, char **argv)
{
KAboutData about("dolphin", 0,
ki18nc("@title", "Dolphin"),
- "1.0",
+ "1.0.1",
ki18nc("@title", "File Manager"),
KAboutData::License_GPL,
ki18nc("@info:credit", "(C) 2006, 2007 Peter Penz"));
diff --git a/src/renamedialog.cpp b/src/renamedialog.cpp
index adfc48676..fa5bf60e0 100644
--- a/src/renamedialog.cpp
+++ b/src/renamedialog.cpp
@@ -116,9 +116,9 @@ void RenameDialog::slotButtonClicked(int button)
if (m_newName.isEmpty()) {
m_errorString = i18nc("@info:status",
"The new name is empty. A name with at least one character must be entered.");
- } else if (!m_renameOneItem && m_newName.count('#') != 1) {
+ } else if (!m_renameOneItem && (m_newName.count('#') == 0)) {
m_newName.truncate(0);
- m_errorString = i18nc("@info:status", "The name must contain exactly one # character.");
+ m_errorString = i18nc("@info:status", "The name must contain at least one # character.");
}
}
diff --git a/src/viewpropertiesdialog.cpp b/src/viewpropertiesdialog.cpp
index c5d0ec510..dbef7d1f4 100644
--- a/src/viewpropertiesdialog.cpp
+++ b/src/viewpropertiesdialog.cpp
@@ -127,7 +127,7 @@ ViewPropertiesDialog::ViewPropertiesDialog(DolphinView* dolphinView) :
sortingBox->setLayout(sortingLayout);
m_showPreview = new QCheckBox(i18nc("@option:check", "Show preview"), propsBox);
- m_showInGroups = new QCheckBox(i18nc("@option:check", "Show in Groups"), propsBox);
+ m_showInGroups = new QCheckBox(i18nc("@option:check", "Show in groups"), propsBox);
m_showHiddenFiles = new QCheckBox(i18nc("@option:check", "Show hidden files"), propsBox);
m_additionalInfo = new QPushButton(i18nc("@action:button", "Additional Information"), propsBox);