]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/dolphincolumnwidget.cpp
Forwardport 773570:
[dolphin.git] / src / dolphincolumnwidget.cpp
index 92fbd4e79064595bbd26090179d9b0f4f8fab91f..c2ba385ad0b635878c18f337c153a3f2fe9fc6ab 100644 (file)
 #include "dolphincolumnview.h"
 #include "dolphincontroller.h"
 #include "dolphindirlister.h"
-#include "dolphinmodel.h"
 #include "dolphinsortfilterproxymodel.h"
 #include "dolphinsettings.h"
-
 #include "dolphin_columnmodesettings.h"
+#include "dolphin_generalsettings.h"
+#include "draganddrophelper.h"
+#include "selectionmanager.h"
 
-#include <kcolorutils.h>
 #include <kcolorscheme.h>
 #include <kdirlister.h>
 #include <kfileitem.h>
 #include <kio/previewjob.h>
 #include <kiconeffect.h>
+#include <kjob.h>
+#include <kmimetyperesolver.h>
 #include <konqmimedata.h>
 
-#include <QAbstractProxyModel>
+#include "iconmanager.h"
+
 #include <QApplication>
 #include <QClipboard>
+#include <QPainter>
 #include <QPoint>
-#include <QScrollBar>
-#include <QTimer>
-#include <QTimeLine>
 
 DolphinColumnWidget::DolphinColumnWidget(QWidget* parent,
                                          DolphinColumnView* columnView,
                                          const KUrl& url) :
     QListView(parent),
     m_active(true),
-    m_showPreview(false),
     m_view(columnView),
     m_url(url),
     m_childUrl(),
-    m_viewOptions(),
+    m_font(),
+    m_decorationSize(),
     m_dirLister(0),
     m_dolphinModel(0),
     m_proxyModel(0),
+    m_iconManager(0),
     m_dragging(false),
     m_dropRect()
 {
     setMouseTracking(true);
     viewport()->setAttribute(Qt::WA_Hover);
     setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
-    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
+    setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
     setSelectionBehavior(SelectItems);
     setSelectionMode(QAbstractItemView::ExtendedSelection);
     setDragDropMode(QAbstractItemView::DragDrop);
     setDropIndicatorShown(false);
-    setFocusPolicy(Qt::NoFocus);
+    setSelectionRectVisible(true);
 
 // TODO: Remove this check when 4.3.2 is released and KDE requires it... this
 //       check avoids a division by zero happening on versions before 4.3.1.
@@ -84,17 +86,12 @@ DolphinColumnWidget::DolphinColumnWidget(QWidget* parent,
     const ColumnModeSettings* settings = DolphinSettings::instance().columnModeSettings();
     Q_ASSERT(settings != 0);
 
-    m_viewOptions = QListView::viewOptions();
-
-    QFont font(settings->fontFamily(), settings->fontSize());
-    font.setItalic(settings->italicFont());
-    font.setBold(settings->boldFont());
-    m_viewOptions.font = font;
+    m_font = QFont(settings->fontFamily(), settings->fontSize());
+    m_font.setItalic(settings->italicFont());
+    m_font.setBold(settings->boldFont());
 
     const int iconSize = settings->iconSize();
-    m_viewOptions.decorationSize = QSize(iconSize, iconSize);
-
-    m_viewOptions.showDecorationSelected = true;
+    setDecorationSize(QSize(iconSize, iconSize));
 
     KFileItemDelegate* delegate = new KFileItemDelegate(this);
     setItemDelegate(delegate);
@@ -111,9 +108,8 @@ DolphinColumnWidget::DolphinColumnWidget(QWidget* parent,
     m_dirLister->setAutoUpdate(true);
     m_dirLister->setMainWindow(this);
     m_dirLister->setDelayedMimeTypes(true);
-    m_dirLister->setShowingDotFiles(m_view->m_controller->showHiddenFiles());
-    connect(m_dirLister, SIGNAL(newItems(const KFileItemList&)),
-            this, SLOT(generatePreviews(const KFileItemList&)));
+    const bool showHiddenFiles = m_view->m_controller->dolphinView()->showHiddenFiles();
+    m_dirLister->setShowingDotFiles(showHiddenFiles);
 
     m_dolphinModel = new DolphinModel(this);
     m_dolphinModel->setDirLister(m_dirLister);
@@ -121,21 +117,38 @@ DolphinColumnWidget::DolphinColumnWidget(QWidget* parent,
 
     m_proxyModel = new DolphinSortFilterProxyModel(this);
     m_proxyModel->setSourceModel(m_dolphinModel);
+    m_proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
 
     setModel(m_proxyModel);
+    const bool useSelManager = KGlobalSettings::singleClick() &&
+                               DolphinSettings::instance().generalSettings()->showSelectionToggle();
+    if (useSelManager) {
+        SelectionManager* selManager = new SelectionManager(this);
+        connect(selManager, SIGNAL(selectionChanged()),
+                this, SLOT(requestActivation()));
+        connect(m_view->m_controller, SIGNAL(urlChanged(const KUrl&)),
+                selManager, SLOT(reset()));
+}
+    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);
 }
 
 DolphinColumnWidget::~DolphinColumnWidget()
 {
-    delete m_dirLister;
-    m_dirLister = 0;
+    delete m_proxyModel;
+    m_proxyModel = 0;
+    delete m_dolphinModel;
+    m_dolphinModel = 0;
+    m_dirLister = 0; // deleted by m_dolphinModel
 }
 
 void DolphinColumnWidget::setDecorationSize(const QSize& size)
 {
-    m_viewOptions.decorationSize = size;
+    setIconSize(size);
+    m_decorationSize = size;
     doItemsLayout();
 }
 
@@ -171,20 +184,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(0);
-    }
+    // 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();
@@ -192,22 +209,22 @@ void DolphinColumnWidget::updateBackground()
 
 void DolphinColumnWidget::setNameFilter(const QString& nameFilter)
 {
-    // The name filter of KDirLister does a 'hard' filtering, which
-    // means that only the items are shown where the names match
-    // exactly the filter. This is non-transparent for the user, which
-    // just wants to have a 'soft' filtering: does the name contain
-    // the filter string?
-    QString adjustedFilter(nameFilter);
-    adjustedFilter.insert(0, '*');
-    adjustedFilter.append('*');
-
-    m_dirLister->setNameFilter(adjustedFilter);
-    m_dirLister->emitChanges();
+    m_proxyModel->setFilterRegExp(nameFilter);
+}
+
+
+QStyleOptionViewItem DolphinColumnWidget::viewOptions() const
+{
+    QStyleOptionViewItem viewOptions = QListView::viewOptions();
+    viewOptions.font = m_font;
+    viewOptions.decorationSize = m_decorationSize;
+    viewOptions.showDecorationSelected = true;
+    return viewOptions;
 }
 
-QString DolphinColumnWidget::nameFilter() const
+void DolphinColumnWidget::startDrag(Qt::DropActions supportedActions)
 {
-    return m_dirLister->nameFilter();
+    DragAndDropHelper::startDrag(this, supportedActions);
 }
 
 void DolphinColumnWidget::dragEnterEvent(QDragEnterEvent* event)
@@ -235,19 +252,32 @@ void DolphinColumnWidget::dragMoveEvent(QDragMoveEvent* event)
     // TODO: remove this code when the issue #160611 is solved in Qt 4.4
     const QModelIndex index = indexAt(event->pos());
     setDirtyRegion(m_dropRect);
-    m_dropRect = visualRect(index);
+
+    m_dropRect.setSize(QSize()); // set as invalid
+    if (index.isValid()) {
+        const KFileItem item = itemForIndex(index);
+        if (!item.isNull() && item.isDir()) {
+            m_dropRect = visualRect(index);
+        }
+    }
     setDirtyRegion(m_dropRect);
+
+    if (event->mimeData()->hasUrls()) {
+        // accept url drops, independently from the destination item
+        event->acceptProposedAction();
+    }
 }
 
 void DolphinColumnWidget::dropEvent(QDropEvent* event)
 {
     const KUrl::List urls = KUrl::List::fromMimeData(event->mimeData());
     if (!urls.isEmpty()) {
-        event->acceptProposedAction();
+        const QModelIndex index = indexAt(event->pos());
+        const KFileItem item = itemForIndex(index);
         m_view->m_controller->indicateDroppedUrls(urls,
                                                   url(),
-                                                  indexAt(event->pos()),
-                                                  event->source());
+                                                  item);
+        event->acceptProposedAction();
     }
     QListView::dropEvent(event);
     m_dragging = false;
@@ -278,19 +308,14 @@ void DolphinColumnWidget::paintEvent(QPaintEvent* event)
 
     // TODO: remove this code when the issue #160611 is solved in Qt 4.4
     if (m_dragging) {
-        const QBrush& brush = m_viewOptions.palette.brush(QPalette::Normal, QPalette::Highlight);
-        DolphinController::drawHoverIndication(viewport(), m_dropRect, brush);
+        const QBrush& brush = viewOptions().palette.brush(QPalette::Normal, QPalette::Highlight);
+        DragAndDropHelper::drawHoverIndication(this, m_dropRect, brush);
     }
 }
 
 void DolphinColumnWidget::mousePressEvent(QMouseEvent* event)
 {
-    m_view->m_controller->requestActivation();
-    if (!m_active) {
-        m_view->requestActivation(this);
-        m_view->m_controller->triggerUrlChangeRequest(m_url);
-    }
-
+    requestActivation();
     QListView::mousePressEvent(event);
 }
 
@@ -334,49 +359,13 @@ void DolphinColumnWidget::selectionChanged(const QItemSelection& selected, const
     selModel->select(selected, QItemSelectionModel::Select);
     selModel->select(deselected, QItemSelectionModel::Deselect);
 }
+
 void DolphinColumnWidget::triggerItem(const QModelIndex& index)
 {
-    const KFileItem item = m_dolphinModel->itemForIndex(m_proxyModel->mapToSource(index));
+    const KFileItem item = itemForIndex(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->showPreview()) {
-        KIO::PreviewJob* job = KIO::filePreview(items, 128);
-        connect(job, SIGNAL(gotPreview(const KFileItem&, const QPixmap&)),
-                this, SLOT(showPreview(const KFileItem&, const QPixmap&)));
-    }
-}
-
-void DolphinColumnWidget::showPreview(const KFileItem& item, const QPixmap& pixmap)
-{
-    // TODO: same implementation as in DolphinView; create helper class
-    // for generatePreviews(), showPreview() and isCutItem()
-
-    Q_ASSERT(!item.isNull());
-    if (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);
@@ -384,12 +373,19 @@ void DolphinColumnWidget::slotEntered(const QModelIndex& index)
     m_view->m_controller->emitItemEntered(item);
 }
 
-void DolphinColumnWidget::activate()
+void DolphinColumnWidget::requestActivation()
 {
-    if (m_view->hasFocus()) {
-        setFocus(Qt::OtherFocusReason);
+    m_view->m_controller->requestActivation();
+    if (!m_active) {
+        m_view->requestActivation(this);
+        m_view->m_controller->triggerUrlChangeRequest(m_url);
+        selectionModel()->clear();
     }
-    m_view->setFocusProxy(this);
+}
+
+void DolphinColumnWidget::activate()
+{
+    setFocus(Qt::OtherFocusReason);
 
     // TODO: Connecting to the signal 'activated()' is not possible, as kstyle
     // does not forward the single vs. doubleclick to it yet (KDE 4.1?). Hence it is
@@ -402,19 +398,16 @@ void DolphinColumnWidget::activate()
                 this, SLOT(triggerItem(const QModelIndex&)));
     }
 
-    if (!m_childUrl.isEmpty()) {
-        // assure that the current index is set on the index that represents
-        // the child URL
-        const QModelIndex dirIndex = m_dolphinModel->indexForUrl(m_childUrl);
-        const QModelIndex proxyIndex = m_proxyModel->mapFromSource(dirIndex);
-        selectionModel()->setCurrentIndex(proxyIndex, QItemSelectionModel::Current);
-    }
+    if (selectionModel() && selectionModel()->currentIndex().isValid())
+        selectionModel()->setCurrentIndex(selectionModel()->currentIndex(), QItemSelectionModel::SelectCurrent);
 
     updateBackground();
 }
 
 void DolphinColumnWidget::deactivate()
 {
+    clearFocus();
+
     // TODO: Connecting to the signal 'activated()' is not possible, as kstyle
     // does not forward the single vs. doubleclick to it yet (KDE 4.1?). Hence it is
     // necessary connecting the signal 'singleClick()' or 'doubleClick'.
@@ -426,29 +419,17 @@ 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
+KFileItem DolphinColumnWidget::itemForIndex(const QModelIndex& index) 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;
+    const QModelIndex dirIndex = m_proxyModel->mapToSource(index);
+    return m_dolphinModel->itemForIndex(dirIndex);
 }
 
+
 #include "dolphincolumnwidget.moc"