1 | /* |
2 | This file is part of the KDE project |
3 | |
4 | Copyright (C) 2007 Tobias Koenig <tokoe@kde.org> |
5 | |
6 | This library is free software; you can redistribute it and/or |
7 | modify it under the terms of the GNU Library General Public |
8 | License as published by the Free Software Foundation; either |
9 | version 2 of the License, or (at your option) any later version. |
10 | |
11 | This library is distributed in the hope that it will be useful, |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | Library General Public License for more details. |
15 | |
16 | You should have received a copy of the GNU Library General Public License |
17 | along with this library; see the file COPYING.LIB. If not, write to |
18 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
19 | Boston, MA 02110-1301, USA. |
20 | */ |
21 | |
22 | #include "kfiletreeview.h" |
23 | |
24 | #include <QtCore/QDir> |
25 | #include <QtGui/QContextMenuEvent> |
26 | #include <QtGui/QMenu> |
27 | |
28 | #include <kdirlister.h> |
29 | #include <kdirmodel.h> |
30 | #include <kdirsortfilterproxymodel.h> |
31 | #include <kfileitemdelegate.h> |
32 | #include <klocale.h> |
33 | #include <ktoggleaction.h> |
34 | #include <kurl.h> |
35 | |
36 | class KFileTreeView::Private |
37 | { |
38 | public: |
39 | Private(KFileTreeView *parent) |
40 | : q(parent) |
41 | { |
42 | } |
43 | |
44 | KUrl urlForProxyIndex(const QModelIndex &index) const; |
45 | |
46 | void _k_activated(const QModelIndex&); |
47 | void _k_currentChanged(const QModelIndex&, const QModelIndex&); |
48 | void _k_expanded(const QModelIndex&); |
49 | |
50 | KFileTreeView *q; |
51 | KDirModel *mSourceModel; |
52 | KDirSortFilterProxyModel *mProxyModel; |
53 | }; |
54 | |
55 | KUrl KFileTreeView::Private::urlForProxyIndex(const QModelIndex &index) const |
56 | { |
57 | const KFileItem item = mSourceModel->itemForIndex(mProxyModel->mapToSource(index)); |
58 | |
59 | return !item.isNull() ? item.url() : KUrl(); |
60 | } |
61 | |
62 | void KFileTreeView::Private::_k_activated(const QModelIndex &index) |
63 | { |
64 | const KUrl url = urlForProxyIndex(index); |
65 | if (url.isValid()) |
66 | emit q->activated(url); |
67 | } |
68 | |
69 | void KFileTreeView::Private::_k_currentChanged(const QModelIndex ¤tIndex, const QModelIndex&) |
70 | { |
71 | const KUrl url = urlForProxyIndex(currentIndex); |
72 | if (url.isValid()) |
73 | emit q->currentChanged(url); |
74 | } |
75 | |
76 | void KFileTreeView::Private::_k_expanded(const QModelIndex &baseIndex) |
77 | { |
78 | QModelIndex index = mProxyModel->mapFromSource(baseIndex); |
79 | |
80 | q->selectionModel()->clearSelection(); |
81 | q->selectionModel()->setCurrentIndex(index, QItemSelectionModel::SelectCurrent); |
82 | q->scrollTo(index); |
83 | } |
84 | |
85 | KFileTreeView::KFileTreeView(QWidget *parent) |
86 | : QTreeView(parent), d(new Private(this)) |
87 | { |
88 | d->mSourceModel = new KDirModel(this); |
89 | d->mProxyModel = new KDirSortFilterProxyModel(this); |
90 | d->mProxyModel->setSourceModel(d->mSourceModel); |
91 | |
92 | setModel(d->mProxyModel); |
93 | setItemDelegate(new KFileItemDelegate(this)); |
94 | setLayoutDirection(Qt::LeftToRight); |
95 | |
96 | d->mSourceModel->dirLister()->openUrl(KUrl(QDir::root().absolutePath()), KDirLister::Keep); |
97 | |
98 | connect(this, SIGNAL(activated(QModelIndex)), |
99 | this, SLOT(_k_activated(QModelIndex))); |
100 | connect(selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), |
101 | this, SLOT(_k_currentChanged(QModelIndex,QModelIndex))); |
102 | |
103 | connect(d->mSourceModel, SIGNAL(expand(QModelIndex)), |
104 | this, SLOT(_k_expanded(QModelIndex))); |
105 | } |
106 | |
107 | KFileTreeView::~KFileTreeView() |
108 | { |
109 | delete d; |
110 | } |
111 | |
112 | KUrl KFileTreeView::currentUrl() const |
113 | { |
114 | return d->urlForProxyIndex(currentIndex()); |
115 | } |
116 | |
117 | KUrl KFileTreeView::selectedUrl() const |
118 | { |
119 | if (!selectionModel()->hasSelection()) |
120 | return KUrl(); |
121 | |
122 | const QItemSelection selection = selectionModel()->selection(); |
123 | const QModelIndex firstIndex = selection.indexes().first(); |
124 | |
125 | return d->urlForProxyIndex(firstIndex); |
126 | } |
127 | |
128 | KUrl::List KFileTreeView::selectedUrls() const |
129 | { |
130 | KUrl::List urls; |
131 | |
132 | if (!selectionModel()->hasSelection()) |
133 | return urls; |
134 | |
135 | const QModelIndexList indexes = selectionModel()->selection().indexes(); |
136 | foreach (const QModelIndex &index, indexes) { |
137 | const KUrl url = d->urlForProxyIndex(index); |
138 | if (url.isValid()) |
139 | urls.append(url); |
140 | } |
141 | |
142 | return urls; |
143 | } |
144 | |
145 | KUrl KFileTreeView::rootUrl() const |
146 | { |
147 | return d->mSourceModel->dirLister()->url(); |
148 | } |
149 | |
150 | void KFileTreeView::setDirOnlyMode(bool enabled) |
151 | { |
152 | d->mSourceModel->dirLister()->setDirOnlyMode(enabled); |
153 | d->mSourceModel->dirLister()->openUrl(d->mSourceModel->dirLister()->url()); |
154 | } |
155 | |
156 | void KFileTreeView::setShowHiddenFiles(bool enabled) |
157 | { |
158 | KUrl url = currentUrl(); |
159 | d->mSourceModel->dirLister()->setShowingDotFiles(enabled); |
160 | d->mSourceModel->dirLister()->openUrl(d->mSourceModel->dirLister()->url()); |
161 | setCurrentUrl(url); |
162 | } |
163 | |
164 | void KFileTreeView::setCurrentUrl(const KUrl &url) |
165 | { |
166 | QModelIndex baseIndex = d->mSourceModel->indexForUrl(url); |
167 | |
168 | if (!baseIndex.isValid()) { |
169 | d->mSourceModel->expandToUrl(url); |
170 | return; |
171 | } |
172 | |
173 | QModelIndex proxyIndex = d->mProxyModel->mapFromSource(baseIndex); |
174 | selectionModel()->clearSelection(); |
175 | selectionModel()->setCurrentIndex(proxyIndex, QItemSelectionModel::SelectCurrent); |
176 | scrollTo(proxyIndex); |
177 | } |
178 | |
179 | void KFileTreeView::setRootUrl(const KUrl &url) |
180 | { |
181 | d->mSourceModel->dirLister()->openUrl(url); |
182 | } |
183 | |
184 | void KFileTreeView::(QContextMenuEvent *event) |
185 | { |
186 | QMenu ; |
187 | KToggleAction *showHiddenAction = new KToggleAction(i18n("Show Hidden Folders" ), &menu); |
188 | showHiddenAction->setChecked(d->mSourceModel->dirLister()->showingDotFiles()); |
189 | connect(showHiddenAction, SIGNAL(toggled(bool)), this, SLOT(setShowHiddenFiles(bool))); |
190 | |
191 | menu.addAction(showHiddenAction); |
192 | menu.exec(event->globalPos()); |
193 | } |
194 | |
195 | bool KFileTreeView::showHiddenFiles() const |
196 | { |
197 | return d->mSourceModel->dirLister()->showingDotFiles(); |
198 | } |
199 | |
200 | QSize KFileTreeView::sizeHint() const |
201 | { |
202 | // This size makes KDirSelectDialog pop up just under 800x600 by default :-) |
203 | return QSize(680, 500); |
204 | } |
205 | |
206 | #include "kfiletreeview.moc" |
207 | |