diff --git a/src/dolphinmainwindow.h b/src/dolphinmainwindow.h --- a/src/dolphinmainwindow.h +++ b/src/dolphinmainwindow.h @@ -46,6 +46,7 @@ class KFileItemList; class KJob; class KNewFileMenu; +class KHelpMenu; class QToolButton; class QIcon; class PlacesPanel; @@ -205,6 +206,11 @@ /** @see KMainWindow::readProperties() */ void readProperties(const KConfigGroup& group) override; + /** Handles QWhatsThisClickedEvent and passes all others on. */ + bool event(QEvent* event) override; + /** Handles QWhatsThisClickedEvent and passes all others on. */ + bool eventFilter(QObject*, QEvent*) override; + private slots: /** * Refreshes the views of the main window by recreating them according to @@ -496,8 +502,16 @@ void slotToolBarActionMiddleClicked(QAction *action); private: + /** + * Sets up the various menus and actions and connects them. + */ void setupActions(); + + /** + * Sets up the dock widgets and their panels. + */ void setupDockWidgets(); + void updateEditActions(); void updateViewActions(); void updateGoActions(); @@ -541,6 +555,9 @@ QAction* dockAction, const QString& actionName); + /** Adds "What's This?" texts to many widgets and StandardActions. */ + void setupWhatsThis(); + private: /** * Implements a custom error handling for the undo manager. This @@ -556,6 +573,7 @@ }; KNewFileMenu* m_newFileMenu; + KHelpMenu* m_helpMenu; DolphinTabWidget* m_tabWidget; DolphinViewContainer* m_activeViewContainer; diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -72,6 +72,7 @@ #include #include #include +#include #include #include #include @@ -82,16 +83,18 @@ #include #include #include +#include namespace { // Used for GeneralSettings::version() to determine whether // an updated version of Dolphin is running. const int CurrentDolphinVersion = 200; } DolphinMainWindow::DolphinMainWindow() : - KXmlGuiWindow(nullptr), + KXmlGuiWindow(nullptr, Qt::WindowContextHelpButtonHint), m_newFileMenu(nullptr), + m_helpMenu(nullptr), m_tabWidget(nullptr), m_activeViewContainer(nullptr), m_actionHandler(nullptr), @@ -181,6 +184,8 @@ auto *middleClickEventFilter = new MiddleClickActionEventFilter(this); connect(middleClickEventFilter, &MiddleClickActionEventFilter::actionMiddleClicked, this, &DolphinMainWindow::slotToolBarActionMiddleClicked); toolBar()->installEventFilter(middleClickEventFilter); + + setupWhatsThis(); } DolphinMainWindow::~DolphinMainWindow() @@ -318,12 +323,15 @@ QAction* backAction = actionCollection()->action(KStandardAction::name(KStandardAction::Back)); if (backAction) { backAction->setToolTip(i18nc("@info", "Go back")); + backAction->setWhatsThis(i18nc("@info:whatsthis go back", "Return to the previously viewed folder.")); backAction->setEnabled(index < urlNavigator->historySize() - 1); } QAction* forwardAction = actionCollection()->action(KStandardAction::name(KStandardAction::Forward)); if (forwardAction) { forwardAction->setToolTip(i18nc("@info", "Go forward")); + forwardAction->setWhatsThis(xi18nc("@info:whatsthis go forward", + "This undoes a Go|Back action.")); forwardAction->setEnabled(index > 0); } } @@ -1031,8 +1039,7 @@ addActionToMenu(ac->action(KStandardAction::name(KStandardAction::Preferences)), menu); // Add "Help" menu - auto helpMenu = new KHelpMenu(menu); - menu->addMenu(helpMenu->menu()); + menu->addMenu(m_helpMenu->menu()); menu->addSeparator(); addActionToMenu(ac->action(KStandardAction::name(KStandardAction::ShowMenubar)), menu); @@ -1149,48 +1156,94 @@ QAction* newWindow = KStandardAction::openNew(this, &DolphinMainWindow::openNewMainWindow, actionCollection()); newWindow->setText(i18nc("@action:inmenu File", "New &Window")); + newWindow->setWhatsThis(xi18nc("@info:whatsthis", "This opens a new " + "window just like this one with the current location and view." + "You can drag and drop items between windows.")); newWindow->setIcon(QIcon::fromTheme(QStringLiteral("window-new"))); QAction* newTab = actionCollection()->addAction(QStringLiteral("new_tab")); newTab->setIcon(QIcon::fromTheme(QStringLiteral("tab-new"))); newTab->setText(i18nc("@action:inmenu File", "New Tab")); + newTab->setWhatsThis(xi18nc("@info:whatsthis", "This opens a new " + "Tab with the current location and view." + "A tab is an additional view within this window. " + "You can drag and drop items between tabs.")); actionCollection()->setDefaultShortcuts(newTab, {Qt::CTRL + Qt::Key_T, Qt::CTRL + Qt::SHIFT + Qt::Key_N}); connect(newTab, &QAction::triggered, this, &DolphinMainWindow::openNewActivatedTab); QAction* closeTab = KStandardAction::close(m_tabWidget, QOverload<>::of(&DolphinTabWidget::closeTab), actionCollection()); closeTab->setText(i18nc("@action:inmenu File", "Close Tab")); + closeTab->setWhatsThis(i18nc("@info:whatsthis", "This closes the " + "currently viewed tab. If no more tabs are left this window " + "will close instead.")); - KStandardAction::quit(this, &DolphinMainWindow::quit, actionCollection()); + QAction* quitAction = KStandardAction::quit(this, &DolphinMainWindow::quit, actionCollection()); + quitAction->setWhatsThis(i18nc("@info:whatsthis quit", "This closes this window.")); // setup 'Edit' menu KStandardAction::undo(this, &DolphinMainWindow::undo, actionCollection()); - - KStandardAction::cut(this, &DolphinMainWindow::cut, actionCollection()); - KStandardAction::copy(this, &DolphinMainWindow::copy, actionCollection()); + // i18n: This will be the last paragraph for the whatsthis for all three: + // Cut, Copy and Paste + const QString cutCopyPastePara = xi18nc("@info:whatsthis", "Cut, " + "Copy and Paste work between many " + "applications and are among the most used commands. That's why their " + "keyboard shortcuts are prominently placed right " + "next to each other on the keyboard: Ctrl+X, " + "Ctrl+C and Ctrl+V."); + QAction* cutAction = KStandardAction::cut(this, &DolphinMainWindow::cut, actionCollection()); + cutAction->setWhatsThis(xi18nc("@info:whatsthis cut", "This copies the items " + "in your current selection to the clipboard." + "Use the Paste action afterwards to copy them from " + "the clipboard to a new location. The items will be removed from their " + "initial location.") + cutCopyPastePara); + QAction* copyAction = KStandardAction::copy(this, &DolphinMainWindow::copy, actionCollection()); + copyAction->setWhatsThis(xi18nc("@info:whatsthis copy", "This copies the " + "items in your current selection to the clipboard." + "Use the Paste action afterwards to copy them " + "from the clipboard to a new location.") + cutCopyPastePara); QAction* paste = KStandardAction::paste(this, &DolphinMainWindow::paste, actionCollection()); // The text of the paste-action is modified dynamically by Dolphin // (e. g. to "Paste One Folder"). To prevent that the size of the toolbar changes // due to the long text, the text "Paste" is used: paste->setIconText(i18nc("@action:inmenu Edit", "Paste")); + paste->setWhatsThis(xi18nc("@info:whatsthis paste", "This copies the items from " + "your clipboard to the currently viewed folder." + "If the items were added to the clipboard by the Cut " + "action they are removed from their old location.") + cutCopyPastePara); QAction *searchAction = KStandardAction::find(this, &DolphinMainWindow::find, actionCollection()); searchAction->setText(i18n("Search...")); - - KStandardAction::selectAll(this, &DolphinMainWindow::selectAll, actionCollection()); + searchAction->setToolTip(i18nc("@info:tooltip", "Search for files and folders")); + searchAction->setWhatsThis(xi18nc("@info:whatsthis find", "This helps you " + "find files and folders by opening a find bar. " + "There you can enter search terms and specify settings to find the " + "objects you are looking for.Use this help again on " + "the find bar so we can have a look at it while the settings are " + "explained.")); + + QAction* selectAllAction = KStandardAction::selectAll(this, &DolphinMainWindow::selectAll, actionCollection()); + selectAllAction->setWhatsThis(xi18nc("@info:whatsthis", "This selects all " + "files and folders in the current location.")); QAction* invertSelection = actionCollection()->addAction(QStringLiteral("invert_selection")); invertSelection->setText(i18nc("@action:inmenu Edit", "Invert Selection")); + invertSelection->setWhatsThis(xi18nc("@info:whatsthis invert", "This selects all " + "objects that you have currently not selected instead.")); invertSelection->setIcon(QIcon::fromTheme(QStringLiteral("edit-select-invert"))); actionCollection()->setDefaultShortcut(invertSelection, Qt::CTRL + Qt::SHIFT + Qt::Key_A); connect(invertSelection, &QAction::triggered, this, &DolphinMainWindow::invertSelection); // setup 'View' menu // (note that most of it is set up in DolphinViewActionHandler) QAction* split = actionCollection()->addAction(QStringLiteral("split_view")); + split->setWhatsThis(xi18nc("@info:whatsthis find", "This splits " + "the folder view below into two autonomous views.This " + "way you can see two locations at once and move items between them " + "quickly.Click this again afterwards to recombine the views.")); actionCollection()->setDefaultShortcut(split, Qt::Key_F3); connect(split, &QAction::triggered, this, &DolphinMainWindow::toggleSplitView); @@ -1208,16 +1261,28 @@ QAction* stop = actionCollection()->addAction(QStringLiteral("stop")); stop->setText(i18nc("@action:inmenu View", "Stop")); stop->setToolTip(i18nc("@info", "Stop loading")); + stop->setWhatsThis(i18nc("@info", "This stops the loading of the contents of the current folder.")); stop->setIcon(QIcon::fromTheme(QStringLiteral("process-stop"))); connect(stop, &QAction::triggered, this, &DolphinMainWindow::stopLoading); KToggleAction* editableLocation = actionCollection()->add(QStringLiteral("editable_location")); editableLocation->setText(i18nc("@action:inmenu Navigation Bar", "Editable Location")); + editableLocation->setWhatsThis(xi18nc("@info:whatsthis", + "This toggles the Location Bar to be " + "editable so you can directly enter a location you want to go to." + "You can also switch to editing by clicking to the right of the " + "location and switch back by confirming the edited location.")); actionCollection()->setDefaultShortcut(editableLocation, Qt::Key_F6); connect(editableLocation, &KToggleAction::triggered, this, &DolphinMainWindow::toggleEditLocation); QAction* replaceLocation = actionCollection()->addAction(QStringLiteral("replace_location")); replaceLocation->setText(i18nc("@action:inmenu Navigation Bar", "Replace Location")); + // i18n: "enter" is used both in the meaning of "writing" and "going to" a new location here. + // Both meanings are useful but not necessary to understand the use of "Replace Location". + // So you might want to be more verbose in your language to convey the meaning but it's up to you. + replaceLocation->setWhatsThis(xi18nc("@info:whatsthis", + "This switches to editing the location and selects it " + "so you can quickly enter a different location.")); actionCollection()->setDefaultShortcut(replaceLocation, Qt::CTRL + Qt::Key_L); connect(replaceLocation, &QAction::triggered, this, &DolphinMainWindow::replaceLocation); @@ -1238,21 +1303,37 @@ QAction* undoCloseTab = actionCollection()->addAction(QStringLiteral("undo_close_tab")); undoCloseTab->setText(i18nc("@action:inmenu File", "Undo close tab")); + undoCloseTab->setWhatsThis(i18nc("@info:whatsthis undo close tab", + "This returns you to the previously closed tab.")); actionCollection()->setDefaultShortcut(undoCloseTab, Qt::CTRL + Qt::SHIFT + Qt::Key_T); undoCloseTab->setIcon(QIcon::fromTheme(QStringLiteral("edit-undo"))); undoCloseTab->setEnabled(false); connect(undoCloseTab, &QAction::triggered, recentTabsMenu, &DolphinRecentTabsMenu::undoCloseTab); auto undoAction = actionCollection()->action(KStandardAction::name(KStandardAction::Undo)); + undoAction->setWhatsThis(xi18nc("@info:whatsthis", "This undoes " + "the last change you made to files or folders." + "Such changes include creating, renaming " + "and moving them to a different location " + "or to the Trash. Changes that can't " + "be undone will ask for your confirmation.")); undoAction->setEnabled(false); // undo should be disabled by default KStandardAction::forward(this, &DolphinMainWindow::goForward, actionCollection()); KStandardAction::up(this, &DolphinMainWindow::goUp, actionCollection()); - KStandardAction::home(this, &DolphinMainWindow::goHome, actionCollection()); + QAction* homeAction = KStandardAction::home(this, &DolphinMainWindow::goHome, actionCollection()); + homeAction->setWhatsThis(xi18nc("@info:whatsthis", "Go to your " + "Home folder.Every user account " + "has their own Home that contains their data " + "including folders that contain personal application data.")); // setup 'Tools' menu QAction* showFilterBar = actionCollection()->addAction(QStringLiteral("show_filter_bar")); showFilterBar->setText(i18nc("@action:inmenu Tools", "Show Filter Bar")); + showFilterBar->setWhatsThis(xi18nc("@info:whatsthis", "This opens the " + "Filter Bar at the bottom of the window. " + "There you can enter a text to filter the files and folders currently displayed. " + "Only those that contain the text in their name will be kept in view.")); showFilterBar->setIcon(QIcon::fromTheme(QStringLiteral("view-filter"))); actionCollection()->setDefaultShortcuts(showFilterBar, {Qt::CTRL + Qt::Key_I, Qt::Key_Slash}); connect(showFilterBar, &QAction::triggered, this, &DolphinMainWindow::showFilterBar); @@ -1267,6 +1348,9 @@ if (KAuthorized::authorize(QStringLiteral("shell_access"))) { QAction* openTerminal = actionCollection()->addAction(QStringLiteral("open_terminal")); openTerminal->setText(i18nc("@action:inmenu Tools", "Open Terminal")); + openTerminal->setWhatsThis(xi18nc("@info:whatsthis", + "This opens a terminal application for the viewed location." + "To learn more about terminals use the help in the terminal application.")); openTerminal->setIcon(QIcon::fromTheme(QStringLiteral("utilities-terminal"))); actionCollection()->setDefaultShortcut(openTerminal, Qt::SHIFT + Qt::Key_F4); connect(openTerminal, &QAction::triggered, this, &DolphinMainWindow::openTerminal); @@ -1283,10 +1367,21 @@ // setup 'Settings' menu KToggleAction* showMenuBar = KStandardAction::showMenubar(nullptr, nullptr, actionCollection()); + showMenuBar->setWhatsThis(xi18nc("@info:whatsthis", + "This switches between having a Menubar " + "and having a Control button. Both " + "contain mostly the same commands and configuration options.")); connect(showMenuBar, &KToggleAction::triggered, // Fixes #286822 this, &DolphinMainWindow::toggleShowMenuBar, Qt::QueuedConnection); KStandardAction::preferences(this, &DolphinMainWindow::editSettings, actionCollection()); + // setup 'Help' menu for the m_controlButton. The other one is set up in the base class. + m_helpMenu = new KHelpMenu(nullptr); + m_helpMenu->menu()->installEventFilter(this); + // remove duplicate shortcuts + m_helpMenu->action(KHelpMenu::menuHelpContents)->setShortcut(QKeySequence()); + m_helpMenu->action(KHelpMenu::menuWhatsThis)->setShortcut(QKeySequence()); + // not in menu actions QList nextTabKeys = KStandardShortcut::tabNext(); nextTabKeys.append(QKeySequence(Qt::CTRL + Qt::Key_Tab)); @@ -1340,6 +1435,11 @@ lockLayoutAction->setActiveIcon(QIcon::fromTheme(QStringLiteral("object-unlocked"))); lockLayoutAction->setInactiveText(i18nc("@action:inmenu Panels", "Lock Panels")); lockLayoutAction->setInactiveIcon(QIcon::fromTheme(QStringLiteral("object-locked"))); + lockLayoutAction->setWhatsThis(xi18nc("@info:whatsthis", "This " + "switches between having panels locked or " + "unlocked.Unlocked panels can be " + "dragged to the other side of the window and have a close " + "button.Locked panels are embedded more cleanly.")); lockLayoutAction->setActive(lock); connect(lockLayoutAction, &KDualAction::triggered, this, &DolphinMainWindow::togglePanelLockState); @@ -1367,6 +1467,24 @@ infoPanel, &InformationPanel::requestDelayedItemInfo); #endif + // i18n: This is the last paragraph for the "What's This"-texts of all four panels. + const QString panelWhatsThis = xi18nc("@info:whatsthis", "To show or " + "hide panels like this go to Control|Panels " + "or View|Panels."); + actionCollection()->action(QStringLiteral("show_information_panel")) + ->setWhatsThis(xi18nc("@info:whatsthis", " This toggles the " + "information panel at the right side of the " + "window.The panel provides in-depth information " + "about the items your mouse is hovering over or about the selected " + "items. Otherwise it informs you about the currently viewed folder." + "For single items a preview of their contents is provided.")); + infoDock->setWhatsThis(xi18nc("@info:whatsthis", "This panel " + "provides in-depth information about the items your mouse is " + "hovering over or about the selected items. Otherwise it informs " + "you about the currently viewed folder.For single items a " + "preview of their contents is provided.You can configure " + "which and how details are given here by right-clicking.") + panelWhatsThis); + // Setup "Folders" DolphinDockWidget* foldersDock = new DolphinDockWidget(i18nc("@title:window", "Folders")); foldersDock->setLocked(lock); @@ -1389,6 +1507,17 @@ connect(foldersPanel, &FoldersPanel::errorMessage, this, &DolphinMainWindow::showErrorMessage); + actionCollection()->action(QStringLiteral("show_folders_panel")) + ->setWhatsThis(xi18nc("@info:whatsthis", "This toggles the " + "folders panel at the left side of the window." + "It shows the folders of the file system" + " in a tree view.")); + foldersDock->setWhatsThis(xi18nc("@info:whatsthis", "This panel " + "shows the folders of the file system in a " + "tree view.Click a folder to go " + "there. Click the arrow to the left of a folder to see its subfolders. " + "This allows quick switching between any folders.") + panelWhatsThis); + // Setup "Terminal" #ifdef HAVE_TERMINAL if (KAuthorized::authorize(QStringLiteral("shell_access"))) { @@ -1416,6 +1545,22 @@ if (GeneralSettings::version() < 200) { terminalDock->hide(); } + + actionCollection()->action(QStringLiteral("show_terminal_panel")) + ->setWhatsThis(xi18nc("@info:whatsthis", "This toggles the " + "terminal panel at the bottom of the window." + "The location in the terminal will always match the folder " + "view so you can navigate using either.The terminal " + "panel is not needed for basic computer usage but can be useful " + "for advanced tasks. To learn more about terminals use the help " + "in a standalone terminal application like Konsole.")); + terminalDock->setWhatsThis(xi18nc("@info:whatsthis", "This is " + "the terminal panel. It behaves like a " + "normal terminal but will match the location of the folder view " + "so you can navigate using either.The terminal panel " + "is not needed for basic computer usage but can be useful for " + "advanced tasks. To learn more about terminals use the help in a " + "standalone terminal application like Konsole.") + panelWhatsThis); } #endif @@ -1459,6 +1604,9 @@ auto actionShowAllPlaces = new QAction(QIcon::fromTheme(QStringLiteral("hint")), i18nc("@item:inmenu", "Show Hidden Places"), this); actionShowAllPlaces->setCheckable(true); actionShowAllPlaces->setDisabled(true); + actionShowAllPlaces->setWhatsThis(i18nc("@info:whatsthis", "This displays " + "all places in the places panel that have been hidden. They will " + "appear semi-transparent unless you uncheck their hide property.")); connect(actionShowAllPlaces, &QAction::triggered, this, [actionShowAllPlaces, this](bool checked){ actionShowAllPlaces->setIcon(QIcon::fromTheme(checked ? QStringLiteral("visibility") : QStringLiteral("hint"))); @@ -1470,6 +1618,25 @@ actionShowAllPlaces->setIcon(QIcon::fromTheme(checked ? QStringLiteral("visibility") : QStringLiteral("hint"))); }); + actionCollection()->action(QStringLiteral("show_places_panel")) + ->setWhatsThis(xi18nc("@info:whatsthis", "This toggles the " + "places panel at the left side of the window." + "It allows you to go to locations you have " + "bookmarked and to access disk or media attached to the computer " + "or to the network. It also contains sections to find recently " + "saved files or files of a certain type.")); + placesDock->setWhatsThis(xi18nc("@info:whatsthis", "This is the " + "Places panel. It allows you to go to locations " + "you have bookmarked and to access disk or media attached to the " + "computer or to the network. It also contains sections to find " + "recently saved files or files of a certain type." + "Click on an entry to go there. Click with the right mouse button " + "instead to open any entry in a new tab or new window." + "New entries can be added by dragging folders onto this panel. " + "Right-click any section or entry to hide it. Right-click an empty " + "space on this panel and select Show Hidden Places" + " to display it again.") + panelWhatsThis); + // Add actions into the "Panels" menu KActionMenu* panelsMenu = new KActionMenu(i18nc("@action:inmenu View", "Panels"), this); actionCollection()->addAction(QStringLiteral("panels"), panelsMenu); @@ -1536,6 +1703,16 @@ { QAction* goUpAction = actionCollection()->action(KStandardAction::name(KStandardAction::Up)); const QUrl currentUrl = m_activeViewContainer->url(); + // I think this is one of the best places to firstly be confronted + // with a file system and its hierarchy. Talking about the root + // directory might seem too much here but it is the question that + // naturally arises in this context. + goUpAction->setWhatsThis(xi18nc("@info:whatsthis", "Go to " + "the folder that contains the currenty viewed one." + "All files and folders are organized in a hierarchical " + "file system. At the top of this hierarchy is " + "a directory that contains all data connected to this computer" + "—the root directory.")); goUpAction->setEnabled(KIO::upUrl(currentUrl) != currentUrl); } @@ -1549,11 +1726,13 @@ m_controlButton = new QToolButton(this); m_controlButton->setIcon(QIcon::fromTheme(QStringLiteral("application-menu"))); m_controlButton->setText(i18nc("@action", "Control")); + m_controlButton->setAttribute(Qt::WidgetAttribute::WA_CustomWhatsThis); m_controlButton->setPopupMode(QToolButton::InstantPopup); m_controlButton->setToolButtonStyle(toolBar()->toolButtonStyle()); QMenu* controlMenu = new QMenu(m_controlButton); connect(controlMenu, &QMenu::aboutToShow, this, &DolphinMainWindow::updateControlMenu); + controlMenu->installEventFilter(this); m_controlButton->setMenu(controlMenu); @@ -1708,6 +1887,184 @@ connect(dockAction, &QAction::toggled, panelAction, &QAction::setChecked); } +void DolphinMainWindow::setupWhatsThis() +{ + // main widgets + menuBar()->setWhatsThis(xi18nc("@info:whatsthis", "This is the " + "Menubar. It provides access to commands and " + "configuration options. Left-click on any of the menus on this " + "bar to see its contents.The Menubar can be hidden " + "by unchecking Settings|Show Menubar. Then " + "most of its contents become available through a Control" + " button on the Toolbar.")); + toolBar()->setWhatsThis(xi18nc("@info:whatsthis", "This is the " + "Toolbar. It allows quick access to " + "frequently used actions.It is highly customizable. " + "All items you see in the Control menu or " + "in the Menubar can be placed on the " + "Toolbar. Just right-click on it and select Configure " + "Toolbars… or find this action in the " + "Control or Settings menu." + "The location of the bar and the style of its " + "buttons can also be changed in the right-click menu. Right-click " + "a button if you want to show or hide its text.")); + m_tabWidget->setWhatsThis(xi18nc("@info:whatsthis main view", + "Here you can see the folders and " + "files that are at the location described in " + "the Location Bar above. This area is the " + "central part of this application where you navigate to the files " + "you want to use.For an elaborate and general " + "introduction to this application " + "click here. This will open an introductory article from " + "the KDE UserBase Wiki.For brief " + "explanations of all the features of this view " + "click here " + "instead. This will open a page from the Handbook" + " that covers the basics.")); + + // Settings menu + actionCollection()->action(KStandardAction::name(KStandardAction::KeyBindings)) + ->setWhatsThis(xi18nc("@info:whatsthis","This opens a window " + "that lists the keyboard shortcuts." + "There you can set up key combinations to trigger an action when " + "they are pressed simultaneously. All commands in this application can " + "be triggered this way.")); + actionCollection()->action(KStandardAction::name(KStandardAction::ConfigureToolbars)) + ->setWhatsThis(xi18nc("@info:whatsthis","This opens a window in which " + "you can change which buttons appear on the Toolbar." + "All items you see in the Control menu " + "or in the Menubar can also be placed on the Toolbar.")); + actionCollection()->action(KStandardAction::name(KStandardAction::Preferences)) + ->setWhatsThis(xi18nc("@info:whatsthis","This opens a window where you can " + "change a multitude of settings for this application. For an explanation " + "of the various settings go to the chapter Configuring Dolphin" + " in Help|Dolphin Handbook.")); + + // Help menu + // The whatsthis has to be set for the m_helpMenu and for the + // StandardAction separately because both are used in different locations. + // m_helpMenu is only used for createControlButton() button. + + // Links do not work within the Menubar so texts without links are provided there. + + // i18n: If the external link isn't available in your language you should + // probably state the external link language at least in brackets to not + // frustrate the user. If there are multiple languages that the user might + // know with a reasonable chance you might want to have 2 external links. + // The same is in my opinion true for every external link you translate. + const QString whatsThisHelpContents = xi18nc("@info:whatsthis handbook", + "This opens the Handbook for this application. It provides " + "explanations for every part of Dolphin."); + actionCollection()->action(KStandardAction::name(KStandardAction::HelpContents)) + ->setWhatsThis(whatsThisHelpContents + + xi18nc("@info:whatsthis second half of handbook hb text without link", + "If you want more elaborate introductions to the " + "different features of Dolphin " + "go to the KDE UserBase Wiki.")); + m_helpMenu->action(KHelpMenu::menuHelpContents)->setWhatsThis(whatsThisHelpContents + + xi18nc("@info:whatsthis second half of handbook text with link", + "If you want more elaborate introductions to the " + "different features of Dolphin " + "click here. " + "It will open the dedicated page in the KDE UserBase Wiki.")); + + const QString whatsThisWhatsThis = xi18nc("@info:whatsthis whatsthis button", + "This is the button that invokes the help feature you are " + "using right now! Click it, then click any component of this " + "application to ask \"What's this?\" about it. The mouse cursor " + "will change appearance if no help is available for a spot."); + actionCollection()->action(KStandardAction::name(KStandardAction::WhatsThis)) + ->setWhatsThis(whatsThisWhatsThis + + xi18nc("@info:whatsthis second half of whatsthis button text without link", + "There are two other ways to get help for this application: The " + "Dolphin Handbook in the Help" + " menu and the KDE UserBase Wiki " + "article about File Management online." + "The \"What's this?\" help is " + "missing in most other windows so don't get too used to this.")); + m_helpMenu->action(KHelpMenu::menuWhatsThis)->setWhatsThis(whatsThisWhatsThis + + xi18nc("@info:whatsthis second half of whatsthis button text with link", + "There are two other ways to get help: " + "The Dolphin Handbook and " + "the KDE " + "UserBase Wiki.The \"What's this?\" help is " + "missing in most other windows so don't get too used to this.")); + + const QString whatsThisReportBug = xi18nc("@info:whatsthis","This opens a " + "window that will guide you through reporting errors or flaws " + "in this application or in other KDE software."); + actionCollection()->action(KStandardAction::name(KStandardAction::ReportBug)) + ->setWhatsThis(whatsThisReportBug); + m_helpMenu->action(KHelpMenu::menuReportBug)->setWhatsThis(whatsThisReportBug + + xi18nc("@info:whatsthis second half of reportbug text with link", + "High-quality bug reports are much appreciated. To learn " + "how to make your bug report as effective as possible " + "" + "click here.")); + + const QString whatsThisDonate = xi18nc("@info:whatsthis","This opens a " + "web page where you can donate to " + "support the continued work on this application and many " + "other projects by the KDE community." + "Donating is the easiest and fastest way to efficiently " + "support KDE and its projects. KDE projects are available for " + "free therefore your donation is needed to cover things that " + "require money like servers, contributor meetings, etc." + "KDE e.V. is the non-profit " + "organization behind the KDE community."); + actionCollection()->action(KStandardAction::name(KStandardAction::Donate)) + ->setWhatsThis(whatsThisDonate); + m_helpMenu->action(KHelpMenu::menuDonate)->setWhatsThis(whatsThisDonate); + + const QString whatsThisSwitchLanguage = xi18nc("@info:whatsthis", + "With this you can change the language this application uses." + "You can even set secondary languages which will be used " + "if texts are not available in your preferred language."); + actionCollection()->action(KStandardAction::name(KStandardAction::SwitchApplicationLanguage)) + ->setWhatsThis(whatsThisSwitchLanguage); + m_helpMenu->action(KHelpMenu::menuSwitchLanguage)->setWhatsThis(whatsThisSwitchLanguage); + + const QString whatsThisAboutApp = xi18nc("@info:whatsthis","This opens a " + "window that informs you about the version, license, " + "used libraries and maintainers of this application."); + actionCollection()->action(KStandardAction::name(KStandardAction::AboutApp)) + ->setWhatsThis(whatsThisAboutApp); + m_helpMenu->action(KHelpMenu::menuAboutApp)->setWhatsThis(whatsThisAboutApp); + + const QString whatsThisAboutKDE = xi18nc("@info:whatsthis","This opens a " + "window with information about KDE. " + "The KDE community are the people behind this free software." + "If you like using this application but don't know " + "about KDE or want to see a cute dragon have a look!"); + actionCollection()->action(KStandardAction::name(KStandardAction::AboutKDE)) + ->setWhatsThis(whatsThisAboutKDE); + m_helpMenu->action(KHelpMenu::menuAboutKDE)->setWhatsThis(whatsThisAboutKDE); +} + +bool DolphinMainWindow::event(QEvent *event) +{ + if (event->type() == QEvent::WhatsThisClicked) { + event->accept(); + QWhatsThisClickedEvent* whatsThisEvent = dynamic_cast(event); + QDesktopServices::openUrl(QUrl(whatsThisEvent->href())); + return true; + } + return KXmlGuiWindow::event(event); +} + +bool DolphinMainWindow::eventFilter(QObject* obj, QEvent* event) +{ + Q_UNUSED(obj) + if (event->type() == QEvent::WhatsThisClicked) { + event->accept(); + QWhatsThisClickedEvent* whatsThisEvent = dynamic_cast(event); + QDesktopServices::openUrl(QUrl(whatsThisEvent->href())); + return true; + } + return false; +} + DolphinMainWindow::UndoUiInterface::UndoUiInterface() : KIO::FileUndoManager::UiInterface() { diff --git a/src/dolphinviewcontainer.cpp b/src/dolphinviewcontainer.cpp --- a/src/dolphinviewcontainer.cpp +++ b/src/dolphinviewcontainer.cpp @@ -80,6 +80,18 @@ QHBoxLayout* navigatorLayout = new QHBoxLayout(m_navigatorWidget); navigatorLayout->setSpacing(0); navigatorLayout->setContentsMargins(0, 0, 0, 0); + m_navigatorWidget->setWhatsThis(xi18nc("@info:whatsthis location bar", + "This line describes the location of the files and folders " + "displayed below.The name of the currently viewed " + "folder can be read at the very right. To the left of it is the " + "name of the folder that contains it. The whole line is called " + "the path to the current location because " + "following these folders from left to right leads here." + "The path is displayed on the location bar " + "which is more powerful than one would expect. To learn more " + "about the basic and advanced features of the location bar " + "click here. " + "This will open the dedicated page in the Handbook.")); m_urlNavigator = new KUrlNavigator(DolphinPlacesModelSingleton::instance().placesModel(), url, this); connect(m_urlNavigator, &KUrlNavigator::activated, @@ -107,6 +119,18 @@ connect(m_searchBox, &DolphinSearchBox::closeRequest, this, &DolphinViewContainer::closeSearchBox); connect(m_searchBox, &DolphinSearchBox::searchRequest, this, &DolphinViewContainer::startSearching); connect(m_searchBox, &DolphinSearchBox::returnPressed, this, &DolphinViewContainer::requestFocus); + m_searchBox->setWhatsThis(xi18nc("@info:whatsthis findbar", + "This helps you find files and folders. Enter a " + "search term and specify search settings with the " + "buttons at the bottom:Filename/Content: " + "Does the item you are looking for contain the search terms " + "within its filename or its contents?The contents of images, " + "audio files and videos will not be searched." + "From Here/Everywhere: Do you want to search in this " + "folder and its sub-folders or everywhere?" + "More Options: Click this to search by media type, access " + "time or rating.More Search Tools: Install other " + "means to find an item.")); m_messageWidget = new KMessageWidget(this); m_messageWidget->setCloseButtonVisible(true); diff --git a/src/statusbar/dolphinstatusbar.cpp b/src/statusbar/dolphinstatusbar.cpp --- a/src/statusbar/dolphinstatusbar.cpp +++ b/src/statusbar/dolphinstatusbar.cpp @@ -131,6 +131,15 @@ topLayout->addWidget(m_progressBar); setExtensionsVisible(true); + setWhatsThis(xi18nc("@info:whatsthis Statusbar", "This is " + "the Statusbar. It contains three elements " + "by default (left to right):A text field" + " that displays the size of selected items. If only " + "one item is selected the name and type is shown as well." + "A zoom slider that allows you " + "to adjust the size of the icons in the view." + "Space information about the " + "current storage device.")); } DolphinStatusBar::~DolphinStatusBar() diff --git a/src/views/dolphinviewactionhandler.h b/src/views/dolphinviewactionhandler.h --- a/src/views/dolphinviewactionhandler.h +++ b/src/views/dolphinviewactionhandler.h @@ -37,7 +37,7 @@ * @short Handles all actions for DolphinView * * The action handler owns all the actions and slots related to DolphinView, - * but can the view that is acts upon can be switched to another one + * but the view that it acts upon can be switched to another one * (this is used in the case of split views). * * The purpose of this class is also to share this code between DolphinMainWindow diff --git a/src/views/dolphinviewactionhandler.cpp b/src/views/dolphinviewactionhandler.cpp --- a/src/views/dolphinviewactionhandler.cpp +++ b/src/views/dolphinviewactionhandler.cpp @@ -99,21 +99,31 @@ // File menu - KStandardAction::renameFile(this, &DolphinViewActionHandler::slotRename, m_actionCollection); + auto renameAction = KStandardAction::renameFile(this, &DolphinViewActionHandler::slotRename, m_actionCollection); + renameAction->setWhatsThis(xi18nc("@info:whatsthis", "This renames the " + "items in your current selection.Renaming multiple items " + "at once amounts to their new names differing only in a number.")); auto trashAction = KStandardAction::moveToTrash(this, &DolphinViewActionHandler::slotTrashActivated, m_actionCollection); auto trashShortcuts = trashAction->shortcuts(); if (!trashShortcuts.contains(QKeySequence::Delete)) { trashShortcuts.append(QKeySequence::Delete); m_actionCollection->setDefaultShortcuts(trashAction, trashShortcuts); } + trashAction->setWhatsThis(xi18nc("@info:whatsthis", "This moves the " + "items in your current selection to the Trash" + ".The trash is a temporary storage where " + "items can be deleted from if disk space is needed.")); auto deleteAction = KStandardAction::deleteFile(this, &DolphinViewActionHandler::slotDeleteItems, m_actionCollection); auto deleteShortcuts = deleteAction->shortcuts(); if (!deleteShortcuts.contains(Qt::SHIFT | Qt::Key_Delete)) { deleteShortcuts.append(Qt::SHIFT | Qt::Key_Delete); m_actionCollection->setDefaultShortcuts(deleteAction, deleteShortcuts); } + deleteAction->setWhatsThis(xi18nc("@info:whatsthis", "This deletes " + "the items in your current selection completely. They can " + "not be recovered by normal means.")); // This action is useful for being enabled when KStandardAction::MoveToTrash should be // disabled and KStandardAction::DeleteFile is enabled (e.g. non-local files), so that Key_Del @@ -129,6 +139,12 @@ QAction *propertiesAction = m_actionCollection->addAction( QStringLiteral("properties") ); // Well, it's the File menu in dolphinmainwindow and the Edit menu in dolphinpart... :) propertiesAction->setText( i18nc("@action:inmenu File", "Properties") ); + propertiesAction->setWhatsThis(xi18nc("@info:whatsthis properties", + "This shows a complete list of properties of the currently " + "selected items in a new window.If nothing is selected the " + "window will be about the currently viewed folder instead." + "You can configure advanced options there like managing " + "read- and write-permissions.")); propertiesAction->setIcon(QIcon::fromTheme(QStringLiteral("document-properties"))); m_actionCollection->setDefaultShortcuts(propertiesAction, {Qt::ALT + Qt::Key_Return, Qt::ALT + Qt::Key_Enter}); connect(propertiesAction, &QAction::triggered, this, &DolphinViewActionHandler::slotProperties); @@ -138,25 +154,52 @@ KToggleAction* compactAction = compactModeAction(); KToggleAction* detailsAction = detailsModeAction(); + iconsAction->setWhatsThis(xi18nc("@info:whatsthis Icons view mode", + "This switches to a view mode that focuses on the folder " + "and file icons. This mode makes it easy to distinguish folders " + "from files and to detect items with distinctive " + "file types. This mode is handy to " + "browse through pictures when the Preview" + " option is enabled.")); + compactAction->setWhatsThis(xi18nc("@info:whatsthis Compact view mode", + "This switches to a compact view mode that lists the folders " + "and files in columns with the names beside the icons. " + "This helps to keep the overview in folders with many items.")); + detailsAction->setWhatsThis(xi18nc("@info:whatsthis Details view mode", + "This switches to a list view mode that focuses on folder " + "and file details.Click on a detail in the column " + "header to sort the items by it. Click again to sort the other " + "way around. To select which details should be displayed click " + "the header with the right mouse button.You can " + "view the contents of a folder without leaving the current " + "location by clicking to the left of it. This way you can view " + "the contents of multiple folders in the same list.")); + KSelectAction* viewModeActions = m_actionCollection->add(QStringLiteral("view_mode")); viewModeActions->setText(i18nc("@action:intoolbar", "View Mode")); viewModeActions->addAction(iconsAction); viewModeActions->addAction(compactAction); viewModeActions->addAction(detailsAction); viewModeActions->setToolBarMode(KSelectAction::MenuMode); connect(viewModeActions, QOverload::of(&KSelectAction::triggered), this, &DolphinViewActionHandler::slotViewModeActionTriggered); - KStandardAction::zoomIn(this, + QAction* zoomInAction = KStandardAction::zoomIn(this, &DolphinViewActionHandler::zoomIn, m_actionCollection); + zoomInAction->setWhatsThis(i18nc("@info:whatsthis zoom in", "This increases the icon size.")); - KStandardAction::zoomOut(this, + QAction* zoomOutAction = KStandardAction::zoomOut(this, &DolphinViewActionHandler::zoomOut, m_actionCollection); + zoomOutAction->setWhatsThis(i18nc("@info:whatsthis zoom in", "This reduces the icon size.")); KToggleAction* showPreview = m_actionCollection->add(QStringLiteral("show_preview")); showPreview->setText(i18nc("@action:intoolbar", "Preview")); showPreview->setToolTip(i18nc("@info", "Show preview of files and folders")); + showPreview->setWhatsThis(xi18nc("@info:whatsthis", "When this is " + "enabled, the icons are based on the actual file or folder " + "contents.For example the icons of images become scaled " + "down versions of the images.")); showPreview->setIcon(QIcon::fromTheme(QStringLiteral("view-preview"))); connect(showPreview, &KToggleAction::triggered, this, &DolphinViewActionHandler::togglePreview); @@ -197,16 +240,25 @@ KToggleAction* showInGroups = m_actionCollection->add(QStringLiteral("show_in_groups")); showInGroups->setIcon(QIcon::fromTheme(QStringLiteral("view-group"))); showInGroups->setText(i18nc("@action:inmenu View", "Show in Groups")); + showInGroups->setWhatsThis(i18nc("@info:whatsthis", "This groups files and folders by their first letter.")); connect(showInGroups, &KToggleAction::triggered, this, &DolphinViewActionHandler::toggleGroupedSorting); KToggleAction* showHiddenFiles = m_actionCollection->add(QStringLiteral("show_hidden_files")); showHiddenFiles->setText(i18nc("@action:inmenu View", "Hidden Files")); showHiddenFiles->setToolTip(i18nc("@info", "Visibility of hidden files and folders")); + showHiddenFiles->setWhatsThis(xi18nc("@info:whatsthis", "When " + "this is enabled hidden files and folders " + "are visible. They will be displayed semi-transparent." + "Hidden items only differ from other ones in that their " + "name starts with a \".\". In general there is no need for " + "users to access them which is why they are hidden.")); m_actionCollection->setDefaultShortcuts(showHiddenFiles, {Qt::ALT + Qt::Key_Period, Qt::CTRL + Qt::Key_H, Qt::Key_F8}); connect(showHiddenFiles, &KToggleAction::triggered, this, &DolphinViewActionHandler::toggleShowHiddenFiles); QAction* adjustViewProps = m_actionCollection->addAction(QStringLiteral("view_properties")); adjustViewProps->setText(i18nc("@action:inmenu View", "Adjust View Properties...")); + adjustViewProps->setWhatsThis(i18nc("@info:whatsthis", "This opens a window " + "in which all folder view properties can be adjusted.")); connect(adjustViewProps, &QAction::triggered, this, &DolphinViewActionHandler::slotAdjustViewProperties); }