X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/4832bd7fbde4bae828fb5cd667eb129d1ce78af7..b5eca6dc2aaa6f90d7dc2fe27ab9ccc45aee77f2:/src/dolphinview.cpp diff --git a/src/dolphinview.cpp b/src/dolphinview.cpp index 69d7706d3..51dbb708c 100644 --- a/src/dolphinview.cpp +++ b/src/dolphinview.cpp @@ -51,7 +51,6 @@ #include "viewproperties.h" #include "dolphinsettings.h" #include "dolphin_generalsettings.h" -#include "dolphincategorydrawer.h" DolphinView::DolphinView(QWidget* parent, const KUrl& url, @@ -61,7 +60,7 @@ DolphinView::DolphinView(QWidget* parent, QWidget(parent), m_active(true), m_loadingDirectory(false), - m_initializeColumnView(false), + m_storedCategorizedSorting(false), m_mode(DolphinView::IconsView), m_topLayout(0), m_controller(0), @@ -71,8 +70,7 @@ DolphinView::DolphinView(QWidget* parent, m_fileItemDelegate(0), m_dolphinModel(dolphinModel), m_dirLister(dirLister), - m_proxyModel(proxyModel), - m_rootUrl(url) + m_proxyModel(proxyModel) { setFocusPolicy(Qt::StrongFocus); m_topLayout = new QVBoxLayout(this); @@ -85,8 +83,8 @@ DolphinView::DolphinView(QWidget* parent, connect(m_dirLister, SIGNAL(completed()), this, SLOT(updateCutItems())); - connect(m_dirLister, SIGNAL(newItems(const QList&)), - this, SLOT(generatePreviews(const QList&))); + connect(m_dirLister, SIGNAL(newItems(const KFileItemList&)), + this, SLOT(generatePreviews(const KFileItemList&))); m_controller = new DolphinController(this); m_controller->setUrl(url); @@ -100,12 +98,12 @@ DolphinView::DolphinView(QWidget* parent, this, SLOT(updateSorting(DolphinView::Sorting))); connect(m_controller, SIGNAL(sortOrderChanged(Qt::SortOrder)), this, SLOT(updateSortOrder(Qt::SortOrder))); - connect(m_controller, SIGNAL(itemTriggered(const QModelIndex&)), - this, SLOT(triggerItem(const QModelIndex&))); + connect(m_controller, SIGNAL(itemTriggered(const KFileItem&)), + this, SLOT(triggerItem(const KFileItem&))); connect(m_controller, SIGNAL(activated()), this, SLOT(activate())); - connect(m_controller, SIGNAL(itemEntered(const QModelIndex&)), - this, SLOT(showHoverInformation(const QModelIndex&))); + connect(m_controller, SIGNAL(itemEntered(const KFileItem&)), + this, SLOT(showHoverInformation(const KFileItem&))); connect(m_controller, SIGNAL(viewportEntered()), this, SLOT(clearHoverInformation())); @@ -122,14 +120,9 @@ const KUrl& DolphinView::url() const return m_controller->url(); } -void DolphinView::setRootUrl(const KUrl& url) -{ - m_rootUrl = url; -} - KUrl DolphinView::rootUrl() const { - return isColumnViewActive() ? m_dirLister->url() : url(); + return isColumnViewActive() ? m_columnView->rootUrl() : url(); } void DolphinView::setActive(bool active) @@ -140,12 +133,29 @@ void DolphinView::setActive(bool active) m_active = active; - updateViewportColor(); + QColor color = KColorScheme(QPalette::Active, KColorScheme::View).background().color(); + if (active) { + // TODO: emitting urlChanged() is a hack, as the URL hasn't really changed. It + // bypasses the problem when having a split view and changing the active view to + // update the some URL dependent states. A nicer approach should be no big deal... + emit urlChanged(url()); + emit selectionChanged(selectedItems()); + } else { + color.setAlpha(150); + } + + QWidget* viewport = itemView()->viewport(); + QPalette palette; + palette.setColor(viewport->backgroundRole(), color); + viewport->setPalette(palette); + update(); if (active) { emit activated(); } + + m_controller->indicateActivationChange(active); } bool DolphinView::isActive() const @@ -166,8 +176,9 @@ void DolphinView::setMode(Mode mode) // to go back to the root URL of the column view automatically. // Otherwise there it would not be possible to turn off the column view // without focusing the first column. - setUrl(m_dirLister->url()); - m_controller->setUrl(m_dirLister->url()); + const KUrl root = rootUrl(); + setUrl(root); + m_controller->setUrl(root); } const KUrl viewPropsUrl = viewPropertiesUrl(); @@ -175,7 +186,19 @@ void DolphinView::setMode(Mode mode) props.setViewMode(m_mode); createView(); - startDirLister(viewPropsUrl); + + // Not all view modes support categorized sorting. Adjust the sorting model + // if changing the view mode results in a change of the categorized sorting + // capabilities. + m_storedCategorizedSorting = props.categorizedSorting(); + const bool categorized = m_storedCategorizedSorting && supportsCategorizedSorting(); + if (categorized != m_proxyModel->isCategorizedModel()) { + m_proxyModel->setCategorizedModel(categorized); + m_proxyModel->sort(m_proxyModel->sortColumn(), m_proxyModel->sortOrder()); + emit categorizedSortingChanged(); + } + + loadDirectory(viewPropsUrl); emit modeChanged(); } @@ -194,7 +217,7 @@ void DolphinView::setShowPreview(bool show) m_controller->setShowPreview(show); emit showPreviewChanged(); - startDirLister(viewPropsUrl, true); + loadDirectory(viewPropsUrl, true); } bool DolphinView::showPreview() const @@ -213,9 +236,10 @@ void DolphinView::setShowHiddenFiles(bool show) props.setShowHiddenFiles(show); m_dirLister->setShowingDotFiles(show); + m_controller->setShowHiddenFiles(show); emit showHiddenFilesChanged(); - startDirLister(viewPropsUrl, true); + loadDirectory(viewPropsUrl, true); } bool DolphinView::showHiddenFiles() const @@ -225,16 +249,19 @@ bool DolphinView::showHiddenFiles() const void DolphinView::setCategorizedSorting(bool categorized) { - if (!supportsCategorizedSorting() || (categorized == categorizedSorting())) { + if (categorized == categorizedSorting()) { return; } - Q_ASSERT(m_iconsView != 0); + // setCategorizedSorting(true) may only get invoked + // if the view supports categorized sorting + Q_ASSERT(!categorized || supportsCategorizedSorting()); ViewProperties props(viewPropertiesUrl()); props.setCategorizedSorting(categorized); props.save(); + m_storedCategorizedSorting = categorized; m_proxyModel->setCategorizedModel(categorized); m_proxyModel->sort(m_proxyModel->sortColumn(), m_proxyModel->sortOrder()); @@ -243,7 +270,14 @@ void DolphinView::setCategorizedSorting(bool categorized) bool DolphinView::categorizedSorting() const { - return m_proxyModel->isCategorizedModel(); + // If all view modes would support categorized sorting, returning + // m_proxyModel->isCategorizedModel() would be the way to go. As + // currently only the icons view supports caterized sorting, we remember + // the stored view properties state in m_storedCategorizedSorting and + // return this state. The application takes care to disable the corresponding + // checkbox by checking DolphinView::supportsCategorizedSorting() to indicate + // that this setting is not applied to the current view mode. + return m_storedCategorizedSorting; } bool DolphinView::supportsCategorizedSorting() const @@ -258,15 +292,24 @@ void DolphinView::selectAll() void DolphinView::invertSelection() { - QItemSelectionModel* selectionModel = itemView()->selectionModel(); - const QAbstractItemModel* itemModel = selectionModel->model(); + if (isColumnViewActive()) { + // QAbstractItemView does not offer a virtual method invertSelection() + // as counterpart to QAbstractItemView::selectAll(). This makes it + // necessary to delegate the inverting of the selection to the + // column view, as only the selection of the active column should + // get inverted. + m_columnView->invertSelection(); + } else { + QItemSelectionModel* selectionModel = 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 QModelIndex topLeft = itemModel->index(0, 0); + const QModelIndex bottomRight = itemModel->index(itemModel->rowCount() - 1, + itemModel->columnCount() - 1); - QItemSelection selection(topLeft, bottomRight); - selectionModel->select(selection, QItemSelectionModel::Toggle); + const QItemSelection selection(topLeft, bottomRight); + selectionModel->select(selection, QItemSelectionModel::Toggle); + } } bool DolphinView::hasSelection() const @@ -279,7 +322,7 @@ void DolphinView::clearSelection() itemView()->selectionModel()->clear(); } -QList DolphinView::selectedItems() const +KFileItemList DolphinView::selectedItems() const { const QAbstractItemView* view = itemView(); @@ -288,7 +331,7 @@ QList DolphinView::selectedItems() const Q_ASSERT((view != 0) && (view->selectionModel() != 0)); const QItemSelection selection = m_proxyModel->mapSelectionToSource(view->selectionModel()->selection()); - QList itemList; + KFileItemList itemList; const QModelIndexList indexList = selection.indexes(); foreach (QModelIndex index, indexList) { @@ -304,10 +347,9 @@ QList DolphinView::selectedItems() const KUrl::List DolphinView::selectedUrls() const { KUrl::List urls; - const QList list = selectedItems(); - for ( QList::const_iterator it = list.begin(), end = list.end(); - it != end; ++it ) { - urls.append((*it).url()); + const KFileItemList list = selectedItems(); + foreach (KFileItem item, list) { + urls.append(item.url()); } return urls; } @@ -382,71 +424,77 @@ Qt::SortOrder DolphinView::sortOrder() const return m_proxyModel->sortOrder(); } -void DolphinView::setAdditionalInfo(KFileItemDelegate::AdditionalInformation info) +void DolphinView::setAdditionalInfo(KFileItemDelegate::InformationList info) { const KUrl viewPropsUrl = viewPropertiesUrl(); ViewProperties props(viewPropsUrl); props.setAdditionalInfo(info); - m_controller->setShowAdditionalInfo(info != KFileItemDelegate::NoInformation); - m_fileItemDelegate->setAdditionalInformation(info); + m_controller->setAdditionalInfoCount(info.count()); + m_fileItemDelegate->setShowInformation(info); emit additionalInfoChanged(info); - startDirLister(viewPropsUrl, true); + loadDirectory(viewPropsUrl, true); } -KFileItemDelegate::AdditionalInformation DolphinView::additionalInfo() const +KFileItemDelegate::InformationList DolphinView::additionalInfo() const { - return m_fileItemDelegate->additionalInformation(); + return m_fileItemDelegate->showInformation(); } void DolphinView::reload() { setUrl(url()); - startDirLister(url(), true); + loadDirectory(url(), true); } void DolphinView::refresh() { + const bool oldActivationState = m_active; + m_active = true; + createView(); applyViewProperties(m_controller->url()); reload(); - updateViewportColor(); + + setActive(oldActivationState); } -void DolphinView::setUrl(const KUrl& url) +void DolphinView::updateView(const KUrl& url, const KUrl& rootUrl) { if (m_controller->url() == url) { return; } - const KUrl oldRootUrl = rootUrl(); + const bool restoreColumnView = !rootUrl.isEmpty() + && !rootUrl.equals(url, KUrl::CompareWithoutTrailingSlash) + && rootUrl.isParentOf(url); + m_controller->setUrl(url); // emits urlChanged, which we forward - bool useUrlProperties = true; - const bool restoreColumnView = !isColumnViewActive() - && m_rootUrl.isParentOf(url) - && (m_rootUrl != url); if (restoreColumnView) { - applyViewProperties(m_rootUrl); + applyViewProperties(rootUrl); + loadDirectory(rootUrl); + // Restoring the column view relies on the URL-history. It might be possible + // that the view properties have been changed or deleted in the meantime, so + // it cannot be asserted that really a column view has been created: if (itemView() == m_columnView) { - startDirLister(m_rootUrl); + m_columnView->setRootUrl(rootUrl); m_columnView->showColumn(url); - useUrlProperties = false; } - } - - if (useUrlProperties) { + } else { applyViewProperties(url); - startDirLister(url); + loadDirectory(url); } itemView()->setFocus(); - const KUrl newRootUrl = rootUrl(); - if (newRootUrl != oldRootUrl) { - emit rootUrlChanged(newRootUrl); - } + emit startedPathLoading(url); +} + +void DolphinView::setUrl(const KUrl& url) +{ + updateView(url, KUrl()); } void DolphinView::mouseReleaseEvent(QMouseEvent* event) @@ -459,10 +507,8 @@ void DolphinView::activate() setActive(true); } -void DolphinView::triggerItem(const QModelIndex& index) +void DolphinView::triggerItem(const KFileItem& item) { - Q_ASSERT(index.isValid()); - const Qt::KeyboardModifiers modifier = QApplication::keyboardModifiers(); if ((modifier & Qt::ShiftModifier) || (modifier & Qt::ControlModifier)) { // items are selected by the user, hence don't trigger the @@ -470,8 +516,6 @@ void DolphinView::triggerItem(const QModelIndex& index) return; } - const KFileItem item = m_dolphinModel->itemForIndex(m_proxyModel->mapToSource(index)); - if (item.isNull()) { return; } @@ -479,7 +523,7 @@ void DolphinView::triggerItem(const QModelIndex& index) emit itemTriggered(item); // caught by DolphinViewContainer or DolphinPart } -void DolphinView::generatePreviews(const QList& items) +void DolphinView::generatePreviews(const KFileItemList& items) { if (m_controller->showPreview()) { KIO::PreviewJob* job = KIO::filePreview(items, 128); @@ -502,7 +546,7 @@ void DolphinView::showPreview(const KFileItem& item, const QPixmap& pixmap) const QMimeData* mimeData = QApplication::clipboard()->mimeData(); if (KonqMimeData::decodeIsCutSelection(mimeData) && isCutItem(item)) { KIconEffect iconEffect; - const QPixmap cutPixmap = iconEffect.apply(pixmap, K3Icon::Desktop, K3Icon::DisabledState); + 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); @@ -515,7 +559,7 @@ void DolphinView::emitSelectionChangedSignal() emit selectionChanged(DolphinView::selectedItems()); } -void DolphinView::startDirLister(const KUrl& url, bool reload) +void DolphinView::loadDirectory(const KUrl& url, bool reload) { if (!url.isValid()) { const QString location(url.pathOrUrl()); @@ -531,32 +575,16 @@ void DolphinView::startDirLister(const KUrl& url, bool reload) m_loadingDirectory = true; m_dirLister->stop(); + m_dirLister->openUrl(url, reload ? KDirLister::Reload : KDirLister::NoFlags); - bool keepOldDirs = isColumnViewActive() && !m_initializeColumnView; - m_initializeColumnView = false; - - if (keepOldDirs) { - // keeping old directories is only necessary for hierarchical views - // like the column view + if (isColumnViewActive()) { + // adjusting the directory lister is not enough in the case of the + // column view, as each column has its own directory lister internally... if (reload) { - // for the column view it is not enough to reload the directory lister, - // so this task is delegated to the column view directly m_columnView->reload(); - } else if (m_dirLister->directories().contains(url)) { - // The dir lister contains the directory already, so - // KDirLister::openUrl() may not get invoked twice. - m_dirLister->updateDirectory(url); } else { - const KUrl& dirListerUrl = m_dirLister->url(); - if ((dirListerUrl == url) || !m_dirLister->url().isParentOf(url)) { - // The current URL is not a child of the dir lister - // URL. This may happen when e. g. a place has been selected - // and hence the view must be reset. - m_dirLister->openUrl(url, false, false); - } + m_columnView->showColumn(url); } - } else { - m_dirLister->openUrl(url, false, reload); } } @@ -571,7 +599,7 @@ KUrl DolphinView::viewPropertiesUrl() const void DolphinView::applyViewProperties(const KUrl& url) { - if (isColumnViewActive() && m_dirLister->url().isParentOf(url)) { + if (isColumnViewActive() && rootUrl().isParentOf(url)) { // The column view is active, hence don't apply the view properties // of sub directories (represented by columns) to the view. The // view always represents the properties of the first column. @@ -585,14 +613,6 @@ void DolphinView::applyViewProperties(const KUrl& url) m_mode = mode; createView(); emit modeChanged(); - - if (m_mode == ColumnView) { - // The mode has been changed to the Column View. When starting the dir - // lister with DolphinView::startDirLister() it is important to give a - // hint that the dir lister may not keep the current directory - // although this is the default for showing a hierarchy. - m_initializeColumnView = true; - } } if (itemView() == 0) { createView(); @@ -603,12 +623,15 @@ void DolphinView::applyViewProperties(const KUrl& url) const bool showHiddenFiles = props.showHiddenFiles(); if (showHiddenFiles != m_dirLister->showingDotFiles()) { m_dirLister->setShowingDotFiles(showHiddenFiles); + m_controller->setShowHiddenFiles(showHiddenFiles); emit showHiddenFilesChanged(); } - const bool categorized = props.categorizedSorting(); - if (categorized != categorizedSorting()) { + m_storedCategorizedSorting = props.categorizedSorting(); + const bool categorized = m_storedCategorizedSorting && supportsCategorizedSorting(); + if (categorized != m_proxyModel->isCategorizedModel()) { m_proxyModel->setCategorizedModel(categorized); + m_proxyModel->sort(m_proxyModel->sortColumn(), m_proxyModel->sortOrder()); emit categorizedSortingChanged(); } @@ -624,10 +647,10 @@ void DolphinView::applyViewProperties(const KUrl& url) emit sortOrderChanged(sortOrder); } - KFileItemDelegate::AdditionalInformation info = props.additionalInfo(); - if (info != m_fileItemDelegate->additionalInformation()) { - m_controller->setShowAdditionalInfo(info != KFileItemDelegate::NoInformation); - m_fileItemDelegate->setAdditionalInformation(info); + KFileItemDelegate::InformationList info = props.additionalInfo(); + if (info != m_fileItemDelegate->showInformation()) { + m_controller->setAdditionalInfoCount(info.count()); + m_fileItemDelegate->setShowInformation(info); emit additionalInfoChanged(info); } @@ -638,7 +661,7 @@ void DolphinView::applyViewProperties(const KUrl& url) } } -void DolphinView::changeSelection(const QList& selection) +void DolphinView::changeSelection(const KFileItemList& selection) { clearSelection(); if (selection.isEmpty()) { @@ -755,16 +778,13 @@ void DolphinView::updateCutItems() applyCutItemEffect(); } -void DolphinView::showHoverInformation(const QModelIndex& index) +void DolphinView::showHoverInformation(const KFileItem& item) { if (hasSelection()) { return; } - const KFileItem item = fileItem(index); - if (!item.isNull()) { - emit requestItemInfo(item); - } + emit requestItemInfo(item); } void DolphinView::clearHoverInformation() @@ -775,6 +795,11 @@ void DolphinView::clearHoverInformation() void DolphinView::createView() { + KFileItemDelegate::InformationList infoList; + if (m_fileItemDelegate != 0) { + infoList = m_fileItemDelegate->showInformation(); + } + // delete current view QAbstractItemView* view = itemView(); if (view != 0) { @@ -794,11 +819,11 @@ void DolphinView::createView() // ... and recreate it representing the current mode switch (m_mode) { - case IconsView: + case IconsView: { m_iconsView = new DolphinIconsView(this, m_controller); - m_iconsView->setCategoryDrawer(new DolphinCategoryDrawer()); view = m_iconsView; break; + } case DetailsView: m_detailsView = new DolphinDetailsView(this, m_controller); @@ -814,6 +839,7 @@ void DolphinView::createView() Q_ASSERT(view != 0); m_fileItemDelegate = new KFileItemDelegate(view); + m_fileItemDelegate->setShowInformation(infoList); view->setItemDelegate(m_fileItemDelegate); view->setModel(m_proxyModel); @@ -876,11 +902,9 @@ void DolphinView::applyCutItemEffect() KFileItemList::const_iterator it = items.begin(); const KFileItemList::const_iterator end = items.end(); while (it != end) { - KFileItem* item = *it; - if (isCutItem(*item)) { - const QModelIndex index = m_dolphinModel->indexForItem(*item); - // Huh? the item is already known - //const KFileItem item = m_dolphinModel->itemForIndex(index); + 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(value)); @@ -889,13 +913,13 @@ void DolphinView::applyCutItemEffect() // remember current pixmap for the item to be able // to restore it when other items get cut CutItem cutItem; - cutItem.url = item->url(); + cutItem.url = item.url(); cutItem.pixmap = pixmap; m_cutItemsCache.append(cutItem); // apply icon effect to the cut item KIconEffect iconEffect; - pixmap = iconEffect.apply(pixmap, K3Icon::Desktop, K3Icon::DisabledState); + pixmap = iconEffect.apply(pixmap, KIconLoader::Desktop, KIconLoader::DisabledState); m_dolphinModel->setData(index, QIcon(pixmap), Qt::DecorationRole); } } @@ -903,20 +927,4 @@ void DolphinView::applyCutItemEffect() } } -void DolphinView::updateViewportColor() -{ - QColor color = KColorScheme(QPalette::Active, KColorScheme::View).background().color(); - if (m_active) { - emit urlChanged(url()); // Hmm, this is a hack; the url hasn't really changed. - emit selectionChanged(selectedItems()); - } else { - color.setAlpha(0); - } - - QWidget* viewport = itemView()->viewport(); - QPalette palette; - palette.setColor(viewport->backgroundRole(), color); - viewport->setPalette(palette); -} - #include "dolphinview.moc"