]> cloud.milkyroute.net Git - dolphin.git/blob - src/dolphinmainwindow.cpp
Ooops, fix name of componentdata so that the dolphinpart GUI is found again.
[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 KIO::FileUndoManager* undoManager = KIO::FileUndoManager::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(KIO::FileUndoManager::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(KIO::FileUndoManager::CommandType)),
164 this, SLOT(slotDoingOperation(KIO::FileUndoManager::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 KIO::FileUndoManager::CommandType command = m_undoCommandTypes.takeFirst();
391 DolphinStatusBar* statusBar = m_activeViewContainer->statusBar();
392 switch (command) {
393 case KIO::FileUndoManager::Copy:
394 statusBar->setMessage(i18nc("@info:status", "Copy operation completed."),
395 DolphinStatusBar::OperationCompleted);
396 break;
397 case KIO::FileUndoManager::Move:
398 statusBar->setMessage(i18nc("@info:status", "Move operation completed."),
399 DolphinStatusBar::OperationCompleted);
400 break;
401 case KIO::FileUndoManager::Link:
402 statusBar->setMessage(i18nc("@info:status", "Link operation completed."),
403 DolphinStatusBar::OperationCompleted);
404 break;
405 case KIO::FileUndoManager::Trash:
406 statusBar->setMessage(i18nc("@info:status", "Move to trash operation completed."),
407 DolphinStatusBar::OperationCompleted);
408 break;
409 case KIO::FileUndoManager::Rename:
410 statusBar->setMessage(i18nc("@info:status", "Renaming operation completed."),
411 DolphinStatusBar::OperationCompleted);
412 break;
413
414 case KIO::FileUndoManager::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 KIO::FileUndoManager::self()->uiInterface()->setParentWidget(this);
438 KIO::FileUndoManager::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
504 setActiveViewContainer(m_viewTab[m_tabIndex].secondaryView);
505 } else if (m_activeViewContainer == m_viewTab[m_tabIndex].primaryView) {
506 // remove secondary view
507 m_viewTab[m_tabIndex].secondaryView->close();
508 m_viewTab[m_tabIndex].secondaryView->deleteLater();
509 m_viewTab[m_tabIndex].secondaryView = 0;
510
511 setActiveViewContainer(m_viewTab[m_tabIndex].primaryView);
512 } else {
513 // The secondary view is active, hence from a users point of view
514 // the content of the secondary view should be moved to the primary view.
515 // From an implementation point of view it is more efficient to close
516 // the primary view and exchange the internal pointers afterwards.
517
518 m_viewTab[m_tabIndex].primaryView->close();
519 m_viewTab[m_tabIndex].primaryView->deleteLater();
520 m_viewTab[m_tabIndex].primaryView = m_viewTab[m_tabIndex].secondaryView;
521 m_viewTab[m_tabIndex].secondaryView = 0;
522
523 setActiveViewContainer(m_viewTab[m_tabIndex].primaryView);
524 }
525
526 updateViewActions();
527 }
528
529 void DolphinMainWindow::reloadView()
530 {
531 clearStatusBar();
532 m_activeViewContainer->view()->reload();
533 }
534
535 void DolphinMainWindow::stopLoading()
536 {
537 }
538
539 void DolphinMainWindow::toggleFilterBarVisibility(bool show)
540 {
541 m_activeViewContainer->showFilterBar(show);
542 }
543
544 void DolphinMainWindow::toggleEditLocation()
545 {
546 clearStatusBar();
547
548 QAction* action = actionCollection()->action("editable_location");
549 KUrlNavigator* urlNavigator = m_activeViewContainer->urlNavigator();
550 urlNavigator->setUrlEditable(action->isChecked());
551 }
552
553 void DolphinMainWindow::editLocation()
554 {
555 KUrlNavigator* navigator = m_activeViewContainer->urlNavigator();
556 navigator->setUrlEditable(true);
557 navigator->setFocus();
558
559 // select the whole text of the combo box editor
560 QLineEdit* lineEdit = navigator->editor()->lineEdit();
561 const QString text = lineEdit->text();
562 lineEdit->setSelection(0, text.length());
563 }
564
565 void DolphinMainWindow::adjustViewProperties()
566 {
567 clearStatusBar();
568 ViewPropertiesDialog dlg(m_activeViewContainer->view());
569 dlg.exec();
570 }
571
572 void DolphinMainWindow::goBack()
573 {
574 clearStatusBar();
575 m_activeViewContainer->urlNavigator()->goBack();
576 }
577
578 void DolphinMainWindow::goForward()
579 {
580 clearStatusBar();
581 m_activeViewContainer->urlNavigator()->goForward();
582 }
583
584 void DolphinMainWindow::goUp()
585 {
586 clearStatusBar();
587 m_activeViewContainer->urlNavigator()->goUp();
588 }
589
590 void DolphinMainWindow::goHome()
591 {
592 clearStatusBar();
593 m_activeViewContainer->urlNavigator()->goHome();
594 }
595
596 void DolphinMainWindow::findFile()
597 {
598 KRun::run("kfind", m_activeViewContainer->url(), this);
599 }
600
601 void DolphinMainWindow::compareFiles()
602 {
603 // The method is only invoked if exactly 2 files have
604 // been selected. The selected files may be:
605 // - both in the primary view
606 // - both in the secondary view
607 // - one in the primary view and the other in the secondary
608 // view
609 Q_ASSERT(m_viewTab[m_tabIndex].primaryView != 0);
610
611 KUrl urlA;
612 KUrl urlB;
613 KUrl::List urls = m_viewTab[m_tabIndex].primaryView->view()->selectedUrls();
614
615 switch (urls.count()) {
616 case 0: {
617 Q_ASSERT(m_viewTab[m_tabIndex].secondaryView != 0);
618 urls = m_viewTab[m_tabIndex].secondaryView->view()->selectedUrls();
619 Q_ASSERT(urls.count() == 2);
620 urlA = urls[0];
621 urlB = urls[1];
622 break;
623 }
624
625 case 1: {
626 urlA = urls[0];
627 Q_ASSERT(m_viewTab[m_tabIndex].secondaryView != 0);
628 urls = m_viewTab[m_tabIndex].secondaryView->view()->selectedUrls();
629 Q_ASSERT(urls.count() == 1);
630 urlB = urls[0];
631 break;
632 }
633
634 case 2: {
635 urlA = urls[0];
636 urlB = urls[1];
637 break;
638 }
639
640 default: {
641 // may not happen: compareFiles may only get invoked if 2
642 // files are selected
643 Q_ASSERT(false);
644 }
645 }
646
647 QString command("kompare -c \"");
648 command.append(urlA.pathOrUrl());
649 command.append("\" \"");
650 command.append(urlB.pathOrUrl());
651 command.append('\"');
652 KRun::runCommand(command, "Kompare", "kompare", this);
653 }
654
655 void DolphinMainWindow::toggleShowMenuBar()
656 {
657 const bool visible = menuBar()->isVisible();
658 menuBar()->setVisible(!visible);
659 }
660
661 void DolphinMainWindow::editSettings()
662 {
663 DolphinSettingsDialog dialog(this);
664 dialog.exec();
665 }
666
667 void DolphinMainWindow::setActiveTab(int index)
668 {
669 Q_ASSERT(index >= 0);
670 Q_ASSERT(index < m_viewTab.count());
671 if (index == m_tabIndex) {
672 return;
673 }
674
675 // hide current tab content
676 m_viewTab[m_tabIndex].isPrimaryViewActive = m_viewTab[m_tabIndex].primaryView->isActive();
677 QSplitter* splitter = m_viewTab[m_tabIndex].splitter;
678 splitter->hide();
679 m_centralWidgetLayout->removeWidget(splitter);
680
681 // show active tab content
682 m_tabIndex = index;
683
684 ViewTab& viewTab = m_viewTab[index];
685 m_centralWidgetLayout->addWidget(viewTab.splitter);
686 viewTab.primaryView->show();
687 if (viewTab.secondaryView != 0) {
688 viewTab.secondaryView->show();
689 }
690 viewTab.splitter->show();
691
692 setActiveViewContainer(viewTab.isPrimaryViewActive ? viewTab.primaryView :
693 viewTab.secondaryView);
694 }
695
696 void DolphinMainWindow::closeTab()
697 {
698 closeTab(m_tabBar->currentIndex());
699 }
700
701 void DolphinMainWindow::closeTab(int index)
702 {
703 Q_ASSERT(index >= 0);
704 Q_ASSERT(index < m_viewTab.count());
705 if (m_viewTab.count() == 1) {
706 // the last tab may never get closed
707 return;
708 }
709
710 if (index == m_tabIndex) {
711 // The tab that should be closed is the active tab. Activate the
712 // previous tab before closing the tab.
713 setActiveTab((index > 0) ? index - 1 : 1);
714 }
715
716 // delete tab
717 m_viewTab[index].primaryView->deleteLater();
718 if (m_viewTab[index].secondaryView != 0) {
719 m_viewTab[index].secondaryView->deleteLater();
720 }
721 m_viewTab[index].splitter->deleteLater();
722 m_viewTab.erase(m_viewTab.begin() + index);
723
724 m_tabBar->blockSignals(true);
725 m_tabBar->removeTab(index);
726
727 if (m_tabIndex > index) {
728 m_tabIndex--;
729 Q_ASSERT(m_tabIndex >= 0);
730 }
731
732 // if only one tab is left, also remove the tab entry so that
733 // closing the last tab is not possible
734 if (m_viewTab.count() == 1) {
735 m_tabBar->removeTab(0);
736 } else {
737 m_tabBar->blockSignals(false);
738 }
739 }
740
741 void DolphinMainWindow::openTabContextMenu(int index, const QPoint& pos)
742 {
743 KMenu menu(this);
744
745 QAction* newTabAction = menu.addAction(KIcon("tab-new"), i18nc("@action:inmenu", "New Tab"));
746 newTabAction->setShortcut(actionCollection()->action("new_tab")->shortcut());
747
748 QAction* closeOtherTabsAction = menu.addAction(KIcon("tab-close"), i18nc("@action:inmenu", "Close Other Tabs"));
749
750 QAction* closeTabAction = menu.addAction(KIcon("tab-close"), i18nc("@action:inmenu", "Close Tab"));
751 closeTabAction->setShortcut(actionCollection()->action("close_tab")->shortcut());
752
753 QAction* selectedAction = menu.exec(pos);
754 if (selectedAction == newTabAction) {
755 const ViewTab& tab = m_viewTab[index];
756 Q_ASSERT(tab.primaryView != 0);
757 const KUrl url = (tab.secondaryView != 0) && tab.secondaryView->isActive() ?
758 tab.secondaryView->url() : tab.primaryView->url();
759 openNewTab(url);
760 m_tabBar->setCurrentIndex(m_viewTab.count() - 1);
761 } else if (selectedAction == closeOtherTabsAction) {
762 const int count = m_tabBar->count();
763 for (int i = 0; i < index; ++i) {
764 closeTab(0);
765 }
766 for (int i = index + 1; i < count; ++i) {
767 closeTab(1);
768 }
769 } else if (selectedAction == closeTabAction) {
770 closeTab(index);
771 }
772 }
773
774 void DolphinMainWindow::init()
775 {
776 DolphinSettings& settings = DolphinSettings::instance();
777
778 // Check whether Dolphin runs the first time. If yes then
779 // a proper default window size is given at the end of DolphinMainWindow::init().
780 GeneralSettings* generalSettings = settings.generalSettings();
781 const bool firstRun = generalSettings->firstRun();
782 if (firstRun) {
783 generalSettings->setViewPropsTimestamp(QDateTime::currentDateTime());
784 }
785
786 setAcceptDrops(true);
787
788 m_viewTab[m_tabIndex].splitter = new QSplitter(this);
789
790 setupActions();
791
792 const KUrl& homeUrl = generalSettings->homeUrl();
793 setCaption(homeUrl.fileName());
794 m_actionHandler = new DolphinViewActionHandler(actionCollection(), this);
795 connect(m_actionHandler, SIGNAL(actionBeingHandled()), SLOT(clearStatusBar()));
796 ViewProperties props(homeUrl);
797 m_viewTab[m_tabIndex].primaryView = new DolphinViewContainer(this,
798 m_viewTab[m_tabIndex].splitter,
799 homeUrl);
800
801 m_activeViewContainer = m_viewTab[m_tabIndex].primaryView;
802 connectViewSignals(m_activeViewContainer);
803 DolphinView* view = m_activeViewContainer->view();
804 view->reload();
805 m_activeViewContainer->show();
806 m_actionHandler->setCurrentView(view);
807
808 m_tabBar = new KTabBar(this);
809 m_tabBar->setCloseButtonEnabled(true);
810 connect(m_tabBar, SIGNAL(currentChanged(int)),
811 this, SLOT(setActiveTab(int)));
812 connect(m_tabBar, SIGNAL(closeRequest(int)),
813 this, SLOT(closeTab(int)));
814 connect(m_tabBar, SIGNAL(contextMenu(int, const QPoint&)),
815 this, SLOT(openTabContextMenu(int, const QPoint&)));
816 connect(m_tabBar, SIGNAL(newTabRequest()),
817 this, SLOT(openNewTab()));
818 m_tabBar->blockSignals(true); // signals get unblocked after at least 2 tabs are open
819
820 QWidget* centralWidget = new QWidget(this);
821 m_centralWidgetLayout = new QVBoxLayout(centralWidget);
822 m_centralWidgetLayout->setSpacing(0);
823 m_centralWidgetLayout->setMargin(0);
824 m_centralWidgetLayout->addWidget(m_tabBar);
825 m_centralWidgetLayout->addWidget(m_viewTab[m_tabIndex].splitter);
826
827
828 setCentralWidget(centralWidget);
829 setupDockWidgets();
830
831 setupGUI(Keys | Save | Create | ToolBar);
832 createGUI();
833
834 stateChanged("new_file");
835 setAutoSaveSettings();
836
837 QClipboard* clipboard = QApplication::clipboard();
838 connect(clipboard, SIGNAL(dataChanged()),
839 this, SLOT(updatePasteAction()));
840 updatePasteAction();
841 updateGoActions();
842
843 if (generalSettings->splitView()) {
844 toggleSplitView();
845 }
846 updateViewActions();
847
848 if (firstRun) {
849 // assure a proper default size if Dolphin runs the first time
850 resize(750, 500);
851 }
852
853 emit urlChanged(homeUrl);
854 }
855
856 void DolphinMainWindow::setActiveViewContainer(DolphinViewContainer* viewContainer)
857 {
858 Q_ASSERT(viewContainer != 0);
859 Q_ASSERT((viewContainer == m_viewTab[m_tabIndex].primaryView) ||
860 (viewContainer == m_viewTab[m_tabIndex].secondaryView));
861 if (m_activeViewContainer == viewContainer) {
862 return;
863 }
864
865 m_activeViewContainer->setActive(false);
866 m_activeViewContainer = viewContainer;
867
868 // Activating the view container might trigger a recursive setActiveViewContainer() call
869 // inside DolphinMainWindow::toggleActiveView() when having a split view. Temporary
870 // disconnect the activated() signal in this case:
871 disconnect(m_activeViewContainer->view(), SIGNAL(activated()), this, SLOT(toggleActiveView()));
872 m_activeViewContainer->setActive(true);
873 connect(m_activeViewContainer->view(), SIGNAL(activated()), this, SLOT(toggleActiveView()));
874
875 m_actionHandler->setCurrentView(viewContainer->view());
876
877 updateHistory();
878 updateEditActions();
879 updateViewActions();
880 updateGoActions();
881
882 const KUrl& url = m_activeViewContainer->url();
883 setCaption(url.fileName());
884 if (m_viewTab.count() > 1) {
885 m_tabBar->setTabText(m_tabIndex, tabName(url));
886 }
887
888 emit urlChanged(url);
889 }
890
891 void DolphinMainWindow::setupActions()
892 {
893 // setup 'File' menu
894 m_newMenu = new DolphinNewMenu(this);
895 KMenu* menu = m_newMenu->menu();
896 menu->setTitle(i18nc("@title:menu Create new folder, file, link, etc.", "Create New"));
897 menu->setIcon(KIcon("document-new"));
898 connect(menu, SIGNAL(aboutToShow()),
899 this, SLOT(updateNewMenu()));
900
901 KAction* newWindow = actionCollection()->addAction("new_window");
902 newWindow->setIcon(KIcon("window-new"));
903 newWindow->setText(i18nc("@action:inmenu File", "New &Window"));
904 newWindow->setShortcut(Qt::CTRL | Qt::Key_N);
905 connect(newWindow, SIGNAL(triggered()), this, SLOT(openNewMainWindow()));
906
907 KAction* newTab = actionCollection()->addAction("new_tab");
908 newTab->setIcon(KIcon("tab-new"));
909 newTab->setText(i18nc("@action:inmenu File", "New Tab"));
910 newTab->setShortcut(Qt::CTRL | Qt::SHIFT | Qt::Key_N);
911 connect(newTab, SIGNAL(triggered()), this, SLOT(openNewTab()));
912
913 QAction* closeTab = new QAction(KIcon("tab-close"), i18nc("@action:inmenu File", "Close Tab"), this);
914 closeTab->setShortcut(Qt::CTRL | Qt::Key_W);
915 connect(closeTab, SIGNAL(triggered()), this, SLOT(closeTab()));
916 actionCollection()->addAction("close_tab", closeTab);
917
918 KAction* properties = actionCollection()->addAction("properties");
919 properties->setText(i18nc("@action:inmenu File", "Properties"));
920 properties->setShortcut(Qt::ALT | Qt::Key_Return);
921 connect(properties, SIGNAL(triggered()), this, SLOT(properties()));
922
923 KStandardAction::quit(this, SLOT(quit()), actionCollection());
924
925 // setup 'Edit' menu
926 KStandardAction::undo(this,
927 SLOT(undo()),
928 actionCollection());
929
930 // need to remove shift+del from cut action, else the shortcut for deletejob
931 // doesn't work
932 KAction* cut = KStandardAction::cut(this, SLOT(cut()), actionCollection());
933 KShortcut cutShortcut = cut->shortcut();
934 cutShortcut.remove(Qt::SHIFT + Qt::Key_Delete, KShortcut::KeepEmpty);
935 cut->setShortcut(cutShortcut);
936 KStandardAction::copy(this, SLOT(copy()), actionCollection());
937 KStandardAction::paste(this, SLOT(paste()), actionCollection());
938
939 KAction* selectAll = actionCollection()->addAction("select_all");
940 selectAll->setText(i18nc("@action:inmenu Edit", "Select All"));
941 selectAll->setShortcut(Qt::CTRL + Qt::Key_A);
942 connect(selectAll, SIGNAL(triggered()), this, SLOT(selectAll()));
943
944 KAction* invertSelection = actionCollection()->addAction("invert_selection");
945 invertSelection->setText(i18nc("@action:inmenu Edit", "Invert Selection"));
946 invertSelection->setShortcut(Qt::CTRL | Qt::SHIFT | Qt::Key_A);
947 connect(invertSelection, SIGNAL(triggered()), this, SLOT(invertSelection()));
948
949 // setup 'View' menu
950 // (note that most of it is set up in DolphinViewActionHandler)
951
952 KAction* split = actionCollection()->addAction("split_view");
953 split->setShortcut(Qt::Key_F3);
954 updateSplitAction();
955 connect(split, SIGNAL(triggered()), this, SLOT(toggleSplitView()));
956
957 KAction* reload = actionCollection()->addAction("reload");
958 reload->setText(i18nc("@action:inmenu View", "Reload"));
959 reload->setShortcut(Qt::Key_F5);
960 reload->setIcon(KIcon("view-refresh"));
961 connect(reload, SIGNAL(triggered()), this, SLOT(reloadView()));
962
963 KAction* stop = actionCollection()->addAction("stop");
964 stop->setText(i18nc("@action:inmenu View", "Stop"));
965 stop->setIcon(KIcon("process-stop"));
966 connect(stop, SIGNAL(triggered()), this, SLOT(stopLoading()));
967
968 // TODO: the naming "Show full Location" is currently confusing...
969 KToggleAction* showFullLocation = actionCollection()->add<KToggleAction>("editable_location");
970 showFullLocation->setText(i18nc("@action:inmenu Navigation Bar", "Show Full Location"));
971 showFullLocation->setShortcut(Qt::CTRL | Qt::Key_L);
972 connect(showFullLocation, SIGNAL(triggered()), this, SLOT(toggleEditLocation()));
973
974 KAction* editLocation = actionCollection()->addAction("edit_location");
975 editLocation->setText(i18nc("@action:inmenu Navigation Bar", "Edit Location"));
976 editLocation->setShortcut(Qt::Key_F6);
977 connect(editLocation, SIGNAL(triggered()), this, SLOT(editLocation()));
978
979 KAction* adjustViewProps = actionCollection()->addAction("view_properties");
980 adjustViewProps->setText(i18nc("@action:inmenu View", "Adjust View Properties..."));
981 connect(adjustViewProps, SIGNAL(triggered()), this, SLOT(adjustViewProperties()));
982
983 // setup 'Go' menu
984 KAction* backAction = KStandardAction::back(this, SLOT(goBack()), actionCollection());
985 KShortcut backShortcut = backAction->shortcut();
986 backShortcut.setAlternate(Qt::Key_Backspace);
987 backAction->setShortcut(backShortcut);
988
989 KStandardAction::forward(this, SLOT(goForward()), actionCollection());
990 KStandardAction::up(this, SLOT(goUp()), actionCollection());
991 KStandardAction::home(this, SLOT(goHome()), actionCollection());
992
993 // setup 'Tools' menu
994 QAction* findFile = actionCollection()->addAction("find_file");
995 findFile->setText(i18nc("@action:inmenu Tools", "Find File..."));
996 findFile->setShortcut(Qt::CTRL | Qt::Key_F);
997 findFile->setIcon(KIcon("edit-find"));
998 connect(findFile, SIGNAL(triggered()), this, SLOT(findFile()));
999
1000 KToggleAction* showFilterBar = actionCollection()->add<KToggleAction>("show_filter_bar");
1001 showFilterBar->setText(i18nc("@action:inmenu Tools", "Show Filter Bar"));
1002 showFilterBar->setShortcut(Qt::CTRL | Qt::Key_I);
1003 connect(showFilterBar, SIGNAL(triggered(bool)), this, SLOT(toggleFilterBarVisibility(bool)));
1004
1005 KAction* compareFiles = actionCollection()->addAction("compare_files");
1006 compareFiles->setText(i18nc("@action:inmenu Tools", "Compare Files"));
1007 compareFiles->setIcon(KIcon("kompare"));
1008 compareFiles->setEnabled(false);
1009 connect(compareFiles, SIGNAL(triggered()), this, SLOT(compareFiles()));
1010
1011 // setup 'Settings' menu
1012 m_showMenuBar = KStandardAction::showMenubar(this, SLOT(toggleShowMenuBar()), actionCollection());
1013 KStandardAction::preferences(this, SLOT(editSettings()), actionCollection());
1014 }
1015
1016 void DolphinMainWindow::setupDockWidgets()
1017 {
1018 // setup "Information"
1019 QDockWidget* infoDock = new QDockWidget(i18nc("@title:window", "Information"));
1020 infoDock->setObjectName("infoDock");
1021 infoDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
1022 SidebarPage* infoWidget = new InfoSidebarPage(infoDock);
1023 infoDock->setWidget(infoWidget);
1024
1025 infoDock->toggleViewAction()->setText(i18nc("@title:window", "Information"));
1026 infoDock->toggleViewAction()->setShortcut(Qt::Key_F11);
1027 actionCollection()->addAction("show_info_panel", infoDock->toggleViewAction());
1028
1029 addDockWidget(Qt::RightDockWidgetArea, infoDock);
1030 connect(this, SIGNAL(urlChanged(KUrl)),
1031 infoWidget, SLOT(setUrl(KUrl)));
1032 connect(this, SIGNAL(selectionChanged(KFileItemList)),
1033 infoWidget, SLOT(setSelection(KFileItemList)));
1034 connect(this, SIGNAL(requestItemInfo(KFileItem)),
1035 infoWidget, SLOT(requestDelayedItemInfo(KFileItem)));
1036
1037 // setup "Tree View"
1038 QDockWidget* treeViewDock = new QDockWidget(i18nc("@title:window", "Folders"));
1039 treeViewDock->setObjectName("treeViewDock");
1040 treeViewDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
1041 TreeViewSidebarPage* treeWidget = new TreeViewSidebarPage(treeViewDock);
1042 treeViewDock->setWidget(treeWidget);
1043
1044 treeViewDock->toggleViewAction()->setText(i18nc("@title:window", "Folders"));
1045 treeViewDock->toggleViewAction()->setShortcut(Qt::Key_F7);
1046 actionCollection()->addAction("show_folders_panel", treeViewDock->toggleViewAction());
1047
1048 addDockWidget(Qt::LeftDockWidgetArea, treeViewDock);
1049 connect(this, SIGNAL(urlChanged(KUrl)),
1050 treeWidget, SLOT(setUrl(KUrl)));
1051 connect(treeWidget, SIGNAL(changeUrl(KUrl)),
1052 this, SLOT(changeUrl(KUrl)));
1053 connect(treeWidget, SIGNAL(changeSelection(KFileItemList)),
1054 this, SLOT(changeSelection(KFileItemList)));
1055 connect(treeWidget, SIGNAL(urlsDropped(KUrl::List, KUrl)),
1056 this, SLOT(dropUrls(KUrl::List, KUrl)));
1057
1058 // setup "Terminal"
1059 #ifndef Q_OS_WIN
1060 QDockWidget* terminalDock = new QDockWidget(i18nc("@title:window Shell terminal", "Terminal"));
1061 terminalDock->setObjectName("terminalDock");
1062 terminalDock->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
1063 SidebarPage* terminalWidget = new TerminalSidebarPage(terminalDock);
1064 terminalDock->setWidget(terminalWidget);
1065
1066 connect(terminalWidget, SIGNAL(hideTerminalSidebarPage()), terminalDock, SLOT(hide()));
1067
1068 terminalDock->toggleViewAction()->setText(i18nc("@title:window Shell terminal", "Terminal"));
1069 terminalDock->toggleViewAction()->setShortcut(Qt::Key_F4);
1070 actionCollection()->addAction("show_terminal_panel", terminalDock->toggleViewAction());
1071
1072 addDockWidget(Qt::BottomDockWidgetArea, terminalDock);
1073 connect(this, SIGNAL(urlChanged(KUrl)),
1074 terminalWidget, SLOT(setUrl(KUrl)));
1075 #endif
1076
1077 const bool firstRun = DolphinSettings::instance().generalSettings()->firstRun();
1078 if (firstRun) {
1079 treeViewDock->hide();
1080 #ifndef Q_OS_WIN
1081 terminalDock->hide();
1082 #endif
1083 }
1084
1085 QDockWidget* placesDock = new QDockWidget(i18nc("@title:window", "Places"));
1086 placesDock->setObjectName("placesDock");
1087 placesDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
1088
1089 DolphinFilePlacesView* placesView = new DolphinFilePlacesView(placesDock);
1090 placesDock->setWidget(placesView);
1091 placesView->setModel(DolphinSettings::instance().placesModel());
1092 placesView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1093
1094 placesDock->toggleViewAction()->setText(i18nc("@title:window", "Places"));
1095 placesDock->toggleViewAction()->setShortcut(Qt::Key_F9);
1096 actionCollection()->addAction("show_places_panel", placesDock->toggleViewAction());
1097
1098 addDockWidget(Qt::LeftDockWidgetArea, placesDock);
1099 connect(placesView, SIGNAL(urlChanged(KUrl)),
1100 this, SLOT(changeUrl(KUrl)));
1101 connect(this, SIGNAL(urlChanged(KUrl)),
1102 placesView, SLOT(setUrl(KUrl)));
1103 }
1104
1105 void DolphinMainWindow::updateEditActions()
1106 {
1107 const KFileItemList list = m_activeViewContainer->view()->selectedItems();
1108 if (list.isEmpty()) {
1109 stateChanged("has_no_selection");
1110 } else {
1111 stateChanged("has_selection");
1112
1113 FileItemCapabilities capabilities(list);
1114 actionCollection()->action("rename")->setEnabled(capabilities.supportsMoving());
1115 const bool enableMoveToTrash = capabilities.isLocal() && capabilities.supportsMoving();
1116 actionCollection()->action("move_to_trash")->setEnabled(enableMoveToTrash);
1117 actionCollection()->action("delete")->setEnabled(capabilities.supportsDeleting());
1118 }
1119 updatePasteAction();
1120 }
1121
1122 void DolphinMainWindow::updateViewActions()
1123 {
1124 m_actionHandler->updateViewActions();
1125
1126 QAction* showFilterBarAction = actionCollection()->action("show_filter_bar");
1127 showFilterBarAction->setChecked(m_activeViewContainer->isFilterBarVisible());
1128
1129 updateSplitAction();
1130
1131 QAction* editableLocactionAction = actionCollection()->action("editable_location");
1132 const KUrlNavigator* urlNavigator = m_activeViewContainer->urlNavigator();
1133 editableLocactionAction->setChecked(urlNavigator->isUrlEditable());
1134 }
1135
1136 void DolphinMainWindow::updateGoActions()
1137 {
1138 QAction* goUpAction = actionCollection()->action(KStandardAction::name(KStandardAction::Up));
1139 const KUrl& currentUrl = m_activeViewContainer->url();
1140 goUpAction->setEnabled(currentUrl.upUrl() != currentUrl);
1141 }
1142
1143 void DolphinMainWindow::clearStatusBar()
1144 {
1145 m_activeViewContainer->statusBar()->clear();
1146 }
1147
1148 void DolphinMainWindow::connectViewSignals(DolphinViewContainer* container)
1149 {
1150 connect(container, SIGNAL(showFilterBarChanged(bool)),
1151 this, SLOT(updateFilterBarAction(bool)));
1152
1153 DolphinView* view = container->view();
1154 connect(view, SIGNAL(selectionChanged(KFileItemList)),
1155 this, SLOT(slotSelectionChanged(KFileItemList)));
1156 connect(view, SIGNAL(requestItemInfo(KFileItem)),
1157 this, SLOT(slotRequestItemInfo(KFileItem)));
1158 connect(view, SIGNAL(activated()),
1159 this, SLOT(toggleActiveView()));
1160 connect(view, SIGNAL(doingOperation(KIO::FileUndoManager::CommandType)),
1161 this, SLOT(slotDoingOperation(KIO::FileUndoManager::CommandType)));
1162 connect(view, SIGNAL(tabRequested(const KUrl&)),
1163 this, SLOT(openNewTab(const KUrl&)));
1164
1165 const KUrlNavigator* navigator = container->urlNavigator();
1166 connect(navigator, SIGNAL(urlChanged(const KUrl&)),
1167 this, SLOT(changeUrl(const KUrl&)));
1168 connect(navigator, SIGNAL(historyChanged()),
1169 this, SLOT(updateHistory()));
1170 connect(navigator, SIGNAL(editableStateChanged(bool)),
1171 this, SLOT(slotEditableStateChanged(bool)));
1172 }
1173
1174 void DolphinMainWindow::updateSplitAction()
1175 {
1176 QAction* splitAction = actionCollection()->action("split_view");
1177 if (m_viewTab[m_tabIndex].secondaryView != 0) {
1178 if (m_activeViewContainer == m_viewTab[m_tabIndex].primaryView) {
1179 splitAction->setText(i18nc("@action:intoolbar Close right view", "Close"));
1180 splitAction->setIcon(KIcon("view-right-close"));
1181 } else {
1182 splitAction->setText(i18nc("@action:intoolbar Close left view", "Close"));
1183 splitAction->setIcon(KIcon("view-left-close"));
1184 }
1185 } else {
1186 splitAction->setText(i18nc("@action:intoolbar Split view", "Split"));
1187 splitAction->setIcon(KIcon("view-right-new"));
1188 }
1189 }
1190
1191 QString DolphinMainWindow::tabName(const KUrl& url) const
1192 {
1193 return url.equals(KUrl("file:///")) ? "/" : url.fileName();
1194 }
1195
1196 DolphinMainWindow::UndoUiInterface::UndoUiInterface() :
1197 KIO::FileUndoManager::UiInterface()
1198 {
1199 }
1200
1201 DolphinMainWindow::UndoUiInterface::~UndoUiInterface()
1202 {
1203 }
1204
1205 void DolphinMainWindow::UndoUiInterface::jobError(KIO::Job* job)
1206 {
1207 DolphinMainWindow* mainWin= qobject_cast<DolphinMainWindow *>(parentWidget());
1208 if (mainWin) {
1209 DolphinStatusBar* statusBar = mainWin->activeViewContainer()->statusBar();
1210 statusBar->setMessage(job->errorString(), DolphinStatusBar::Error);
1211 } else {
1212 KIO::FileUndoManager::UiInterface::jobError(job);
1213 }
1214 }
1215
1216 #include "dolphinmainwindow.moc"