diff options
| author | Peter Penz <[email protected]> | 2010-07-24 21:45:49 +0000 |
|---|---|---|
| committer | Peter Penz <[email protected]> | 2010-07-24 21:45:49 +0000 |
| commit | 652d08c9242ed51d86dba3b2afda9d3b2e9a9cd7 (patch) | |
| tree | f65face40917d355fa74f593e04df9865f5a1552 /src/views/dolphincolumnview.cpp | |
| parent | 935cc8a03bcb6088ff520d7161db14b9b6a29044 (diff) | |
Sourcecode hierarchy cleanup: Create folder "views" and move view related sources to it
svn path=/trunk/KDE/kdebase/apps/; revision=1154146
Diffstat (limited to 'src/views/dolphincolumnview.cpp')
| -rw-r--r-- | src/views/dolphincolumnview.cpp | 466 |
1 files changed, 466 insertions, 0 deletions
diff --git a/src/views/dolphincolumnview.cpp b/src/views/dolphincolumnview.cpp new file mode 100644 index 000000000..7e2b522b4 --- /dev/null +++ b/src/views/dolphincolumnview.cpp @@ -0,0 +1,466 @@ +/*************************************************************************** + * Copyright (C) 2007-2009 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 "dolphincolumnview.h" + +#include "dolphinmodel.h" +#include "dolphincolumnviewcontainer.h" +#include "dolphinviewcontroller.h" +#include "dolphindirlister.h" +#include "dolphinsortfilterproxymodel.h" +#include "settings/dolphinsettings.h" +#include "dolphinviewautoscroller.h" +#include "dolphin_columnmodesettings.h" +#include "dolphin_generalsettings.h" +#include "draganddrophelper.h" +#include "folderexpander.h" +#include "tooltips/tooltipmanager.h" +#include "viewextensionsfactory.h" +#include "viewmodecontroller.h" +#include "zoomlevelinfo.h" + +#include <kcolorscheme.h> +#include <kdirlister.h> +#include <kfileitem.h> +#include <kio/previewjob.h> +#include <kiconeffect.h> +#include <kjob.h> +#include <konqmimedata.h> + +#include <QApplication> +#include <QClipboard> +#include <QPainter> +#include <QPoint> +#include <QScrollBar> + +DolphinColumnView::DolphinColumnView(QWidget* parent, + DolphinColumnViewContainer* container, + const KUrl& url) : + QListView(parent), + m_active(false), + m_container(container), + m_extensionsFactory(0), + m_url(url), + m_childUrl(), + m_font(), + m_decorationSize(), + m_dirLister(0), + m_dolphinModel(0), + m_proxyModel(0), + m_dropRect() +{ + setMouseTracking(true); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); + setSelectionBehavior(SelectItems); + setSelectionMode(QAbstractItemView::ExtendedSelection); + setDragDropMode(QAbstractItemView::DragDrop); + setDropIndicatorShown(false); + setSelectionRectVisible(true); + setEditTriggers(QAbstractItemView::NoEditTriggers); + + setVerticalScrollMode(QListView::ScrollPerPixel); + setHorizontalScrollMode(QListView::ScrollPerPixel); + + // apply the column mode settings to the widget + const ColumnModeSettings* settings = DolphinSettings::instance().columnModeSettings(); + Q_ASSERT(settings != 0); + + if (settings->useSystemFont()) { + m_font = KGlobalSettings::generalFont(); + } else { + m_font = QFont(settings->fontFamily(), + qRound(settings->fontSize()), + settings->fontWeight(), + settings->italicFont()); + m_font.setPointSizeF(settings->fontSize()); + } + + connect(this, SIGNAL(viewportEntered()), + m_container->m_dolphinViewController, SLOT(emitViewportEntered())); + connect(this, SIGNAL(entered(const QModelIndex&)), + this, SLOT(slotEntered(const QModelIndex&))); + + const DolphinView* dolphinView = m_container->m_dolphinViewController->view(); + connect(dolphinView, SIGNAL(showPreviewChanged()), + this, SLOT(slotShowPreviewChanged())); + + m_dirLister = new DolphinDirLister(); + m_dirLister->setAutoUpdate(true); + m_dirLister->setMainWindow(window()); + m_dirLister->setDelayedMimeTypes(true); + const bool showHiddenFiles = m_container->m_dolphinViewController->view()->showHiddenFiles(); + m_dirLister->setShowingDotFiles(showHiddenFiles); + + m_dolphinModel = new DolphinModel(this); + m_dolphinModel->setDirLister(m_dirLister); + m_dolphinModel->setDropsAllowed(DolphinModel::DropOnDirectory); + + m_proxyModel = new DolphinSortFilterProxyModel(this); + m_proxyModel->setSourceModel(m_dolphinModel); + m_proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); + + m_proxyModel->setSorting(dolphinView->sorting()); + m_proxyModel->setSortOrder(dolphinView->sortOrder()); + m_proxyModel->setSortFoldersFirst(dolphinView->sortFoldersFirst()); + + setModel(m_proxyModel); + + connect(KGlobalSettings::self(), SIGNAL(kdisplayFontChanged()), + this, SLOT(updateFont())); + + const ViewModeController* viewModeController = m_container->m_viewModeController; + connect(viewModeController, SIGNAL(zoomLevelChanged(int)), + this, SLOT(setZoomLevel(int))); + const QString nameFilter = viewModeController->nameFilter(); + if (!nameFilter.isEmpty()) { + m_proxyModel->setFilterFixedString(nameFilter); + } + + updateDecorationSize(dolphinView->showPreview()); + updateBackground(); + + DolphinViewController* dolphinViewController = m_container->m_dolphinViewController; + m_extensionsFactory = new ViewExtensionsFactory(this, dolphinViewController, viewModeController); + + m_dirLister->openUrl(url, KDirLister::NoFlags); +} + +DolphinColumnView::~DolphinColumnView() +{ + delete m_proxyModel; + m_proxyModel = 0; + delete m_dolphinModel; + m_dolphinModel = 0; + m_dirLister = 0; // deleted by m_dolphinModel +} + +void DolphinColumnView::setActive(bool active) +{ + if (m_active != active) { + m_active = active; + + if (active) { + activate(); + } else { + deactivate(); + } + } +} + +void DolphinColumnView::updateBackground() +{ + // TODO: The alpha-value 150 is copied from DolphinView::setActive(). When + // cleaning up the cut-indication of DolphinColumnView 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_container->m_active) ? 255 : 150); + + QPalette palette = viewport()->palette(); + palette.setColor(role, color); + viewport()->setPalette(palette); + + update(); +} + +KFileItem DolphinColumnView::itemAt(const QPoint& pos) const +{ + KFileItem item; + const QModelIndex index = indexAt(pos); + if (index.isValid() && (index.column() == DolphinModel::Name)) { + const QModelIndex dolphinModelIndex = m_proxyModel->mapToSource(index); + item = m_dolphinModel->itemForIndex(dolphinModelIndex); + } + return item; +} + +void DolphinColumnView::setSelectionModel(QItemSelectionModel* model) +{ + // If a change of the selection is done although the view is not active + // (e. g. by the selection markers), the column must be activated. This + // is done by listening to the current selectionChanged() signal. + if (selectionModel() != 0) { + disconnect(selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), + this, SLOT(requestActivation())); + } + + QListView::setSelectionModel(model); + + connect(selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), + this, SLOT(requestActivation())); +} + +QStyleOptionViewItem DolphinColumnView::viewOptions() const +{ + QStyleOptionViewItem viewOptions = QListView::viewOptions(); + viewOptions.font = m_font; + viewOptions.fontMetrics = QFontMetrics(m_font); + viewOptions.decorationSize = m_decorationSize; + viewOptions.showDecorationSelected = true; + return viewOptions; +} + +void DolphinColumnView::startDrag(Qt::DropActions supportedActions) +{ + DragAndDropHelper::instance().startDrag(this, supportedActions, m_container->m_dolphinViewController); +} + +void DolphinColumnView::dragEnterEvent(QDragEnterEvent* event) +{ + if (DragAndDropHelper::instance().isMimeDataSupported(event->mimeData())) { + event->acceptProposedAction(); + requestActivation(); + } +} + +void DolphinColumnView::dragLeaveEvent(QDragLeaveEvent* event) +{ + QListView::dragLeaveEvent(event); + setDirtyRegion(m_dropRect); +} + +void DolphinColumnView::dragMoveEvent(QDragMoveEvent* event) +{ + QListView::dragMoveEvent(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.setSize(QSize()); // set as invalid + if (index.isValid()) { + m_container->m_dolphinViewController->setItemView(this); + const KFileItem item = m_container->m_dolphinViewController->itemForIndex(index); + if (!item.isNull() && item.isDir()) { + m_dropRect = visualRect(index); + } + } + setDirtyRegion(m_dropRect); + + if (DragAndDropHelper::instance().isMimeDataSupported(event->mimeData())) { + // accept url drops, independently from the destination item + event->acceptProposedAction(); + } +} + +void DolphinColumnView::dropEvent(QDropEvent* event) +{ + const QModelIndex index = indexAt(event->pos()); + m_container->m_dolphinViewController->setItemView(this); + const KFileItem item = m_container->m_dolphinViewController->itemForIndex(index); + m_container->m_dolphinViewController->indicateDroppedUrls(item, url(), event); + QListView::dropEvent(event); +} + +void DolphinColumnView::paintEvent(QPaintEvent* event) +{ + if (!m_childUrl.isEmpty()) { + // indicate the shown URL of the next column by highlighting the shown folder item + const QModelIndex dirIndex = m_dolphinModel->indexForUrl(m_childUrl); + const QModelIndex proxyIndex = m_proxyModel->mapFromSource(dirIndex); + if (proxyIndex.isValid() && !selectionModel()->isSelected(proxyIndex)) { + const QRect itemRect = visualRect(proxyIndex); + QPainter painter(viewport()); + QColor color = KColorScheme(QPalette::Active, KColorScheme::View).foreground().color(); + color.setAlpha(32); + painter.setPen(Qt::NoPen); + painter.setBrush(color); + painter.drawRect(itemRect); + } + } + + QListView::paintEvent(event); +} + +void DolphinColumnView::mousePressEvent(QMouseEvent* event) +{ + requestActivation(); + if (!indexAt(event->pos()).isValid()) { + if (QApplication::mouseButtons() & Qt::MidButton) { + m_container->m_dolphinViewController->replaceUrlByClipboard(); + } + } else if (event->button() == Qt::LeftButton) { + // TODO: see comment in DolphinIconsView::mousePressEvent() + setState(QAbstractItemView::DraggingState); + } + QListView::mousePressEvent(event); +} + +void DolphinColumnView::keyPressEvent(QKeyEvent* event) +{ + QListView::keyPressEvent(event); + + DolphinViewController* controller = m_container->m_dolphinViewController; + controller->handleKeyPressEvent(event); + switch (event->key()) { + case Qt::Key_Right: { + // Special key handling for the column: A Key_Right should + // open a new column for the currently selected folder. + const QModelIndex index = currentIndex(); + const KFileItem item = controller->itemForIndex(index); + if (!item.isNull() && item.isDir()) { + controller->emitItemTriggered(item); + } + break; + } + + case Qt::Key_Escape: + selectionModel()->setCurrentIndex(selectionModel()->currentIndex(), + QItemSelectionModel::Current | + QItemSelectionModel::Clear); + break; + + default: + break; + } +} + +void DolphinColumnView::contextMenuEvent(QContextMenuEvent* event) +{ + requestActivation(); + QListView::contextMenuEvent(event); + m_container->m_dolphinViewController->triggerContextMenuRequest(event->pos()); +} + +void DolphinColumnView::wheelEvent(QWheelEvent* event) +{ + const int step = m_decorationSize.height(); + verticalScrollBar()->setSingleStep(step); + QListView::wheelEvent(event); +} + +void DolphinColumnView::leaveEvent(QEvent* event) +{ + QListView::leaveEvent(event); + // if the mouse is above an item and moved very fast outside the widget, + // no viewportEntered() signal might be emitted although the mouse has been moved + // above the viewport + m_container->m_dolphinViewController->emitViewportEntered(); +} + +void DolphinColumnView::currentChanged(const QModelIndex& current, const QModelIndex& previous) +{ + QListView::currentChanged(current, previous); + m_extensionsFactory->handleCurrentIndexChange(current, previous); +} + +void DolphinColumnView::setZoomLevel(int level) +{ + const int size = ZoomLevelInfo::iconSizeForZoomLevel(level); + ColumnModeSettings* settings = DolphinSettings::instance().columnModeSettings(); + + const bool showPreview = m_container->m_dolphinViewController->view()->showPreview(); + if (showPreview) { + settings->setPreviewSize(size); + } else { + settings->setIconSize(size); + } + + updateDecorationSize(showPreview); +} + +void DolphinColumnView::slotEntered(const QModelIndex& index) +{ + m_container->m_dolphinViewController->setItemView(this); + m_container->m_dolphinViewController->emitItemEntered(index); +} + +void DolphinColumnView::requestActivation() +{ + m_container->m_dolphinViewController->requestActivation(); + if (!m_active) { + m_container->requestActivation(this); + selectionModel()->clear(); + } +} + +void DolphinColumnView::updateFont() +{ + const ColumnModeSettings* settings = DolphinSettings::instance().columnModeSettings(); + Q_ASSERT(settings != 0); + + if (settings->useSystemFont()) { + m_font = KGlobalSettings::generalFont(); + } +} + +void DolphinColumnView::slotShowPreviewChanged() +{ + const DolphinView* view = m_container->m_dolphinViewController->view(); + updateDecorationSize(view->showPreview()); +} + +void DolphinColumnView::activate() +{ + setFocus(Qt::OtherFocusReason); + + if (KGlobalSettings::singleClick()) { + connect(this, SIGNAL(clicked(const QModelIndex&)), + m_container->m_dolphinViewController, SLOT(triggerItem(const QModelIndex&))); + } else { + connect(this, SIGNAL(doubleClicked(const QModelIndex&)), + m_container->m_dolphinViewController, SLOT(triggerItem(const QModelIndex&))); + } + + if (selectionModel() && selectionModel()->currentIndex().isValid()) { + selectionModel()->setCurrentIndex(selectionModel()->currentIndex(), QItemSelectionModel::SelectCurrent); + } + + updateBackground(); +} + +void DolphinColumnView::deactivate() +{ + clearFocus(); + if (KGlobalSettings::singleClick()) { + disconnect(this, SIGNAL(clicked(const QModelIndex&)), + m_container->m_dolphinViewController, SLOT(triggerItem(const QModelIndex&))); + } else { + disconnect(this, SIGNAL(doubleClicked(const QModelIndex&)), + m_container->m_dolphinViewController, SLOT(triggerItem(const QModelIndex&))); + } + + // It is important to disconnect the connection to requestActivation() temporary, otherwise the internal + // clearing of the selection would result in activating the column again. + disconnect(selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), + this, SLOT(requestActivation())); + const QModelIndex current = selectionModel()->currentIndex(); + selectionModel()->clear(); + selectionModel()->setCurrentIndex(current, QItemSelectionModel::NoUpdate); + connect(selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), + this, SLOT(requestActivation())); + + updateBackground(); +} + +void DolphinColumnView::updateDecorationSize(bool showPreview) +{ + ColumnModeSettings* settings = DolphinSettings::instance().columnModeSettings(); + const int iconSize = showPreview ? settings->previewSize() : settings->iconSize(); + const QSize size(iconSize, iconSize); + setIconSize(size); + + m_decorationSize = size; + + doItemsLayout(); +} + +#include "dolphincolumnview.moc" |
