X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/652d08c9242ed51d86dba3b2afda9d3b2e9a9cd7..39f89141b06c:/src/views/dolphinview.cpp diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp index 73a0c63c3..346c7b691 100644 --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -45,7 +45,6 @@ #include #include #include -#include #include #include @@ -55,7 +54,7 @@ #include "dolphinviewcontroller.h" #include "dolphindetailsview.h" #include "dolphinfileitemdelegate.h" -#include "dolphinnewmenuobserver.h" +#include "dolphinnewfilemenuobserver.h" #include "dolphinsortfilterproxymodel.h" #include "dolphin_detailsmodesettings.h" #include "dolphiniconsview.h" @@ -68,15 +67,6 @@ #include "zoomlevelinfo.h" #include "dolphindetailsviewexpander.h" -/** - * Helper function for sorting items with qSort() in - * DolphinView::renameSelectedItems(). - */ -bool lessThan(const KFileItem& item1, const KFileItem& item2) -{ - return KStringHandler::naturalCompare(item1.name(), item2.name()) < 0; -} - DolphinView::DolphinView(QWidget* parent, const KUrl& url, DolphinSortFilterProxyModel* proxyModel) : @@ -86,14 +76,12 @@ DolphinView::DolphinView(QWidget* parent, m_storedCategorizedSorting(false), m_tabsForFiles(false), m_isContextMenuOpen(false), - m_ignoreViewProperties(false), m_assureVisibleCurrentIndex(false), m_mode(DolphinView::IconsView), m_topLayout(0), m_dolphinViewController(0), m_viewModeController(0), m_viewAccessor(proxyModel), - m_selectionModel(0), m_selectionChangedTimer(0), m_rootUrl(), m_activeItemUrl(), @@ -150,7 +138,7 @@ DolphinView::DolphinView(QWidget* parent, // When a new item has been created by the "Create New..." menu, the item should // get selected and it must be assured that the item will get visible. As the // creation is done asynchronously, several signals must be checked: - connect(&DolphinNewMenuObserver::instance(), SIGNAL(itemCreated(const KUrl&)), + connect(&DolphinNewFileMenuObserver::instance(), SIGNAL(itemCreated(const KUrl&)), this, SLOT(observeCreatedItem(const KUrl&))); m_selectionChangedTimer = new QTimer(this); @@ -326,16 +314,6 @@ KFileItemList DolphinView::selectedItems() const return itemList; } -KUrl::List DolphinView::selectedUrls() const -{ - KUrl::List urls; - const KFileItemList list = selectedItems(); - foreach (const KFileItem &item, list) { - urls.append(item.url()); - } - return urls; -} - int DolphinView::selectedItemsCount() const { const QAbstractItemView* view = m_viewAccessor.itemView(); @@ -439,10 +417,13 @@ void DolphinView::reload() restoreState(restoreStream); } -void DolphinView::refresh() +void DolphinView::stopLoading() { - m_ignoreViewProperties = false; + m_viewAccessor.dirLister()->stop(); +} +void DolphinView::refresh() +{ const bool oldActivationState = m_active; const int oldZoomLevel = m_viewModeController->zoomLevel(); m_active = true; @@ -540,29 +521,36 @@ QList DolphinView::versionControlActions(const KFileItemList& items) c void DolphinView::setUrl(const KUrl& url) { - if (m_viewModeController->url() != url) { - m_newFileNames.clear(); + if (m_viewModeController->url() == url) { + return; + } - m_viewModeController->setUrl(url); // emits urlChanged, which we forward - m_viewAccessor.prepareUrlChange(url); - applyViewProperties(); - loadDirectory(url); + // The selection model might change in the case of the column view. Disconnect + // from the current selection model and reconnect later after the URL switch. + const bool hadSelection = hasSelection(); + QAbstractItemView* view = m_viewAccessor.itemView(); + disconnect(view->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), + this, SLOT(slotSelectionChanged(QItemSelection, QItemSelection))); - // When changing the URL there is no need to keep the version - // data of the previous URL. - m_viewAccessor.dirModel()->clearVersionData(); + m_newFileNames.clear(); - emit startedPathLoading(url); - } + m_viewModeController->setUrl(url); // emits urlChanged, which we forward + m_viewAccessor.prepareUrlChange(url); + applyViewProperties(); + loadDirectory(url); - // the selection model might have changed in the case of a column view - QItemSelectionModel* selectionModel = m_viewAccessor.itemView()->selectionModel(); - if (m_selectionModel != selectionModel) { - disconnect(m_selectionModel, SIGNAL(selectionChanged(QItemSelection, QItemSelection)), - this, SLOT(slotSelectionChanged(QItemSelection, QItemSelection))); - m_selectionModel = selectionModel; - connect(m_selectionModel, SIGNAL(selectionChanged(QItemSelection, QItemSelection)), - this, SLOT(slotSelectionChanged(QItemSelection, QItemSelection))); + // When changing the URL there is no need to keep the version + // data of the previous URL. + m_viewAccessor.dirModel()->clearVersionData(); + + emit startedPathLoading(url); + + // Reconnect to the (probably) new selection model + view = m_viewAccessor.itemView(); + connect(view->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), + this, SLOT(slotSelectionChanged(QItemSelection, QItemSelection))); + if (hadSelection || hasSelection()) { + emitSelectionChangedSignal(); } } @@ -597,82 +585,17 @@ void DolphinView::renameSelectedItems() return; } - if (itemCount > 1) { - // More than one item has been selected for renaming. Open - // a rename dialog and rename all items afterwards. - QPointer dialog = new RenameDialog(this, items); - if (dialog->exec() == QDialog::Rejected) { - delete dialog; - return; - } - - const QString newName = dialog->newName(); - if (newName.isEmpty()) { - emit errorMessage(dialog->errorString()); - delete dialog; - return; - } - delete dialog; - - // the selection would be invalid after renaming the items, so just clear - // it before - clearSelection(); - - // 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('#')); - - // currently the items are sorted by the selection order, resort - // them by the file name - qSort(items.begin(), items.end(), lessThan); - - // iterate through all selected items and rename them... - int index = 1; - foreach (const KFileItem& item, items) { - const KUrl& oldUrl = item.url(); - QString number; - number.setNum(index++); - - QString name = newName; - name.replace('#', number); - - if (oldUrl.fileName() != name) { - KUrl newUrl = oldUrl; - newUrl.setFileName(name); - KonqOperations::rename(this, oldUrl, newUrl); - } - } - } else if (DolphinSettings::instance().generalSettings()->renameInline()) { - Q_ASSERT(itemCount == 1); + if ((itemCount == 1) && DolphinSettings::instance().generalSettings()->renameInline()) { const QModelIndex dirIndex = m_viewAccessor.dirModel()->indexForItem(items.first()); const QModelIndex proxyIndex = m_viewAccessor.proxyModel()->mapFromSource(dirIndex); m_viewAccessor.itemView()->edit(proxyIndex); } else { - Q_ASSERT(itemCount == 1); - - QPointer dialog = new RenameDialog(this, items); - if (dialog->exec() == QDialog::Rejected) { - delete dialog; - return; - } - - const QString newName = dialog->newName(); - if (newName.isEmpty()) { - emit errorMessage(dialog->errorString()); - delete dialog; - return; - } - delete dialog; - - const KUrl& oldUrl = items.first().url(); - KUrl newUrl = oldUrl; - newUrl.setFileName(newName); - KonqOperations::rename(this, oldUrl, newUrl); + RenameDialog* dialog = new RenameDialog(this, items); + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->show(); + dialog->raise(); + dialog->activateWindow(); } - - // assure that the current index remains visible when KDirLister - // will notify the view about changed items - m_assureVisibleCurrentIndex = true; } void DolphinView::trashSelectedItems() @@ -776,40 +699,6 @@ void DolphinView::setCategorizedSorting(bool categorized) emit categorizedSortingChanged(); } -void DolphinView::toggleSortOrder() -{ - const Qt::SortOrder order = (sortOrder() == Qt::AscendingOrder) ? - Qt::DescendingOrder : - Qt::AscendingOrder; - setSortOrder(order); -} - -void DolphinView::toggleSortFoldersFirst() -{ - setSortFoldersFirst(!sortFoldersFirst()); -} - -void DolphinView::toggleAdditionalInfo(QAction* action) -{ - const KFileItemDelegate::Information info = - static_cast(action->data().toInt()); - - KFileItemDelegate::InformationList list = additionalInfo(); - - const bool show = action->isChecked(); - - const int index = list.indexOf(info); - const bool containsInfo = (index >= 0); - if (show && !containsInfo) { - list.append(info); - setAdditionalInfo(list); - } else if (!show && containsInfo) { - list.removeAt(index); - setAdditionalInfo(list); - Q_ASSERT(list.indexOf(info) < 0); - } -} - void DolphinView::mouseReleaseEvent(QMouseEvent* event) { QWidget::mouseReleaseEvent(event); @@ -903,7 +792,8 @@ void DolphinView::slotSelectionChanged(const QItemSelection& selected, const QIt void DolphinView::emitSelectionChangedSignal() { - emit selectionChanged(DolphinView::selectedItems()); + m_selectionChangedTimer->stop(); + emit selectionChanged(selectedItems()); } void DolphinView::openContextMenu(const QPoint& pos, @@ -974,18 +864,18 @@ void DolphinView::updateAdditionalInfoActions(KActionCollection* collection) { const AdditionalInfoAccessor& infoAccessor = AdditionalInfoAccessor::instance(); - const KFileItemDelegate::InformationList checkedInfos = m_viewAccessor.itemDelegate()->showInformation(); - const KFileItemDelegate::InformationList infos = infoAccessor.keys(); + const KFileItemDelegate::InformationList checkedInfo = m_viewAccessor.itemDelegate()->showInformation(); + const KFileItemDelegate::InformationList infoKeys = infoAccessor.keys(); const bool enable = (m_mode == DolphinView::DetailsView) || (m_mode == DolphinView::IconsView); - foreach (const KFileItemDelegate::Information& info, infos) { + foreach (const KFileItemDelegate::Information& info, infoKeys) { const QString name = infoAccessor.actionCollectionName(info, AdditionalInfoAccessor::AdditionalInfoType); QAction* action = collection->action(name); Q_ASSERT(action != 0); action->setEnabled(enable); - action->setChecked(checkedInfos.contains(info)); + action->setChecked(checkedInfo.contains(info)); } } @@ -1162,6 +1052,8 @@ void DolphinView::slotLoadingCompleted() // 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); + + emit finishedPathLoading(url()); } void DolphinView::slotRefreshItems() @@ -1190,10 +1082,6 @@ void DolphinView::loadDirectory(const KUrl& url, bool reload) void DolphinView::applyViewProperties() { - if (m_ignoreViewProperties) { - return; - } - const ViewProperties props(rootUrl()); const Mode mode = props.viewMode(); @@ -1260,13 +1148,6 @@ void DolphinView::applyViewProperties() // the used zoom level of the controller must be adjusted manually: updateZoomLevel(oldZoomLevel); } - - if (DolphinSettings::instance().generalSettings()->globalViewProps()) { - // During the lifetime of a DolphinView instance the global view properties - // should not be changed. This allows e. g. to split a view and use different - // view properties for each view. - m_ignoreViewProperties = true; - } } void DolphinView::createView() @@ -1274,6 +1155,7 @@ void DolphinView::createView() deleteView(); Q_ASSERT(m_viewAccessor.itemView() == 0); + Q_ASSERT(m_dolphinViewController->itemView() == 0); m_viewAccessor.createView(this, m_dolphinViewController, m_viewModeController, m_mode); QAbstractItemView* view = m_viewAccessor.itemView(); @@ -1283,16 +1165,10 @@ void DolphinView::createView() m_dolphinViewController->setItemView(view); - // 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(m_selectionModel, SIGNAL(selectionChanged(QItemSelection, QItemSelection)), + const int zoomLevel = ZoomLevelInfo::zoomLevelForIconSize(view->iconSize()); + m_viewModeController->setZoomLevel(zoomLevel); + + connect(view->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(slotSelectionChanged(QItemSelection, QItemSelection))); setFocusProxy(m_viewAccessor.layoutTarget()); @@ -1302,7 +1178,15 @@ void DolphinView::createView() void DolphinView::deleteView() { QAbstractItemView* view = m_viewAccessor.itemView(); + Q_ASSERT((m_dolphinViewController->itemView() == 0) || (m_dolphinViewController->itemView() == view)); + m_dolphinViewController->setItemView(0); + if (view != 0) { + if (view->selectionModel() != 0) { + disconnect(view->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), + this, SLOT(slotSelectionChanged(QItemSelection, QItemSelection))); + } + // 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 @@ -1310,13 +1194,7 @@ void DolphinView::deleteView() setFocusProxy(0); setFocus(); - m_topLayout->removeWidget(view); - view->close(); - - // disconnect all signal/slots - disconnect(view); m_viewModeController->disconnect(view); - view->disconnect(); m_viewAccessor.deleteView(); } @@ -1339,11 +1217,19 @@ void DolphinView::updateZoomLevel(int oldZoomLevel) KUrl::List DolphinView::simplifiedSelectedUrls() const { - KUrl::List list = selectedUrls(); - if (itemsExpandable() ) { - list = KDirModel::simplifiedUrlList(list); + KUrl::List urls; + + const KFileItemList items = selectedItems(); + foreach (const KFileItem &item, items) { + urls.append(item.url()); + } + + + if (itemsExpandable()) { + urls = KDirModel::simplifiedUrlList(urls); } - return list; + + return urls; } QMimeData* DolphinView::selectionMimeData() const @@ -1412,32 +1298,38 @@ void DolphinView::ViewAccessor::createView(QWidget* parent, void DolphinView::ViewAccessor::deleteView() { - 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; + if (m_columnsContainer != 0) { + m_columnsContainer->close(); + m_columnsContainer->disconnect(); + m_columnsContainer->deleteLater(); + m_columnsContainer = 0; + } else { + QAbstractItemView* view = itemView(); + if (view != 0) { + view->close(); + view->disconnect(); + + 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(); + view = 0; } - view->hide(); - m_dragSource = view; - } else { - view->deleteLater(); } - } - - m_iconsView = 0; - m_detailsView = 0; - if (m_columnsContainer != 0) { - m_columnsContainer->deleteLater(); + m_iconsView = 0; + m_detailsView = 0; } - m_columnsContainer = 0; }