X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/41c14c5f8ebc00ba443f13d300f5b445aee7aa1b..ab39a5952001cdb3d1b9ca693da7f8e246558fb8:/src/dolphinview.cpp diff --git a/src/dolphinview.cpp b/src/dolphinview.cpp index e9b33e9a1..e057c950a 100644 --- a/src/dolphinview.cpp +++ b/src/dolphinview.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2006 by Peter Penz * + * Copyright (C) 2006-2009 by Peter Penz * * Copyright (C) 2006 by Gregor Kališnik * * * * This program is free software; you can redistribute it and/or modify * @@ -20,6 +20,7 @@ #include "dolphinview.h" +#include #include #include #include @@ -31,7 +32,6 @@ #include #include #include -#include #include #include #include @@ -60,13 +60,11 @@ #include "dolphiniconsview.h" #include "dolphin_generalsettings.h" #include "draganddrophelper.h" -#include "folderexpander.h" #include "renamedialog.h" -#include "tooltips/tooltipmanager.h" #include "settings/dolphinsettings.h" -#include "versioncontrolobserver.h" #include "viewproperties.h" #include "zoomlevelinfo.h" +#include "dolphindetailsviewexpander.h" /** * Helper function for sorting items with qSort() in @@ -92,19 +90,15 @@ DolphinView::DolphinView(QWidget* parent, m_mode(DolphinView::IconsView), m_topLayout(0), m_controller(0), - m_fileItemDelegate(0), m_viewAccessor(proxyModel), m_selectionModel(0), m_selectionChangedTimer(0), - m_previewGenerator(0), - m_toolTipManager(0), - m_versionControlObserver(0), m_rootUrl(), m_activeItemUrl(), + m_restoredContentsPosition(), m_createdItemUrl(), m_selectedItems(), - m_newFileNames(), - m_expandedDragSource(0) + m_newFileNames() { m_topLayout = new QVBoxLayout(this); m_topLayout->setSpacing(0); @@ -142,8 +136,8 @@ DolphinView::DolphinView(QWidget* parent, this, SLOT(clearHoverInformation())); KDirLister* dirLister = m_viewAccessor.dirLister(); - connect(dirLister, SIGNAL(redirection(KUrl, KUrl)), - this, SIGNAL(redirection(KUrl, KUrl))); + connect(dirLister, SIGNAL(redirection(KUrl,KUrl)), + this, SLOT(slotRedirection(KUrl,KUrl))); connect(dirLister, SIGNAL(completed()), this, SLOT(slotDirListerCompleted())); connect(dirLister, SIGNAL(refreshItems(const QList>&)), @@ -155,14 +149,18 @@ DolphinView::DolphinView(QWidget* parent, connect(&DolphinNewMenuObserver::instance(), SIGNAL(itemCreated(const KUrl&)), this, SLOT(observeCreatedItem(const KUrl&))); + m_selectionChangedTimer = new QTimer(this); + m_selectionChangedTimer->setSingleShot(true); + m_selectionChangedTimer->setInterval(300); + connect(m_selectionChangedTimer, SIGNAL(timeout()), + this, SLOT(emitSelectionChangedSignal())); + applyViewProperties(); m_topLayout->addWidget(m_viewAccessor.itemView()); } DolphinView::~DolphinView() { - delete m_expandedDragSource; - m_expandedDragSource = 0; } const KUrl& DolphinView::url() const @@ -234,7 +232,7 @@ void DolphinView::setMode(Mode mode) // the file item delegate has been recreated, apply the current // additional information manually const KFileItemDelegate::InformationList infoList = props.additionalInfo(); - m_fileItemDelegate->setShowInformation(infoList); + m_viewAccessor.itemDelegate()->setShowInformation(infoList); emit additionalInfoChanged(); // Not all view modes support categorized sorting. Adjust the sorting model @@ -287,42 +285,10 @@ bool DolphinView::supportsCategorizedSorting() const return m_viewAccessor.supportsCategorizedSorting(); } -void DolphinView::selectAll() -{ - QAbstractItemView* view = m_viewAccessor.itemView(); - // TODO: there seems to be a bug in QAbstractItemView::selectAll(); if - // the Ctrl-key is pressed (e. g. for Ctrl+A), selectAll() inverts the - // selection instead of selecting all items. This is bypassed for KDE 4.0 - // by invoking clearSelection() first. - view->clearSelection(); - view->selectAll(); -} - -void DolphinView::invertSelection() -{ - QItemSelectionModel* selectionModel = m_viewAccessor.itemView()->selectionModel(); - const QAbstractItemModel* itemModel = selectionModel->model(); - - const QModelIndex topLeft = itemModel->index(0, 0); - const QModelIndex bottomRight = itemModel->index(itemModel->rowCount() - 1, - itemModel->columnCount() - 1); - - const QItemSelection selection(topLeft, bottomRight); - selectionModel->select(selection, QItemSelectionModel::Toggle); -} - bool DolphinView::hasSelection() const { - return m_viewAccessor.itemView()->selectionModel()->hasSelection(); -} - -void DolphinView::clearSelection() -{ - QItemSelectionModel* selModel = m_viewAccessor.itemView()->selectionModel(); - const QModelIndex currentIndex = selModel->currentIndex(); - selModel->setCurrentIndex(currentIndex, QItemSelectionModel::Current | - QItemSelectionModel::Clear); - m_selectedItems.clear(); + const QAbstractItemView* view = m_viewAccessor.itemView(); + return view && view->selectionModel()->hasSelection(); } KFileItemList DolphinView::selectedItems() const @@ -362,19 +328,37 @@ int DolphinView::selectedItemsCount() const return m_viewAccessor.itemView()->selectionModel()->selectedIndexes().count(); } +QItemSelectionModel* DolphinView::selectionModel() const +{ + return m_viewAccessor.itemView()->selectionModel(); +} + void DolphinView::setContentsPosition(int x, int y) { QAbstractItemView* view = m_viewAccessor.itemView(); + Q_ASSERT(view != 0); view->horizontalScrollBar()->setValue(x); view->verticalScrollBar()->setValue(y); m_loadingDirectory = false; } +void DolphinView::setRestoredContentsPosition(const QPoint& pos) +{ + // TODO: This function is called by DolphinViewContainer. + // If it makes use of DolphinView::restoreState(...) to restore the + // view state in KDE 4.5, this function can be removed. + m_restoredContentsPosition = pos; +} + QPoint DolphinView::contentsPosition() const { - const int x = m_viewAccessor.itemView()->horizontalScrollBar()->value(); - const int y = m_viewAccessor.itemView()->verticalScrollBar()->value(); + // TODO: If DolphinViewContainer uses DolphinView::saveState(...) to save the + // view state in KDE 4.5, this code can be moved to DolphinView::saveState. + QAbstractItemView* view = m_viewAccessor.itemView(); + Q_ASSERT(view != 0); + const int x = view->horizontalScrollBar()->value(); + const int y = view->verticalScrollBar()->value(); return QPoint(x, y); } @@ -388,7 +372,6 @@ void DolphinView::setZoomLevel(int level) if (level != zoomLevel()) { m_controller->setZoomLevel(level); - m_previewGenerator->updateIcons(); emit zoomLevelChanged(level); } } @@ -439,7 +422,7 @@ void DolphinView::setAdditionalInfo(KFileItemDelegate::InformationList info) const KUrl viewPropsUrl = rootUrl(); ViewProperties props(viewPropsUrl); props.setAdditionalInfo(info); - m_fileItemDelegate->setShowInformation(info); + m_viewAccessor.itemDelegate()->setShowInformation(info); emit additionalInfoChanged(); @@ -450,7 +433,7 @@ void DolphinView::setAdditionalInfo(KFileItemDelegate::InformationList info) KFileItemDelegate::InformationList DolphinView::additionalInfo() const { - return m_fileItemDelegate->showInformation(); + return m_viewAccessor.itemDelegate()->showInformation(); } void DolphinView::reload() @@ -483,11 +466,8 @@ void DolphinView::updateView(const KUrl& url, const KUrl& rootUrl) return; } - m_previewGenerator->cancelPreviews(); m_controller->setUrl(url); // emits urlChanged, which we forward - if (m_viewAccessor.prepareUrlChange(url)) { - initializeView(); - } + m_viewAccessor.prepareUrlChange(url); applyViewProperties(); loadDirectory(url); @@ -500,7 +480,7 @@ void DolphinView::updateView(const KUrl& url, const KUrl& rootUrl) void DolphinView::setNameFilter(const QString& nameFilter) { - m_viewAccessor.setNameFilter(nameFilter); + m_controller->setNameFilter(nameFilter); } void DolphinView::calculateItemCount(int& fileCount, @@ -578,9 +558,7 @@ QString DolphinView::statusBarText() const QList DolphinView::versionControlActions(const KFileItemList& items) const { - return items.isEmpty() - ? m_versionControlObserver->contextMenuActions(url().path(KUrl::AddTrailingSlash)) - : m_versionControlObserver->contextMenuActions(items); + return m_controller->versionControlActions(items); } void DolphinView::setUrl(const KUrl& url) @@ -589,6 +567,39 @@ void DolphinView::setUrl(const KUrl& url) updateView(url, KUrl()); } +void DolphinView::selectAll() +{ + QAbstractItemView* view = m_viewAccessor.itemView(); + // TODO: there seems to be a bug in QAbstractItemView::selectAll(); if + // the Ctrl-key is pressed (e. g. for Ctrl+A), selectAll() inverts the + // selection instead of selecting all items. This is bypassed for KDE 4.0 + // by invoking clearSelection() first. + view->clearSelection(); + view->selectAll(); +} + +void DolphinView::invertSelection() +{ + QItemSelectionModel* selectionModel = m_viewAccessor.itemView()->selectionModel(); + const QAbstractItemModel* itemModel = selectionModel->model(); + + const QModelIndex topLeft = itemModel->index(0, 0); + const QModelIndex bottomRight = itemModel->index(itemModel->rowCount() - 1, + itemModel->columnCount() - 1); + + const QItemSelection selection(topLeft, bottomRight); + selectionModel->select(selection, QItemSelectionModel::Toggle); +} + +void DolphinView::clearSelection() +{ + QItemSelectionModel* selModel = m_viewAccessor.itemView()->selectionModel(); + const QModelIndex currentIndex = selModel->currentIndex(); + selModel->setCurrentIndex(currentIndex, QItemSelectionModel::Current | + QItemSelectionModel::Clear); + m_selectedItems.clear(); +} + void DolphinView::changeSelection(const KFileItemList& selection) { clearSelection(); @@ -634,7 +645,7 @@ void DolphinView::renameSelectedItems() return; } delete dialog; - + // the selection would be invalid after renaming the items, so just clear // it before clearSelection(); @@ -754,8 +765,6 @@ void DolphinView::setShowPreview(bool show) props.setShowPreview(show); m_showPreview = show; - m_previewGenerator->setPreviewShown(show); - const int oldZoomLevel = m_controller->zoomLevel(); emit showPreviewChanged(); @@ -763,8 +772,6 @@ void DolphinView::setShowPreview(bool show) // As the view does not emit a signal when the icon size has been changed, // the used zoom level of the controller must be adjusted manually: updateZoomLevel(oldZoomLevel); - - loadDirectory(viewPropsUrl); } void DolphinView::setShowHiddenFiles(bool show) @@ -779,8 +786,6 @@ void DolphinView::setShowHiddenFiles(bool show) m_viewAccessor.dirLister()->setShowingDotFiles(show); emit showHiddenFilesChanged(); - - loadDirectory(viewPropsUrl); } void DolphinView::setCategorizedSorting(bool categorized) @@ -843,20 +848,6 @@ void DolphinView::mouseReleaseEvent(QMouseEvent* event) setActive(true); } -void DolphinView::wheelEvent(QWheelEvent* event) -{ - if (event->modifiers() & Qt::ControlModifier) { - const int delta = event->delta(); - const int level = zoomLevel(); - if (delta > 0) { - setZoomLevel(level + 1); - } else if (delta < 0) { - setZoomLevel(level - 1); - } - event->accept(); - } -} - bool DolphinView::eventFilter(QObject* watched, QEvent* event) { switch (event->type()) { @@ -866,18 +857,6 @@ bool DolphinView::eventFilter(QObject* watched, QEvent* event) } break; - case QEvent::MouseButtonPress: - if ((watched == m_viewAccessor.itemView()->viewport()) && (m_expandedDragSource != 0)) { - // Listening to a mousebutton press event to delete expanded views is a - // workaround, as it seems impossible for the FolderExpander to know when - // a dragging outside a view has been finished. However it works quite well: - // A mousebutton press event indicates that a drag operation must be - // finished already. - m_expandedDragSource->deleteLater(); - m_expandedDragSource = 0; - } - break; - case QEvent::DragEnter: if (watched == m_viewAccessor.itemView()->viewport()) { setActive(true); @@ -886,10 +865,6 @@ bool DolphinView::eventFilter(QObject* watched, QEvent* event) case QEvent::KeyPress: if (watched == m_viewAccessor.itemView()) { - if (m_toolTipManager != 0) { - m_toolTipManager->hideTip(); - } - // clear the selection when Escape has been pressed QKeyEvent* keyEvent = static_cast(event); if (keyEvent->key() == Qt::Key_Escape) { @@ -898,6 +873,24 @@ bool DolphinView::eventFilter(QObject* watched, QEvent* event) } break; + case QEvent::Wheel: + if (watched == m_viewAccessor.itemView()->viewport()) { + // Ctrl+wheel events should cause icon zooming, but not if the left mouse button is pressed + // (the user is probably trying to scroll during a selection in that case) + QWheelEvent* wheelEvent = static_cast(event); + if (wheelEvent->modifiers() & Qt::ControlModifier && !(wheelEvent->buttons() & Qt::LeftButton)) { + const int delta = wheelEvent->delta(); + const int level = zoomLevel(); + if (delta > 0) { + setZoomLevel(level + 1); + } else if (delta < 0) { + setZoomLevel(level - 1); + } + return true; + } + } + break; + default: break; } @@ -924,9 +917,6 @@ void DolphinView::triggerItem(const KFileItem& item) return; } - if (m_toolTipManager != 0) { - m_toolTipManager->hideTip(); - } emit itemTriggered(item); // caught by DolphinViewContainer or DolphinPart } @@ -953,10 +943,6 @@ void DolphinView::openContextMenu(const QPoint& pos, item = m_viewAccessor.dirModel()->itemForIndex(dolphinModelIndex); } - if (m_toolTipManager != 0) { - m_toolTipManager->hideTip(); - } - m_isContextMenuOpen = true; // TODO: workaround for Qt-issue 207192 emit requestContextMenu(item, url(), customActions); m_isContextMenuOpen = false; @@ -1006,7 +992,7 @@ void DolphinView::updateAdditionalInfo(const KFileItemDelegate::InformationList& props.setAdditionalInfo(info); props.save(); - m_fileItemDelegate->setShowInformation(info); + m_viewAccessor.itemDelegate()->setShowInformation(info); emit additionalInfoChanged(); } @@ -1037,7 +1023,7 @@ void DolphinView::updateAdditionalInfoActions(KActionCollection* collection) showGroupInfo->setEnabled(enable); showMimeInfo->setEnabled(enable); - foreach (KFileItemDelegate::Information info, m_fileItemDelegate->showInformation()) { + foreach (KFileItemDelegate::Information info, m_viewAccessor.itemDelegate()->showInformation()) { switch (info) { case KFileItemDelegate::Size: showSizeInfo->setChecked(true); @@ -1080,6 +1066,8 @@ bool DolphinView::isTabsForFilesEnabled() const void DolphinView::activateItem(const KUrl& url) { + // TODO: If DolphinViewContainer uses DolphinView::restoreState(...) to restore the + // view state in KDE 4.5, this function can be removed. m_activeItemUrl = url; } @@ -1088,24 +1076,51 @@ bool DolphinView::itemsExpandable() const return m_viewAccessor.itemsExpandable(); } -void DolphinView::deleteWhenNotDragSource(QAbstractItemView *view) +void DolphinView::restoreState(QDataStream &stream) { - if (view == 0) - return; + // current item + stream >> m_activeItemUrl; - if (DragAndDropHelper::instance().isDragSource(view)) { - // We must store for later deletion. - if (m_expandedDragSource != 0) { - // The old stored view is obviously not the drag source anymore. - m_expandedDragSource->deleteLater(); - m_expandedDragSource = 0; - } - view->hide(); - m_expandedDragSource = view; + // view position + stream >> m_restoredContentsPosition; + + // expanded folders (only relevant for the details view - will be ignored by the view in other view modes) + QSet urlsToExpand; + stream >> urlsToExpand; + const DolphinDetailsViewExpander* expander = m_viewAccessor.setExpandedUrls(urlsToExpand); + + if (expander) { + m_expanderActive = true; + connect (expander, SIGNAL(completed()), this, SLOT(slotLoadingCompleted())); } else { - view->deleteLater(); + m_expanderActive = false; + } +} + +void DolphinView::saveState(QDataStream &stream) +{ + // current item + KFileItem currentItem; + const QAbstractItemView* view = m_viewAccessor.itemView(); + + if(view) { + const QModelIndex proxyIndex = view->currentIndex(); + const QModelIndex dirModelIndex = m_viewAccessor.proxyModel()->mapToSource(proxyIndex); + currentItem = m_viewAccessor.dirModel()->itemForIndex(dirModelIndex); } + + KUrl currentUrl; + if (!currentItem.isNull()) + currentUrl = currentItem.url(); + + stream << currentUrl; + + // view position + stream << contentsPosition(); + + // expanded folders (only relevant for the details view - the set will be empty in other view modes) + stream << m_viewAccessor.expandedUrls(); } void DolphinView::observeCreatedItem(const KUrl& url) @@ -1136,6 +1151,11 @@ void DolphinView::restoreSelection() void DolphinView::emitContentsMoved() { + // TODO: If DolphinViewContainer uses DolphinView::saveState(...) to save the + // view state in KDE 4.5, the contentsMoved signal might not be needed anymore, + // depending on how the implementation is done. + // In that case, the code in contentsPosition() can be moved to saveState(). + // only emit the contents moved signal if no directory loading is ongoing // (this would reset the contents position always to (0, 0)) if (!m_loadingDirectory) { @@ -1171,19 +1191,8 @@ void DolphinView::slotRequestUrlChange(const KUrl& url) void DolphinView::slotDirListerCompleted() { - if (!m_activeItemUrl.isEmpty()) { - // assure that the current item remains visible - const QModelIndex dirIndex = m_viewAccessor.dirModel()->indexForUrl(m_activeItemUrl); - if (dirIndex.isValid()) { - const QModelIndex proxyIndex = m_viewAccessor.proxyModel()->mapFromSource(dirIndex); - QAbstractItemView* view = m_viewAccessor.itemView(); - const bool clearSelection = !hasSelection(); - view->setCurrentIndex(proxyIndex); - if (clearSelection) { - view->clearSelection(); - } - m_activeItemUrl.clear(); - } + if (!m_expanderActive) { + slotLoadingCompleted(); } if (!m_newFileNames.isEmpty()) { @@ -1205,6 +1214,31 @@ void DolphinView::slotDirListerCompleted() } } +void DolphinView::slotLoadingCompleted() +{ + m_expanderActive = false; + m_loadingDirectory = false; + + if (!m_activeItemUrl.isEmpty()) { + // assure that the current item remains visible + const QModelIndex dirIndex = m_viewAccessor.dirModel()->indexForUrl(m_activeItemUrl); + if (dirIndex.isValid()) { + const QModelIndex proxyIndex = m_viewAccessor.proxyModel()->mapFromSource(dirIndex); + QAbstractItemView* view = m_viewAccessor.itemView(); + const bool clearSelection = !hasSelection(); + view->setCurrentIndex(proxyIndex); + if (clearSelection) { + view->clearSelection(); + } + m_activeItemUrl.clear(); + } + } + + // Restore the contents position. This has to be done using a Qt::QueuedConnection + // because the view might not be in its final state yet. + QMetaObject::invokeMethod(this, "restoreContentsPosition", Qt::QueuedConnection); +} + void DolphinView::slotRefreshItems() { if (m_assureVisibleCurrentIndex) { @@ -1226,13 +1260,13 @@ void DolphinView::loadDirectory(const KUrl& url, bool reload) } m_loadingDirectory = true; + m_expanderActive = false; if (reload) { m_selectedItems = selectedItems(); connect(m_viewAccessor.dirLister(), SIGNAL(completed()), this, SLOT(restoreSelection())); } - m_viewAccessor.dirLister()->stop(); m_viewAccessor.dirLister()->openUrl(url, reload ? KDirLister::Reload : KDirLister::NoFlags); } @@ -1258,7 +1292,7 @@ void DolphinView::applyViewProperties() createView(); } Q_ASSERT(m_viewAccessor.itemView() != 0); - Q_ASSERT(m_fileItemDelegate != 0); + Q_ASSERT(m_viewAccessor.itemDelegate() != 0); const bool showHiddenFiles = props.showHiddenFiles(); if (showHiddenFiles != m_viewAccessor.dirLister()->showingDotFiles()) { @@ -1292,16 +1326,14 @@ void DolphinView::applyViewProperties() } KFileItemDelegate::InformationList info = props.additionalInfo(); - if (info != m_fileItemDelegate->showInformation()) { - m_fileItemDelegate->setShowInformation(info); + if (info != m_viewAccessor.itemDelegate()->showInformation()) { + m_viewAccessor.itemDelegate()->setShowInformation(info); emit additionalInfoChanged(); } const bool showPreview = props.showPreview(); if (showPreview != m_showPreview) { m_showPreview = showPreview; - m_previewGenerator->setPreviewShown(showPreview); - const int oldZoomLevel = m_controller->zoomLevel(); emit showPreviewChanged(); @@ -1322,9 +1354,35 @@ void DolphinView::applyViewProperties() void DolphinView::createView() { deleteView(); + Q_ASSERT(m_viewAccessor.itemView() == 0); m_viewAccessor.createView(this, m_controller, m_mode); - initializeView(); + + QAbstractItemView* view = m_viewAccessor.itemView(); + Q_ASSERT(view != 0); + view->installEventFilter(this); + view->viewport()->installEventFilter(this); + + m_controller->setItemView(view); + connect(m_controller, SIGNAL(selectionChanged()), + this, SLOT(emitDelayedSelectionChangedSignal())); + + // When changing the view mode, the selection is lost due to reinstantiating + // a new item view with a custom selection model. Pass the ownership of the + // selection model to DolphinView, so that it can be shared by all item views. + if (m_selectionModel != 0) { + view->setSelectionModel(m_selectionModel); + } else { + m_selectionModel = view->selectionModel(); + } + m_selectionModel->setParent(this); + + connect(view->verticalScrollBar(), SIGNAL(valueChanged(int)), + this, SLOT(emitContentsMoved())); + connect(view->horizontalScrollBar(), SIGNAL(valueChanged(int)), + this, SLOT(emitContentsMoved())); + + setFocusProxy(m_viewAccessor.layoutTarget()); m_topLayout->insertWidget(1, m_viewAccessor.layoutTarget()); } @@ -1342,99 +1400,17 @@ void DolphinView::deleteView() m_topLayout->removeWidget(view); view->close(); - // m_previewGenerator's parent is not always destroyed, and we - // don't want two active at once - manually delete. - delete m_previewGenerator; - m_previewGenerator = 0; - + // disconnect all signal/slots disconnect(view); m_controller->disconnect(view); view->disconnect(); - - // TODO: move this code into ViewAccessor::deleteView() - deleteWhenNotDragSource(view); - view = 0; + disconnect(view->verticalScrollBar(), SIGNAL(valueChanged(int)), + this, SLOT(emitContentsMoved())); + disconnect(view->horizontalScrollBar(), SIGNAL(valueChanged(int)), + this, SLOT(emitContentsMoved())); m_viewAccessor.deleteView(); - m_fileItemDelegate = 0; - m_toolTipManager = 0; - } -} - -void DolphinView::initializeView() -{ - QAbstractItemView* view = m_viewAccessor.itemView(); - Q_ASSERT(view != 0); - view->installEventFilter(this); - view->viewport()->installEventFilter(this); - setFocusProxy(view); - - //if (m_mode != ColumnView) { - // Give the view the ability to auto-expand its directories on hovering - // (the column view takes care about this itself). If the details view - // uses expandable folders, the auto-expanding should be used always. - FolderExpander* folderExpander = new FolderExpander(view, m_viewAccessor.proxyModel()); - folderExpander->setEnabled(m_viewAccessor.hasExpandableFolders()); - connect(folderExpander, SIGNAL(enterDir(const QModelIndex&)), - m_controller, SLOT(triggerItem(const QModelIndex&))); - - // TODO: enable again later - /*} - else { - // Listen out for requests to delete the current column. - connect(m_viewAccessor.columnsContainer(), SIGNAL(requestColumnDeletion(QAbstractItemView*)), - this, SLOT(deleteWhenNotDragSource(QAbstractItemView*))); - }*/ - - m_controller->setItemView(view); - - m_fileItemDelegate = new DolphinFileItemDelegate(view); - m_fileItemDelegate->setShowToolTipWhenElided(false); - m_fileItemDelegate->setMinimizedNameColumn(m_mode == DetailsView); - view->setItemDelegate(m_fileItemDelegate); - - view->setModel(m_viewAccessor.proxyModel()); - if (m_selectionModel != 0) { - view->setSelectionModel(m_selectionModel); - } else { - m_selectionModel = view->selectionModel(); - } - - m_selectionChangedTimer = new QTimer(this); - m_selectionChangedTimer->setSingleShot(true); - m_selectionChangedTimer->setInterval(300); - connect(m_selectionChangedTimer, SIGNAL(timeout()), - this, SLOT(emitSelectionChangedSignal())); - - // reparent the selection model, as it should not be deleted - // when deleting the model - m_selectionModel->setParent(this); - - view->setSelectionMode(QAbstractItemView::ExtendedSelection); - - m_previewGenerator = new KFilePreviewGenerator(view); - m_previewGenerator->setPreviewShown(m_showPreview); - - m_versionControlObserver = new VersionControlObserver(view); - connect(m_versionControlObserver, SIGNAL(infoMessage(const QString&)), - this, SIGNAL(infoMessage(const QString&))); - connect(m_versionControlObserver, SIGNAL(errorMessage(const QString&)), - this, SIGNAL(errorMessage(const QString&))); - connect(m_versionControlObserver, SIGNAL(operationCompletedMessage(const QString&)), - this, SIGNAL(operationCompletedMessage(const QString&))); - - if (DolphinSettings::instance().generalSettings()->showToolTips()) { - m_toolTipManager = new ToolTipManager(view, m_viewAccessor.proxyModel()); - connect(m_controller, SIGNAL(hideToolTip()), - m_toolTipManager, SLOT(hideTip())); } - - connect(view->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), - this, SLOT(emitDelayedSelectionChangedSignal())); - connect(view->verticalScrollBar(), SIGNAL(valueChanged(int)), - this, SLOT(emitContentsMoved())); - connect(view->horizontalScrollBar(), SIGNAL(valueChanged(int)), - this, SLOT(emitContentsMoved())); } void DolphinView::pasteToUrl(const KUrl& url) @@ -1481,8 +1457,15 @@ DolphinView::ViewAccessor::ViewAccessor(DolphinSortFilterProxyModel* proxyModel) m_iconsView(0), m_detailsView(0), m_columnsContainer(0), - m_proxyModel(proxyModel) + m_proxyModel(proxyModel), + m_dragSource(0) +{ +} + +DolphinView::ViewAccessor::~ViewAccessor() { + delete m_dragSource; + m_dragSource = 0; } void DolphinView::ViewAccessor::createView(QWidget* parent, @@ -1493,11 +1476,11 @@ void DolphinView::ViewAccessor::createView(QWidget* parent, switch (mode) { case IconsView: - m_iconsView = new DolphinIconsView(parent, controller); + m_iconsView = new DolphinIconsView(parent, controller, m_proxyModel); break; case DetailsView: - m_detailsView = new DolphinDetailsView(parent, controller); + m_detailsView = new DolphinDetailsView(parent, controller, m_proxyModel); break; case ColumnView: @@ -1511,23 +1494,45 @@ void DolphinView::ViewAccessor::createView(QWidget* parent, void DolphinView::ViewAccessor::deleteView() { - // TODO: Move the deleteWhenNotDragSource() code into the view - // accessor, so that creating and deleting is fully done by - // the view accessor. + QAbstractItemView* view = itemView(); + if (view != 0) { + if (DragAndDropHelper::instance().isDragSource(view)) { + // The view is a drag source (the feature "Open folders + // during drag operations" is used). Deleting the view + // during an ongoing drag operation is not allowed, so + // this will postponed. + if (m_dragSource != 0) { + // the old stored view is obviously not the drag source anymore + m_dragSource->deleteLater(); + m_dragSource = 0; + } + view->hide(); + m_dragSource = view; + } else { + view->deleteLater(); + } + } + m_iconsView = 0; m_detailsView = 0; - m_columnsContainer->deleteLater(); + if (m_columnsContainer != 0) { + m_columnsContainer->deleteLater(); + } m_columnsContainer = 0; } -bool DolphinView::ViewAccessor::prepareUrlChange(const KUrl& url) +void DolphinView::ViewAccessor::prepareUrlChange(const KUrl& url) { if (m_columnsContainer != 0) { - return m_columnsContainer->showColumn(url); + m_columnsContainer->showColumn(url); + } + + if(!m_detailsViewExpander.isNull()) { + // Stop expanding items in the current folder + m_detailsViewExpander->stop(); } - return false; } QAbstractItemView* DolphinView::ViewAccessor::itemView() const @@ -1547,6 +1552,11 @@ QAbstractItemView* DolphinView::ViewAccessor::itemView() const return 0; } +KFileItemDelegate* DolphinView::ViewAccessor::itemDelegate() const +{ + return static_cast(itemView()->itemDelegate()); +} + QWidget* DolphinView::ViewAccessor::layoutTarget() const { if (m_columnsContainer != 0) { @@ -1555,15 +1565,6 @@ QWidget* DolphinView::ViewAccessor::layoutTarget() const return itemView(); } -void DolphinView::ViewAccessor::setNameFilter(const QString& nameFilter) -{ - if (m_columnsContainer == 0) { - m_columnsContainer->setNameFilter(nameFilter); - } else { - proxyModel()->setFilterRegExp(nameFilter); - } -} - KUrl DolphinView::ViewAccessor::rootUrl() const { return (m_columnsContainer != 0) ? m_columnsContainer->rootUrl() : KUrl(); @@ -1574,16 +1575,31 @@ bool DolphinView::ViewAccessor::supportsCategorizedSorting() const return m_iconsView != 0; } -bool DolphinView::ViewAccessor::hasExpandableFolders() const +bool DolphinView::ViewAccessor::itemsExpandable() const { - const DolphinSettings& settings = DolphinSettings::instance(); - return settings.generalSettings()->autoExpandFolders() || - ((m_detailsView != 0) && settings.detailsModeSettings()->expandableFolders()); + return (m_detailsView != 0) && m_detailsView->itemsExpandable(); } -bool DolphinView::ViewAccessor::itemsExpandable() const + +QSet DolphinView::ViewAccessor::expandedUrls() const { - return (m_detailsView != 0) && m_detailsView->itemsExpandable(); + if(m_detailsView != 0) { + return m_detailsView->expandedUrls(); + } + else { + return QSet(); + } +} + +const DolphinDetailsViewExpander* DolphinView::ViewAccessor::setExpandedUrls(const QSet& urlsToExpand) +{ + if((m_detailsView != 0) && m_detailsView->itemsExpandable() && !urlsToExpand.isEmpty()) { + m_detailsViewExpander = new DolphinDetailsViewExpander(m_detailsView, urlsToExpand); + return m_detailsViewExpander; + } + else { + return 0; + } } bool DolphinView::ViewAccessor::reloadOnAdditionalInfoChange() const @@ -1593,7 +1609,6 @@ bool DolphinView::ViewAccessor::reloadOnAdditionalInfoChange() const return m_detailsView != 0; } - DolphinModel* DolphinView::ViewAccessor::dirModel() const { return static_cast(proxyModel()->sourceModel()); @@ -1612,4 +1627,18 @@ KDirLister* DolphinView::ViewAccessor::dirLister() const return dirModel()->dirLister(); } +void DolphinView::slotRedirection(const KUrl& oldUrl, const KUrl& newUrl) +{ + emit redirection(oldUrl, newUrl); + m_controller->redirectToUrl(newUrl); // #186947 +} + +void DolphinView::restoreContentsPosition() +{ + if (!m_restoredContentsPosition.isNull()) { + setContentsPosition(m_restoredContentsPosition.x(), m_restoredContentsPosition.y()); + m_restoredContentsPosition = QPoint(); + } +} + #include "dolphinview.moc"