]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Forwardport 773570:
authorDavid Faure <faure@kde.org>
Mon, 11 Feb 2008 12:44:46 +0000 (12:44 +0000)
committerDavid Faure <faure@kde.org>
Mon, 11 Feb 2008 12:44:46 +0000 (12:44 +0000)
Factorize all the view-related action handling to DolphinViewActionHandler, to remove code duplication between mainwindow and part, and to remove my code-splitting with the static createFooAction methods in the view.

svn path=/trunk/KDE/kdebase/apps/; revision=773572

51 files changed:
COPYING.DOC [moved from COPYING-DOCS with 100% similarity]
src/CMakeLists.txt
src/dolphin.desktop
src/dolphin_generalsettings.kcfg
src/dolphincategorydrawer.cpp
src/dolphincategorydrawer.h
src/dolphincolumnview.cpp
src/dolphincolumnwidget.cpp
src/dolphincolumnwidget.h
src/dolphincontextmenu.cpp
src/dolphindetailsview.cpp
src/dolphindetailsview.h
src/dolphindropcontroller.cpp
src/dolphinfileplacesview.cpp [new file with mode: 0644]
src/dolphinfileplacesview.h [new file with mode: 0644]
src/dolphiniconsview.cpp
src/dolphiniconsview.h
src/dolphinmainwindow.cpp
src/dolphinmainwindow.h
src/dolphinmodel.cpp
src/dolphinpart.desktop
src/dolphinpart.rc
src/dolphinsettingsdialog.cpp
src/dolphinsettingsdialog.h
src/dolphinui.rc
src/dolphinview.cpp
src/dolphinview.h
src/dolphinviewcontainer.cpp
src/generalsettingspage.cpp
src/generalsettingspage.h
src/generalviewsettingspage.cpp
src/generalviewsettingspage.h
src/iconmanager.cpp [new file with mode: 0644]
src/iconmanager.h [new file with mode: 0644]
src/infosidebarpage.cpp
src/kcategorizedview.cpp [deleted file]
src/kcategorizedview.h [deleted file]
src/kcategorizedview_p.h [deleted file]
src/kcategorydrawer.cpp [deleted file]
src/kcategorydrawer.h [deleted file]
src/main.cpp
src/pixmapviewer.cpp
src/pixmapviewer.h
src/renamedialog.cpp
src/selectionmanager.cpp [new file with mode: 0644]
src/selectionmanager.h [new file with mode: 0644]
src/selectiontoggle.cpp [new file with mode: 0644]
src/selectiontoggle.h [new file with mode: 0644]
src/startupsettingspage.cpp [new file with mode: 0644]
src/startupsettingspage.h [new file with mode: 0644]
src/viewpropertiesdialog.cpp

similarity index 100%
rename from COPYING-DOCS
rename to COPYING.DOC
index b2cdfd582e8546d398aae6c34143985ac4f007ab..f5a6c3ed9c993307fd1e1f40d8287aabbe27c5c1 100644 (file)
@@ -2,6 +2,8 @@
 add_subdirectory( pics )
 add_subdirectory( tests )
 
+macro_optional_find_package(Soprano)
+
 include_directories( ${KDE4_INCLUDE_DIR} ${QT_INCLUDES} ${BLITZ_INCLUDES} )
 if (Soprano_FOUND)
   include_directories( ${SOPRANO_INCLUDE_DIR} )
@@ -15,19 +17,20 @@ set(dolphinprivate_LIB_SRCS
     dolphiniconsview.cpp
     dolphincolumnview.cpp
     dolphincolumnwidget.cpp
+    dolphindropcontroller.cpp
+    dolphinsortfilterproxymodel.cpp
     draganddrophelper.cpp
-    kcategorizedview.cpp
-    kcategorydrawer.cpp
     dolphinmodel.cpp
     dolphinsettings.cpp
     dolphincategorydrawer.cpp
-    viewproperties.cpp
-    dolphinsortfilterproxymodel.cpp
-    renamedialog.cpp
     dolphinview.cpp
     dolphinviewactionhandler.cpp
+    iconmanager.cpp
     ratingpainter.cpp
-    dolphindropcontroller.cpp
+    renamedialog.cpp
+    selectiontoggle.cpp
+    selectionmanager.cpp
+    viewproperties.cpp
     )
 
 kde4_add_kcfg_files(dolphinprivate_LIB_SRCS
@@ -88,6 +91,7 @@ set(dolphin_SRCS
    dolphinstatusbar.cpp
    dolphindirlister.cpp
    dolphincontextmenu.cpp
+   dolphinfileplacesview.cpp
    dolphinsettingsdialog.cpp
    draganddrophelper.cpp
    filterbar.cpp
@@ -101,6 +105,7 @@ set(dolphin_SRCS
    pixmapviewer.cpp
    settingspagebase.cpp
    sidebarpage.cpp
+   startupsettingspage.cpp
    statusbarspaceinfo.cpp
    statusbarmessagelabel.cpp
    terminalsidebarpage.cpp
index 7bd80e9ab66fa57576de587d1d48eba0b0749bd3..f640ee49b5fb6043d289b72ed62167d830420550 100644 (file)
@@ -2,6 +2,7 @@
 Name=Dolphin
 Name[ar]=الدولفين
 Name[hi]=डॉल्फ़िन
+Name[kn]=ಡಾಲ್ಫಿನ್
 Name[ne]=डल्फिन
 Name[pa]=ਡਾਲਫਿਨ
 Name[sr]=Делфин
@@ -22,6 +23,7 @@ GenericName[csb]=Menadżer lopków
 GenericName[da]=Filhåndtering
 GenericName[de]=Dateimanager
 GenericName[el]=Διαχειριστής αρχείων
+GenericName[eo]=Dosieradministrilo
 GenericName[es]=Gestor de archivos
 GenericName[et]=Failihaldur
 GenericName[eu]=Fitxategi kudeatzailea
@@ -39,6 +41,7 @@ GenericName[it]=Gestione file
 GenericName[ja]=ファイルマネージャ
 GenericName[kk]=Файл менеджері
 GenericName[km]=កម្មវិធី​គ្រប់គ្រង​ឯកសារ
+GenericName[kn]=ಕಡತ ವ್ಯವಸ್ಥಾಪಕ
 GenericName[ko]=파일 관리자
 GenericName[ku]=Rêveberê Pelan
 GenericName[lv]=Failu pārvaldnieks
@@ -52,6 +55,7 @@ GenericName[pa]=ਫਾਇਲ ਮੈਨੇਜਰ
 GenericName[pl]=Menedżer plików
 GenericName[pt]=Gestor de Ficheiros
 GenericName[pt_BR]=Gerenciador de Arquivos
+GenericName[ro]=Manager de fişiere
 GenericName[ru]=Файловый менеджер
 GenericName[se]=Fiilagieđahalli
 GenericName[sl]=Upravitelj datotek
index 19474065aaa856ae1e20101122cdb47ed04bbd19..6149480b31e9d9f6fb6d86b03c132a3340ce5a24 100644 (file)
             <label context="@label">Should the view properties used for all directories</label>
             <default>false</default>
         </entry>
+        <entry name="BrowseThroughArchives" type="Bool">
+            <label context="@label">Browse through archives</label>
+            <default>false</default>
+        </entry>
+        <entry name="ShowSelectionToggle" type="Bool">
+            <label context="@label">Show selection toggle</label>
+            <default>true</default>
+        </entry>
         <entry name="ViewPropsTimestamp" type="DateTime" >
             <label context="@label">Timestamp since when the view properties are valid</label>
         </entry>
index 8148a7b8ed02f0ab8f1d1bd50cf267998786ab76..6cf84560f501c7d912a1125620305bef720a3c4c 100644 (file)
@@ -50,6 +50,8 @@ DolphinCategoryDrawer::~DolphinCategoryDrawer()
 void DolphinCategoryDrawer::drawCategory(const QModelIndex &index, int sortRole,
                                          const QStyleOption &option, QPainter *painter) const
 {
+    Q_UNUSED(sortRole);
+
     QRect starRect = option.rect;
 
     int iconSize = KIconLoader::global()->currentSize(KIconLoader::Small);
index ea70a922bb382f848aa67d094cd37c8b4aba52c1..1cccc620e496bd0a85f0f96ca4f9d0a997d2b899 100644 (file)
@@ -21,7 +21,7 @@
 #ifndef DOLPHINCATEGORYDRAWER_H
 #define DOLPHINCATEGORYDRAWER_H
 
-#include "kcategorydrawer.h"
+#include <kcategorydrawer.h>
 
 #include <QStyleOption>
 #include <QModelIndex>
index bfbc5d9f135e3fab954cc17416a5b4023361a3a6..7e74b7e3452e86b8efbe6da71f17eb2360ad5733 100644 (file)
@@ -370,11 +370,13 @@ void DolphinColumnView::updateDecorationSize()
 {
     ColumnModeSettings* settings = DolphinSettings::instance().columnModeSettings();
     const int iconSize = settings->iconSize();
+    const QSize size(iconSize, iconSize);
+    setIconSize(size);
 
     foreach (QObject* object, viewport()->children()) {
         if (object->inherits("QListView")) {
             DolphinColumnWidget* widget = static_cast<DolphinColumnWidget*>(object);
-            widget->setDecorationSize(QSize(iconSize, iconSize));
+            widget->setDecorationSize(size);
         }
     }
 
@@ -393,8 +395,12 @@ void DolphinColumnView::updateColumnsBackground(bool active)
     m_active = active;
 
     // dim the background of the viewport
-    QPalette palette;
-    palette.setColor(viewport()->backgroundRole(), QColor(0, 0, 0, 0));
+    const QPalette::ColorRole role = viewport()->backgroundRole();
+    QColor background = viewport()->palette().color(role);
+    background.setAlpha(0);  // make background transparent
+
+    QPalette palette = viewport()->palette();
+    palette.setColor(role, background);
     viewport()->setPalette(palette);
 
     foreach (DolphinColumnWidget* column, m_columns) {
@@ -503,8 +509,9 @@ void DolphinColumnView::assureVisibleActiveColumn()
         } else {
             m_animation->setFrameRange(-m_contentX, -newContentX);
         }
-        if(m_animation->state() != QTimeLine::Running)
+        if (m_animation->state() != QTimeLine::Running) {
            m_animation->start();
+        }
     } else if (x < 0) {
         const int newContentX = m_contentX - x;
         if (isRightToLeft()) {
@@ -512,8 +519,9 @@ void DolphinColumnView::assureVisibleActiveColumn()
         } else {
             m_animation->setFrameRange(-m_contentX, -newContentX);
         }
-        if(m_animation->state() != QTimeLine::Running)
+        if (m_animation->state() != QTimeLine::Running) {
            m_animation->start();
+        }
     }
 }
 
index 7cff99398cb94d82b2e283e2df21f2b8efbde9c1..c2ba385ad0b635878c18f337c153a3f2fe9fc6ab 100644 (file)
@@ -26,7 +26,9 @@
 #include "dolphinsortfilterproxymodel.h"
 #include "dolphinsettings.h"
 #include "dolphin_columnmodesettings.h"
+#include "dolphin_generalsettings.h"
 #include "draganddrophelper.h"
+#include "selectionmanager.h"
 
 #include <kcolorscheme.h>
 #include <kdirlister.h>
@@ -37,6 +39,8 @@
 #include <kmimetyperesolver.h>
 #include <konqmimedata.h>
 
+#include "iconmanager.h"
+
 #include <QApplication>
 #include <QClipboard>
 #include <QPainter>
@@ -47,7 +51,6 @@ DolphinColumnWidget::DolphinColumnWidget(QWidget* parent,
                                          const KUrl& url) :
     QListView(parent),
     m_active(true),
-    m_showPreview(false),
     m_view(columnView),
     m_url(url),
     m_childUrl(),
@@ -56,7 +59,7 @@ DolphinColumnWidget::DolphinColumnWidget(QWidget* parent,
     m_dirLister(0),
     m_dolphinModel(0),
     m_proxyModel(0),
-    m_previewJob(0),
+    m_iconManager(0),
     m_dragging(false),
     m_dropRect()
 {
@@ -88,7 +91,7 @@ DolphinColumnWidget::DolphinColumnWidget(QWidget* parent,
     m_font.setBold(settings->boldFont());
 
     const int iconSize = settings->iconSize();
-    m_decorationSize = QSize(iconSize, iconSize);
+    setDecorationSize(QSize(iconSize, iconSize));
 
     KFileItemDelegate* delegate = new KFileItemDelegate(this);
     setItemDelegate(delegate);
@@ -107,8 +110,6 @@ DolphinColumnWidget::DolphinColumnWidget(QWidget* parent,
     m_dirLister->setDelayedMimeTypes(true);
     const bool showHiddenFiles = m_view->m_controller->dolphinView()->showHiddenFiles();
     m_dirLister->setShowingDotFiles(showHiddenFiles);
-    connect(m_dirLister, SIGNAL(newItems(const KFileItemList&)),
-            this, SLOT(generatePreviews(const KFileItemList&)));
 
     m_dolphinModel = new DolphinModel(this);
     m_dolphinModel->setDirLister(m_dirLister);
@@ -119,7 +120,18 @@ DolphinColumnWidget::DolphinColumnWidget(QWidget* parent,
     m_proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
 
     setModel(m_proxyModel);
+    const bool useSelManager = KGlobalSettings::singleClick() &&
+                               DolphinSettings::instance().generalSettings()->showSelectionToggle();
+    if (useSelManager) {
+        SelectionManager* selManager = new SelectionManager(this);
+        connect(selManager, SIGNAL(selectionChanged()),
+                this, SLOT(requestActivation()));
+        connect(m_view->m_controller, SIGNAL(urlChanged(const KUrl&)),
+                selManager, SLOT(reset()));
+}
     new KMimeTypeResolver(this, m_dolphinModel);
+    m_iconManager = new IconManager(this, m_proxyModel);
+    m_iconManager->setShowPreview(m_view->m_controller->dolphinView()->showPreview());
 
     m_dirLister->openUrl(url, KDirLister::NoFlags);
 }
@@ -131,15 +143,11 @@ DolphinColumnWidget::~DolphinColumnWidget()
     delete m_dolphinModel;
     m_dolphinModel = 0;
     m_dirLister = 0; // deleted by m_dolphinModel
-
-    if (m_previewJob != 0) {
-        m_previewJob->kill();
-        m_previewJob = 0;
-    }
 }
 
 void DolphinColumnWidget::setDecorationSize(const QSize& size)
 {
+    setIconSize(size);
     m_decorationSize = size;
     doItemsLayout();
 }
@@ -176,20 +184,24 @@ void DolphinColumnWidget::setShowHiddenFiles(bool show)
 
 void DolphinColumnWidget::setShowPreview(bool show)
 {
-    if (show != m_showPreview) {
-        m_dirLister->stop();
-        m_dirLister->openUrl(m_url, KDirLister::Reload);
-    }
+    m_iconManager->setShowPreview(show);
+
+    m_dirLister->stop();
+    m_dirLister->openUrl(m_url, KDirLister::Reload);
 }
 
 void DolphinColumnWidget::updateBackground()
 {
-    QColor color = KColorScheme(QPalette::Active, KColorScheme::View).background().color();
-    if (!m_active || !m_view->m_active) {
-        color.setAlpha(150);
-    }
+    // TODO: The alpha-value 150 is copied from DolphinView::setActive(). When
+    // cleaning up the cut-indication of DolphinColumnWidget with the code from
+    // DolphinView a common helper-class should be available which can be shared
+    // by all view implementations -> no hardcoded value anymore
+    const QPalette::ColorRole role = viewport()->backgroundRole();
+    QColor color = viewport()->palette().color(role);
+    color.setAlpha((m_active && m_view->m_active) ? 255 : 150);
+
     QPalette palette = viewport()->palette();
-    palette.setColor(viewport()->backgroundRole(), color);
+    palette.setColor(role, color);
     viewport()->setPalette(palette);
 
     update();
@@ -303,12 +315,7 @@ void DolphinColumnWidget::paintEvent(QPaintEvent* event)
 
 void DolphinColumnWidget::mousePressEvent(QMouseEvent* event)
 {
-    m_view->m_controller->requestActivation();
-    if (!m_active) {
-        m_view->requestActivation(this);
-        m_view->m_controller->triggerUrlChangeRequest(m_url);
-    }
-
+    requestActivation();
     QListView::mousePressEvent(event);
 }
 
@@ -359,51 +366,6 @@ void DolphinColumnWidget::triggerItem(const QModelIndex& index)
     m_view->m_controller->triggerItem(item);
 }
 
-void DolphinColumnWidget::generatePreviews(const KFileItemList& items)
-{
-    // TODO: same implementation as in DolphinView; create helper class
-    // for generatePreviews(), showPreview() and isCutItem()
-
-    if (m_view->m_controller->dolphinView()->showPreview()) {
-        if (m_previewJob != 0) {
-            m_previewJob->kill();
-            m_previewJob = 0;
-        }
-
-        m_previewJob = KIO::filePreview(items, 128);
-        connect(m_previewJob, SIGNAL(gotPreview(const KFileItem&, const QPixmap&)),
-                this, SLOT(replaceIcon(const KFileItem&, const QPixmap&)));
-        connect(m_previewJob, SIGNAL(finished(KJob*)),
-                this, SLOT(slotPreviewJobFinished(KJob*)));
-    }
-}
-
-void DolphinColumnWidget::replaceIcon(const KFileItem& item, const QPixmap& pixmap)
-{
-    // TODO: same implementation as in DolphinView; create helper class
-    // for generatePreviews(), showPreview() and isCutItem()
-
-    Q_ASSERT(!item.isNull());
-    const bool showPreview = m_view->m_controller->dolphinView()->showPreview();
-    if (!showPreview || (item.url().directory() != m_dirLister->url().path())) {
-        // the preview job is still working on items of an older URL, hence
-        // the item is not part of the directory model anymore
-        return;
-    }
-
-    const QModelIndex idx = m_dolphinModel->indexForItem(item);
-    if (idx.isValid() && (idx.column() == 0)) {
-        const QMimeData* mimeData = QApplication::clipboard()->mimeData();
-        if (KonqMimeData::decodeIsCutSelection(mimeData) && isCutItem(item)) {
-            KIconEffect iconEffect;
-            const QPixmap cutPixmap = iconEffect.apply(pixmap, KIconLoader::Desktop, KIconLoader::DisabledState);
-            m_dolphinModel->setData(idx, QIcon(cutPixmap), Qt::DecorationRole);
-        } else {
-            m_dolphinModel->setData(idx, QIcon(pixmap), Qt::DecorationRole);
-        }
-    }
-}
-
 void DolphinColumnWidget::slotEntered(const QModelIndex& index)
 {
     const QModelIndex dirIndex = m_proxyModel->mapToSource(index);
@@ -411,10 +373,14 @@ void DolphinColumnWidget::slotEntered(const QModelIndex& index)
     m_view->m_controller->emitItemEntered(item);
 }
 
-void DolphinColumnWidget::slotPreviewJobFinished(KJob* job)
+void DolphinColumnWidget::requestActivation()
 {
-    Q_ASSERT(job == m_previewJob);
-    m_previewJob = 0;
+    m_view->m_controller->requestActivation();
+    if (!m_active) {
+        m_view->requestActivation(this);
+        m_view->m_controller->triggerUrlChangeRequest(m_url);
+        selectionModel()->clear();
+    }
 }
 
 void DolphinColumnWidget::activate()
@@ -432,6 +398,9 @@ void DolphinColumnWidget::activate()
                 this, SLOT(triggerItem(const QModelIndex&)));
     }
 
+    if (selectionModel() && selectionModel()->currentIndex().isValid())
+        selectionModel()->setCurrentIndex(selectionModel()->currentIndex(), QItemSelectionModel::SelectCurrent);
+
     updateBackground();
 }
 
@@ -450,31 +419,12 @@ void DolphinColumnWidget::deactivate()
                    this, SLOT(triggerItem(const QModelIndex&)));
     }
 
+    const QModelIndex current = selectionModel()->currentIndex();
     selectionModel()->clear();
+    selectionModel()->setCurrentIndex(current, QItemSelectionModel::NoUpdate);
     updateBackground();
 }
 
-bool DolphinColumnWidget::isCutItem(const KFileItem& item) const
-{
-    // TODO: same implementation as in DolphinView; create helper class
-    // for generatePreviews(), showPreview() and isCutItem()
-
-    const QMimeData* mimeData = QApplication::clipboard()->mimeData();
-    const KUrl::List cutUrls = KUrl::List::fromMimeData(mimeData);
-
-    const KUrl& itemUrl = item.url();
-    KUrl::List::const_iterator it = cutUrls.begin();
-    const KUrl::List::const_iterator end = cutUrls.end();
-    while (it != end) {
-        if (*it == itemUrl) {
-            return true;
-        }
-        ++it;
-    }
-
-    return false;
-}
-
 KFileItem DolphinColumnWidget::itemForIndex(const QModelIndex& index) const
 {
     const QModelIndex dirIndex = m_proxyModel->mapToSource(index);
index 87024626942b034fe637e0831c50b28f586ca884..87c7ab5771b8f3d2fba1aec2513e290a099785ca 100644 (file)
 class DolphinColumnView;
 class DolphinModel;
 class DolphinSortFilterProxyModel;
+class IconManager;
 class KDirLister;
 class KJob;
 class KFileItem;
 class KFileItemList;
 class QPixmap;
-namespace KIO
-{
-    class PreviewJob;
-}
 
 /**
  * Represents one column inside the DolphinColumnView and has been
@@ -118,26 +115,9 @@ private slots:
      */
     void triggerItem(const QModelIndex& index);
 
-    /**
-     * Generates a preview image for each file item in \a items.
-     * The current preview settings (maximum size, 'Show Preview' menu)
-     * are respected.
-     */
-    void generatePreviews(const KFileItemList& items);
-
-    /**
-     * Replaces the icon of the item \a item by the preview pixmap
-     * \a pixmap.
-     */
-    void replaceIcon(const KFileItem& item, const QPixmap& pixmap);
-
     void slotEntered(const QModelIndex& index);
 
-    /**
-     * Is invoked when the preview job has been finished and
-     * set m_previewJob to 0.
-     */
-    void slotPreviewJobFinished(KJob* job);
+    void requestActivation();
 
 private:
     /** Used by DolphinColumnWidget::setActive(). */
@@ -146,17 +126,10 @@ private:
     /** Used by DolphinColumnWidget::setActive(). */
     void deactivate();
 
-    /**
-     * Returns true, if the item \a item has been cut into
-     * the clipboard.
-     */
-    bool isCutItem(const KFileItem& item) const;
-
     KFileItem itemForIndex(const QModelIndex& index) const;
 
 private:
     bool m_active;
-    bool m_showPreview;
     DolphinColumnView* m_view;
     KUrl m_url;      // URL of the directory that is shown
     KUrl m_childUrl; // URL of the next column that is shown
@@ -168,7 +141,7 @@ private:
     DolphinModel* m_dolphinModel;
     DolphinSortFilterProxyModel* m_proxyModel;
 
-    KIO::PreviewJob* m_previewJob;
+    IconManager* m_iconManager;
 
     bool m_dragging;   // TODO: remove this property when the issue #160611 is solved in Qt 4.4
     QRect m_dropRect;  // TODO: remove this property when the issue #160611 is solved in Qt 4.4
index 601e5f141bbe8fc3ed47d828100c93a050712305..2dcb916a55c9fdb1b31ed096cec70a3152723f7b 100644 (file)
@@ -230,7 +230,7 @@ void DolphinContextMenu::openViewportContextMenu()
     popup->addMenu(newMenu->menu());
     popup->addSeparator();
 
-    QAction* pasteAction = m_mainWindow->actionCollection()->action(KStandardAction::stdName(KStandardAction::Paste));
+    QAction* pasteAction = m_mainWindow->actionCollection()->action(KStandardAction::name(KStandardAction::Paste));
     popup->addAction(pasteAction);
 
     // setup 'View Mode' menu
@@ -279,9 +279,9 @@ void DolphinContextMenu::insertDefaultItemActions(KMenu* popup)
     const KActionCollection* collection = m_mainWindow->actionCollection();
 
     // insert 'Cut', 'Copy' and 'Paste'
-    QAction* cutAction = collection->action(KStandardAction::stdName(KStandardAction::Cut));
-    QAction* copyAction  = collection->action(KStandardAction::stdName(KStandardAction::Copy));
-    QAction* pasteAction = collection->action(KStandardAction::stdName(KStandardAction::Paste));
+    QAction* cutAction = collection->action(KStandardAction::name(KStandardAction::Cut));
+    QAction* copyAction  = collection->action(KStandardAction::name(KStandardAction::Copy));
+    QAction* pasteAction = collection->action(KStandardAction::name(KStandardAction::Paste));
 
     popup->addAction(cutAction);
     popup->addAction(copyAction);
index 2861c134fb6d90da874e47f74924109716079d2d..3be22fb4262db912a59e6301f629e99ab5612ef1 100644 (file)
 #include "dolphinsettings.h"
 #include "dolphinsortfilterproxymodel.h"
 #include "draganddrophelper.h"
+#include "selectionmanager.h"
 #include "viewproperties.h"
 
 #include "dolphin_detailsmodesettings.h"
+#include "dolphin_generalsettings.h"
 
 #include <kdirmodel.h>
 #include <klocale.h>
@@ -43,6 +45,7 @@
 
 DolphinDetailsView::DolphinDetailsView(QWidget* parent, DolphinController* controller) :
     QTreeView(parent),
+       m_autoResize(true),
     m_controller(controller),
     m_font(),
     m_decorationSize(),
@@ -76,6 +79,10 @@ DolphinDetailsView::DolphinDetailsView(QWidget* parent, DolphinController* contr
     headerView->setContextMenuPolicy(Qt::CustomContextMenu);
     connect(headerView, SIGNAL(customContextMenuRequested(const QPoint&)),
             this, SLOT(configureColumns(const QPoint&)));
+    connect(headerView, SIGNAL(sectionResized(int, int, int)),
+            this, SLOT(slotHeaderSectionResized(int, int, int)));
+    connect(headerView, SIGNAL(sectionHandleDoubleClicked(int)),
+            this, SLOT(disableAutoResizing()));
 
     connect(parent, SIGNAL(sortingChanged(DolphinView::Sorting)),
             this, SLOT(setSortIndicatorSection(DolphinView::Sorting)));
@@ -89,6 +96,13 @@ DolphinDetailsView::DolphinDetailsView(QWidget* parent, DolphinController* contr
     if (KGlobalSettings::singleClick()) {
         connect(this, SIGNAL(clicked(const QModelIndex&)),
                 this, SLOT(triggerItem(const QModelIndex&)));
+        if (DolphinSettings::instance().generalSettings()->showSelectionToggle()) {
+            SelectionManager* selManager = new SelectionManager(this);
+            connect(selManager, SIGNAL(selectionChanged()),
+                    this, SLOT(requestActivation()));
+            connect(m_controller, SIGNAL(urlChanged(const KUrl&)),
+                    selManager, SLOT(reset()));
+        }
     } else {
         connect(this, SIGNAL(doubleClicked(const QModelIndex&)),
                 this, SLOT(triggerItem(const QModelIndex&)));
@@ -345,13 +359,7 @@ void DolphinDetailsView::keyPressEvent(QKeyEvent* event)
 void DolphinDetailsView::resizeEvent(QResizeEvent* event)
 {
     QTreeView::resizeEvent(event);
-
-    // TODO: There seems to be no easy way to find out whether the resize event
-    // has been triggered because of resizing the window or by adjusting the column-width
-    // by a left mouse-click (the columns should only be resized automatically when the window
-    // size is adjusted). The following workaround works well, but it should be
-    // considered solving this in a more transparent way.
-    if (!(QApplication::mouseButtons() & Qt::LeftButton)) {
+    if (m_autoResize) {
         resizeColumns();
     }
 }
@@ -494,6 +502,26 @@ void DolphinDetailsView::updateColumnVisibility()
     resizeColumns();
 }
 
+void DolphinDetailsView::slotHeaderSectionResized(int logicalIndex, int oldSize, int newSize)
+{
+    Q_UNUSED(logicalIndex);
+    Q_UNUSED(oldSize);
+    Q_UNUSED(newSize);
+    if (QApplication::mouseButtons() & Qt::LeftButton) {
+        disableAutoResizing();
+    }
+}
+
+void DolphinDetailsView::disableAutoResizing()
+{
+    m_autoResize = false;
+}
+
+void DolphinDetailsView::requestActivation()
+{
+    m_controller->requestActivation();
+}
+
 bool DolphinDetailsView::isZoomInPossible() const
 {
     DetailsModeSettings* settings = DolphinSettings::instance().detailsModeSettings();
@@ -510,6 +538,7 @@ void DolphinDetailsView::updateDecorationSize()
 {
     DetailsModeSettings* settings = DolphinSettings::instance().detailsModeSettings();
     const int iconSize = settings->iconSize();
+    setIconSize(QSize(iconSize, iconSize));
     m_decorationSize = QSize(iconSize, iconSize);
 
     m_controller->setZoomInPossible(isZoomInPossible());
index 086121f7ab78ca60264af9100be44163fd8097ca..316620a5a43ef54144874a6d72b1b23849599dce 100644 (file)
@@ -118,6 +118,20 @@ private slots:
 
     void updateColumnVisibility();
 
+    /**
+     * Disables the automatical resizing of columns, if the user has resized the columns
+     * with the mouse.
+     */
+    void slotHeaderSectionResized(int logicalIndex, int oldSize, int newSize);
+
+    /**
+     * Disables the automatical resizing of the columns. Per default all columns
+     * are resized to use the maximum available width of the view as good as possible.
+     */
+    void disableAutoResizing();
+
+    void requestActivation();
+
 private:
     bool isZoomInPossible() const;
     bool isZoomOutPossible() const;
@@ -143,6 +157,8 @@ private:
     void resizeColumns();
 
 private:
+       bool m_autoResize;  // if true, the columns are resized automatically to the available width
+
     DolphinController* m_controller;
 
     QFont m_font;
index 002c242ac8f2cb3eb92775adbdc37514f689b36d..d322c593d52fbcf2522a112af57a92b7c93c7b8c 100644 (file)
@@ -45,24 +45,23 @@ void DolphinDropController::dropUrls(const KUrl::List& urls,
     kDebug() << "Source" << urls;
     kDebug() << "Destination:" << destination;
 
+    if (destination.protocol() == "trash") {
+        KonqOperations::del(m_parentWidget, KonqOperations::TRASH, urls);
+        return;
+    }
+
     Qt::DropAction action = Qt::CopyAction;
 
     Qt::KeyboardModifiers modifier = QApplication::keyboardModifiers();
     const bool shiftPressed   = modifier & Qt::ShiftModifier;
     const bool controlPressed = modifier & Qt::ControlModifier;
     const bool altPressed = modifier & Qt::AltModifier;
-    if (shiftPressed && controlPressed) {
-        // shortcut for 'Link Here' is used
+    if ((shiftPressed && controlPressed) || altPressed) {
         action = Qt::LinkAction;
-    } else if (shiftPressed) {
-        // shortcut for 'Move Here' is used
-        action = Qt::MoveAction;
     } else if (controlPressed) {
-        // shortcut for 'Copy Here' is used
         action = Qt::CopyAction;
-    } else if (altPressed) {
-        // shortcut for 'Link Here' is used
-        action = Qt::LinkAction;
+    } else if (shiftPressed) {
+        action = Qt::MoveAction;
     } else {
         // open a context menu which offers the following actions:
         // - Move Here
diff --git a/src/dolphinfileplacesview.cpp b/src/dolphinfileplacesview.cpp
new file mode 100644 (file)
index 0000000..5dacae6
--- /dev/null
@@ -0,0 +1,47 @@
+/***************************************************************************
+ *   Copyright (C) 2008 by Peter Penz <peter.penz@gmx.at>                  *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
+ ***************************************************************************/
+
+#include "dolphinfileplacesview.h"
+#include "dolphindropcontroller.h"
+#include <konq_operations.h>
+
+DolphinFilePlacesView::DolphinFilePlacesView(QWidget* parent) :
+    KFilePlacesView(parent)
+{
+    setDropOnPlaceEnabled(true);
+    connect(this, SIGNAL(urlsDropped(const KUrl&, QDropEvent*, QWidget*)),
+            this, SLOT(slotUrlsDropped(const KUrl&, QDropEvent*, QWidget*)));
+}
+
+DolphinFilePlacesView::~DolphinFilePlacesView()
+{
+}
+
+void DolphinFilePlacesView::slotUrlsDropped(const KUrl& dest, QDropEvent* event, QWidget* parent)
+{
+    const KUrl::List urls = KUrl::List::fromMimeData(event->mimeData());
+
+    DolphinDropController dropController(parent);
+    // forward doingOperation signal up to the mainwindow
+    connect(&dropController, SIGNAL(doingOperation(KonqFileUndoManager::CommandType)),
+            this, SIGNAL(doingOperation(KonqFileUndoManager::CommandType)));
+    dropController.dropUrls(urls, dest);
+}
+
+#include "dolphinfileplacesview.moc"
diff --git a/src/dolphinfileplacesview.h b/src/dolphinfileplacesview.h
new file mode 100644 (file)
index 0000000..8bad0fa
--- /dev/null
@@ -0,0 +1,41 @@
+/***************************************************************************
+ *   Copyright (C) 2008 by Peter Penz <peter.penz@gmx.at>                  *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
+ ***************************************************************************/
+
+#ifndef DOLPHINFILEPLACESVIEW_H
+#define DOLPHINFILEPLACESVIEW_H
+
+#include <kfileplacesview.h>
+
+/**
+ * @brief Combines bookmarks and mounted devices as list which is
+ *        embedded as panel.
+ */
+class DolphinFilePlacesView : public KFilePlacesView
+{
+    Q_OBJECT
+
+public:
+    DolphinFilePlacesView(QWidget* parent);
+    virtual ~DolphinFilePlacesView();
+
+private slots:
+    void slotUrlsDropped(const KUrl& dest, QDropEvent* event, QWidget* parent);
+};
+
+#endif // DOLPHINFILEPLACESVIEW_H
index d3d485f1a05f1f3cb600dd7f11d53ce7e7d1a98d..ccf12a737d55fb986f701a80e81eea21943bd237 100644 (file)
@@ -23,7 +23,9 @@
 #include "dolphincontroller.h"
 #include "dolphinsettings.h"
 #include "dolphin_iconsmodesettings.h"
+#include "dolphin_generalsettings.h"
 #include "draganddrophelper.h"
+#include "selectionmanager.h"
 
 #include <kcategorizedsortfilterproxymodel.h>
 #include <kdialog.h>
@@ -33,6 +35,7 @@
 #include <QApplication>
 #include <QPainter>
 #include <QPoint>
+#include <QScrollBar>
 
 DolphinIconsView::DolphinIconsView(QWidget* parent, DolphinController* controller) :
     KCategorizedView(parent),
@@ -64,6 +67,13 @@ DolphinIconsView::DolphinIconsView(QWidget* parent, DolphinController* controlle
     if (KGlobalSettings::singleClick()) {
         connect(this, SIGNAL(clicked(const QModelIndex&)),
                 this, SLOT(triggerItem(const QModelIndex&)));
+        if (DolphinSettings::instance().generalSettings()->showSelectionToggle()) {
+            SelectionManager* selManager = new SelectionManager(this);
+            connect(selManager, SIGNAL(selectionChanged()),
+                    this, SLOT(requestActivation()));
+            connect(m_controller, SIGNAL(urlChanged(const KUrl&)),
+                    selManager, SLOT(reset()));
+        }
     } else {
         connect(this, SIGNAL(doubleClicked(const QModelIndex&)),
                 this, SLOT(triggerItem(const QModelIndex&)));
@@ -285,6 +295,34 @@ void DolphinIconsView::keyPressEvent(QKeyEvent* event)
     }
 }
 
+void DolphinIconsView::wheelEvent(QWheelEvent* event)
+{
+    KCategorizedView::wheelEvent(event);
+
+    if ((event->modifiers() & Qt::ControlModifier) == Qt::ControlModifier) {
+        int d = event->delta();
+        if (d > 0) {
+            zoomIn();
+        } else if (d < 0) {
+            zoomOut();
+        }
+    } else {
+        // if the icons are aligned left to right, the vertical wheel event should
+        // be applied to the horizontal scrollbar
+        const IconsModeSettings* settings = DolphinSettings::instance().iconsModeSettings();
+        const bool scrollHorizontal = (event->orientation() == Qt::Vertical) &&
+                                      (settings->arrangement() == QListView::LeftToRight);
+        if (scrollHorizontal) {
+            QWheelEvent horizEvent(event->pos(),
+                                   event->delta(),
+                                   event->buttons(),
+                                   event->modifiers(),
+                                   Qt::Horizontal);
+            QApplication::sendEvent(horizontalScrollBar(), &horizEvent);
+        }
+    }
+}
+
 void DolphinIconsView::triggerItem(const QModelIndex& index)
 {
     m_controller->triggerItem(itemForIndex(index));
@@ -369,6 +407,11 @@ void DolphinIconsView::zoomOut()
     }
 }
 
+void DolphinIconsView::requestActivation()
+{
+    m_controller->requestActivation();
+}
+
 bool DolphinIconsView::isZoomInPossible() const
 {
     IconsModeSettings* settings = DolphinSettings::instance().iconsModeSettings();
@@ -431,6 +474,7 @@ void DolphinIconsView::updateGridSize(bool showPreview, int additionalInfoCount)
 
         size = previewSize;
     }
+    setIconSize(QSize(size, size));
 
     Q_ASSERT(additionalInfoCount >= 0);
     itemHeight += additionalInfoCount * m_font.pointSize() * 2;
index af65bbda8af715ebcedf7c7c69fd183ac5e2a08c..05b21a2b0c53c44c55f120c35992aca3cc470e1a 100644 (file)
@@ -62,6 +62,7 @@ protected:
     virtual void dropEvent(QDropEvent* event);
     virtual void paintEvent(QPaintEvent* event);
     virtual void keyPressEvent(QKeyEvent* event);
+    virtual void wheelEvent(QWheelEvent* event);
 
 private slots:
     void triggerItem(const QModelIndex& index);
@@ -70,6 +71,7 @@ private slots:
     void slotAdditionalInfoChanged();
     void zoomIn();
     void zoomOut();
+    void requestActivation();
 
 private:
     bool isZoomInPossible() const;
index c1d6cef39b583d0f1e90ac1f5388a3448524e40d..160c423ecc038979fbe8423300d3e56542be1468 100644 (file)
@@ -26,6 +26,7 @@
 #include <config-nepomuk.h>
 
 #include "dolphinapplication.h"
+#include "dolphinfileplacesview.h"
 #include "dolphinnewmenu.h"
 #include "dolphinsettings.h"
 #include "dolphinsettingsdialog.h"
 #include "mainwindowadaptor.h"
 #include "terminalsidebarpage.h"
 #include "treeviewsidebarpage.h"
-#include "kurlnavigator.h"
 #include "viewpropertiesdialog.h"
 #include "viewproperties.h"
-#include "kfileplacesmodel.h"
-#include "kfileplacesview.h"
 
 #include "dolphin_generalsettings.h"
 #include "dolphin_iconsmodesettings.h"
@@ -51,6 +49,7 @@
 #include <kdesktopfile.h>
 #include <kdeversion.h>
 #include <kfiledialog.h>
+#include <kfileplacesmodel.h>
 #include <kglobal.h>
 #include <kicon.h>
 #include <kiconloader.h>
@@ -60,6 +59,7 @@
 #include <kmenu.h>
 #include <kmenubar.h>
 #include <kmessagebox.h>
+#include <kurlnavigator.h>
 #include <konqmimedata.h>
 #include <kpropertiesdialog.h>
 #include <kprotocolinfo.h>
@@ -224,6 +224,13 @@ void DolphinMainWindow::slotSortingChanged(DolphinView::Sorting sorting)
     }
 }
 
+void DolphinMainWindow::slotEditableStateChanged(bool editable)
+{
+    KToggleAction* editableLocationAction =
+        static_cast<KToggleAction*>(actionCollection()->action("editable_location"));
+    editableLocationAction->setChecked(editable);
+}
+
 void DolphinMainWindow::slotSelectionChanged(const KFileItemList& selection)
 {
     updateEditActions();
@@ -368,7 +375,7 @@ void DolphinMainWindow::slotHandlePlacesError(const QString &message)
 
 void DolphinMainWindow::slotUndoAvailable(bool available)
 {
-    QAction* undoAction = actionCollection()->action(KStandardAction::stdName(KStandardAction::Undo));
+    QAction* undoAction = actionCollection()->action(KStandardAction::name(KStandardAction::Undo));
     if (undoAction != 0) {
         undoAction->setEnabled(available);
     }
@@ -412,7 +419,7 @@ void DolphinMainWindow::slotUndoAvailable(bool available)
 
 void DolphinMainWindow::slotUndoTextChanged(const QString& text)
 {
-    QAction* undoAction = actionCollection()->action(KStandardAction::stdName(KStandardAction::Undo));
+    QAction* undoAction = actionCollection()->action(KStandardAction::name(KStandardAction::Undo));
     if (undoAction != 0) {
         undoAction->setText(text);
     }
@@ -441,7 +448,7 @@ void DolphinMainWindow::paste()
 
 void DolphinMainWindow::updatePasteAction()
 {
-    QAction* pasteAction = actionCollection()->action(KStandardAction::stdName(KStandardAction::Paste));
+    QAction* pasteAction = actionCollection()->action(KStandardAction::name(KStandardAction::Paste));
     if (pasteAction == 0) {
         return;
     }
@@ -815,8 +822,8 @@ void DolphinMainWindow::setupActions()
                           SLOT(undo()),
                           actionCollection());
 
-    //Need to remove shift+del from cut action, else the shortcut for deletejob
-    //doesn't work
+    // need to remove shift+del from cut action, else the shortcut for deletejob
+    // doesn't work
     KAction* cut = KStandardAction::cut(this, SLOT(cut()), actionCollection());
     KShortcut cutShortcut = cut->shortcut();
     cutShortcut.remove(Qt::SHIFT + Qt::Key_Delete, KShortcut::KeepEmpty);
@@ -932,9 +939,7 @@ void DolphinMainWindow::setupActions()
     stop->setIcon(KIcon("process-stop"));
     connect(stop, SIGNAL(triggered()), this, SLOT(stopLoading()));
 
-    // 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...
+    // TODO: the naming "Show full Location" is currently confusing...
     KToggleAction* showFullLocation = actionCollection()->add<KToggleAction>("editable_location");
     showFullLocation->setText(i18nc("@action:inmenu Navigation Bar", "Show Full Location"));
     showFullLocation->setShortcut(Qt::CTRL | Qt::Key_L);
@@ -1051,7 +1056,8 @@ void DolphinMainWindow::setupDockWidgets()
     QDockWidget* placesDock = new QDockWidget(i18nc("@title:window", "Places"));
     placesDock->setObjectName("placesDock");
     placesDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
-    KFilePlacesView* placesView = new KFilePlacesView(placesDock);
+
+    DolphinFilePlacesView* placesView = new DolphinFilePlacesView(placesDock);
     placesDock->setWidget(placesView);
     placesView->setModel(DolphinSettings::instance().placesModel());
     placesView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
@@ -1139,7 +1145,7 @@ void DolphinMainWindow::updateViewActions()
 
 void DolphinMainWindow::updateGoActions()
 {
-    QAction* goUpAction = actionCollection()->action(KStandardAction::stdName(KStandardAction::Up));
+    QAction* goUpAction = actionCollection()->action(KStandardAction::name(KStandardAction::Up));
     const KUrl& currentUrl = m_activeViewContainer->url();
     goUpAction->setEnabled(currentUrl.upUrl() != currentUrl);
 }
@@ -1174,6 +1180,8 @@ void DolphinMainWindow::connectViewSignals(int viewIndex)
             this, SLOT(changeUrl(const KUrl&)));
     connect(navigator, SIGNAL(historyChanged()),
             this, SLOT(slotHistoryChanged()));
+    connect(navigator, SIGNAL(editableStateChanged(bool)),
+            this, SLOT(slotEditableStateChanged(bool)));
 }
 
 void DolphinMainWindow::updateSplitAction()
index b1694c323ac4869b94328ab658b85a2ef9e47001..bddeba7b1d42721e7e361f1932d8d670ec626b20 100644 (file)
@@ -271,7 +271,7 @@ private slots:
     void toggleFilterBarVisibility(bool show);
 
     /**
-     * Toggles between edit and brose mode of the navigation bar.
+     * Toggles between edit and browse mode of the navigation bar.
      */
     void toggleEditLocation();
 
@@ -320,6 +320,9 @@ private slots:
     /** Updates the state of the 'Sort by' actions. */
     void slotSortingChanged(DolphinView::Sorting sorting);
 
+    /** Updates the state of the 'Show Full Location' action. */
+    void slotEditableStateChanged(bool editable);
+
     /**
      * Updates the state of the 'Edit' menu actions and emits
      * the signal selectionChanged().
index 1b94e0339d2b5bd26c9a419873574851dc36a0d9..b0e5ef5c4702ad4194662e2235d4f6f2c330e5bc 100644 (file)
@@ -137,8 +137,7 @@ QVariant DolphinModel::data(const QModelIndex &index, int role) const
             }
 
             case KDirModel::ModifiedTime: {
-                KDateTime modifiedTime;
-                modifiedTime.setTime_t(item.time(KIO::UDSEntry::UDS_MODIFICATION_TIME));
+                KDateTime modifiedTime = item.time(KFileItem::ModificationTime);
                 modifiedTime = modifiedTime.toLocalZone();
 
                 retString = modifiedTime.toString(i18nc("Prints out the month and year: %B is full month name in current locale, and %Y is full year number", "%B, %Y"));
@@ -266,8 +265,7 @@ QVariant DolphinModel::data(const QModelIndex &index, int role) const
         }
 
         case KDirModel::ModifiedTime: {
-            KDateTime modifiedTime;
-            modifiedTime.setTime_t(item.time(KIO::UDSEntry::UDS_MODIFICATION_TIME));
+            KDateTime modifiedTime = item.time(KFileItem::ModificationTime);
             modifiedTime = modifiedTime.toLocalZone();
 
             retVariant = -(modifiedTime.date().year() * 100 + modifiedTime.date().month());
index a8b9217cc3b9c26b8c2e1d20897989045c73a895..1a139f1cd0a8d413b8e3682f780cf3ffde292f4c 100644 (file)
@@ -9,6 +9,7 @@ Name[csb]=Dolphin - kòmpònenta
 Name[da]=Dolphin-Part
 Name[de]=Dolphin-Komponente
 Name[el]=Τμήμα Dolphin
+Name[eo]=Komponanto de Dolphin
 Name[es]=Part Dolphin
 Name[et]=Dolphini komponent
 Name[fi]=Dolphin osa
@@ -23,6 +24,7 @@ Name[it]=Componente Dolphin
 Name[ja]=Dolphin パート
 Name[kk]=Dolphin бөлшегі
 Name[km]=ផ្នែក​របស់ Dolphin
+Name[kn]=ಡಾಲ್ಫಿನ್ ಭಾಗ
 Name[ko]=Dolphin 부분
 Name[ku]=Parçeyê Bibîne
 Name[lv]=Dolphin daļa
@@ -35,12 +37,14 @@ Name[pa]=ਡਾਲਫਿਨ ਭਾਗ
 Name[pl]=Moduł Dophina
 Name[pt]=Componente do Dolphin
 Name[pt_BR]=Componente Dolphin
+Name[ro]=Componentă Dolphin
 Name[ru]=Встраиваемый компонент Dolphin
 Name[se]=Dolphin-oassi
 Name[sl]=Del Dolphin
 Name[sr]=Делфин део
 Name[sr@latin]=Dolphin deo
 Name[sv]=Dolphin-delprogram
+Name[ta]=டால்பினின் பகுதி
 Name[tg]=Қисми Dolphin
 Name[tr]=Dolphin Parçacığı
 Name[uk]=Компонент Дельфіна
index 35bde506e792442ad5421fdbc3d4c1b347275ae4..2e3f63e5c39b1e14bb2b729e3e56eeb2bf61b430 100644 (file)
@@ -13,7 +13,7 @@
   </Menu>
   <Menu name="view">
    <Menu name="sort">
-    <text context="@title:menu">Sort by</text>
+    <text context="@title:menu">Sort By</text>
     <Action name="sort_by_name" />
     <Action name="sort_by_size" />
     <Action name="sort_by_date" />
index 1bbbbde55064de520d9c95f1f3b22662c7c7b313..d3f387aa9bf5de99e3456d0bf9f2b7b628e8c076 100644 (file)
@@ -23,6 +23,7 @@
 #include "dolphinapplication.h"
 #include "dolphinmainwindow.h"
 #include "generalsettingspage.h"
+#include "startupsettingspage.h"
 #include "viewsettingspage.h"
 
 #include <klocale.h>
 #include <kicon.h>
 
 DolphinSettingsDialog::DolphinSettingsDialog(DolphinMainWindow* mainWindow) :
-    KPageDialog(mainWindow)
+    KPageDialog(mainWindow),
+    m_startupSettingsPage(0),
+    m_generalSettingsPage(0),
+    m_viewSettingsPage(0)
+
 {
     const QSize minSize = minimumSize();
     setMinimumSize(QSize(512, minSize.height()));
@@ -40,16 +45,21 @@ DolphinSettingsDialog::DolphinSettingsDialog(DolphinMainWindow* mainWindow) :
     setButtons(Ok | Apply | Cancel | Default);
     setDefaultButton(Ok);
 
-    m_generalSettingsPage = new GeneralSettingsPage(mainWindow, this);
-    KPageWidgetItem* generalSettingsFrame = addPage(m_generalSettingsPage,
-                                                    i18nc("@title:group", "General"));
-    generalSettingsFrame->setIcon(KIcon("system-run"));
+    m_startupSettingsPage = new StartupSettingsPage(mainWindow, this);
+    KPageWidgetItem* startupSettingsFrame = addPage(m_startupSettingsPage,
+                                                    i18nc("@title:group", "Startup"));
+    startupSettingsFrame->setIcon(KIcon("go-home"));
 
     m_viewSettingsPage = new ViewSettingsPage(mainWindow, this);
     KPageWidgetItem* viewSettingsFrame = addPage(m_viewSettingsPage,
                                                  i18nc("@title:group", "View Modes"));
     viewSettingsFrame->setIcon(KIcon("view-choose"));
 
+    m_generalSettingsPage = new GeneralSettingsPage(mainWindow, this);
+    KPageWidgetItem* generalSettingsFrame = addPage(m_generalSettingsPage,
+                                                    i18nc("@title:group", "General"));
+    generalSettingsFrame->setIcon(KIcon("system-run"));
+
     const KConfigGroup dialogConfig(KSharedConfig::openConfig("dolphinrc"), "SettingsDialog");
     restoreDialogSize(dialogConfig);
 }
@@ -76,6 +86,7 @@ void DolphinSettingsDialog::slotButtonClicked(int button)
 
 void DolphinSettingsDialog::applySettings()
 {
+    m_startupSettingsPage->applySettings();
     m_generalSettingsPage->applySettings();
     m_viewSettingsPage->applySettings();
     DolphinApplication::app()->refreshMainWindows();
@@ -83,6 +94,7 @@ void DolphinSettingsDialog::applySettings()
 
 void DolphinSettingsDialog::restoreDefaults()
 {
+    m_startupSettingsPage->restoreDefaults();
     m_generalSettingsPage->restoreDefaults();
     m_viewSettingsPage->restoreDefaults();
     DolphinApplication::app()->refreshMainWindows();
index e68d8279892e20362b60ed84602f02548a26014c..2cb7fc78ebdbe34a97a19e706fdf5bea37898054 100644 (file)
 #define DOLPHINSETTINGSDIALOG_H
 
 #include <kpagedialog.h>
+
 class GeneralSettingsPage;
+class StartupSettingsPage;
 class ViewSettingsPage;
 class DolphinMainWindow;
 
 /**
  * @brief Settings dialog for Dolphin.
  *
- * Contains the pages for general settings and view settings.
+ * Contains the pages for startup settings, general settings and view settings.
  *
  * @author Peter Penz <peter.penz@gmx.at>
  */
@@ -50,6 +52,7 @@ private:
     void restoreDefaults();
 
 private:
+    StartupSettingsPage* m_startupSettingsPage;
     GeneralSettingsPage* m_generalSettingsPage;
     ViewSettingsPage* m_viewSettingsPage;
 };
index 1763aefda0ae6dcaac638b3d64ea9213876481a8..8aaddcd260f329c6a21a9e23919c69ac5eae17ec 100644 (file)
@@ -23,7 +23,7 @@
     <Action name="columns" />
    </Menu>
    <Menu name="sort">
-    <text context="@title:menu">Sort by</text>
+    <text context="@title:menu">Sort By</text>
     <Action name="sort_by_name" />
     <Action name="sort_by_size" />
     <Action name="sort_by_date" />
index 7979b06c3f122de327ac5e181c1d708b999f7016..1ed8310a6404bc3bea0d6ee9b9dbd141b5cbbbd9 100644 (file)
 #include <kcolorscheme.h>
 #include <kdirlister.h>
 #include <kfileitemdelegate.h>
-#include <klocale.h>
 #include <kiconeffect.h>
+#include <klocale.h>
 #include <kio/deletejob.h>
 #include <kio/netaccess.h>
 #include <kio/previewjob.h>
 #include <kjob.h>
 #include <kmenu.h>
 #include <kmimetyperesolver.h>
-#include <konqmimedata.h>
 #include <konq_operations.h>
+#include <konqmimedata.h>
 #include <ktoggleaction.h>
 #include <kurl.h>
 
 #include "dolphinsortfilterproxymodel.h"
 #include "dolphindetailsview.h"
 #include "dolphiniconsview.h"
-#include "renamedialog.h"
-#include "viewproperties.h"
 #include "dolphinsettings.h"
 #include "dolphin_generalsettings.h"
+#include "iconmanager.h"
+#include "renamedialog.h"
+#include "viewproperties.h"
 
 DolphinView::DolphinView(QWidget* parent,
                          const KUrl& url,
@@ -78,21 +79,15 @@ DolphinView::DolphinView(QWidget* parent,
     m_dolphinModel(dolphinModel),
     m_dirLister(dirLister),
     m_proxyModel(proxyModel),
-    m_previewJob(0)
+    m_iconManager(0)
 {
     setFocusPolicy(Qt::StrongFocus);
     m_topLayout = new QVBoxLayout(this);
     m_topLayout->setSpacing(0);
     m_topLayout->setMargin(0);
 
-    QClipboard* clipboard = QApplication::clipboard();
-    connect(clipboard, SIGNAL(dataChanged()),
-            this, SLOT(updateCutItems()));
-
     connect(m_dirLister, SIGNAL(completed()),
             this, SLOT(updateCutItems()));
-    connect(m_dirLister, SIGNAL(newItems(const KFileItemList&)),
-            this, SLOT(generatePreviews(const KFileItemList&)));
 
     m_controller = new DolphinController(this);
     m_controller->setUrl(url);
@@ -131,10 +126,6 @@ DolphinView::DolphinView(QWidget* parent,
 
 DolphinView::~DolphinView()
 {
-    if (m_previewJob != 0) {
-        m_previewJob->kill();
-        m_previewJob = 0;
-    }
 }
 
 const KUrl& DolphinView::url() const
@@ -194,16 +185,6 @@ void DolphinView::setMode(Mode mode)
 
     m_mode = mode;
 
-    if (isColumnViewActive()) {
-        // When changing the mode in the column view, it makes sense
-        // to go back to the root URL of the column view automatically.
-        // Otherwise there it would not be possible to turn off the column view
-        // without focusing the first column.
-        const KUrl root = rootUrl();
-        setUrl(root);
-        m_controller->setUrl(root);
-    }
-
     deleteView();
 
     const KUrl viewPropsUrl = viewPropertiesUrl();
@@ -246,7 +227,7 @@ void DolphinView::setShowPreview(bool show)
     props.setShowPreview(show);
 
     m_showPreview = show;
-
+    m_iconManager->setShowPreview(show);
     emit showPreviewChanged();
 
     loadDirectory(viewPropsUrl, true);
@@ -419,11 +400,13 @@ QPoint DolphinView::contentsPosition() const
 void DolphinView::zoomIn()
 {
     m_controller->triggerZoomIn();
+    reload();
 }
 
 void DolphinView::zoomOut()
 {
     m_controller->triggerZoomOut();
+    reload();
 }
 
 bool DolphinView::isZoomInPossible() const
@@ -575,45 +558,6 @@ void DolphinView::triggerItem(const KFileItem& item)
     emit itemTriggered(item); // caught by DolphinViewContainer or DolphinPart
 }
 
-void DolphinView::generatePreviews(const KFileItemList& items)
-{
-    if (m_controller->dolphinView()->showPreview()) {
-        if (m_previewJob != 0) {
-            m_previewJob->kill();
-            m_previewJob = 0;
-        }
-
-        m_previewJob = KIO::filePreview(items, 128);
-        connect(m_previewJob, SIGNAL(gotPreview(const KFileItem&, const QPixmap&)),
-                this, SLOT(replaceIcon(const KFileItem&, const QPixmap&)));
-        connect(m_previewJob, SIGNAL(finished(KJob*)),
-                this, SLOT(slotPreviewJobFinished(KJob*)));
-    }
-}
-
-void DolphinView::replaceIcon(const KFileItem& item, const QPixmap& pixmap)
-{
-    Q_ASSERT(!item.isNull());
-    if (!m_showPreview || (item.url().directory() != m_dirLister->url().path())) {
-        // the preview has been deactivated in the meanwhile or the preview
-        // job is still working on items of an older URL, hence
-        // the item is not part of the directory model anymore
-        return;
-    }
-
-    const QModelIndex idx = m_dolphinModel->indexForItem(item);
-    if (idx.isValid() && (idx.column() == 0)) {
-        const QMimeData* mimeData = QApplication::clipboard()->mimeData();
-        if (KonqMimeData::decodeIsCutSelection(mimeData) && isCutItem(item)) {
-            KIconEffect iconEffect;
-            const QPixmap cutPixmap = iconEffect.apply(pixmap, KIconLoader::Desktop, KIconLoader::DisabledState);
-            m_dolphinModel->setData(idx, QIcon(cutPixmap), Qt::DecorationRole);
-        } else {
-            m_dolphinModel->setData(idx, QIcon(pixmap), Qt::DecorationRole);
-        }
-    }
-}
-
 void DolphinView::emitSelectionChangedSignal()
 {
     emit selectionChanged(DolphinView::selectedItems());
@@ -631,7 +575,6 @@ void DolphinView::loadDirectory(const KUrl& url, bool reload)
         return;
     }
 
-    m_cutItemsCache.clear();
     m_loadingDirectory = true;
 
     m_dirLister->stop();
@@ -714,6 +657,7 @@ void DolphinView::applyViewProperties(const KUrl& url)
     const bool showPreview = props.showPreview();
     if (showPreview != m_showPreview) {
         m_showPreview = showPreview;
+        m_iconManager->setShowPreview(showPreview);
         emit showPreviewChanged();
     }
 }
@@ -899,25 +843,6 @@ void DolphinView::emitContentsMoved()
     }
 }
 
-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_dolphinModel->indexForUrl((*it).url);
-        if (index.isValid()) {
-            m_dolphinModel->setData(index, QIcon((*it).pixmap), Qt::DecorationRole);
-        }
-        ++it;
-    }
-    m_cutItemsCache.clear();
-
-    // ... and apply an item effect to all currently cut items
-    applyCutItemEffect();
-}
-
 void DolphinView::showHoverInformation(const KFileItem& item)
 {
     if (hasSelection() || !m_active) {
@@ -934,7 +859,6 @@ void DolphinView::clearHoverInformation()
     }
 }
 
-
 void DolphinView::createView()
 {
     deleteView();
@@ -980,6 +904,9 @@ void DolphinView::createView()
     view->setSelectionMode(QAbstractItemView::ExtendedSelection);
 
     new KMimeTypeResolver(view, m_dolphinModel);
+    m_iconManager = new IconManager(view, m_proxyModel);
+    m_iconManager->setShowPreview(m_showPreview);
+
     m_topLayout->insertWidget(1, view);
 
     connect(view->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
@@ -1002,6 +929,7 @@ void DolphinView::deleteView()
         m_detailsView = 0;
         m_columnView = 0;
         m_fileItemDelegate = 0;
+        m_iconManager = 0;
     }
 }
 
@@ -1034,42 +962,6 @@ 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) {
-        const KFileItem item = *it;
-        if (isCutItem(item)) {
-            const QModelIndex index = m_dolphinModel->indexForItem(item);
-            const QVariant value = m_dolphinModel->data(index, Qt::DecorationRole);
-            if (value.type() == QVariant::Icon) {
-                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, KIconLoader::Desktop, KIconLoader::DisabledState);
-                m_dolphinModel->setData(index, QIcon(pixmap), Qt::DecorationRole);
-            }
-        }
-        ++it;
-    }
-}
-
 KToggleAction* DolphinView::iconsModeAction(KActionCollection* actionCollection)
 {
     KToggleAction* iconsView = actionCollection->add<KToggleAction>("icons");
@@ -1133,19 +1025,14 @@ void DolphinView::renameSelectedItems()
             Q_ASSERT(newName.contains('#'));
 
             // iterate through all selected items and rename them...
-            const int replaceIndex = newName.indexOf('#');
-            Q_ASSERT(replaceIndex >= 0);
             int index = 1;
-
-            KFileItemList::const_iterator it = items.begin();
-            const KFileItemList::const_iterator end = items.end();
-            while (it != end) {
-                const KUrl& oldUrl = (*it).url();
+            foreach (KFileItem item, items) {
+                const KUrl& oldUrl = item.url();
                 QString number;
                 number.setNum(index++);
 
-                QString name(newName);
-                name.replace(replaceIndex, 1, number);
+                QString name = newName;
+                name.replace('#', number);
 
                 if (oldUrl.fileName() != name) {
                     KUrl newUrl = oldUrl;
@@ -1153,7 +1040,6 @@ void DolphinView::renameSelectedItems()
                     KonqOperations::rename(this, oldUrl, newUrl);
                     emit doingOperation(KonqFileUndoManager::RENAME);
                 }
-                ++it;
             }
         }
     } else {
@@ -1212,12 +1098,6 @@ void DolphinView::slotDeleteFileFinished(KJob* job)
     }
 }
 
-void DolphinView::slotPreviewJobFinished(KJob* job)
-{
-    Q_ASSERT(job == m_previewJob);
-    m_previewJob = 0;
-}
-
 void DolphinView::cutSelectedItems()
 {
     QMimeData* mimeData = new QMimeData();
index 6f0289f6264e6af7ce533a9f6aa9a0efccbe73bf..215a2a23c35793f5dd40e6cc4e4d76775e36fe4b 100644 (file)
 #include <QWidget>
 
 class QActionGroup;
-class KAction;
-class KToggleAction;
 class DolphinController;
-class KDirLister;
-class KFileItemDelegate;
-class KUrl;
-class DolphinModel;
 class DolphinColumnView;
 class DolphinDetailsView;
 class DolphinIconsView;
 class DolphinMainWindow;
+class DolphinModel;
 class DolphinSortFilterProxyModel;
+class IconManager;
+class KAction;
+class KActionCollection;
+class KDirLister;
+class KFileItemDelegate;
+class KUrl;
+class KToggleAction;
 class QModelIndex;
 class ViewProperties;
-namespace KIO
-{
-    class PreviewJob;
-}
 
 /**
  * @short Represents a view for the directory content.
@@ -529,19 +527,6 @@ private slots:
      */
     void triggerItem(const KFileItem& index);
 
-    /**
-     * Generates a preview image for each file item in \a items.
-     * The current preview settings (maximum size, 'Show Preview' menu)
-     * are respected.
-     */
-    void generatePreviews(const KFileItemList& items);
-
-    /**
-     * Replaces the icon of the item \a item by the preview pixmap
-     * \a pixmap.
-     */
-    void replaceIcon(const KFileItem& item, const QPixmap& pixmap);
-
     void emitSelectionChangedSignal();
 
     /**
@@ -590,9 +575,6 @@ private slots:
      */
     void emitContentsMoved();
 
-    /** Applies an item effect to all cut items of the clipboard. */
-    void updateCutItems();
-
     /**
      * Updates the status bar to show hover information for the
      * item \a item. If currently other items are selected,
@@ -613,12 +595,6 @@ private slots:
      */
     void slotDeleteFileFinished(KJob* job);
 
-    /**
-     * Is invoked when the preview job has been finished and
-     * set m_previewJob to 0.
-     */
-    void slotPreviewJobFinished(KJob* job);
-
 private:
     void loadDirectory(const KUrl& url, bool reload = false);
 
@@ -657,9 +633,6 @@ private:
      */
     bool isCutItem(const KFileItem& item) const;
 
-    /** Applies an item effect to all cut items. */
-    void applyCutItemEffect();
-
     /**
      * Returns true, if the ColumnView is activated. As the column view
      * requires some special handling for iterating through directories,
@@ -671,16 +644,6 @@ private:
     }
 
 private:
-    /**
-     * Remembers the original pixmap for an item before
-     * the cut effect is applied.
-     */
-    struct CutItem
-    {
-        KUrl url;
-        QPixmap pixmap;
-    };
-
     bool m_active;
     bool m_showPreview;
     bool m_loadingDirectory;
@@ -701,9 +664,7 @@ private:
     KDirLister* m_dirLister;
     DolphinSortFilterProxyModel* m_proxyModel;
 
-    KIO::PreviewJob* m_previewJob;
-
-    QList<CutItem> m_cutItemsCache;
+    IconManager* m_iconManager;
 
     KUrl m_rootUrl;
 };
index a1846dc758c73bd2acb4a9351595cf3fc284c21c..e6966affb153b30e01af5f06e36e8b97602930eb 100644 (file)
@@ -398,10 +398,13 @@ void DolphinViewContainer::slotItemTriggered(const KFileItem& item)
 
     if (item.isDir()) {
         m_view->setUrl(url);
-    } else if (item.isFile() && url.isLocalFile()) {
-        // allow to browse through ZIP and tar files
-        // TODO: make this configurable for Dolphin in KDE 4.1
+        return;
+    }
 
+    const GeneralSettings* settings = DolphinSettings::instance().generalSettings();
+    const bool browseThroughArchives = settings->browseThroughArchives() &&
+                                       item.isFile() && url.isLocalFile();
+    if (browseThroughArchives) {
         KMimeType::Ptr mime = item.mimeTypePtr();
 
         // Don't use mime->is("application/zip"), as this would
@@ -409,19 +412,21 @@ void DolphinViewContainer::slotItemTriggered(const KFileItem& item)
         if (mime->name() == "application/zip") {
             url.setProtocol("zip");
             m_view->setUrl(url);
-        } else if (mime->is("application/x-tar") ||
-                   mime->is("application/x-tarz") ||
-                   mime->is("application/x-bzip-compressed-tar") ||
-                   mime->is("application/x-compressed-tar") ||
-                   mime->is("application/x-tzo")) {
+            return;
+        }
+
+        if (mime->is("application/x-tar") ||
+            mime->is("application/x-tarz") ||
+            mime->is("application/x-bzip-compressed-tar") ||
+            mime->is("application/x-compressed-tar") ||
+            mime->is("application/x-tzo")) {
             url.setProtocol("tar");
             m_view->setUrl(url);
-        } else {
-            item.run();
+            return;
         }
-    } else {
-        item.run();
     }
+
+    item.run();
 }
 
 #include "dolphinviewcontainer.moc"
index f856de1b17894e8135115bf084abf86dd7b6d31c..04863c0379ea350a07af4a8dcdbc194e77c8cd01 100644 (file)
 #include "generalsettingspage.h"
 
 #include "dolphinsettings.h"
-#include "dolphinmainwindow.h"
-#include "dolphinview.h"
-#include "dolphinviewcontainer.h"
 
 #include "dolphin_generalsettings.h"
 
 #include <kdialog.h>
-#include <kfiledialog.h>
 #include <klocale.h>
 #include <kvbox.h>
 
 #include <QCheckBox>
 #include <QGroupBox>
 #include <QLabel>
-#include <QLineEdit>
-#include <QPushButton>
-#include <QRadioButton>
+#include <QVBoxLayout>
 
 GeneralSettingsPage::GeneralSettingsPage(DolphinMainWindow* mainWin, QWidget* parent) :
     SettingsPageBase(parent),
-    m_mainWindow(mainWin),
-    m_homeUrl(0),
-    m_splitView(0),
-    m_editableUrl(0),
-    m_filterBar(0),
     m_showDeleteCommand(0),
     m_confirmMoveToTrash(0),
-    m_confirmDelete(0)
+    m_confirmDelete(0),
+    m_browseThroughArchives(0)
 {
+    Q_UNUSED(mainWin);
+
     const int spacing = KDialog::spacingHint();
 
     QVBoxLayout* topLayout = new QVBoxLayout(this);
     KVBox* vBox = new KVBox(this);
     vBox->setSpacing(spacing);
 
-    // create 'Home URL' editor
-    QGroupBox* homeBox = new QGroupBox(i18nc("@title:group", "Home Folder"), vBox);
-
-    KHBox* homeUrlBox = new KHBox(homeBox);
-    homeUrlBox->setSpacing(spacing);
-
-    new QLabel(i18nc("@label:textbox", "Location:"), homeUrlBox);
-    m_homeUrl = new QLineEdit(homeUrlBox);
-
-    QPushButton* selectHomeUrlButton = new QPushButton(KIcon("folder-open"), QString(), homeUrlBox);
-    connect(selectHomeUrlButton, SIGNAL(clicked()),
-            this, SLOT(selectHomeUrl()));
-
-    KHBox* buttonBox = new KHBox(homeBox);
-    buttonBox->setSpacing(spacing);
-
-    QPushButton* useCurrentButton = new QPushButton(i18nc("@action:button", "Use Current Location"), buttonBox);
-    connect(useCurrentButton, SIGNAL(clicked()),
-            this, SLOT(useCurrentLocation()));
-    QPushButton* useDefaultButton = new QPushButton(i18nc("@action:button", "Use Default Location"), buttonBox);
-    connect(useDefaultButton, SIGNAL(clicked()),
-            this, SLOT(useDefaultLocation()));
-
-    QVBoxLayout* homeBoxLayout = new QVBoxLayout(homeBox);
-    homeBoxLayout->addWidget(homeUrlBox);
-    homeBoxLayout->addWidget(buttonBox);
-
-    QGroupBox* startBox = new QGroupBox(i18nc("@title:group", "Startup Settings"), vBox);
-
-    // create 'Split view', 'Editable location' and 'Filter bar' checkboxes
-    m_splitView = new QCheckBox(i18nc("@option:check Startup Settings", "Split view mode"), startBox);
-    m_editableUrl = new QCheckBox(i18nc("@option:check Startup Settings", "Editable location bar"), startBox);
-    m_filterBar = new QCheckBox(i18nc("@option:check Startup Settings", "Show filter bar"),startBox);
-
-    QVBoxLayout* startBoxLayout = new QVBoxLayout(startBox);
-    startBoxLayout->addWidget(m_splitView);
-    startBoxLayout->addWidget(m_editableUrl);
-    startBoxLayout->addWidget(m_filterBar);
-
     // create 'Ask Confirmation For' group
     QGroupBox* confirmBox = new QGroupBox(i18nc("@title:group", "Ask For Confirmation When"), vBox);
     m_confirmMoveToTrash = new QCheckBox(i18nc("@option:check Ask for Confirmation When",
@@ -109,6 +62,8 @@ GeneralSettingsPage::GeneralSettingsPage(DolphinMainWindow* mainWin, QWidget* pa
     // create 'Show the command 'Delete' in context menu' checkbox
     m_showDeleteCommand = new QCheckBox(i18nc("@option:check", "Show 'Delete' command in context menu"), vBox);
 
+    m_browseThroughArchives = new QCheckBox(i18nc("option:check", "Browse through archives"), vBox);
+
     // Add a dummy widget with no restriction regarding
     // a vertical resizing. This assures that the dialog layout
     // is not stretched vertically.
@@ -127,16 +82,6 @@ void GeneralSettingsPage::applySettings()
 {
     GeneralSettings* settings = DolphinSettings::instance().generalSettings();
 
-    const KUrl url(m_homeUrl->text());
-    KFileItem fileItem(S_IFDIR, KFileItem::Unknown, url);
-    if (url.isValid() && fileItem.isDir()) {
-        settings->setHomeUrl(url.prettyUrl());
-    }
-
-    settings->setSplitView(m_splitView->isChecked());
-    settings->setEditableUrl(m_editableUrl->isChecked());
-    settings->setFilterBar(m_filterBar->isChecked());
-
     KSharedConfig::Ptr konqConfig = KSharedConfig::openConfig("konquerorrc", KConfig::IncludeGlobals);
     KConfigGroup trashConfig(konqConfig, "Trash");
     trashConfig.writeEntry("ConfirmTrash", m_confirmMoveToTrash->isChecked());
@@ -146,6 +91,8 @@ void GeneralSettingsPage::applySettings()
     KConfigGroup kdeConfig(KGlobal::config(), "KDE");
     kdeConfig.writeEntry("ShowDeleteCommand", m_showDeleteCommand->isChecked());
     kdeConfig.sync();
+
+    settings->setBrowseThroughArchives(m_browseThroughArchives->isChecked());
 }
 
 void GeneralSettingsPage::restoreDefaults()
@@ -158,34 +105,8 @@ void GeneralSettingsPage::restoreDefaults()
     loadSettings();
 }
 
-void GeneralSettingsPage::selectHomeUrl()
-{
-    const QString homeUrl(m_homeUrl->text());
-    KUrl url(KFileDialog::getExistingDirectoryUrl(homeUrl));
-    if (!url.isEmpty()) {
-        m_homeUrl->setText(url.prettyUrl());
-    }
-}
-
-void GeneralSettingsPage::useCurrentLocation()
-{
-    const DolphinView* view = m_mainWindow->activeViewContainer()->view();
-    m_homeUrl->setText(view->url().prettyUrl());
-}
-
-void GeneralSettingsPage::useDefaultLocation()
-{
-    m_homeUrl->setText("file://" + QDir::homePath());
-}
-
 void GeneralSettingsPage::loadSettings()
 {
-    GeneralSettings* settings = DolphinSettings::instance().generalSettings();
-    m_homeUrl->setText(settings->homeUrl());
-    m_splitView->setChecked(settings->splitView());
-    m_editableUrl->setChecked(settings->editableUrl());
-    m_filterBar->setChecked(settings->filterBar());
-
     KSharedConfig::Ptr konqConfig = KSharedConfig::openConfig("konquerorrc", KConfig::IncludeGlobals);
     const KConfigGroup trashConfig(konqConfig, "Trash");
     m_confirmMoveToTrash->setChecked(trashConfig.readEntry("ConfirmTrash", false));
@@ -193,6 +114,9 @@ void GeneralSettingsPage::loadSettings()
 
     const KConfigGroup kdeConfig(KGlobal::config(), "KDE");
     m_showDeleteCommand->setChecked(kdeConfig.readEntry("ShowDeleteCommand", false));
+
+    GeneralSettings* settings = DolphinSettings::instance().generalSettings();
+    m_browseThroughArchives->setChecked(settings->browseThroughArchives());
 }
 
 #include "generalsettingspage.moc"
index 7bcf75c9e3835d11b3b80646733de04e5d4a883d..df713ad477ec6f8c446b1aaa3a13a09bf26915a9 100644 (file)
@@ -28,9 +28,6 @@ class QCheckBox;
 
 /**
  * @brief Page for the 'General' settings of the Dolphin settings dialog.
- *
- * The general settings allow to set the home URL and to configure the
- * state of the view mode, split mode and the filter bar when starting Dolphin.
  */
 class GeneralSettingsPage : public SettingsPageBase
 {
@@ -46,25 +43,15 @@ public:
     /** @see SettingsPageBase::restoreDefaults() */
     virtual void restoreDefaults();
 
-private slots:
-    void selectHomeUrl();
-    void useCurrentLocation();
-    void useDefaultLocation();
-
 private:
     void loadSettings();
 
 private:
-    DolphinMainWindow* m_mainWindow;
-    QLineEdit* m_homeUrl;
-
-    QCheckBox* m_splitView;
-    QCheckBox* m_editableUrl;
-    QCheckBox* m_filterBar;
-
     QCheckBox* m_showDeleteCommand;
     QCheckBox* m_confirmMoveToTrash;
     QCheckBox* m_confirmDelete;
+
+    QCheckBox* m_browseThroughArchives;
 };
 
 #endif
index 2d815d3d20274995a083d10e901ed3ae6137c5bc..ebf235f2a392ae165f56f39e44de4d51fd8d4e94 100644 (file)
@@ -47,7 +47,8 @@ GeneralViewSettingsPage::GeneralViewSettingsPage(DolphinMainWindow* mainWindow,
     m_globalProps(0),
     m_maxPreviewSize(0),
     m_spinBox(0),
-    m_useFileThumbnails(0)
+    m_useFileThumbnails(0),
+    m_showSelectionToggle(0)
 {
     const int spacing = KDialog::spacingHint();
     const int margin = KDialog::marginHint();
@@ -71,7 +72,7 @@ GeneralViewSettingsPage::GeneralViewSettingsPage(DolphinMainWindow* mainWindow,
     KHBox* vBox = new KHBox(previewBox);
     vBox->setSpacing(spacing);
 
-    QLabel* maxFileSize = new QLabel(i18nc("@label:slider", "Maximum file size:"), vBox);
+    new QLabel(i18nc("@label:slider", "Maximum file size:"), vBox);
     m_maxPreviewSize = new QSlider(Qt::Horizontal, vBox);
 
     m_spinBox = new QSpinBox(vBox);
@@ -87,6 +88,8 @@ GeneralViewSettingsPage::GeneralViewSettingsPage(DolphinMainWindow* mainWindow,
     previewBoxLayout->addWidget(vBox);
     previewBoxLayout->addWidget(m_useFileThumbnails);
 
+    m_showSelectionToggle = new QCheckBox(i18nc("option:check", "Show selection toggle"), this);
+
     // Add a dummy widget with no restriction regarding
     // a vertical resizing. This assures that the dialog layout
     // is not stretched vertically.
@@ -128,6 +131,8 @@ void GeneralViewSettingsPage::applySettings()
                             m_useFileThumbnails->isChecked(),
                             KConfigBase::Normal | KConfigBase::Global);
     globalConfig.sync();
+
+    settings->setShowSelectionToggle(m_showSelectionToggle->isChecked());
 }
 
 void GeneralViewSettingsPage::restoreDefaults()
@@ -154,6 +159,9 @@ void GeneralViewSettingsPage::loadSettings()
     m_maxPreviewSize->setTickPosition(QSlider::TicksBelow);
 
     KConfigGroup globalConfig(KGlobal::config(), "PreviewSettings");
+    // TODO: The default value of 5 MB must match with the default value inside
+    // kdelibs/kio/kio/previewjob.cpp. Maybe a static getter method in PreviewJob
+    // should be added for getting the default size?
     const int maxByteSize = globalConfig.readEntry("MaximumSize", 5 * 1024 * 1024 /* 5 MB */);
     int maxMByteSize = maxByteSize / (1024 * 1024);
     if (maxMByteSize < 1) {
@@ -171,6 +179,8 @@ void GeneralViewSettingsPage::loadSettings()
 
     const bool useFileThumbnails = globalConfig.readEntry("UseFileThumbnails", true);
     m_useFileThumbnails->setChecked(useFileThumbnails);
+
+    m_showSelectionToggle->setChecked(settings->showSelectionToggle());
 }
 
 #include "generalviewsettingspage.moc"
index 5aad4be4fc1146b5ecd8a091f1d03a14bbd40a8b..c84335dc1e655011ab320820177e7c36d257c9ba 100644 (file)
@@ -60,6 +60,7 @@ private:
     QSlider* m_maxPreviewSize;
     QSpinBox* m_spinBox;
     QCheckBox* m_useFileThumbnails;
+    QCheckBox* m_showSelectionToggle;
 };
 
 #endif
diff --git a/src/iconmanager.cpp b/src/iconmanager.cpp
new file mode 100644 (file)
index 0000000..5940c90
--- /dev/null
@@ -0,0 +1,232 @@
+/***************************************************************************
+ *   Copyright (C) 2008 by Peter Penz <peter.penz@gmx.at>                  *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
+ ***************************************************************************/
+
+#include "iconmanager.h"
+
+#include "dolphinmodel.h"
+#include "dolphinsortfilterproxymodel.h"
+
+#include <kiconeffect.h>
+#include <kio/previewjob.h>
+#include <kdebug.h>
+#include <kdirlister.h>
+#include <konqmimedata.h>
+
+#include <QApplication>
+#include <QAbstractItemView>
+#include <QClipboard>
+#include <QColor>
+#include <QIcon>
+
+IconManager::IconManager(QAbstractItemView* parent, DolphinSortFilterProxyModel* model) :
+    QObject(parent),
+    m_showPreview(false),
+    m_view(parent),
+    m_previewJobs(),
+    m_dolphinModel(0),
+    m_proxyModel(model),
+    m_cutItemsCache()
+{
+    Q_ASSERT(m_view->iconSize().isValid());  // each view must provide its current icon size
+
+    m_dolphinModel = static_cast<DolphinModel*>(m_proxyModel->sourceModel());
+    connect(m_dolphinModel->dirLister(), SIGNAL(newItems(const KFileItemList&)),
+            this, SLOT(updateIcons(const KFileItemList&)));
+
+    QClipboard* clipboard = QApplication::clipboard();
+    connect(clipboard, SIGNAL(dataChanged()),
+            this, SLOT(updateCutItems()));
+}
+
+IconManager::~IconManager()
+{
+    foreach (KJob* job, m_previewJobs) {
+        Q_ASSERT(job != 0);
+        job->kill();
+    }
+    m_previewJobs.clear();
+}
+
+
+void IconManager::setShowPreview(bool show)
+{
+    if (m_showPreview != show) {
+        m_showPreview = show;
+        m_cutItemsCache.clear();
+        updateCutItems();
+    }
+}
+
+void IconManager::updateIcons(const KFileItemList& items)
+{
+    // make the icons of all hidden files semitransparent
+    foreach (KFileItem item, items) {
+        if (item.isHidden()) {
+            applyHiddenItemEffect(item);
+        }
+    }
+
+    if (!m_showPreview) {
+        return;
+    }
+
+    // generate previews
+    const QRect visibleArea = m_view->viewport()->rect();
+
+    // Order the items in a way that the preview for the visible items
+    // is generated first, as this improves the feeled performance a lot.
+    KFileItemList orderedItems;
+    foreach (KFileItem item, items) {
+        const QModelIndex dirIndex = m_dolphinModel->indexForItem(item);
+        const QModelIndex proxyIndex = m_proxyModel->mapFromSource(dirIndex);
+        const QRect itemRect = m_view->visualRect(proxyIndex);
+        if (itemRect.intersects(visibleArea)) {
+            orderedItems.insert(0, item);
+        } else {
+            orderedItems.append(item);
+        }
+    }
+
+    const QSize size = m_view->iconSize();
+    KIO::PreviewJob* job = KIO::filePreview(orderedItems, size.width(), size.height());
+    connect(job, SIGNAL(gotPreview(const KFileItem&, const QPixmap&)),
+            this, SLOT(replaceIcon(const KFileItem&, const QPixmap&)));
+    connect(job, SIGNAL(finished(KJob*)),
+            this, SLOT(slotPreviewJobFinished(KJob*)));
+
+    m_previewJobs.append(job);
+}
+
+void IconManager::replaceIcon(const KFileItem& item, const QPixmap& pixmap)
+{
+    Q_ASSERT(!item.isNull());
+    KDirLister* dirLister = m_dolphinModel->dirLister();
+    if (!m_showPreview || (item.url().directory() != dirLister->url().path())) {
+        // the preview has been canceled in the meanwhile or the preview
+        // job is still working on items of an older URL, hence
+        // the item is not part of the directory model anymore
+        return;
+    }
+
+    const QModelIndex idx = m_dolphinModel->indexForItem(item);
+    if (idx.isValid() && (idx.column() == 0)) {
+        QPixmap icon = pixmap;
+        if (item.isHidden()) {
+            if (!icon.hasAlpha()) {
+                // the semitransparent operation requires having an alpha mask
+                QPixmap alphaMask(icon.width(), icon.height());
+                alphaMask.fill();
+                icon.setAlphaChannel(alphaMask);
+            }
+            KIconEffect::semiTransparent(icon);
+        }
+
+        const QMimeData* mimeData = QApplication::clipboard()->mimeData();
+        if (KonqMimeData::decodeIsCutSelection(mimeData) && isCutItem(item)) {
+            KIconEffect iconEffect;
+            icon = iconEffect.apply(icon, KIconLoader::Desktop, KIconLoader::DisabledState);
+            m_dolphinModel->setData(idx, QIcon(icon), Qt::DecorationRole);
+        } else {
+            m_dolphinModel->setData(idx, QIcon(icon), Qt::DecorationRole);
+        }
+    }
+}
+
+void IconManager::slotPreviewJobFinished(KJob* job)
+{
+    const int index = m_previewJobs.indexOf(job);
+    m_previewJobs.removeAt(index);
+}
+
+void IconManager::updateCutItems()
+{
+    // restore the icons of all previously selected items to the
+    // original state...
+    foreach (CutItem cutItem, m_cutItemsCache) {
+        const QModelIndex index = m_dolphinModel->indexForUrl(cutItem.url);
+        if (index.isValid()) {
+            m_dolphinModel->setData(index, QIcon(cutItem.pixmap), Qt::DecorationRole);
+        }
+    }
+    m_cutItemsCache.clear();
+
+    // ... and apply an item effect to all currently cut items
+    applyCutItemEffect();
+}
+
+bool IconManager::isCutItem(const KFileItem& item) const
+{
+    const QMimeData* mimeData = QApplication::clipboard()->mimeData();
+    const KUrl::List cutUrls = KUrl::List::fromMimeData(mimeData);
+
+    const KUrl& itemUrl = item.url();
+    foreach (KUrl url, cutUrls) {
+        if (url == itemUrl) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+void IconManager::applyCutItemEffect()
+{
+    const QMimeData* mimeData = QApplication::clipboard()->mimeData();
+    if (!KonqMimeData::decodeIsCutSelection(mimeData)) {
+        return;
+    }
+
+    const KFileItemList items(m_dolphinModel->dirLister()->items());
+    foreach (KFileItem item, items) {
+        if (isCutItem(item)) {
+            const QModelIndex index = m_dolphinModel->indexForItem(item);
+            const QVariant value = m_dolphinModel->data(index, Qt::DecorationRole);
+            if (value.type() == QVariant::Icon) {
+                const QIcon icon(qvariant_cast<QIcon>(value));
+                QPixmap pixmap = icon.pixmap(m_view->iconSize());
+
+                // 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, KIconLoader::Desktop, KIconLoader::DisabledState);
+                m_dolphinModel->setData(index, QIcon(pixmap), Qt::DecorationRole);
+            }
+        }
+    }
+}
+
+void IconManager::applyHiddenItemEffect(const KFileItem& hiddenItem)
+{
+    const QModelIndex index = m_dolphinModel->indexForItem(hiddenItem);
+    const QVariant value = m_dolphinModel->data(index, Qt::DecorationRole);
+    if (value.type() == QVariant::Icon) {
+        const QIcon icon(qvariant_cast<QIcon>(value));
+        QPixmap pixmap = icon.pixmap(m_view->iconSize());
+        KIconEffect::semiTransparent(pixmap);
+        m_dolphinModel->setData(index, QIcon(pixmap), Qt::DecorationRole);
+    }
+}
+
+#include "iconmanager.moc"
diff --git a/src/iconmanager.h b/src/iconmanager.h
new file mode 100644 (file)
index 0000000..d6cf533
--- /dev/null
@@ -0,0 +1,114 @@
+/***************************************************************************
+ *   Copyright (C) 2008 by Peter Penz <peter.penz@gmx.at>                  *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
+ ***************************************************************************/
+
+#ifndef ICONMANAGER_H
+#define ICONMANAGER_H
+
+#include <kfileitem.h>
+#include <kurl.h>
+
+#include <QList>
+#include <QObject>
+#include <QPixmap>
+
+class DolphinModel;
+class DolphinSortFilterProxyModel;
+class KJob;
+class QAbstractItemView;
+
+/**
+ * @brief Manages the icon state of a directory model.
+ *
+ * Per default a preview is generated for each item.
+ * Additionally the clipboard is checked for cut items.
+ * The icon state for cut items gets dimmed automatically.
+ */
+class IconManager : public QObject
+{
+    Q_OBJECT
+
+public:
+    IconManager(QAbstractItemView* parent, DolphinSortFilterProxyModel* model);
+    virtual ~IconManager();
+    void setShowPreview(bool show);
+    bool showPreview() const;
+
+private slots:
+    /**
+     * Updates the icons of for each item in \a items by making hidden
+     * items semitransparent and generating previews. The current preview
+     * settings (maximum size, 'Show Preview' menu) are respected.
+     */
+    void updateIcons(const KFileItemList& items);
+
+    /**
+     * Replaces the icon of the item \a item by the preview pixmap
+     * \a pixmap.
+     */
+    void replaceIcon(const KFileItem& item, const QPixmap& pixmap);
+
+    /**
+     * Is invoked when the preview job has been finished and
+     * set m_previewJob to 0.
+     */
+    void slotPreviewJobFinished(KJob* job);
+
+    /** Synchronizes the item icon with the clipboard of cut items. */
+    void updateCutItems();
+
+private:
+    /**
+     * Returns true, if the item \a item has been cut into
+     * the clipboard.
+     */
+    bool isCutItem(const KFileItem& item) const;
+
+    /** Applies an item effect to all cut items. */
+    void applyCutItemEffect();
+
+    /** Applies an item effect to the hidden item \a hiddenItem. */
+    void applyHiddenItemEffect(const KFileItem& hiddenItem);
+
+private:
+    /**
+     * Remembers the original pixmap for an item before
+     * the cut effect is applied.
+     */
+    struct CutItem
+    {
+        KUrl url;
+        QPixmap pixmap;
+    };
+
+    bool m_showPreview;
+
+    QAbstractItemView* m_view;
+    QList<KJob*> m_previewJobs;
+    DolphinModel* m_dolphinModel;
+    DolphinSortFilterProxyModel* m_proxyModel;
+
+    QList<CutItem> m_cutItemsCache;
+};
+
+inline bool IconManager::showPreview() const
+{
+    return m_showPreview;
+}
+
+#endif
index bcb28aa1987c006ea1eb58dcec229430018fa165..30c4467b45d138cc6dcd4c9985e252709c648839 100644 (file)
@@ -69,7 +69,7 @@ InfoSidebarPage::InfoSidebarPage(QWidget* parent) :
     // preview
     m_preview = new PixmapViewer(this);
     m_preview->setMinimumWidth(KIconLoader::SizeEnormous);
-    m_preview->setFixedHeight(KIconLoader::SizeEnormous);
+    m_preview->setMinimumHeight(KIconLoader::SizeEnormous);
 
     // name
     m_nameLabel = new QLabel(this);
@@ -169,6 +169,12 @@ void InfoSidebarPage::resizeEvent(QResizeEvent* event)
     const int maxWidth = event->size().width() - KDialog::spacingHint() * 4;
     m_nameLabel->setMaximumWidth(maxWidth);
     m_infoLabel->setMaximumWidth(maxWidth);
+
+    // try to increase the preview as large as possible
+    m_preview->setSizeHint(QSize(maxWidth, maxWidth));
+    m_urlCandidate = m_shownUrl; // reset the URL candidate if a resizing is done
+    m_timer->start(TimerDelay);
+
     SidebarPage::resizeEvent(event);
 }
 
@@ -196,7 +202,7 @@ void InfoSidebarPage::showItemInfo()
         KIconLoader iconLoader;
         QPixmap icon = iconLoader.loadIcon("system-run",
                                            KIconLoader::NoGroup,
-                                           KIconLoader::SizeEnormous);
+                                           m_preview->width());
         m_preview->setPixmap(icon);
         m_nameLabel->setText(i18ncp("@info", "%1 item selected", "%1 items selected", selectedItems.count()));
     } else if (!applyPlace(file)) {
@@ -209,7 +215,7 @@ void InfoSidebarPage::showItemInfo()
 
         KIO::PreviewJob* job = KIO::filePreview(list,
                                                 m_preview->width(),
-                                                KIconLoader::SizeEnormous,
+                                                m_preview->height(),
                                                 0,
                                                 0,
                                                 true,
diff --git a/src/kcategorizedview.cpp b/src/kcategorizedview.cpp
deleted file mode 100644 (file)
index 648a712..0000000
+++ /dev/null
@@ -1,1596 +0,0 @@
-/**
-  * This file is part of the KDE project
-  * Copyright (C) 2007 Rafael Fernández López <ereslibre@kde.org>
-  *
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Library General Public
-  * License as published by the Free Software Foundation; either
-  * version 2 of the License, or (at your option) any later version.
-  *
-  * This library is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  * Library General Public License for more details.
-  *
-  * You should have received a copy of the GNU Library General Public License
-  * along with this library; see the file COPYING.LIB.  If not, write to
-  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-  * Boston, MA 02110-1301, USA.
-  */
-
-#include "kcategorizedview.h"
-#include "kcategorizedview_p.h"
-
-#include <math.h> // trunc on C99 compliant systems
-#include <kdefakes.h> // trunc for not C99 compliant systems
-
-#include <QPainter>
-#include <QScrollBar>
-#include <QPaintEvent>
-
-#include <kstyle.h>
-
-#include "kcategorydrawer.h"
-#include "kcategorizedsortfilterproxymodel.h"
-
-// By defining DOLPHIN_DRAGANDDROP the custom drag and drop implementation of
-// KCategorizedView is bypassed to have a consistent drag and drop look for all
-// views. Hopefully transparent pixmaps for drag objects will be supported in
-// Qt 4.4, so that this workaround can be skipped.
-#define DOLPHIN_DRAGANDDROP
-
-KCategorizedView::Private::Private(KCategorizedView *listView)
-    : listView(listView)
-    , categoryDrawer(0)
-    , biggestItemSize(QSize(0, 0))
-    , mouseButtonPressed(false)
-    , rightMouseButtonPressed(false)
-    , isDragging(false)
-    , dragLeftViewport(false)
-    , proxyModel(0)
-{
-}
-
-KCategorizedView::Private::~Private()
-{
-}
-
-const QModelIndexList &KCategorizedView::Private::intersectionSet(const QRect &rect)
-{
-    QModelIndex index;
-    QRect indexVisualRect;
-
-    intersectedIndexes.clear();
-
-    int itemHeight;
-
-    if (listView->gridSize().isEmpty())
-    {
-        itemHeight = biggestItemSize.height();
-    }
-    else
-    {
-        itemHeight = listView->gridSize().height();
-    }
-
-    // Lets find out where we should start
-    int top = proxyModel->rowCount() - 1;
-    int bottom = 0;
-    int middle = (top + bottom) / 2;
-    while (bottom <= top)
-    {
-        middle = (top + bottom) / 2;
-
-        index = proxyModel->index(middle, 0);
-        indexVisualRect = visualRect(index);
-        // We need the whole height (not only the visualRect). This will help us to update
-        // all needed indexes correctly (ereslibre)
-        indexVisualRect.setHeight(indexVisualRect.height() + (itemHeight - indexVisualRect.height()));
-
-        if (qMax(indexVisualRect.topLeft().y(),
-                 indexVisualRect.bottomRight().y()) < qMin(rect.topLeft().y(),
-                                                           rect.bottomRight().y()))
-        {
-            bottom = middle + 1;
-        }
-        else
-        {
-            top = middle - 1;
-        }
-    }
-
-    for (int i = middle; i < proxyModel->rowCount(); i++)
-    {
-        index = proxyModel->index(i, 0);
-        indexVisualRect = visualRect(index);
-
-        if (rect.intersects(indexVisualRect))
-            intersectedIndexes.append(index);
-
-        // If we passed next item, stop searching for hits
-        if (qMax(rect.bottomRight().y(), rect.topLeft().y()) <
-                                                  qMin(indexVisualRect.topLeft().y(),
-                                                       indexVisualRect.bottomRight().y()))
-            break;
-    }
-
-    return intersectedIndexes;
-}
-
-QRect KCategorizedView::Private::visualRectInViewport(const QModelIndex &index) const
-{
-    if (!index.isValid())
-        return QRect();
-
-    QString curCategory = elementsInfo[index.row()].category;
-
-    QRect retRect;
-
-    if (listView->layoutDirection() == Qt::LeftToRight)
-    {
-        retRect = QRect(listView->spacing(), listView->spacing() * 2 +
-                        categoryDrawer->categoryHeight(index, listView->viewOptions()), 0, 0);
-    }
-    else
-    {
-        retRect = QRect(listView->viewport()->width() - listView->spacing(), listView->spacing() * 2 +
-                        categoryDrawer->categoryHeight(index, listView->viewOptions()), 0, 0);
-    }
-
-    int viewportWidth = listView->viewport()->width() - listView->spacing();
-
-    int itemHeight;
-    int itemWidth;
-
-    if (listView->gridSize().isEmpty())
-    {
-        itemHeight = biggestItemSize.height();
-        itemWidth = biggestItemSize.width();
-    }
-    else
-    {
-        itemHeight = listView->gridSize().height();
-        itemWidth = listView->gridSize().width();
-    }
-
-    int itemWidthPlusSeparation = listView->spacing() + itemWidth;
-    int elementsPerRow = viewportWidth / itemWidthPlusSeparation;
-    if (!elementsPerRow)
-        elementsPerRow++;
-
-    int column = elementsInfo[index.row()].relativeOffsetToCategory % elementsPerRow;
-    int row = elementsInfo[index.row()].relativeOffsetToCategory / elementsPerRow;
-
-    if (listView->layoutDirection() == Qt::LeftToRight)
-    {
-        retRect.setLeft(retRect.left() + column * listView->spacing() +
-                        column * itemWidth);
-    }
-    else
-    {
-        retRect.setLeft(retRect.right() - column * listView->spacing() -
-                         column * itemWidth - itemWidth);
-
-        retRect.setRight(retRect.right() - column * listView->spacing() -
-                         column * itemWidth);
-    }
-
-    foreach (const QString &category, categories)
-    {
-        if (category == curCategory)
-            break;
-
-        float rows = (float) ((float) categoriesIndexes[category].count() /
-                              (float) elementsPerRow);
-
-        int rowsInt = categoriesIndexes[category].count() / elementsPerRow;
-
-        if (rows - trunc(rows)) rowsInt++;
-
-        retRect.setTop(retRect.top() +
-                       (rowsInt * itemHeight) +
-                       categoryDrawer->categoryHeight(index, listView->viewOptions()) +
-                       listView->spacing() * 2);
-
-        if (listView->gridSize().isEmpty())
-        {
-            retRect.setTop(retRect.top() +
-                           (rowsInt * listView->spacing()));
-        }
-    }
-
-    if (listView->gridSize().isEmpty())
-    {
-        retRect.setTop(retRect.top() + row * listView->spacing() +
-                       (row * itemHeight));
-    }
-    else
-    {
-        retRect.setTop(retRect.top() + (row * itemHeight));
-    }
-
-    retRect.setWidth(itemWidth);
-
-    QModelIndex heightIndex = proxyModel->index(index.row(), 0);
-    if (listView->gridSize().isEmpty())
-    {
-        retRect.setHeight(listView->sizeHintForIndex(heightIndex).height());
-    }
-    else
-    {
-        retRect.setHeight(qMin(listView->sizeHintForIndex(heightIndex).height(),
-                               listView->gridSize().height()));
-    }
-
-    return retRect;
-}
-
-QRect KCategorizedView::Private::visualCategoryRectInViewport(const QString &category)
-                                                                           const
-{
-    QRect retRect(listView->spacing(),
-                  listView->spacing(),
-                  listView->viewport()->width() - listView->spacing() * 2,
-                  0);
-
-    if (!proxyModel->rowCount() || !categories.contains(category))
-        return QRect();
-
-    QModelIndex index = proxyModel->index(0, 0, QModelIndex());
-
-    int viewportWidth = listView->viewport()->width() - listView->spacing();
-
-    int itemHeight;
-    int itemWidth;
-
-    if (listView->gridSize().isEmpty())
-    {
-        itemHeight = biggestItemSize.height();
-        itemWidth = biggestItemSize.width();
-    }
-    else
-    {
-        itemHeight = listView->gridSize().height();
-        itemWidth = listView->gridSize().width();
-    }
-
-    int itemWidthPlusSeparation = listView->spacing() + itemWidth;
-    int elementsPerRow = viewportWidth / itemWidthPlusSeparation;
-
-    if (!elementsPerRow)
-        elementsPerRow++;
-
-    foreach (const QString &itCategory, categories)
-    {
-        if (itCategory == category)
-            break;
-
-        float rows = (float) ((float) categoriesIndexes[itCategory].count() /
-                              (float) elementsPerRow);
-        int rowsInt = categoriesIndexes[itCategory].count() / elementsPerRow;
-
-        if (rows - trunc(rows)) rowsInt++;
-
-        retRect.setTop(retRect.top() +
-                       (rowsInt * itemHeight) +
-                       categoryDrawer->categoryHeight(index, listView->viewOptions()) +
-                       listView->spacing() * 2);
-
-        if (listView->gridSize().isEmpty())
-        {
-            retRect.setTop(retRect.top() +
-                           (rowsInt * listView->spacing()));
-        }
-    }
-
-    retRect.setHeight(categoryDrawer->categoryHeight(index, listView->viewOptions()));
-
-    return retRect;
-}
-
-// We're sure elementsPosition doesn't contain index
-const QRect &KCategorizedView::Private::cacheIndex(const QModelIndex &index)
-{
-    QRect rect = visualRectInViewport(index);
-    elementsPosition[index.row()] = rect;
-
-    return elementsPosition[index.row()];
-}
-
-// We're sure categoriesPosition doesn't contain category
-const QRect &KCategorizedView::Private::cacheCategory(const QString &category)
-{
-    QRect rect = visualCategoryRectInViewport(category);
-    categoriesPosition[category] = rect;
-
-    return categoriesPosition[category];
-}
-
-const QRect &KCategorizedView::Private::cachedRectIndex(const QModelIndex &index)
-{
-    if (elementsPosition.contains(index.row())) // If we have it cached
-    {                                        // return it
-        return elementsPosition[index.row()];
-    }
-    else                                     // Otherwise, cache it
-    {                                        // and return it
-        return cacheIndex(index);
-    }
-}
-
-const QRect &KCategorizedView::Private::cachedRectCategory(const QString &category)
-{
-    if (categoriesPosition.contains(category)) // If we have it cached
-    {                                                // return it
-        return categoriesPosition[category];
-    }
-    else                                            // Otherwise, cache it and
-    {                                               // return it
-        return cacheCategory(category);
-    }
-}
-
-QRect KCategorizedView::Private::visualRect(const QModelIndex &index)
-{
-    QRect retRect = cachedRectIndex(index);
-    int dx = -listView->horizontalOffset();
-    int dy = -listView->verticalOffset();
-    retRect.adjust(dx, dy, dx, dy);
-
-    return retRect;
-}
-
-QRect KCategorizedView::Private::categoryVisualRect(const QString &category)
-{
-    QRect retRect = cachedRectCategory(category);
-    int dx = -listView->horizontalOffset();
-    int dy = -listView->verticalOffset();
-    retRect.adjust(dx, dy, dx, dy);
-
-    return retRect;
-}
-
-void KCategorizedView::Private::drawNewCategory(const QModelIndex &index,
-                                                int sortRole,
-                                                const QStyleOption &option,
-                                                QPainter *painter)
-{
-    if (!index.isValid())
-    {
-        return;
-    }
-
-    QStyleOption optionCopy = option;
-    const QString category = proxyModel->data(index, KCategorizedSortFilterProxyModel::CategoryDisplayRole).toString();
-
-    optionCopy.state &= ~QStyle::State_Selected;
-
-    if ((listView->selectionMode() != SingleSelection) && (listView->selectionMode() != NoSelection)) {
-        if ((category == hoveredCategory) && !mouseButtonPressed)
-        {
-            optionCopy.state |= QStyle::State_MouseOver;
-        }
-        else if ((category == hoveredCategory) && mouseButtonPressed)
-        {
-            QPoint initialPressPosition = listView->viewport()->mapFromGlobal(QCursor::pos());
-            initialPressPosition.setY(initialPressPosition.y() + listView->verticalOffset());
-            initialPressPosition.setX(initialPressPosition.x() + listView->horizontalOffset());
-
-            if (initialPressPosition == this->initialPressPosition)
-            {
-                optionCopy.state |= QStyle::State_Selected;
-            }
-        }
-    }
-
-    categoryDrawer->drawCategory(index,
-                                 sortRole,
-                                 optionCopy,
-                                 painter);
-}
-
-
-void KCategorizedView::Private::updateScrollbars()
-{
-    // find the last index in the last category
-    QModelIndex lastIndex = categoriesIndexes.isEmpty() ? QModelIndex() : categoriesIndexes[categories.last()].last();
-
-    int lastItemBottom = cachedRectIndex(lastIndex).top() +
-                         listView->spacing() + (listView->gridSize().isEmpty() ? biggestItemSize.height() : listView->gridSize().height()) - listView->viewport()->height();
-
-    listView->horizontalScrollBar()->setRange(0, 0);
-
-    listView->verticalScrollBar()->setSingleStep(listView->viewport()->height() / 10);
-    listView->verticalScrollBar()->setPageStep(listView->viewport()->height());
-    listView->verticalScrollBar()->setRange(0, lastItemBottom);
-}
-
-void KCategorizedView::Private::drawDraggedItems(QPainter *painter)
-{
-    QStyleOptionViewItemV3 option = listView->viewOptions();
-    option.state &= ~QStyle::State_MouseOver;
-    foreach (const QModelIndex &index, listView->selectionModel()->selectedIndexes())
-    {
-        const int dx = mousePosition.x() - initialPressPosition.x() + listView->horizontalOffset();
-        const int dy = mousePosition.y() - initialPressPosition.y() + listView->verticalOffset();
-
-        option.rect = visualRect(index);
-        option.rect.adjust(dx, dy, dx, dy);
-
-        if (option.rect.intersects(listView->viewport()->rect()))
-        {
-            listView->itemDelegate(index)->paint(painter, option, index);
-        }
-    }
-}
-
-void KCategorizedView::Private::layoutChanged(bool forceItemReload)
-{
-    if ((listView->viewMode() == KCategorizedView::IconMode) && proxyModel &&
-        categoryDrawer && proxyModel->isCategorizedModel() &&
-        ((forceItemReload ||
-          (modelSortRole != proxyModel->sortRole()) ||
-          (modelSortColumn != proxyModel->sortColumn()) ||
-          (modelSortOrder != proxyModel->sortOrder()) ||
-          (modelLastRowCount != proxyModel->rowCount()) ||
-          (modelCategorized != proxyModel->isCategorizedModel()))))
-    {
-        // Force the view to update all elements
-        listView->rowsInsertedArtifficial(QModelIndex(), 0, proxyModel->rowCount() - 1);
-
-        if (!forceItemReload)
-        {
-            modelSortRole = proxyModel->sortRole();
-            modelSortColumn = proxyModel->sortColumn();
-            modelSortOrder = proxyModel->sortOrder();
-            modelLastRowCount = proxyModel->rowCount();
-            modelCategorized = proxyModel->isCategorizedModel();
-        }
-    }
-    else if ((listView->viewMode() == KCategorizedView::IconMode) && proxyModel &&
-             categoryDrawer && proxyModel->isCategorizedModel())
-    {
-        updateScrollbars();
-    }
-}
-
-void KCategorizedView::Private::drawDraggedItems()
-{
-    QRect rectToUpdate;
-    QRect currentRect;
-    foreach (const QModelIndex &index, listView->selectionModel()->selectedIndexes())
-    {
-        int dx = mousePosition.x() - initialPressPosition.x() + listView->horizontalOffset();
-        int dy = mousePosition.y() - initialPressPosition.y() + listView->verticalOffset();
-
-        currentRect = visualRect(index);
-        currentRect.adjust(dx, dy, dx, dy);
-
-        if (currentRect.intersects(listView->viewport()->rect()))
-        {
-            rectToUpdate = rectToUpdate.united(currentRect);
-        }
-    }
-
-    listView->viewport()->update(lastDraggedItemsRect.united(rectToUpdate));
-
-    lastDraggedItemsRect = rectToUpdate;
-}
-
-
-//==============================================================================
-
-
-KCategorizedView::KCategorizedView(QWidget *parent)
-    : QListView(parent)
-    , d(new Private(this))
-{
-}
-
-KCategorizedView::~KCategorizedView()
-{
-    delete d;
-}
-
-void KCategorizedView::setGridSize(const QSize &size)
-{
-    QListView::setGridSize(size);
-
-    d->layoutChanged(true);
-}
-
-void KCategorizedView::setModel(QAbstractItemModel *model)
-{
-    d->lastSelection = QItemSelection();
-    d->forcedSelectionPosition = 0;
-    d->elementsInfo.clear();
-    d->elementsPosition.clear();
-    d->categoriesIndexes.clear();
-    d->categoriesPosition.clear();
-    d->categories.clear();
-    d->intersectedIndexes.clear();
-    d->modelIndexList.clear();
-    d->hovered = QModelIndex();
-    d->mouseButtonPressed = false;
-    d->rightMouseButtonPressed = false;
-
-    if (d->proxyModel)
-    {
-        QObject::disconnect(d->proxyModel,
-                            SIGNAL(layoutChanged()),
-                            this, SLOT(slotLayoutChanged()));
-
-        QObject::disconnect(d->proxyModel,
-                            SIGNAL(dataChanged(QModelIndex,QModelIndex)),
-                            this, SLOT(slotLayoutChanged()));
-
-        QObject::disconnect(d->proxyModel,
-                            SIGNAL(rowsRemoved(QModelIndex,int,int)),
-                            this, SLOT(rowsRemoved(QModelIndex,int,int)));
-    }
-
-    QListView::setModel(model);
-
-    d->proxyModel = dynamic_cast<KCategorizedSortFilterProxyModel*>(model);
-
-    if (d->proxyModel)
-    {
-        d->modelSortRole = d->proxyModel->sortRole();
-        d->modelSortColumn = d->proxyModel->sortColumn();
-        d->modelSortOrder = d->proxyModel->sortOrder();
-        d->modelLastRowCount = d->proxyModel->rowCount();
-        d->modelCategorized = d->proxyModel->isCategorizedModel();
-
-        QObject::connect(d->proxyModel,
-                         SIGNAL(layoutChanged()),
-                         this, SLOT(slotLayoutChanged()));
-
-        QObject::connect(d->proxyModel,
-                         SIGNAL(dataChanged(QModelIndex,QModelIndex)),
-                         this, SLOT(slotLayoutChanged()));
-
-        QObject::connect(d->proxyModel,
-                         SIGNAL(rowsRemoved(QModelIndex,int,int)),
-                         this, SLOT(rowsRemoved(QModelIndex,int,int)));
-
-        if (d->proxyModel->rowCount())
-        {
-            d->layoutChanged(true);
-        }
-    }
-    else
-    {
-        d->modelCategorized = false;
-    }
-}
-
-QRect KCategorizedView::visualRect(const QModelIndex &index) const
-{
-    if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel ||
-        !d->categoryDrawer || !d->proxyModel->isCategorizedModel())
-    {
-        return QListView::visualRect(index);
-    }
-
-    if (!qobject_cast<const QSortFilterProxyModel*>(index.model()))
-    {
-        return d->visualRect(d->proxyModel->mapFromSource(index));
-    }
-
-    return d->visualRect(index);
-}
-
-KCategoryDrawer *KCategorizedView::categoryDrawer() const
-{
-    return d->categoryDrawer;
-}
-
-void KCategorizedView::setCategoryDrawer(KCategoryDrawer *categoryDrawer)
-{
-    d->lastSelection = QItemSelection();
-    d->forcedSelectionPosition = 0;
-    d->elementsInfo.clear();
-    d->elementsPosition.clear();
-    d->categoriesIndexes.clear();
-    d->categoriesPosition.clear();
-    d->categories.clear();
-    d->intersectedIndexes.clear();
-    d->modelIndexList.clear();
-    d->hovered = QModelIndex();
-    d->mouseButtonPressed = false;
-    d->rightMouseButtonPressed = false;
-
-    if (!categoryDrawer && d->proxyModel)
-    {
-        QObject::disconnect(d->proxyModel,
-                            SIGNAL(layoutChanged()),
-                            this, SLOT(slotLayoutChanged()));
-
-        QObject::disconnect(d->proxyModel,
-                            SIGNAL(dataChanged(QModelIndex,QModelIndex)),
-                            this, SLOT(slotLayoutChanged()));
-
-        QObject::disconnect(d->proxyModel,
-                            SIGNAL(rowsRemoved(QModelIndex,int,int)),
-                            this, SLOT(rowsRemoved(QModelIndex,int,int)));
-    }
-    else if (categoryDrawer && d->proxyModel)
-    {
-        QObject::connect(d->proxyModel,
-                         SIGNAL(layoutChanged()),
-                         this, SLOT(slotLayoutChanged()));
-
-        QObject::connect(d->proxyModel,
-                         SIGNAL(dataChanged(QModelIndex,QModelIndex)),
-                         this, SLOT(slotLayoutChanged()));
-
-        QObject::connect(d->proxyModel,
-                         SIGNAL(rowsRemoved(QModelIndex,int,int)),
-                         this, SLOT(rowsRemoved(QModelIndex,int,int)));
-    }
-
-    d->categoryDrawer = categoryDrawer;
-
-    if (categoryDrawer)
-    {
-        if (d->proxyModel)
-        {
-            if (d->proxyModel->rowCount())
-            {
-                d->layoutChanged(true);
-            }
-        }
-    }
-    else
-    {
-        updateGeometries();
-    }
-}
-
-QModelIndex KCategorizedView::indexAt(const QPoint &point) const
-{
-    if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel ||
-        !d->categoryDrawer || !d->proxyModel->isCategorizedModel())
-    {
-        return QListView::indexAt(point);
-    }
-
-    QModelIndex index;
-
-    QModelIndexList item = d->intersectionSet(QRect(point, point));
-
-    if (item.count() == 1)
-    {
-        index = item[0];
-    }
-
-    return index;
-}
-
-void KCategorizedView::reset()
-{
-    QListView::reset();
-
-    d->lastSelection = QItemSelection();
-    d->forcedSelectionPosition = 0;
-    d->elementsInfo.clear();
-    d->elementsPosition.clear();
-    d->categoriesIndexes.clear();
-    d->categoriesPosition.clear();
-    d->categories.clear();
-    d->intersectedIndexes.clear();
-    d->modelIndexList.clear();
-    d->hovered = QModelIndex();
-    d->biggestItemSize = QSize(0, 0);
-    d->mouseButtonPressed = false;
-    d->rightMouseButtonPressed = false;
-}
-
-void KCategorizedView::paintEvent(QPaintEvent *event)
-{
-    if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel ||
-        !d->categoryDrawer || !d->proxyModel->isCategorizedModel())
-    {
-        QListView::paintEvent(event);
-        return;
-    }
-
-    QStyleOptionViewItemV3 option = viewOptions();
-    option.widget = this;
-    if (wordWrap())
-    {
-        option.features |= QStyleOptionViewItemV2::WrapText;
-    }
-
-    QPainter painter(viewport());
-    QRect area = event->rect();
-    const bool focus = (hasFocus() || viewport()->hasFocus()) &&
-                        currentIndex().isValid();
-    const QStyle::State state = option.state;
-    const bool enabled = (state & QStyle::State_Enabled) != 0;
-
-    painter.save();
-
-    QModelIndexList dirtyIndexes = d->intersectionSet(area);
-    foreach (const QModelIndex &index, dirtyIndexes)
-    {
-        option.state = state;
-        option.rect = visualRect(index);
-
-        if (selectionModel() && selectionModel()->isSelected(index))
-        {
-            option.state |= QStyle::State_Selected;
-        }
-
-        if (enabled)
-        {
-            QPalette::ColorGroup cg;
-            if ((d->proxyModel->flags(index) & Qt::ItemIsEnabled) == 0)
-            {
-                option.state &= ~QStyle::State_Enabled;
-                cg = QPalette::Disabled;
-            }
-            else
-            {
-                cg = QPalette::Normal;
-            }
-            option.palette.setCurrentColorGroup(cg);
-        }
-
-        if (focus && currentIndex() == index)
-        {
-            option.state |= QStyle::State_HasFocus;
-            if (this->state() == EditingState)
-                option.state |= QStyle::State_Editing;
-        }
-
-        // we are only interested to give the mouse over feedback when no
-        // dragging is happening (ereslibre)
-        if ((index == d->hovered) && !d->mouseButtonPressed &&
-            (this->state() == QAbstractItemView::NoState))
-            option.state |= QStyle::State_MouseOver;
-        else
-            option.state &= ~QStyle::State_MouseOver;
-
-        itemDelegate(index)->paint(&painter, option, index);
-    }
-
-    // Redraw categories
-    QStyleOptionViewItem otherOption;
-    bool intersectedInThePast = false;
-    foreach (const QString &category, d->categories)
-    {
-        otherOption = option;
-        otherOption.rect = d->categoryVisualRect(category);
-        otherOption.state &= ~QStyle::State_MouseOver;
-
-        if (otherOption.rect.intersects(area))
-        {
-            intersectedInThePast = true;
-
-            QModelIndex indexToDraw = d->proxyModel->index(d->categoriesIndexes[category][0].row(), d->proxyModel->sortColumn());
-
-            d->drawNewCategory(indexToDraw,
-                               d->proxyModel->sortRole(), otherOption, &painter);
-        }
-        else if (intersectedInThePast)
-        {
-            break; // the visible area has been finished, we don't need to keep asking, the rest won't intersect
-                // this is doable because we know that categories are correctly ordered on the list
-        }
-    }
-
-    if ((selectionMode() != SingleSelection) && (selectionMode() != NoSelection))
-    {
-        if (d->mouseButtonPressed && !d->isDragging)
-        {
-            QPoint start, end, initialPressPosition;
-
-            initialPressPosition = d->initialPressPosition;
-
-            initialPressPosition.setY(initialPressPosition.y() - verticalOffset());
-            initialPressPosition.setX(initialPressPosition.x() - horizontalOffset());
-
-            if (d->initialPressPosition.x() > d->mousePosition.x() ||
-                d->initialPressPosition.y() > d->mousePosition.y())
-            {
-                start = d->mousePosition;
-                end = initialPressPosition;
-            }
-            else
-            {
-                start = initialPressPosition;
-                end = d->mousePosition;
-            }
-
-            QStyleOptionRubberBand yetAnotherOption;
-            yetAnotherOption.initFrom(this);
-            yetAnotherOption.shape = QRubberBand::Rectangle;
-            yetAnotherOption.opaque = false;
-            yetAnotherOption.rect = QRect(start, end).intersected(viewport()->rect().adjusted(-16, -16, 16, 16));
-            painter.save();
-            style()->drawControl(QStyle::CE_RubberBand, &yetAnotherOption, &painter);
-            painter.restore();
-        }
-    }
-
-    if (d->isDragging && !d->dragLeftViewport)
-    {
-        painter.setOpacity(0.5);
-        d->drawDraggedItems(&painter);
-    }
-
-    painter.restore();
-}
-
-void KCategorizedView::resizeEvent(QResizeEvent *event)
-{
-    QListView::resizeEvent(event);
-
-    // Clear the items positions cache
-    d->elementsPosition.clear();
-    d->categoriesPosition.clear();
-    d->forcedSelectionPosition = 0;
-
-    if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel ||
-        !d->categoryDrawer || !d->proxyModel->isCategorizedModel())
-    {
-        return;
-    }
-
-    d->updateScrollbars();
-}
-
-void KCategorizedView::setSelection(const QRect &rect,
-                                    QItemSelectionModel::SelectionFlags flags)
-{
-    if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel ||
-        !d->categoryDrawer || !d->proxyModel->isCategorizedModel())
-    {
-        QListView::setSelection(rect, flags);
-        return;
-    }
-
-    if (!flags)
-        return;
-
-    if (flags & QItemSelectionModel::Clear)
-    {
-        selectionModel()->clear();
-        d->lastSelection.clear();
-    }
-
-    QModelIndexList dirtyIndexes = d->intersectionSet(rect);
-
-    // no items affected, just leave
-    if (!dirtyIndexes.count())
-    {
-        selectionModel()->select(d->lastSelection, QItemSelectionModel::SelectCurrent);
-
-        return;
-    }
-
-    QModelIndex topLeft;
-    QModelIndex bottomRight;
-
-    if (d->mouseButtonPressed || d->rightMouseButtonPressed) // selection with click + drag
-    {
-        QItemSelection selection;
-
-        QModelIndex prev = dirtyIndexes[0];
-        QModelIndex first = prev;
-        foreach (const QModelIndex &index, dirtyIndexes)
-        {
-            // we have a different interval. non-contiguous items
-            if ((index.row() - prev.row()) > 1) {
-                selection << QItemSelectionRange(first, prev);
-
-                first = index;
-            }
-
-            prev = index;
-        }
-
-        selection << QItemSelectionRange(first, prev);
-
-        if (flags & QItemSelectionModel::Current)
-        {
-            if (rect.topLeft() == rect.bottomRight())
-            {
-                selectionModel()->setCurrentIndex(indexAt(rect.topLeft()), QItemSelectionModel::NoUpdate);
-            }
-
-            selection.merge(d->lastSelection, flags);
-        }
-        else
-        {
-            selection.merge(selectionModel()->selection(), flags);
-
-            selectionModel()->select(selection, QItemSelectionModel::SelectCurrent);
-
-            return;
-        }
-
-        selectionModel()->select(selection, flags);
-    }
-    else // selection with click + keyboard keys
-    {
-        QModelIndex topLeftIndex = indexAt(QPoint(rect.topLeft().x(),
-                                                  rect.topLeft().y()));
-        QModelIndex bottomRightIndex = indexAt(QPoint(rect.bottomRight().x(),
-                                                      rect.bottomRight().y()));
-
-        // keyboard selection comes "upside down". Let's normalize it
-        if (topLeftIndex.row() > bottomRightIndex.row())
-        {
-            QModelIndex auxIndex = topLeftIndex;
-            topLeftIndex = bottomRightIndex;
-            bottomRightIndex = auxIndex;
-        }
-
-        int viewportWidth = viewport()->width() - spacing();
-        int itemWidth;
-
-        if (gridSize().isEmpty())
-        {
-            itemWidth = d->biggestItemSize.width();
-        }
-        else
-        {
-            itemWidth = gridSize().width();
-        }
-
-        int itemWidthPlusSeparation = spacing() + itemWidth;
-        int elementsPerRow = viewportWidth / itemWidthPlusSeparation;
-        if (!elementsPerRow)
-            elementsPerRow++;
-
-        QModelIndexList theoricDirty(dirtyIndexes);
-        dirtyIndexes.clear();
-        int first = model()->rowCount();
-        int last = 0;
-
-        foreach (const QModelIndex &index, theoricDirty)
-        {
-            if ((index.row() < first) &&
-                ((((topLeftIndex.row() / elementsPerRow) == (index.row() / elementsPerRow)) &&
-                  ((topLeftIndex.row() % elementsPerRow) <= (index.row() % elementsPerRow))) ||
-                 (topLeftIndex.row() / elementsPerRow) != (index.row() / elementsPerRow)))
-            {
-                first = index.row();
-                topLeft = index;
-            }
-
-            if ((index.row() > last) &&
-                ((((bottomRightIndex.row() / elementsPerRow) == (index.row() / elementsPerRow)) &&
-                  ((bottomRightIndex.row() % elementsPerRow) >= (index.row() % elementsPerRow))) ||
-                 (bottomRightIndex.row() / elementsPerRow) != (index.row() / elementsPerRow)))
-            {
-                last = index.row();
-                bottomRight = index;
-            }
-        }
-
-        for (int i = first; i <= last; i++)
-        {
-            dirtyIndexes << model()->index(i, theoricDirty[0].column(), theoricDirty[0].parent());
-        }
-
-        QItemSelection selection(topLeft, bottomRight);
-
-        selectionModel()->select(selection, flags);
-    }
-}
-
-void KCategorizedView::mouseMoveEvent(QMouseEvent *event)
-{
-    QListView::mouseMoveEvent(event);
-
-    if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel ||
-        !d->categoryDrawer || !d->proxyModel->isCategorizedModel())
-    {
-        return;
-    }
-
-    QModelIndexList item = d->intersectionSet(QRect(event->pos(), event->pos()));
-
-    if (item.count() == 1)
-    {
-        d->hovered = item[0];
-    }
-    else
-    {
-        d->hovered = QModelIndex();
-    }
-
-    const QString previousHoveredCategory = d->hoveredCategory;
-
-    d->mousePosition = event->pos();
-    d->hoveredCategory = QString();
-
-    // Redraw categories
-    foreach (const QString &category, d->categories)
-    {
-        if (d->categoryVisualRect(category).intersects(QRect(event->pos(), event->pos())))
-        {
-            d->hoveredCategory = category;
-            viewport()->update(d->categoryVisualRect(category));
-        }
-        else if ((category == previousHoveredCategory) &&
-                 (!d->categoryVisualRect(previousHoveredCategory).intersects(QRect(event->pos(), event->pos()))))
-        {
-            viewport()->update(d->categoryVisualRect(category));
-        }
-    }
-
-    QRect rect;
-    if (d->mouseButtonPressed && !d->isDragging)
-    {
-        QPoint start, end, initialPressPosition;
-
-        initialPressPosition = d->initialPressPosition;
-
-        initialPressPosition.setY(initialPressPosition.y() - verticalOffset());
-        initialPressPosition.setX(initialPressPosition.x() - horizontalOffset());
-
-        if (d->initialPressPosition.x() > d->mousePosition.x() ||
-            d->initialPressPosition.y() > d->mousePosition.y())
-        {
-            start = d->mousePosition;
-            end = initialPressPosition;
-        }
-        else
-        {
-            start = initialPressPosition;
-            end = d->mousePosition;
-        }
-
-        rect = QRect(start, end).adjusted(-16, -16, 16, 16);
-        rect = rect.united(QRect(start, end).adjusted(16, 16, -16, -16)).intersected(viewport()->rect());
-
-        viewport()->update(rect);
-    }
-}
-
-void KCategorizedView::mousePressEvent(QMouseEvent *event)
-{
-    d->dragLeftViewport = false;
-
-    if (event->button() == Qt::LeftButton)
-    {
-        d->mouseButtonPressed = true;
-
-        d->initialPressPosition = event->pos();
-        d->initialPressPosition.setY(d->initialPressPosition.y() +
-                                                              verticalOffset());
-        d->initialPressPosition.setX(d->initialPressPosition.x() +
-                                                            horizontalOffset());
-    }
-    else if (event->button() == Qt::RightButton)
-    {
-        d->rightMouseButtonPressed = true;
-    }
-
-    QListView::mousePressEvent(event);
-
-    d->lastSelection = selectionModel()->selection();
-
-    viewport()->update(d->categoryVisualRect(d->hoveredCategory));
-}
-
-void KCategorizedView::mouseReleaseEvent(QMouseEvent *event)
-{
-    d->mouseButtonPressed = false;
-    d->rightMouseButtonPressed = false;
-
-    QListView::mouseReleaseEvent(event);
-
-    if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel ||
-        !d->categoryDrawer || !d->proxyModel->isCategorizedModel())
-    {
-        return;
-    }
-
-    QPoint initialPressPosition = viewport()->mapFromGlobal(QCursor::pos());
-    initialPressPosition.setY(initialPressPosition.y() + verticalOffset());
-    initialPressPosition.setX(initialPressPosition.x() + horizontalOffset());
-
-    if ((selectionMode() != SingleSelection) && (selectionMode() != NoSelection) &&
-        (initialPressPosition == d->initialPressPosition))
-    {
-        foreach(const QString &category, d->categories)
-        {
-            if (d->categoryVisualRect(category).contains(event->pos()))
-            {
-                QItemSelection selection = selectionModel()->selection();
-                QModelIndexList indexList = d->categoriesIndexes[category];
-
-                foreach (const QModelIndex &index, indexList)
-                {
-                    QModelIndex selectIndex = index.model()->index(index.row(), 0);
-
-                    selection << QItemSelectionRange(selectIndex);
-                }
-
-                selectionModel()->select(selection, QItemSelectionModel::SelectCurrent);
-
-                break;
-            }
-        }
-    }
-
-    QRect rect;
-    if (!d->isDragging)
-    {
-        QPoint start, end, initialPressPosition;
-
-        initialPressPosition = d->initialPressPosition;
-
-        initialPressPosition.setY(initialPressPosition.y() - verticalOffset());
-        initialPressPosition.setX(initialPressPosition.x() - horizontalOffset());
-
-        if (d->initialPressPosition.x() > d->mousePosition.x() ||
-            d->initialPressPosition.y() > d->mousePosition.y())
-        {
-            start = d->mousePosition;
-            end = initialPressPosition;
-        }
-        else
-        {
-            start = initialPressPosition;
-            end = d->mousePosition;
-        }
-
-        rect = QRect(start, end).adjusted(-16, -16, 16, 16);
-        rect = rect.united(QRect(start, end).adjusted(16, 16, -16, -16)).intersected(viewport()->rect());
-
-        viewport()->update(rect);
-    }
-
-    if (d->hovered.isValid())
-        viewport()->update(visualRect(d->hovered));
-    else if (!d->hoveredCategory.isEmpty())
-        viewport()->update(d->categoryVisualRect(d->hoveredCategory));
-}
-
-void KCategorizedView::leaveEvent(QEvent *event)
-{
-    d->hovered = QModelIndex();
-    d->hoveredCategory = QString();
-
-    QListView::leaveEvent(event);
-}
-
-void KCategorizedView::startDrag(Qt::DropActions supportedActions)
-{
-    // FIXME: QAbstractItemView does far better here since it sets the
-    //        pixmap of selected icons to the dragging cursor, but it sets a non
-    //        ARGB window so it is no transparent. Use QAbstractItemView when
-    //        this is fixed on Qt.
-    // QAbstractItemView::startDrag(supportedActions);
-#if !defined(DOLPHIN_DRAGANDDROP)
-    QListView::startDrag(supportedActions);
-#endif
-
-    d->isDragging = false;
-    d->mouseButtonPressed = false;
-    d->rightMouseButtonPressed = false;
-
-    viewport()->update(d->lastDraggedItemsRect);
-}
-
-void KCategorizedView::dragMoveEvent(QDragMoveEvent *event)
-{
-    d->mousePosition = event->pos();
-
-    if (d->mouseButtonPressed)
-    {
-        d->isDragging = true;
-    }
-    else
-    {
-        d->isDragging = false;
-    }
-
-    d->dragLeftViewport = false;
-
-#if defined(DOLPHIN_DRAGANDDROP)
-    QAbstractItemView::dragMoveEvent(event);
-#else
-    QListView::dragMoveEvent(event);
-#endif
-
-    if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel ||
-        !d->categoryDrawer || !d->proxyModel->isCategorizedModel())
-    {
-        return;
-    }
-
-    d->drawDraggedItems();
-}
-
-void KCategorizedView::dragLeaveEvent(QDragLeaveEvent *event)
-{
-    d->dragLeftViewport = true;
-
-#if defined(DOLPHIN_DRAGANDDROP)
-    QAbstractItemView::dragLeaveEvent(event);
-#else
-    QListView::dragLeaveEvent(event);
-#endif
-}
-
-void KCategorizedView::dropEvent(QDropEvent *event)
-{
-#if defined(DOLPHIN_DRAGANDDROP)
-    QAbstractItemView::dropEvent(event);
-#else
-    QListView::dropEvent(event);
-#endif
-}
-
-QModelIndex KCategorizedView::moveCursor(CursorAction cursorAction,
-                                         Qt::KeyboardModifiers modifiers)
-{
-    if ((viewMode() != KCategorizedView::IconMode) ||
-         !d->proxyModel ||
-         !d->categoryDrawer ||
-          d->categories.isEmpty() ||
-         !d->proxyModel->isCategorizedModel()
-       )
-    {
-        return QListView::moveCursor(cursorAction, modifiers);
-    }
-
-    int viewportWidth = viewport()->width() - spacing();
-    int itemWidth;
-
-    if (gridSize().isEmpty())
-    {
-        itemWidth = d->biggestItemSize.width();
-    }
-    else
-    {
-        itemWidth = gridSize().width();
-    }
-
-    int itemWidthPlusSeparation = spacing() + itemWidth;
-    int elementsPerRow = viewportWidth / itemWidthPlusSeparation;
-    if (!elementsPerRow)
-        elementsPerRow++;
-
-    QModelIndex current = selectionModel()->currentIndex();
-
-    if (!current.isValid())
-    {
-        if (cursorAction == MoveEnd)
-        {
-            current = model()->index(model()->rowCount() - 1, 0, QModelIndex());
-            d->forcedSelectionPosition = d->elementsInfo[current.row()].relativeOffsetToCategory % elementsPerRow;
-        }
-        else
-        {
-            current = model()->index(0, 0, QModelIndex());
-            d->forcedSelectionPosition = 0;
-        }
-
-        return current;
-    }
-    else if (!current.isValid())
-    {
-        return QModelIndex();
-    }
-
-    QString lastCategory = d->categories.first();
-    QString theCategory = d->categories.first();
-    QString afterCategory = d->categories.first();
-
-    bool hasToBreak = false;
-    foreach (const QString &category, d->categories)
-    {
-        if (hasToBreak)
-        {
-            afterCategory = category;
-
-            break;
-        }
-
-        if (category == d->elementsInfo[current.row()].category)
-        {
-            theCategory = category;
-
-            hasToBreak = true;
-        }
-
-        if (!hasToBreak)
-        {
-            lastCategory = category;
-        }
-    }
-
-    switch (cursorAction)
-    {
-        case QAbstractItemView::MoveUp: {
-            if (d->elementsInfo[current.row()].relativeOffsetToCategory >= elementsPerRow)
-            {
-                int indexToMove = current.row();
-                indexToMove -= qMin(((d->elementsInfo[current.row()].relativeOffsetToCategory) + d->forcedSelectionPosition), elementsPerRow - d->forcedSelectionPosition + (d->elementsInfo[current.row()].relativeOffsetToCategory % elementsPerRow));
-
-                return d->proxyModel->index(indexToMove, 0);
-            }
-            else
-            {
-                int lastCategoryLastRow = (d->categoriesIndexes[lastCategory].count() - 1) % elementsPerRow;
-                int indexToMove = current.row() - d->elementsInfo[current.row()].relativeOffsetToCategory;
-
-                if (d->forcedSelectionPosition >= lastCategoryLastRow)
-                {
-                    indexToMove -= 1;
-                }
-                else
-                {
-                    indexToMove -= qMin((lastCategoryLastRow - d->forcedSelectionPosition + 1), d->forcedSelectionPosition + elementsPerRow + 1);
-                }
-
-                return d->proxyModel->index(indexToMove, 0);
-            }
-        }
-
-        case QAbstractItemView::MoveDown: {
-            if (d->elementsInfo[current.row()].relativeOffsetToCategory < (d->categoriesIndexes[theCategory].count() - 1 - ((d->categoriesIndexes[theCategory].count() - 1) % elementsPerRow)))
-            {
-                int indexToMove = current.row();
-                indexToMove += qMin(elementsPerRow, d->categoriesIndexes[theCategory].count() - 1 - d->elementsInfo[current.row()].relativeOffsetToCategory);
-
-                return d->proxyModel->index(indexToMove, 0);
-            }
-            else
-            {
-                int afterCategoryLastRow = qMin(elementsPerRow, d->categoriesIndexes[afterCategory].count());
-                int indexToMove = current.row() + (d->categoriesIndexes[theCategory].count() - d->elementsInfo[current.row()].relativeOffsetToCategory);
-
-                if (d->forcedSelectionPosition >= afterCategoryLastRow)
-                {
-                    indexToMove += afterCategoryLastRow - 1;
-                }
-                else
-                {
-                    indexToMove += qMin(d->forcedSelectionPosition, elementsPerRow);
-                }
-
-                return d->proxyModel->index(indexToMove, 0);
-            }
-        }
-
-        case QAbstractItemView::MoveLeft:
-            if (layoutDirection() == Qt::RightToLeft)
-            {
-                if (!(d->elementsInfo[current.row() + 1].relativeOffsetToCategory % elementsPerRow))
-                    return current;
-
-                d->forcedSelectionPosition = d->elementsInfo[current.row() + 1].relativeOffsetToCategory % elementsPerRow;
-
-#if 0 //follow qt view behavior. lateral movements won't change visual row
-                if (d->forcedSelectionPosition < 0)
-                    d->forcedSelectionPosition = (d->categoriesIndexes[theCategory].count() - 1) % elementsPerRow;
-#endif
-
-                return d->proxyModel->index(current.row() + 1, 0);
-            }
-
-            if (!(d->elementsInfo[current.row()].relativeOffsetToCategory % elementsPerRow))
-                return current;
-
-            d->forcedSelectionPosition = d->elementsInfo[current.row() - 1].relativeOffsetToCategory % elementsPerRow;
-
-#if 0 //follow qt view behavior. lateral movements won't change visual row
-            if (d->forcedSelectionPosition < 0)
-                d->forcedSelectionPosition = (d->categoriesIndexes[theCategory].count() - 1) % elementsPerRow;
-#endif
-
-            return d->proxyModel->index(current.row() - 1, 0);
-
-        case QAbstractItemView::MoveRight:
-            if (layoutDirection() == Qt::RightToLeft)
-            {
-                if (!(d->elementsInfo[current.row()].relativeOffsetToCategory % elementsPerRow))
-                    return current;
-
-                d->forcedSelectionPosition = d->elementsInfo[current.row() - 1].relativeOffsetToCategory % elementsPerRow;
-
-#if 0 //follow qt view behavior. lateral movements won't change visual row
-                if (d->forcedSelectionPosition < 0)
-                    d->forcedSelectionPosition = (d->categoriesIndexes[theCategory].count() - 1) % elementsPerRow;
-#endif
-
-                return d->proxyModel->index(current.row() - 1, 0);
-            }
-
-            if (!(d->elementsInfo[current.row() + 1].relativeOffsetToCategory % elementsPerRow))
-                return current;
-
-            d->forcedSelectionPosition = d->elementsInfo[current.row() + 1].relativeOffsetToCategory % elementsPerRow;
-
-#if 0 //follow qt view behavior. lateral movements won't change visual row
-            if (d->forcedSelectionPosition < 0)
-                d->forcedSelectionPosition = (d->categoriesIndexes[theCategory].count() - 1) % elementsPerRow;
-#endif
-
-            return d->proxyModel->index(current.row() + 1, 0);
-
-        default:
-            break;
-    }
-
-    return QListView::moveCursor(cursorAction, modifiers);
-}
-
-void KCategorizedView::rowsInserted(const QModelIndex &parent,
-                                    int start,
-                                    int end)
-{
-    QListView::rowsInserted(parent, start, end);
-
-    if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel ||
-        !d->categoryDrawer || !d->proxyModel->isCategorizedModel())
-    {
-        d->forcedSelectionPosition = 0;
-        d->elementsInfo.clear();
-        d->elementsPosition.clear();
-        d->categoriesIndexes.clear();
-        d->categoriesPosition.clear();
-        d->categories.clear();
-        d->intersectedIndexes.clear();
-        d->modelIndexList.clear();
-        d->hovered = QModelIndex();
-        d->biggestItemSize = QSize(0, 0);
-        d->mouseButtonPressed = false;
-        d->rightMouseButtonPressed = false;
-
-        return;
-    }
-
-    rowsInsertedArtifficial(parent, start, end);
-}
-
-void KCategorizedView::rowsInsertedArtifficial(const QModelIndex &parent,
-                                               int start,
-                                               int end)
-{
-    Q_UNUSED(parent);
-
-    d->forcedSelectionPosition = 0;
-    d->elementsInfo.clear();
-    d->elementsPosition.clear();
-    d->categoriesIndexes.clear();
-    d->categoriesPosition.clear();
-    d->categories.clear();
-    d->intersectedIndexes.clear();
-    d->modelIndexList.clear();
-    d->hovered = QModelIndex();
-    d->biggestItemSize = QSize(0, 0);
-    d->mouseButtonPressed = false;
-    d->rightMouseButtonPressed = false;
-
-    if (start > end || end < 0 || start < 0 || !d->proxyModel->rowCount())
-    {
-        return;
-    }
-
-    // Add all elements mapped to the source model and explore categories
-    QString prevCategory = d->proxyModel->data(d->proxyModel->index(0, d->proxyModel->sortColumn()), KCategorizedSortFilterProxyModel::CategoryDisplayRole).toString();
-    QString lastCategory = prevCategory;
-    QModelIndexList modelIndexList;
-    struct Private::ElementInfo elementInfo;
-    int offset = -1;
-    for (int k = 0; k < d->proxyModel->rowCount(); ++k)
-    {
-        QModelIndex index = d->proxyModel->index(k, d->proxyModel->sortColumn());
-        QModelIndex indexSize = d->proxyModel->index(k, 0);
-
-        d->biggestItemSize = QSize(qMax(sizeHintForIndex(indexSize).width(),
-                                        d->biggestItemSize.width()),
-                                   qMax(sizeHintForIndex(indexSize).height(),
-                                        d->biggestItemSize.height()));
-
-        d->modelIndexList << index;
-
-        lastCategory = d->proxyModel->data(index, KCategorizedSortFilterProxyModel::CategoryDisplayRole).toString();
-
-        elementInfo.category = lastCategory;
-
-        if (prevCategory != lastCategory)
-        {
-            offset = 0;
-            d->categoriesIndexes.insert(prevCategory, modelIndexList);
-            d->categories << prevCategory;
-            modelIndexList.clear();
-        }
-        else
-        {
-            offset++;
-        }
-
-        elementInfo.relativeOffsetToCategory = offset;
-
-        modelIndexList << index;
-        prevCategory = lastCategory;
-
-        d->elementsInfo.insert(index.row(), elementInfo);
-    }
-
-    d->categoriesIndexes.insert(prevCategory, modelIndexList);
-    d->categories << prevCategory;
-
-    d->updateScrollbars();
-
-    // FIXME: We need to safely save the last selection. This is on my TODO
-    // list (ereslibre).
-    selectionModel()->clear();
-}
-
-void KCategorizedView::rowsRemoved(const QModelIndex &parent,
-                                   int start,
-                                   int end)
-{
-    if ((viewMode() == KCategorizedView::IconMode) && d->proxyModel &&
-        d->categoryDrawer && d->proxyModel->isCategorizedModel())
-    {
-        // Force the view to update all elements
-        rowsInsertedArtifficial(QModelIndex(), 0, d->proxyModel->rowCount() - 1);
-    }
-}
-
-void KCategorizedView::updateGeometries()
-{
-    if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel ||
-        !d->categoryDrawer || !d->proxyModel->isCategorizedModel())
-    {
-        QListView::updateGeometries();
-        return;
-    }
-
-    // Avoid QListView::updateGeometries(), since it will try to set another
-    // range to our scroll bars, what we don't want (ereslibre)
-    QAbstractItemView::updateGeometries();
-}
-
-void KCategorizedView::slotLayoutChanged()
-{
-    d->layoutChanged();
-}
-
-void KCategorizedView::currentChanged(const QModelIndex &current,
-                                      const QModelIndex &previous)
-{
-    // We need to update the forcedSelectionPosition property in order to correctly
-    // navigate after with keyboard using up & down keys
-
-    int viewportWidth = viewport()->width() - spacing();
-
-    int itemHeight;
-    int itemWidth;
-
-    if (gridSize().isEmpty())
-    {
-        itemHeight = d->biggestItemSize.height();
-        itemWidth = d->biggestItemSize.width();
-    }
-    else
-    {
-        itemHeight = gridSize().height();
-        itemWidth = gridSize().width();
-    }
-
-    int itemWidthPlusSeparation = spacing() + itemWidth;
-    int elementsPerRow = viewportWidth / itemWidthPlusSeparation;
-    if (!elementsPerRow)
-        elementsPerRow++;
-
-    if (d->mouseButtonPressed || d->rightMouseButtonPressed)
-        d->forcedSelectionPosition = d->elementsInfo[current.row()].relativeOffsetToCategory % elementsPerRow;
-
-    QListView::currentChanged(current, previous);
-}
-
-#include "kcategorizedview.moc"
diff --git a/src/kcategorizedview.h b/src/kcategorizedview.h
deleted file mode 100644 (file)
index 015433a..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/**
-  * This file is part of the KDE project
-  * Copyright (C) 2007 Rafael Fernández López <ereslibre@kde.org>
-  *
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Library General Public
-  * License as published by the Free Software Foundation; either
-  * version 2 of the License, or (at your option) any later version.
-  *
-  * This library is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  * Library General Public License for more details.
-  *
-  * You should have received a copy of the GNU Library General Public License
-  * along with this library; see the file COPYING.LIB.  If not, write to
-  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-  * Boston, MA 02110-1301, USA.
-  */
-
-#ifndef KCATEGORIZEDVIEW_H
-#define KCATEGORIZEDVIEW_H
-
-#include <QtGui/QListView>
-
-#include <libdolphin_export.h>
-
-class KCategoryDrawer;
-
-/**
-  * @short Item view for listing items
-  *
-  * KCategorizedView allows you to use it as it were a QListView. You can add an
-  * itemCategorizer to it, so your items became categorized depending on the
-  * KItemCategorizer inherited class rules.
-  *
-  * @see KItemCategorizer, KSortFilterProxyModel
-  *
-  * @author Rafael Fernández López <ereslibre@kde.org>
-  */
-class LIBDOLPHINPRIVATE_EXPORT KCategorizedView
-    : public QListView
-{
-    Q_OBJECT
-
-public:
-    KCategorizedView(QWidget *parent = 0);
-
-    ~KCategorizedView();
-
-    virtual void setModel(QAbstractItemModel *model);
-
-    void setGridSize(const QSize &size);
-
-    virtual QRect visualRect(const QModelIndex &index) const;
-
-    KCategoryDrawer *categoryDrawer() const;
-
-    void setCategoryDrawer(KCategoryDrawer *categoryDrawer);
-
-    virtual QModelIndex indexAt(const QPoint &point) const;
-
-public Q_SLOTS:
-    virtual void reset();
-
-protected:
-    virtual void paintEvent(QPaintEvent *event);
-
-    virtual void resizeEvent(QResizeEvent *event);
-
-    virtual void setSelection(const QRect &rect,
-                              QItemSelectionModel::SelectionFlags flags);
-
-    virtual void mouseMoveEvent(QMouseEvent *event);
-
-    virtual void mousePressEvent(QMouseEvent *event);
-
-    virtual void mouseReleaseEvent(QMouseEvent *event);
-
-    virtual void leaveEvent(QEvent *event);
-
-    virtual void startDrag(Qt::DropActions supportedActions);
-
-    virtual void dragMoveEvent(QDragMoveEvent *event);
-
-    virtual void dragLeaveEvent(QDragLeaveEvent *event);
-
-    virtual void dropEvent(QDropEvent *event);
-
-    virtual QModelIndex moveCursor(CursorAction cursorAction,
-                                   Qt::KeyboardModifiers modifiers);
-
-protected Q_SLOTS:
-    virtual void rowsInserted(const QModelIndex &parent,
-                              int start,
-                              int end);
-
-    virtual void rowsInsertedArtifficial(const QModelIndex &parent,
-                                         int start,
-                                         int end);
-
-    virtual void rowsRemoved(const QModelIndex &parent,
-                             int start,
-                             int end);
-
-    virtual void updateGeometries();
-
-    virtual void slotLayoutChanged();
-
-    virtual void currentChanged(const QModelIndex &current,
-                                const QModelIndex &previous);
-
-
-private:
-    class Private;
-    Private *d;
-};
-
-#endif // KCATEGORIZEDVIEW_H
diff --git a/src/kcategorizedview_p.h b/src/kcategorizedview_p.h
deleted file mode 100644 (file)
index a18854b..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-/**
-  * This file is part of the KDE project
-  * Copyright (C) 2007 Rafael Fernández López <ereslibre@kde.org>
-  *
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Library General Public
-  * License as published by the Free Software Foundation; either
-  * version 2 of the License, or (at your option) any later version.
-  *
-  * This library is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  * Library General Public License for more details.
-  *
-  * You should have received a copy of the GNU Library General Public License
-  * along with this library; see the file COPYING.LIB.  If not, write to
-  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-  * Boston, MA 02110-1301, USA.
-  */
-
-#ifndef KCATEGORIZEDVIEW_P_H
-#define KCATEGORIZEDVIEW_P_H
-
-class KCategorizedSortFilterProxyModel;
-class KCategoryDrawer;
-
-/**
-  * @internal
-  */
-class KCategorizedView::Private
-{
-public:
-    Private(KCategorizedView *listView);
-    ~Private();
-
-
-    // Methods
-
-    /**
-      * Returns the list of items that intersects with @p rect
-      */
-    const QModelIndexList &intersectionSet(const QRect &rect);
-
-    /**
-      * Gets the item rect in the viewport for @p index
-      */
-    QRect visualRectInViewport(const QModelIndex &index) const;
-
-    /**
-      * Returns the category rect in the viewport for @p category
-      */
-    QRect visualCategoryRectInViewport(const QString &category) const;
-
-    /**
-      * Caches and returns the rect that corresponds to @p index
-      */
-    const QRect &cacheIndex(const QModelIndex &index);
-
-    /**
-      * Caches and returns the rect that corresponds to @p category
-      */
-    const QRect &cacheCategory(const QString &category);
-
-    /**
-      * Returns the rect that corresponds to @p index
-      * @note If the rect is not cached, it becomes cached
-      */
-    const QRect &cachedRectIndex(const QModelIndex &index);
-
-    /**
-      * Returns the rect that corresponds to @p category
-      * @note If the rect is not cached, it becomes cached
-      */
-    const QRect &cachedRectCategory(const QString &category);
-
-    /**
-      * Returns the visual rect (taking in count x and y offsets) for @p index
-      * @note If the rect is not cached, it becomes cached
-      */
-    QRect visualRect(const QModelIndex &index);
-
-    /**
-      * Returns the visual rect (taking in count x and y offsets) for @p category
-      * @note If the rect is not cached, it becomes cached
-      */
-    QRect categoryVisualRect(const QString &category);
-
-    /**
-      * This method will draw a new category represented by index
-      * @param index  on the rect specified by @p option.rect, with
-      * painter @p painter
-      */
-    void drawNewCategory(const QModelIndex &index,
-                         int sortRole,
-                         const QStyleOption &option,
-                         QPainter *painter);
-
-    /**
-      * This method will update scrollbars ranges. Called when our model changes
-      * or when the view is resized
-      */
-    void updateScrollbars();
-
-    /**
-      * This method will draw dragged items in the painting operation
-      */
-    void drawDraggedItems(QPainter *painter);
-
-    /**
-      * This method will determine which rect needs to be updated because of a
-      * dragging operation
-      */
-    void drawDraggedItems();
-
-    void layoutChanged(bool forceItemReload = false);
-
-
-    // Attributes
-
-    struct ElementInfo
-    {
-        QString category;
-        int relativeOffsetToCategory;
-    };
-
-    // Basic data
-    KCategorizedView *listView;
-    KCategoryDrawer *categoryDrawer;
-    QSize biggestItemSize;
-
-    // Behavior data
-    bool mouseButtonPressed;
-    bool rightMouseButtonPressed;
-    bool isDragging;
-    bool dragLeftViewport;
-    QModelIndex hovered;
-    QString hoveredCategory;
-    QPoint initialPressPosition;
-    QPoint mousePosition;
-    int forcedSelectionPosition;
-
-    // Cache data
-    // We cannot merge some of them into structs because it would affect
-    // performance
-    QHash<int, struct ElementInfo> elementsInfo;
-    QHash<int, QRect> elementsPosition;
-    QHash<QString, QModelIndexList> categoriesIndexes;
-    QHash<QString, QRect> categoriesPosition;
-    QStringList categories;
-    QModelIndexList intersectedIndexes;
-    QRect lastDraggedItemsRect;
-    int modelSortRole;
-    int modelSortColumn;
-    int modelLastRowCount;
-    bool modelCategorized;
-    Qt::SortOrder modelSortOrder;
-    QItemSelection lastSelection;
-
-    // Attributes for speed reasons
-    KCategorizedSortFilterProxyModel *proxyModel;
-    QModelIndexList modelIndexList;
-};
-
-#endif // KCATEGORIZEDVIEW_P_H
diff --git a/src/kcategorydrawer.cpp b/src/kcategorydrawer.cpp
deleted file mode 100644 (file)
index 6d82bf9..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/**
-  * This file is part of the KDE project
-  * Copyright (C) 2007 Rafael Fernández López <ereslibre@kde.org>
-  *
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Library General Public
-  * License as published by the Free Software Foundation; either
-  * version 2 of the License, or (at your option) any later version.
-  *
-  * This library is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  * Library General Public License for more details.
-  *
-  * You should have received a copy of the GNU Library General Public License
-  * along with this library; see the file COPYING.LIB.  If not, write to
-  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-  * Boston, MA 02110-1301, USA.
-  */
-
-#include "kcategorydrawer.h"
-
-#include <QPainter>
-#include <QStyleOption>
-
-#include <kiconloader.h>
-#include <kcategorizedsortfilterproxymodel.h>
-
-KCategoryDrawer::KCategoryDrawer()
-{
-}
-
-KCategoryDrawer::~KCategoryDrawer()
-{
-}
-
-void KCategoryDrawer::drawCategory(const QModelIndex &index,
-                                   int /*sortRole*/,
-                                   const QStyleOption &option,
-                                   QPainter *painter) const
-{
-    const QString category = index.model()->data(index, KCategorizedSortFilterProxyModel::CategoryDisplayRole).toString();
-
-    QColor color;
-
-    if (option.state & QStyle::State_Selected)
-    {
-        color = option.palette.color(QPalette::HighlightedText);
-    }
-    else
-    {
-        color = option.palette.color(QPalette::Text);
-    }
-
-    painter->save();
-    painter->setRenderHint(QPainter::Antialiasing);
-
-    if (option.state & QStyle::State_Selected)
-    {
-        QColor selected = option.palette.color(QPalette::Highlight);
-
-        QLinearGradient gradient(option.rect.topLeft(),
-                                 option.rect.bottomRight());
-        gradient.setColorAt(option.direction == Qt::LeftToRight ? 0
-                                                                : 1, selected);
-        gradient.setColorAt(option.direction == Qt::LeftToRight ? 1
-                                                                : 0, Qt::transparent);
-
-        painter->fillRect(option.rect, gradient);
-    }
-    else if (option.state & QStyle::State_MouseOver)
-    {
-        QColor hover = option.palette.color(QPalette::Highlight).light();
-        hover.setAlpha(88);
-
-        QLinearGradient gradient(option.rect.topLeft(),
-                                 option.rect.bottomRight());
-        gradient.setColorAt(option.direction == Qt::LeftToRight ? 0
-                                                                : 1, hover);
-        gradient.setColorAt(option.direction == Qt::LeftToRight ? 1
-                                                                : 0, Qt::transparent);
-
-        painter->fillRect(option.rect, gradient);
-    }
-
-    QFont painterFont = painter->font();
-    painterFont.setWeight(QFont::Bold);
-    QFontMetrics metrics(painterFont);
-    painter->setFont(painterFont);
-
-    QRect lineRect(option.rect.left(),
-                   option.rect.bottom() - 1,
-                   option.rect.width(),
-                   1);
-
-    QLinearGradient gradient(option.rect.topLeft(),
-                             option.rect.bottomRight());
-    gradient.setColorAt(option.direction == Qt::LeftToRight ? 0
-                                                            : 1, color);
-    gradient.setColorAt(option.direction == Qt::LeftToRight ? 1
-                                                            : 0, Qt::transparent);
-
-    painter->fillRect(lineRect, gradient);
-
-    painter->setPen(color);
-
-    painter->drawText(option.rect, Qt::AlignVCenter | Qt::AlignLeft,
-    metrics.elidedText(category, Qt::ElideRight, option.rect.width()));
-
-    painter->restore();
-}
-
-int KCategoryDrawer::categoryHeight(const QModelIndex &index, const QStyleOption &option) const
-{
-    Q_UNUSED(index);
-
-    return option.fontMetrics.height() + 4 /* 3 separator; 1 gradient */;
-}
diff --git a/src/kcategorydrawer.h b/src/kcategorydrawer.h
deleted file mode 100644 (file)
index 6af0d73..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
-  * This file is part of the KDE project
-  * Copyright (C) 2007 Rafael Fernández López <ereslibre@kde.org>
-  *
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Library General Public
-  * License as published by the Free Software Foundation; either
-  * version 2 of the License, or (at your option) any later version.
-  *
-  * This library is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  * Library General Public License for more details.
-  *
-  * You should have received a copy of the GNU Library General Public License
-  * along with this library; see the file COPYING.LIB.  If not, write to
-  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-  * Boston, MA 02110-1301, USA.
-  */
-
-#ifndef KCATEGORYDRAWER_H
-#define KCATEGORYDRAWER_H
-
-#include <libdolphin_export.h>
-
-class QPainter;
-class QModelIndex;
-class QStyleOption;
-
-class LIBDOLPHINPRIVATE_EXPORT KCategoryDrawer
-{
-public:
-    KCategoryDrawer();
-
-    virtual ~KCategoryDrawer();
-
-    /**
-      * This method purpose is to draw a category represented by the given
-      * @param index with the given @param sortRole sorting role
-      *
-      * @note This method will be called one time per category, always with the
-      *       first element in that category
-      */
-    virtual void drawCategory(const QModelIndex &index,
-                              int sortRole,
-                              const QStyleOption &option,
-                              QPainter *painter) const;
-
-    virtual int categoryHeight(const QModelIndex &index, const QStyleOption &option) const;
-};
-
-#endif // KCATEGORYDRAWER_H
index 3cc7c000b6fba151b7b9e490dfb0932f6b3e67e8..b9e8997a726ea2eb26902552959d90925f7b66be 100644 (file)
@@ -33,7 +33,7 @@ int main(int argc, char **argv)
 {
     KAboutData about("dolphin", 0,
                      ki18nc("@title", "Dolphin"),
-                     "1.0.1",
+                     "1.0.99",
                      ki18nc("@title", "File Manager"),
                      KAboutData::License_GPL,
                      ki18nc("@info:credit", "(C) 2006, 2007 Peter Penz"));
index a7a593bb06b7a19e350f0fd0b82a071fa6ab7180..f535475aac0ef784bb15af03e8fa58016e90dd3b 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <kiconloader.h>
 
+#include <QLayout>
 #include <QPainter>
 #include <QPixmap>
 #include <QKeyEvent>
@@ -28,7 +29,8 @@
 PixmapViewer::PixmapViewer(QWidget* parent, Transition transition) :
     QWidget(parent),
     m_transition(transition),
-    m_animationStep(0)
+    m_animationStep(0),
+    m_sizeHint()
 {
     setMinimumWidth(KIconLoader::SizeEnormous);
     setMinimumHeight(KIconLoader::SizeEnormous);
@@ -72,6 +74,19 @@ void PixmapViewer::setPixmap(const QPixmap& pixmap)
     }
 }
 
+void PixmapViewer::setSizeHint(const QSize& size)
+{
+    m_sizeHint = size;
+    if ((parentWidget() != 0) && (parentWidget()->layout() != 0)) {
+        parentWidget()->layout()->activate();
+    }
+}
+
+QSize PixmapViewer::sizeHint() const
+{
+    return m_sizeHint;
+}
+
 void PixmapViewer::paintEvent(QPaintEvent* event)
 {
     QWidget::paintEvent(event);
index 01d8cf1c18a842a0038ca2446ae449e71421d765..26e520aab3bc05e117bbdf1d242aa4c011891580 100644 (file)
@@ -66,6 +66,13 @@ public:
     void setPixmap(const QPixmap& pixmap);
     const QPixmap& pixmap() const;
 
+    /**
+     * Sets the size hint to \a size and triggers a relayout
+     * of the parent widget. Per default no size hint is given.
+     */
+    void setSizeHint(const QSize& size);
+    virtual QSize sizeHint() const;
+
 protected:
     virtual void paintEvent(QPaintEvent* event);
 
@@ -79,6 +86,7 @@ private:
     QTimeLine m_animation;
     Transition m_transition;
     int m_animationStep;
+    QSize m_sizeHint;
 };
 
 inline const QPixmap& PixmapViewer::pixmap() const
index adfc48676467e4fa135ae5b23cb87bc65f3fff22..fa5bf60e06278659e71ab70c24e6bc2802ecc8df 100644 (file)
@@ -116,9 +116,9 @@ void RenameDialog::slotButtonClicked(int button)
         if (m_newName.isEmpty()) {
             m_errorString = i18nc("@info:status",
                                   "The new name is empty. A name with at least one character must be entered.");
-        } else if (!m_renameOneItem && m_newName.count('#') != 1) {
+        } else if (!m_renameOneItem && (m_newName.count('#') == 0)) {
             m_newName.truncate(0);
-            m_errorString = i18nc("@info:status", "The name must contain exactly one # character.");
+            m_errorString = i18nc("@info:status", "The name must contain at least one # character.");
         }
     }
 
diff --git a/src/selectionmanager.cpp b/src/selectionmanager.cpp
new file mode 100644 (file)
index 0000000..02125d7
--- /dev/null
@@ -0,0 +1,132 @@
+/***************************************************************************
+ *   Copyright (C) 2008 by Peter Penz <peter.penz@gmx.at>                  *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
+ ***************************************************************************/
+
+#include "selectionmanager.h"
+
+#include "dolphinmodel.h"
+#include "selectiontoggle.h"
+#include <kdirmodel.h>
+#include <kiconeffect.h>
+
+#include <QAbstractButton>
+#include <QAbstractItemView>
+#include <QAbstractProxyModel>
+#include <QModelIndex>
+#include <QPainter>
+#include <QPaintEvent>
+#include <QRect>
+#include <QTimeLine>
+
+SelectionManager::SelectionManager(QAbstractItemView* parent) :
+    QObject(parent),
+    m_view(parent),
+    m_toggle(0)
+{
+    connect(parent, SIGNAL(entered(const QModelIndex&)),
+            this, SLOT(slotEntered(const QModelIndex&)));
+    connect(parent, SIGNAL(viewportEntered()),
+            this, SLOT(slotViewportEntered()));
+    m_toggle = new SelectionToggle(m_view->viewport());
+    m_toggle->setCheckable(true);
+    m_toggle->hide();
+    connect(m_toggle, SIGNAL(clicked(bool)),
+            this, SLOT(setItemSelected(bool)));
+}
+
+SelectionManager::~SelectionManager()
+{
+}
+
+void SelectionManager::reset()
+{
+    m_toggle->reset();
+}
+
+void SelectionManager::slotEntered(const QModelIndex& index)
+{
+    m_toggle->hide();
+    if (index.isValid() && (index.column() == DolphinModel::Name)) {
+        m_toggle->setFileItem(itemForIndex(index));
+
+        connect(m_view->model(), SIGNAL(rowsRemoved(const QModelIndex&, int, int)),
+                this, SLOT(slotRowsRemoved(const QModelIndex&, int, int)));
+
+        const QRect rect = m_view->visualRect(index);
+
+        const int gap = 2;
+        const int x = rect.left() + gap;
+        const int y = rect.top() + gap;
+        m_toggle->move(QPoint(x, y));
+
+        QItemSelectionModel* selModel = m_view->selectionModel();
+        m_toggle->setChecked(selModel->isSelected(index));
+        m_toggle->show();
+    } else {
+        m_toggle->setFileItem(KFileItem());
+        disconnect(m_view->model(), SIGNAL(rowsRemoved(const QModelIndex&, int, int)),
+                   this, SLOT(slotRowsRemoved(const QModelIndex&, int, int)));
+    }
+}
+
+void SelectionManager::slotViewportEntered()
+{
+    m_toggle->hide();
+}
+
+void SelectionManager::setItemSelected(bool selected)
+{
+    emit selectionChanged();
+    Q_ASSERT(!m_toggle->fileItem().isNull());
+
+    const QModelIndex index = indexForItem(m_toggle->fileItem());
+    if (index.isValid()) {
+        QItemSelectionModel* selModel = m_view->selectionModel();
+        if (selected) {
+            selModel->select(index, QItemSelectionModel::Select);
+        } else {
+            selModel->select(index, QItemSelectionModel::Deselect);
+        }
+    }
+}
+
+void SelectionManager::slotRowsRemoved(const QModelIndex& parent, int start, int end)
+{
+    Q_UNUSED(parent);
+    Q_UNUSED(start);
+    Q_UNUSED(end);
+    m_toggle->hide();
+}
+
+KFileItem SelectionManager::itemForIndex(const QModelIndex& index) const
+{
+    QAbstractProxyModel* proxyModel = static_cast<QAbstractProxyModel*>(m_view->model());
+    KDirModel* dirModel = static_cast<KDirModel*>(proxyModel->sourceModel());
+    const QModelIndex dirIndex = proxyModel->mapToSource(index);
+    return dirModel->itemForIndex(dirIndex);
+}
+
+const QModelIndex SelectionManager::indexForItem(const KFileItem& item) const
+{
+    QAbstractProxyModel* proxyModel = static_cast<QAbstractProxyModel*>(m_view->model());
+    KDirModel* dirModel = static_cast<KDirModel*>(proxyModel->sourceModel());
+    const QModelIndex dirIndex = dirModel->indexForItem(item);
+    return proxyModel->mapFromSource(dirIndex);
+}
+
+#include "selectionmanager.moc"
diff --git a/src/selectionmanager.h b/src/selectionmanager.h
new file mode 100644 (file)
index 0000000..04e6e29
--- /dev/null
@@ -0,0 +1,73 @@
+/***************************************************************************
+ *   Copyright (C) 2008 by Peter Penz <peter.penz@gmx.at>                  *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
+ ***************************************************************************/
+
+#ifndef SELECTIONMANAGER_H
+#define SELECTIONMANAGER_H
+
+#include <kfileitem.h>
+
+#include <QObject>
+
+class DolphinSortFilterProxyModel;
+class QAbstractItemView;
+class QModelIndex;
+class QAbstractButton;
+class SelectionToggle;
+
+/**
+ * @brief Allows to select and deselect items for the single-click mode.
+ *
+ * Whenever an item is hovered by the mouse, a toggle button is shown
+ * which allows to select/deselect the current item.
+ */
+class SelectionManager : public QObject
+{
+    Q_OBJECT
+
+public:
+    SelectionManager(QAbstractItemView* parent);
+    virtual ~SelectionManager();
+
+public slots:
+    /**
+     * Resets the selection manager so that the toggle button gets
+     * invisible.
+     */
+    void reset();
+
+signals:
+    /** Is emitted if the selection has been changed by the toggle button. */
+    void selectionChanged();
+
+private slots:
+    void slotEntered(const QModelIndex& index);
+    void slotViewportEntered();
+    void setItemSelected(bool selected);
+    void slotRowsRemoved(const QModelIndex& parent, int start, int end);
+
+private:
+    KFileItem itemForIndex(const QModelIndex& index) const;
+    const QModelIndex indexForItem(const KFileItem& item) const;
+
+private:
+    QAbstractItemView* m_view;
+    SelectionToggle* m_toggle;
+};
+
+#endif
diff --git a/src/selectiontoggle.cpp b/src/selectiontoggle.cpp
new file mode 100644 (file)
index 0000000..7a3f0ef
--- /dev/null
@@ -0,0 +1,171 @@
+/***************************************************************************
+ *   Copyright (C) 2008 by Peter Penz <peter.penz@gmx.at>                  *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
+ ***************************************************************************/
+
+#include "selectiontoggle.h"
+
+#include <kicon.h>
+#include <kiconloader.h>
+#include <kiconeffect.h>
+
+#include <QPainter>
+#include <QPaintEvent>
+#include <QRect>
+#include <QTimer>
+#include <QTimeLine>
+
+SelectionToggle::SelectionToggle(QWidget* parent) :
+    QAbstractButton(parent),
+    m_isHovered(false),
+    m_fadingValue(0),
+    m_icon(),
+    m_fadingTimeLine(0)
+{
+    parent->installEventFilter(this);
+    resize(sizeHint());
+    m_icon = KIconLoader::global()->loadIcon("dialog-ok",
+                                             KIconLoader::NoGroup,
+                                             KIconLoader::SizeSmall);
+}
+
+SelectionToggle::~SelectionToggle()
+{
+}
+
+QSize SelectionToggle::sizeHint() const
+{
+    return QSize(16, 16);
+}
+
+void SelectionToggle::reset()
+{
+    m_item = KFileItem();
+    hide();
+}
+
+void SelectionToggle::setFileItem(const KFileItem& item)
+{
+    m_item = item;
+    if (!item.isNull()) {
+        startFading();
+    }
+}
+
+KFileItem SelectionToggle::fileItem() const
+{
+    return m_item;
+}
+
+void SelectionToggle::setVisible(bool visible)
+{
+    QAbstractButton::setVisible(visible);
+
+    stopFading();
+    if (visible) {
+        startFading();
+    }
+
+}
+
+bool SelectionToggle::eventFilter(QObject* obj, QEvent* event)
+{
+    if ((obj == parent()) && (event->type() == QEvent::Leave)) {
+        hide();
+    }
+    return QAbstractButton::eventFilter(obj, event);
+}
+
+void SelectionToggle::enterEvent(QEvent* event)
+{
+    QAbstractButton::enterEvent(event);
+
+    // if the mouse cursor is above the selection toggle, display
+    // it immediately without fading timer
+    m_isHovered = true;
+    if (m_fadingTimeLine != 0) {
+        m_fadingTimeLine->stop();
+    }
+    m_fadingValue = 255;
+    update();
+}
+
+void SelectionToggle::leaveEvent(QEvent* event)
+{
+    QAbstractButton::leaveEvent(event);
+    m_isHovered = false;
+    update();
+}
+
+void SelectionToggle::paintEvent(QPaintEvent* event)
+{
+    QPainter painter(this);
+    painter.setClipRect(event->rect());
+
+    if (m_isHovered) {
+        KIconEffect iconEffect;
+        QPixmap activeIcon = iconEffect.apply(m_icon, KIconLoader::Desktop, KIconLoader::ActiveState);
+        painter.drawPixmap(0, 0, activeIcon);
+    } else {
+        if (m_fadingValue < 255) {
+            // apply an alpha mask respecting the fading value to the icon
+            QPixmap icon = m_icon;
+            QPixmap alphaMask(icon.width(), icon.height());
+            const QColor color(m_fadingValue, m_fadingValue, m_fadingValue);
+            alphaMask.fill(color);
+            icon.setAlphaChannel(alphaMask);
+            painter.drawPixmap(0, 0, icon);
+        } else {
+            // no fading is required
+            painter.drawPixmap(0, 0, m_icon);
+        }
+    }
+}
+
+void SelectionToggle::setFadingValue(int value)
+{
+    m_fadingValue = value;
+    if (m_fadingValue >= 255) {
+        Q_ASSERT(m_fadingTimeLine != 0);
+        m_fadingTimeLine->stop();
+    }
+    update();
+}
+
+void SelectionToggle::startFading()
+{
+    Q_ASSERT(m_fadingTimeLine == 0);
+
+    m_fadingTimeLine = new QTimeLine(2000, this);
+    connect(m_fadingTimeLine, SIGNAL(frameChanged(int)),
+            this, SLOT(setFadingValue(int)));
+    m_fadingTimeLine->setFrameRange(0, 255);
+    m_fadingTimeLine->start();
+    m_fadingValue = 0;
+}
+
+void SelectionToggle::stopFading()
+{
+    if (m_fadingTimeLine != 0) {
+        m_fadingTimeLine->stop();
+        delete m_fadingTimeLine;
+        m_fadingTimeLine = 0;
+    }
+    m_fadingValue = 0;
+}
+
+#include "selectiontoggle.moc"
diff --git a/src/selectiontoggle.h b/src/selectiontoggle.h
new file mode 100644 (file)
index 0000000..653104a
--- /dev/null
@@ -0,0 +1,84 @@
+/***************************************************************************
+ *   Copyright (C) 2008 by Peter Penz <peter.penz@gmx.at>                  *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
+ ***************************************************************************/
+
+#ifndef SELECTIONTOGGLE_H
+#define SELECTIONTOGGLE_H
+
+#include <kfileitem.h>
+
+#include <QAbstractButton>
+#include <QPixmap>
+
+class QTimeLine;
+
+/**
+ * @brief Toggle button for changing the selection of an hovered item.
+ *
+ * The toggle button is visually invisible until it is displayed at least
+ * for one second.
+ *
+ * @see SelectionManager
+ */
+class SelectionToggle : public QAbstractButton
+{
+    Q_OBJECT
+
+public:
+    explicit SelectionToggle(QWidget* parent);
+    virtual ~SelectionToggle();
+    virtual QSize sizeHint() const;
+
+    /**
+     * Resets the selection toggle so that it is hidden and stays
+     * visually invisible for at least one second after it is shown again.
+     */
+    void reset();
+
+    void setFileItem(const KFileItem& item);
+    KFileItem fileItem() const;
+
+public slots:
+    virtual void setVisible(bool visible);
+
+protected:
+    virtual bool eventFilter(QObject* obj, QEvent* event);
+    virtual void enterEvent(QEvent* event);
+    virtual void leaveEvent(QEvent* event);
+    virtual void paintEvent(QPaintEvent* event);
+
+private slots:
+    /**
+     * Sets the alpha value for the fading animation and is
+     * connected with m_fadingTimeLine.
+     */
+    void setFadingValue(int value);
+
+private:
+    void startFading();
+    void stopFading();
+
+private:
+    bool m_isHovered;
+    int m_fadingValue;
+    QPixmap m_icon;
+    QTimeLine* m_fadingTimeLine;
+    KFileItem m_item;
+};
+
+#endif
diff --git a/src/startupsettingspage.cpp b/src/startupsettingspage.cpp
new file mode 100644 (file)
index 0000000..e3f237c
--- /dev/null
@@ -0,0 +1,152 @@
+/***************************************************************************
+ *   Copyright (C) 2008 by Peter Penz <peter.penz@gmx.at>                  *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
+ ***************************************************************************/
+
+#include "startupsettingspage.h"
+
+#include "dolphinsettings.h"
+#include "dolphinmainwindow.h"
+#include "dolphinview.h"
+#include "dolphinviewcontainer.h"
+
+#include "dolphin_generalsettings.h"
+
+#include <kdialog.h>
+#include <kfiledialog.h>
+#include <klocale.h>
+#include <kvbox.h>
+
+#include <QCheckBox>
+#include <QGroupBox>
+#include <QLabel>
+#include <QLineEdit>
+#include <QPushButton>
+#include <QRadioButton>
+
+StartupSettingsPage::StartupSettingsPage(DolphinMainWindow* mainWin, QWidget* parent) :
+    SettingsPageBase(parent),
+    m_mainWindow(mainWin),
+    m_homeUrl(0),
+    m_splitView(0),
+    m_editableUrl(0),
+    m_filterBar(0)
+{
+    const int spacing = KDialog::spacingHint();
+
+    QVBoxLayout* topLayout = new QVBoxLayout(this);
+    KVBox* vBox = new KVBox(this);
+    vBox->setSpacing(spacing);
+
+    // create 'Home URL' editor
+    QGroupBox* homeBox = new QGroupBox(i18nc("@title:group", "Home Folder"), vBox);
+
+    KHBox* homeUrlBox = new KHBox(homeBox);
+    homeUrlBox->setSpacing(spacing);
+
+    new QLabel(i18nc("@label:textbox", "Location:"), homeUrlBox);
+    m_homeUrl = new QLineEdit(homeUrlBox);
+
+    QPushButton* selectHomeUrlButton = new QPushButton(KIcon("folder-open"), QString(), homeUrlBox);
+    connect(selectHomeUrlButton, SIGNAL(clicked()),
+            this, SLOT(selectHomeUrl()));
+
+    KHBox* buttonBox = new KHBox(homeBox);
+    buttonBox->setSpacing(spacing);
+
+    QPushButton* useCurrentButton = new QPushButton(i18nc("@action:button", "Use Current Location"), buttonBox);
+    connect(useCurrentButton, SIGNAL(clicked()),
+            this, SLOT(useCurrentLocation()));
+    QPushButton* useDefaultButton = new QPushButton(i18nc("@action:button", "Use Default Location"), buttonBox);
+    connect(useDefaultButton, SIGNAL(clicked()),
+            this, SLOT(useDefaultLocation()));
+
+    QVBoxLayout* homeBoxLayout = new QVBoxLayout(homeBox);
+    homeBoxLayout->addWidget(homeUrlBox);
+    homeBoxLayout->addWidget(buttonBox);
+
+    // create 'Split view', 'Editable location' and 'Filter bar' checkboxes
+    m_splitView = new QCheckBox(i18nc("@option:check Startup Settings", "Split view mode"), vBox);
+    m_editableUrl = new QCheckBox(i18nc("@option:check Startup Settings", "Editable location bar"), vBox);
+    m_filterBar = new QCheckBox(i18nc("@option:check Startup Settings", "Show filter bar"), vBox);
+
+    // Add a dummy widget with no restriction regarding
+    // a vertical resizing. This assures that the dialog layout
+    // is not stretched vertically.
+    new QWidget(vBox);
+
+    topLayout->addWidget(vBox);
+
+    loadSettings();
+}
+
+StartupSettingsPage::~StartupSettingsPage()
+{
+}
+
+void StartupSettingsPage::applySettings()
+{
+    GeneralSettings* settings = DolphinSettings::instance().generalSettings();
+
+    const KUrl url(m_homeUrl->text());
+    KFileItem fileItem(S_IFDIR, KFileItem::Unknown, url);
+    if (url.isValid() && fileItem.isDir()) {
+        settings->setHomeUrl(url.prettyUrl());
+    }
+
+    settings->setSplitView(m_splitView->isChecked());
+    settings->setEditableUrl(m_editableUrl->isChecked());
+    settings->setFilterBar(m_filterBar->isChecked());
+}
+
+void StartupSettingsPage::restoreDefaults()
+{
+    GeneralSettings* settings = DolphinSettings::instance().generalSettings();
+    settings->setDefaults();
+    loadSettings();
+}
+
+void StartupSettingsPage::selectHomeUrl()
+{
+    const QString homeUrl = m_homeUrl->text();
+    KUrl url = KFileDialog::getExistingDirectoryUrl(homeUrl);
+    if (!url.isEmpty()) {
+        m_homeUrl->setText(url.prettyUrl());
+    }
+}
+
+void StartupSettingsPage::useCurrentLocation()
+{
+    const DolphinView* view = m_mainWindow->activeViewContainer()->view();
+    m_homeUrl->setText(view->url().prettyUrl());
+}
+
+void StartupSettingsPage::useDefaultLocation()
+{
+    m_homeUrl->setText("file://" + QDir::homePath());
+}
+
+void StartupSettingsPage::loadSettings()
+{
+    GeneralSettings* settings = DolphinSettings::instance().generalSettings();
+    m_homeUrl->setText(settings->homeUrl());
+    m_splitView->setChecked(settings->splitView());
+    m_editableUrl->setChecked(settings->editableUrl());
+    m_filterBar->setChecked(settings->filterBar());
+}
+
+#include "startupsettingspage.moc"
diff --git a/src/startupsettingspage.h b/src/startupsettingspage.h
new file mode 100644 (file)
index 0000000..14314c6
--- /dev/null
@@ -0,0 +1,65 @@
+/***************************************************************************
+ *   Copyright (C) 2008 by Peter Penz <peter.penz@gmx.at>                  *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
+ ***************************************************************************/
+#ifndef STARTUPSETTINGSPAGE_H
+#define STARTUPSETTINGSPAGE_H
+
+#include <settingspagebase.h>
+
+class DolphinMainWindow;
+class QLineEdit;
+class QCheckBox;
+
+/**
+ * @brief Page for the 'Startup' settings of the Dolphin settings dialog.
+ *
+ * The startup settings allow to set the home URL and to configure the
+ * state of the view mode, split mode and the filter bar when starting Dolphin.
+ */
+class StartupSettingsPage : public SettingsPageBase
+{
+    Q_OBJECT
+
+public:
+    StartupSettingsPage(DolphinMainWindow* mainWindow, QWidget* parent);
+    virtual ~StartupSettingsPage();
+
+    /** @see SettingsPageBase::applySettings() */
+    virtual void applySettings();
+
+    /** @see SettingsPageBase::restoreDefaults() */
+    virtual void restoreDefaults();
+
+private slots:
+    void selectHomeUrl();
+    void useCurrentLocation();
+    void useDefaultLocation();
+
+private:
+    void loadSettings();
+
+private:
+    DolphinMainWindow* m_mainWindow;
+    QLineEdit* m_homeUrl;
+
+    QCheckBox* m_splitView;
+    QCheckBox* m_editableUrl;
+    QCheckBox* m_filterBar;
+};
+
+#endif
index c5d0ec5101ee4cb84755814e337ed8881f8d9872..844a2ecf9e355734017dd22c395a52e811e40789 100644 (file)
@@ -89,14 +89,16 @@ ViewPropertiesDialog::ViewPropertiesDialog(DolphinView* dolphinView) :
         propsBox = new QGroupBox(i18nc("@title:group", "Properties"), main);
     }
 
-    QLabel* viewModeLabel = new QLabel(i18nc("@label:listbox", "View mode:"), propsBox);
-    m_viewMode = new QComboBox(propsBox);
+    QWidget* propsGrid = new QWidget();
+
+    QLabel* viewModeLabel = new QLabel(i18nc("@label:listbox", "View mode:"), propsGrid);
+    m_viewMode = new QComboBox(propsGrid);
     m_viewMode->addItem(KIcon("view-list-icons"), i18nc("@item:inlistbox", "Icons"));
     m_viewMode->addItem(KIcon("view-list-details"), i18nc("@item:inlistbox", "Details"));
     m_viewMode->addItem(KIcon("view-file-columns"), i18nc("@item:inlistbox", "Column"));
 
-    QLabel* sortingLabel = new QLabel(i18nc("@label:listbox", "Sorting:"), propsBox);
-    QWidget* sortingBox = new QWidget(propsBox);
+    QLabel* sortingLabel = new QLabel(i18nc("@label:listbox", "Sorting:"), propsGrid);
+    QWidget* sortingBox = new QWidget(propsGrid);
 
     m_sortOrder = new QComboBox(sortingBox);
     m_sortOrder->addItem(i18nc("@item:inlistbox", "Ascending"));
@@ -119,6 +121,11 @@ ViewPropertiesDialog::ViewPropertiesDialog(DolphinView* dolphinView) :
     //    m_sorting->addItem(i18nc("@item:inlistbox Sort", "By Tags"));
     // }
 #endif
+    m_showPreview = new QCheckBox(i18nc("@option:check", "Show preview"), propsBox);
+    m_showInGroups = new QCheckBox(i18nc("@option:check", "Show in groups"), propsBox);
+    m_showHiddenFiles = new QCheckBox(i18nc("@option:check", "Show hidden files"), propsBox);
+
+    m_additionalInfo = new QPushButton(i18nc("@action:button", "Additional Information"), propsBox);
 
     QHBoxLayout* sortingLayout = new QHBoxLayout();
     sortingLayout->setMargin(0);
@@ -126,23 +133,18 @@ ViewPropertiesDialog::ViewPropertiesDialog(DolphinView* dolphinView) :
     sortingLayout->addWidget(m_sorting);
     sortingBox->setLayout(sortingLayout);
 
-    m_showPreview = new QCheckBox(i18nc("@option:check", "Show preview"), propsBox);
-    m_showInGroups = new QCheckBox(i18nc("@option:check", "Show in Groups"), propsBox);
-    m_showHiddenFiles = new QCheckBox(i18nc("@option:check", "Show hidden files"), propsBox);
+    QGridLayout* propsGridLayout = new QGridLayout(propsGrid);
+    propsGridLayout->addWidget(viewModeLabel, 0, 0);
+    propsGridLayout->addWidget(m_viewMode, 0, 1);
+    propsGridLayout->addWidget(sortingLabel, 1, 0);
+    propsGridLayout->addWidget(sortingBox, 1, 1);
 
-    m_additionalInfo = new QPushButton(i18nc("@action:button", "Additional Information"), propsBox);
-    connect(m_additionalInfo, SIGNAL(clicked()),
-            this, SLOT(configureAdditionalInfo()));
-
-    QGridLayout* propsBoxLayout = new QGridLayout(propsBox);
-    propsBoxLayout->addWidget(viewModeLabel, 0, 0);
-    propsBoxLayout->addWidget(m_viewMode, 0, 1);
-    propsBoxLayout->addWidget(sortingLabel, 1, 0);
-    propsBoxLayout->addWidget(sortingBox, 1, 1);
-    propsBoxLayout->addWidget(m_showPreview, 2, 0);
-    propsBoxLayout->addWidget(m_showInGroups, 3, 0);
-    propsBoxLayout->addWidget(m_showHiddenFiles, 4, 0);
-    propsBoxLayout->addWidget(m_additionalInfo, 5, 0);
+    QVBoxLayout* propsBoxLayout = new QVBoxLayout(propsBox);
+    propsBoxLayout->addWidget(propsGrid);
+    propsBoxLayout->addWidget(m_showPreview);
+    propsBoxLayout->addWidget(m_showInGroups);
+    propsBoxLayout->addWidget(m_showHiddenFiles);
+    propsBoxLayout->addWidget(m_additionalInfo);
 
     topLayout->addWidget(propsBox);
 
@@ -152,8 +154,8 @@ ViewPropertiesDialog::ViewPropertiesDialog(DolphinView* dolphinView) :
             this, SLOT(slotSortingChanged(int)));
     connect(m_sortOrder, SIGNAL(activated(int)),
             this, SLOT(slotSortOrderChanged(int)));
-    connect(m_additionalInfo, SIGNAL(activated(int)),
-            this, SLOT(slotAdditionalInfoChanged(int)));
+    connect(m_additionalInfo, SIGNAL(clicked()),
+            this, SLOT(configureAdditionalInfo()));
     connect(m_showPreview, SIGNAL(clicked()),
             this, SLOT(slotShowPreviewChanged()));
     connect(m_showInGroups, SIGNAL(clicked()),