+ QString pathInsidePlace = url.path().mid(placeUrl.path().length());
+
+ if (!pathInsidePlace.isEmpty() && !pathInsidePlace.startsWith(QLatin1Char('/'))) {
+ pathInsidePlace.prepend(QLatin1Char('/'));
+ }
+
+ if (pathInsidePlace != QLatin1Char('/')) {
+ text.append(pathInsidePlace);
+ }
+ }
+ }
+
+ QAction *action = new QAction(QIcon::fromTheme(KIO::iconNameForUrl(url)), text, parent);
+ action->setData(historyIndex);
+ return action;
+}
+
+void DolphinMainWindow::slotAboutToShowBackPopupMenu()
+{
+ const KUrlNavigator *urlNavigator = m_activeViewContainer->urlNavigatorInternalWithHistory();
+ int entries = 0;
+ QMenu *menu = m_backAction->popupMenu();
+ menu->clear();
+ for (int i = urlNavigator->historyIndex() + 1; i < urlNavigator->historySize() && entries < MaxNumberOfNavigationentries; ++i, ++entries) {
+ QAction *action = urlNavigatorHistoryAction(urlNavigator, i, menu);
+ menu->addAction(action);
+ }
+}
+
+void DolphinMainWindow::slotGoBack(QAction *action)
+{
+ int gotoIndex = action->data().value<int>();
+ const KUrlNavigator *urlNavigator = m_activeViewContainer->urlNavigatorInternalWithHistory();
+ for (int i = gotoIndex - urlNavigator->historyIndex(); i > 0; --i) {
+ goBack();
+ }
+}
+
+void DolphinMainWindow::slotBackForwardActionMiddleClicked(QAction *action)
+{
+ if (action) {
+ const KUrlNavigator *urlNavigator = activeViewContainer()->urlNavigatorInternalWithHistory();
+ openNewTab(urlNavigator->locationUrl(action->data().value<int>()));
+ }
+}
+
+void DolphinMainWindow::slotAboutToShowForwardPopupMenu()
+{
+ const KUrlNavigator *urlNavigator = m_activeViewContainer->urlNavigatorInternalWithHistory();
+ int entries = 0;
+ QMenu *menu = m_forwardAction->popupMenu();
+ menu->clear();
+ for (int i = urlNavigator->historyIndex() - 1; i >= 0 && entries < MaxNumberOfNavigationentries; --i, ++entries) {
+ QAction *action = urlNavigatorHistoryAction(urlNavigator, i, menu);
+ menu->addAction(action);
+ }
+}
+
+void DolphinMainWindow::slotGoForward(QAction *action)
+{
+ int gotoIndex = action->data().value<int>();
+ const KUrlNavigator *urlNavigator = m_activeViewContainer->urlNavigatorInternalWithHistory();
+ for (int i = urlNavigator->historyIndex() - gotoIndex; i > 0; --i) {
+ goForward();
+ }
+}
+
+void DolphinMainWindow::slotSetSelectionMode(bool enabled, SelectionMode::BottomBar::Contents bottomBarContents)
+{
+ m_activeViewContainer->setSelectionModeEnabled(enabled, actionCollection(), bottomBarContents);
+}
+
+void DolphinMainWindow::selectAll()
+{
+ clearStatusBar();
+
+ // if the URL navigator is editable and focused, select the whole
+ // URL instead of all items of the view
+
+ KUrlNavigator *urlNavigator = m_activeViewContainer->urlNavigator();
+ QLineEdit *lineEdit = urlNavigator->editor()->lineEdit();
+ const bool selectUrl = urlNavigator->isUrlEditable() && lineEdit->hasFocus();
+ if (selectUrl) {
+ lineEdit->selectAll();
+ } else {
+ m_activeViewContainer->view()->selectAll();
+ }
+}
+
+void DolphinMainWindow::invertSelection()
+{
+ clearStatusBar();
+ m_activeViewContainer->view()->invertSelection();
+}
+
+void DolphinMainWindow::toggleSplitView()
+{
+ QUrl newSplitViewUrl;
+ const KFileItemList list = m_activeViewContainer->view()->selectedItems();
+ if (list.count() == 1) {
+ const KFileItem &item = list.first();
+ newSplitViewUrl = DolphinView::openItemAsFolderUrl(item);
+ }
+
+ DolphinTabPage *tabPage = m_tabWidget->currentTabPage();
+ tabPage->setSplitViewEnabled(!tabPage->splitViewEnabled(), WithAnimation, newSplitViewUrl);
+ m_tabWidget->updateTabName(m_tabWidget->indexOf(tabPage));
+ updateViewActions();
+}
+
+void DolphinMainWindow::popoutSplitView()
+{
+ DolphinTabPage *tabPage = m_tabWidget->currentTabPage();
+ if (!tabPage->splitViewEnabled())
+ return;
+ openNewWindow((GeneralSettings::closeActiveSplitView() ? tabPage->activeViewContainer() : tabPage->inactiveViewContainer())->url());
+ tabPage->setSplitViewEnabled(false, WithAnimation);
+ updateSplitActions();
+}
+
+void DolphinMainWindow::toggleSplitStash()
+{
+ DolphinTabPage *tabPage = m_tabWidget->currentTabPage();
+ tabPage->setSplitViewEnabled(false, WithAnimation);
+ tabPage->setSplitViewEnabled(true, WithAnimation, QUrl("stash:/"));
+}
+
+void DolphinMainWindow::copyToInactiveSplitView()
+{
+ if (m_activeViewContainer->view()->selectedItems().isEmpty()) {
+ m_activeViewContainer->setSelectionModeEnabled(true, actionCollection(), SelectionMode::BottomBar::Contents::CopyToOtherViewContents);
+ } else {
+ m_tabWidget->copyToInactiveSplitView();
+ m_activeViewContainer->setSelectionModeEnabled(false);
+ }
+}
+
+void DolphinMainWindow::moveToInactiveSplitView()
+{
+ if (m_activeViewContainer->view()->selectedItems().isEmpty()) {
+ m_activeViewContainer->setSelectionModeEnabled(true, actionCollection(), SelectionMode::BottomBar::Contents::MoveToOtherViewContents);
+ } else {
+ m_tabWidget->moveToInactiveSplitView();
+ m_activeViewContainer->setSelectionModeEnabled(false);
+ }
+}
+
+void DolphinMainWindow::reloadView()
+{
+ clearStatusBar();
+ m_activeViewContainer->reload();
+ m_activeViewContainer->statusBar()->updateSpaceInfo();
+}
+
+void DolphinMainWindow::stopLoading()
+{
+ m_activeViewContainer->view()->stopLoading();
+}
+
+void DolphinMainWindow::enableStopAction()
+{
+ actionCollection()->action(QStringLiteral("stop"))->setEnabled(true);
+}
+
+void DolphinMainWindow::disableStopAction()
+{
+ actionCollection()->action(QStringLiteral("stop"))->setEnabled(false);
+}
+
+void DolphinMainWindow::toggleSelectionMode()
+{
+ const bool checked = !m_activeViewContainer->isSelectionModeEnabled();
+
+ m_activeViewContainer->setSelectionModeEnabled(checked, actionCollection(), SelectionMode::BottomBar::Contents::GeneralContents);
+ actionCollection()->action(QStringLiteral("toggle_selection_mode"))->setChecked(checked);
+}
+
+void DolphinMainWindow::showFilterBar()
+{
+ m_activeViewContainer->setFilterBarVisible(true);
+}
+
+void DolphinMainWindow::toggleFilterBar()
+{
+ const bool checked = !m_activeViewContainer->isFilterBarVisible();
+ m_activeViewContainer->setFilterBarVisible(checked);
+
+ QAction *toggleFilterBarAction = actionCollection()->action(QStringLiteral("toggle_filter"));
+ toggleFilterBarAction->setChecked(checked);
+}
+
+void DolphinMainWindow::toggleEditLocation()
+{
+ clearStatusBar();
+
+ QAction *action = actionCollection()->action(QStringLiteral("editable_location"));
+ KUrlNavigator *urlNavigator = m_activeViewContainer->urlNavigator();
+ urlNavigator->setUrlEditable(action->isChecked());
+}
+
+void DolphinMainWindow::replaceLocation()
+{
+ KUrlNavigator *navigator = m_activeViewContainer->urlNavigator();
+ QLineEdit *lineEdit = navigator->editor()->lineEdit();
+
+ // If the text field currently has focus and everything is selected,
+ // pressing the keyboard shortcut returns the whole thing to breadcrumb mode
+ // and goes back to the view, just like how it was before this action was triggered the first time.
+ if (navigator->isUrlEditable() && lineEdit->hasFocus() && lineEdit->selectedText() == lineEdit->text()) {
+ navigator->setUrlEditable(false);
+ m_activeViewContainer->view()->setFocus();
+ } else {
+ navigator->setUrlEditable(true);
+ navigator->setFocus();
+ lineEdit->selectAll();
+ }
+}
+
+void DolphinMainWindow::togglePanelLockState()
+{
+ const bool newLockState = !GeneralSettings::lockPanels();
+ const auto childrenObjects = children();
+ for (QObject *child : childrenObjects) {
+ DolphinDockWidget *dock = qobject_cast<DolphinDockWidget *>(child);
+ if (dock) {
+ dock->setLocked(newLockState);
+ }
+ }
+
+ DolphinPlacesModelSingleton::instance().placesModel()->setPanelsLocked(newLockState);
+
+ GeneralSettings::setLockPanels(newLockState);
+}
+
+void DolphinMainWindow::slotTerminalPanelVisibilityChanged(bool visible)
+{
+ if (!visible && m_activeViewContainer) {
+ m_activeViewContainer->view()->setFocus();
+ }
+ // Putting focus to the Terminal is not handled here but in TerminalPanel::showEvent().
+}
+
+void DolphinMainWindow::slotPlacesPanelVisibilityChanged(bool visible)
+{
+ if (!visible && m_activeViewContainer) {
+ m_activeViewContainer->view()->setFocus();
+ return;
+ }
+ m_placesPanel->setFocus();
+}
+
+void DolphinMainWindow::goBack()
+{
+ DolphinUrlNavigator *urlNavigator = m_activeViewContainer->urlNavigatorInternalWithHistory();
+ urlNavigator->goBack();
+
+ if (urlNavigator->locationState().isEmpty()) {
+ // An empty location state indicates a redirection URL,
+ // which must be skipped too
+ urlNavigator->goBack();
+ }
+}
+
+void DolphinMainWindow::goForward()
+{
+ m_activeViewContainer->urlNavigatorInternalWithHistory()->goForward();
+}
+
+void DolphinMainWindow::goUp()
+{
+ m_activeViewContainer->urlNavigatorInternalWithHistory()->goUp();
+}
+
+void DolphinMainWindow::goHome()
+{
+ m_activeViewContainer->urlNavigatorInternalWithHistory()->goHome();
+}
+
+void DolphinMainWindow::goBackInNewTab()
+{
+ const KUrlNavigator *urlNavigator = activeViewContainer()->urlNavigatorInternalWithHistory();
+ const int index = urlNavigator->historyIndex() + 1;
+ openNewTab(urlNavigator->locationUrl(index));
+}
+
+void DolphinMainWindow::goForwardInNewTab()
+{
+ const KUrlNavigator *urlNavigator = activeViewContainer()->urlNavigatorInternalWithHistory();
+ const int index = urlNavigator->historyIndex() - 1;
+ openNewTab(urlNavigator->locationUrl(index));
+}
+
+void DolphinMainWindow::goUpInNewTab()
+{
+ const QUrl currentUrl = activeViewContainer()->urlNavigator()->locationUrl();
+ openNewTab(KIO::upUrl(currentUrl));
+}
+
+void DolphinMainWindow::goHomeInNewTab()
+{
+ openNewTab(Dolphin::homeUrl());
+}
+
+void DolphinMainWindow::compareFiles()
+{
+ const KFileItemList items = m_tabWidget->currentTabPage()->selectedItems();
+ if (items.count() != 2) {
+ // The action is disabled in this case, but it could have been triggered
+ // via D-Bus, see https://bugs.kde.org/show_bug.cgi?id=325517
+ return;
+ }
+
+ QUrl urlA = items.at(0).url();
+ QUrl urlB = items.at(1).url();
+
+ QString command(QStringLiteral("kompare -c \""));
+ command.append(urlA.toDisplayString(QUrl::PreferLocalFile));
+ command.append("\" \"");
+ command.append(urlB.toDisplayString(QUrl::PreferLocalFile));
+ command.append('\"');
+
+ KIO::CommandLauncherJob *job = new KIO::CommandLauncherJob(command, this);
+ job->setDesktopName(QStringLiteral("org.kde.kompare"));
+ job->start();