]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/dolphinmainwindow.cpp
allow to enable the categorization feature for sorting
[dolphin.git] / src / dolphinmainwindow.cpp
index dd985fc1d1c939dfb75b5c704ebcee00e6cce6c3..eed6da4ea74b26a8011ce6b3b7d1828ec4653cac 100644 (file)
  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
  ***************************************************************************/
 
+#include <config-kmetadata.h>
 #include "dolphinmainwindow.h"
 
-#include <assert.h>
+#include "dolphinapplication.h"
+#include "dolphinnewmenu.h"
+#include "dolphinsettings.h"
+#include "dolphinsettingsdialog.h"
+#include "dolphinstatusbar.h"
+#include "infosidebarpage.h"
+#include "metadatawidget.h"
+#include "mainwindowadaptor.h"
+#include "treeviewsidebarpage.h"
+#include "kurlnavigator.h"
+#include "viewpropertiesdialog.h"
+#include "viewproperties.h"
+#include "kfileplacesmodel.h"
+#include "kfileplacesview.h"
+
+#include "dolphin_generalsettings.h"
 
+#include <kaction.h>
 #include <kactioncollection.h>
-#include <ktoggleaction.h>
-#include <kbookmarkmanager.h>
+#include <kconfig.h>
+#include <kdesktopfile.h>
+#include <kdeversion.h>
+#include <kfiledialog.h>
 #include <kglobal.h>
-#include <kpropertiesdialog.h>
 #include <kicon.h>
 #include <kiconloader.h>
-#include <kdeversion.h>
-#include <kstatusbar.h>
 #include <kio/netaccess.h>
-#include <kfiledialog.h>
-#include <kconfig.h>
-#include <kurl.h>
-#include <kstdaccel.h>
-#include <kaction.h>
-#include <kstdaction.h>
-#include <kmenu.h>
-#include <kio/renamedlg.h>
+#include <kio/deletejob.h>
+#include <kio/renamedialog.h>
 #include <kinputdialog.h>
-#include <kshell.h>
-#include <kdesktopfile.h>
-#include <kstandarddirs.h>
-#include <kprotocolinfo.h>
+#include <klocale.h>
+#include <kmenu.h>
 #include <kmessagebox.h>
-#include <kservice.h>
-#include <kstandarddirs.h>
+#include <konqmimedata.h>
+#include <konq_operations.h>
+#include <kpropertiesdialog.h>
+#include <kprotocolinfo.h>
+#include <ktoggleaction.h>
 #include <krun.h>
-#include <klocale.h>
+#include <kshell.h>
+#include <kstandarddirs.h>
+#include <kstatusbar.h>
+#include <kstandardaction.h>
+#include <kurl.h>
 
-#include <qclipboard.h>
-#include <q3dragobject.h>
-//Added by qt3to4:
-#include <Q3ValueList>
 #include <QCloseEvent>
+#include <QClipboard>
 #include <QSplitter>
 #include <QDockWidget>
 
-#include "urlnavigator.h"
-#include "viewpropertiesdialog.h"
-#include "viewproperties.h"
-#include "dolphinsettings.h"
-#include "dolphinsettingsdialog.h"
-#include "dolphinstatusbar.h"
-#include "dolphinapplication.h"
-#include "undomanager.h"
-#include "progressindicator.h"
-#include "dolphinsettings.h"
-#include "bookmarkssidebarpage.h"
-#include "infosidebarpage.h"
-#include "generalsettings.h"
-#include "dolphinapplication.h"
-
-
-DolphinMainWindow::DolphinMainWindow() :
-    KMainWindow(0),
-    m_splitter(0),
-    m_activeView(0),
-    m_clipboardContainsCutData(false)
+DolphinMainWindow::DolphinMainWindow(int id) :
+        KMainWindow(0),
+        m_newMenu(0),
+        m_splitter(0),
+        m_activeView(0),
+        m_id(id)
 {
     setObjectName("Dolphin");
     m_view[PrimaryIdx] = 0;
     m_view[SecondaryIdx] = 0;
 
-    // TODO: the following members are not used yet. See documentation
-    // of DolphinMainWindow::linkGroupActions() and DolphinMainWindow::linkToDeviceActions()
-    // in the header file for details.
+    new MainWindowAdaptor(this);
+    QDBusConnection::sessionBus().registerObject(QString("/dolphin/MainWindow%1").arg(m_id), this);
+
+    KonqUndoManager::incRef();
+
+    KonqUndoManager* undoManager = KonqUndoManager::self();
+    undoManager->setUiInterface(new UndoUiInterface(this));
+
+    connect(undoManager, SIGNAL(undoAvailable(bool)),
+            this, SLOT(slotUndoAvailable(bool)));
+    connect(undoManager, SIGNAL(undoTextChanged(const QString&)),
+            this, SLOT(slotUndoTextChanged(const QString&)));
 }
 
 DolphinMainWindow::~DolphinMainWindow()
 {
-    qDeleteAll(m_fileGroupActions);
-    //qDeleteAll(m_linkToDeviceActions);
-    //qDeleteAll(m_linkGroupActions);
-    m_fileGroupActions.clear();
-    //m_linkGroupActions.clear();
-    //m_linkToDeviceActions.clear();
-
-    /*
-     * bye, bye managed window
-     */
-    DolphinApplication::app()->removeMainWindow( this );
+    KonqUndoManager::decRef();
+    DolphinApplication::app()->removeMainWindow(this);
 }
 
 void DolphinMainWindow::setActiveView(DolphinView* view)
 {
-    assert((view == m_view[PrimaryIdx]) || (view == m_view[SecondaryIdx]));
+    Q_ASSERT((view == m_view[PrimaryIdx]) || (view == m_view[SecondaryIdx]));
     if (m_activeView == view) {
         return;
     }
@@ -126,85 +123,93 @@ void DolphinMainWindow::setActiveView(DolphinView* view)
 }
 
 void DolphinMainWindow::dropUrls(const KUrl::List& urls,
-                       const KUrl& destination)
+                                 const KUrl& destination)
 {
-    int selectedIndex = -1;
-
-    /* KDE4-TODO
-    const ButtonState keyboardState = KApplication::keyboardMouseState();
-    const bool shiftPressed = (keyboardState & ShiftButton) > 0;
-    const bool controlPressed = (keyboardState & ControlButton) > 0;
-
-
+    Qt::DropAction action = Qt::CopyAction;
 
+    Qt::KeyboardModifiers modifier = QApplication::keyboardModifiers();
+    const bool shiftPressed   = modifier & Qt::ShiftModifier;
+    const bool controlPressed = modifier & Qt::ControlModifier;
     if (shiftPressed && controlPressed) {
-        // shortcut for 'Linke Here' is used
-        selectedIndex = 2;
-    }
-    else if (controlPressed) {
-        // shortcut for 'Copy Here' is used
-        selectedIndex = 1;
-    }
-    else if (shiftPressed) {
+        // shortcut for 'Link Here' is used
+        action = Qt::LinkAction;
+    } else if (shiftPressed) {
         // shortcut for 'Move Here' is used
-        selectedIndex = 0;
-    }
-    else*/ {
-        // no shortcut is used, hence open a popup menu
-        KMenu popup(this);
+        action = Qt::MoveAction;
+    } else if (controlPressed) {
+        // shortcut for 'Copy Here' is used
+        action = Qt::CopyAction;
+    } else {
+        // open a context menu which offers the following actions:
+        // - Move Here
+        // - Copy Here
+        // - Link Here
+        // - Cancel
 
-        popup.insertItem(SmallIcon("goto"), i18n("&Move Here") + "\t" /* KDE4-TODO: + KKey::modFlagLabel(KKey::SHIFT)*/, 0);
-        popup.insertItem(SmallIcon("editcopy"), i18n( "&Copy Here" ) /* KDE4-TODO + "\t" + KKey::modFlagLabel(KKey::CTRL)*/, 1);
-        popup.insertItem(i18n("&Link Here") /* KDE4-TODO + "\t" + KKey::modFlagLabel((KKey::ModFlag)(KKey::CTRL|KKey::SHIFT)) */, 2);
-        popup.insertSeparator();
-        popup.insertItem(SmallIcon("stop"), i18n("Cancel"), 3);
-        popup.setAccel(i18n("Escape"), 3);
-
-        /* KDE4-TODO: selectedIndex = popup.exec(QCursor::pos()); */
-        popup.exec(QCursor::pos());
-        selectedIndex = 0; // KD4-TODO: use QAction instead of switch below
-        // See libkonq/konq_operations.cc: KonqOperations::doDropFileCopy() (and doDrop, the main method)
-    }
+        KMenu popup(this);
 
-    if (selectedIndex < 0) {
-        return;
+        QString seq = QKeySequence(Qt::ShiftModifier).toString();
+        seq.chop(1); // chop superfluous '+'
+        QAction* moveAction = popup.addAction(KIcon("goto-page"),
+                                              i18n("&Move Here") + '\t' + seq);
+
+        seq = QKeySequence(Qt::ControlModifier).toString();
+        seq.chop(1);
+        QAction* copyAction = popup.addAction(KIcon("edit-copy"),
+                                              i18n("&Copy Here") + '\t' + seq);
+
+        seq = QKeySequence(Qt::ControlModifier + Qt::ShiftModifier).toString();
+        seq.chop(1);
+        QAction* linkAction = popup.addAction(KIcon("www"),
+                                              i18n("&Link Here") + '\t' + seq);
+
+        popup.addSeparator();
+        popup.addAction(KIcon("process-stop"), i18n("Cancel"));
+
+        QAction* activatedAction = popup.exec(QCursor::pos());
+        if (activatedAction == moveAction) {
+            action = Qt::MoveAction;
+        } else if (activatedAction == copyAction) {
+            action = Qt::CopyAction;
+        } else if (activatedAction == linkAction) {
+            action = Qt::LinkAction;
+        } else {
+            return;
+        }
     }
 
-    switch (selectedIndex) {
-        case 0: {
-            // 'Move Here' has been selected
-            updateViewProperties(urls);
-            moveUrls(urls, destination);
-            break;
-        }
+    switch (action) {
+    case Qt::MoveAction:
+        moveUrls(urls, destination);
+        break;
 
-        case 1: {
-            // 'Copy Here' has been selected
-            updateViewProperties(urls);
-            copyUrls(urls, destination);
-            break;
-        }
+    case Qt::CopyAction:
+        copyUrls(urls, destination);
+        break;
 
-        case 2: {
-            // 'Link Here' has been selected
-            KIO::Job* job = KIO::link(urls, destination);
-            addPendingUndoJob(job, DolphinCommand::Link, urls, destination);
-            break;
-        }
+    case Qt::LinkAction:
+        linkUrls(urls, destination);
+        break;
 
-        default:
-            // 'Cancel' has been selected
-            break;
+    default:
+        break;
     }
 }
 
+void DolphinMainWindow::rename(const KUrl& oldUrl, const KUrl& newUrl)
+{
+    clearStatusBar();
+    KonqOperations::rename(this, oldUrl, newUrl);
+    m_undoCommandTypes.append(KonqUndoManager::RENAME);
+}
+
 void DolphinMainWindow::refreshViews()
 {
     const bool split = DolphinSettings::instance().generalSettings()->splitView();
     const bool isPrimaryViewActive = (m_activeView == m_view[PrimaryIdx]);
     KUrl url;
     for (int i = PrimaryIdx; i <= SecondaryIdx; ++i) {
-       if (m_view[i] != 0) {
+        if (m_view[i] != 0) {
             url = m_view[i]->url();
 
             // delete view instance...
@@ -222,22 +227,47 @@ void DolphinMainWindow::refreshViews()
                                         props.viewMode(),
                                         props.showHiddenFiles());
             connectViewSignals(i);
+            m_view[i]->reload();
             m_view[i]->show();
         }
     }
 
     m_activeView = isPrimaryViewActive ? m_view[PrimaryIdx] : m_view[SecondaryIdx];
-    assert(m_activeView != 0);
+    Q_ASSERT(m_activeView != 0);
 
     updateViewActions();
     emit activeViewChanged();
 }
 
+void DolphinMainWindow::changeUrl(const KUrl& url)
+{
+    if (activeView() != 0) {
+        activeView()->setUrl(url);
+        updateEditActions();
+        updateViewActions();
+        updateGoActions();
+        setCaption(url.fileName());
+        emit urlChanged(url);
+    }
+}
+
+void DolphinMainWindow::changeSelection(const KFileItemList& selection)
+{
+    activeView()->changeSelection(selection);
+}
+
 void DolphinMainWindow::slotViewModeChanged()
 {
     updateViewActions();
 }
 
+void DolphinMainWindow::slotShowPreviewChanged()
+{
+    // It is not enough to update the 'Show Preview' action, also
+    // the 'Zoom In' and 'Zoom Out' actions must be adapted.
+    updateViewActions();
+}
+
 void DolphinMainWindow::slotShowHiddenFilesChanged()
 {
     KToggleAction* showHiddenFilesAction =
@@ -245,21 +275,38 @@ void DolphinMainWindow::slotShowHiddenFilesChanged()
     showHiddenFilesAction->setChecked(m_activeView->showHiddenFiles());
 }
 
+void DolphinMainWindow::slotCategorizedSortingChanged()
+{
+    KToggleAction* categorizedSortingAction =
+        static_cast<KToggleAction*>(actionCollection()->action("categorized"));
+    categorizedSortingAction->setChecked(m_activeView->categorizedSorting());
+    categorizedSortingAction->setEnabled(m_activeView->supportsCategorizedSorting());
+}
+
 void DolphinMainWindow::slotSortingChanged(DolphinView::Sorting sorting)
 {
     QAction* action = 0;
     switch (sorting) {
-        case DolphinView::SortByName:
-            action = actionCollection()->action("by_name");
-            break;
-        case DolphinView::SortBySize:
-            action = actionCollection()->action("by_size");
-            break;
-        case DolphinView::SortByDate:
-            action = actionCollection()->action("by_date");
-            break;
-        default:
-            break;
+    case DolphinView::SortByName:
+        action = actionCollection()->action("by_name");
+        break;
+    case DolphinView::SortBySize:
+        action = actionCollection()->action("by_size");
+        break;
+    case DolphinView::SortByDate:
+        action = actionCollection()->action("by_date");
+        break;
+    case DolphinView::SortByPermissions:
+        action = actionCollection()->action("by_permissions");
+        break;
+    case DolphinView::SortByOwner:
+        action = actionCollection()->action("by_owner");
+        break;
+    case DolphinView::SortByGroup:
+        action = actionCollection()->action("by_group");
+        break;
+    default:
+        break;
     }
 
     if (action != 0) {
@@ -271,15 +318,44 @@ void DolphinMainWindow::slotSortingChanged(DolphinView::Sorting sorting)
 void DolphinMainWindow::slotSortOrderChanged(Qt::SortOrder order)
 {
     KToggleAction* descending = static_cast<KToggleAction*>(actionCollection()->action("descending"));
-    const bool sortDescending = (order == Qt::Descending);
+    const bool sortDescending = (order == Qt::DescendingOrder);
     descending->setChecked(sortDescending);
 }
 
-void DolphinMainWindow::slotSelectionChanged()
+void DolphinMainWindow::slotAdditionalInfoChanged(KFileItemDelegate::AdditionalInformation info)
+{
+    QAction* action = 0;
+    switch (info) {
+    case KFileItemDelegate::FriendlyMimeType:
+        action = actionCollection()->action("show_mime_info");
+        break;
+    case KFileItemDelegate::Size:
+        action = actionCollection()->action("show_size_info");
+        break;
+    case KFileItemDelegate::ModificationTime:
+        action = actionCollection()->action("show_date_info");
+        break;
+    case KFileItemDelegate::NoInformation:
+    default:
+        action = actionCollection()->action("clear_info");
+        break;
+    }
+
+    if (action != 0) {
+        KToggleAction* toggleAction = static_cast<KToggleAction*>(action);
+        toggleAction->setChecked(true);
+
+        QActionGroup* group = toggleAction->actionGroup();
+        Q_ASSERT(group != 0);
+        group->setEnabled(m_activeView->mode() == DolphinView::IconsView);
+    }
+}
+
+void DolphinMainWindow::slotSelectionChanged(const KFileItemList& selection)
 {
     updateEditActions();
 
-    assert(m_view[PrimaryIdx] != 0);
+    Q_ASSERT(m_view[PrimaryIdx] != 0);
     int selectedUrlsCount = m_view[PrimaryIdx]->selectedUrls().count();
     if (m_view[SecondaryIdx] != 0) {
         selectedUrlsCount += m_view[SecondaryIdx]->selectedUrls().count();
@@ -290,7 +366,7 @@ void DolphinMainWindow::slotSelectionChanged()
 
     m_activeView->updateStatusBar();
 
-    emit selectionChanged();
+    emit selectionChanged(selection);
 }
 
 void DolphinMainWindow::slotHistoryChanged()
@@ -298,13 +374,6 @@ void DolphinMainWindow::slotHistoryChanged()
     updateHistory();
 }
 
-void DolphinMainWindow::slotUrlChanged(const KUrl& url)
-{
-    updateEditActions();
-    updateGoActions();
-    setCaption(url.fileName());
-}
-
 void DolphinMainWindow::updateFilterBarAction(bool show)
 {
     KToggleAction* showFilterBarAction =
@@ -312,16 +381,6 @@ void DolphinMainWindow::updateFilterBarAction(bool show)
     showFilterBarAction->setChecked(show);
 }
 
-void DolphinMainWindow::redo()
-{
-    UndoManager::instance().redo(this);
-}
-
-void DolphinMainWindow::undo()
-{
-    UndoManager::instance().undo(this);
-}
-
 void DolphinMainWindow::openNewMainWindow()
 {
     DolphinApplication::app()->createMainWindow()->show();
@@ -329,216 +388,59 @@ void DolphinMainWindow::openNewMainWindow()
 
 void DolphinMainWindow::closeEvent(QCloseEvent* event)
 {
-    // KDE4-TODO
-    //KConfig* config = KGlobal::config();
-    //config->setGroup("General");
-    //config->writeEntry("First Run", false);
-
     DolphinSettings& settings = DolphinSettings::instance();
     GeneralSettings* generalSettings = settings.generalSettings();
     generalSettings->setFirstRun(false);
 
     settings.save();
 
+    // TODO: I assume there will be a generic way in KDE 4 to store the docks
+    // of the main window. In the meantime they are stored manually:
+    QString filename = KStandardDirs::locateLocal("data", KGlobal::mainComponent().componentName());
+    filename.append("/panels_layout");
+    QFile file(filename);
+    if (file.open(QIODevice::WriteOnly)) {
+        QByteArray data = saveState();
+        file.write(data);
+        file.close();
+    }
+
     KMainWindow::closeEvent(event);
 }
 
 void DolphinMainWindow::saveProperties(KConfig* config)
 {
-    config->setGroup("Primary view");
-    config->writeEntry("Url", m_view[PrimaryIdx]->url().url());
-    config->writeEntry("Editable Url", m_view[PrimaryIdx]->isUrlEditable());
+    KConfigGroup primaryView = config->group("Primary view");
+    primaryView.writeEntry("Url", m_view[PrimaryIdx]->url().url());
+    primaryView.writeEntry("Editable Url", m_view[PrimaryIdx]->isUrlEditable());
     if (m_view[SecondaryIdx] != 0) {
-        config->setGroup("Secondary view");
-        config->writeEntry("Url", m_view[SecondaryIdx]->url().url());
-        config->writeEntry("Editable Url", m_view[SecondaryIdx]->isUrlEditable());
+        KConfigGroup secondaryView = config->group("Secondary view");
+        secondaryView.writeEntry("Url", m_view[SecondaryIdx]->url().url());
+        secondaryView.writeEntry("Editable Url", m_view[SecondaryIdx]->isUrlEditable());
     }
 }
 
 void DolphinMainWindow::readProperties(KConfig* config)
 {
-    config->setGroup("Primary view");
-    m_view[PrimaryIdx]->setUrl(config->readEntry("Url"));
-    m_view[PrimaryIdx]->setUrlEditable(config->readEntry("Editable Url", false));
+    const KConfigGroup primaryView = config->group("Primary view");
+    m_view[PrimaryIdx]->setUrl(primaryView.readEntry("Url"));
+    m_view[PrimaryIdx]->setUrlEditable(primaryView.readEntry("Editable Url", false));
     if (config->hasGroup("Secondary view")) {
-        config->setGroup("Secondary view");
+        const KConfigGroup secondaryView = config->group("Secondary view");
         if (m_view[SecondaryIdx] == 0) {
             toggleSplitView();
         }
-        m_view[SecondaryIdx]->setUrl(config->readEntry("Url"));
-        m_view[SecondaryIdx]->setUrlEditable(config->readEntry("Editable Url", false));
-    }
-    else if (m_view[SecondaryIdx] != 0) {
+        m_view[SecondaryIdx]->setUrl(secondaryView.readEntry("Url"));
+        m_view[SecondaryIdx]->setUrlEditable(secondaryView.readEntry("Editable Url", false));
+    } else if (m_view[SecondaryIdx] != 0) {
         toggleSplitView();
     }
 }
 
-void DolphinMainWindow::createFolder()
-{
-    // Parts of the following code have been taken
-    // from the class KonqPopupMenu located in
-    // libqonq/konq_popupmenu.h of Konqueror.
-    // (Copyright (C) 2000  David Faure <faure@kde.org>,
-    // Copyright (C) 2001 Holger Freyther <freyther@yahoo.com>)
-
-    clearStatusBar();
-
-    DolphinStatusBar* statusBar = m_activeView->statusBar();
-    const KUrl baseUrl(m_activeView->url());
-
-    QString name(i18n("New Folder"));
-    baseUrl.path(KUrl::AddTrailingSlash);
-
-
-    if (baseUrl.isLocalFile() && QFileInfo(baseUrl.path(KUrl::AddTrailingSlash) + name).exists()) {
-        name = KIO::RenameDlg::suggestName(baseUrl, i18n("New Folder"));
-    }
-
-    bool ok = false;
-    name = KInputDialog::getText(i18n("New Folder"),
-                                 i18n("Enter folder name:" ),
-                                 name,
-                                 &ok,
-                                 this);
-
-    if (!ok) {
-        // the user has pressed 'Cancel'
-        return;
-    }
-
-    assert(!name.isEmpty());
-
-    KUrl url;
-    if ((name[0] == '/') || (name[0] == '~')) {
-        url.setPath(KShell::tildeExpand(name));
-    }
-    else {
-        name = KIO::encodeFileName(name);
-        url = baseUrl;
-        url.addPath(name);
-    }
-    ok = KIO::NetAccess::mkdir(url, this);
-
-    // TODO: provide message type hint
-    if (ok) {
-        statusBar->setMessage(i18n("Created folder %1.",url.path()),
-                              DolphinStatusBar::OperationCompleted);
-
-        DolphinCommand command(DolphinCommand::CreateFolder, KUrl::List(), url);
-        UndoManager::instance().addCommand(command);
-    }
-    else {
-        // Creating of the folder has been failed. Check whether the creating
-        // has been failed because a folder with the same name exists...
-        if (KIO::NetAccess::exists(url, true, this)) {
-            statusBar->setMessage(i18n("A folder named %1 already exists.",url.path()),
-                                  DolphinStatusBar::Error);
-        }
-        else {
-            statusBar->setMessage(i18n("Creating of folder %1 failed.",url.path()),
-                                  DolphinStatusBar::Error);
-        }
-
-    }
-}
-
-void DolphinMainWindow::createFile()
+void DolphinMainWindow::updateNewMenu()
 {
-    // Parts of the following code have been taken
-    // from the class KonqPopupMenu located in
-    // libqonq/konq_popupmenu.h of Konqueror.
-    // (Copyright (C) 2000  David Faure <faure@kde.org>,
-    // Copyright (C) 2001 Holger Freyther <freyther@yahoo.com>)
-
-    clearStatusBar();
-
-    // TODO: const Entry& entry = m_createFileTemplates[QString(sender->name())];
-    // should be enough. Anyway: the implemantation of [] does a linear search internally too.
-    KSortableList<CreateFileEntry, QString>::ConstIterator it = m_createFileTemplates.begin();
-    KSortableList<CreateFileEntry, QString>::ConstIterator end = m_createFileTemplates.end();
-
-    const QString senderName(sender()->objectName());
-    bool found = false;
-    CreateFileEntry entry;
-    while (!found && (it != end)) {
-        if ((*it).key() == senderName) {
-            entry = (*it).value();
-            found = true;
-        }
-        else {
-            ++it;
-        }
-    }
-
-    DolphinStatusBar* statusBar = m_activeView->statusBar();
-    if (!found || !QFile::exists(entry.templatePath)) {
-        statusBar->setMessage(i18n("Could not create file."), DolphinStatusBar::Error);
-       return;
-    }
-
-    // Get the source path of the template which should be copied.
-    // The source path is part of the Url entry of the desktop file.
-    const int pos = entry.templatePath.lastIndexOf('/');
-    QString sourcePath(entry.templatePath.left(pos + 1));
-    sourcePath += KDesktopFile(entry.templatePath, true).readPathEntry("Url");
-
-    QString name(i18n(entry.name.toAscii()));
-    // Most entry names end with "..." (e. g. "HTML File..."), which is ok for
-    // menus but no good choice for a new file name -> remove the dots...
-    name.replace("...", QString::null);
-
-    // add the file extension to the name
-    name.append(sourcePath.right(sourcePath.length() - sourcePath.lastIndexOf('.')));
-
-    // Check whether a file with the current name already exists. If yes suggest automatically
-    // a unique file name (e. g. "HTML File" will be replaced by "HTML File_1").
-    const KUrl viewUrl(m_activeView->url());
-    const bool fileExists = viewUrl.isLocalFile() &&
-                            QFileInfo(viewUrl.path(KUrl::AddTrailingSlash) + KIO::encodeFileName(name)).exists();
-    if (fileExists) {
-        name = KIO::RenameDlg::suggestName(viewUrl, name);
-    }
-
-    // let the user change the suggested file name
-    bool ok = false;
-    name = KInputDialog::getText(entry.name,
-                                 entry.comment,
-                                 name,
-                                 &ok,
-                                 this);
-    if (!ok) {
-        // the user has pressed 'Cancel'
-        return;
-    }
-
-    // before copying the template to the destination path check whether a file
-    // with the given name already exists
-    const QString destPath(viewUrl.pathOrUrl() + "/" + KIO::encodeFileName(name));
-    const KUrl destUrl(destPath);
-    if (KIO::NetAccess::exists(destUrl, false, this)) {
-        statusBar->setMessage(i18n("A file named %1 already exists.",name),
-                              DolphinStatusBar::Error);
-        return;
-    }
-
-    // copy the template to the destination path
-    const KUrl sourceUrl(sourcePath);
-    KIO::CopyJob* job = KIO::copyAs(sourceUrl, destUrl);
-    job->setDefaultPermissions(true);
-    if (KIO::NetAccess::synchronousRun(job, this)) {
-        statusBar->setMessage(i18n("Created file %1.",name),
-                              DolphinStatusBar::OperationCompleted);
-
-        KUrl::List list;
-        list.append(sourceUrl);
-        DolphinCommand command(DolphinCommand::CreateFile, list, destUrl);
-        UndoManager::instance().addCommand(command);
-
-    }
-    else {
-        statusBar->setMessage(i18n("Creating of file %1 failed.",name),
-                              DolphinStatusBar::Error);
-    }
+    m_newMenu->slotCheckUpToDate();
+    m_newMenu->setPopupFiles(activeView()->url());
 }
 
 void DolphinMainWindow::rename()
@@ -550,33 +452,21 @@ void DolphinMainWindow::rename()
 void DolphinMainWindow::moveToTrash()
 {
     clearStatusBar();
-    KUrl::List selectedUrls = m_activeView->selectedUrls();
-    KIO::Job* job = KIO::trash(selectedUrls);
-    addPendingUndoJob(job, DolphinCommand::Trash, selectedUrls, m_activeView->url());
+    const KUrl::List selectedUrls = m_activeView->selectedUrls();
+    KonqOperations::del(this, KonqOperations::TRASH, selectedUrls);
+    m_undoCommandTypes.append(KonqUndoManager::TRASH);
 }
 
 void DolphinMainWindow::deleteItems()
 {
     clearStatusBar();
 
-    KUrl::List list = m_activeView->selectedUrls();
-    const uint itemCount = list.count();
-    assert(itemCount >= 1);
+    const KUrl::List list = m_activeView->selectedUrls();
+    const bool del = KonqOperations::askDeleteConfirmation(list,
+                     KonqOperations::DEL,
+                     KonqOperations::DEFAULT_CONFIRMATION,
+                     this);
 
-    QString text;
-    if (itemCount > 1) {
-        text = i18n("Do you really want to delete the %1 selected items?",itemCount);
-    }
-    else {
-        const KUrl& url = list.first();
-        text = i18n("Do you really want to delete '%1'?",url.fileName());
-    }
-
-    const bool del = KMessageBox::warningContinueCancel(this,
-                                                        text,
-                                                        QString::null,
-                                                        KGuiItem(i18n("Delete"), SmallIcon("editdelete"))
-                                                       ) == KMessageBox::Continue;
     if (del) {
         KIO::Job* job = KIO::del(list);
         connect(job, SIGNAL(result(KJob*)),
@@ -600,78 +490,94 @@ void DolphinMainWindow::quit()
 void DolphinMainWindow::slotHandleJobError(KJob* job)
 {
     if (job->error() != 0) {
-        m_activeView->statusBar()->setMessage(job->errorString(),
-                                              DolphinStatusBar::Error);
+        DolphinStatusBar* statusBar = m_activeView->statusBar();
+        statusBar->setMessage(job->errorString(),
+                              DolphinStatusBar::Error);
     }
 }
 
 void DolphinMainWindow::slotDeleteFileFinished(KJob* job)
 {
     if (job->error() == 0) {
-        m_activeView->statusBar()->setMessage(i18n("Delete operation completed."),
-                                               DolphinStatusBar::OperationCompleted);
-
-        // TODO: In opposite to the 'Move to Trash' operation in the class KFileIconView
-        // no rearranging of the item position is done when a file has been deleted.
-        // This is bypassed by reloading the view, but it might be worth to investigate
-        // deeper for the root of this issue.
-        m_activeView->reload();
+        DolphinStatusBar* statusBar = m_activeView->statusBar();
+        statusBar->setMessage(i18n("Delete operation completed."),
+                              DolphinStatusBar::OperationCompleted);
     }
 }
 
 void DolphinMainWindow::slotUndoAvailable(bool available)
 {
-    QAction* undoAction = actionCollection()->action(KStdAction::stdName(KStdAction::Undo));
+    QAction* undoAction = actionCollection()->action(KStandardAction::stdName(KStandardAction::Undo));
     if (undoAction != 0) {
         undoAction->setEnabled(available);
     }
+
+    if (available && (m_undoCommandTypes.count() > 0)) {
+        const KonqUndoManager::CommandType command = m_undoCommandTypes.takeFirst();
+        DolphinStatusBar* statusBar = m_activeView->statusBar();
+        switch (command) {
+        case KonqUndoManager::COPY:
+            statusBar->setMessage(i18n("Copy operation completed."),
+                                  DolphinStatusBar::OperationCompleted);
+            break;
+        case KonqUndoManager::MOVE:
+            statusBar->setMessage(i18n("Move operation completed."),
+                                  DolphinStatusBar::OperationCompleted);
+            break;
+        case KonqUndoManager::LINK:
+            statusBar->setMessage(i18n("Link operation completed."),
+                                  DolphinStatusBar::OperationCompleted);
+            break;
+        case KonqUndoManager::TRASH:
+            statusBar->setMessage(i18n("Move to trash operation completed."),
+                                  DolphinStatusBar::OperationCompleted);
+            break;
+        case KonqUndoManager::RENAME:
+            statusBar->setMessage(i18n("Renaming operation completed."),
+                                  DolphinStatusBar::OperationCompleted);
+            break;
+
+        case KonqUndoManager::MKDIR:
+            statusBar->setMessage(i18n("Created directory."),
+                                  DolphinStatusBar::OperationCompleted);
+            break;
+
+        default:
+            break;
+        }
+
+    }
 }
 
 void DolphinMainWindow::slotUndoTextChanged(const QString& text)
 {
-    QAction* undoAction = actionCollection()->action(KStdAction::stdName(KStdAction::Undo));
+    QAction* undoAction = actionCollection()->action(KStandardAction::stdName(KStandardAction::Undo));
     if (undoAction != 0) {
         undoAction->setText(text);
     }
 }
 
-void DolphinMainWindow::slotRedoAvailable(bool available)
-{
-    QAction* redoAction = actionCollection()->action(KStdAction::stdName(KStdAction::Redo));
-    if (redoAction != 0) {
-        redoAction->setEnabled(available);
-    }
-}
-
-void DolphinMainWindow::slotRedoTextChanged(const QString& text)
+void DolphinMainWindow::undo()
 {
-    QAction* redoAction = actionCollection()->action(KStdAction::stdName(KStdAction::Redo));
-    if (redoAction != 0) {
-        redoAction->setText(text);
-    }
+    clearStatusBar();
+    KonqUndoManager::self()->undo();
 }
 
 void DolphinMainWindow::cut()
 {
-    // TODO: this boolean doesn't work between instances of dolphin or with konqueror or with other
-    // apps. The "application/x-kde-cutselection" mimetype should be used instead, see KonqMimeData
-    // in libkonq
-    m_clipboardContainsCutData = true;
-
     QMimeData* mimeData = new QMimeData();
-    const KUrl::List selectedUrls = m_activeView->selectedUrls();
-    selectedUrls.populateMimeData(mimeData);
-
+    const KUrl::List kdeUrls = m_activeView->selectedUrls();
+    const KUrl::List mostLocalUrls;
+    KonqMimeData::populateMimeData(mimeData, kdeUrls, mostLocalUrls, true);
     QApplication::clipboard()->setMimeData(mimeData);
 }
 
 void DolphinMainWindow::copy()
 {
-    m_clipboardContainsCutData = false;
-
     QMimeData* mimeData = new QMimeData();
-    const KUrl::List selectedUrls = m_activeView->selectedUrls();
-    selectedUrls.populateMimeData(mimeData);
+    const KUrl::List kdeUrls = m_activeView->selectedUrls();
+    const KUrl::List mostLocalUrls;
+    KonqMimeData::populateMimeData(mimeData, kdeUrls, mostLocalUrls, false);
 
     QApplication::clipboard()->setMimeData(mimeData);
 }
@@ -702,25 +608,17 @@ void DolphinMainWindow::paste()
         }
     }
 
-    // TODO #1: use libkonq commands (see doPaste() implementation
-    // KIO::Job* job = KIO::pasteClipboard(destUrl, this, false);
-    // ...
-    // TODO #2: this boolean doesn't work between instances of dolphin or with konqueror or with other
-    // apps. The "application/x-kde-cutselection" mimetype should be used instead, see KonqMimeData
-    // in libkonq
-    if (m_clipboardContainsCutData) {
+    if (KonqMimeData::decodeIsCutSelection(mimeData)) {
         moveUrls(sourceUrls, destUrl);
-        m_clipboardContainsCutData = false;
         clipboard->clear();
-    }
-    else {
+    } else {
         copyUrls(sourceUrls, destUrl);
     }
 }
 
 void DolphinMainWindow::updatePasteAction()
 {
-    QAction* pasteAction = actionCollection()->action(KStdAction::stdName(KStdAction::Paste));
+    QAction* pasteAction = actionCollection()->action(KStandardAction::stdName(KStandardAction::Paste));
     if (pasteAction == 0) {
         return;
     }
@@ -733,15 +631,8 @@ void DolphinMainWindow::updatePasteAction()
     if (!urls.isEmpty()) {
         pasteAction->setEnabled(true);
 
-        const int count = urls.count();
-        if (count == 1) {
-            pasteAction->setText(i18n("Paste 1 File"));
-        }
-        else {
-            pasteAction->setText(i18n("Paste %1 Files").arg(count));
-        }
-    }
-    else {
+        pasteAction->setText(i18np("Paste One File", "Paste %1 Files", urls.count()));
+    } else {
         pasteAction->setEnabled(false);
         pasteAction->setText(i18n("Paste"));
     }
@@ -753,8 +644,7 @@ void DolphinMainWindow::updatePasteAction()
             // pasting should not be allowed when more than one file
             // is selected
             pasteAction->setEnabled(false);
-        }
-        else if (count == 1) {
+        } else if (count == 1) {
             // Only one file is selected. Pasting is only allowed if this
             // file is a directory.
             // TODO: this doesn't work with remote protocols; instead we need a
@@ -789,6 +679,11 @@ void DolphinMainWindow::setDetailsView()
     m_activeView->setMode(DolphinView::DetailsView);
 }
 
+void DolphinMainWindow::setColumnView()
+{
+    m_activeView->setMode(DolphinView::ColumnView);
+}
+
 void DolphinMainWindow::sortByName()
 {
     m_activeView->setSorting(DolphinView::SortByName);
@@ -804,14 +699,58 @@ void DolphinMainWindow::sortByDate()
     m_activeView->setSorting(DolphinView::SortByDate);
 }
 
+void DolphinMainWindow::sortByPermissions()
+{
+    m_activeView->setSorting(DolphinView::SortByPermissions);
+}
+
+void DolphinMainWindow::sortByOwner()
+{
+    m_activeView->setSorting(DolphinView::SortByOwner);
+}
+
+void DolphinMainWindow::sortByGroup()
+{
+    m_activeView->setSorting(DolphinView::SortByGroup);
+}
+
 void DolphinMainWindow::toggleSortOrder()
 {
-    const Qt::SortOrder order = (m_activeView->sortOrder() == Qt::Ascending) ?
-                                Qt::Descending :
-                                Qt::Ascending;
+    const Qt::SortOrder order = (m_activeView->sortOrder() == Qt::AscendingOrder) ?
+                                Qt::DescendingOrder :
+                                Qt::AscendingOrder;
     m_activeView->setSortOrder(order);
 }
 
+void DolphinMainWindow::toggleSortCategorization()
+{
+    const bool categorizedSorting = m_activeView->categorizedSorting();
+    m_activeView->setCategorizedSorting(!categorizedSorting);
+}
+
+void DolphinMainWindow::clearInfo()
+{
+    m_activeView->setAdditionalInfo(KFileItemDelegate::NoInformation);
+}
+
+void DolphinMainWindow::showMimeInfo()
+{
+    clearStatusBar();
+    m_activeView->setAdditionalInfo(KFileItemDelegate::FriendlyMimeType);
+}
+
+void DolphinMainWindow::showSizeInfo()
+{
+    clearStatusBar();
+    m_activeView->setAdditionalInfo(KFileItemDelegate::Size);
+}
+
+void DolphinMainWindow::showDateInfo()
+{
+    clearStatusBar();
+    m_activeView->setAdditionalInfo(KFileItemDelegate::ModificationTime);
+}
+
 void DolphinMainWindow::toggleSplitView()
 {
     if (m_view[SecondaryIdx] == 0) {
@@ -825,17 +764,16 @@ void DolphinMainWindow::toggleSplitView()
         connectViewSignals(SecondaryIdx);
         m_splitter->addWidget(m_view[SecondaryIdx]);
         m_splitter->setSizes(QList<int>() << newWidth << newWidth);
+        m_view[SecondaryIdx]->reload();
         m_view[SecondaryIdx]->show();
-    }
-    else {
+    } else {
         // remove secondary view
         if (m_activeView == m_view[PrimaryIdx]) {
             m_view[SecondaryIdx]->close();
             m_view[SecondaryIdx]->deleteLater();
             m_view[SecondaryIdx] = 0;
             setActiveView(m_view[PrimaryIdx]);
-        }
-        else {
+        } else {
             // The secondary view is active, hence from the users point of view
             // the content of the secondary view should be moved to the primary view.
             // From an implementation point of view it is more efficient to close
@@ -847,6 +785,7 @@ void DolphinMainWindow::toggleSplitView()
             setActiveView(m_view[PrimaryIdx]);
         }
     }
+    emit activeViewChanged();
 }
 
 void DolphinMainWindow::reloadView()
@@ -856,11 +795,16 @@ void DolphinMainWindow::reloadView()
 }
 
 void DolphinMainWindow::stopLoading()
-{
-}
+{}
 
 void DolphinMainWindow::togglePreview()
 {
+    clearStatusBar();
+
+    const KToggleAction* showPreviewAction =
+        static_cast<KToggleAction*>(actionCollection()->action("show_preview"));
+    const bool show = showPreviewAction->isChecked();
+    m_activeView->setShowPreview(show);
 }
 
 void DolphinMainWindow::toggleShowHiddenFiles()
@@ -878,7 +822,7 @@ void DolphinMainWindow::showFilterBar()
     const KToggleAction* showFilterBarAction =
         static_cast<KToggleAction*>(actionCollection()->action("show_filter_bar"));
     const bool show = showFilterBarAction->isChecked();
-    m_activeView->slotShowFilterBar(show);
+    m_activeView->showFilterBar(show);
 }
 
 void DolphinMainWindow::zoomIn()
@@ -900,14 +844,11 @@ void DolphinMainWindow::toggleEditLocation()
     KToggleAction* action = static_cast<KToggleAction*>(actionCollection()->action("editable_location"));
 
     bool editOrBrowse = action->isChecked();
-//    action->setChecked(action->setChecked);
     m_activeView->setUrlEditable(editOrBrowse);
 }
 
 void DolphinMainWindow::editLocation()
 {
-    KToggleAction* action = static_cast<KToggleAction*>(actionCollection()->action("editable_location"));
-    action->setChecked(true);
     m_activeView->setUrlEditable(true);
 }
 
@@ -964,42 +905,42 @@ void DolphinMainWindow::compareFiles()
     // - both in the secondary view
     // - one in the primary view and the other in the secondary
     //   view
-    assert(m_view[PrimaryIdx] != 0);
+    Q_ASSERT(m_view[PrimaryIdx] != 0);
 
     KUrl urlA;
     KUrl urlB;
     KUrl::List urls = m_view[PrimaryIdx]->selectedUrls();
 
     switch (urls.count()) {
-        case 0: {
-            assert(m_view[SecondaryIdx] != 0);
-            urls = m_view[SecondaryIdx]->selectedUrls();
-            assert(urls.count() == 2);
-            urlA = urls[0];
-            urlB = urls[1];
-            break;
-        }
+    case 0: {
+        Q_ASSERT(m_view[SecondaryIdx] != 0);
+        urls = m_view[SecondaryIdx]->selectedUrls();
+        Q_ASSERT(urls.count() == 2);
+        urlA = urls[0];
+        urlB = urls[1];
+        break;
+    }
 
-        case 1: {
-            urlA = urls[0];
-            assert(m_view[SecondaryIdx] != 0);
-            urls = m_view[SecondaryIdx]->selectedUrls();
-            assert(urls.count() == 1);
-            urlB = urls[0];
-            break;
-        }
+    case 1: {
+        urlA = urls[0];
+        Q_ASSERT(m_view[SecondaryIdx] != 0);
+        urls = m_view[SecondaryIdx]->selectedUrls();
+        Q_ASSERT(urls.count() == 1);
+        urlB = urls[0];
+        break;
+    }
 
-        case 2: {
-            urlA = urls[0];
-            urlB = urls[1];
-            break;
-        }
+    case 2: {
+        urlA = urls[0];
+        urlB = urls[1];
+        break;
+    }
 
-        default: {
-            // may not happen: compareFiles may only get invoked if 2
-            // files are selected
-            assert(false);
-        }
+    default: {
+        // may not happen: compareFiles may only get invoked if 2
+        // files are selected
+        Q_ASSERT(false);
+    }
     }
 
     QString command("kompare -c \"");
@@ -1018,86 +959,15 @@ void DolphinMainWindow::editSettings()
     dlg.exec();
 }
 
-void DolphinMainWindow::addUndoOperation(KJob* job)
-{
-    if (job->error() != 0) {
-        slotHandleJobError(job);
-    }
-    else {
-        const int id = job->progressId();
-
-        // set iterator to the executed command with the current id...
-        Q3ValueList<UndoInfo>::Iterator it = m_pendingUndoJobs.begin();
-        const Q3ValueList<UndoInfo>::Iterator end = m_pendingUndoJobs.end();
-        bool found = false;
-        while (!found && (it != end)) {
-            if ((*it).id == id) {
-                found = true;
-            }
-            else {
-                ++it;
-            }
-        }
-
-        if (found) {
-            DolphinCommand command = (*it).command;
-            if (command.type() == DolphinCommand::Trash) {
-                // To be able to perform an undo for the 'Move to Trash' operation
-                // all source Urls must be updated with the trash Url. E. g. when moving
-                // a file "test.txt" and a second file "test.txt" to the trash,
-                // then the filenames in the trash are "0-test.txt" and "1-test.txt".
-                QMap<QString, QString> metaData;
-                KIO::Job *kiojob = qobject_cast<KIO::Job*>( job );
-                if ( kiojob )
-                {
-                    metaData = kiojob->metaData();
-                }
-                KUrl::List newSourceUrls;
-
-                KUrl::List sourceUrls = command.source();
-                KUrl::List::Iterator sourceIt = sourceUrls.begin();
-                const KUrl::List::Iterator sourceEnd = sourceUrls.end();
-
-                while (sourceIt != sourceEnd) {
-                    QMap<QString, QString>::ConstIterator metaIt = metaData.find("trashUrl-" + (*sourceIt).path());
-                    if (metaIt != metaData.end()) {
-                        newSourceUrls.append(KUrl(metaIt.value()));
-                    }
-                    ++sourceIt;
-                }
-                command.setSource(newSourceUrls);
-            }
-
-            UndoManager::instance().addCommand(command);
-            m_pendingUndoJobs.erase(it);
-
-            DolphinStatusBar* statusBar = m_activeView->statusBar();
-            switch (command.type()) {
-                case DolphinCommand::Copy:
-                    statusBar->setMessage(i18n("Copy operation completed."),
-                                          DolphinStatusBar::OperationCompleted);
-                    break;
-                case DolphinCommand::Move:
-                    statusBar->setMessage(i18n("Move operation completed."),
-                                          DolphinStatusBar::OperationCompleted);
-                    break;
-                case DolphinCommand::Trash:
-                    statusBar->setMessage(i18n("Move to trash operation completed."),
-                                          DolphinStatusBar::OperationCompleted);
-                    break;
-                default:
-                    break;
-            }
-        }
-    }
-}
-
 void DolphinMainWindow::init()
 {
     // Check whether Dolphin runs the first time. If yes then
     // a proper default window size is given at the end of DolphinMainWindow::init().
     GeneralSettings* generalSettings = DolphinSettings::instance().generalSettings();
     const bool firstRun = generalSettings->firstRun();
+    if (firstRun) {
+        generalSettings->setViewPropsTimestamp(QDateTime::currentDateTime());
+    }
 
     setAcceptDrops(true);
 
@@ -1105,20 +975,9 @@ void DolphinMainWindow::init()
 
     DolphinSettings& settings = DolphinSettings::instance();
 
-    KBookmarkManager* manager = settings.bookmarkManager();
-    assert(manager != 0);
-    KBookmarkGroup root = manager->root();
-    if (root.first().isNull()) {
-        root.addBookmark(manager, i18n("Home"), settings.generalSettings()->homeUrl(), "folder_home");
-        root.addBookmark(manager, i18n("Storage Media"), KUrl("media:/"), "blockdevice");
-        root.addBookmark(manager, i18n("Network"), KUrl("remote:/"), "network_local");
-        root.addBookmark(manager, i18n("Root"), KUrl("/"), "folder_red");
-        root.addBookmark(manager, i18n("Trash"), KUrl("trash:/"), "trashcan_full");
-    }
-
     setupActions();
 
-    const KUrl& homeUrl = root.first().url();
+    const KUrl& homeUrl = settings.generalSettings()->homeUrl();
     setCaption(homeUrl.fileName());
     ViewProperties props(homeUrl);
     m_view[PrimaryIdx] = new DolphinView(this,
@@ -1126,15 +985,16 @@ void DolphinMainWindow::init()
                                          homeUrl,
                                          props.viewMode(),
                                          props.showHiddenFiles());
-    connectViewSignals(PrimaryIdx);
-    m_view[PrimaryIdx]->show();
 
     m_activeView = m_view[PrimaryIdx];
+    connectViewSignals(PrimaryIdx);
+    m_view[PrimaryIdx]->reload();
+    m_view[PrimaryIdx]->show();
 
     setCentralWidget(m_splitter);
     setupDockWidgets();
 
-    setupGUI(Keys|Save|Create|ToolBar);
+    setupGUI(Keys | Save | Create | ToolBar);
     createGUI();
 
     stateChanged("new_file");
@@ -1146,14 +1006,18 @@ void DolphinMainWindow::init()
     updatePasteAction();
     updateGoActions();
 
-    setupCreateNewMenuActions();
-
     loadSettings();
 
     if (firstRun) {
         // assure a proper default size if Dolphin runs the first time
         resize(640, 480);
     }
+#ifdef HAVE_KMETADATA
+    if (!MetaDataWidget::metaDataAvailable())
+        activeView()->statusBar()->setMessage(i18n("Failed to contact Nepomuk service, annotation and tagging are disabled."), DolphinStatusBar::Error);
+#endif
+
+    emit urlChanged(homeUrl);
 }
 
 void DolphinMainWindow::loadSettings()
@@ -1167,306 +1031,309 @@ void DolphinMainWindow::loadSettings()
     }
 
     updateViewActions();
+
+    // TODO: I assume there will be a generic way in KDE 4 to restore the docks
+    // of the main window. In the meantime they are restored manually (see also
+    // DolphinMainWindow::closeEvent() for more details):
+    QString filename = KStandardDirs::locateLocal("data", KGlobal::mainComponent().componentName());   filename.append("/panels_layout");
+    QFile file(filename);
+    if (file.open(QIODevice::ReadOnly)) {
+        QByteArray data = file.readAll();
+        restoreState(data);
+        file.close();
+    }
 }
 
 void DolphinMainWindow::setupActions()
 {
     // setup 'File' menu
-    KAction *action = new KAction(KIcon("window_new"),  i18n( "New &Window" ), actionCollection(), "new_window" );
-    connect(action, SIGNAL(triggered()), this, SLOT(openNewMainWindow()));
-
-    KAction* createFolder = new KAction(i18n("Folder..."), actionCollection(), "create_folder");
-    createFolder->setIcon(KIcon("folder"));
-    createFolder->setShortcut(Qt::Key_N);
-    connect(createFolder, SIGNAL(triggered()), this, SLOT(createFolder()));
-
-    KAction* rename = new KAction(i18n("Rename"), actionCollection(), "rename");
+    m_newMenu = new DolphinNewMenu(this);
+    KMenu* menu = m_newMenu->menu();
+    menu->setTitle(i18n("Create New"));
+    menu->setIcon(KIcon("document-new"));
+    connect(menu, SIGNAL(aboutToShow()),
+            this, SLOT(updateNewMenu()));
+
+    QAction* newWindow = actionCollection()->addAction("new_window");
+    newWindow->setIcon(KIcon("window-new"));
+    newWindow->setText(i18n("New &Window"));
+    newWindow->setShortcut(Qt::CTRL | Qt::Key_N);
+    connect(newWindow, SIGNAL(triggered()), this, SLOT(openNewMainWindow()));
+
+    QAction* rename = actionCollection()->addAction("rename");
+    rename->setText(i18n("Rename..."));
     rename->setShortcut(Qt::Key_F2);
     connect(rename, SIGNAL(triggered()), this, SLOT(rename()));
 
-    KAction* moveToTrash = new KAction(i18n("Move to Trash"), actionCollection(), "move_to_trash");
-    moveToTrash->setIcon(KIcon("edittrash"));
+    QAction* moveToTrash = actionCollection()->addAction("move_to_trash");
+    moveToTrash->setText(i18n("Move to Trash"));
+    moveToTrash->setIcon(KIcon("edit-trash"));
     moveToTrash->setShortcut(QKeySequence::Delete);
     connect(moveToTrash, SIGNAL(triggered()), this, SLOT(moveToTrash()));
 
-    KAction* deleteAction = new KAction(i18n("Delete"), actionCollection(), "delete");
-    deleteAction->setShortcut(Qt::ALT | Qt::Key_Delete);
-    deleteAction->setIcon(KIcon("editdelete"));
+    QAction* deleteAction = actionCollection()->addAction("delete");
+    deleteAction->setText(i18n("Delete"));
+    deleteAction->setShortcut(Qt::SHIFT | Qt::Key_Delete);
+    deleteAction->setIcon(KIcon("edit-delete"));
     connect(deleteAction, SIGNAL(triggered()), this, SLOT(deleteItems()));
 
-    KAction* properties = new KAction(i18n("Propert&ies"), actionCollection(), "properties");
-    properties->setShortcut(Qt::Key_Alt | Qt::Key_Return);
+    QAction* properties = actionCollection()->addAction("properties");
+    properties->setText(i18n("Properties"));
+    properties->setShortcut(Qt::ALT | Qt::Key_Return);
     connect(properties, SIGNAL(triggered()), this, SLOT(properties()));
 
-    KStdAction::quit(this, SLOT(quit()), actionCollection());
+    KStandardAction::quit(this, SLOT(quit()), actionCollection());
 
     // setup 'Edit' menu
-    UndoManager& undoManager = UndoManager::instance();
-    KStdAction::undo(this,
-                     SLOT(undo()),
-                     actionCollection());
-    connect(&undoManager, SIGNAL(undoAvailable(bool)),
-            this, SLOT(slotUndoAvailable(bool)));
-    connect(&undoManager, SIGNAL(undoTextChanged(const QString&)),
-            this, SLOT(slotUndoTextChanged(const QString&)));
+    KStandardAction::undo(this,
+                          SLOT(undo()),
+                          actionCollection());
 
-    KStdAction::redo(this,
-                     SLOT(redo()),
-                     actionCollection());
-    connect(&undoManager, SIGNAL(redoAvailable(bool)),
-            this, SLOT(slotRedoAvailable(bool)));
-    connect(&undoManager, SIGNAL(redoTextChanged(const QString&)),
-            this, SLOT(slotRedoTextChanged(const QString&)));
+    KStandardAction::cut(this, SLOT(cut()), actionCollection());
+    KStandardAction::copy(this, SLOT(copy()), actionCollection());
+    KStandardAction::paste(this, SLOT(paste()), actionCollection());
 
-    KStdAction::cut(this, SLOT(cut()), actionCollection());
-    KStdAction::copy(this, SLOT(copy()), actionCollection());
-    KStdAction::paste(this, SLOT(paste()), actionCollection());
-
-    KAction* selectAll = new KAction(i18n("Select All"), actionCollection(), "select_all");
+    QAction* selectAll = actionCollection()->addAction("select_all");
+    selectAll->setText(i18n("Select All"));
     selectAll->setShortcut(Qt::CTRL + Qt::Key_A);
     connect(selectAll, SIGNAL(triggered()), this, SLOT(selectAll()));
 
-    KAction* invertSelection = new KAction(i18n("Invert Selection"), actionCollection(), "invert_selection");
+    QAction* invertSelection = actionCollection()->addAction("invert_selection");
+    invertSelection->setText(i18n("Invert Selection"));
     invertSelection->setShortcut(Qt::CTRL | Qt::SHIFT | Qt::Key_A);
     connect(invertSelection, SIGNAL(triggered()), this, SLOT(invertSelection()));
 
     // setup 'View' menu
-    KStdAction::zoomIn(this,
-                       SLOT(zoomIn()),
-                       actionCollection());
+    KStandardAction::zoomIn(this,
+                            SLOT(zoomIn()),
+                            actionCollection());
 
-    KStdAction::zoomOut(this,
-                        SLOT(zoomOut()),
-                        actionCollection());
+    KStandardAction::zoomOut(this,
+                             SLOT(zoomOut()),
+                             actionCollection());
 
-    KToggleAction* iconsView = new KToggleAction(i18n("Icons"), actionCollection(), "icons");
+    KToggleAction* iconsView = actionCollection()->add<KToggleAction>("icons");
+    iconsView->setText(i18n("Icons"));
     iconsView->setShortcut(Qt::CTRL | Qt::Key_1);
-    iconsView->setIcon(KIcon("view_icon"));
+    iconsView->setIcon(KIcon("view-icon"));
     connect(iconsView, SIGNAL(triggered()), this, SLOT(setIconsView()));
 
-    KToggleAction* detailsView = new KToggleAction(i18n("Details"), actionCollection(), "details");
+    KToggleAction* detailsView = actionCollection()->add<KToggleAction>("details");
+    detailsView->setText(i18n("Details"));
     detailsView->setShortcut(Qt::CTRL | Qt::Key_2);
-    detailsView->setIcon(KIcon("view_text"));
+    detailsView->setIcon(KIcon("fileview-text"));
     connect(detailsView, SIGNAL(triggered()), this, SLOT(setDetailsView()));
 
+    KToggleAction* columnView = actionCollection()->add<KToggleAction>("columns");
+    columnView->setText(i18n("Columns"));
+    columnView->setShortcut(Qt::CTRL | Qt::Key_3);
+    columnView->setIcon(KIcon("view-tree"));
+    connect(columnView, SIGNAL(triggered()), this, SLOT(setColumnView()));
+
     QActionGroup* viewModeGroup = new QActionGroup(this);
     viewModeGroup->addAction(iconsView);
     viewModeGroup->addAction(detailsView);
+    viewModeGroup->addAction(columnView);
 
-    KToggleAction* sortByName = new KToggleAction(i18n("By Name"), actionCollection(), "by_name");
+    KToggleAction* sortByName = actionCollection()->add<KToggleAction>("by_name");
+    sortByName->setText(i18n("By Name"));
     connect(sortByName, SIGNAL(triggered()), this, SLOT(sortByName()));
 
-    KToggleAction* sortBySize = new KToggleAction(i18n("By Size"), actionCollection(), "by_size");
+    KToggleAction* sortBySize = actionCollection()->add<KToggleAction>("by_size");
+    sortBySize->setText(i18n("By Size"));
     connect(sortBySize, SIGNAL(triggered()), this, SLOT(sortBySize()));
 
-    KToggleAction* sortByDate = new KToggleAction(i18n("By Date"), actionCollection(), "by_date");
+    KToggleAction* sortByDate = actionCollection()->add<KToggleAction>("by_date");
+    sortByDate->setText(i18n("By Date"));
     connect(sortByDate, SIGNAL(triggered()), this, SLOT(sortByDate()));
 
+    KToggleAction* sortByPermissions = actionCollection()->add<KToggleAction>("by_permissions");
+    sortByPermissions->setText(i18n("By Permissions"));
+    connect(sortByPermissions, SIGNAL(triggered()), this, SLOT(sortByPermissions()));
+
+    KToggleAction* sortByOwner = actionCollection()->add<KToggleAction>("by_owner");
+    sortByOwner->setText(i18n("By Owner"));
+    connect(sortByOwner, SIGNAL(triggered()), this, SLOT(sortByOwner()));
+
+    KToggleAction* sortByGroup = actionCollection()->add<KToggleAction>("by_group");
+    sortByGroup->setText(i18n("By Group"));
+    connect(sortByGroup, SIGNAL(triggered()), this, SLOT(sortByGroup()));
+
     QActionGroup* sortGroup = new QActionGroup(this);
     sortGroup->addAction(sortByName);
     sortGroup->addAction(sortBySize);
     sortGroup->addAction(sortByDate);
+    sortGroup->addAction(sortByPermissions);
+    sortGroup->addAction(sortByOwner);
+    sortGroup->addAction(sortByGroup);
 
-    KToggleAction* sortDescending = new KToggleAction(i18n("Descending"), actionCollection(), "descending");
+    KToggleAction* sortDescending = actionCollection()->add<KToggleAction>("descending");
+    sortDescending->setText(i18n("Descending"));
     connect(sortDescending, SIGNAL(triggered()), this, SLOT(toggleSortOrder()));
 
-    KToggleAction* showPreview = new KToggleAction(i18n("Show Preview"), actionCollection(), "show_preview");
+    KToggleAction* sortCategorized = actionCollection()->add<KToggleAction>("categorized");
+    sortCategorized->setText(i18n("Categorized"));
+    connect(sortCategorized, SIGNAL(triggered()), this, SLOT(toggleSortCategorization()));
+
+    KToggleAction* clearInfo = actionCollection()->add<KToggleAction>("clear_info");
+    clearInfo->setText(i18n("No Information"));
+    connect(clearInfo, SIGNAL(triggered()), this, SLOT(clearInfo()));
+
+    KToggleAction* showMimeInfo = actionCollection()->add<KToggleAction>("show_mime_info");
+    showMimeInfo->setText(i18n("Type"));
+    connect(showMimeInfo, SIGNAL(triggered()), this, SLOT(showMimeInfo()));
+
+    KToggleAction* showSizeInfo = actionCollection()->add<KToggleAction>("show_size_info");
+    showSizeInfo->setText(i18n("Size"));
+    connect(showSizeInfo, SIGNAL(triggered()), this, SLOT(showSizeInfo()));
+
+    KToggleAction* showDateInfo = actionCollection()->add<KToggleAction>("show_date_info");
+    showDateInfo->setText(i18n("Date"));
+    connect(showDateInfo, SIGNAL(triggered()), this, SLOT(showDateInfo()));
+
+    QActionGroup* infoGroup = new QActionGroup(this);
+    infoGroup->addAction(clearInfo);
+    infoGroup->addAction(showMimeInfo);
+    infoGroup->addAction(showSizeInfo);
+    infoGroup->addAction(showDateInfo);
+
+    KToggleAction* showPreview = actionCollection()->add<KToggleAction>("show_preview");
+    showPreview->setText(i18n("Preview"));
+    showPreview->setIcon(KIcon("thumbnail-show"));
     connect(showPreview, SIGNAL(triggered()), this, SLOT(togglePreview()));
 
-    KToggleAction* showHiddenFiles = new KToggleAction(i18n("Show Hidden Files"), actionCollection(), "show_hidden_files");
-    //showHiddenFiles->setShortcut(Qt::ALT | Qt::Key_      KDE4-TODO: what Qt-Key represents '.'?
+    KToggleAction* showHiddenFiles = actionCollection()->add<KToggleAction>("show_hidden_files");
+    showHiddenFiles->setText(i18n("Show Hidden Files"));
+    showHiddenFiles->setShortcut(Qt::ALT | Qt::Key_Period);
     connect(showHiddenFiles, SIGNAL(triggered()), this, SLOT(toggleShowHiddenFiles()));
 
-    KToggleAction* split = new KToggleAction(i18n("Split View"), actionCollection(), "split_view");
+    KToggleAction* split = actionCollection()->add<KToggleAction>("split_view");
+    split->setText(i18n("Split"));
     split->setShortcut(Qt::Key_F10);
-    split->setIcon(KIcon("view_left_right"));
+    split->setIcon(KIcon("view-left-right"));
     connect(split, SIGNAL(triggered()), this, SLOT(toggleSplitView()));
 
-    KAction* reload = new KAction(i18n("Reload"), "F5", actionCollection(), "reload");
+    QAction* reload = actionCollection()->addAction("reload");
+    reload->setText(i18n("Reload"));
     reload->setShortcut(Qt::Key_F5);
-    reload->setIcon(KIcon("reload"));
+    reload->setIcon(KIcon("view-refresh"));
     connect(reload, SIGNAL(triggered()), this, SLOT(reloadView()));
 
-    KAction* stop = new KAction(i18n("Stop"), actionCollection(), "stop");
-    stop->setIcon(KIcon("stop"));
+    QAction* stop = actionCollection()->addAction("stop");
+    stop->setText(i18n("Stop"));
+    stop->setIcon(KIcon("process-stop"));
     connect(stop, SIGNAL(triggered()), this, SLOT(stopLoading()));
 
-    KToggleAction* showFullLocation = new KToggleAction(i18n("Show Full Location"), actionCollection(), "editable_location");
+    // TODO: the URL navigator must emit a signal if the editable state has been
+    // changed, so that the corresponding showFullLocation action is updated. Also
+    // the naming "Show full Location" is currently confusing...
+    KToggleAction* showFullLocation = actionCollection()->add<KToggleAction>("editable_location");
+    showFullLocation->setText(i18n("Show Full Location"));
     showFullLocation->setShortcut(Qt::CTRL | Qt::Key_L);
     connect(showFullLocation, SIGNAL(triggered()), this, SLOT(toggleEditLocation()));
 
-    KToggleAction* editLocation = new KToggleAction(i18n("Edit Location"), actionCollection(), "edit_location");
+    QAction* editLocation = actionCollection()->addAction("edit_location");
+    editLocation->setText(i18n("Edit Location"));
     editLocation->setShortcut(Qt::Key_F6);
     connect(editLocation, SIGNAL(triggered()), this, SLOT(editLocation()));
 
-    KAction* adjustViewProps = new KAction(i18n("Adjust View Properties..."), actionCollection(), "view_properties");
+    QAction* adjustViewProps = actionCollection()->addAction("view_properties");
+    adjustViewProps->setText(i18n("Adjust View Properties..."));
     connect(adjustViewProps, SIGNAL(triggered()), this, SLOT(adjustViewProperties()));
 
     // setup 'Go' menu
-    KStdAction::back(this, SLOT(goBack()), actionCollection());
-    KStdAction::forward(this, SLOT(goForward()), actionCollection());
-    KStdAction::up(this, SLOT(goUp()), actionCollection());
-    KStdAction::home(this, SLOT(goHome()), actionCollection());
+    KStandardAction::back(this, SLOT(goBack()), actionCollection());
+    KStandardAction::forward(this, SLOT(goForward()), actionCollection());
+    KStandardAction::up(this, SLOT(goUp()), actionCollection());
+    KStandardAction::home(this, SLOT(goHome()), actionCollection());
 
     // setup 'Tools' menu
-    KAction* openTerminal = new KAction(i18n("Open Terminal"), actionCollection(), "open_terminal");
+    QAction* openTerminal = actionCollection()->addAction("open_terminal");
+    openTerminal->setText(i18n("Open Terminal"));
     openTerminal->setShortcut(Qt::Key_F4);
     openTerminal->setIcon(KIcon("konsole"));
     connect(openTerminal, SIGNAL(triggered()), this, SLOT(openTerminal()));
 
-    KAction* findFile = new KAction(i18n("Find File..."), actionCollection(), "find_file");
+    QAction* findFile = actionCollection()->addAction("find_file");
+    findFile->setText(i18n("Find File..."));
     findFile->setShortcut(Qt::Key_F);
-    findFile->setIcon(KIcon("filefind"));
+    findFile->setIcon(KIcon("file-find"));
     connect(findFile, SIGNAL(triggered()), this, SLOT(findFile()));
 
-    KToggleAction* showFilterBar = new KToggleAction(i18n("Show Filter Bar"), actionCollection(), "show_filter_bar");
+    KToggleAction* showFilterBar = actionCollection()->add<KToggleAction>("show_filter_bar");
+    showFilterBar->setText(i18n("Show Filter Bar"));
     showFilterBar->setShortcut(Qt::Key_Slash);
     connect(showFilterBar, SIGNAL(triggered()), this, SLOT(showFilterBar()));
 
-    KAction* compareFiles = new KAction(i18n("Compare Files"), actionCollection(), "compare_files");
+    QAction* compareFiles = actionCollection()->addAction("compare_files");
+    compareFiles->setText(i18n("Compare Files"));
     compareFiles->setIcon(KIcon("kompare"));
     compareFiles->setEnabled(false);
     connect(compareFiles, SIGNAL(triggered()), this, SLOT(compareFiles()));
 
     // setup 'Settings' menu
-    KStdAction::preferences(this, SLOT(editSettings()), actionCollection());
+    KStandardAction::preferences(this, SLOT(editSettings()), actionCollection());
 }
 
 void DolphinMainWindow::setupDockWidgets()
 {
-    QDockWidget *shortcutsDock = new QDockWidget(i18n("Shortcuts"));
-
-    shortcutsDock->setObjectName("shortcutsDock");
-    shortcutsDock->setWidget(new BookmarksSidebarPage(this));
-
-    shortcutsDock->toggleViewAction()->setObjectName("show_shortcuts_pane");
-    shortcutsDock->toggleViewAction()->setText(i18n("Show Shortcuts Panel"));
-    actionCollection()->insert(shortcutsDock->toggleViewAction());
-
-    addDockWidget(Qt::LeftDockWidgetArea, shortcutsDock);
-
-    QDockWidget *infoDock = new QDockWidget(i18n("Information"));
+    // TODO: there's a lot copy/paste code here. Provide a generic approach
+    // after the dock concept has been finalized.
 
+    // setup "Information"
+    QDockWidget* infoDock = new QDockWidget(i18n("Information"), this);
     infoDock->setObjectName("infoDock");
-    infoDock->setWidget(new InfoSidebarPage(this));
+    infoDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
+    SidebarPage* infoWidget = new InfoSidebarPage(infoDock);
+    infoDock->setWidget(infoWidget);
+
 
-    infoDock->toggleViewAction()->setObjectName("show_info_pane");
     infoDock->toggleViewAction()->setText(i18n("Show Information Panel"));
-    actionCollection()->insert(infoDock->toggleViewAction());
+    actionCollection()->addAction("show_info_panel", infoDock->toggleViewAction());
 
     addDockWidget(Qt::RightDockWidgetArea, infoDock);
-}
+    connectSidebarPage(infoWidget);
 
-void DolphinMainWindow::setupCreateNewMenuActions()
-{
-    // Parts of the following code have been taken
-    // from the class KNewMenu located in
-    // libqonq/knewmenu.h of Konqueror.
-    //  Copyright (C) 1998, 1999 David Faure <faure@kde.org>
-    //                2003       Sven Leiber <s.leiber@web.de>
-
-    QStringList files = actionCollection()->instance()->dirs()->findAllResources("templates");
-    for (QStringList::Iterator it = files.begin() ; it != files.end(); ++it) {
-        if ((*it)[0] != '.' ) {
-            KSimpleConfig config(*it, true);
-            config.setDesktopGroup();
-
-            // tricky solution to ensure that TextFile is at the beginning
-            // because this filetype is the most used (according kde-core discussion)
-            const QString name(config.readEntry("Name"));
-            QString key(name);
-
-            const QString path(config.readPathEntry("Url"));
-            if (!path.endsWith("emptydir")) {
-                if (path.endsWith("TextFile.txt")) {
-                    key = "1" + key;
-                }
-                else if (!KDesktopFile::isDesktopFile(path)) {
-                    key = "2" + key;
-                }
-                else if (path.endsWith("Url.desktop")){
-                    key = "3" + key;
-                }
-                else if (path.endsWith("Program.desktop")){
-                    key = "4" + key;
-                }
-                else {
-                    key = "5";
-                }
-
-                const QString icon(config.readEntry("Icon"));
-                const QString comment(config.readEntry("Comment"));
-                const QString type(config.readEntry("Type"));
-
-                const QString filePath(*it);
-
-
-                if (type == "Link") {
-                    CreateFileEntry entry;
-                    entry.name = name;
-                    entry.icon = icon;
-                    entry.comment = comment;
-                    entry.templatePath = filePath;
-                    m_createFileTemplates.insert(key, entry);
-                }
-            }
-        }
-    }
-    m_createFileTemplates.sort();
-
-    unplugActionList("create_actions");
-    KSortableList<CreateFileEntry, QString>::ConstIterator it = m_createFileTemplates.begin();
-    KSortableList<CreateFileEntry, QString>::ConstIterator end = m_createFileTemplates.end();
-    /* KDE4-TODO: don't port this code; use KNewMenu instead
-    while (it != end) {
-        CreateFileEntry entry = (*it).value();
-        KAction* action = new KAction(entry.name);
-        action->setIcon(entry.icon);
-        action->setName((*it).index());
-        connect(action, SIGNAL(activated()),
-                this, SLOT(createFile()));
-
-        const QChar section = ((*it).index()[0]);
-        switch (section) {
-            case '1':
-            case '2': {
-                m_fileGroupActions.append(action);
-                break;
-            }
+    // setup "Tree View"
+    QDockWidget* treeViewDock = new QDockWidget(i18n("Folders")); // TODO: naming?
+    treeViewDock->setObjectName("treeViewDock");
+    treeViewDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
+    TreeViewSidebarPage* treeWidget = new TreeViewSidebarPage(treeViewDock);
+    treeViewDock->setWidget(treeWidget);
 
-            case '3':
-            case '4': {
-                // TODO: not used yet. See documentation of DolphinMainWindow::linkGroupActions()
-                // and DolphinMainWindow::linkToDeviceActions() in the header file for details.
-                //m_linkGroupActions.append(action);
-                break;
-            }
+    treeViewDock->toggleViewAction()->setText(i18n("Show Folders Panel"));
+    actionCollection()->addAction("show_folders_panel", treeViewDock->toggleViewAction());
 
-            case '5': {
-                // TODO: not used yet. See documentation of DolphinMainWindow::linkGroupActions()
-                // and DolphinMainWindow::linkToDeviceActions() in the header file for details.
-                //m_linkToDeviceActions.append(action);
-                break;
-            }
-            default:
-                break;
-        }
-        ++it;
+    addDockWidget(Qt::LeftDockWidgetArea, treeViewDock);
+    connectSidebarPage(treeWidget);
+
+    const bool firstRun = DolphinSettings::instance().generalSettings()->firstRun();
+    if (firstRun) {
+        infoDock->hide();
+        treeViewDock->hide();
     }
 
-    plugActionList("create_file_group", m_fileGroupActions);
-    //plugActionList("create_link_group", m_linkGroupActions);
-    //plugActionList("link_to_device", m_linkToDeviceActions);*/
+    QDockWidget *placesDock = new QDockWidget(i18n("Places"));
+    placesDock->setObjectName("placesDock");
+    placesDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
+    KFilePlacesView *listView = new KFilePlacesView(placesDock);
+    placesDock->setWidget(listView);
+    listView->setModel(DolphinSettings::instance().placesModel());
+    addDockWidget(Qt::LeftDockWidgetArea, placesDock);
+    connect(listView, SIGNAL(urlChanged(KUrl)),
+            this, SLOT(changeUrl(KUrl)));
+    connect(this, SIGNAL(urlChanged(KUrl)),
+            listView, SLOT(setUrl(KUrl)));
 }
 
 void DolphinMainWindow::updateHistory()
 {
-    int index = 0;
-    const Q3ValueList<UrlNavigator::HistoryElem> list = m_activeView->urlHistory(index);
+    const KUrlNavigator* urlNavigator = m_activeView->urlNavigator();
+    const int index = urlNavigator->historyIndex();
 
     QAction* backAction = actionCollection()->action("go_back");
     if (backAction != 0) {
-        backAction->setEnabled(index < static_cast<int>(list.count()) - 1);
+        backAction->setEnabled(index < urlNavigator->historySize() - 1);
     }
 
     QAction* forwardAction = actionCollection()->action("go_forward");
@@ -1480,8 +1347,7 @@ void DolphinMainWindow::updateEditActions()
     const KFileItemList list = m_activeView->selectedItems();
     if (list.isEmpty()) {
         stateChanged("has_no_selection");
-    }
-    else {
+    } else {
         stateChanged("has_selection");
 
         QAction* renameAction = actionCollection()->action("rename");
@@ -1511,29 +1377,29 @@ void DolphinMainWindow::updateEditActions()
 
 void DolphinMainWindow::updateViewActions()
 {
-    QAction* zoomInAction = actionCollection()->action(KStdAction::stdName(KStdAction::ZoomIn));
+    QAction* zoomInAction = actionCollection()->action(KStandardAction::stdName(KStandardAction::ZoomIn));
     if (zoomInAction != 0) {
         zoomInAction->setEnabled(m_activeView->isZoomInPossible());
     }
 
-    QAction* zoomOutAction = actionCollection()->action(KStdAction::stdName(KStdAction::ZoomOut));
+    QAction* zoomOutAction = actionCollection()->action(KStandardAction::stdName(KStandardAction::ZoomOut));
     if (zoomOutAction != 0) {
         zoomOutAction->setEnabled(m_activeView->isZoomOutPossible());
     }
 
     QAction* action = 0;
     switch (m_activeView->mode()) {
-        case DolphinView::IconsView:
-            action = actionCollection()->action("icons");
-            break;
-        case DolphinView::DetailsView:
-            action = actionCollection()->action("details");
-            break;
-        //case DolphinView::PreviewsView:
-        //    action = actionCollection()->action("previews");
-        //    break;
-        default:
-            break;
+    case DolphinView::IconsView:
+        action = actionCollection()->action("icons");
+        break;
+    case DolphinView::DetailsView:
+        action = actionCollection()->action("details");
+        break;
+    case DolphinView::ColumnView:
+        action = actionCollection()->action("columns");
+        break;
+    default:
+        break;
     }
 
     if (action != 0) {
@@ -1543,74 +1409,52 @@ void DolphinMainWindow::updateViewActions()
 
     slotSortingChanged(m_activeView->sorting());
     slotSortOrderChanged(m_activeView->sortOrder());
+    slotCategorizedSortingChanged();
+    slotAdditionalInfoChanged(m_activeView->additionalInfo());
 
     KToggleAction* showFilterBarAction =
         static_cast<KToggleAction*>(actionCollection()->action("show_filter_bar"));
     showFilterBarAction->setChecked(m_activeView->isFilterBarVisible());
 
+    KToggleAction* showPreviewAction =
+        static_cast<KToggleAction*>(actionCollection()->action("show_preview"));
+    showPreviewAction->setChecked(m_activeView->showPreview());
+
     KToggleAction* showHiddenFilesAction =
         static_cast<KToggleAction*>(actionCollection()->action("show_hidden_files"));
     showHiddenFilesAction->setChecked(m_activeView->showHiddenFiles());
 
     KToggleAction* splitAction = static_cast<KToggleAction*>(actionCollection()->action("split_view"));
     splitAction->setChecked(m_view[SecondaryIdx] != 0);
+
+    KToggleAction* editableLocactionAction =
+        static_cast<KToggleAction*>(actionCollection()->action("editable_location"));
+    editableLocactionAction->setChecked(m_activeView->isUrlEditable());
 }
 
 void DolphinMainWindow::updateGoActions()
 {
-    QAction* goUpAction = actionCollection()->action(KStdAction::stdName(KStdAction::Up));
+    QAction* goUpAction = actionCollection()->action(KStandardAction::stdName(KStandardAction::Up));
     const KUrl& currentUrl = m_activeView->url();
     goUpAction->setEnabled(currentUrl.upUrl() != currentUrl);
 }
 
-void DolphinMainWindow::updateViewProperties(const KUrl::List& urls)
-{
-    if (urls.isEmpty()) {
-        return;
-    }
-
-    // Updating the view properties might take up to several seconds
-    // when dragging several thousand Urls. Writing a KIO slave for this
-    // use case is not worth the effort, but at least the main widget
-    // must be disabled and a progress should be shown.
-    ProgressIndicator progressIndicator(this,
-                                        i18n("Updating view properties..."),
-                                        QString::null,
-                                        urls.count());
-
-    KUrl::List::ConstIterator end = urls.end();
-    for(KUrl::List::ConstIterator it = urls.begin(); it != end; ++it) {
-        progressIndicator.execOperation();
-
-        ViewProperties props(*it);
-        props.save();
-    }
-}
-
 void DolphinMainWindow::copyUrls(const KUrl::List& source, const KUrl& dest)
 {
-    KIO::Job* job = KIO::copy(source, dest);
-    addPendingUndoJob(job, DolphinCommand::Copy, source, dest);
+    KonqOperations::copy(this, KonqOperations::COPY, source, dest);
+    m_undoCommandTypes.append(KonqUndoManager::COPY);
 }
 
 void DolphinMainWindow::moveUrls(const KUrl::List& source, const KUrl& dest)
 {
-    KIO::Job* job = KIO::move(source, dest);
-    addPendingUndoJob(job, DolphinCommand::Move, source, dest);
+    KonqOperations::copy(this, KonqOperations::MOVE, source, dest);
+    m_undoCommandTypes.append(KonqUndoManager::MOVE);
 }
 
-void DolphinMainWindow::addPendingUndoJob(KIO::Job* job,
-                                          DolphinCommand::Type commandType,
-                                          const KUrl::List& source,
-                                          const KUrl& dest)
+void DolphinMainWindow::linkUrls(const KUrl::List& source, const KUrl& dest)
 {
-    connect(job, SIGNAL(result(KJob*)),
-            this, SLOT(addUndoOperation(KJob*)));
-
-    UndoInfo undoInfo;
-    undoInfo.id = job->progressId();
-    undoInfo.command = DolphinCommand(commandType, source, dest);
-    m_pendingUndoJobs.append(undoInfo);
+    KonqOperations::copy(this, KonqOperations::LINK, source, dest);
+    m_undoCommandTypes.append(KonqUndoManager::LINK);
 }
 
 void DolphinMainWindow::clearStatusBar()
@@ -1623,23 +1467,60 @@ void DolphinMainWindow::connectViewSignals(int viewIndex)
     DolphinView* view = m_view[viewIndex];
     connect(view, SIGNAL(modeChanged()),
             this, SLOT(slotViewModeChanged()));
+    connect(view, SIGNAL(showPreviewChanged()),
+            this, SLOT(slotShowPreviewChanged()));
     connect(view, SIGNAL(showHiddenFilesChanged()),
             this, SLOT(slotShowHiddenFilesChanged()));
+    connect(view, SIGNAL(categorizedSortingChanged()),
+            this, SLOT(slotCategorizedSortingChanged()));
     connect(view, SIGNAL(sortingChanged(DolphinView::Sorting)),
             this, SLOT(slotSortingChanged(DolphinView::Sorting)));
     connect(view, SIGNAL(sortOrderChanged(Qt::SortOrder)),
             this, SLOT(slotSortOrderChanged(Qt::SortOrder)));
-    connect(view, SIGNAL(selectionChanged()),
-            this, SLOT(slotSelectionChanged()));
+    connect(view, SIGNAL(additionalInfoChanged(KFileItemDelegate::AdditionalInformation)),
+            this, SLOT(slotAdditionalInfoChanged(KFileItemDelegate::AdditionalInformation)));
+    connect(view, SIGNAL(selectionChanged(KFileItemList)),
+            this, SLOT(slotSelectionChanged(KFileItemList)));
     connect(view, SIGNAL(showFilterBarChanged(bool)),
             this, SLOT(updateFilterBarAction(bool)));
+    connect(view, SIGNAL(urlChanged(KUrl)),
+            this, SLOT(changeUrl(KUrl)));
 
-    const UrlNavigator* navigator = view->urlNavigator();
+    const KUrlNavigator* navigator = view->urlNavigator();
     connect(navigator, SIGNAL(urlChanged(const KUrl&)),
-            this, SLOT(slotUrlChanged(const KUrl&)));
+            this, SLOT(changeUrl(const KUrl&)));
     connect(navigator, SIGNAL(historyChanged()),
             this, SLOT(slotHistoryChanged()));
+}
+void DolphinMainWindow::connectSidebarPage(SidebarPage* page)
+{
+    connect(page, SIGNAL(changeUrl(KUrl)),
+            this, SLOT(changeUrl(KUrl)));
+    connect(page, SIGNAL(changeSelection(KFileItemList)),
+            this, SLOT(changeSelection(KFileItemList)));
+    connect(page, SIGNAL(urlsDropped(KUrl::List, KUrl)),
+            this, SLOT(dropUrls(KUrl::List, KUrl)));
+
+    connect(this, SIGNAL(urlChanged(KUrl)),
+            page, SLOT(setUrl(KUrl)));
+    connect(this, SIGNAL(selectionChanged(KFileItemList)),
+            page, SLOT(setSelection(KFileItemList)));
+}
 
+DolphinMainWindow::UndoUiInterface::UndoUiInterface(DolphinMainWindow* mainWin) :
+        KonqUndoManager::UiInterface(mainWin),
+        m_mainWin(mainWin)
+{
+    Q_ASSERT(m_mainWin != 0);
+}
+
+DolphinMainWindow::UndoUiInterface::~UndoUiInterface()
+{}
+
+void DolphinMainWindow::UndoUiInterface::jobError(KIO::Job* job)
+{
+    DolphinStatusBar* statusBar = m_mainWin->activeView()->statusBar();
+    statusBar->setMessage(job->errorString(), DolphinStatusBar::Error);
 }
 
 #include "dolphinmainwindow.moc"