X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/c33b01efb2aed904af9ffaef27fb3b0b4bdda37b..d673ccac4dec1e81f3a3ed5a1c2081cce3724e62:/src/dolphinview.cpp diff --git a/src/dolphinview.cpp b/src/dolphinview.cpp index e1f1cf53c..2f80682cc 100644 --- a/src/dolphinview.cpp +++ b/src/dolphinview.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -57,6 +58,7 @@ #include "dolphin_generalsettings.h" #include "iconmanager.h" #include "renamedialog.h" +#include "tooltipmanager.h" #include "viewproperties.h" DolphinView::DolphinView(QWidget* parent, @@ -69,6 +71,8 @@ DolphinView::DolphinView(QWidget* parent, m_showPreview(false), m_loadingDirectory(false), m_storedCategorizedSorting(false), + m_tabsForFiles(false), + m_isContextMenuOpen(false), m_mode(DolphinView::IconsView), m_topLayout(0), m_controller(0), @@ -80,9 +84,11 @@ DolphinView::DolphinView(QWidget* parent, m_dolphinModel(dolphinModel), m_dirLister(dirLister), m_proxyModel(proxyModel), - m_iconManager(0) + m_iconManager(0), + m_toolTipManager(0), + m_rootUrl(), + m_currentItemUrl() { - setFocusPolicy(Qt::StrongFocus); m_topLayout = new QVBoxLayout(this); m_topLayout->setSpacing(0); m_topLayout->setMargin(0); @@ -90,14 +96,10 @@ DolphinView::DolphinView(QWidget* parent, m_controller = new DolphinController(this); m_controller->setUrl(url); - // Receiver of the DolphinView signal 'urlChanged()' don't need - // to care whether the internal controller changed the URL already or whether - // the controller just requested an URL change and will be updated later. - // In both cases the URL has been changed: connect(m_controller, SIGNAL(urlChanged(const KUrl&)), this, SIGNAL(urlChanged(const KUrl&))); connect(m_controller, SIGNAL(requestUrlChange(const KUrl&)), - this, SIGNAL(urlChanged(const KUrl&))); + this, SLOT(slotRequestUrlChange(const KUrl&))); connect(m_controller, SIGNAL(requestContextMenu(const QPoint&)), this, SLOT(openContextMenu(const QPoint&))); @@ -111,6 +113,8 @@ DolphinView::DolphinView(QWidget* parent, this, SLOT(updateAdditionalInfo(const KFileItemDelegate::InformationList&))); connect(m_controller, SIGNAL(itemTriggered(const KFileItem&)), this, SLOT(triggerItem(const KFileItem&))); + connect(m_controller, SIGNAL(tabRequested(const KUrl&)), + this, SIGNAL(tabRequested(const KUrl&))); connect(m_controller, SIGNAL(activated()), this, SLOT(activate())); connect(m_controller, SIGNAL(itemEntered(const KFileItem&)), @@ -118,6 +122,11 @@ DolphinView::DolphinView(QWidget* parent, connect(m_controller, SIGNAL(viewportEntered()), this, SLOT(clearHoverInformation())); + connect(m_dirLister, SIGNAL(redirection(KUrl, KUrl)), + this, SLOT(slotRedirection(KUrl, KUrl))); + connect(m_dirLister, SIGNAL(completed()), + this, SLOT(restoreCurrentItem())); + applyViewProperties(url); m_topLayout->addWidget(itemView()); } @@ -143,7 +152,6 @@ void DolphinView::setActive(bool active) } m_active = active; - m_selectionModel->clearSelection(); QColor color = KColorScheme(QPalette::Active, KColorScheme::View).background().color(); if (active) { @@ -164,6 +172,7 @@ void DolphinView::setActive(bool active) update(); if (active) { + itemView()->setFocus(); emit activated(); } @@ -286,6 +295,10 @@ void DolphinView::clearSelection() KFileItemList DolphinView::selectedItems() const { + if (isColumnViewActive()) { + return m_columnView->selectedItems(); + } + const QAbstractItemView* view = itemView(); // Our view has a selection, we will map them back to the DolphinModel @@ -296,7 +309,7 @@ KFileItemList DolphinView::selectedItems() const KFileItemList itemList; const QModelIndexList indexList = selection.indexes(); - foreach (QModelIndex index, indexList) { + foreach (const QModelIndex &index, indexList) { KFileItem item = m_dolphinModel->itemForIndex(index); if (!item.isNull()) { itemList.append(item); @@ -310,16 +323,21 @@ KUrl::List DolphinView::selectedUrls() const { KUrl::List urls; const KFileItemList list = selectedItems(); - foreach (KFileItem item, list) { + foreach (const KFileItem &item, list) { urls.append(item.url()); } return urls; } -KFileItem DolphinView::fileItem(const QModelIndex& index) const +int DolphinView::selectedItemsCount() const { - const QModelIndex dolphinModelIndex = m_proxyModel->mapToSource(index); - return m_dolphinModel->itemForIndex(dolphinModelIndex); + if (isColumnViewActive()) { + // TODO: get rid of this special case by adjusting the dir lister + // to the current column + return m_columnView->selectedItems().count(); + } + + return itemView()->selectionModel()->selection().count(); } void DolphinView::setContentsPosition(int x, int y) @@ -433,6 +451,7 @@ void DolphinView::updateView(const KUrl& url, const KUrl& rootUrl) return; } + m_iconManager->cancelPreviews(); m_controller->setUrl(url); // emits urlChanged, which we forward if (!rootUrl.isEmpty() && rootUrl.isParentOf(url)) { @@ -463,7 +482,7 @@ void DolphinView::setNameFilter(const QString& nameFilter) void DolphinView::calculateItemCount(int& fileCount, int& folderCount) { - foreach (KFileItem item, m_dirLister->items()) { + foreach (const KFileItem &item, m_dirLister->items()) { if (item.isDir()) { ++folderCount; } else { @@ -474,6 +493,8 @@ void DolphinView::calculateItemCount(int& fileCount, int& folderCount) void DolphinView::setUrl(const KUrl& url) { + // remember current item candidate (see restoreCurrentItem()) + m_currentItemUrl = url; updateView(url, KUrl()); } @@ -501,7 +522,12 @@ void DolphinView::changeSelection(const KFileItemList& selection) void DolphinView::renameSelectedItems() { const KFileItemList items = selectedItems(); - if (items.count() > 1) { + const int itemCount = items.count(); + if (itemCount < 1) { + return; + } + + if (itemCount > 1) { // More than one item has been selected for renaming. Open // a rename dialog and rename all items afterwards. RenameDialog dialog(this, items); @@ -513,13 +539,13 @@ void DolphinView::renameSelectedItems() if (newName.isEmpty()) { emit errorMessage(dialog.errorString()); } else { - // TODO: check how this can be integrated into KonqFileUndoManager/KonqOperations + // TODO: check how this can be integrated into KIO::FileUndoManager/KonqOperations // as one operation instead of n rename operations like it is done now... Q_ASSERT(newName.contains('#')); // iterate through all selected items and rename them... int index = 1; - foreach (KFileItem item, items) { + foreach (const KFileItem &item, items) { const KUrl& oldUrl = item.url(); QString number; number.setNum(index++); @@ -531,13 +557,11 @@ void DolphinView::renameSelectedItems() KUrl newUrl = oldUrl; newUrl.setFileName(name); KonqOperations::rename(this, oldUrl, newUrl); - emit doingOperation(KonqFileUndoManager::RENAME); + emit doingOperation(KIO::FileUndoManager::Rename); } } } } else if (DolphinSettings::instance().generalSettings()->renameInline()) { - Q_ASSERT(items.count() == 1); - if (isColumnViewActive()) { m_columnView->editItem(items.first()); } else { @@ -546,8 +570,6 @@ void DolphinView::renameSelectedItems() itemView()->edit(proxyIndex); } } else { - Q_ASSERT(items.count() == 1); - RenameDialog dialog(this, items); if (dialog.exec() == QDialog::Rejected) { return; @@ -561,14 +583,14 @@ void DolphinView::renameSelectedItems() KUrl newUrl = oldUrl; newUrl.setFileName(newName); KonqOperations::rename(this, oldUrl, newUrl); - emit doingOperation(KonqFileUndoManager::RENAME); + emit doingOperation(KIO::FileUndoManager::Rename); } } } void DolphinView::trashSelectedItems() { - emit doingOperation(KonqFileUndoManager::TRASH); + emit doingOperation(KIO::FileUndoManager::Trash); KonqOperations::del(this, KonqOperations::TRASH, selectedUrls()); } @@ -743,10 +765,14 @@ void DolphinView::triggerItem(const KFileItem& item) return; } - if (item.isNull()) { + // TODO: the m_isContextMenuOpen check is a workaround for Qt-issue 207192 + if (item.isNull() || m_isContextMenuOpen) { return; } + if (m_toolTipManager != 0) { + m_toolTipManager->hideTip(); + } emit itemTriggered(item); // caught by DolphinViewContainer or DolphinPart } @@ -758,13 +784,23 @@ void DolphinView::emitSelectionChangedSignal() void DolphinView::openContextMenu(const QPoint& pos) { KFileItem item; + if (isColumnViewActive()) { + item = m_columnView->itemAt(pos); + } else { + const QModelIndex index = itemView()->indexAt(pos); + if (index.isValid() && (index.column() == DolphinModel::Name)) { + const QModelIndex dolphinModelIndex = m_proxyModel->mapToSource(index); + item = m_dolphinModel->itemForIndex(dolphinModelIndex); + } + } - const QModelIndex index = itemView()->indexAt(pos); - if (index.isValid() && (index.column() == DolphinModel::Name)) { - item = fileItem(index); + if (m_toolTipManager != 0) { + m_toolTipManager->hideTip(); } + m_isContextMenuOpen = true; // TODO: workaround for Qt-issue 207192 emit requestContextMenu(item, url()); + m_isContextMenuOpen = false; } void DolphinView::dropUrls(const KUrl::List& urls, @@ -772,24 +808,18 @@ void DolphinView::dropUrls(const KUrl::List& urls, const KFileItem& destItem) { Q_ASSERT(!urls.isEmpty()); - const KUrl& destination = !destItem.isNull() && destItem.isDir() ? - destItem.url() : destPath; + const KUrl destination = !destItem.isNull() && destItem.isDir() ? + destItem.url() : destPath; const KUrl sourceDir = KUrl(urls.first().directory()); if (sourceDir != destination) { - dropUrls(urls, destination); + DolphinDropController dropController(this); + // forward doingOperation signal up to the mainwindow + connect(&dropController, SIGNAL(doingOperation(KIO::FileUndoManager::CommandType)), + this, SIGNAL(doingOperation(KIO::FileUndoManager::CommandType))); + dropController.dropUrls(urls, destination); } } -void DolphinView::dropUrls(const KUrl::List& urls, - const KUrl& destination) -{ - DolphinDropController dropController(this); - // forward doingOperation signal up to the mainwindow - connect(&dropController, SIGNAL(doingOperation(KonqFileUndoManager::CommandType)), - this, SIGNAL(doingOperation(KonqFileUndoManager::CommandType))); - dropController.dropUrls(urls, destination); -} - void DolphinView::updateSorting(DolphinView::Sorting sorting) { ViewProperties props(viewPropertiesUrl()); @@ -881,7 +911,10 @@ QPair DolphinView::pasteInfo() const KUrl::List urls = KUrl::List::fromMimeData(mimeData); if (!urls.isEmpty()) { - ret.first = true; + // disable the paste action if no writing is supported + KFileItem item(KFileItem::Unknown, KFileItem::Unknown, url()); + ret.first = KonqFileItemCapabilities(KFileItemList() << item).supportsWriting(); + if (urls.count() == 1) { const KFileItem item(KFileItem::Unknown, KFileItem::Unknown, urls.first(), true); ret.second = item.isDir() ? i18nc("@action:inmenu", "Paste One Folder") : @@ -898,6 +931,16 @@ QPair DolphinView::pasteInfo() const return ret; } +void DolphinView::setTabsForFilesEnabled(bool tabsForFiles) +{ + m_tabsForFiles = tabsForFiles; +} + +bool DolphinView::isTabsForFilesEnabled() const +{ + return m_tabsForFiles; +} + void DolphinView::emitContentsMoved() { // only emit the contents moved signal if: @@ -930,6 +973,21 @@ void DolphinView::slotDeleteFileFinished(KJob* job) } } + +void DolphinView::restoreCurrentItem() +{ + const QModelIndex dirIndex = m_dolphinModel->indexForUrl(m_currentItemUrl); + if (dirIndex.isValid()) { + const QModelIndex proxyIndex = m_proxyModel->mapFromSource(dirIndex); + QAbstractItemView* view = itemView(); + const bool clearSelection = !hasSelection(); + view->setCurrentIndex(proxyIndex); + if (clearSelection) { + view->clearSelection(); + } + } +} + void DolphinView::loadDirectory(const KUrl& url, bool reload) { if (!url.isValid()) { @@ -1076,10 +1134,13 @@ void DolphinView::createView() view->setSelectionMode(QAbstractItemView::ExtendedSelection); - new KMimeTypeResolver(view, m_dolphinModel); m_iconManager = new IconManager(view, m_proxyModel); m_iconManager->setShowPreview(m_showPreview); + if (DolphinSettings::instance().generalSettings()->showToolTips()) { + m_toolTipManager = new ToolTipManager(view, m_proxyModel); + } + m_topLayout->insertWidget(1, view); connect(view->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), @@ -1094,6 +1155,12 @@ void DolphinView::deleteView() { QAbstractItemView* view = itemView(); if (view != 0) { + // It's important to set the keyboard focus to the parent + // before deleting the view: Otherwise when having a split + // view the other view will get the focus and will request + // an activation (see DolphinView::eventFilter()). + setFocus(); + m_topLayout->removeWidget(view); view->close(); view->deleteLater(); @@ -1103,6 +1170,7 @@ void DolphinView::deleteView() m_columnView = 0; m_fileItemDelegate = 0; m_iconManager = 0; + m_toolTipManager = 0; } } @@ -1143,11 +1211,24 @@ void DolphinView::pasteToUrl(const KUrl& url) const KUrl::List sourceUrls = KUrl::List::fromMimeData(mimeData); if (KonqMimeData::decodeIsCutSelection(mimeData)) { KonqOperations::copy(this, KonqOperations::MOVE, sourceUrls, url); - emit doingOperation(KonqFileUndoManager::MOVE); + emit doingOperation(KIO::FileUndoManager::Move); clipboard->clear(); } else { KonqOperations::copy(this, KonqOperations::COPY, sourceUrls, url); - emit doingOperation(KonqFileUndoManager::COPY); + emit doingOperation(KIO::FileUndoManager::Copy); + } +} + +void DolphinView::slotRequestUrlChange(const KUrl& url) +{ + emit requestUrlChange(url); + m_controller->setUrl(url); +} + +void DolphinView::slotRedirection(const KUrl& oldUrl, const KUrl& newUrl) +{ + if (oldUrl == m_controller->url()) { + m_controller->setUrl(newUrl); } }