X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/453c48660c87820b0e5f2e445213048bee9968a1..ab39a5952001cdb3d1b9ca693da7f8e246558fb8:/src/dolphinview.cpp diff --git a/src/dolphinview.cpp b/src/dolphinview.cpp index a49aabdd9..e057c950a 100644 --- a/src/dolphinview.cpp +++ b/src/dolphinview.cpp @@ -64,6 +64,7 @@ #include "settings/dolphinsettings.h" #include "viewproperties.h" #include "zoomlevelinfo.h" +#include "dolphindetailsviewexpander.h" /** * Helper function for sorting items with qSort() in @@ -94,6 +95,7 @@ DolphinView::DolphinView(QWidget* parent, m_selectionChangedTimer(0), m_rootUrl(), m_activeItemUrl(), + m_restoredContentsPosition(), m_createdItemUrl(), m_selectedItems(), m_newFileNames() @@ -283,45 +285,12 @@ 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 { const QAbstractItemView* view = m_viewAccessor.itemView(); return view && view->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(); -} - KFileItemList DolphinView::selectedItems() const { const QAbstractItemView* view = m_viewAccessor.itemView(); @@ -359,6 +328,11 @@ 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(); @@ -369,8 +343,18 @@ void DolphinView::setContentsPosition(int x, int 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 { + // 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(); @@ -583,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(); @@ -831,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()) { @@ -870,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; } @@ -1045,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; } @@ -1053,6 +1076,53 @@ bool DolphinView::itemsExpandable() const return m_viewAccessor.itemsExpandable(); } +void DolphinView::restoreState(QDataStream &stream) +{ + // current item + stream >> m_activeItemUrl; + + // 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 { + 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) { m_createdItemUrl = url; @@ -1081,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) { @@ -1116,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()) { @@ -1150,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) { @@ -1171,6 +1260,7 @@ void DolphinView::loadDirectory(const KUrl& url, bool reload) } m_loadingDirectory = true; + m_expanderActive = false; if (reload) { m_selectedItems = selectedItems(); @@ -1438,6 +1528,11 @@ void DolphinView::ViewAccessor::prepareUrlChange(const KUrl& url) if (m_columnsContainer != 0) { m_columnsContainer->showColumn(url); } + + if(!m_detailsViewExpander.isNull()) { + // Stop expanding items in the current folder + m_detailsViewExpander->stop(); + } } QAbstractItemView* DolphinView::ViewAccessor::itemView() const @@ -1485,6 +1580,28 @@ bool DolphinView::ViewAccessor::itemsExpandable() const return (m_detailsView != 0) && m_detailsView->itemsExpandable(); } + +QSet DolphinView::ViewAccessor::expandedUrls() const +{ + 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 { // the details view requires no reloading of the directory, as it maps @@ -1516,4 +1633,12 @@ void DolphinView::slotRedirection(const KUrl& oldUrl, const KUrl& 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"