]> cloud.milkyroute.net Git - dolphin.git/blob - src/dolphinmainwindow.cpp
Fix bug with the UndoUiInterface usage: if more than one mainwindow was used, the...
[dolphin.git] / src / dolphinmainwindow.cpp
1 /***************************************************************************
2 * Copyright (C) 2006 by Peter Penz <peter.penz@gmx.at> *
3 * Copyright (C) 2006 by Stefan Monov <logixoul@gmail.com> *
4 * Copyright (C) 2006 by Cvetoslav Ludmiloff <ludmiloff@gmail.com> *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program 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 *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
20 ***************************************************************************/
21
22 #include "dolphinmainwindow.h"
23 #include "dolphinviewactionhandler.h"
24 #include "dolphindropcontroller.h"
25
26 #include <config-nepomuk.h>
27
28 #include "dolphinapplication.h"
29 #include "dolphinfileplacesview.h"
30 #include "dolphinnewmenu.h"
31 #include "dolphinsettings.h"
32 #include "dolphinsettingsdialog.h"
33 #include "dolphinstatusbar.h"
34 #include "dolphinviewcontainer.h"
35 #include "fileitemcapabilities.h"
36 #include "infosidebarpage.h"
37 #include "metadatawidget.h"
38 #include "mainwindowadaptor.h"
39 #include "treeviewsidebarpage.h"
40 #include "viewpropertiesdialog.h"
41 #include "viewproperties.h"
42
43 #ifndef Q_OS_WIN
44 #include "terminalsidebarpage.h"
45 #endif
46
47 #include "dolphin_generalsettings.h"
48 #include "dolphin_iconsmodesettings.h"
49
50 #include <kaction.h>
51 #include <kactioncollection.h>
52 #include <kconfig.h>
53 #include <kdesktopfile.h>
54 #include <kdeversion.h>
55 #include <kfiledialog.h>
56 #include <kfileplacesmodel.h>
57 #include <kglobal.h>
58 #include <kicon.h>
59 #include <kiconloader.h>
60 #include <kio/netaccess.h>
61 #include <kinputdialog.h>
62 #include <klocale.h>
63 #include <kmenu.h>
64 #include <kmenubar.h>
65 #include <kmessagebox.h>
66 #include <kurlnavigator.h>
67 #include <konqmimedata.h>
68 #include <kpropertiesdialog.h>
69 #include <kprotocolinfo.h>
70 #include <ktoggleaction.h>
71 #include <krun.h>
72 #include <kshell.h>
73 #include <kstandarddirs.h>
74 #include <kstatusbar.h>
75 #include <kstandardaction.h>
76 #include <ktabbar.h>
77 #include <kurl.h>
78 #include <kurlcombobox.h>
79
80 #include <QKeyEvent>
81 #include <QClipboard>
82 #include <QLineEdit>
83 #include <QSplitter>
84 #include <QDockWidget>
85
86 DolphinMainWindow::DolphinMainWindow(int id) :
87 KXmlGuiWindow(0),
88 m_newMenu(0),
89 m_showMenuBar(0),
90 m_tabBar(0),
91 m_activeViewContainer(0),
92 m_centralWidgetLayout(0),
93 m_id(id),
94 m_tabIndex(0),
95 m_viewTab(),
96 m_actionHandler(0)
97 {
98 setObjectName("Dolphin#");
99
100 m_viewTab.append(ViewTab());
101
102 new MainWindowAdaptor(this);
103 QDBusConnection::sessionBus().registerObject(QString("/dolphin/MainWindow%1").arg(m_id), this);
104
105 KonqFileUndoManager* undoManager = KonqFileUndoManager::self();
106 undoManager->setUiInterface(new UndoUiInterface());
107
108 connect(undoManager, SIGNAL(undoAvailable(bool)),
109 this, SLOT(slotUndoAvailable(bool)));
110 connect(undoManager, SIGNAL(undoTextChanged(const QString&)),
111 this, SLOT(slotUndoTextChanged(const QString&)));
112 connect(DolphinSettings::instance().placesModel(), SIGNAL(errorMessage(const QString&)),
113 this, SLOT(slotHandlePlacesError(const QString&)));
114 }
115
116 DolphinMainWindow::~DolphinMainWindow()
117 {
118 DolphinApplication::app()->removeMainWindow(this);
119 }
120
121 void DolphinMainWindow::toggleViews()
122 {
123 if (m_viewTab[m_tabIndex].primaryView == 0) {
124 return;
125 }
126
127 // move secondary view from the last position of the splitter
128 // to the first position
129 m_viewTab[m_tabIndex].splitter->insertWidget(0, m_viewTab[m_tabIndex].secondaryView);
130
131 DolphinViewContainer* container = m_viewTab[m_tabIndex].primaryView;
132 m_viewTab[m_tabIndex].primaryView = m_viewTab[m_tabIndex].secondaryView;
133 m_viewTab[m_tabIndex].secondaryView = container;
134 }
135
136 void DolphinMainWindow::slotDoingOperation(KonqFileUndoManager::CommandType commandType)
137 {
138 clearStatusBar();
139 m_undoCommandTypes.append(commandType);
140 }
141
142 void DolphinMainWindow::refreshViews()
143 {
144 Q_ASSERT(m_viewTab[m_tabIndex].primaryView != 0);
145
146 // remember the current active view, as because of
147 // the refreshing the active view might change to
148 // the secondary view
149 DolphinViewContainer* activeViewContainer = m_activeViewContainer;
150
151 m_viewTab[m_tabIndex].primaryView->view()->refresh();
152 if (m_viewTab[m_tabIndex].secondaryView != 0) {
153 m_viewTab[m_tabIndex].secondaryView->view()->refresh();
154 }
155
156 setActiveViewContainer(activeViewContainer);
157 }
158
159 void DolphinMainWindow::dropUrls(const KUrl::List& urls,
160 const KUrl& destination)
161 {
162 DolphinDropController dropController(this);
163 connect(&dropController, SIGNAL(doingOperation(KonqFileUndoManager::CommandType)),
164 this, SLOT(slotDoingOperation(KonqFileUndoManager::CommandType)));
165 dropController.dropUrls(urls, destination);
166 }
167
168 void DolphinMainWindow::pasteIntoFolder()
169 {
170 m_activeViewContainer->view()->pasteIntoFolder();
171 }
172
173 void DolphinMainWindow::changeUrl(const KUrl& url)
174 {
175 DolphinViewContainer* view = activeViewContainer();
176 if (view != 0) {
177 view->setUrl(url);
178 updateEditActions();
179 updateViewActions();
180 updateGoActions();
181 setCaption(url.fileName());
182 if (m_viewTab.count() > 1) {
183 m_tabBar->setTabText(m_tabIndex, tabName(url));
184 }
185 emit urlChanged(url);
186 }
187 }
188
189 void DolphinMainWindow::changeSelection(const KFileItemList& selection)
190 {
191 activeViewContainer()->view()->changeSelection(selection);
192 }
193
194 void DolphinMainWindow::slotEditableStateChanged(bool editable)
195 {
196 KToggleAction* editableLocationAction =
197 static_cast<KToggleAction*>(actionCollection()->action("editable_location"));
198 editableLocationAction->setChecked(editable);
199 }
200
201 void DolphinMainWindow::slotSelectionChanged(const KFileItemList& selection)
202 {
203 updateEditActions();
204
205 Q_ASSERT(m_viewTab[m_tabIndex].primaryView != 0);
206 int selectedUrlsCount = m_viewTab[m_tabIndex].primaryView->view()->selectedUrls().count();
207 if (m_viewTab[m_tabIndex].secondaryView != 0) {
208 selectedUrlsCount += m_viewTab[m_tabIndex].secondaryView->view()->selectedUrls().count();
209 }
210
211 QAction* compareFilesAction = actionCollection()->action("compare_files");
212 if (selectedUrlsCount == 2) {
213 const bool kompareInstalled = !KGlobal::dirs()->findExe("kompare").isEmpty();
214 compareFilesAction->setEnabled(selectedUrlsCount == 2 && kompareInstalled);
215 } else {
216 compareFilesAction->setEnabled(false);
217 }
218
219 m_activeViewContainer->updateStatusBar();
220
221 emit selectionChanged(selection);
222 }
223
224 void DolphinMainWindow::slotRequestItemInfo(const KFileItem& item)
225 {
226 emit requestItemInfo(item);
227 }
228
229 void DolphinMainWindow::updateHistory()
230 {
231 const KUrlNavigator* urlNavigator = m_activeViewContainer->urlNavigator();
232 const int index = urlNavigator->historyIndex();
233
234 QAction* backAction = actionCollection()->action("go_back");
235 if (backAction != 0) {
236 backAction->setEnabled(index < urlNavigator->historySize() - 1);
237 }
238
239 QAction* forwardAction = actionCollection()->action("go_forward");
240 if (forwardAction != 0) {
241 forwardAction->setEnabled(index > 0);
242 }
243 }
244
245 void DolphinMainWindow::updateFilterBarAction(bool show)
246 {
247 QAction* showFilterBarAction = actionCollection()->action("show_filter_bar");
248 showFilterBarAction->setChecked(show);
249 }
250
251 void DolphinMainWindow::openNewMainWindow()
252 {
253 DolphinApplication::app()->createMainWindow()->show();
254 }
255
256 void DolphinMainWindow::openNewTab()
257 {
258 openNewTab(m_activeViewContainer->url());
259 m_tabBar->setCurrentIndex(m_viewTab.count() - 1);
260 }
261
262 void DolphinMainWindow::openNewTab(const KUrl& url)
263 {
264 if (m_viewTab.count() == 1) {
265 // Only one view is open currently and hence no tab is shown at
266 // all. Before creating a tab for 'url', provide a tab for the current URL.
267 m_tabBar->addTab(KIcon("folder"), tabName(m_activeViewContainer->url()));
268 m_tabBar->blockSignals(false);
269 }
270
271 m_tabBar->addTab(KIcon("folder"), tabName(url));
272
273 ViewTab viewTab;
274 viewTab.splitter = new QSplitter(this);
275 viewTab.primaryView = new DolphinViewContainer(this, viewTab.splitter, url);
276 connectViewSignals(viewTab.primaryView);
277 viewTab.primaryView->view()->reload();
278
279 m_viewTab.append(viewTab);
280 }
281
282 void DolphinMainWindow::toggleActiveView()
283 {
284 if (m_viewTab[m_tabIndex].secondaryView == 0) {
285 // only one view is available
286 return;
287 }
288
289 Q_ASSERT(m_activeViewContainer != 0);
290 Q_ASSERT(m_viewTab[m_tabIndex].primaryView != 0);
291
292 DolphinViewContainer* left = m_viewTab[m_tabIndex].primaryView;
293 DolphinViewContainer* right = m_viewTab[m_tabIndex].secondaryView;
294 setActiveViewContainer(m_activeViewContainer == right ? left : right);
295 }
296
297 void DolphinMainWindow::closeEvent(QCloseEvent* event)
298 {
299 DolphinSettings& settings = DolphinSettings::instance();
300 GeneralSettings* generalSettings = settings.generalSettings();
301 generalSettings->setFirstRun(false);
302
303 settings.save();
304
305 KXmlGuiWindow::closeEvent(event);
306 }
307
308 void DolphinMainWindow::saveProperties(KConfigGroup& group)
309 {
310 // TODO: remember tabs
311 DolphinViewContainer* cont = m_viewTab[m_tabIndex].primaryView;
312 group.writeEntry("Primary Url", cont->url().url());
313 group.writeEntry("Primary Editable Url", cont->isUrlEditable());
314
315 cont = m_viewTab[m_tabIndex].secondaryView;
316 if (cont != 0) {
317 group.writeEntry("Secondary Url", cont->url().url());
318 group.writeEntry("Secondary Editable Url", cont->isUrlEditable());
319 }
320 }
321
322 void DolphinMainWindow::readProperties(const KConfigGroup& group)
323 {
324 // TODO: read tabs
325 DolphinViewContainer* cont = m_viewTab[m_tabIndex].primaryView;
326
327 cont->setUrl(group.readEntry("Primary Url"));
328 bool editable = group.readEntry("Primary Editable Url", false);
329 cont->urlNavigator()->setUrlEditable(editable);
330
331 cont = m_viewTab[m_tabIndex].secondaryView;
332 const QString secondaryUrl = group.readEntry("Secondary Url");
333 if (!secondaryUrl.isEmpty()) {
334 if (cont == 0) {
335 // a secondary view should be shown, but no one is available
336 // currently -> create a new view
337 toggleSplitView();
338 cont = m_viewTab[m_tabIndex].secondaryView;
339 Q_ASSERT(cont != 0);
340 }
341
342 cont->setUrl(secondaryUrl);
343 bool editable = group.readEntry("Secondary Editable Url", false);
344 cont->urlNavigator()->setUrlEditable(editable);
345 } else if (cont != 0) {
346 // no secondary view should be shown, but the default setting shows
347 // one already -> close the view
348 toggleSplitView();
349 }
350 }
351
352 void DolphinMainWindow::updateNewMenu()
353 {
354 m_newMenu->slotCheckUpToDate();
355 m_newMenu->setPopupFiles(activeViewContainer()->url());
356 }
357
358 void DolphinMainWindow::properties()
359 {
360 const KFileItemList list = m_activeViewContainer->view()->selectedItems();
361
362 KPropertiesDialog *dialog = new KPropertiesDialog(list, this);
363 dialog->setAttribute(Qt::WA_DeleteOnClose);
364 dialog->show();
365 dialog->raise();
366 dialog->activateWindow();
367 }
368
369 void DolphinMainWindow::quit()
370 {
371 close();
372 }
373
374 void DolphinMainWindow::slotHandlePlacesError(const QString &message)
375 {
376 if (!message.isEmpty()) {
377 DolphinStatusBar* statusBar = m_activeViewContainer->statusBar();
378 statusBar->setMessage(message, DolphinStatusBar::Error);
379 }
380 }
381
382 void DolphinMainWindow::slotUndoAvailable(bool available)
383 {
384 QAction* undoAction = actionCollection()->action(KStandardAction::name(KStandardAction::Undo));
385 if (undoAction != 0) {
386 undoAction->setEnabled(available);
387 }
388
389 if (available && (m_undoCommandTypes.count() > 0)) {
390 const KonqFileUndoManager::CommandType command = m_undoCommandTypes.takeFirst();
391 DolphinStatusBar* statusBar = m_activeViewContainer->statusBar();
392 switch (command) {
393 case KonqFileUndoManager::COPY:
394 statusBar->setMessage(i18nc("@info:status", "Copy operation completed."),
395 DolphinStatusBar::OperationCompleted);
396 break;
397 case KonqFileUndoManager::MOVE:
398 statusBar->setMessage(i18nc("@info:status", "Move operation completed."),
399 DolphinStatusBar::OperationCompleted);
400 break;
401 case KonqFileUndoManager::LINK:
402 statusBar->setMessage(i18nc("@info:status", "Link operation completed."),
403 DolphinStatusBar::OperationCompleted);
404 break;
405 case KonqFileUndoManager::TRASH:
406 statusBar->setMessage(i18nc("@info:status", "Move to trash operation completed."),
407 DolphinStatusBar::OperationCompleted);
408 break;
409 case KonqFileUndoManager::RENAME:
410 statusBar->setMessage(i18nc("@info:status", "Renaming operation completed."),
411 DolphinStatusBar::OperationCompleted);
412 break;
413
414 case KonqFileUndoManager::MKDIR:
415 statusBar->setMessage(i18nc("@info:status", "Created folder."),
416 DolphinStatusBar::OperationCompleted);
417 break;
418
419 default:
420 break;
421 }
422
423 }
424 }
425
426 void DolphinMainWindow::slotUndoTextChanged(const QString& text)
427 {
428 QAction* undoAction = actionCollection()->action(KStandardAction::name(KStandardAction::Undo));
429 if (undoAction != 0) {
430 undoAction->setText(text);
431 }
432 }
433
434 void DolphinMainWindow::undo()
435 {
436 clearStatusBar();
437 KonqFileUndoManager::self()->uiInterface()->setParentWidget(this);
438 KonqFileUndoManager::self()->undo();
439 }
440
441 void DolphinMainWindow::cut()
442 {
443 m_activeViewContainer->view()->cutSelectedItems();
444 }
445
446 void DolphinMainWindow::copy()
447 {
448 m_activeViewContainer->view()->copySelectedItems();
449 }
450
451 void DolphinMainWindow::paste()
452 {
453 m_activeViewContainer->view()->paste();
454 }
455
456 void DolphinMainWindow::updatePasteAction()
457 {
458 QAction* pasteAction = actionCollection()->action(KStandardAction::name(KStandardAction::Paste));
459 QPair<bool, QString> pasteInfo = m_activeViewContainer->view()->pasteInfo();
460 pasteAction->setEnabled(pasteInfo.first);
461 pasteAction->setText(pasteInfo.second);
462 }
463
464 void DolphinMainWindow::selectAll()
465 {
466 clearStatusBar();
467
468 // if the URL navigator is editable and focused, select the whole
469 // URL instead of all items of the view
470
471 KUrlNavigator* urlNavigator = m_activeViewContainer->urlNavigator();
472 QLineEdit* lineEdit = urlNavigator->editor()->lineEdit();
473 const bool selectUrl = urlNavigator->isUrlEditable() &&
474 lineEdit->hasFocus();
475 if (selectUrl) {
476 lineEdit->selectAll();
477 } else {
478 m_activeViewContainer->view()->selectAll();
479 }
480 }
481
482 void DolphinMainWindow::invertSelection()
483 {
484 clearStatusBar();
485 m_activeViewContainer->view()->invertSelection();
486 }
487
488 void DolphinMainWindow::toggleSplitView()
489 {
490 if (m_viewTab[m_tabIndex].secondaryView == 0) {
491 // create a secondary view
492 QSplitter* splitter = m_viewTab[m_tabIndex].splitter;
493 const int newWidth = (m_viewTab[m_tabIndex].primaryView->width() - splitter->handleWidth()) / 2;
494
495 const DolphinView* view = m_viewTab[m_tabIndex].primaryView->view();
496 m_viewTab[m_tabIndex].secondaryView = new DolphinViewContainer(this, 0, view->rootUrl());
497 connectViewSignals(m_viewTab[m_tabIndex].secondaryView);
498 splitter->addWidget(m_viewTab[m_tabIndex].secondaryView);
499 splitter->setSizes(QList<int>() << newWidth << newWidth);
500 m_viewTab[m_tabIndex].secondaryView->view()->reload();
501 m_viewTab[m_tabIndex].secondaryView->setActive(false);
502 m_viewTab[m_tabIndex].secondaryView->show();
503 } else if (m_activeViewContainer == m_viewTab[m_tabIndex].primaryView) {
504 // remove secondary view
505 m_viewTab[m_tabIndex].secondaryView->close();
506 m_viewTab[m_tabIndex].secondaryView->deleteLater();
507 m_viewTab[m_tabIndex].secondaryView = 0;
508 } else {
509 // The secondary view is active, hence from a users point of view
510 // the content of the secondary view should be moved to the primary view.
511 // From an implementation point of view it is more efficient to close
512 // the primary view and exchange the internal pointers afterwards.
513
514 m_viewTab[m_tabIndex].primaryView->close();
515 m_viewTab[m_tabIndex].primaryView->deleteLater();
516 m_viewTab[m_tabIndex].primaryView = m_viewTab[m_tabIndex].secondaryView;
517 m_viewTab[m_tabIndex].secondaryView = 0;
518 }
519
520 setActiveViewContainer(m_viewTab[m_tabIndex].primaryView);
521 updateViewActions();
522 }
523
524 void DolphinMainWindow::reloadView()
525 {
526 clearStatusBar();
527 m_activeViewContainer->view()->reload();
528 }
529
530 void DolphinMainWindow::stopLoading()
531 {
532 }
533
534 void DolphinMainWindow::toggleFilterBarVisibility(bool show)
535 {
536 m_activeViewContainer->showFilterBar(show);
537 }
538
539 void DolphinMainWindow::toggleEditLocation()
540 {
541 clearStatusBar();
542
543 QAction* action = actionCollection()->action("editable_location");
544 KUrlNavigator* urlNavigator = m_activeViewContainer->urlNavigator();
545 urlNavigator->setUrlEditable(action->isChecked());
546 }
547
548 void DolphinMainWindow::editLocation()
549 {
550 KUrlNavigator* navigator = m_activeViewContainer->urlNavigator();
551 navigator->setUrlEditable(true);
552 navigator->setFocus();
553
554 // select the whole text of the combo box editor
555 QLineEdit* lineEdit = navigator->editor()->lineEdit();
556 const QString text = lineEdit->text();
557 lineEdit->setSelection(0, text.length());
558 }
559
560 void DolphinMainWindow::adjustViewProperties()
561 {
562 clearStatusBar();
563 ViewPropertiesDialog dlg(m_activeViewContainer->view());
564 dlg.exec();
565 }
566
567 void DolphinMainWindow::goBack()
568 {
569 clearStatusBar();
570 m_activeViewContainer->urlNavigator()->goBack();
571 }
572
573 void DolphinMainWindow::goForward()
574 {
575 clearStatusBar();
576 m_activeViewContainer->urlNavigator()->goForward();
577 }
578
579 void DolphinMainWindow::goUp()
580 {
581 clearStatusBar();
582 m_activeViewContainer->urlNavigator()->goUp();
583 }
584
585 void DolphinMainWindow::goHome()
586 {
587 clearStatusBar();
588 m_activeViewContainer->urlNavigator()->goHome();
589 }
590
591 void DolphinMainWindow::findFile()
592 {
593 KRun::run("kfind", m_activeViewContainer->url(), this);
594 }
595
596 void DolphinMainWindow::compareFiles()
597 {
598 // The method is only invoked if exactly 2 files have
599 // been selected. The selected files may be:
600 // - both in the primary view
601 // - both in the secondary view
602 // - one in the primary view and the other in the secondary
603 // view
604 Q_ASSERT(m_viewTab[m_tabIndex].primaryView != 0);
605
606 KUrl urlA;
607 KUrl urlB;
608 KUrl::List urls = m_viewTab[m_tabIndex].primaryView->view()->selectedUrls();
609
610 switch (urls.count()) {
611 case 0: {
612 Q_ASSERT(m_viewTab[m_tabIndex].secondaryView != 0);
613 urls = m_viewTab[m_tabIndex].secondaryView->view()->selectedUrls();
614 Q_ASSERT(urls.count() == 2);
615 urlA = urls[0];
616 urlB = urls[1];
617 break;
618 }
619
620 case 1: {
621 urlA = urls[0];
622 Q_ASSERT(m_viewTab[m_tabIndex].secondaryView != 0);
623 urls = m_viewTab[m_tabIndex].secondaryView->view()->selectedUrls();
624 Q_ASSERT(urls.count() == 1);
625 urlB = urls[0];
626 break;
627 }
628
629 case 2: {
630 urlA = urls[0];
631 urlB = urls[1];
632 break;
633 }
634
635 default: {
636 // may not happen: compareFiles may only get invoked if 2
637 // files are selected
638 Q_ASSERT(false);
639 }
640 }
641
642 QString command("kompare -c \"");
643 command.append(urlA.pathOrUrl());
644 command.append("\" \"");
645 command.append(urlB.pathOrUrl());
646 command.append('\"');
647 KRun::runCommand(command, "Kompare", "kompare", this);
648 }
649
650 void DolphinMainWindow::toggleShowMenuBar()
651 {
652 const bool visible = menuBar()->isVisible();
653 menuBar()->setVisible(!visible);
654 }
655
656 void DolphinMainWindow::editSettings()
657 {
658 DolphinSettingsDialog dialog(this);
659 dialog.exec();
660 }
661
662 void DolphinMainWindow::setActiveTab(int index)
663 {
664 Q_ASSERT(index >= 0);
665 Q_ASSERT(index < m_viewTab.count());
666 if (index == m_tabIndex) {
667 return;
668 }
669
670 // hide current tab content
671 m_viewTab[m_tabIndex].isPrimaryViewActive = m_viewTab[m_tabIndex].primaryView->isActive();
672 QSplitter* splitter = m_viewTab[m_tabIndex].splitter;
673 splitter->hide();
674 m_centralWidgetLayout->removeWidget(splitter);
675
676 // show active tab content
677 m_tabIndex = index;
678
679 ViewTab& viewTab = m_viewTab[index];
680 m_centralWidgetLayout->addWidget(viewTab.splitter);
681 viewTab.primaryView->show();
682 if (viewTab.secondaryView != 0) {
683 viewTab.secondaryView->show();
684 }
685 viewTab.splitter->show();
686
687 setActiveViewContainer(viewTab.isPrimaryViewActive ? viewTab.primaryView :
688 viewTab.secondaryView);
689 }
690
691 void DolphinMainWindow::closeTab()
692 {
693 closeTab(m_tabBar->currentIndex());
694 }
695
696 void DolphinMainWindow::closeTab(int index)
697 {
698 Q_ASSERT(index >= 0);
699 Q_ASSERT(index < m_viewTab.count());
700 if (m_viewTab.count() == 1) {
701 // the last tab may never get closed
702 return;
703 }
704
705 if (index == m_tabIndex) {
706 // The tab that should be closed is the active tab. Activate the
707 // previous tab before closing the tab.
708 setActiveTab((index > 0) ? index - 1 : 1);
709 }
710
711 // delete tab
712 m_viewTab[index].primaryView->deleteLater();
713 if (m_viewTab[index].secondaryView != 0) {
714 m_viewTab[index].secondaryView->deleteLater();
715 }
716 m_viewTab[index].splitter->deleteLater();
717 m_viewTab.erase(m_viewTab.begin() + index);
718
719 m_tabBar->blockSignals(true);
720 m_tabBar->removeTab(index);
721
722 if (m_tabIndex > index) {
723 m_tabIndex--;
724 Q_ASSERT(m_tabIndex >= 0);
725 }
726
727 // if only one tab is left, also remove the tab entry so that
728 // closing the last tab is not possible
729 if (m_viewTab.count() == 1) {
730 m_tabBar->removeTab(0);
731 } else {
732 m_tabBar->blockSignals(false);
733 }
734 }
735
736 void DolphinMainWindow::openTabContextMenu(int index, const QPoint& pos)
737 {
738 KMenu menu(this);
739
740 QAction* newTabAction = menu.addAction(KIcon("tab-new"), i18nc("@action:inmenu", "New Tab"));
741 newTabAction->setShortcut(actionCollection()->action("new_tab")->shortcut());
742
743 QAction* closeOtherTabsAction = menu.addAction(KIcon("tab-close"), i18nc("@action:inmenu", "Close Other Tabs"));
744
745 QAction* closeTabAction = menu.addAction(KIcon("tab-close"), i18nc("@action:inmenu", "Close Tab"));
746 closeTabAction->setShortcut(actionCollection()->action("close_tab")->shortcut());
747
748 QAction* selectedAction = menu.exec(pos);
749 if (selectedAction == newTabAction) {
750 const ViewTab& tab = m_viewTab[index];
751 Q_ASSERT(tab.primaryView != 0);
752 const KUrl url = (tab.secondaryView != 0) && tab.secondaryView->isActive() ?
753 tab.secondaryView->url() : tab.primaryView->url();
754 openNewTab(url);
755 m_tabBar->setCurrentIndex(m_viewTab.count() - 1);
756 } else if (selectedAction == closeOtherTabsAction) {
757 const int count = m_tabBar->count();
758 for (int i = 0; i < index; ++i) {
759 closeTab(0);
760 }
761 for (int i = index + 1; i < count; ++i) {
762 closeTab(1);
763 }
764 } else if (selectedAction == closeTabAction) {
765 closeTab(index);
766 }
767 }
768
769 void DolphinMainWindow::init()
770 {
771 DolphinSettings& settings = DolphinSettings::instance();
772
773 // Check whether Dolphin runs the first time. If yes then
774 // a proper default window size is given at the end of DolphinMainWindow::init().
775 GeneralSettings* generalSettings = settings.generalSettings();
776 const bool firstRun = generalSettings->firstRun();
777 if (firstRun) {
778 generalSettings->setViewPropsTimestamp(QDateTime::currentDateTime());
779 }
780
781 setAcceptDrops(true);
782
783 m_viewTab[m_tabIndex].splitter = new QSplitter(this);
784
785 setupActions();
786
787 const KUrl& homeUrl = generalSettings->homeUrl();
788 setCaption(homeUrl.fileName());
789 m_actionHandler = new DolphinViewActionHandler(actionCollection(), this);
790 connect(m_actionHandler, SIGNAL(actionBeingHandled()), SLOT(clearStatusBar()));
791 ViewProperties props(homeUrl);
792 m_viewTab[m_tabIndex].primaryView = new DolphinViewContainer(this,
793 m_viewTab[m_tabIndex].splitter,
794 homeUrl);
795
796 m_activeViewContainer = m_viewTab[m_tabIndex].primaryView;
797 connectViewSignals(m_activeViewContainer);
798 DolphinView* view = m_activeViewContainer->view();
799 view->reload();
800 m_activeViewContainer->show();
801 m_actionHandler->setCurrentView(view);
802
803 m_tabBar = new KTabBar(this);
804 m_tabBar->setCloseButtonEnabled(true);
805 connect(m_tabBar, SIGNAL(currentChanged(int)),
806 this, SLOT(setActiveTab(int)));
807 connect(m_tabBar, SIGNAL(closeRequest(int)),
808 this, SLOT(closeTab(int)));
809 connect(m_tabBar, SIGNAL(contextMenu(int, const QPoint&)),
810 this, SLOT(openTabContextMenu(int, const QPoint&)));
811 m_tabBar->blockSignals(true); // signals get unblocked after at least 2 tabs are open
812
813 QWidget* centralWidget = new QWidget(this);
814 m_centralWidgetLayout = new QVBoxLayout(centralWidget);
815 m_centralWidgetLayout->setSpacing(0);
816 m_centralWidgetLayout->setMargin(0);
817 m_centralWidgetLayout->addWidget(m_tabBar);
818 m_centralWidgetLayout->addWidget(m_viewTab[m_tabIndex].splitter);
819
820
821 setCentralWidget(centralWidget);
822 setupDockWidgets();
823
824 setupGUI(Keys | Save | Create | ToolBar);
825 createGUI();
826
827 stateChanged("new_file");
828 setAutoSaveSettings();
829
830 QClipboard* clipboard = QApplication::clipboard();
831 connect(clipboard, SIGNAL(dataChanged()),
832 this, SLOT(updatePasteAction()));
833 updatePasteAction();
834 updateGoActions();
835
836 if (generalSettings->splitView()) {
837 toggleSplitView();
838 }
839 updateViewActions();
840
841 if (firstRun) {
842 // assure a proper default size if Dolphin runs the first time
843 resize(750, 500);
844 }
845
846 emit urlChanged(homeUrl);
847 }
848
849 void DolphinMainWindow::setActiveViewContainer(DolphinViewContainer* viewContainer)
850 {
851 Q_ASSERT(viewContainer != 0);
852 Q_ASSERT((viewContainer == m_viewTab[m_tabIndex].primaryView) ||
853 (viewContainer == m_viewTab[m_tabIndex].secondaryView));
854 if (m_activeViewContainer == viewContainer) {
855 return;
856 }
857
858 m_activeViewContainer->setActive(false);
859 m_activeViewContainer = viewContainer;
860
861 // Activating the view container might trigger a recursive setActiveViewContainer() call
862 // inside DolphinMainWindow::toggleActiveView() when having a split view. Temporary
863 // disconnect the activated() signal in this case:
864 disconnect(m_activeViewContainer->view(), SIGNAL(activated()), this, SLOT(toggleActiveView()));
865 m_activeViewContainer->setActive(true);
866 connect(m_activeViewContainer->view(), SIGNAL(activated()), this, SLOT(toggleActiveView()));
867
868 m_actionHandler->setCurrentView(viewContainer->view());
869
870 updateHistory();
871 updateEditActions();
872 updateViewActions();
873 updateGoActions();
874
875 const KUrl& url = m_activeViewContainer->url();
876 setCaption(url.fileName());
877 if (m_viewTab.count() > 1) {
878 m_tabBar->setTabText(m_tabIndex, tabName(url));
879 }
880
881 emit urlChanged(url);
882 }
883
884 void DolphinMainWindow::setupActions()
885 {
886 // setup 'File' menu
887 m_newMenu = new DolphinNewMenu(this);
888 KMenu* menu = m_newMenu->menu();
889 menu->setTitle(i18nc("@title:menu Create new folder, file, link, etc.", "Create New"));
890 menu->setIcon(KIcon("document-new"));
891 connect(menu, SIGNAL(aboutToShow()),
892 this, SLOT(updateNewMenu()));
893
894 KAction* newWindow = actionCollection()->addAction("new_window");
895 newWindow->setIcon(KIcon("window-new"));
896 newWindow->setText(i18nc("@action:inmenu File", "New &Window"));
897 newWindow->setShortcut(Qt::CTRL | Qt::Key_N);
898 connect(newWindow, SIGNAL(triggered()), this, SLOT(openNewMainWindow()));
899
900 KAction* newTab = actionCollection()->addAction("new_tab");
901 newTab->setIcon(KIcon("tab-new"));
902 newTab->setText(i18nc("@action:inmenu File", "New Tab"));
903 newTab->setShortcut(Qt::CTRL | Qt::SHIFT | Qt::Key_N);
904 connect(newTab, SIGNAL(triggered()), this, SLOT(openNewTab()));
905
906 QAction* closeTab = new QAction(KIcon("tab-close"), i18nc("@action:inmenu File", "Close Tab"), this);
907 closeTab->setShortcut(Qt::CTRL | Qt::Key_W);
908 connect(closeTab, SIGNAL(triggered()), this, SLOT(closeTab()));
909 actionCollection()->addAction("close_tab", closeTab);
910
911 KAction* properties = actionCollection()->addAction("properties");
912 properties->setText(i18nc("@action:inmenu File", "Properties"));
913 properties->setShortcut(Qt::ALT | Qt::Key_Return);
914 connect(properties, SIGNAL(triggered()), this, SLOT(properties()));
915
916 KStandardAction::quit(this, SLOT(quit()), actionCollection());
917
918 // setup 'Edit' menu
919 KStandardAction::undo(this,
920 SLOT(undo()),
921 actionCollection());
922
923 // need to remove shift+del from cut action, else the shortcut for deletejob
924 // doesn't work
925 KAction* cut = KStandardAction::cut(this, SLOT(cut()), actionCollection());
926 KShortcut cutShortcut = cut->shortcut();
927 cutShortcut.remove(Qt::SHIFT + Qt::Key_Delete, KShortcut::KeepEmpty);
928 cut->setShortcut(cutShortcut);
929 KStandardAction::copy(this, SLOT(copy()), actionCollection());
930 KStandardAction::paste(this, SLOT(paste()), actionCollection());
931
932 KAction* selectAll = actionCollection()->addAction("select_all");
933 selectAll->setText(i18nc("@action:inmenu Edit", "Select All"));
934 selectAll->setShortcut(Qt::CTRL + Qt::Key_A);
935 connect(selectAll, SIGNAL(triggered()), this, SLOT(selectAll()));
936
937 KAction* invertSelection = actionCollection()->addAction("invert_selection");
938 invertSelection->setText(i18nc("@action:inmenu Edit", "Invert Selection"));
939 invertSelection->setShortcut(Qt::CTRL | Qt::SHIFT | Qt::Key_A);
940 connect(invertSelection, SIGNAL(triggered()), this, SLOT(invertSelection()));
941
942 // setup 'View' menu
943 // (note that most of it is set up in DolphinViewActionHandler)
944
945 KAction* split = actionCollection()->addAction("split_view");
946 split->setShortcut(Qt::Key_F3);
947 updateSplitAction();
948 connect(split, SIGNAL(triggered()), this, SLOT(toggleSplitView()));
949
950 KAction* reload = actionCollection()->addAction("reload");
951 reload->setText(i18nc("@action:inmenu View", "Reload"));
952 reload->setShortcut(Qt::Key_F5);
953 reload->setIcon(KIcon("view-refresh"));
954 connect(reload, SIGNAL(triggered()), this, SLOT(reloadView()));
955
956 KAction* stop = actionCollection()->addAction("stop");
957 stop->setText(i18nc("@action:inmenu View", "Stop"));
958 stop->setIcon(KIcon("process-stop"));
959 connect(stop, SIGNAL(triggered()), this, SLOT(stopLoading()));
960
961 // TODO: the naming "Show full Location" is currently confusing...
962 KToggleAction* showFullLocation = actionCollection()->add<KToggleAction>("editable_location");
963 showFullLocation->setText(i18nc("@action:inmenu Navigation Bar", "Show Full Location"));
964 showFullLocation->setShortcut(Qt::CTRL | Qt::Key_L);
965 connect(showFullLocation, SIGNAL(triggered()), this, SLOT(toggleEditLocation()));
966
967 KAction* editLocation = actionCollection()->addAction("edit_location");
968 editLocation->setText(i18nc("@action:inmenu Navigation Bar", "Edit Location"));
969 editLocation->setShortcut(Qt::Key_F6);
970 connect(editLocation, SIGNAL(triggered()), this, SLOT(editLocation()));
971
972 KAction* adjustViewProps = actionCollection()->addAction("view_properties");
973 adjustViewProps->setText(i18nc("@action:inmenu View", "Adjust View Properties..."));
974 connect(adjustViewProps, SIGNAL(triggered()), this, SLOT(adjustViewProperties()));
975
976 // setup 'Go' menu
977 KAction* backAction = KStandardAction::back(this, SLOT(goBack()), actionCollection());
978 KShortcut backShortcut = backAction->shortcut();
979 backShortcut.setAlternate(Qt::Key_Backspace);
980 backAction->setShortcut(backShortcut);
981
982 KStandardAction::forward(this, SLOT(goForward()), actionCollection());
983 KStandardAction::up(this, SLOT(goUp()), actionCollection());
984 KStandardAction::home(this, SLOT(goHome()), actionCollection());
985
986 // setup 'Tools' menu
987 QAction* findFile = actionCollection()->addAction("find_file");
988 findFile->setText(i18nc("@action:inmenu Tools", "Find File..."));
989 findFile->setShortcut(Qt::CTRL | Qt::Key_F);
990 findFile->setIcon(KIcon("edit-find"));
991 connect(findFile, SIGNAL(triggered()), this, SLOT(findFile()));
992
993 KToggleAction* showFilterBar = actionCollection()->add<KToggleAction>("show_filter_bar");
994 showFilterBar->setText(i18nc("@action:inmenu Tools", "Show Filter Bar"));
995 showFilterBar->setShortcut(Qt::CTRL | Qt::Key_I);
996 connect(showFilterBar, SIGNAL(triggered(bool)), this, SLOT(toggleFilterBarVisibility(bool)));
997
998 KAction* compareFiles = actionCollection()->addAction("compare_files");
999 compareFiles->setText(i18nc("@action:inmenu Tools", "Compare Files"));
1000 compareFiles->setIcon(KIcon("kompare"));
1001 compareFiles->setEnabled(false);
1002 connect(compareFiles, SIGNAL(triggered()), this, SLOT(compareFiles()));
1003
1004 // setup 'Settings' menu
1005 m_showMenuBar = KStandardAction::showMenubar(this, SLOT(toggleShowMenuBar()), actionCollection());
1006 KStandardAction::preferences(this, SLOT(editSettings()), actionCollection());
1007 }
1008
1009 void DolphinMainWindow::setupDockWidgets()
1010 {
1011 // setup "Information"
1012 QDockWidget* infoDock = new QDockWidget(i18nc("@title:window", "Information"));
1013 infoDock->setObjectName("infoDock");
1014 infoDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
1015 SidebarPage* infoWidget = new InfoSidebarPage(infoDock);
1016 infoDock->setWidget(infoWidget);
1017
1018 infoDock->toggleViewAction()->setText(i18nc("@title:window", "Information"));
1019 infoDock->toggleViewAction()->setShortcut(Qt::Key_F11);
1020 actionCollection()->addAction("show_info_panel", infoDock->toggleViewAction());
1021
1022 addDockWidget(Qt::RightDockWidgetArea, infoDock);
1023 connect(this, SIGNAL(urlChanged(KUrl)),
1024 infoWidget, SLOT(setUrl(KUrl)));
1025 connect(this, SIGNAL(selectionChanged(KFileItemList)),
1026 infoWidget, SLOT(setSelection(KFileItemList)));
1027 connect(this, SIGNAL(requestItemInfo(KFileItem)),
1028 infoWidget, SLOT(requestDelayedItemInfo(KFileItem)));
1029
1030 // setup "Tree View"
1031 QDockWidget* treeViewDock = new QDockWidget(i18nc("@title:window", "Folders"));
1032 treeViewDock->setObjectName("treeViewDock");
1033 treeViewDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
1034 TreeViewSidebarPage* treeWidget = new TreeViewSidebarPage(treeViewDock);
1035 treeViewDock->setWidget(treeWidget);
1036
1037 treeViewDock->toggleViewAction()->setText(i18nc("@title:window", "Folders"));
1038 treeViewDock->toggleViewAction()->setShortcut(Qt::Key_F7);
1039 actionCollection()->addAction("show_folders_panel", treeViewDock->toggleViewAction());
1040
1041 addDockWidget(Qt::LeftDockWidgetArea, treeViewDock);
1042 connect(this, SIGNAL(urlChanged(KUrl)),
1043 treeWidget, SLOT(setUrl(KUrl)));
1044 connect(treeWidget, SIGNAL(changeUrl(KUrl)),
1045 this, SLOT(changeUrl(KUrl)));
1046 connect(treeWidget, SIGNAL(changeSelection(KFileItemList)),
1047 this, SLOT(changeSelection(KFileItemList)));
1048 connect(treeWidget, SIGNAL(urlsDropped(KUrl::List, KUrl)),
1049 this, SLOT(dropUrls(KUrl::List, KUrl)));
1050
1051 // setup "Terminal"
1052 #ifndef Q_OS_WIN
1053 QDockWidget* terminalDock = new QDockWidget(i18nc("@title:window Shell terminal", "Terminal"));
1054 terminalDock->setObjectName("terminalDock");
1055 terminalDock->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
1056 SidebarPage* terminalWidget = new TerminalSidebarPage(terminalDock);
1057 terminalDock->setWidget(terminalWidget);
1058
1059 connect(terminalWidget, SIGNAL(hideTerminalSidebarPage()), terminalDock, SLOT(hide()));
1060
1061 terminalDock->toggleViewAction()->setText(i18nc("@title:window Shell terminal", "Terminal"));
1062 terminalDock->toggleViewAction()->setShortcut(Qt::Key_F4);
1063 actionCollection()->addAction("show_terminal_panel", terminalDock->toggleViewAction());
1064
1065 addDockWidget(Qt::BottomDockWidgetArea, terminalDock);
1066 connect(this, SIGNAL(urlChanged(KUrl)),
1067 terminalWidget, SLOT(setUrl(KUrl)));
1068 #endif
1069
1070 const bool firstRun = DolphinSettings::instance().generalSettings()->firstRun();
1071 if (firstRun) {
1072 treeViewDock->hide();
1073 #ifndef Q_OS_WIN
1074 terminalDock->hide();
1075 #endif
1076 }
1077
1078 QDockWidget* placesDock = new QDockWidget(i18nc("@title:window", "Places"));
1079 placesDock->setObjectName("placesDock");
1080 placesDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
1081
1082 DolphinFilePlacesView* placesView = new DolphinFilePlacesView(placesDock);
1083 placesDock->setWidget(placesView);
1084 placesView->setModel(DolphinSettings::instance().placesModel());
1085 placesView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1086
1087 placesDock->toggleViewAction()->setText(i18nc("@title:window", "Places"));
1088 placesDock->toggleViewAction()->setShortcut(Qt::Key_F9);
1089 actionCollection()->addAction("show_places_panel", placesDock->toggleViewAction());
1090
1091 addDockWidget(Qt::LeftDockWidgetArea, placesDock);
1092 connect(placesView, SIGNAL(urlChanged(KUrl)),
1093 this, SLOT(changeUrl(KUrl)));
1094 connect(this, SIGNAL(urlChanged(KUrl)),
1095 placesView, SLOT(setUrl(KUrl)));
1096 }
1097
1098 void DolphinMainWindow::updateEditActions()
1099 {
1100 const KFileItemList list = m_activeViewContainer->view()->selectedItems();
1101 if (list.isEmpty()) {
1102 stateChanged("has_no_selection");
1103 } else {
1104 stateChanged("has_selection");
1105
1106 FileItemCapabilities capabilities(list);
1107 actionCollection()->action("rename")->setEnabled(capabilities.supportsMoving());
1108 const bool enableMoveToTrash = capabilities.isLocal() && capabilities.supportsMoving();
1109 actionCollection()->action("move_to_trash")->setEnabled(enableMoveToTrash);
1110 actionCollection()->action("delete")->setEnabled(capabilities.supportsDeleting());
1111 }
1112 updatePasteAction();
1113 }
1114
1115 void DolphinMainWindow::updateViewActions()
1116 {
1117 m_actionHandler->updateViewActions();
1118
1119 QAction* showFilterBarAction = actionCollection()->action("show_filter_bar");
1120 showFilterBarAction->setChecked(m_activeViewContainer->isFilterBarVisible());
1121
1122 updateSplitAction();
1123
1124 QAction* editableLocactionAction = actionCollection()->action("editable_location");
1125 const KUrlNavigator* urlNavigator = m_activeViewContainer->urlNavigator();
1126 editableLocactionAction->setChecked(urlNavigator->isUrlEditable());
1127 }
1128
1129 void DolphinMainWindow::updateGoActions()
1130 {
1131 QAction* goUpAction = actionCollection()->action(KStandardAction::name(KStandardAction::Up));
1132 const KUrl& currentUrl = m_activeViewContainer->url();
1133 goUpAction->setEnabled(currentUrl.upUrl() != currentUrl);
1134 }
1135
1136 void DolphinMainWindow::clearStatusBar()
1137 {
1138 m_activeViewContainer->statusBar()->clear();
1139 }
1140
1141 void DolphinMainWindow::connectViewSignals(DolphinViewContainer* container)
1142 {
1143 connect(container, SIGNAL(showFilterBarChanged(bool)),
1144 this, SLOT(updateFilterBarAction(bool)));
1145
1146 DolphinView* view = container->view();
1147 connect(view, SIGNAL(selectionChanged(KFileItemList)),
1148 this, SLOT(slotSelectionChanged(KFileItemList)));
1149 connect(view, SIGNAL(requestItemInfo(KFileItem)),
1150 this, SLOT(slotRequestItemInfo(KFileItem)));
1151 connect(view, SIGNAL(activated()),
1152 this, SLOT(toggleActiveView()));
1153 connect(view, SIGNAL(doingOperation(KonqFileUndoManager::CommandType)),
1154 this, SLOT(slotDoingOperation(KonqFileUndoManager::CommandType)));
1155 connect(view, SIGNAL(tabRequested(const KUrl&)),
1156 this, SLOT(openNewTab(const KUrl&)));
1157
1158 const KUrlNavigator* navigator = container->urlNavigator();
1159 connect(navigator, SIGNAL(urlChanged(const KUrl&)),
1160 this, SLOT(changeUrl(const KUrl&)));
1161 connect(navigator, SIGNAL(historyChanged()),
1162 this, SLOT(updateHistory()));
1163 connect(navigator, SIGNAL(editableStateChanged(bool)),
1164 this, SLOT(slotEditableStateChanged(bool)));
1165 }
1166
1167 void DolphinMainWindow::updateSplitAction()
1168 {
1169 QAction* splitAction = actionCollection()->action("split_view");
1170 if (m_viewTab[m_tabIndex].secondaryView != 0) {
1171 if (m_activeViewContainer == m_viewTab[m_tabIndex].primaryView) {
1172 splitAction->setText(i18nc("@action:intoolbar Close right view", "Close"));
1173 splitAction->setIcon(KIcon("view-right-close"));
1174 } else {
1175 splitAction->setText(i18nc("@action:intoolbar Close left view", "Close"));
1176 splitAction->setIcon(KIcon("view-left-close"));
1177 }
1178 } else {
1179 splitAction->setText(i18nc("@action:intoolbar Split view", "Split"));
1180 splitAction->setIcon(KIcon("view-right-new"));
1181 }
1182 }
1183
1184 QString DolphinMainWindow::tabName(const KUrl& url) const
1185 {
1186 return url.equals(KUrl("file:///")) ? "/" : url.fileName();
1187 }
1188
1189 DolphinMainWindow::UndoUiInterface::UndoUiInterface() :
1190 KonqFileUndoManager::UiInterface()
1191 {
1192 }
1193
1194 DolphinMainWindow::UndoUiInterface::~UndoUiInterface()
1195 {
1196 }
1197
1198 void DolphinMainWindow::UndoUiInterface::jobError(KIO::Job* job)
1199 {
1200 DolphinMainWindow* mainWin= qobject_cast<DolphinMainWindow *>(parentWidget());
1201 if (mainWin) {
1202 DolphinStatusBar* statusBar = mainWin->activeViewContainer()->statusBar();
1203 statusBar->setMessage(job->errorString(), DolphinStatusBar::Error);
1204 } else {
1205 KonqFileUndoManager::UiInterface::jobError(job);
1206 }
1207 }
1208
1209 #include "dolphinmainwindow.moc"