1 | /* This file is part of the KDE project |
2 | Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org> |
3 | Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org> |
4 | Copyright (C) 2001 Anders Lund <anders.lund@lund.tdcadsl.dk> |
5 | Copyright (C) 2007 Mirko Stocker <me@misto.ch> |
6 | Copyright (C) 2009 Dominik Haumann <dhaumann kde org> |
7 | |
8 | This library is free software; you can redistribute it and/or |
9 | modify it under the terms of the GNU Library General Public |
10 | License version 2 as published by the Free Software Foundation. |
11 | |
12 | This library is distributed in the hope that it will be useful, |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | Library General Public License for more details. |
16 | |
17 | You should have received a copy of the GNU Library General Public License |
18 | along with this library; see the file COPYING.LIB. If not, write to |
19 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
20 | Boston, MA 02110-1301, USA. |
21 | */ |
22 | |
23 | //BEGIN Includes |
24 | #include "katefilebrowser.h" |
25 | #include "katefilebrowser.moc" |
26 | |
27 | #include "katebookmarkhandler.h" |
28 | |
29 | #include <ktexteditor/document.h> |
30 | #include <ktexteditor/view.h> |
31 | |
32 | #include <KActionCollection> |
33 | #include <KActionMenu> |
34 | #include <KConfigGroup> |
35 | #include <KDebug> |
36 | #include <KDirOperator> |
37 | #include <KFilePlacesModel> |
38 | #include <KHistoryComboBox> |
39 | #include <KLocale> |
40 | #include <KToolBar> |
41 | #include <KUrlNavigator> |
42 | #include <QAbstractItemView> |
43 | #include <QDir> |
44 | #include <QLabel> |
45 | #include <QLineEdit> |
46 | #include <QToolButton> |
47 | #include <KMessageBox> |
48 | |
49 | #include <kdeversion.h> |
50 | |
51 | //END Includes |
52 | |
53 | |
54 | KateFileBrowser::KateFileBrowser(Kate::MainWindow *mainWindow, |
55 | QWidget * parent, const char * name) |
56 | : KVBox (parent) |
57 | , m_mainWindow(mainWindow) |
58 | { |
59 | setObjectName(name); |
60 | |
61 | m_toolbar = new KToolBar(this); |
62 | m_toolbar->setMovable(false); |
63 | m_toolbar->setToolButtonStyle(Qt::ToolButtonIconOnly); |
64 | m_toolbar->setContextMenuPolicy(Qt::NoContextMenu); |
65 | |
66 | // includes some actions, but not hooked into the shortcut dialog atm |
67 | m_actionCollection = new KActionCollection(this); |
68 | m_actionCollection->addAssociatedWidget(this); |
69 | |
70 | KFilePlacesModel* model = new KFilePlacesModel(this); |
71 | m_urlNavigator = new KUrlNavigator(model, KUrl(QDir::homePath()), this); |
72 | connect(m_urlNavigator, SIGNAL(urlChanged(KUrl)), SLOT(updateDirOperator(KUrl))); |
73 | |
74 | m_dirOperator = new KDirOperator(KUrl(), this); |
75 | m_dirOperator->setView(KFile::/* Simple */Detail); |
76 | m_dirOperator->view()->setSelectionMode(QAbstractItemView::ExtendedSelection); |
77 | m_dirOperator->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding)); |
78 | |
79 | // Mime filter for the KDirOperator |
80 | QStringList filter; |
81 | filter << "text/plain" << "text/html" << "inode/directory" ; |
82 | m_dirOperator->setNewFileMenuSupportedMimeTypes(filter); |
83 | |
84 | setFocusProxy(m_dirOperator); |
85 | connect(m_dirOperator, SIGNAL(viewChanged(QAbstractItemView*)), |
86 | this, SLOT(selectorViewChanged(QAbstractItemView*))); |
87 | connect(m_urlNavigator, SIGNAL(returnPressed()), |
88 | m_dirOperator, SLOT(setFocus())); |
89 | // now all actions exist in dir operator and we can use them in the toolbar |
90 | setupActions(); |
91 | setupToolbar(); |
92 | |
93 | KHBox* filterBox = new KHBox(this); |
94 | |
95 | QLabel* filterLabel = new QLabel(i18n("Filter:" ), filterBox); |
96 | m_filter = new KHistoryComboBox(true, filterBox); |
97 | filterLabel->setBuddy(m_filter); |
98 | m_filter->setMaxCount(10); |
99 | m_filter->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); |
100 | |
101 | connect(m_filter, SIGNAL(editTextChanged(QString)), |
102 | SLOT(slotFilterChange(QString))); |
103 | connect(m_filter, SIGNAL(returnPressed(QString)), |
104 | m_filter, SLOT(addToHistory(QString))); |
105 | connect(m_filter, SIGNAL(returnPressed(QString)), |
106 | m_dirOperator, SLOT(setFocus())); |
107 | |
108 | connect(m_dirOperator, SIGNAL(urlEntered(KUrl)), |
109 | this, SLOT(updateUrlNavigator(KUrl))); |
110 | |
111 | // Connect the bookmark handler |
112 | connect(m_bookmarkHandler, SIGNAL(openUrl(QString)), |
113 | this, SLOT(setDir(QString))); |
114 | |
115 | m_filter->setWhatsThis(i18n("Enter a name filter to limit which files are displayed." )); |
116 | |
117 | connect(m_dirOperator, SIGNAL(fileSelected(KFileItem)), this, SLOT(fileSelected(KFileItem))); |
118 | connect(m_mainWindow, SIGNAL(viewChanged()), this, SLOT(autoSyncFolder())); |
119 | } |
120 | |
121 | KateFileBrowser::~KateFileBrowser() |
122 | { |
123 | } |
124 | //END Constroctor/Destrctor |
125 | |
126 | //BEGIN Public Methods |
127 | void KateFileBrowser::setupToolbar() |
128 | { |
129 | KConfigGroup config(KGlobal::config(), "filebrowser" ); |
130 | QStringList actions = config.readEntry( "toolbar actions" , QStringList() ); |
131 | if ( actions.isEmpty() ) // default toolbar |
132 | actions << "back" << "forward" << "bookmarks" << "sync_dir" << "configure" ; |
133 | |
134 | // remove all actions from the toolbar (there should be none) |
135 | m_toolbar->clear(); |
136 | |
137 | // now add all actions to the toolbar |
138 | foreach (const QString& it, actions) |
139 | { |
140 | QAction *ac = 0; |
141 | if (it.isEmpty()) continue; |
142 | if (it == "bookmarks" || it == "sync_dir" || it == "configure" ) |
143 | ac = actionCollection()->action(it); |
144 | else |
145 | ac = m_dirOperator->actionCollection()->action(it); |
146 | |
147 | if (ac) |
148 | m_toolbar->addAction(ac); |
149 | } |
150 | } |
151 | |
152 | void KateFileBrowser::readSessionConfig(KConfigBase *config, const QString & name) |
153 | { |
154 | KConfigGroup cgDir(config, name + ":dir" ); |
155 | m_dirOperator->readConfig(cgDir); |
156 | m_dirOperator->setView(KFile::Default); |
157 | |
158 | KConfigGroup cg(config, name); |
159 | m_urlNavigator->setLocationUrl(cg.readPathEntry("location" , QDir::homePath())); |
160 | setDir(cg.readPathEntry("location" , QDir::homePath())); |
161 | m_autoSyncFolder->setChecked(cg.readEntry("auto sync folder" , false)); |
162 | m_filter->setHistoryItems(cg.readEntry("filter history" , QStringList()), true); |
163 | } |
164 | |
165 | void KateFileBrowser::writeSessionConfig(KConfigBase *config, const QString & name) |
166 | { |
167 | KConfigGroup cgDir(config, name + ":dir" ); |
168 | m_dirOperator->writeConfig(cgDir); |
169 | |
170 | KConfigGroup cg = KConfigGroup(config, name); |
171 | cg.writePathEntry("location" , m_urlNavigator->locationUrl().url()); |
172 | cg.writeEntry("auto sync folder" , m_autoSyncFolder->isChecked()); |
173 | cg.writeEntry("filter history" , m_filter->historyItems()); |
174 | } |
175 | |
176 | //END Public Methods |
177 | |
178 | //BEGIN Public Slots |
179 | |
180 | void KateFileBrowser::slotFilterChange(const QString & nf) |
181 | { |
182 | QString f = nf.trimmed(); |
183 | const bool empty = f.isEmpty() || f == "*" ; |
184 | |
185 | if (empty) { |
186 | m_dirOperator->clearFilter(); |
187 | } else { |
188 | m_dirOperator->setNameFilter(f); |
189 | } |
190 | |
191 | m_dirOperator->updateDir(); |
192 | } |
193 | |
194 | bool kateFileSelectorIsReadable (const KUrl& url) |
195 | { |
196 | if (!url.isLocalFile()) |
197 | return true; // what else can we say? |
198 | |
199 | QDir dir(url.toLocalFile()); |
200 | return dir.exists (); |
201 | } |
202 | |
203 | void KateFileBrowser::setDir(KUrl u) |
204 | { |
205 | KUrl newurl; |
206 | |
207 | if (!u.isValid()) |
208 | newurl.setPath(QDir::homePath()); |
209 | else |
210 | newurl = u; |
211 | |
212 | QString pathstr = newurl.path(KUrl::AddTrailingSlash); |
213 | newurl.setPath(pathstr); |
214 | |
215 | if (!kateFileSelectorIsReadable (newurl)) |
216 | newurl.cd(QString::fromLatin1(".." )); |
217 | |
218 | if (!kateFileSelectorIsReadable (newurl)) |
219 | newurl.setPath(QDir::homePath()); |
220 | |
221 | m_dirOperator->setUrl(newurl, true); |
222 | } |
223 | |
224 | //END Public Slots |
225 | |
226 | //BEGIN Private Slots |
227 | |
228 | void KateFileBrowser::fileSelected(const KFileItem & /*file*/) |
229 | { |
230 | openSelectedFiles(); |
231 | } |
232 | |
233 | void KateFileBrowser::openSelectedFiles() |
234 | { |
235 | const KFileItemList list = m_dirOperator->selectedItems(); |
236 | |
237 | if (list.count()>20) { |
238 | if (KMessageBox::questionYesNo(this,i18np("You are trying to open 1 file, are you sure?" , "You are trying to open %1 files, are you sure?" , list.count())) |
239 | == KMessageBox::No) return; |
240 | } |
241 | |
242 | foreach (const KFileItem& item, list) |
243 | { |
244 | m_mainWindow->openUrl(item.url()); |
245 | } |
246 | |
247 | m_dirOperator->view()->selectionModel()->clear(); |
248 | } |
249 | |
250 | |
251 | |
252 | |
253 | void KateFileBrowser::updateDirOperator(const KUrl& u) |
254 | { |
255 | m_dirOperator->setUrl(u, true); |
256 | } |
257 | |
258 | void KateFileBrowser::updateUrlNavigator(const KUrl& u) |
259 | { |
260 | m_urlNavigator->setLocationUrl(u); |
261 | } |
262 | |
263 | void KateFileBrowser::setActiveDocumentDir() |
264 | { |
265 | // kDebug(13001)<<"KateFileBrowser::setActiveDocumentDir()"; |
266 | KUrl u = activeDocumentUrl(); |
267 | // kDebug(13001)<<"URL: "<<u.pathOrUrl(); |
268 | if (!u.isEmpty()) |
269 | setDir(u.upUrl()); |
270 | // kDebug(13001)<<"... setActiveDocumentDir() DONE!"; |
271 | } |
272 | |
273 | void KateFileBrowser::autoSyncFolder() |
274 | { |
275 | if (m_autoSyncFolder->isChecked()) { |
276 | setActiveDocumentDir(); |
277 | } |
278 | } |
279 | |
280 | |
281 | void KateFileBrowser::selectorViewChanged(QAbstractItemView * newView) |
282 | { |
283 | newView->setSelectionMode(QAbstractItemView::ExtendedSelection); |
284 | } |
285 | |
286 | //END Private Slots |
287 | |
288 | //BEGIN Protected |
289 | |
290 | KUrl KateFileBrowser::activeDocumentUrl() |
291 | { |
292 | KTextEditor::View *v = m_mainWindow->activeView(); |
293 | if (v) |
294 | return v->document()->url(); |
295 | return KUrl(); |
296 | } |
297 | |
298 | void KateFileBrowser::setupActions() |
299 | { |
300 | // bookmarks action! |
301 | KActionMenu *acmBookmarks = new KActionMenu(KIcon("bookmarks" ), i18n("Bookmarks" ), this); |
302 | acmBookmarks->setDelayed(false); |
303 | m_bookmarkHandler = new KateBookmarkHandler(this, acmBookmarks->menu()); |
304 | acmBookmarks->setShortcutContext(Qt::WidgetWithChildrenShortcut); |
305 | |
306 | // action for synchronizing the dir operator with the current document path |
307 | KAction* syncFolder = new KAction(this); |
308 | syncFolder->setShortcutContext(Qt::WidgetWithChildrenShortcut); |
309 | syncFolder->setText(i18n("Current Document Folder" )); |
310 | syncFolder->setIcon(KIcon("system-switch-user" )); |
311 | connect(syncFolder, SIGNAL(triggered()), this, SLOT(setActiveDocumentDir())); |
312 | |
313 | m_actionCollection->addAction("sync_dir" , syncFolder); |
314 | m_actionCollection->addAction("bookmarks" , acmBookmarks); |
315 | |
316 | // section for settings menu |
317 | KActionMenu * = new KActionMenu(KIcon("configure" ), i18n("Options" ), this); |
318 | optionsMenu->setDelayed(false); |
319 | optionsMenu->addAction(m_dirOperator->actionCollection()->action("short view" )); |
320 | optionsMenu->addAction(m_dirOperator->actionCollection()->action("detailed view" )); |
321 | optionsMenu->addAction(m_dirOperator->actionCollection()->action("tree view" )); |
322 | optionsMenu->addAction(m_dirOperator->actionCollection()->action("detailed tree view" )); |
323 | optionsMenu->addSeparator(); |
324 | optionsMenu->addAction(m_dirOperator->actionCollection()->action("show hidden" )); |
325 | |
326 | // action for synchronising the dir operator with the current document path |
327 | m_autoSyncFolder = new KAction(this); |
328 | m_autoSyncFolder->setCheckable(true); |
329 | m_autoSyncFolder->setText(i18n("Automatically synchronize with current document" )); |
330 | m_autoSyncFolder->setIcon(KIcon("system-switch-user" )); |
331 | connect(m_autoSyncFolder, SIGNAL(triggered()), this, SLOT(autoSyncFolder())); |
332 | optionsMenu->addAction(m_autoSyncFolder); |
333 | |
334 | m_actionCollection->addAction("configure" , optionsMenu); |
335 | |
336 | // |
337 | // Remove all shortcuts due to shortcut clashes (e.g. F5: reload, Ctrl+B: bookmark) |
338 | // BUGS: #188954, #236368 |
339 | // |
340 | foreach (QAction* a, m_actionCollection->actions()) { |
341 | a->setShortcut(QKeySequence()); |
342 | } |
343 | foreach (QAction* a, m_dirOperator->actionCollection()->actions()) { |
344 | a->setShortcut(QKeySequence()); |
345 | } |
346 | } |
347 | //END Protected |
348 | |
349 | // kate: space-indent on; indent-width 2; replace-tabs on; |
350 | |