]> cloud.milkyroute.net Git - dolphin.git/blob - src/treeviewsidebarpage.cpp
A small step in trying to make urlnavigator useable in kdelibs for the file dialog:
[dolphin.git] / src / treeviewsidebarpage.cpp
1 /***************************************************************************
2 * Copyright (C) 2006 by Peter Penz <peter.penz@gmx.at> *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
18 ***************************************************************************/
19
20 #include "treeviewsidebarpage.h"
21
22 #include "bookmarkselector.h"
23 #include "dolphinmainwindow.h"
24 #include "dolphinsortfilterproxymodel.h"
25 #include "dolphinview.h"
26 #include "sidebartreeview.h"
27 #include "treeviewcontextmenu.h"
28
29 #include <kdirlister.h>
30 #include <kdirmodel.h>
31 #include <kfileitem.h>
32
33 #include <QHeaderView>
34 #include <QItemSelectionModel>
35 #include <QTreeView>
36 #include <QVBoxLayout>
37 #include "dolphinsettings.h"
38
39 // TODO: currently when using a proxy model the strange effect occurs
40 // that items get duplicated. Activate the following define to have the proxy
41 // model:
42 //#define USE_PROXY_MODEL
43
44 TreeViewSidebarPage::TreeViewSidebarPage(QWidget* parent) :
45 SidebarPage(parent),
46 m_dirLister(0),
47 m_dirModel(0),
48 m_proxyModel(0),
49 m_treeView(0)
50 {
51 m_dirLister = new KDirLister();
52 m_dirLister->setDirOnlyMode(true);
53 m_dirLister->setAutoUpdate(true);
54 m_dirLister->setMainWindow(this);
55 m_dirLister->setDelayedMimeTypes(true);
56 m_dirLister->setAutoErrorHandlingEnabled(false, this);
57
58 m_dirModel = new KDirModel();
59 m_dirModel->setDirLister(m_dirLister);
60 m_dirModel->setDropsAllowed(KDirModel::DropOnDirectory);
61
62
63 #if defined(USE_PROXY_MODEL)
64 m_proxyModel = new DolphinSortFilterProxyModel(this);
65 m_proxyModel->setSourceModel(m_dirModel);
66
67 m_treeView = new SidebarTreeView(this);
68 m_treeView->setModel(m_proxyModel);
69
70 m_proxyModel->setSorting(DolphinView::SortByName);
71 m_proxyModel->setSortOrder(Qt::Ascending);
72 #else
73 m_treeView = new SidebarTreeView(this);
74 m_treeView->setModel(m_dirModel);
75 #endif
76
77 connect(m_treeView, SIGNAL(clicked(const QModelIndex&)),
78 this, SLOT(updateActiveView(const QModelIndex&)));
79 connect(m_treeView, SIGNAL(urlsDropped(const KUrl::List&, const QModelIndex&)),
80 this, SLOT(dropUrls(const KUrl::List&, const QModelIndex&)));
81
82 QVBoxLayout* layout = new QVBoxLayout(this);
83 layout->setMargin(0);
84 layout->addWidget(m_treeView);
85 }
86
87 TreeViewSidebarPage::~TreeViewSidebarPage()
88 {
89 delete m_dirLister;
90 m_dirLister = 0;
91 }
92
93 void TreeViewSidebarPage::setUrl(const KUrl& url)
94 {
95 if (!url.isValid() || (url == m_url)) {
96 return;
97 }
98
99 m_url = url;
100
101 // adjust the root of the tree to the base bookmark
102 const KUrl baseUrl = BookmarkSelector::baseBookmark(DolphinSettings::instance().bookmarkManager(), url).url();
103 if (m_dirLister->url() != baseUrl) {
104 m_dirLister->stop();
105 m_dirLister->openUrl(baseUrl);
106 }
107
108 // select the folder which contains the given URL
109 QItemSelectionModel* selModel = m_treeView->selectionModel();
110 selModel->clearSelection();
111
112 const QModelIndex index = m_dirModel->indexForUrl(url);
113 if (index.isValid()) {
114 #if defined(USE_PROXY_MODEL)
115 // the item with the given URL is already part of the model
116 const QModelIndex proxyIndex = m_proxyModel->mapFromSource(index);
117 m_treeView->scrollTo(proxyIndex);
118 selModel->setCurrentIndex(proxyIndex, QItemSelectionModel::Select);
119 #else
120 m_treeView->scrollTo(index);
121 selModel->setCurrentIndex(index, QItemSelectionModel::Select);
122 #endif
123 }
124 else {
125 // The item with the given URL is not loaded by the model yet. Iterate
126 // backward to the base URL and trigger the loading of the items for
127 // each hierarchy level.
128 connect(m_dirLister, SIGNAL(completed()),
129 this, SLOT(expandSelectionParent()));
130
131 KUrl parentUrl = url.upUrl();
132 while (!parentUrl.isParentOf(baseUrl)) {
133 m_dirLister->openUrl(parentUrl, true, false);
134 parentUrl = parentUrl.upUrl();
135 }
136 }
137
138 }
139
140 void TreeViewSidebarPage::showEvent(QShowEvent* event)
141 {
142 SidebarPage::showEvent(event);
143 }
144
145 void TreeViewSidebarPage::contextMenuEvent(QContextMenuEvent* event)
146 {
147 SidebarPage::contextMenuEvent(event);
148
149 const QModelIndex index = m_treeView->indexAt(event->pos());
150 if (!index.isValid()) {
151 // only open a context menu above a directory item
152 return;
153 }
154
155 #if defined(USE_PROXY_MODEL)
156 const QModelIndex dirModelIndex = m_proxyModel->mapToSource(index);
157 KFileItem* item = m_dirModel->itemForIndex(dirModelIndex);
158 #else
159 KFileItem* item = m_dirModel->itemForIndex(index);
160 #endif
161
162 emit changeSelection(KFileItemList());
163 TreeViewContextMenu contextMenu(this, item);
164 contextMenu.open();
165 }
166
167 void TreeViewSidebarPage::expandSelectionParent()
168 {
169 disconnect(m_dirLister, SIGNAL(completed()),
170 this, SLOT(expandSelectionParent()));
171
172 // expand the parent folder of the selected item
173 KUrl parentUrl = m_url.upUrl();
174 if (!m_dirLister->url().isParentOf(parentUrl)) {
175 return;
176 }
177
178 QModelIndex index = m_dirModel->indexForUrl(parentUrl);
179 if (index.isValid()) {
180 #if defined(USE_PROXY_MODEL)
181 QModelIndex proxyIndex = m_proxyModel->mapFromSource(index);
182 m_treeView->setExpanded(proxyIndex, true);
183 #else
184 m_treeView->setExpanded(index, true);
185 #endif
186
187 // select the item and assure that the item is visible
188 index = m_dirModel->indexForUrl(m_url);
189 if (index.isValid()) {
190 #if defined(USE_PROXY_MODEL)
191 proxyIndex = m_proxyModel->mapFromSource(index);
192 m_treeView->scrollTo(proxyIndex);
193
194 QItemSelectionModel* selModel = m_treeView->selectionModel();
195 selModel->setCurrentIndex(proxyIndex, QItemSelectionModel::Select);
196 #else
197 m_treeView->scrollTo(index);
198
199 QItemSelectionModel* selModel = m_treeView->selectionModel();
200 selModel->setCurrentIndex(index, QItemSelectionModel::Select);
201 #endif
202 }
203 }
204 }
205
206 void TreeViewSidebarPage::updateActiveView(const QModelIndex& index)
207 {
208 #if defined(USE_PROXY_MODEL)
209 const QModelIndex& dirIndex = m_proxyModel->mapToSource(index);
210 const KFileItem* item = m_dirModel->itemForIndex(dirIndex);
211 #else
212 const KFileItem* item = m_dirModel->itemForIndex(index);
213 #endif
214 if (item != 0) {
215 const KUrl& url = item->url();
216 emit changeUrl(url);
217 }
218 }
219
220 void TreeViewSidebarPage::dropUrls(const KUrl::List& urls,
221 const QModelIndex& index)
222 {
223 if (index.isValid()) {
224 #if defined(USE_PROXY_MODEL)
225 const QModelIndex& dirIndex = m_proxyModel->mapToSource(index);
226 KFileItem* item = m_dirModel->itemForIndex(dirIndex);
227 #else
228 KFileItem* item = m_dirModel->itemForIndex(index);
229 #endif
230 Q_ASSERT(item != 0);
231 if (item->isDir()) {
232 emit urlsDropped(urls, item->url());
233 }
234 }
235 }
236
237 #include "treeviewsidebarpage.moc"