File indexing completed on 2024-04-28 09:40:55
0001 /* 0002 * SPDX-FileCopyrightText: 2006 Peter Penz <peter.penz19@gmail.com> 0003 * SPDX-FileCopyrightText: 2006 Stefan Monov <logixoul@gmail.com> 0004 * SPDX-FileCopyrightText: 2006 Cvetoslav Ludmiloff <ludmiloff@gmail.com> 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #ifndef DOLPHIN_MAINWINDOW_H 0010 #define DOLPHIN_MAINWINDOW_H 0011 0012 #include "config-dolphin.h" 0013 #include "dolphintabwidget.h" 0014 #include "selectionmode/bottombar.h" 0015 #include <KFileItemActions> 0016 #include <kio/fileundomanager.h> 0017 #include <kxmlguiwindow.h> 0018 0019 #if HAVE_BALOO 0020 #include "panels/information/informationpanel.h" 0021 #endif 0022 0023 #include <QIcon> 0024 #include <QList> 0025 #include <QMenu> 0026 #include <QPointer> 0027 #include <QUrl> 0028 #include <QVector> 0029 0030 typedef KIO::FileUndoManager::CommandType CommandType; 0031 0032 class DolphinBookmarkHandler; 0033 class DolphinViewActionHandler; 0034 class DolphinSettingsDialog; 0035 class DolphinViewContainer; 0036 class DolphinRemoteEncoding; 0037 class DolphinTabWidget; 0038 class KFileItem; 0039 class KFileItemList; 0040 class KJob; 0041 class KNewFileMenu; 0042 class KToolBarPopupAction; 0043 class QToolButton; 0044 class PlacesPanel; 0045 class TerminalPanel; 0046 0047 namespace KIO 0048 { 0049 class OpenUrlJob; 0050 } 0051 namespace SelectionMode 0052 { 0053 class ActionTextHelper; 0054 } 0055 0056 /** 0057 * @short Main window for Dolphin. 0058 * 0059 * Handles the menus, toolbars and Dolphin views. 0060 */ 0061 class DolphinMainWindow : public KXmlGuiWindow 0062 { 0063 Q_OBJECT 0064 Q_CLASSINFO("D-Bus Interface", "org.kde.dolphin.MainWindow") 0065 0066 public: 0067 DolphinMainWindow(); 0068 ~DolphinMainWindow() override; 0069 0070 /** 0071 * Returns the currently active view. 0072 * All menu actions are applied to this view. When 0073 * having a split view setup, the nonactive view 0074 * is usually shown in darker colors. 0075 */ 0076 DolphinViewContainer *activeViewContainer() const; 0077 0078 /** 0079 * Returns view container for all tabs 0080 */ 0081 QVector<DolphinViewContainer *> viewContainers() const; 0082 0083 /** 0084 * Opens each directory in \p dirs in a separate tab. If \a splitView is set, 0085 * 2 directories are collected within one tab. 0086 * \pre \a dirs must contain at least one url. 0087 */ 0088 void openDirectories(const QList<QUrl> &dirs, bool splitView); 0089 0090 /** 0091 * Opens the directories which contain the files \p files and selects all files. 0092 * If \a splitView is set, 2 directories are collected within one tab. 0093 * \pre \a files must contain at least one url. 0094 */ 0095 void openFiles(const QList<QUrl> &files, bool splitView); 0096 0097 /** 0098 * Returns the 'Create New...' sub menu which also can be shared 0099 * with other menus (e. g. a context menu). 0100 */ 0101 KNewFileMenu *newFileMenu() const; 0102 0103 /** 0104 * Augments Qt's build-in QMainWindow context menu to add 0105 * Dolphin-specific actions, such as "unlock panels". 0106 */ 0107 QMenu *createPopupMenu() override; 0108 0109 /** 0110 * Switch the window's view containers' locations to display the home path 0111 * for any which are currently displaying a location corresponding to or 0112 * within mountPath. 0113 * 0114 * This typically done after unmounting a disk at mountPath to ensure that 0115 * the window is not displaying an invalid location. 0116 */ 0117 void setViewsToHomeIfMountPathOpen(const QString &mountPath); 0118 0119 bool isFoldersPanelEnabled() const; 0120 bool isInformationPanelEnabled() const; 0121 bool isSplitViewEnabledInCurrentTab() const; 0122 0123 public Q_SLOTS: 0124 /** 0125 * Opens each directory in \p dirs in a separate tab. If \a splitView is set, 0126 * 2 directories are collected within one tab. 0127 * \pre \a dirs must contain at least one url. 0128 * 0129 * @note this function is overloaded so that it is callable via DBus. 0130 */ 0131 void openDirectories(const QStringList &dirs, bool splitView); 0132 0133 /** 0134 * Opens the directories which contain the files \p files and selects all files. 0135 * If \a splitView is set, 2 directories are collected within one tab. 0136 * \pre \a files must contain at least one url. 0137 * 0138 * @note this is overloaded so that this function is callable via DBus. 0139 */ 0140 void openFiles(const QStringList &files, bool splitView); 0141 0142 /** 0143 * Tries to raise/activate the Dolphin window. 0144 */ 0145 void activateWindow(const QString &activationToken); 0146 0147 bool isActiveWindow(); 0148 0149 /** 0150 * Determines if a URL is open in any tab. 0151 * @note Use of QString instead of QUrl is required to be callable via DBus. 0152 * 0153 * @param url URL to look for 0154 * @returns true if url is currently open in a tab, false otherwise. 0155 */ 0156 bool isUrlOpen(const QString &url); 0157 0158 /** 0159 * @return Whether the item with @p url can be found in any view only by switching 0160 * between already open tabs and scrolling in their primary or secondary view. 0161 * @note Use of QString instead of QUrl is required to be callable via DBus. 0162 */ 0163 bool isItemVisibleInAnyView(const QString &urlOfItem); 0164 0165 /** 0166 * Pastes the clipboard data into the currently selected folder 0167 * of the active view. If not exactly one folder is selected, 0168 * no pasting is done at all. 0169 */ 0170 void pasteIntoFolder(); 0171 0172 /** 0173 * Implementation of the MainWindowAdaptor/QDBusAbstractAdaptor interface. 0174 * Inform all affected dolphin components (panels, views) of an URL 0175 * change. 0176 */ 0177 void changeUrl(const QUrl &url); 0178 0179 /** 0180 * The current directory of the Terminal Panel has changed, probably because 0181 * the user entered a 'cd' command. This slot calls changeUrl(url) and makes 0182 * sure that the panel keeps the keyboard focus. 0183 */ 0184 void slotTerminalDirectoryChanged(const QUrl &url); 0185 0186 /** Stores all settings and quits Dolphin. */ 0187 void quit(); 0188 0189 /** 0190 * Opens a new tab in the background showing the URL \a url. 0191 */ 0192 void openNewTab(const QUrl &url); 0193 0194 /** 0195 * Opens a new tab showing the URL \a url and activate it. 0196 */ 0197 void openNewTabAndActivate(const QUrl &url); 0198 0199 /** 0200 * Opens a new window showing the URL \a url. 0201 */ 0202 void openNewWindow(const QUrl &url); 0203 0204 /** @see GeneralSettings::splitViewChanged() */ 0205 void slotSplitViewChanged(); 0206 0207 Q_SIGNALS: 0208 /** 0209 * Is sent if the selection of the currently active view has 0210 * been changed. 0211 */ 0212 void selectionChanged(const KFileItemList &selection); 0213 0214 /** 0215 * Is sent if the url of the currently active view has 0216 * been changed. 0217 */ 0218 void urlChanged(const QUrl &url); 0219 0220 /** 0221 * Is emitted if information of an item is requested to be shown e. g. in the panel. 0222 * If item is null, no item information request is pending. 0223 */ 0224 void requestItemInfo(const KFileItem &item); 0225 0226 /** 0227 * It is emitted when in the current view, files are changed, 0228 * or dirs have files/removed from them. 0229 */ 0230 void fileItemsChanged(const KFileItemList &changedFileItems); 0231 0232 /** 0233 * Is emitted if the settings have been changed. 0234 */ 0235 void settingsChanged(); 0236 0237 protected: 0238 /** @see QObject::event() */ 0239 bool event(QEvent *event) override; 0240 0241 /** @see QWidget::showEvent() */ 0242 void showEvent(QShowEvent *event) override; 0243 0244 /** @see QMainWindow::closeEvent() */ 0245 void closeEvent(QCloseEvent *event) override; 0246 0247 /** @see KMainWindow::saveProperties() */ 0248 void saveProperties(KConfigGroup &group) override; 0249 0250 /** @see KMainWindow::readProperties() */ 0251 void readProperties(const KConfigGroup &group) override; 0252 0253 /** Sets a sane initial window size **/ 0254 QSize sizeHint() const override; 0255 0256 protected Q_SLOTS: 0257 /** 0258 * Calls the base method KXmlGuiWindow::saveNewToolbarConfig(). 0259 * Is also used to set toolbar constraints and UrlNavigator position 0260 * based on the newly changed toolbar configuration. 0261 */ 0262 void saveNewToolbarConfig() override; 0263 0264 private Q_SLOTS: 0265 /** 0266 * Refreshes the views of the main window by recreating them according to 0267 * the given Dolphin settings. 0268 */ 0269 void refreshViews(); 0270 0271 void clearStatusBar(); 0272 0273 /** Updates the 'Create New...' sub menu. */ 0274 void updateNewMenu(); 0275 0276 void createDirectory(); 0277 0278 /** Shows the error message in the status bar of the active view. */ 0279 void showErrorMessage(const QString &message); 0280 0281 /** 0282 * Updates the state of the 'Undo' menu action dependent 0283 * on the parameter \a available. 0284 */ 0285 void slotUndoAvailable(bool available); 0286 0287 /** Sets the text of the 'Undo' menu action to \a text. */ 0288 void slotUndoTextChanged(const QString &text); 0289 0290 /** Performs the current undo operation. */ 0291 void undo(); 0292 0293 /** 0294 * Copies all selected items to the clipboard and marks 0295 * the items as cut. 0296 */ 0297 void cut(); 0298 0299 /** Copies all selected items to the clipboard. */ 0300 void copy(); 0301 0302 /** Pastes the clipboard data to the active view. */ 0303 void paste(); 0304 0305 /** Replaces the URL navigator by a search box to find files. */ 0306 void find(); 0307 0308 /** Updates the state of the search action according to the view container. */ 0309 void updateSearchAction(); 0310 0311 /** 0312 * Updates the text of the paste action dependent on 0313 * the number of items which are in the clipboard. 0314 */ 0315 void updatePasteAction(); 0316 0317 /** Calls DolphinViewContainer::setSelectionMode() for m_activeViewContainer. */ 0318 void slotSetSelectionMode(bool enabled, SelectionMode::BottomBar::Contents bottomBarContents); 0319 0320 /** Selects all items from the active view. */ 0321 void selectAll(); 0322 0323 /** 0324 * Inverts the selection of all items of the active view: 0325 * Selected items get nonselected and nonselected items get 0326 * selected. 0327 */ 0328 void invertSelection(); 0329 0330 /** 0331 * Switches between one and two views: 0332 * If one view is visible, it will get split into two views. 0333 * If already two views are visible, the active view gets closed. 0334 */ 0335 void toggleSplitView(); 0336 0337 /** Dedicated action to open the stash:/ ioslave in split view. */ 0338 void toggleSplitStash(); 0339 0340 /** Copies all selected items to the inactive view. */ 0341 void copyToInactiveSplitView(); 0342 0343 /** Moves all selected items to the inactive view. */ 0344 void moveToInactiveSplitView(); 0345 0346 /** Reloads the currently active view. */ 0347 void reloadView(); 0348 0349 /** Stops the loading process for the currently active view. */ 0350 void stopLoading(); 0351 0352 void enableStopAction(); 0353 void disableStopAction(); 0354 0355 void toggleSelectionMode(); 0356 0357 void showFilterBar(); 0358 void toggleFilterBar(); 0359 0360 /** 0361 * Toggles between edit and browse mode of the navigation bar. 0362 */ 0363 void toggleEditLocation(); 0364 0365 /** 0366 * Switches to the edit mode of the navigation bar and selects 0367 * the whole URL, so that it can be replaced by the user. If the edit mode is 0368 * already active, it is assured that the navigation bar get focused. 0369 */ 0370 void replaceLocation(); 0371 0372 /** 0373 * Toggles the state of the panels between a locked and unlocked layout. 0374 */ 0375 void togglePanelLockState(); 0376 0377 /** 0378 * Is invoked if the Terminal panel got visible/invisible and takes care 0379 * that the active view has the focus if the Terminal panel is invisible. 0380 */ 0381 void slotTerminalPanelVisibilityChanged(); 0382 0383 /** Goes back one step of the URL history. */ 0384 void goBack(); 0385 0386 /** Goes forward one step of the URL history. */ 0387 void goForward(); 0388 0389 /** Goes up one hierarchy of the current URL. */ 0390 void goUp(); 0391 0392 /** Changes the location to the home URL. */ 0393 void goHome(); 0394 0395 /** Open the previous URL in the URL history in a new tab. */ 0396 void goBackInNewTab(); 0397 0398 /** Open the next URL in the URL history in a new tab. */ 0399 void goForwardInNewTab(); 0400 0401 /** Open the URL one hierarchy above the current URL in a new tab. */ 0402 void goUpInNewTab(); 0403 0404 /** * Open the home URL in a new tab. */ 0405 void goHomeInNewTab(); 0406 0407 /** Opens Kompare for 2 selected files. */ 0408 void compareFiles(); 0409 0410 /** 0411 * Hides the menu bar if it is visible, makes the menu bar 0412 * visible if it is hidden. 0413 */ 0414 void toggleShowMenuBar(); 0415 0416 /** Updates "Open Preferred Search Tool" action. */ 0417 void updateOpenPreferredSearchToolAction(); 0418 0419 /** Opens preferred search tool for the current location. */ 0420 void openPreferredSearchTool(); 0421 0422 /** Opens a terminal window for the current location. */ 0423 void openTerminal(); 0424 0425 /** Opens terminal windows for the selected items' locations. */ 0426 void openTerminalHere(); 0427 0428 /** Opens a terminal window for the URL. */ 0429 void openTerminalJob(const QUrl &url); 0430 0431 /** Focus a Terminal Panel. */ 0432 void focusTerminalPanel(); 0433 0434 /** Opens the settings dialog for Dolphin. */ 0435 void editSettings(); 0436 0437 /** Updates the state of the 'Show Full Location' action. */ 0438 void slotEditableStateChanged(bool editable); 0439 0440 /** 0441 * Updates the state of the 'Edit' menu actions and emits 0442 * the signal selectionChanged(). 0443 */ 0444 void slotSelectionChanged(const KFileItemList &selection); 0445 0446 /** 0447 * Updates the state of the 'Back' and 'Forward' menu 0448 * actions corresponding to the current history. 0449 */ 0450 void updateHistory(); 0451 0452 /** Updates the state of the 'Show filter bar' menu action. */ 0453 void updateFilterBarAction(bool show); 0454 0455 /** Open a new main window. */ 0456 void openNewMainWindow(); 0457 0458 /** 0459 * Opens a new view with the current URL that is part of a tab and 0460 * activates it. 0461 */ 0462 void openNewActivatedTab(); 0463 0464 /** 0465 * Adds the current URL as an entry to the Places panel 0466 */ 0467 void addToPlaces(); 0468 0469 /** 0470 * Opens the selected folder in a new tab. 0471 */ 0472 void openInNewTab(); 0473 0474 /** 0475 * Opens the selected folder in a new window. 0476 */ 0477 void openInNewWindow(); 0478 0479 /** 0480 * Opens the selected folder in the other inactive split view, enables split view if necessary. 0481 */ 0482 void openInSplitView(const QUrl &url); 0483 0484 /** 0485 * Show the target of the selected symlink 0486 */ 0487 void showTarget(); 0488 0489 /** 0490 * Indicates in the statusbar that the execution of the command \a command 0491 * has been finished. 0492 */ 0493 void showCommand(CommandType command); 0494 0495 /** 0496 * If the URL can be listed, open it in the current view, otherwise 0497 * run it through KRun. 0498 */ 0499 void handleUrl(const QUrl &url); 0500 0501 /** 0502 * Is invoked when the write state of a folder has been changed and 0503 * enables/disables the "Create New..." menu entry. 0504 */ 0505 void slotWriteStateChanged(bool isFolderWritable); 0506 0507 /** 0508 * Opens the context menu on the current mouse position. 0509 * @pos Position in screen coordinates. 0510 * @item File item context. If item is null, the context menu 0511 * should be applied to \a url. 0512 * @selectedItems The selected items for which the context menu 0513 * is opened. This list generally includes \a item. 0514 * @url URL which contains \a item. 0515 */ 0516 void openContextMenu(const QPoint &pos, const KFileItem &item, const KFileItemList &selectedItems, const QUrl &url); 0517 0518 /** 0519 * Updates the menu that is by default at the right end of the toolbar. 0520 * 0521 * In true "simple by default" fashion, the menu only contains the most important 0522 * and necessary actions to be able to use Dolphin. This is supposed to hold true even 0523 * if the user does not know how to open a context menu. More advanced actions can be 0524 * discovered through a sub-menu (@see KConfigWidgets::KHamburgerMenu::setMenuBarAdvertised()). 0525 */ 0526 void updateHamburgerMenu(); 0527 0528 /** 0529 * Is called if the user clicked an item in the Places Panel. 0530 * Reloads the view if \a url is the current URL already, and changes the 0531 * current URL otherwise. 0532 */ 0533 void slotPlaceActivated(const QUrl &url); 0534 0535 /** 0536 * Is called if the another view has been activated by changing the current 0537 * tab or activating another view in split-view mode. 0538 * 0539 * Activates the given view, which means that all menu actions are applied 0540 * to this view. When having a split view setup, the nonactive view is 0541 * usually shown in darker colors. 0542 */ 0543 void activeViewChanged(DolphinViewContainer *viewContainer); 0544 0545 void closedTabsCountChanged(unsigned int count); 0546 0547 /** 0548 * Is called if a new tab has been opened or a tab has been closed to 0549 * enable/disable the tab actions. 0550 */ 0551 void tabCountChanged(int count); 0552 0553 /** 0554 * Updates the Window Title with the caption from the active view container 0555 */ 0556 void updateWindowTitle(); 0557 0558 /** 0559 * This slot is called when the user requested to unmount a removable media 0560 * from the places menu 0561 */ 0562 void slotStorageTearDownFromPlacesRequested(const QString &mountPath); 0563 0564 /** 0565 * This slot is called when the user requested to unmount a removable media 0566 * _not_ from the dolphin's places menu (from the notification area for e.g.) 0567 * This slot is basically connected to each removable device's 0568 * Solid::StorageAccess::teardownRequested(const QString & udi) 0569 * signal through the places panel. 0570 */ 0571 void slotStorageTearDownExternallyRequested(const QString &mountPath); 0572 0573 /** 0574 * Is called when the view has finished loading the directory. 0575 */ 0576 void slotDirectoryLoadingCompleted(); 0577 0578 /** 0579 * Is called when the user middle clicks a toolbar button. 0580 * 0581 * Here middle clicking Back/Forward/Up/Home will open the resulting 0582 * folder in a new tab. 0583 */ 0584 void slotToolBarActionMiddleClicked(QAction *action); 0585 0586 /** 0587 * Is called before the Back popup menu is shown. This slot will populate 0588 * the menu with history data 0589 */ 0590 void slotAboutToShowBackPopupMenu(); 0591 0592 /** 0593 * This slot is used by the Back Popup Menu to go back to a specific 0594 * history index. The QAction::data will carry an int with the index 0595 * to go to. 0596 */ 0597 void slotGoBack(QAction *action); 0598 0599 /** 0600 * Middle clicking Back/Forward will open the resulting folder in a new tab. 0601 */ 0602 void slotBackForwardActionMiddleClicked(QAction *action); 0603 0604 /** 0605 * Is called before the Forward popup menu is shown. This slot will populate 0606 * the menu with history data 0607 */ 0608 void slotAboutToShowForwardPopupMenu(); 0609 0610 /** 0611 * This slot is used by the Forward Popup Menu to go forward to a specific 0612 * history index. The QAction::data will carry an int with the index 0613 * to go to. 0614 */ 0615 void slotGoForward(QAction *action); 0616 0617 /** 0618 * Is called when configuring the keyboard shortcuts 0619 */ 0620 void slotKeyBindings(); 0621 0622 private: 0623 /** 0624 * Sets up the various menus and actions and connects them. 0625 */ 0626 void setupActions(); 0627 0628 /** 0629 * Sets up the dock widgets and their panels. 0630 */ 0631 void setupDockWidgets(); 0632 0633 void updateFileAndEditActions(); 0634 void updateViewActions(); 0635 void updateGoActions(); 0636 0637 /** 0638 * Connects the signals from the created DolphinView with 0639 * the DolphinViewContainer \a container with the corresponding slots of 0640 * the DolphinMainWindow. This method must be invoked each 0641 * time a DolphinView has been created. 0642 */ 0643 void connectViewSignals(DolphinViewContainer *container); 0644 0645 /** 0646 * Updates the text of the split action: 0647 * If two views are shown, the text is set to "Split", 0648 * otherwise the text is set to "Join". The icon 0649 * is updated to match with the text and the currently active view. 0650 */ 0651 void updateSplitAction(); 0652 0653 /** 0654 * Sets the window sides the toolbar may be moved to based on toolbar contents. 0655 */ 0656 void updateAllowedToolbarAreas(); 0657 0658 bool isKompareInstalled() const; 0659 0660 /** 0661 * Creates an action for showing/hiding a panel, that is accessible 0662 * in "Configure toolbars..." and "Configure shortcuts...". 0663 */ 0664 void createPanelAction(const QIcon &icon, const QKeySequence &shortcut, QDockWidget *dockAction, const QString &actionName); 0665 0666 /** Adds "What's This?" texts to many widgets and StandardActions. */ 0667 void setupWhatsThis(); 0668 0669 /** Returns preferred search tool as configured in "More Search Tools" menu. */ 0670 QPointer<QAction> preferredSearchTool(); 0671 0672 /** 0673 * Adds this action to the mainWindow's toolbar and saves the change 0674 * in the users ui configuration file. 0675 * This method is only needed for migration and should be removed once we can expect 0676 * that pretty much all users have been migrated. Remove in 2026 because that's when 0677 * even the most risk-averse distros will already have been forced to upgrade. 0678 * @return true if successful. Otherwise false. 0679 */ 0680 bool addHamburgerMenuToToolbar(); 0681 0682 /** Creates an action representing an item in the URL navigator history */ 0683 static QAction *urlNavigatorHistoryAction(const KUrlNavigator *urlNavigator, int historyIndex, QObject *parent = nullptr); 0684 0685 private: 0686 /** 0687 * Implements a custom error handling for the undo manager. This 0688 * assures that all errors are shown in the status bar of Dolphin 0689 * instead as modal error dialog with an OK button. 0690 */ 0691 class UndoUiInterface : public KIO::FileUndoManager::UiInterface 0692 { 0693 public: 0694 UndoUiInterface(); 0695 ~UndoUiInterface() override; 0696 void jobError(KIO::Job *job) override; 0697 }; 0698 0699 KNewFileMenu *m_newFileMenu; 0700 DolphinTabWidget *m_tabWidget; 0701 DolphinViewContainer *m_activeViewContainer; 0702 0703 DolphinViewActionHandler *m_actionHandler; 0704 DolphinRemoteEncoding *m_remoteEncoding; 0705 QPointer<DolphinSettingsDialog> m_settingsDialog; 0706 DolphinBookmarkHandler *m_bookmarkHandler; 0707 SelectionMode::ActionTextHelper *m_actionTextHelper; 0708 0709 KIO::OpenUrlJob *m_lastHandleUrlOpenJob; 0710 0711 TerminalPanel *m_terminalPanel; 0712 PlacesPanel *m_placesPanel; 0713 bool m_tearDownFromPlacesRequested; 0714 0715 KToolBarPopupAction *m_backAction; 0716 KToolBarPopupAction *m_forwardAction; 0717 0718 QMenu m_searchTools; 0719 KFileItemActions m_fileItemActions; 0720 0721 friend class DolphinMainWindowTest; 0722 }; 0723 0724 inline DolphinViewContainer *DolphinMainWindow::activeViewContainer() const 0725 { 0726 return m_activeViewContainer; 0727 } 0728 0729 inline KNewFileMenu *DolphinMainWindow::newFileMenu() const 0730 { 0731 return m_newFileMenu; 0732 } 0733 0734 #endif // DOLPHIN_MAINWINDOW_H