]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/dolphinview.cpp
Patch by Luca Gugelmann: get rid of any mainwindow dependency from the sidebars.
[dolphin.git] / src / dolphinview.cpp
index 6569530cea1fc6705a2b5f100c1d7bf6fa0db836..99757bac7510015391bd6c6bc5340e34b847a258 100644 (file)
@@ -20,8 +20,6 @@
 
 #include "dolphinview.h"
 
-#include <assert.h>
-
 #include <QApplication>
 #include <QClipboard>
 #include <QDropEvent>
@@ -61,6 +59,7 @@ DolphinView::DolphinView(DolphinMainWindow* mainWindow,
                          bool showHiddenFiles) :
     QWidget(parent),
     m_showProgress(false),
+    m_blockContentsMovedSignal(false),
     m_mode(mode),
     m_iconSize(0),
     m_folderCount(0),
@@ -87,6 +86,10 @@ DolphinView::DolphinView(DolphinMainWindow* mainWindow,
     connect(m_mainWindow, SIGNAL(activeViewChanged()),
             this, SLOT(updateActivationState()));
 
+    QClipboard* clipboard = QApplication::clipboard();
+    connect(clipboard, SIGNAL(dataChanged()),
+            this, SLOT(updateCutItems()));
+
     m_urlNavigator = new UrlNavigator(url, this);
     m_urlNavigator->setShowHiddenFiles(showHiddenFiles);
     connect(m_urlNavigator, SIGNAL(urlChanged(const KUrl&)),
@@ -161,8 +164,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()
@@ -250,6 +251,7 @@ bool DolphinView::showHiddenFiles() const
 
 void DolphinView::renameSelectedItems()
 {
+    DolphinView* view = mainWindow()->activeView();
     const KUrl::List urls = selectedUrls();
     if (urls.count() > 1) {
         // More than one item has been selected for renaming. Open
@@ -259,80 +261,64 @@ void DolphinView::renameSelectedItems()
             return;
         }
 
-        DolphinView* view = mainWindow()->activeView();
         const QString& newName = dialog.newName();
         if (newName.isEmpty()) {
-            view->statusBar()->setMessage(i18n("The new item name is invalid."),
+            view->statusBar()->setMessage(dialog.errorString(),
                                           DolphinStatusBar::Error);
         }
         else {
             // TODO: check how this can be integrated into KonqUndoManager/KonqOperations
-
-            //UndoManager& undoMan = UndoManager::instance();
-            //undoMan.beginMacro();
-
-            assert(newName.contains('#'));
-
-            const int urlsCount = urls.count();
+            // 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...
             const int replaceIndex = newName.indexOf('#');
-            assert(replaceIndex >= 0);
-            for (int i = 0; i < urlsCount; ++i) {
-                const KUrl& source = urls[i];
+            Q_ASSERT(replaceIndex >= 0);
+            int index = 1;
+
+            KUrl::List::const_iterator it = urls.begin();
+            KUrl::List::const_iterator end = urls.end();
+            while (it != end) {
+                const KUrl& oldUrl = *it;
                 QString number;
-                number.setNum(i + 1);
+                number.setNum(index++);
 
                 QString name(newName);
                 name.replace(replaceIndex, 1, number);
 
-                if (source.fileName() != name) {
-                    KUrl dest(source.upUrl());
-                    dest.addPath(name);
-
-                    const bool destExists = KIO::NetAccess::exists(dest, false, view);
-                    if (destExists) {
-                        view->statusBar()->setMessage(i18n("Renaming failed (item '%1' already exists).",name),
-                                                      DolphinStatusBar::Error);
-                        break;
-                    }
-                    else if (KIO::NetAccess::file_move(source, dest)) {
-                        // TODO: From the users point of view he executed one 'rename n files' operation,
-                        // but internally we store it as n 'rename 1 file' operations for the undo mechanism.
-                        //DolphinCommand command(DolphinCommand::Rename, source, dest);
-                        //undoMan.addCommand(command);
-                    }
+                if (oldUrl.fileName() != name) {
+                    KUrl newUrl(oldUrl.upUrl());
+                    newUrl.addPath(name);
+                    m_mainWindow->rename(oldUrl, newUrl);
                 }
+                ++it;
             }
-
-            //undoMan.endMacro();
         }
     }
     else {
         // Only one item has been selected for renaming. Use the custom
         // renaming mechanism from the views.
-        assert(urls.count() == 1);
-        // TODO:
-        /*if (m_mode == DetailsView) {
-            Q3ListViewItem* item = m_iconsView->firstChild();
-            while (item != 0) {
-                if (item->isSelected()) {
-                    m_iconsView->rename(item, DolphinDetailsView::NameColumn);
-                    break;
-                }
-                item = item->nextSibling();
-            }
+        Q_ASSERT(urls.count() == 1);
+
+        // TODO: Think about using KFileItemDelegate as soon as it supports editing.
+        // Currently the RenameDialog is used, but I'm not sure whether inline renaming
+        // is a benefit for the user at all -> let's wait for some input first...
+        RenameDialog dialog(urls);
+        if (dialog.exec() == QDialog::Rejected) {
+            return;
+        }
+
+        const QString& newName = dialog.newName();
+        if (newName.isEmpty()) {
+            view->statusBar()->setMessage(dialog.errorString(),
+                                          DolphinStatusBar::Error);
         }
         else {
-            KFileIconViewItem* item = static_cast<KFileIconViewItem*>(m_iconsView->firstItem());
-            while (item != 0) {
-                if (item->isSelected()) {
-                    item->rename();
-                    break;
-                }
-                item = static_cast<KFileIconViewItem*>(item->nextItem());
-            }
-        }*/
+            const KUrl& oldUrl = urls.first();
+            KUrl newUrl = oldUrl.upUrl();
+            newUrl.addPath(newName);
+            m_mainWindow->rename(oldUrl, newUrl);
+        }
     }
 }
 
@@ -477,6 +463,11 @@ bool DolphinView::hasSelection() const
     return itemView()->selectionModel()->hasSelection();
 }
 
+void DolphinView::clearSelection()
+{
+    itemView()->selectionModel()->clear();
+}
+
 KFileItemList DolphinView::selectedItems() const
 {
     const QAbstractItemView* view = itemView();
@@ -603,6 +594,10 @@ DolphinMainWindow* DolphinView::mainWindow() const
 
 void DolphinView::loadDirectory(const KUrl& url)
 {
+    if(!isActive()) {
+        requestActivation();
+    }
+
     const ViewProperties props(url);
 
     const Mode mode = props.viewMode();
@@ -687,14 +682,14 @@ void DolphinView::triggerItem(const QModelIndex& index)
     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-bzip-compressed-tar") ||
+                 mime->is("application/x-compressed-tar") ||
                  mime->is("application/x-tzo")) {
             url.setProtocol("tar");
             setUrl(url);
@@ -743,6 +738,7 @@ void DolphinView::updateItemCount()
 
     updateStatusBar();
 
+    m_blockContentsMovedSignal = false;
     QTimer::singleShot(0, this, SLOT(restoreContentsPos()));
 }
 
@@ -753,11 +749,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)
@@ -768,11 +759,11 @@ 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);
+            const QPixmap cutPixmap = iconEffect.apply(pixmap, K3Icon::Desktop, K3Icon::DisabledState);
+            m_dirModel->setData(idx, QIcon(cutPixmap), Qt::DecorationRole);
         }
         else {
-            m_dirModel->setData(idx, pixmap, Qt::DecorationRole);
+            m_dirModel->setData(idx, QIcon(pixmap), Qt::DecorationRole);
         }
     }
 }
@@ -804,7 +795,7 @@ void DolphinView::showErrorMessage(const QString& msg)
 
 void DolphinView::emitSelectionChangedSignal()
 {
-    emit selectionChanged();
+    emit selectionChanged(DolphinView::selectedItems());
 }
 
 void DolphinView::closeFilterBar()
@@ -838,6 +829,8 @@ 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);
 }
@@ -894,7 +887,7 @@ QString DolphinView::selectionStatusBarText() const
 
 void DolphinView::showFilterBar(bool show)
 {
-    assert(m_filterBar != 0);
+    Q_ASSERT(m_filterBar != 0);
     if (show) {
         m_filterBar->show();
     }
@@ -931,29 +924,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)
@@ -990,7 +979,7 @@ void DolphinView::openContextMenu(const QPoint& pos)
         item = fileItem(index);
     }
 
-    DolphinContextMenu contextMenu(this, item);
+    DolphinContextMenu contextMenu(m_mainWindow, item, url());
     contextMenu.open();
 }
 
@@ -1001,7 +990,7 @@ void DolphinView::dropUrls(const KUrl::List& urls,
     KFileItem* directory = 0;
     if (isValidNameIndex(index)) {
         KFileItem* item = fileItem(index);
-        assert(item != 0);
+        Q_ASSERT(item != 0);
         if (item->isDir()) {
             // the URLs are dropped above a directory
             directory = item;
@@ -1016,9 +1005,6 @@ void DolphinView::dropUrls(const KUrl::List& urls,
 
     const KUrl& destination = (directory == 0) ? url() :
                                                  directory->url();
-
-    kDebug() << "DolphinView::dropUrls() - destination: " << destination.prettyUrl() << endl;
-
     dropUrls(urls, destination);
 }
 
@@ -1028,7 +1014,6 @@ void DolphinView::dropUrls(const KUrl::List& urls,
     m_mainWindow->dropUrls(urls, destination);
 }
 
-
 void DolphinView::updateSorting(DolphinView::Sorting sorting)
 {
     ViewProperties props(url());
@@ -1051,12 +1036,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<CutItem>::const_iterator it = m_cutItemsCache.begin();
+    QList<CutItem>::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()
@@ -1073,8 +1083,8 @@ void DolphinView::createView()
         m_fileItemDelegate = 0;
     }
 
-    assert(m_iconsView == 0);
-    assert(m_detailsView == 0);
+    Q_ASSERT(m_iconsView == 0);
+    Q_ASSERT(m_detailsView == 0);
 
     // ... and recreate it representing the current mode
     switch (m_mode) {
@@ -1089,7 +1099,7 @@ void DolphinView::createView()
             break;
     }
 
-    assert(view != 0);
+    Q_ASSERT(view != 0);
 
     m_fileItemDelegate = new KFileItemDelegate(view);
     view->setItemDelegate(m_fileItemDelegate);
@@ -1153,4 +1163,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<QIcon>(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"