X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/1cdb64a12bf5e6f3b97d38992799ba6bfbb06ef5..5b5a7b8da8cb3ee6bbb9f7450c87fca5de41dc05:/src/dolphinview.cpp diff --git a/src/dolphinview.cpp b/src/dolphinview.cpp index 8f06d3dc8..45717afc1 100644 --- a/src/dolphinview.cpp +++ b/src/dolphinview.cpp @@ -26,9 +26,12 @@ #include #include #include +#include +#include #include #include +#include #include #include #include @@ -39,6 +42,7 @@ #include #include +#include "dolphincolumnview.h" #include "dolphincontroller.h" #include "dolphinstatusbar.h" #include "dolphinmainwindow.h" @@ -49,32 +53,36 @@ #include "dolphincontextmenu.h" #include "filterbar.h" #include "renamedialog.h" -#include "urlnavigator.h" +#include "kurlnavigator.h" #include "viewproperties.h" +#include "dolphinsettings.h" +#include "dolphin_generalsettings.h" DolphinView::DolphinView(DolphinMainWindow* mainWindow, QWidget* parent, const KUrl& url, Mode mode, bool showHiddenFiles) : - QWidget(parent), - m_showProgress(false), - m_mode(mode), - m_iconSize(0), - m_folderCount(0), - m_fileCount(0), - m_mainWindow(mainWindow), - m_topLayout(0), - m_urlNavigator(0), - m_controller(0), - m_iconsView(0), - m_detailsView(0), - m_fileItemDelegate(0), - m_filterBar(0), - m_statusBar(0), - m_dirModel(0), - m_dirLister(0), - m_proxyModel(0) + QWidget(parent), + m_showProgress(false), + m_blockContentsMovedSignal(false), + m_mode(mode), + m_iconSize(0), + m_folderCount(0), + m_fileCount(0), + m_mainWindow(mainWindow), + m_topLayout(0), + m_urlNavigator(0), + m_controller(0), + m_iconsView(0), + m_detailsView(0), + m_columnView(0), + m_fileItemDelegate(0), + m_filterBar(0), + m_statusBar(0), + m_dirModel(0), + m_dirLister(0), + m_proxyModel(0) { hide(); setFocusPolicy(Qt::StrongFocus); @@ -85,8 +93,13 @@ DolphinView::DolphinView(DolphinMainWindow* mainWindow, connect(m_mainWindow, SIGNAL(activeViewChanged()), this, SLOT(updateActivationState())); - m_urlNavigator = new UrlNavigator(url, this); - m_urlNavigator->setShowHiddenFiles(showHiddenFiles); + QClipboard* clipboard = QApplication::clipboard(); + connect(clipboard, SIGNAL(dataChanged()), + this, SLOT(updateCutItems())); + + m_urlNavigator = new KUrlNavigator(DolphinSettings::instance().placesModel(), url, this); + m_urlNavigator->setUrlEditable(DolphinSettings::instance().generalSettings()->editableUrl()); + m_urlNavigator->setHomeUrl(DolphinSettings::instance().generalSettings()->homeUrl()); connect(m_urlNavigator, SIGNAL(urlChanged(const KUrl&)), this, SLOT(loadDirectory(const KUrl&))); connect(m_urlNavigator, SIGNAL(urlsDropped(const KUrl::List&, const KUrl&)), @@ -94,7 +107,7 @@ DolphinView::DolphinView(DolphinMainWindow* mainWindow, connect(m_urlNavigator, SIGNAL(activated()), this, SLOT(requestActivation())); connect(this, SIGNAL(contentsMoved(int, int)), - m_urlNavigator, SLOT(storeContentsPosition(int, int))); + m_urlNavigator, SLOT(savePosition(int, int))); m_statusBar = new DolphinStatusBar(this); @@ -151,7 +164,7 @@ DolphinView::DolphinView(DolphinMainWindow* mainWindow, m_filterBar = new FilterBar(this); m_filterBar->hide(); connect(m_filterBar, SIGNAL(filterChanged(const QString&)), - this, SLOT(changeNameFilter(const QString&))); + this, SLOT(changeNameFilter(const QString&))); connect(m_filterBar, SIGNAL(closeRequest()), this, SLOT(closeFilterBar())); @@ -159,8 +172,6 @@ DolphinView::DolphinView(DolphinMainWindow* mainWindow, m_topLayout->addWidget(itemView()); m_topLayout->addWidget(m_filterBar); m_topLayout->addWidget(m_statusBar); - - loadDirectory(m_urlNavigator->url()); } DolphinView::~DolphinView() @@ -234,8 +245,6 @@ void DolphinView::setShowHiddenFiles(bool show) props.save(); m_dirLister->setShowingDotFiles(show); - m_urlNavigator->setShowHiddenFiles(show); - emit showHiddenFilesChanged(); reload(); @@ -262,8 +271,7 @@ void DolphinView::renameSelectedItems() if (newName.isEmpty()) { view->statusBar()->setMessage(dialog.errorString(), DolphinStatusBar::Error); - } - else { + } else { // TODO: check how this can be integrated into KonqUndoManager/KonqOperations // as one operation instead of n rename operations like it is done now... Q_ASSERT(newName.contains('#')); @@ -284,15 +292,14 @@ void DolphinView::renameSelectedItems() name.replace(replaceIndex, 1, number); if (oldUrl.fileName() != name) { - KUrl newUrl(oldUrl.upUrl()); - newUrl.addPath(name); + KUrl newUrl = oldUrl; + newUrl.setFileName(name); m_mainWindow->rename(oldUrl, newUrl); } ++it; } } - } - else { + } else { // Only one item has been selected for renaming. Use the custom // renaming mechanism from the views. Q_ASSERT(urls.count() == 1); @@ -309,11 +316,10 @@ void DolphinView::renameSelectedItems() if (newName.isEmpty()) { view->statusBar()->setMessage(dialog.errorString(), DolphinStatusBar::Error); - } - else { + } else { const KUrl& oldUrl = urls.first(); - KUrl newUrl = oldUrl.upUrl(); - newUrl.addPath(newName); + KUrl newUrl = oldUrl; + newUrl.setFileName(newName); m_mainWindow->rename(oldUrl, newUrl); } } @@ -336,7 +342,6 @@ DolphinStatusBar* DolphinView::statusBar() const int DolphinView::contentsX() const { - return itemView()->horizontalScrollBar()->value(); } @@ -345,11 +350,6 @@ int DolphinView::contentsY() const return itemView()->verticalScrollBar()->value(); } -void DolphinView::refreshSettings() -{ - startDirLister(m_urlNavigator->url()); -} - void DolphinView::emitRequestItemInfo(const KUrl& url) { emit requestItemInfo(url); @@ -357,7 +357,7 @@ void DolphinView::emitRequestItemInfo(const KUrl& url) bool DolphinView::isFilterBarVisible() const { - return m_filterBar->isVisible(); + return m_filterBar->isVisible(); } bool DolphinView::isUrlEditable() const @@ -447,17 +447,17 @@ void DolphinView::goHome() void DolphinView::setUrlEditable(bool editable) { - m_urlNavigator->editUrl(editable); + m_urlNavigator->setUrlEditable(editable); } -const QLinkedList DolphinView::urlHistory(int& index) const +bool DolphinView::hasSelection() const { - return m_urlNavigator->history(index); + return itemView()->selectionModel()->hasSelection(); } -bool DolphinView::hasSelection() const +void DolphinView::clearSelection() { - return itemView()->selectionModel()->hasSelection(); + itemView()->selectionModel()->clear(); } KFileItemList DolphinView::selectedItems() const @@ -519,8 +519,8 @@ void DolphinView::rename(const KUrl& source, const QString& newName) dest.addPath(newName); const bool destExists = KIO::NetAccess::exists(dest, - false, - mainWindow()->activeView()); + false, + mainWindow()->activeView()); if (destExists) { // the destination already exists, hence ask the user // how to proceed... @@ -530,25 +530,24 @@ void DolphinView::rename(const KUrl& source, const QString& newName) dest.path(), KIO::M_OVERWRITE); switch (renameDialog.exec()) { - case KIO::R_OVERWRITE: - // the destination should be overwritten - ok = KIO::NetAccess::file_move(source, dest, -1, true); - break; - - case KIO::R_RENAME: { - // a new name for the destination has been used - KUrl newDest(renameDialog.newDestUrl()); - ok = KIO::NetAccess::file_move(source, newDest); - break; - } + case KIO::R_OVERWRITE: + // the destination should be overwritten + ok = KIO::NetAccess::file_move(source, dest, -1, true); + break; - default: - // the renaming operation has been canceled - reload(); - return; + case KIO::R_RENAME: { + // a new name for the destination has been used + KUrl newDest(renameDialog.newDestUrl()); + ok = KIO::NetAccess::file_move(source, newDest); + break; } - } - else { + + default: + // the renaming operation has been canceled + reload(); + return; + } + } else { // no destination exists, hence just move the file to // do the renaming ok = KIO::NetAccess::file_move(source, dest); @@ -556,13 +555,12 @@ void DolphinView::rename(const KUrl& source, const QString& newName) const QString destFileName = dest.fileName(); if (ok) { - m_statusBar->setMessage(i18n("Renamed file '%1' to '%2'.",source.fileName(), destFileName), + m_statusBar->setMessage(i18n("Renamed file '%1' to '%2'.", source.fileName(), destFileName), DolphinStatusBar::OperationCompleted); KonqOperations::rename(this, source, destFileName); - } - else { - m_statusBar->setMessage(i18n("Renaming of file '%1' to '%2' failed.",source.fileName(), destFileName), + } else { + m_statusBar->setMessage(i18n("Renaming of file '%1' to '%2' failed.", source.fileName(), destFileName), DolphinStatusBar::Error); reload(); } @@ -586,10 +584,23 @@ DolphinMainWindow* DolphinView::mainWindow() const void DolphinView::loadDirectory(const KUrl& url) { + if (!isActive()) { + requestActivation(); + } + const ViewProperties props(url); const Mode mode = props.viewMode(); - if (m_mode != mode) { + bool changeMode = (m_mode != mode); + if (changeMode && isColumnViewActive()) { + // The column view is active. Only change the + // mode if the current URL is no child of the column view. + if (m_dirLister->url().isParentOf(url)) { + changeMode = false; + } + } + + if (changeMode) { m_mode = mode; createView(); emit modeChanged(); @@ -659,34 +670,29 @@ void DolphinView::triggerItem(const QModelIndex& index) KUrl url; if (localPath.isEmpty()) { url = item->url(); - } - else { + } else { url = localPath; } if (item->isDir()) { setUrl(url); - } - else if (item->isFile()) { + } else if (item->isFile()) { // allow to browse through ZIP and tar files KMimeType::Ptr mime = item->mimeTypePtr(); - if (mime->is("application/x-zip")) { + if (mime->is("application/zip")) { url.setProtocol("zip"); setUrl(url); - } - else if (mime->is("application/x-tar") || - mime->is("application/x-tarz") || - mime->is("application/x-tbz") || - mime->is("application/x-tgz") || - mime->is("application/x-tzo")) { + } else if (mime->is("application/x-tar") || + mime->is("application/x-tarz") || + mime->is("application/x-bzip-compressed-tar") || + mime->is("application/x-compressed-tar") || + mime->is("application/x-tzo")) { url.setProtocol("tar"); setUrl(url); - } - else { + } else { item->run(); } - } - else { + } else { item->run(); } } @@ -717,8 +723,7 @@ void DolphinView::updateItemCount() KFileItem* item = *it; if (item->isDir()) { ++m_folderCount; - } - else { + } else { ++m_fileCount; } ++it; @@ -726,6 +731,7 @@ void DolphinView::updateItemCount() updateStatusBar(); + m_blockContentsMovedSignal = false; QTimer::singleShot(0, this, SLOT(restoreContentsPos())); } @@ -736,11 +742,6 @@ void DolphinView::generatePreviews(const KFileItemList& items) connect(job, SIGNAL(gotPreview(const KFileItem*, const QPixmap&)), this, SLOT(showPreview(const KFileItem*, const QPixmap&))); } - - const QMimeData* mimeData = QApplication::clipboard()->mimeData(); - if (KonqMimeData::decodeIsCutSelection(mimeData)) { - QTimer::singleShot(0, this, SLOT(applyCutEffect())); - } } void DolphinView::showPreview(const KFileItem* item, const QPixmap& pixmap) @@ -751,27 +752,23 @@ void DolphinView::showPreview(const KFileItem* item, const QPixmap& pixmap) const QMimeData* mimeData = QApplication::clipboard()->mimeData(); if (KonqMimeData::decodeIsCutSelection(mimeData) && isCutItem(*item)) { KIconEffect iconEffect; - QPixmap cutPixmap = iconEffect.apply(pixmap, K3Icon::Desktop, K3Icon::DisabledState); - m_dirModel->setData(idx, cutPixmap, Qt::DecorationRole); - } - else { - m_dirModel->setData(idx, pixmap, Qt::DecorationRole); + const QPixmap cutPixmap = iconEffect.apply(pixmap, K3Icon::Desktop, K3Icon::DisabledState); + m_dirModel->setData(idx, QIcon(cutPixmap), Qt::DecorationRole); + } else { + m_dirModel->setData(idx, QIcon(pixmap), Qt::DecorationRole); } } } void DolphinView::restoreContentsPos() { - int index = 0; - const QLinkedList history = urlHistory(index); - if (!history.isEmpty()) { + KUrl currentUrl = m_urlNavigator->url(); + if (!currentUrl.isEmpty()) { QAbstractItemView* view = itemView(); - // TODO: view->setCurrentItem(history[index].currentFileName()); - - QLinkedList::const_iterator it = history.begin(); - it += index; - view->horizontalScrollBar()->setValue((*it).contentsX()); - view->verticalScrollBar()->setValue((*it).contentsY()); + // TODO: view->setCurrentItem(m_urlNavigator->currentFileName()); + QPoint pos = m_urlNavigator->savedPosition(); + view->horizontalScrollBar()->setValue(pos.x()); + view->verticalScrollBar()->setValue(pos.y()); } } @@ -787,7 +784,7 @@ void DolphinView::showErrorMessage(const QString& msg) void DolphinView::emitSelectionChangedSignal() { - emit selectionChanged(); + emit selectionChanged(DolphinView::selectedItems()); } void DolphinView::closeFilterBar() @@ -802,9 +799,8 @@ void DolphinView::startDirLister(const KUrl& url, bool reload) const QString location(url.pathOrUrl()); if (location.isEmpty()) { m_statusBar->setMessage(i18n("The location is empty."), DolphinStatusBar::Error); - } - else { - m_statusBar->setMessage(i18n("The location '%1' is invalid.",location), + } else { + m_statusBar->setMessage(i18n("The location '%1' is invalid.", location), DolphinStatusBar::Error); } return; @@ -821,8 +817,44 @@ void DolphinView::startDirLister(const KUrl& url, bool reload) m_statusBar->setProgress(0); } + m_cutItemsCache.clear(); + m_blockContentsMovedSignal = true; m_dirLister->stop(); - m_dirLister->openUrl(url, false, reload); + + bool openDir = true; + bool keepOldDirs = isColumnViewActive(); + if (keepOldDirs) { + if (reload) { + keepOldDirs = false; + + const KUrl& dirListerUrl = m_dirLister->url(); + if (dirListerUrl.isValid()) { + const KUrl::List dirs = m_dirLister->directories(); + KUrl url; + foreach(url, dirs) { + m_dirLister->updateDirectory(url); + } + openDir = false; + } + } else if (m_dirLister->directories().contains(url)) { + // The dir lister contains the directory already, so + // KDirLister::openUrl() may not been invoked twice. + m_dirLister->updateDirectory(url); + openDir = false; + } 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 bookmark has been selected + // and hence the view must be reset. + keepOldDirs = false; + } + } + } + + if (openDir) { + m_dirLister->openUrl(url, keepOldDirs, reload); + } } QString DolphinView::defaultStatusBarText() const @@ -848,12 +880,11 @@ QString DolphinView::selectionStatusBarText() const KIO::filesize_t byteSize = 0; KFileItemList::const_iterator it = list.begin(); const KFileItemList::const_iterator end = list.end(); - while (it != end){ + while (it != end) { KFileItem* item = *it; if (item->isDir()) { ++folderCount; - } - else { + } else { ++fileCount; byteSize += item->size(); } @@ -880,8 +911,7 @@ void DolphinView::showFilterBar(bool show) Q_ASSERT(m_filterBar != 0); if (show) { m_filterBar->show(); - } - else { + } else { m_filterBar->hide(); } } @@ -914,29 +944,25 @@ void DolphinView::requestActivation() m_mainWindow->setActiveView(this); } -void DolphinView::updateCutItems() +void DolphinView::changeSelection(const KFileItemList& selection) { - const QMimeData* mimeData = QApplication::clipboard()->mimeData(); - if (!KonqMimeData::decodeIsCutSelection(mimeData)) { + clearSelection(); + if (selection.isEmpty()) { return; } - - KFileItemList items(m_dirLister->items()); - KFileItemList::const_iterator it = items.begin(); - const KFileItemList::const_iterator end = items.end(); - while (it != end) { - KFileItem* item = *it; - if (isCutItem(*item)) { - QPixmap pixmap = item->pixmap(0); - KIconEffect iconEffect; - pixmap = iconEffect.apply(pixmap, K3Icon::Desktop, K3Icon::DisabledState); - const QModelIndex idx = m_dirModel->indexForItem(*item); - if (idx.isValid()) { - m_dirModel->setData(idx, pixmap, Qt::DecorationRole); - } + KUrl baseUrl = url(); + KUrl url; + QItemSelection new_selection; + foreach(KFileItem* item, selection) { + url = item->url().upUrl(); + if (baseUrl.equals(url, KUrl::CompareWithoutTrailingSlash)) { + QModelIndex index = m_proxyModel->mapFromSource(m_dirModel->indexForItem(*item)); + new_selection.select(index, index); } - ++it; } + itemView()->selectionModel()->select(new_selection, + QItemSelectionModel::ClearAndSelect + | QItemSelectionModel::Current); } void DolphinView::changeNameFilter(const QString& nameFilter) @@ -960,7 +986,7 @@ void DolphinView::changeNameFilter(const QString& nameFilter) m_dirLister->setNameFilter(adjustedFilter); m_dirLister->emitChanges(); #else - m_proxyModel->setFilterRegExp( nameFilter ); + m_proxyModel->setFilterRegExp(nameFilter); #endif } @@ -973,10 +999,7 @@ void DolphinView::openContextMenu(const QPoint& pos) item = fileItem(index); } - DolphinContextMenu contextMenu(m_mainWindow, - item, - url(), - selectedItems()); + DolphinContextMenu contextMenu(m_mainWindow, item, url()); contextMenu.open(); } @@ -1001,10 +1024,7 @@ void DolphinView::dropUrls(const KUrl::List& urls, } const KUrl& destination = (directory == 0) ? url() : - directory->url(); - - kDebug() << "DolphinView::dropUrls() - destination: " << destination.prettyUrl() << endl; - + directory->url(); dropUrls(urls, destination); } @@ -1014,7 +1034,6 @@ void DolphinView::dropUrls(const KUrl::List& urls, m_mainWindow->dropUrls(urls, destination); } - void DolphinView::updateSorting(DolphinView::Sorting sorting) { ViewProperties props(url()); @@ -1037,12 +1056,37 @@ void DolphinView::updateSortOrder(Qt::SortOrder order) void DolphinView::emitContentsMoved() { - emit contentsMoved(contentsX(), contentsY()); + if (!m_blockContentsMovedSignal) { + emit contentsMoved(contentsX(), contentsY()); + } } void DolphinView::updateActivationState() { m_urlNavigator->setActive(isActive()); + if (isActive()) { + emit urlChanged(url()); + emit selectionChanged(selectedItems()); + } +} + +void DolphinView::updateCutItems() +{ + // restore the icons of all previously selected items to the + // original state... + QList::const_iterator it = m_cutItemsCache.begin(); + QList::const_iterator end = m_cutItemsCache.end(); + while (it != end) { + const QModelIndex index = m_dirModel->indexForUrl((*it).url); + if (index.isValid()) { + m_dirModel->setData(index, QIcon((*it).pixmap), Qt::DecorationRole); + } + ++it; + } + m_cutItemsCache.clear(); + + // ... and apply an item effect to all currently cut items + applyCutItemEffect(); } void DolphinView::createView() @@ -1056,23 +1100,30 @@ void DolphinView::createView() view = 0; m_iconsView = 0; m_detailsView = 0; + m_columnView = 0; m_fileItemDelegate = 0; } Q_ASSERT(m_iconsView == 0); Q_ASSERT(m_detailsView == 0); + Q_ASSERT(m_columnView == 0); // ... and recreate it representing the current mode switch (m_mode) { - case IconsView: - m_iconsView = new DolphinIconsView(this, m_controller); - view = m_iconsView; - break; - - case DetailsView: - m_detailsView = new DolphinDetailsView(this, m_controller); - view = m_detailsView; - break; + case IconsView: + m_iconsView = new DolphinIconsView(this, m_controller); + view = m_iconsView; + break; + + case DetailsView: + m_detailsView = new DolphinDetailsView(this, m_controller); + view = m_detailsView; + break; + + case ColumnView: + m_columnView = new DolphinColumnView(this, m_controller); + view = m_columnView; + break; } Q_ASSERT(view != 0); @@ -1101,7 +1152,7 @@ void DolphinView::selectAll(QItemSelectionModel::SelectionFlags flags) const QModelIndex topLeft = itemModel->index(0, 0); const QModelIndex bottomRight = itemModel->index(itemModel->rowCount() - 1, - itemModel->columnCount() - 1); + itemModel->columnCount() - 1); QItemSelection selection(topLeft, bottomRight); selectionModel->select(selection, flags); @@ -1109,10 +1160,12 @@ void DolphinView::selectAll(QItemSelectionModel::SelectionFlags flags) QAbstractItemView* DolphinView::itemView() const { - Q_ASSERT((m_iconsView == 0) || (m_detailsView == 0)); if (m_detailsView != 0) { return m_detailsView; + } else if (m_columnView != 0) { + return m_columnView; } + return m_iconsView; } @@ -1129,7 +1182,7 @@ bool DolphinView::isCutItem(const KFileItem& item) const const KUrl& itemUrl = item.url(); KUrl::List::const_iterator it = cutUrls.begin(); const KUrl::List::const_iterator end = cutUrls.end(); - while (it != end){ + while (it != end) { if (*it == itemUrl) { return true; } @@ -1139,4 +1192,41 @@ bool DolphinView::isCutItem(const KFileItem& item) const return false; } +void DolphinView::applyCutItemEffect() +{ + const QMimeData* mimeData = QApplication::clipboard()->mimeData(); + if (!KonqMimeData::decodeIsCutSelection(mimeData)) { + return; + } + + KFileItemList items(m_dirLister->items()); + 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_dirModel->indexForItem(*item); + const KFileItem* item = m_dirModel->itemForIndex(index); + const QVariant value = m_dirModel->data(index, Qt::DecorationRole); + if ((value.type() == QVariant::Icon) && (item != 0)) { + const QIcon icon(qvariant_cast(value)); + QPixmap pixmap = icon.pixmap(128, 128); + + // remember current pixmap for the item to be able + // to restore it when other items get cut + CutItem cutItem; + 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); + m_dirModel->setData(index, QIcon(pixmap), Qt::DecorationRole); + } + } + ++it; + } +} + #include "dolphinview.moc"