diff options
| author | Peter Penz <[email protected]> | 2009-01-14 19:26:23 +0000 |
|---|---|---|
| committer | Peter Penz <[email protected]> | 2009-01-14 19:26:23 +0000 |
| commit | 307285e9635a4bf584d6e5d7478876b90ef870f0 (patch) | |
| tree | db36cbbdc7996ab86c38be8f96fe83597d350dfb /src/panels/folders | |
| parent | 86d9c40ab71df5b8bd5063251337d5ca0c22380a (diff) | |
Group classes into folders, Dolphin is too big in the meantime for having a flat directory hierarchy. dolphin/src/CMakeLists.txt will be cleaned up later.
svn path=/trunk/KDE/kdebase/apps/; revision=911065
Diffstat (limited to 'src/panels/folders')
| -rw-r--r-- | src/panels/folders/dolphin_folderspanelsettings.kcfg | 11 | ||||
| -rw-r--r-- | src/panels/folders/dolphin_folderspanelsettings.kcfgc | 4 | ||||
| -rw-r--r-- | src/panels/folders/ktreeview.cpp | 180 | ||||
| -rw-r--r-- | src/panels/folders/ktreeview.h | 48 | ||||
| -rw-r--r-- | src/panels/folders/ktreeview_p.h | 49 | ||||
| -rw-r--r-- | src/panels/folders/sidebartreeview.cpp | 147 | ||||
| -rw-r--r-- | src/panels/folders/sidebartreeview.h | 58 | ||||
| -rw-r--r-- | src/panels/folders/treeviewcontextmenu.cpp | 194 | ||||
| -rw-r--r-- | src/panels/folders/treeviewcontextmenu.h | 88 | ||||
| -rw-r--r-- | src/panels/folders/treeviewsidebarpage.cpp | 279 | ||||
| -rw-r--r-- | src/panels/folders/treeviewsidebarpage.h | 135 |
11 files changed, 1193 insertions, 0 deletions
diff --git a/src/panels/folders/dolphin_folderspanelsettings.kcfg b/src/panels/folders/dolphin_folderspanelsettings.kcfg new file mode 100644 index 000000000..816d783c8 --- /dev/null +++ b/src/panels/folders/dolphin_folderspanelsettings.kcfg @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE kcfg SYSTEM "http://www.kde.org/standards/kcfg/1.0/kcfg.dtd"> +<kcfg> + <kcfgfile name="dolphinrc"/> + <group name="FoldersPanel"> + <entry name="ShowHiddenFiles" type="Bool"> + <label context="@label">Show hidden files</label> + <default>false</default> + </entry> + </group> +</kcfg> diff --git a/src/panels/folders/dolphin_folderspanelsettings.kcfgc b/src/panels/folders/dolphin_folderspanelsettings.kcfgc new file mode 100644 index 000000000..f73e8807d --- /dev/null +++ b/src/panels/folders/dolphin_folderspanelsettings.kcfgc @@ -0,0 +1,4 @@ +File=dolphin_folderspanelsettings.kcfg +ClassName=FoldersPanelSettings +Singleton=true +Mutators=true diff --git a/src/panels/folders/ktreeview.cpp b/src/panels/folders/ktreeview.cpp new file mode 100644 index 000000000..7c30fad33 --- /dev/null +++ b/src/panels/folders/ktreeview.cpp @@ -0,0 +1,180 @@ +/*************************************************************************** + * Copyright (C) 2008 by <haraldhv (at) stud.ntnu.no> * + * Copyright (C) 2008 by <[email protected]> * + * * + * 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 "ktreeview.h" +#include "ktreeview_p.h" + +#include <KGlobalSettings> + +#include <QItemSelectionModel> +#include <QScrollBar> +#include <QTimer> +#include <QTimeLine> + +KTreeView::KTreeViewPrivate::KTreeViewPrivate(KTreeView *parent) : + parent(parent), + autoHorizontalScroll(false), + timeLine(0), + startScrollTimer(0) +{ + startScrollTimer = new QTimer(this); + startScrollTimer->setSingleShot(true); + startScrollTimer->setInterval(300); + connect(startScrollTimer, SIGNAL(timeout()), + this, SLOT(startScrolling())); + + timeLine = new QTimeLine(300, this); + connect(timeLine, SIGNAL(frameChanged(int)), + this, SLOT(updateVerticalScrollBar(int))); + + connect(parent->verticalScrollBar(), SIGNAL(rangeChanged(int, int)), + startScrollTimer, SLOT(start())); + connect(parent->verticalScrollBar(), SIGNAL(valueChanged(int)), + startScrollTimer, SLOT(start())); + connect(parent, SIGNAL(collapsed(const QModelIndex&)), + startScrollTimer, SLOT(start())); + connect(parent, SIGNAL(expanded(const QModelIndex&)), + startScrollTimer, SLOT(start())); +} + +void KTreeView::KTreeViewPrivate::startScrolling() +{ + QModelIndex index; + + const int viewportHeight = parent->viewport()->height(); + + // check whether there is a selected index which is partly visible + const QModelIndexList selectedIndexes = parent->selectionModel()->selectedIndexes(); + if (selectedIndexes.count() == 1) { + QModelIndex selectedIndex = selectedIndexes.first(); + const QRect rect = parent->visualRect(selectedIndex); + if ((rect.bottom() >= 0) && (rect.top() <= viewportHeight)) { + // the selected index is (at least partly) visible, use it as + // scroll target + index = selectedIndex; + } + } + + if (!index.isValid()) { + // no partly selected index is visible, determine the most left visual index + QModelIndex visibleIndex = parent->indexAt(QPoint(0, 0)); + if (!visibleIndex.isValid()) { + return; + } + + index = visibleIndex; + int minimum = parent->width(); + do { + const QRect rect = parent->visualRect(visibleIndex); + if (rect.top() > viewportHeight) { + // the current index and all successors are not visible anymore + break; + } + if (rect.left() < minimum) { + minimum = rect.left(); + index = visibleIndex; + } + visibleIndex = parent->indexBelow(visibleIndex); + } while (visibleIndex.isValid()); + } + + // start the horizontal scrolling to assure that the item indicated by 'index' gets fully visible + Q_ASSERT(index.isValid()); + const QRect rect = parent->visualRect(index); + + QScrollBar *scrollBar = parent->horizontalScrollBar(); + const int oldScrollBarPos = scrollBar->value(); + + const int itemRight = oldScrollBarPos + rect.left() + rect.width() - 1; + const int availableWidth = parent->viewport()->width(); + int scrollBarPos = itemRight - availableWidth; + const int scrollBarPosMax = oldScrollBarPos + rect.left() - parent->indentation(); + if (scrollBarPos > scrollBarPosMax) { + scrollBarPos = scrollBarPosMax; + } + + if (scrollBarPos != oldScrollBarPos) { + timeLine->setFrameRange(oldScrollBarPos, scrollBarPos); + timeLine->start(); + } +} + +void KTreeView::KTreeViewPrivate::updateVerticalScrollBar(int value) +{ + QScrollBar *scrollBar = parent->horizontalScrollBar(); + scrollBar->setValue(value); + startScrollTimer->stop(); +} + +// ************************************************ + +KTreeView::KTreeView(QWidget *parent) : + QTreeView(parent), + d(new KTreeViewPrivate(this)) +{ + if (KGlobalSettings::graphicEffectsLevel() >= KGlobalSettings::SimpleAnimationEffects) { + setAutoHorizontalScroll(true); + } +} + +KTreeView::~KTreeView() +{ +} + +void KTreeView::setAutoHorizontalScroll(bool value) +{ + d->autoHorizontalScroll = value; +} + +bool KTreeView::autoHorizontalScroll() const +{ + return d->autoHorizontalScroll; +} + +void KTreeView::setSelectionModel(QItemSelectionModel *selectionModel) +{ + QTreeView::setSelectionModel(selectionModel); + connect(selectionModel, + SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), + d->startScrollTimer, SLOT(start())); +} + +void KTreeView::scrollTo(const QModelIndex& index, ScrollHint hint) +{ + if (d->autoHorizontalScroll) { + // assure that the value of the horizontal scrollbar stays on its current value, + // KTreeView will adjust the value manually + const int value = horizontalScrollBar()->value(); + QTreeView::scrollTo(index, hint); + horizontalScrollBar()->setValue(value); + } else { + QTreeView::scrollTo(index, hint); + } +} + +void KTreeView::hideEvent(QHideEvent *event) +{ + d->startScrollTimer->stop(); + d->timeLine->stop(); + QTreeView::hideEvent(event); +} + +#include "ktreeview.moc" +#include "ktreeview_p.moc" diff --git a/src/panels/folders/ktreeview.h b/src/panels/folders/ktreeview.h new file mode 100644 index 000000000..6bc6ea56a --- /dev/null +++ b/src/panels/folders/ktreeview.h @@ -0,0 +1,48 @@ +/*************************************************************************** + * Copyright (C) 2008 by <haraldhv (at) stud.ntnu.no> * + * Copyright (C) 2008 by <[email protected]> * + * * + * 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 KTREEVIEW_H +#define KTREEVIEW_H + +#include <QTreeView> + +class KTreeView : public QTreeView +{ + Q_OBJECT + +public: + KTreeView(QWidget *parent = 0); + virtual ~KTreeView(); + + void setAutoHorizontalScroll(bool value); + bool autoHorizontalScroll() const; + + virtual void setSelectionModel(QItemSelectionModel *selectionModel); + virtual void scrollTo(const QModelIndex& index, ScrollHint hint = EnsureVisible); + +protected: + virtual void hideEvent(QHideEvent *event); + +private: + class KTreeViewPrivate; + KTreeViewPrivate *d; +}; + +#endif /* ifndef KTREEVIEW_H */ diff --git a/src/panels/folders/ktreeview_p.h b/src/panels/folders/ktreeview_p.h new file mode 100644 index 000000000..1cfa463cd --- /dev/null +++ b/src/panels/folders/ktreeview_p.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * Copyright (C) 2008 by <haraldhv (at) stud.ntnu.no> * + * Copyright (C) 2008 by <[email protected]> * + * * + * 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 KTREEVIEW_P_H +#define KTREEVIEW_P_H + +#include <QObject> + +#include "ktreeview.h" + +class QTimer; +class QTimeLine; + +class KTreeView::KTreeViewPrivate : public QObject +{ + Q_OBJECT + +public Q_SLOTS: + void startScrolling(); + void updateVerticalScrollBar(int value); + +public: + KTreeViewPrivate(KTreeView *parent); + KTreeView *parent; + void setScrollTowards( int scrollTowards ); + + bool autoHorizontalScroll; + QTimeLine *timeLine; + QTimer *startScrollTimer; +}; + +#endif /* ifndef KTREEVIEW_P_H */ diff --git a/src/panels/folders/sidebartreeview.cpp b/src/panels/folders/sidebartreeview.cpp new file mode 100644 index 000000000..a876ee6c3 --- /dev/null +++ b/src/panels/folders/sidebartreeview.cpp @@ -0,0 +1,147 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz <[email protected]> * + * * + * 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 "sidebartreeview.h" + +#include "dolphincontroller.h" +#include "dolphinmodel.h" +#include "draganddrophelper.h" + +#include <kfileitemdelegate.h> +#include <QKeyEvent> +#include <QPainter> +#include <QHeaderView> +#include <QScrollBar> + +SidebarTreeView::SidebarTreeView(QWidget* parent) : + KTreeView(parent) +{ + setAcceptDrops(true); + setUniformRowHeights(true); + setSelectionMode(QAbstractItemView::SingleSelection); + setEditTriggers(QAbstractItemView::NoEditTriggers); + setSortingEnabled(true); + setFrameStyle(QFrame::NoFrame); + setDragDropMode(QAbstractItemView::DragDrop); + setDropIndicatorShown(false); + + setVerticalScrollMode(QListView::ScrollPerPixel); + setHorizontalScrollMode(QListView::ScrollPerPixel); + + viewport()->setAttribute(Qt::WA_Hover); + + // make the background transparent and apply the window-text color + // to the text color, so that enough contrast is given for all color + // schemes + QPalette p = palette(); + p.setColor(QPalette::Active, QPalette::Text, p.color(QPalette::Active, QPalette::WindowText)); + p.setColor(QPalette::Inactive, QPalette::Text, p.color(QPalette::Inactive, QPalette::WindowText)); + p.setColor(QPalette::Disabled, QPalette::Text, p.color(QPalette::Disabled, QPalette::WindowText)); + setPalette(p); + viewport()->setAutoFillBackground(false); + + KFileItemDelegate* delegate = new KFileItemDelegate(this); + setItemDelegate(delegate); +} + +SidebarTreeView::~SidebarTreeView() +{ +} + +bool SidebarTreeView::event(QEvent* event) +{ + switch (event->type()) { + case QEvent::Polish: + // hide all columns except of the 'Name' column + hideColumn(DolphinModel::Size); + hideColumn(DolphinModel::ModifiedTime); + hideColumn(DolphinModel::Permissions); + hideColumn(DolphinModel::Owner); + hideColumn(DolphinModel::Group); + hideColumn(DolphinModel::Type); + hideColumn(DolphinModel::Rating); + hideColumn(DolphinModel::Tags); + header()->hide(); + break; + + case QEvent::Show: + // TODO: The opening/closing animation of subtrees flickers in combination with the + // sidebar when using the Oxygen style. As workaround the animation is turned off: + setAnimated(false); + break; + + case QEvent::UpdateRequest: + // a wheel movement will scroll 1 item + if (model()->rowCount() > 0) { + verticalScrollBar()->setSingleStep(sizeHintForRow(0) / 3); + } + break; + + default: + break; + } + + return KTreeView::event(event); +} + +void SidebarTreeView::startDrag(Qt::DropActions supportedActions) +{ + DragAndDropHelper::instance().startDrag(this, supportedActions); +} + +void SidebarTreeView::dragEnterEvent(QDragEnterEvent* event) +{ + KTreeView::dragEnterEvent(event); + if (event->mimeData()->hasUrls()) { + event->acceptProposedAction(); + } +} + +void SidebarTreeView::dragLeaveEvent(QDragLeaveEvent* event) +{ + KTreeView::dragLeaveEvent(event); + setDirtyRegion(m_dropRect); +} + +void SidebarTreeView::dragMoveEvent(QDragMoveEvent* event) +{ + KTreeView::dragMoveEvent(event); + + // TODO: remove this code when the issue #160611 is solved in Qt 4.4 + const QModelIndex index = indexAt(event->pos()); + setDirtyRegion(m_dropRect); + m_dropRect = visualRect(index); + setDirtyRegion(m_dropRect); + + if (event->mimeData()->hasUrls()) { + // accept url drops, independently from the destination item + event->acceptProposedAction(); + } +} + +void SidebarTreeView::dropEvent(QDropEvent* event) +{ + const QModelIndex index = indexAt(event->pos()); + if (index.isValid()) { + emit urlsDropped(index, event); + } + KTreeView::dropEvent(event); +} + +#include "sidebartreeview.moc" diff --git a/src/panels/folders/sidebartreeview.h b/src/panels/folders/sidebartreeview.h new file mode 100644 index 000000000..a5e8b63ce --- /dev/null +++ b/src/panels/folders/sidebartreeview.h @@ -0,0 +1,58 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz <[email protected]> * + * * + * 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 SIDEBARTREEVIEW_H +#define SIDEBARTREEVIEW_H + +#include <kurl.h> +#include <panels/folders/ktreeview.h> + +/** + * @brief Tree view widget which is used for the sidebar panel. + * + * @see TreeViewSidebarPage + */ +class SidebarTreeView : public KTreeView +{ + Q_OBJECT + +public: + explicit SidebarTreeView(QWidget* parent = 0); + virtual ~SidebarTreeView(); + +signals: + /** + * Is emitted if the URL have been dropped to + * the index \a index. + */ + void urlsDropped(const QModelIndex& index, QDropEvent* event); + +protected: + virtual bool event(QEvent* event); + virtual void startDrag(Qt::DropActions supportedActions); + virtual void dragEnterEvent(QDragEnterEvent* event); + virtual void dragLeaveEvent(QDragLeaveEvent* event); + virtual void dragMoveEvent(QDragMoveEvent* event); + virtual void dropEvent(QDropEvent* event); + +private: + QRect m_dropRect; +}; + +#endif diff --git a/src/panels/folders/treeviewcontextmenu.cpp b/src/panels/folders/treeviewcontextmenu.cpp new file mode 100644 index 000000000..9e8638002 --- /dev/null +++ b/src/panels/folders/treeviewcontextmenu.cpp @@ -0,0 +1,194 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz ([email protected]) and * + * Cvetoslav Ludmiloff * + * * + * 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 "treeviewcontextmenu.h" + +#include "dolphin_folderspanelsettings.h" + +#include <kfileitem.h> +#include <kiconloader.h> +#include <kio/deletejob.h> +#include <kmenu.h> +#include <konqmimedata.h> +#include <konq_fileitemcapabilities.h> +#include <konq_operations.h> +#include <klocale.h> +#include <kpropertiesdialog.h> + +#include "treeviewsidebarpage.h" + +#include <QtGui/QApplication> +#include <QtGui/QClipboard> + +TreeViewContextMenu::TreeViewContextMenu(TreeViewSidebarPage* parent, + const KFileItem& fileInfo) : + QObject(parent), + m_parent(parent), + m_fileInfo(fileInfo) +{ +} + +TreeViewContextMenu::~TreeViewContextMenu() +{ +} + +void TreeViewContextMenu::open() +{ + KMenu* popup = new KMenu(m_parent); + + if (!m_fileInfo.isNull()) { + KonqFileItemCapabilities capabilities(KFileItemList() << m_fileInfo); + + // insert 'Cut', 'Copy' and 'Paste' + QAction* cutAction = new QAction(KIcon("edit-cut"), i18nc("@action:inmenu", "Cut"), this); + cutAction->setEnabled(capabilities.supportsMoving()); + connect(cutAction, SIGNAL(triggered()), this, SLOT(cut())); + + QAction* copyAction = new QAction(KIcon("edit-copy"), i18nc("@action:inmenu", "Copy"), this); + connect(copyAction, SIGNAL(triggered()), this, SLOT(copy())); + + QAction* pasteAction = new QAction(KIcon("edit-paste"), i18nc("@action:inmenu", "Paste"), this); + const QMimeData* mimeData = QApplication::clipboard()->mimeData(); + const KUrl::List pasteData = KUrl::List::fromMimeData(mimeData); + connect(pasteAction, SIGNAL(triggered()), this, SLOT(paste())); + pasteAction->setEnabled(!pasteData.isEmpty() && capabilities.supportsWriting()); + + popup->addAction(cutAction); + popup->addAction(copyAction); + popup->addAction(pasteAction); + popup->addSeparator(); + + // insert 'Rename' + QAction* renameAction = new QAction(i18nc("@action:inmenu", "Rename..."), this); + renameAction->setEnabled(capabilities.supportsMoving()); + connect(renameAction, SIGNAL(triggered()), this, SLOT(rename())); + popup->addAction(renameAction); + + // insert 'Move to Trash' and (optionally) 'Delete' + KSharedConfig::Ptr globalConfig = KSharedConfig::openConfig("kdeglobals", KConfig::IncludeGlobals); + KConfigGroup configGroup(globalConfig, "KDE"); + bool showDeleteCommand = configGroup.readEntry("ShowDeleteCommand", false); + + const KUrl& url = m_fileInfo.url(); + if (url.isLocalFile()) { + QAction* moveToTrashAction = new QAction(KIcon("user-trash"), + i18nc("@action:inmenu", "Move To Trash"), this); + const bool enableMoveToTrash = capabilities.isLocal() && capabilities.supportsMoving(); + moveToTrashAction->setEnabled(enableMoveToTrash); + connect(moveToTrashAction, SIGNAL(triggered()), this, SLOT(moveToTrash())); + popup->addAction(moveToTrashAction); + } else { + showDeleteCommand = true; + } + + if (showDeleteCommand) { + QAction* deleteAction = new QAction(KIcon("edit-delete"), i18nc("@action:inmenu", "Delete"), this); + deleteAction->setEnabled(capabilities.supportsDeleting()); + connect(deleteAction, SIGNAL(triggered()), this, SLOT(deleteItem())); + popup->addAction(deleteAction); + } + + popup->addSeparator(); + + // insert 'Properties' entry + QAction* propertiesAction = new QAction(i18nc("@action:inmenu", "Properties"), this); + connect(propertiesAction, SIGNAL(triggered()), this, SLOT(showProperties())); + popup->addAction(propertiesAction); + + popup->addSeparator(); + } + + QAction* showHiddenFilesAction = new QAction(i18nc("@action:inmenu", "Show Hidden Files"), this); + showHiddenFilesAction->setCheckable(true); + showHiddenFilesAction->setChecked(FoldersPanelSettings::showHiddenFiles()); + popup->addAction(showHiddenFilesAction); + + connect(showHiddenFilesAction, SIGNAL(toggled(bool)), this, SLOT(setShowHiddenFiles(bool))); + + popup->exec(QCursor::pos()); + popup->deleteLater(); +} + +void TreeViewContextMenu::populateMimeData(QMimeData* mimeData, bool cut) +{ + KUrl::List kdeUrls; + kdeUrls.append(m_fileInfo.url()); + KUrl::List mostLocalUrls; + bool dummy; + mostLocalUrls.append(m_fileInfo.mostLocalUrl(dummy)); + KonqMimeData::populateMimeData(mimeData, kdeUrls, mostLocalUrls, cut); +} + +void TreeViewContextMenu::cut() +{ + QMimeData* mimeData = new QMimeData(); + populateMimeData(mimeData, true); + QApplication::clipboard()->setMimeData(mimeData); +} + +void TreeViewContextMenu::copy() +{ + QMimeData* mimeData = new QMimeData(); + populateMimeData(mimeData, false); + QApplication::clipboard()->setMimeData(mimeData); +} + +void TreeViewContextMenu::paste() +{ + QClipboard* clipboard = QApplication::clipboard(); + const QMimeData* mimeData = clipboard->mimeData(); + + const KUrl::List source = KUrl::List::fromMimeData(mimeData); + const KUrl& dest = m_fileInfo.url(); + if (KonqMimeData::decodeIsCutSelection(mimeData)) { + KonqOperations::copy(m_parent, KonqOperations::MOVE, source, dest); + clipboard->clear(); + } else { + KonqOperations::copy(m_parent, KonqOperations::COPY, source, dest); + } +} + +void TreeViewContextMenu::rename() +{ + m_parent->rename(m_fileInfo); +} + +void TreeViewContextMenu::moveToTrash() +{ + KonqOperations::del(m_parent, KonqOperations::TRASH, m_fileInfo.url()); +} + +void TreeViewContextMenu::deleteItem() +{ + KonqOperations::del(m_parent, KonqOperations::DEL, m_fileInfo.url()); +} + +void TreeViewContextMenu::showProperties() +{ + KPropertiesDialog dialog(m_fileInfo.url(), m_parent); + dialog.exec(); +} + +void TreeViewContextMenu::setShowHiddenFiles(bool show) +{ + m_parent->setShowHiddenFiles(show); +} + +#include "treeviewcontextmenu.moc" diff --git a/src/panels/folders/treeviewcontextmenu.h b/src/panels/folders/treeviewcontextmenu.h new file mode 100644 index 000000000..20a603573 --- /dev/null +++ b/src/panels/folders/treeviewcontextmenu.h @@ -0,0 +1,88 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz <[email protected]> * + * * + * 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 TREEVIEWCONTEXTMENU_H +#define TREEVIEWCONTEXTMENU_H + +#include <QtCore/QObject> +#include <KFileItem> + +class TreeViewSidebarPage; + +/** + * @brief Represents the context menu which appears when doing a right + * click on an item of the treeview. + */ +class TreeViewContextMenu : public QObject +{ + Q_OBJECT + +public: + /** + * @parent Pointer to the treeview sidebar page the context menu + * belongs to. + * @fileInfo Pointer to the file item the context menu + * is applied. If 0 is passed, the context menu + * is above the viewport. + */ + TreeViewContextMenu(TreeViewSidebarPage* parent, + const KFileItem& fileInfo); + + virtual ~TreeViewContextMenu(); + + /** Opens the context menu modal. */ + void open(); + +private slots: + /** Cuts the item m_fileInfo. */ + void cut(); + + /** Copies the item m_fileInfo. */ + void copy(); + + /** Paste the clipboard to m_fileInfo. */ + void paste(); + + /** Renames the item m_fileInfo. */ + void rename(); + + /** Moves the item m_fileInfo to the trash. */ + void moveToTrash(); + + /** Deletes the item m_fileInfo. */ + void deleteItem(); + + /** Shows the properties of the item m_fileInfo. */ + void showProperties(); + + /** + * Sets the 'Show Hidden Files' setting for the + * folders panel to \a show. + */ + void setShowHiddenFiles(bool show); + +private: + void populateMimeData(QMimeData* mimeData, bool cut); + +private: + TreeViewSidebarPage* m_parent; + KFileItem m_fileInfo; +}; + +#endif diff --git a/src/panels/folders/treeviewsidebarpage.cpp b/src/panels/folders/treeviewsidebarpage.cpp new file mode 100644 index 000000000..7801a97cc --- /dev/null +++ b/src/panels/folders/treeviewsidebarpage.cpp @@ -0,0 +1,279 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz <[email protected]> * + * * + * 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 "treeviewsidebarpage.h" + +#include "dolphinmodel.h" +#include "dolphinsortfilterproxymodel.h" +#include "dolphinview.h" +#include "settings/dolphinsettings.h" +#include "dolphin_folderspanelsettings.h" +#include "dolphin_generalsettings.h" +#include "draganddrophelper.h" +#include "folderexpander.h" +#include "renamedialog.h" +#include "sidebartreeview.h" +#include "treeviewcontextmenu.h" + +#include <kfileplacesmodel.h> +#include <kdirlister.h> +#include <kfileitem.h> +#include <konq_operations.h> + +#include <QApplication> +#include <QItemSelection> +#include <QTreeView> +#include <QBoxLayout> +#include <QModelIndex> +#include <QScrollBar> +#include <QTimer> + +TreeViewSidebarPage::TreeViewSidebarPage(QWidget* parent) : + SidebarPage(parent), + m_setLeafVisible(false), + m_mouseButtons(Qt::NoButton), + m_dirLister(0), + m_dolphinModel(0), + m_proxyModel(0), + m_treeView(0), + m_leafDir() +{ + setLayoutDirection(Qt::LeftToRight); +} + +TreeViewSidebarPage::~TreeViewSidebarPage() +{ + FoldersPanelSettings::self()->writeConfig(); + + delete m_proxyModel; + m_proxyModel = 0; + delete m_dolphinModel; + m_dolphinModel = 0; + m_dirLister = 0; // deleted by m_dolphinModel +} + +QSize TreeViewSidebarPage::sizeHint() const +{ + return QSize(200, 400); +} + +void TreeViewSidebarPage::setShowHiddenFiles(bool show) +{ + FoldersPanelSettings::setShowHiddenFiles(show); + if (m_dirLister != 0) { + m_dirLister->setShowingDotFiles(show); + m_dirLister->openUrl(m_dirLister->url(), KDirLister::Reload); + } +} + +bool TreeViewSidebarPage::showHiddenFiles() const +{ + return FoldersPanelSettings::showHiddenFiles(); +} + +void TreeViewSidebarPage::rename(const KFileItem& item) +{ + if (DolphinSettings::instance().generalSettings()->renameInline()) { + const QModelIndex dirIndex = m_dolphinModel->indexForItem(item); + const QModelIndex proxyIndex = m_proxyModel->mapFromSource(dirIndex); + m_treeView->edit(proxyIndex); + } else { + KFileItemList items; + items.append(item); + RenameDialog dialog(this, items); + if (dialog.exec() == QDialog::Accepted) { + const QString& newName = dialog.newName(); + if (!newName.isEmpty()) { + KUrl newUrl = item.url(); + newUrl.setFileName(newName); + KonqOperations::rename(this, item.url(), newUrl); + } + } + } +} + +void TreeViewSidebarPage::setUrl(const KUrl& url) +{ + if (!url.isValid() || (url == SidebarPage::url())) { + return; + } + + SidebarPage::setUrl(url); + if (m_dirLister != 0) { + m_setLeafVisible = true; + loadTree(url); + } +} + +void TreeViewSidebarPage::showEvent(QShowEvent* event) +{ + if (event->spontaneous()) { + SidebarPage::showEvent(event); + return; + } + + if (m_dirLister == 0) { + // Postpone the creating of the dir lister to the first show event. + // This assures that no performance and memory overhead is given when the TreeView is not + // used at all (see TreeViewSidebarPage::setUrl()). + m_dirLister = new KDirLister(); + m_dirLister->setDirOnlyMode(true); + m_dirLister->setAutoUpdate(true); + m_dirLister->setMainWindow(window()); + m_dirLister->setDelayedMimeTypes(true); + m_dirLister->setAutoErrorHandlingEnabled(false, this); + m_dirLister->setShowingDotFiles(FoldersPanelSettings::showHiddenFiles()); + + Q_ASSERT(m_dolphinModel == 0); + m_dolphinModel = new DolphinModel(this); + m_dolphinModel->setDirLister(m_dirLister); + m_dolphinModel->setDropsAllowed(DolphinModel::DropOnDirectory); + connect(m_dolphinModel, SIGNAL(expand(const QModelIndex&)), + this, SLOT(expandToDir(const QModelIndex&))); + + Q_ASSERT(m_proxyModel == 0); + m_proxyModel = new DolphinSortFilterProxyModel(this); + m_proxyModel->setSourceModel(m_dolphinModel); + + Q_ASSERT(m_treeView == 0); + m_treeView = new SidebarTreeView(this); + m_treeView->setModel(m_proxyModel); + m_proxyModel->setSorting(DolphinView::SortByName); + m_proxyModel->setSortOrder(Qt::AscendingOrder); + + new FolderExpander(m_treeView, m_proxyModel); + + connect(m_treeView, SIGNAL(clicked(const QModelIndex&)), + this, SLOT(updateActiveView(const QModelIndex&))); + connect(m_treeView, SIGNAL(urlsDropped(const QModelIndex&, QDropEvent*)), + this, SLOT(dropUrls(const QModelIndex&, QDropEvent*))); + connect(m_treeView, SIGNAL(pressed(const QModelIndex&)), + this, SLOT(updateMouseButtons())); + + QVBoxLayout* layout = new QVBoxLayout(this); + layout->setMargin(0); + layout->addWidget(m_treeView); + } + + loadTree(url()); + SidebarPage::showEvent(event); +} + +void TreeViewSidebarPage::contextMenuEvent(QContextMenuEvent* event) +{ + SidebarPage::contextMenuEvent(event); + + KFileItem item; + const QModelIndex index = m_treeView->indexAt(event->pos()); + if (index.isValid()) { + const QModelIndex dolphinModelIndex = m_proxyModel->mapToSource(index); + item = m_dolphinModel->itemForIndex(dolphinModelIndex); + emit changeSelection(KFileItemList()); + } + + TreeViewContextMenu contextMenu(this, item); + contextMenu.open(); +} + +void TreeViewSidebarPage::updateActiveView(const QModelIndex& index) +{ + const QModelIndex dirIndex = m_proxyModel->mapToSource(index); + const KFileItem item = m_dolphinModel->itemForIndex(dirIndex); + if (!item.isNull()) { + emit changeUrl(item.url(), m_mouseButtons); + } +} + +void TreeViewSidebarPage::dropUrls(const QModelIndex& index, QDropEvent* event) +{ + if (index.isValid()) { + const QModelIndex dirIndex = m_proxyModel->mapToSource(index); + KFileItem item = m_dolphinModel->itemForIndex(dirIndex); + Q_ASSERT(!item.isNull()); + if (item.isDir()) { + DragAndDropHelper::instance().dropUrls(item, item.url(), event, this); + } + } +} + +void TreeViewSidebarPage::expandToDir(const QModelIndex& index) +{ + m_treeView->setExpanded(index, true); + selectLeafDirectory(); + m_treeView->resizeColumnToContents(DolphinModel::Name); +} + +void TreeViewSidebarPage::scrollToLeaf() +{ + const QModelIndex dirIndex = m_dolphinModel->indexForUrl(m_leafDir); + const QModelIndex proxyIndex = m_proxyModel->mapFromSource(dirIndex); + if (proxyIndex.isValid()) { + m_treeView->scrollTo(proxyIndex); + } +} + +void TreeViewSidebarPage::updateMouseButtons() +{ + m_mouseButtons = QApplication::mouseButtons(); +} + +void TreeViewSidebarPage::loadTree(const KUrl& url) +{ + Q_ASSERT(m_dirLister != 0); + m_leafDir = url; + + KUrl baseUrl; + if (url.isLocalFile()) { + // use the root directory as base for local URLs (#150941) + baseUrl = QDir::rootPath(); + } else { + // clear the path for non-local URLs and use it as base + baseUrl = url; + baseUrl.setPath(QString('/')); + } + + if (m_dirLister->url() != baseUrl) { + m_dirLister->stop(); + m_dirLister->openUrl(baseUrl, KDirLister::Reload); + } + m_dolphinModel->expandToUrl(m_leafDir); +} + +void TreeViewSidebarPage::selectLeafDirectory() +{ + const QModelIndex dirIndex = m_dolphinModel->indexForUrl(m_leafDir); + const QModelIndex proxyIndex = m_proxyModel->mapFromSource(dirIndex); + if (!proxyIndex.isValid()) { + return; + } + + if (m_setLeafVisible) { + // Invoke m_treeView->scrollTo(proxyIndex) asynchronously by + // scrollToLeaf(). This assures that the scrolling is done after + // the horizontal scrollbar gets visible (otherwise the scrollbar + // might hide the leaf). + QTimer::singleShot(100, this, SLOT(scrollToLeaf())); + m_setLeafVisible = false; + } + + QItemSelectionModel* selModel = m_treeView->selectionModel(); + selModel->setCurrentIndex(proxyIndex, QItemSelectionModel::ClearAndSelect); +} + +#include "treeviewsidebarpage.moc" diff --git a/src/panels/folders/treeviewsidebarpage.h b/src/panels/folders/treeviewsidebarpage.h new file mode 100644 index 000000000..39f2323ad --- /dev/null +++ b/src/panels/folders/treeviewsidebarpage.h @@ -0,0 +1,135 @@ +/*************************************************************************** + * Copyright (C) 2006 by Peter Penz <[email protected]> * + * * + * 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 TREEVIEWSIDEBARPAGE_H +#define TREEVIEWSIDEBARPAGE_H + +#include <kurl.h> +#include <panels/sidebarpage.h> + +class KDirLister; +class DolphinModel; + +class DolphinSortFilterProxyModel; +class SidebarTreeView; +class QModelIndex; + +/** + * @brief Shows a tree view of the directories starting from + * the currently selected place. + * + * The tree view is always synchronized with the currently active view + * from the main window. + */ +class TreeViewSidebarPage : public SidebarPage +{ + Q_OBJECT + +public: + TreeViewSidebarPage(QWidget* parent = 0); + virtual ~TreeViewSidebarPage(); + + /** @see QWidget::sizeHint() */ + virtual QSize sizeHint() const; + + void setShowHiddenFiles(bool show); + bool showHiddenFiles() const; + + void rename(const KFileItem& item); + +signals: + /** + * Is emitted if the an URL change is requested. + */ + void changeUrl(const KUrl& url, Qt::MouseButtons buttons); + + /** + * This signal is emitted when the sidebar requests a change in the + * current selection. The file-management view recieving this signal is + * not required to select all listed files, limiting the selection to + * e.g. the current folder. The new selection will be reported via the + * setSelection slot. + */ + void changeSelection(const KFileItemList& selection); + +public slots: + /** + * Changes the current selection inside the tree to \a url. + */ + virtual void setUrl(const KUrl& url); + +protected: + /** @see QWidget::showEvent() */ + virtual void showEvent(QShowEvent* event); + + /** @see QWidget::contextMenuEvent() */ + virtual void contextMenuEvent(QContextMenuEvent* event); + +private slots: + /** + * Updates the active view to the URL + * which is given by the item with the index \a index. + */ + void updateActiveView(const QModelIndex& index); + + /** + * Is emitted if URLs have been dropped + * to the index \a index. + */ + void dropUrls(const QModelIndex& index, QDropEvent* event); + + /** + * Expands the treeview to show the directory + * specified by \a index. + */ + void expandToDir(const QModelIndex& index); + + /** + * Assures that the leaf folder gets visible. + */ + void scrollToLeaf(); + + void updateMouseButtons(); + +private: + /** + * Initializes the base URL of the tree and expands all + * directories until \a url. + * @param url URL of the leaf directory that should get expanded. + */ + void loadTree(const KUrl& url); + + /** + * Selects the current leaf directory m_leafDir and assures + * that the directory is visible if the leaf has been set by + * TreeViewSidebarPage::setUrl(). + */ + void selectLeafDirectory(); + +private: + bool m_setLeafVisible; + Qt::MouseButtons m_mouseButtons; + KDirLister* m_dirLister; + DolphinModel* m_dolphinModel; + DolphinSortFilterProxyModel* m_proxyModel; + SidebarTreeView* m_treeView; + KUrl m_leafDir; +}; + +#endif // TREEVIEWSIDEBARPAGE_H |
