1 | /*************************************************************************** |
2 | * Copyright (C) 2007 by Peter Penz <peter.penz19@gmail.com> * |
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 "dolphinviewcontainer.h" |
21 | #include <KProtocolManager> |
22 | |
23 | #include <QApplication> |
24 | #include <QKeyEvent> |
25 | #include <QItemSelection> |
26 | #include <QBoxLayout> |
27 | #include <QTimer> |
28 | #include <QScrollBar> |
29 | |
30 | #include <KDesktopFile> |
31 | #include <KFileItemDelegate> |
32 | #include <KFileItemActions> |
33 | #include <KFilePlacesModel> |
34 | #include <KLocale> |
35 | #include <KIconEffect> |
36 | #include <KIO/NetAccess> |
37 | #include <KIO/PreviewJob> |
38 | #include <KMessageWidget> |
39 | #include <KNewFileMenu> |
40 | #include <konqmimedata.h> |
41 | #include <konq_operations.h> |
42 | #include <KShell> |
43 | #include <KUrl> |
44 | #include <KUrlComboBox> |
45 | #include <KUrlNavigator> |
46 | #include <KRun> |
47 | |
48 | #ifdef KActivities_FOUND |
49 | #include <KActivities/ResourceInstance> |
50 | #endif |
51 | |
52 | #include "dolphin_generalsettings.h" |
53 | #include "filterbar/filterbar.h" |
54 | #include "search/dolphinsearchbox.h" |
55 | #include "statusbar/dolphinstatusbar.h" |
56 | #include "views/draganddrophelper.h" |
57 | #include "views/viewmodecontroller.h" |
58 | #include "views/viewproperties.h" |
59 | |
60 | DolphinViewContainer::DolphinViewContainer(const KUrl& url, QWidget* parent) : |
61 | QWidget(parent), |
62 | m_topLayout(0), |
63 | m_urlNavigator(0), |
64 | m_searchBox(0), |
65 | m_messageWidget(0), |
66 | m_view(0), |
67 | m_filterBar(0), |
68 | m_statusBar(0), |
69 | m_statusBarTimer(0), |
70 | m_statusBarTimestamp(), |
71 | m_autoGrabFocus(true), |
72 | m_dropDestination(), |
73 | m_dropEvent(0) |
74 | #ifdef KActivities_FOUND |
75 | , m_activityResourceInstance(0) |
76 | #endif |
77 | { |
78 | hide(); |
79 | |
80 | m_topLayout = new QVBoxLayout(this); |
81 | m_topLayout->setSpacing(0); |
82 | m_topLayout->setMargin(0); |
83 | |
84 | m_urlNavigator = new KUrlNavigator(new KFilePlacesModel(this), url, this); |
85 | connect(m_urlNavigator, SIGNAL(urlsDropped(KUrl,QDropEvent*)), |
86 | this, SLOT(dropUrls(KUrl,QDropEvent*))); |
87 | connect(m_urlNavigator, SIGNAL(activated()), |
88 | this, SLOT(activate())); |
89 | connect(m_urlNavigator->editor(), SIGNAL(completionModeChanged(KGlobalSettings::Completion)), |
90 | this, SLOT(saveUrlCompletionMode(KGlobalSettings::Completion))); |
91 | |
92 | const GeneralSettings* settings = GeneralSettings::self(); |
93 | m_urlNavigator->setUrlEditable(settings->editableUrl()); |
94 | m_urlNavigator->setShowFullPath(settings->showFullPath()); |
95 | m_urlNavigator->setHomeUrl(KUrl(settings->homeUrl())); |
96 | KUrlComboBox* editor = m_urlNavigator->editor(); |
97 | editor->setCompletionMode(KGlobalSettings::Completion(settings->urlCompletionMode())); |
98 | |
99 | m_searchBox = new DolphinSearchBox(this); |
100 | m_searchBox->hide(); |
101 | connect(m_searchBox, SIGNAL(activated()), this, SLOT(activate())); |
102 | connect(m_searchBox, SIGNAL(closeRequest()), this, SLOT(closeSearchBox())); |
103 | connect(m_searchBox, SIGNAL(searchRequest()), this, SLOT(startSearching())); |
104 | connect(m_searchBox, SIGNAL(returnPressed(QString)), this, SLOT(requestFocus())); |
105 | |
106 | m_messageWidget = new KMessageWidget(this); |
107 | m_messageWidget->setCloseButtonVisible(true); |
108 | m_messageWidget->hide(); |
109 | |
110 | m_view = new DolphinView(url, this); |
111 | connect(m_view, SIGNAL(urlChanged(KUrl)), m_urlNavigator, SLOT(setUrl(KUrl))); |
112 | connect(m_view, SIGNAL(urlChanged(KUrl)), m_messageWidget, SLOT(hide())); |
113 | connect(m_view, SIGNAL(writeStateChanged(bool)), this, SIGNAL(writeStateChanged(bool))); |
114 | connect(m_view, SIGNAL(requestItemInfo(KFileItem)), this, SLOT(showItemInfo(KFileItem))); |
115 | connect(m_view, SIGNAL(itemActivated(KFileItem)), this, SLOT(slotItemActivated(KFileItem))); |
116 | connect(m_view, SIGNAL(itemsActivated(KFileItemList)), this, SLOT(slotItemsActivated(KFileItemList))); |
117 | connect(m_view, SIGNAL(redirection(KUrl,KUrl)), this, SLOT(redirect(KUrl,KUrl))); |
118 | connect(m_view, SIGNAL(directoryLoadingStarted()), this, SLOT(slotDirectoryLoadingStarted())); |
119 | connect(m_view, SIGNAL(directoryLoadingCompleted()), this, SLOT(slotDirectoryLoadingCompleted())); |
120 | connect(m_view, SIGNAL(directoryLoadingCanceled()), this, SLOT(slotDirectoryLoadingCanceled())); |
121 | connect(m_view, SIGNAL(itemCountChanged()), this, SLOT(delayedStatusBarUpdate())); |
122 | connect(m_view, SIGNAL(directoryLoadingProgress(int)), this, SLOT(updateDirectoryLoadingProgress(int))); |
123 | connect(m_view, SIGNAL(directorySortingProgress(int)), this, SLOT(updateDirectorySortingProgress(int))); |
124 | connect(m_view, SIGNAL(selectionChanged(KFileItemList)), this, SLOT(delayedStatusBarUpdate())); |
125 | connect(m_view, SIGNAL(urlAboutToBeChanged(KUrl)), this, SLOT(slotViewUrlAboutToBeChanged(KUrl))); |
126 | connect(m_view, SIGNAL(errorMessage(QString)), this, SLOT(showErrorMessage(QString))); |
127 | connect(m_view, SIGNAL(urlIsFileError(KUrl)), this, SLOT(slotUrlIsFileError(KUrl))); |
128 | connect(m_view, SIGNAL(activated()), this, SLOT(activate())); |
129 | |
130 | connect(m_urlNavigator, SIGNAL(urlAboutToBeChanged(KUrl)), |
131 | this, SLOT(slotUrlNavigatorLocationAboutToBeChanged(KUrl))); |
132 | connect(m_urlNavigator, SIGNAL(urlChanged(KUrl)), |
133 | this, SLOT(slotUrlNavigatorLocationChanged(KUrl))); |
134 | connect(m_urlNavigator, SIGNAL(historyChanged()), |
135 | this, SLOT(slotHistoryChanged())); |
136 | connect(m_urlNavigator, SIGNAL(returnPressed()), |
137 | this, SLOT(slotReturnPressed())); |
138 | |
139 | // Initialize status bar |
140 | m_statusBar = new DolphinStatusBar(this); |
141 | m_statusBar->setUrl(m_view->url()); |
142 | m_statusBar->setZoomLevel(m_view->zoomLevel()); |
143 | connect(m_view, SIGNAL(urlChanged(KUrl)), m_statusBar, SLOT(setUrl(KUrl))); |
144 | connect(m_view, SIGNAL(zoomLevelChanged(int,int)), m_statusBar, SLOT(setZoomLevel(int))); |
145 | connect(m_view, SIGNAL(infoMessage(QString)), m_statusBar, SLOT(setText(QString))); |
146 | connect(m_view, SIGNAL(operationCompletedMessage(QString)), m_statusBar, SLOT(setText(QString))); |
147 | connect(m_statusBar, SIGNAL(stopPressed()), this, SLOT(stopDirectoryLoading())); |
148 | connect(m_statusBar, SIGNAL(zoomLevelChanged(int)), this, SLOT(slotStatusBarZoomLevelChanged(int))); |
149 | |
150 | m_statusBarTimer = new QTimer(this); |
151 | m_statusBarTimer->setSingleShot(true); |
152 | m_statusBarTimer->setInterval(300); |
153 | connect(m_statusBarTimer, SIGNAL(timeout()), this, SLOT(updateStatusBar())); |
154 | |
155 | KIO::FileUndoManager* undoManager = KIO::FileUndoManager::self(); |
156 | connect(undoManager, SIGNAL(jobRecordingFinished(CommandType)), |
157 | this, SLOT(delayedStatusBarUpdate())); |
158 | |
159 | // Initialize filter bar |
160 | m_filterBar = new FilterBar(this); |
161 | m_filterBar->setVisible(settings->filterBar()); |
162 | connect(m_filterBar, SIGNAL(filterChanged(QString)), |
163 | this, SLOT(setNameFilter(QString))); |
164 | connect(m_filterBar, SIGNAL(closeRequest()), |
165 | this, SLOT(closeFilterBar())); |
166 | connect(m_filterBar, SIGNAL(focusViewRequest()), |
167 | this, SLOT(requestFocus())); |
168 | connect(m_view, SIGNAL(urlChanged(KUrl)), |
169 | m_filterBar, SLOT(slotUrlChanged())); |
170 | |
171 | m_topLayout->addWidget(m_urlNavigator); |
172 | m_topLayout->addWidget(m_searchBox); |
173 | m_topLayout->addWidget(m_messageWidget); |
174 | m_topLayout->addWidget(m_view); |
175 | m_topLayout->addWidget(m_filterBar); |
176 | m_topLayout->addWidget(m_statusBar); |
177 | |
178 | setSearchModeEnabled(isSearchUrl(url)); |
179 | |
180 | // Initialize kactivities resource instance |
181 | |
182 | #ifdef KActivities_FOUND |
183 | m_activityResourceInstance = new KActivities::ResourceInstance( |
184 | window()->winId(), url); |
185 | m_activityResourceInstance->setParent(this); |
186 | #endif |
187 | } |
188 | |
189 | DolphinViewContainer::~DolphinViewContainer() |
190 | { |
191 | } |
192 | |
193 | KUrl DolphinViewContainer::url() const |
194 | { |
195 | return m_view->url(); |
196 | } |
197 | |
198 | void DolphinViewContainer::setActive(bool active) |
199 | { |
200 | m_searchBox->setActive(active); |
201 | m_urlNavigator->setActive(active); |
202 | m_view->setActive(active); |
203 | |
204 | #ifdef KActivities_FOUND |
205 | if (active) { |
206 | m_activityResourceInstance->notifyFocusedIn(); |
207 | } else { |
208 | m_activityResourceInstance->notifyFocusedOut(); |
209 | } |
210 | #endif |
211 | } |
212 | |
213 | bool DolphinViewContainer::isActive() const |
214 | { |
215 | Q_ASSERT(m_view->isActive() == m_urlNavigator->isActive()); |
216 | return m_view->isActive(); |
217 | } |
218 | |
219 | void DolphinViewContainer::setAutoGrabFocus(bool grab) |
220 | { |
221 | m_autoGrabFocus = grab; |
222 | } |
223 | |
224 | bool DolphinViewContainer::autoGrabFocus() const |
225 | { |
226 | return m_autoGrabFocus; |
227 | } |
228 | |
229 | const DolphinStatusBar* DolphinViewContainer::statusBar() const |
230 | { |
231 | return m_statusBar; |
232 | } |
233 | |
234 | DolphinStatusBar* DolphinViewContainer::statusBar() |
235 | { |
236 | return m_statusBar; |
237 | } |
238 | |
239 | const KUrlNavigator* DolphinViewContainer::urlNavigator() const |
240 | { |
241 | return m_urlNavigator; |
242 | } |
243 | |
244 | KUrlNavigator* DolphinViewContainer::urlNavigator() |
245 | { |
246 | return m_urlNavigator; |
247 | } |
248 | |
249 | const DolphinView* DolphinViewContainer::view() const |
250 | { |
251 | return m_view; |
252 | } |
253 | |
254 | DolphinView* DolphinViewContainer::view() |
255 | { |
256 | return m_view; |
257 | } |
258 | |
259 | void DolphinViewContainer::showMessage(const QString& msg, MessageType type) |
260 | { |
261 | if (msg.isEmpty()) { |
262 | return; |
263 | } |
264 | |
265 | m_messageWidget->setText(msg); |
266 | |
267 | switch (type) { |
268 | case Information: m_messageWidget->setMessageType(KMessageWidget::Information); break; |
269 | case Warning: m_messageWidget->setMessageType(KMessageWidget::Warning); break; |
270 | case Error: m_messageWidget->setMessageType(KMessageWidget::Error); break; |
271 | default: |
272 | Q_ASSERT(false); |
273 | break; |
274 | } |
275 | |
276 | m_messageWidget->setWordWrap(false); |
277 | const int unwrappedWidth = m_messageWidget->sizeHint().width(); |
278 | m_messageWidget->setWordWrap(unwrappedWidth > size().width()); |
279 | |
280 | m_messageWidget->animatedShow(); |
281 | } |
282 | |
283 | void DolphinViewContainer::readSettings() |
284 | { |
285 | if (GeneralSettings::modifiedStartupSettings()) { |
286 | // The startup settings should only get applied if they have been |
287 | // modified by the user. Otherwise keep the (possibly) different current |
288 | // settings of the URL navigator and the filterbar. |
289 | m_urlNavigator->setUrlEditable(GeneralSettings::editableUrl()); |
290 | m_urlNavigator->setShowFullPath(GeneralSettings::showFullPath()); |
291 | m_urlNavigator->setHomeUrl(KUrl(GeneralSettings::homeUrl())); |
292 | setFilterBarVisible(GeneralSettings::filterBar()); |
293 | } |
294 | |
295 | m_view->readSettings(); |
296 | m_statusBar->readSettings(); |
297 | } |
298 | |
299 | bool DolphinViewContainer::isFilterBarVisible() const |
300 | { |
301 | return m_filterBar->isVisible(); |
302 | } |
303 | |
304 | void DolphinViewContainer::setSearchModeEnabled(bool enabled) |
305 | { |
306 | if (enabled == isSearchModeEnabled()) { |
307 | if (enabled && !m_searchBox->hasFocus()) { |
308 | m_searchBox->setFocus(); |
309 | m_searchBox->selectAll(); |
310 | } |
311 | return; |
312 | } |
313 | |
314 | m_searchBox->setVisible(enabled); |
315 | m_urlNavigator->setVisible(!enabled); |
316 | |
317 | if (enabled) { |
318 | const KUrl& locationUrl = m_urlNavigator->locationUrl(); |
319 | m_searchBox->fromSearchUrl(locationUrl); |
320 | } else { |
321 | m_view->setViewPropertiesContext(QString()); |
322 | |
323 | // Restore the URL for the URL navigator. If Dolphin has been |
324 | // started with a search-URL, the home URL is used as fallback. |
325 | KUrl url = m_searchBox->searchPath(); |
326 | if (url.isEmpty() || !url.isValid() || isSearchUrl(url)) { |
327 | url = GeneralSettings::self()->homeUrl(); |
328 | } |
329 | m_urlNavigator->setLocationUrl(url); |
330 | } |
331 | } |
332 | |
333 | bool DolphinViewContainer::isSearchModeEnabled() const |
334 | { |
335 | return m_searchBox->isVisible(); |
336 | } |
337 | |
338 | QString DolphinViewContainer::placesText() const |
339 | { |
340 | QString text; |
341 | |
342 | if (isSearchModeEnabled()) { |
343 | text = m_searchBox->searchPath().fileName() + QLatin1String(": " ) + m_searchBox->text(); |
344 | } else { |
345 | text = url().fileName(); |
346 | if (text.isEmpty()) { |
347 | text = url().host(); |
348 | } |
349 | } |
350 | |
351 | return text; |
352 | } |
353 | |
354 | void DolphinViewContainer::setUrl(const KUrl& newUrl) |
355 | { |
356 | if (newUrl != m_urlNavigator->locationUrl()) { |
357 | m_urlNavigator->setLocationUrl(newUrl); |
358 | } |
359 | |
360 | #ifdef KActivities_FOUND |
361 | m_activityResourceInstance->setUri(newUrl); |
362 | #endif |
363 | } |
364 | |
365 | void DolphinViewContainer::setFilterBarVisible(bool visible) |
366 | { |
367 | Q_ASSERT(m_filterBar); |
368 | if (visible) { |
369 | m_filterBar->show(); |
370 | m_filterBar->setFocus(); |
371 | m_filterBar->selectAll(); |
372 | } else { |
373 | closeFilterBar(); |
374 | } |
375 | } |
376 | |
377 | void DolphinViewContainer::delayedStatusBarUpdate() |
378 | { |
379 | if (m_statusBarTimer->isActive() && (m_statusBarTimestamp.elapsed() > 2000)) { |
380 | // No update of the statusbar has been done during the last 2 seconds, |
381 | // although an update has been requested. Trigger an immediate update. |
382 | m_statusBarTimer->stop(); |
383 | updateStatusBar(); |
384 | } else { |
385 | // Invoke updateStatusBar() with a small delay. This assures that |
386 | // when a lot of delayedStatusBarUpdates() are done in a short time, |
387 | // no bottleneck is given. |
388 | m_statusBarTimer->start(); |
389 | } |
390 | } |
391 | |
392 | void DolphinViewContainer::updateStatusBar() |
393 | { |
394 | m_statusBarTimestamp.start(); |
395 | |
396 | const QString text = m_view->statusBarText(); |
397 | m_statusBar->setDefaultText(text); |
398 | m_statusBar->resetToDefaultText(); |
399 | } |
400 | |
401 | void DolphinViewContainer::updateDirectoryLoadingProgress(int percent) |
402 | { |
403 | if (m_statusBar->progressText().isEmpty()) { |
404 | m_statusBar->setProgressText(i18nc("@info:progress" , "Loading folder..." )); |
405 | } |
406 | m_statusBar->setProgress(percent); |
407 | } |
408 | |
409 | void DolphinViewContainer::updateDirectorySortingProgress(int percent) |
410 | { |
411 | if (m_statusBar->progressText().isEmpty()) { |
412 | m_statusBar->setProgressText(i18nc("@info:progress" , "Sorting..." )); |
413 | } |
414 | m_statusBar->setProgress(percent); |
415 | } |
416 | |
417 | void DolphinViewContainer::slotDirectoryLoadingStarted() |
418 | { |
419 | if (isSearchUrl(url())) { |
420 | // Search KIO-slaves usually don't provide any progress information. Give |
421 | // a hint to the user that a searching is done: |
422 | updateStatusBar(); |
423 | m_statusBar->setProgressText(i18nc("@info" , "Searching..." )); |
424 | m_statusBar->setProgress(-1); |
425 | } else { |
426 | // Trigger an undetermined progress indication. The progress |
427 | // information in percent will be triggered by the percent() signal |
428 | // of the directory lister later. |
429 | updateDirectoryLoadingProgress(-1); |
430 | } |
431 | } |
432 | |
433 | void DolphinViewContainer::slotDirectoryLoadingCompleted() |
434 | { |
435 | if (!m_statusBar->progressText().isEmpty()) { |
436 | m_statusBar->setProgressText(QString()); |
437 | m_statusBar->setProgress(100); |
438 | } |
439 | |
440 | if (isSearchUrl(url()) && m_view->itemsCount() == 0) { |
441 | // The dir lister has been completed on a Baloo-URI and no items have been found. Instead |
442 | // of showing the default status bar information ("0 items") a more helpful information is given: |
443 | m_statusBar->setText(i18nc("@info:status" , "No items found." )); |
444 | } else { |
445 | updateStatusBar(); |
446 | } |
447 | } |
448 | |
449 | void DolphinViewContainer::slotDirectoryLoadingCanceled() |
450 | { |
451 | if (!m_statusBar->progressText().isEmpty()) { |
452 | m_statusBar->setProgressText(QString()); |
453 | m_statusBar->setProgress(100); |
454 | } |
455 | |
456 | m_statusBar->setText(QString()); |
457 | } |
458 | |
459 | void DolphinViewContainer::slotUrlIsFileError(const KUrl& url) |
460 | { |
461 | const KFileItem item(KFileItem::Unknown, KFileItem::Unknown, url); |
462 | slotItemActivated(item); |
463 | } |
464 | |
465 | void DolphinViewContainer::slotItemActivated(const KFileItem& item) |
466 | { |
467 | // It is possible to activate items on inactive views by |
468 | // drag & drop operations. Assure that activating an item always |
469 | // results in an active view. |
470 | m_view->setActive(true); |
471 | |
472 | const KUrl& url = DolphinView::openItemAsFolderUrl(item, GeneralSettings::browseThroughArchives()); |
473 | if (!url.isEmpty()) { |
474 | m_view->setUrl(url); |
475 | return; |
476 | } |
477 | |
478 | item.run(); |
479 | } |
480 | |
481 | void DolphinViewContainer::slotItemsActivated(const KFileItemList& items) |
482 | { |
483 | Q_ASSERT(items.count() >= 2); |
484 | |
485 | KFileItemActions fileItemActions(this); |
486 | fileItemActions.runPreferredApplications(items, QString()); |
487 | } |
488 | |
489 | void DolphinViewContainer::showItemInfo(const KFileItem& item) |
490 | { |
491 | if (item.isNull()) { |
492 | m_statusBar->resetToDefaultText(); |
493 | } else { |
494 | m_statusBar->setText(item.getStatusBarInfo()); |
495 | } |
496 | } |
497 | |
498 | void DolphinViewContainer::closeFilterBar() |
499 | { |
500 | m_filterBar->closeFilterBar(); |
501 | m_view->setFocus(); |
502 | emit showFilterBarChanged(false); |
503 | } |
504 | |
505 | void DolphinViewContainer::setNameFilter(const QString& nameFilter) |
506 | { |
507 | m_view->setNameFilter(nameFilter); |
508 | delayedStatusBarUpdate(); |
509 | } |
510 | |
511 | void DolphinViewContainer::activate() |
512 | { |
513 | setActive(true); |
514 | } |
515 | |
516 | void DolphinViewContainer::slotViewUrlAboutToBeChanged(const KUrl& url) |
517 | { |
518 | // URL changes of the view can happen in two ways: |
519 | // 1. The URL navigator gets changed and will trigger the view to update its URL |
520 | // 2. The URL of the view gets changed and will trigger the URL navigator to update |
521 | // its URL (e.g. by clicking on an item) |
522 | // In this scope the view-state may only get saved in case 2: |
523 | if (url != m_urlNavigator->locationUrl()) { |
524 | saveViewState(); |
525 | } |
526 | } |
527 | |
528 | void DolphinViewContainer::slotUrlNavigatorLocationAboutToBeChanged(const KUrl& url) |
529 | { |
530 | // URL changes of the view can happen in two ways: |
531 | // 1. The URL navigator gets changed and will trigger the view to update its URL |
532 | // 2. The URL of the view gets changed and will trigger the URL navigator to update |
533 | // its URL (e.g. by clicking on an item) |
534 | // In this scope the view-state may only get saved in case 1: |
535 | if (url != m_view->url()) { |
536 | saveViewState(); |
537 | } |
538 | } |
539 | |
540 | void DolphinViewContainer::slotUrlNavigatorLocationChanged(const KUrl& url) |
541 | { |
542 | slotReturnPressed(); |
543 | |
544 | if (KProtocolManager::supportsListing(url)) { |
545 | setSearchModeEnabled(isSearchUrl(url)); |
546 | m_view->setUrl(url); |
547 | |
548 | if (m_autoGrabFocus && isActive() && !isSearchUrl(url)) { |
549 | // When an URL has been entered, the view should get the focus. |
550 | // The focus must be requested asynchronously, as changing the URL might create |
551 | // a new view widget. |
552 | QTimer::singleShot(0, this, SLOT(requestFocus())); |
553 | } |
554 | } else if (KProtocolManager::isSourceProtocol(url)) { |
555 | QString app = "konqueror" ; |
556 | if (url.protocol().startsWith(QLatin1String("http" ))) { |
557 | showMessage(i18nc("@info:status" , // krazy:exclude=qmethods |
558 | "Dolphin does not support web pages, the web browser has been launched" ), |
559 | Information); |
560 | |
561 | const KConfigGroup config(KSharedConfig::openConfig("kdeglobals" ), "General" ); |
562 | const QString browser = config.readEntry("BrowserApplication" ); |
563 | if (!browser.isEmpty()) { |
564 | app = browser; |
565 | if (app.startsWith('!')) { |
566 | // a literal command has been configured, remove the '!' prefix |
567 | app = app.mid(1); |
568 | } |
569 | } |
570 | } else { |
571 | showMessage(i18nc("@info:status" , |
572 | "Protocol not supported by Dolphin, Konqueror has been launched" ), |
573 | Information); |
574 | } |
575 | |
576 | const QString secureUrl = KShell::quoteArg(url.pathOrUrl()); |
577 | const QString command = app + ' ' + secureUrl; |
578 | KRun::runCommand(command, app, app, this); |
579 | } else { |
580 | showMessage(i18nc("@info:status" , "Invalid protocol" ), Error); |
581 | } |
582 | } |
583 | |
584 | void DolphinViewContainer::dropUrls(const KUrl& destination, QDropEvent* event) |
585 | { |
586 | m_dropDestination = destination; |
587 | |
588 | const QMimeData* mimeData = event->mimeData(); |
589 | QMimeData* mimeDataCopy = new QMimeData; |
590 | foreach (const QString& format, mimeData->formats()) { |
591 | mimeDataCopy->setData(format, mimeData->data(format)); |
592 | } |
593 | |
594 | m_dropEvent.reset(new QDropEvent(event->pos(), |
595 | event->possibleActions(), |
596 | mimeDataCopy, |
597 | event->mouseButtons(), |
598 | event->keyboardModifiers())); |
599 | |
600 | QTimer::singleShot(0, this, SLOT(dropUrlsDelayed())); |
601 | } |
602 | |
603 | void DolphinViewContainer::dropUrlsDelayed() |
604 | { |
605 | if (m_dropEvent.isNull()) { |
606 | return; |
607 | } |
608 | |
609 | QString error; |
610 | DragAndDropHelper::dropUrls(KFileItem(), m_dropDestination, m_dropEvent.data(), error); |
611 | if (!error.isEmpty()) { |
612 | showMessage(error, Error); |
613 | } |
614 | |
615 | delete m_dropEvent->mimeData(); |
616 | m_dropEvent.reset(); |
617 | } |
618 | |
619 | void DolphinViewContainer::redirect(const KUrl& oldUrl, const KUrl& newUrl) |
620 | { |
621 | Q_UNUSED(oldUrl); |
622 | const bool block = m_urlNavigator->signalsBlocked(); |
623 | m_urlNavigator->blockSignals(true); |
624 | |
625 | // Assure that the location state is reset for redirection URLs. This |
626 | // allows to skip redirection URLs when going back or forward in the |
627 | // URL history. |
628 | m_urlNavigator->saveLocationState(QByteArray()); |
629 | m_urlNavigator->setLocationUrl(newUrl); |
630 | setSearchModeEnabled(isSearchUrl(newUrl)); |
631 | |
632 | m_urlNavigator->blockSignals(block); |
633 | } |
634 | |
635 | void DolphinViewContainer::requestFocus() |
636 | { |
637 | m_view->setFocus(); |
638 | } |
639 | |
640 | void DolphinViewContainer::saveUrlCompletionMode(KGlobalSettings::Completion completion) |
641 | { |
642 | GeneralSettings::setUrlCompletionMode(completion); |
643 | } |
644 | |
645 | void DolphinViewContainer::slotHistoryChanged() |
646 | { |
647 | QByteArray locationState = m_urlNavigator->locationState(); |
648 | if (!locationState.isEmpty()) { |
649 | QDataStream stream(&locationState, QIODevice::ReadOnly); |
650 | m_view->restoreState(stream); |
651 | } |
652 | } |
653 | |
654 | void DolphinViewContainer::slotReturnPressed() |
655 | { |
656 | if (!GeneralSettings::editableUrl()) { |
657 | m_urlNavigator->setUrlEditable(false); |
658 | } |
659 | } |
660 | |
661 | void DolphinViewContainer::startSearching() |
662 | { |
663 | const KUrl url = m_searchBox->urlForSearching(); |
664 | if (url.isValid() && !url.isEmpty()) { |
665 | m_view->setViewPropertiesContext("search" ); |
666 | m_urlNavigator->setLocationUrl(url); |
667 | } |
668 | } |
669 | |
670 | void DolphinViewContainer::closeSearchBox() |
671 | { |
672 | setSearchModeEnabled(false); |
673 | } |
674 | |
675 | void DolphinViewContainer::stopDirectoryLoading() |
676 | { |
677 | m_view->stopLoading(); |
678 | m_statusBar->setProgress(100); |
679 | } |
680 | |
681 | void DolphinViewContainer::slotStatusBarZoomLevelChanged(int zoomLevel) |
682 | { |
683 | m_view->setZoomLevel(zoomLevel); |
684 | } |
685 | |
686 | void DolphinViewContainer::showErrorMessage(const QString& msg) |
687 | { |
688 | showMessage(msg, Error); |
689 | } |
690 | |
691 | bool DolphinViewContainer::isSearchUrl(const KUrl& url) const |
692 | { |
693 | const QString protocol = url.protocol(); |
694 | return protocol.contains("search" ); |
695 | } |
696 | |
697 | void DolphinViewContainer::saveViewState() |
698 | { |
699 | QByteArray locationState; |
700 | QDataStream stream(&locationState, QIODevice::WriteOnly); |
701 | m_view->saveState(stream); |
702 | m_urlNavigator->saveLocationState(locationState); |
703 | } |
704 | |
705 | #include "dolphinviewcontainer.moc" |
706 | |