]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/views/dolphinview.cpp
Bug 196035 - middle clicking on archive files in dolphin does not open them in a...
[dolphin.git] / src / views / dolphinview.cpp
index 57c94a33befc59821bc37e912226d199dba5cfc5..6fadaa85c58f7777d19f64f2beebfcb77826875e 100644 (file)
@@ -33,6 +33,8 @@
 #include <QTimer>
 #include <QScrollBar>
 
+#include <KDesktopFile>
+#include <KProtocolManager>
 #include <KActionCollection>
 #include <KColorScheme>
 #include <KDirModel>
@@ -102,6 +104,7 @@ DolphinView::DolphinView(const KUrl& url, QWidget* parent) :
     m_restoredContentsPosition(),
     m_selectedUrls(),
     m_clearSelectionBeforeSelectingNewItems(false),
+    m_markFirstNewlySelectedItemAsCurrent(false),
     m_versionControlObserver(0)
 {
     m_topLayout = new QVBoxLayout(this);
@@ -343,10 +346,12 @@ int DolphinView::itemsCount() const
 KFileItemList DolphinView::selectedItems() const
 {
     const KItemListSelectionManager* selectionManager = m_container->controller()->selectionManager();
-    const QSet<int> selectedIndexes = selectionManager->selectedItems();
+    QList<int> selectedIndexes = selectionManager->selectedItems().toList();
+
+    qSort(selectedIndexes);
 
     KFileItemList selectedItems;
-    QSetIterator<int> it(selectedIndexes);
+    QListIterator<int> it(selectedIndexes);
     while (it.hasNext()) {
         const int index = it.next();
         selectedItems.append(m_model->fileItem(index));
@@ -792,35 +797,44 @@ void DolphinView::slotItemsActivated(const QSet<int>& indexes)
 {
     Q_ASSERT(indexes.count() >= 2);
 
+    if (indexes.count() > 5) {
+        QString question = i18np("Are you sure you want to open 1 item?", "Are you sure you want to open %1 items?", indexes.count());
+        const int answer = KMessageBox::warningYesNo(this, question);
+        if (answer != KMessageBox::Yes) {
+            return;
+        }
+    }
+
     KFileItemList items;
+    items.reserve(indexes.count());
 
     QSetIterator<int> it(indexes);
     while (it.hasNext()) {
         const int index = it.next();
-        items.append(m_model->fileItem(index));
-    }
+        KFileItem item = m_model->fileItem(index);
+        const KUrl& url = openItemAsFolderUrl(item);
 
-    if (items.count() > 5) {
-        QString question = i18np("Are you sure you want to open 1 item?", "Are you sure you want to open %1 items?", items.count());
-        const int answer = KMessageBox::warningYesNo(this, question);
-        if (answer != KMessageBox::Yes) {
-            return;
+        if (!url.isEmpty()) { // Open folders in new tabs
+            emit tabRequested(url);
+        } else {
+            items.append(item);
         }
     }
 
-    foreach (const KFileItem& item, items) {
-        if (item.isDir()) {
-            emit tabRequested(item.url());
-        } else {
-            emit itemActivated(item);
-        }
+    if (items.count() == 1) {
+        emit itemActivated(items.first());
+    } else if (items.count() > 1) {
+        emit itemsActivated(items);
     }
 }
 
 void DolphinView::slotItemMiddleClicked(int index)
 {
-    const KFileItem item = m_model->fileItem(index);
-    if (item.isDir() || isTabsForFilesEnabled()) {
+    const KFileItem& item = m_model->fileItem(index);
+    const KUrl& url = openItemAsFolderUrl(item);
+    if (!url.isEmpty()) {
+        emit tabRequested(url);
+    } else if (isTabsForFilesEnabled()) {
         emit tabRequested(item.url());
     }
 }
@@ -1016,14 +1030,16 @@ void DolphinView::slotItemDropEvent(int index, QGraphicsSceneDragDropEvent* even
                          event->buttons(),
                          event->modifiers());
 
-    const QString error = DragAndDropHelper::dropUrls(destItem, destUrl, &dropEvent);
+    QString error;
+    KonqOperations* op = DragAndDropHelper::dropUrls(destItem, destUrl, &dropEvent, error);
     if (!error.isEmpty()) {
-        emit errorMessage(error);
+        emit infoMessage(error);
     }
 
-    if (destUrl == url()) {
+    if (op && destUrl == url()) {
         // Mark the dropped urls as selected.
-        markPastedUrlsAsSelected(event->mimeData());
+        m_clearSelectionBeforeSelectingNewItems = true;
+        connect(op, SIGNAL(urlPasted(KUrl)), this, SLOT(slotUrlPasted(KUrl)));
     }
 }
 
@@ -1059,6 +1075,17 @@ void DolphinView::slotMouseButtonPressed(int itemIndex, Qt::MouseButtons buttons
     }
 }
 
+void DolphinView::slotAboutToCreate(const KUrl::List& urls)
+{
+    if (!urls.isEmpty()) {
+        if (m_markFirstNewlySelectedItemAsCurrent) {
+            markUrlAsCurrent(urls.first());
+            m_markFirstNewlySelectedItemAsCurrent = false;
+        }
+        m_selectedUrls << urls;
+    }
+}
+
 void DolphinView::slotSelectionChanged(const QSet<int>& current, const QSet<int>& previous)
 {
     const int currentCount = current.count();
@@ -1181,6 +1208,46 @@ QString DolphinView::viewPropertiesContext() const
     return m_viewPropertiesContext;
 }
 
+KUrl DolphinView::openItemAsFolderUrl(const KFileItem& item, const bool browseThroughArchives)
+{
+    if (item.isNull()) {
+        return KUrl();
+    }
+
+    KUrl url = item.targetUrl();
+
+    if (item.isDir()) {
+        return url;
+    }
+
+    if (item.isMimeTypeKnown()) {
+        const QString& mimetype = item.mimetype();
+
+        if (browseThroughArchives && item.isFile() && url.isLocalFile()) {
+            // Generic mechanism for redirecting to tar:/<path>/ when clicking on a tar file,
+            // zip:/<path>/ when clicking on a zip file, etc.
+            // The .protocol file specifies the mimetype that the kioslave handles.
+            // Note that we don't use mimetype inheritance since we don't want to
+            // open OpenDocument files as zip folders...
+            const QString& protocol = KProtocolManager::protocolForArchiveMimetype(mimetype);
+            if (!protocol.isEmpty()) {
+                url.setProtocol(protocol);
+                return url;
+            }
+        }
+
+        if (mimetype == QLatin1String("application/x-desktop")) {
+            // Redirect to the URL in Type=Link desktop files
+            KDesktopFile desktopFile(url.toLocalFile());
+            if (desktopFile.hasLinkType()) {
+                return desktopFile.readUrl();
+            }
+        }
+    }
+
+    return KUrl();
+}
+
 void DolphinView::observeCreatedItem(const KUrl& url)
 {
     if (m_active) {
@@ -1211,10 +1278,11 @@ void DolphinView::updateViewState()
                 m_view->scrollToItem(currentIndex);
                 m_scrollToCurrentItem = false;
             }
+
+            m_currentItemUrl = KUrl();
         } else {
             selectionManager->setCurrentItem(0);
         }
-        m_currentItemUrl = KUrl();
     }
 
     if (!m_restoredContentsPosition.isNull()) {
@@ -1516,8 +1584,12 @@ void DolphinView::applyModeToView()
 
 void DolphinView::pasteToUrl(const KUrl& url)
 {
-    markPastedUrlsAsSelected(QApplication::clipboard()->mimeData());
-    KonqOperations::doPaste(this, url);
+    KonqOperations* op = KonqOperations::doPasteV2(this, url);
+    if (op) {
+        m_clearSelectionBeforeSelectingNewItems = true;
+        m_markFirstNewlySelectedItemAsCurrent = true;
+        connect(op, SIGNAL(aboutToCreate(KUrl::List)), this, SLOT(slotAboutToCreate(KUrl::List)));
+    }
 }
 
 KUrl::List DolphinView::simplifiedSelectedUrls() const
@@ -1545,18 +1617,6 @@ QMimeData* DolphinView::selectionMimeData() const
     return m_model->createMimeData(selectedIndexes);
 }
 
-void DolphinView::markPastedUrlsAsSelected(const QMimeData* mimeData)
-{
-    const KUrl::List sourceUrls = KUrl::List::fromMimeData(mimeData);
-    KUrl::List destUrls;
-    foreach (const KUrl& source, sourceUrls) {
-        KUrl destination(url().url() + '/' + source.fileName());
-        destUrls << destination;
-    }
-    markUrlsAsSelected(destUrls);
-    m_clearSelectionBeforeSelectingNewItems = true;
-}
-
 void DolphinView::updateWritableState()
 {
     const bool wasFolderWritable = m_isFolderWritable;