]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Improve code quality
authorFelix Ernst <fe.a.ernst@gmail.com>
Mon, 25 Apr 2022 10:52:05 +0000 (12:52 +0200)
committerFelix Ernst <fe.a.ernst@gmail.com>
Sun, 14 Aug 2022 14:42:40 +0000 (14:42 +0000)
15 files changed:
src/dolphinmainwindow.cpp
src/selectionmode/actiontexthelper.cpp
src/selectionmode/actiontexthelper.h
src/selectionmode/actionwithwidget.h
src/selectionmode/backgroundcolorhelper.cpp
src/selectionmode/backgroundcolorhelper.h
src/selectionmode/bottombar.cpp
src/selectionmode/bottombar.h
src/selectionmode/bottombarcontentscontainer.cpp
src/selectionmode/bottombarcontentscontainer.h
src/selectionmode/topbar.cpp
src/selectionmode/topbar.h
src/views/dolphinview.cpp
src/views/dolphinview.h
src/views/dolphinviewactionhandler.cpp

index d8d30448321c3d87a52fc5753a9055feb6982b1c..fcaa5d4a2f65c7e8c705009205e080ce5cc0799e 100644 (file)
@@ -125,7 +125,7 @@ DolphinMainWindow::DolphinMainWindow() :
     setComponentName(QStringLiteral("dolphin"), QGuiApplication::applicationDisplayName());
     setObjectName(QStringLiteral("Dolphin#"));
 
-   // setStateConfigGroup("State");
+    setStateConfigGroup("State");
 
     connect(&DolphinNewFileMenuObserver::instance(), &DolphinNewFileMenuObserver::errorMessage,
             this, &DolphinMainWindow::showErrorMessage);
@@ -1675,8 +1675,7 @@ void DolphinMainWindow::setupActions()
     QAction *toggleSelectionModeAction = actionCollection()->addAction(QStringLiteral("toggle_selection_mode"));
     // i18n: This action toggles a selection mode.
     toggleSelectionModeAction->setText(i18nc("@action:inmenu", "Select Files and Folders"));
-    // i18n: Opens a selection mode for selecting files/folders and later selecting an action that acts on them.
-    // So in a way "Select" here is used to mean both "Select files" and also "Select what to do" but mostly the first.
+    // i18n: Opens a selection mode for selecting files/folders.
     // The text is kept so unspecific because it will be shown on the toolbar where space is at a premium.
     toggleSelectionModeAction->setIconText(i18nc("@action:intoolbar", "Select"));
     toggleSelectionModeAction->setWhatsThis(xi18nc("@info:whatsthis", "<para>This application only knows which files or folders should be acted on if they are"
index 3eb868a8cd29e569057810fede9942c8908aab8a..10360423628fe883b07c7180b929d300e0e109a9 100644 (file)
@@ -22,10 +22,13 @@ void ActionTextHelper::registerTextWhenNothingIsSelected(QAction *action, QStrin
 void ActionTextHelper::textsWhenNothingIsSelectedEnabled(bool enabled)
 {
     for (auto i = m_registeredActionTextChanges.begin(); i != m_registeredActionTextChanges.end(); ++i) {
-        if (!i->action) {
+        while (!i->action) {
             i = m_registeredActionTextChanges.erase(i);
-            continue;
+            if (i == m_registeredActionTextChanges.end()) {
+                break;
+            }
         }
+
         if (enabled && i->textStateOfRegisteredText == TextWhenNothingIsSelected) {
             QString textWhenSomethingIsSelected = i->action->text();
             i->action->setText(i->registeredText);
index 8f7501fa4eb6a185d490c0c0a24d48c2303246a4..1b88403754e3249ad75ddd857b8db30c3d079ac3 100644 (file)
@@ -17,6 +17,11 @@ namespace SelectionMode
 
 /**
  * @brief Helps changing the texts of actions depending on the current selection.
+ *
+ * This is useful for actions that directly trigger a change when there is a selection and do something
+ * different when nothing is selected. For example should the copy action read "Copy" when items are
+ * selected but when no items are selected it can read "Copy…" since triggering it will enter selection
+ * mode and ask users to select the files they want to copy first.
  */
 class ActionTextHelper : QObject
 {
@@ -25,7 +30,7 @@ public:
 
     /**
      * Changes the text of \a action to \a text whenever textsWhenNothingIsSelectedEnabled(true) is called.
-     * The texts can be changed back by calling textsWhenNothingIsSelectedEnabled(false) is called.
+     * The texts can be changed back by calling textsWhenNothingIsSelectedEnabled(false).
      * @see textsWhenNothingIsSelectedEnabled()
      */
     void registerTextWhenNothingIsSelected(QAction *action, QString registeredText);
index cf7b8bc35151eab2d25d5cf8cfa3385e12cd5f10..14db6df2224196d51f4fcaae2af49b47498a44e9 100644 (file)
@@ -21,6 +21,9 @@ namespace SelectionMode
  * @brief Small wrapper/helper class that contains an action and its widget.
  *
  * This class takes neither the responsibility for deleting its action() nor its widget().
+ *
+ * This class is only used from BottomBarContentsContainer currently.
+ * @see BottomBarContentsContainer
  */
 class ActionWithWidget
 {
@@ -28,9 +31,9 @@ public:
     ActionWithWidget(QAction *action);
 
     /**
-     * Connect @p action and @p button using copyActionDataToButton() and the
-     * wraps the two together in the ActionWithWidget object.
-     * ActionWithWidget doesn't take any ownership.
+     * Connect @p action and @p button using copyActionDataToButton() and
+     * wraps the two together in a ActionWithWidget object.
+     * ActionWithWidget doesn't take any ownership over the parameters.
      *
      * @see copyActionDataToButton()
      *
@@ -38,7 +41,7 @@ public:
      */
     ActionWithWidget(QAction *action, QAbstractButton *button);
 
-    /** @returns the action of this object. Crashes if that action has been deleted elsewhere in the meantime. */
+    /** @returns the action of this object. */
     inline QAction *action() {
         Q_CHECK_PTR(m_action);
         return m_action;
@@ -69,7 +72,7 @@ private:
 
 /**
  * A small helper method.
- * @return a button with the correct styling for the general mode of the SelectionModeBottomBar which can be added to its layout.
+ * @return a button with the correct styling for the general mode of the BottomBarContentsContainer which can be added to its layout.
  */
 QAbstractButton *newButtonForAction(QAction *action, QWidget *parent);
 
index 4477d0f2c1dedb4376067a934032f344acd47f0c..fc540315253d06eb7f8b6f6f8d00604e095edfa0 100644 (file)
@@ -54,9 +54,11 @@ void BackgroundColorHelper::slotPaletteChanged()
 {
     updateBackgroundColor();
     for (auto i = m_colorControlledWidgets.begin(); i != m_colorControlledWidgets.end(); ++i) {
-        if (!*i) {
+        while (!*i) {
             i = m_colorControlledWidgets.erase(i);
-            continue;
+            if (i == m_colorControlledWidgets.end()) {
+                break;
+            }
         }
         setBackgroundColorForWidget(*i, m_backgroundColor);
     }
@@ -83,7 +85,8 @@ void BackgroundColorHelper::updateBackgroundColor()
     }
 
     m_backgroundColor = QColor::fromHsv(newHue,
-                                        // Saturation should be closer to the active color because otherwise the selection mode color might overpower it.
+                                        // Saturation should be closer to the saturation of the active color
+                                        // because otherwise the selection mode color might overpower it.
                                         .7 * activeBackgroundColor.saturation() + .3 * positiveBackgroundColor.saturation(),
                                         (activeBackgroundColor.value() + positiveBackgroundColor.value()) / 2,
                                         (activeBackgroundColor.alpha() + positiveBackgroundColor.alpha()) / 2);
index 8d2730fcf1165e8291b96056465fb5ce06ea615a..251c5eddf53e2eca396477263ace318de21893a3 100644 (file)
@@ -28,20 +28,30 @@ public:
 
     /**
      * Changes the background color of @p widget to a distinct color scheme matching color which makes it clear that the widget belongs to the selection mode.
+     * The background color of @p widget will from now on be updated automatically when the palette of the application changes.
      */
     void controlBackgroundColor(QWidget *widget);
 
 private:
     BackgroundColorHelper();
 
+    /**
+     * Called when the palette of the application changes.
+     * Triggers updateBackgroundColor() and the updates the background color of m_colorControlledWidgets.
+     * @see updateBackgroundColor
+     */
     void slotPaletteChanged();
 
+    /** Calculates a new m_colorControlledWidgets based on the current colour scheme of the application. */
     void updateBackgroundColor();
 
 private:
+    /// The widgets who have given up control over the background color to BackgroundColorHelper.
     std::vector<QPointer<QWidget>> m_colorControlledWidgets;
+    /// The color to be used for the widgets' backgrounds.
     QColor m_backgroundColor;
 
+    /// Singleton object
     static BackgroundColorHelper *s_instance;
 };
 
index 999b24ae47885e46c66f082a903e566f17166cae..4ca184a6dfade54033355b3d150743b59f085af3 100644 (file)
 #include "backgroundcolorhelper.h"
 #include "global.h"
 
-#include <KActionCollection>
-#include <KFileItem>
-#include <KFileItemListProperties>
-#include <KStandardAction>
-
 #include <QGridLayout>
 #include <QResizeEvent>
 #include <QScrollArea>
@@ -87,7 +82,6 @@ void BottomBar::setVisibleInternal(bool visible, Animated animated)
     m_heightAnimation->setDuration(2 *
             style()->styleHint(QStyle::SH_Widget_Animation_Duration, nullptr, this) *
             GlobalConfig::animationDurationFactor());
-
     m_heightAnimation->setStartValue(height());
     m_heightAnimation->setEasingCurve(QEasingCurve::OutCubic);
     if (visible) {
@@ -166,7 +160,7 @@ void BottomBar::resizeEvent(QResizeEvent *resizeEvent)
         return QWidget::resizeEvent(resizeEvent);
     }
 
-    m_contentsContainer->updateForNewWidth();
+    m_contentsContainer->adaptToNewBarWidth(width());
 
     return QWidget::resizeEvent(resizeEvent);
 }
index ff23b66998fd3feefbe4134339cf04c2e25d494f..ab29a85a5bf232e4d0628c9adf813176df3d482f 100644 (file)
@@ -15,8 +15,6 @@
 #include <QPropertyAnimation>
 #include <QWidget>
 
-#include <memory>
-
 class KActionCollection;
 class KFileItemList;
 class QAction;
@@ -30,7 +28,7 @@ namespace SelectionMode
     class BottomBarContentsContainer;
 
 /**
- * A bar used in selection mode that serves various purposes depending on what the user is currently trying to do.
+ * @brief A bar used in selection mode that serves various purposes depending on what the user is currently trying to do.
  *
  * The Contents enum below gives a rough idea about the different states this bar might have.
  * The bar is notified of various changes that make changing or updating the content worthwhile.
@@ -43,7 +41,7 @@ class BottomBar : public QWidget
 
 public:
     /** The different contents this bar can have. */
-    enum Contents{
+    enum Contents {
         CopyContents,
         CopyLocationContents,
         CopyToOtherViewContents,
@@ -69,11 +67,20 @@ public:
      *
      * This bar might also not show itself when setVisible(true), when context menu actions are supposed to be shown
      * for the selected items but no items have been selected yet. In that case it will only show itself once items were selected.
+     *
+     * This bar might also ignore a setVisible(false) call, if it has PasteContents because that bar is supposed to stay visible
+     * even outside of selection mode.
+     *
+     * @param visible   Whether this bar is supposed to be visible long term
+     * @param animated  Whether this should be animated. The animation is skipped if the users' settings are configured that way.
+     *
      * @see QWidget::setVisible()
      */
     void setVisible(bool visible, Animated animated);
-    using QWidget::setVisible; // Makes sure that the setVisible() declaration above doesn't hide the one from QWidget.
 
+    /**
+     * Changes the contents of the bar to @p contents.
+     */
     void resetContents(Contents contents);
     Contents contents() const;
 
@@ -81,6 +88,7 @@ public:
     QSize sizeHint() const override;
 
 public Q_SLOTS:
+    /** Adapts the contents based on the selection in the related view. */
     void slotSelectionChanged(const KFileItemList &selection, const QUrl &baseUrl);
 
     /** Used to notify the m_selectionModeBottomBar that there is no other ViewContainer in the tab. */
@@ -102,6 +110,8 @@ protected:
     void resizeEvent(QResizeEvent *resizeEvent) override;
 
 private:
+    using QWidget::setVisible; // Makes sure that the setVisible() declaration above doesn't hide the one from QWidget so we can still use it privately.
+
     /**
      * Identical to SelectionModeBottomBar::setVisible() but doesn't change m_allowedToBeVisible.
      * @see SelectionModeBottomBar::setVisible()
@@ -119,7 +129,7 @@ private:
      * This is necessary because this bar might have been setVisible(true) but there is no reason to show the bar currently so it was kept hidden.
      * @see SelectionModeBottomBar::setVisible() */
     bool m_allowedToBeVisible = false;
-    /// @see SelectionModeBottomBar::setVisible()
+    /** @see SelectionModeBottomBar::setVisible() */
     QPointer<QPropertyAnimation> m_heightAnimation;
 };
 
index 04b52a60f1e4bdd40bd358e3dfc7ccf58c27ad73..2c924415ac7a391599085deacfc5604bea263c14 100644 (file)
@@ -69,8 +69,10 @@ void BottomBarContentsContainer::resetContents(BottomBar::Contents contents)
     }
 }
 
-void BottomBarContentsContainer::updateForNewWidth()
+void BottomBarContentsContainer::adaptToNewBarWidth(int newBarWidth)
 {
+    m_barWidth = newBarWidth;
+
     if (m_contents == BottomBar::GeneralContents) {
         Q_ASSERT(m_overflowButton);
         if (unusedSpace() < 0) {
@@ -94,7 +96,7 @@ void BottomBarContentsContainer::updateForNewWidth()
                 }
             }
         } else {
-            // We have some unusedSpace(). Let's check if we can maybe add more of the contextual action's widgets.
+            // We have some unusedSpace(). Let's check if we can maybe add more of the contextual actions' widgets.
             for (auto i = m_generalBarActions.begin(); i != m_generalBarActions.end(); ++i) {
                 if (i->isWidgetVisible()) {
                     continue;
@@ -130,6 +132,7 @@ void BottomBarContentsContainer::slotSelectionChanged(const KFileItemList &selec
         auto contextActions = contextActionsFor(selection, baseUrl);
         m_generalBarActions.clear();
         if (contextActions.empty()) {
+            // We have nothing to show
             Q_ASSERT(qobject_cast<BottomBar *>(parentWidget()->parentWidget()->parentWidget()));
             if (isVisibleTo(parentWidget()->parentWidget()->parentWidget()->parentWidget())) { // is the bar visible
                 Q_EMIT barVisibilityChangeRequested(false);
@@ -162,7 +165,7 @@ void BottomBarContentsContainer::addCopyContents()
     // We claim to have PasteContents already so triggering the copy action next won't instantly hide the bottom bar.
     connect(copyButton, &QAbstractButton::clicked, [this]() {
         if (GeneralSettings::showPasteBarAfterCopying()) {
-            m_contents = BottomBar::Contents::PasteContents;
+            m_contents = BottomBar::Contents::PasteContents; // prevents hiding
         }
     });
     // Connect the copy action as a second step.
@@ -232,7 +235,7 @@ void BottomBarContentsContainer::addCutContents()
     // We claim to have PasteContents already so triggering the cut action next won't instantly hide the bottom bar.
     connect(cutButton, &QAbstractButton::clicked, [this]() {
         if (GeneralSettings::showPasteBarAfterCopying()) {
-            m_contents = BottomBar::Contents::PasteContents;
+            m_contents = BottomBar::Contents::PasteContents; // prevents hiding
         }
     });
     // Connect the cut action as a second step.
@@ -400,9 +403,9 @@ void BottomBarContentsContainer::addPasteContents()
     vBoxLayout->addWidget(pasteButton);
 
     auto *dismissButton = new QToolButton(this);
-    dismissButton->setText(i18nc("@action Dismisses a bar explaining how to use the Paste action", "Dismiss this Reminder"));
+    dismissButton->setText(i18nc("@action Dismisses a bar explaining how to use the Paste action", "Dismiss This Reminder"));
     connect(dismissButton, &QAbstractButton::clicked, this, actuallyLeaveSelectionMode);
-    auto *dontRemindAgainAction = new QAction(i18nc("@action Dismisses an explanatory area and never shows it again", "Don't remind me again"), this);
+    auto *dontRemindAgainAction = new QAction(i18nc("@action Dismisses an explanatory area and never shows it again", "Don't Remind Me Again"), this);
     connect(dontRemindAgainAction, &QAction::triggered, this, []() {
         GeneralSettings::setShowPasteBarAfterCopying(false);
     });
@@ -516,9 +519,7 @@ int BottomBarContentsContainer::unusedSpace() const
         }
         sumOfPreferredWidths += m_layout->itemAt(i)->sizeHint().width() + m_layout->spacing();
     }
-    Q_ASSERT(qobject_cast<BottomBar *>(parentWidget()->parentWidget()->parentWidget()));
-    const int totalBarWidth = parentWidget()->parentWidget()->parentWidget()->width();
-    return totalBarWidth - sumOfPreferredWidths - 20; // We consider all space used when there are only 20 pixels left
+    return m_barWidth - sumOfPreferredWidths - 20; // We consider all space used when there are only 20 pixels left
                                                       // so there is some room to breath and not too much wonkyness while resizing.
 }
 
@@ -535,7 +536,7 @@ void BottomBarContentsContainer::updateExplanatoryLabelVisibility()
     }
 }
 
-void BottomBarContentsContainer::updateMainActionButton(const KFileItemList& selection)
+void BottomBarContentsContainer::updateMainActionButton(const KFileItemList& selectedItems)
 {
     if (!m_mainAction.widget()) {
         return;
@@ -543,45 +544,69 @@ void BottomBarContentsContainer::updateMainActionButton(const KFileItemList& sel
     Q_ASSERT(qobject_cast<QAbstractButton *>(m_mainAction.widget()));
 
     // Users are nudged towards selecting items by having the button disabled when nothing is selected.
-    m_mainAction.widget()->setEnabled(selection.count() > 0 && m_mainAction.action()->isEnabled());
+    m_mainAction.widget()->setEnabled(selectedItems.count() > 0 && m_mainAction.action()->isEnabled());
     QFontMetrics fontMetrics = m_mainAction.widget()->fontMetrics();
 
     QString buttonText;
     switch (m_contents) {
     case BottomBar::CopyContents:
-        buttonText = i18ncp("@action A more elaborate and clearly worded version of the Copy action",
-                            "Copy %2 to the Clipboard", "Copy %2 to the Clipboard", selection.count(),
-                            fileItemListToString(selection, fontMetrics.averageCharWidth() * 20, fontMetrics));
+        // i18n: A more elaborate and clearly worded version of the Copy action
+        // %2 is a textual representation of the currently selected files or folders. This can be the name of
+        // the file/files like "file1" or "file1, file2 and file3" or an aggregate like "8 Selected Folders".
+        // If this sort of word puzzle can not be correctly translated in your language, translate it as "NULL" (without the quotes)
+        // and a fallback will be used.
+        buttonText = i18ncp("@action", "Copy %2 to the Clipboard", "Copy %2 to the Clipboard", selectedItems.count(), fileItemListToString(selectedItems, fontMetrics.averageCharWidth() * 20, fontMetrics));
+        // All these long lines can not be broken up with line breaks becaue the i18n call should be completely
+        // in the line following the "i18n:" comment without any line breaks within the i18n call
+        // or the comment might not be correctly extracted. See: https://commits.kde.org/kxmlgui/a31135046e1b3335b5d7bbbe6aa9a883ce3284c1
         break;
     case BottomBar::CopyLocationContents:
-        buttonText = i18ncp("@action A more elaborate and clearly worded version of the Copy Location action",
-                            "Copy the Location of %2 to the Clipboard", "Copy the Location of %2 to the Clipboard", selection.count(),
-                            fileItemListToString(selection, fontMetrics.averageCharWidth() * 20, fontMetrics));
+        // i18n: A more elaborate and clearly worded version of the Copy Location action
+        // %2 is a textual representation of the currently selected files or folders. This can be the name of
+        // the file/files like "file1" or "file1, file2 and file3" or an aggregate like "8 Selected Folders".
+        // If this sort of word puzzle can not be correctly translated in your language, translate it as "NULL" (without the quotes)
+        // and a fallback will be used.
+        buttonText = i18ncp("@action", "Copy the Location of %2 to the Clipboard", "Copy the Location of %2 to the Clipboard", selectedItems.count(), fileItemListToString(selectedItems, fontMetrics.averageCharWidth() * 20, fontMetrics));
         break;
     case BottomBar::CutContents:
-        buttonText = i18ncp("@action A more elaborate and clearly worded version of the Cut action",
-                            "Cut %2 to the Clipboard", "Cut %2 to the Clipboard", selection.count(),
-                            fileItemListToString(selection, fontMetrics.averageCharWidth() * 20, fontMetrics));
+        // i18n: A more elaborate and clearly worded version of the Cut action
+        // %2 is a textual representation of the currently selected files or folders. This can be the name of
+        // the file/files like "file1" or "file1, file2 and file3" or an aggregate like "8 Selected Folders".
+        // If this sort of word puzzle can not be correctly translated in your language, translate it as "NULL" (without the quotes)
+        // and a fallback will be used.
+        buttonText = i18ncp("@action", "Cut %2 to the Clipboard", "Cut %2 to the Clipboard", selectedItems.count(), fileItemListToString(selectedItems, fontMetrics.averageCharWidth() * 20, fontMetrics));
         break;
     case BottomBar::DeleteContents:
-        buttonText = i18ncp("@action A more elaborate and clearly worded version of the Delete action",
-                            "Permanently Delete %2", "Permanently Delete %2", selection.count(),
-                            fileItemListToString(selection, fontMetrics.averageCharWidth() * 20, fontMetrics));
+        // i18n: A more elaborate and clearly worded version of the Delete action
+        // %2 is a textual representation of the currently selected files or folders. This can be the name of
+        // the file/files like "file1" or "file1, file2 and file3" or an aggregate like "8 Selected Folders".
+        // If this sort of word puzzle can not be correctly translated in your language, translate it as "NULL" (without the quotes)
+        // and a fallback will be used.
+        buttonText = i18ncp("@action", "Permanently Delete %2", "Permanently Delete %2", selectedItems.count(), fileItemListToString(selectedItems, fontMetrics.averageCharWidth() * 20, fontMetrics));
         break;
     case BottomBar::DuplicateContents:
-        buttonText = i18ncp("@action A more elaborate and clearly worded version of the Duplicate action",
-                            "Duplicate %2", "Duplicate %2", selection.count(),
-                            fileItemListToString(selection, fontMetrics.averageCharWidth() * 20, fontMetrics));
+        // i18n: A more elaborate and clearly worded version of the Duplicate action
+        // %2 is a textual representation of the currently selected files or folders. This can be the name of
+        // the file/files like "file1" or "file1, file2 and file3" or an aggregate like "8 Selected Folders".
+        // If this sort of word puzzle can not be correctly translated in your language, translate it as "NULL" (without the quotes)
+        // and a fallback will be used.
+        buttonText = i18ncp("@action", "Duplicate %2", "Duplicate %2", selectedItems.count(), fileItemListToString(selectedItems, fontMetrics.averageCharWidth() * 20, fontMetrics));
         break;
     case BottomBar::MoveToTrashContents:
-        buttonText = i18ncp("@action A more elaborate and clearly worded version of the Trash action",
-                            "Move %2 to the Trash", "Move %2 to the Trash", selection.count(),
-                            fileItemListToString(selection, fontMetrics.averageCharWidth() * 20, fontMetrics));
+        // i18n: A more elaborate and clearly worded version of the Trash action
+        // %2 is a textual representation of the currently selected files or folders. This can be the name of
+        // the file/files like "file1" or "file1, file2 and file3" or an aggregate like "8 Selected Folders".
+        // If this sort of word puzzle can not be correctly translated in your language, translate it as "NULL" (without the quotes)
+        // and a fallback will be used.
+        buttonText = i18ncp("@action", "Move %2 to the Trash", "Move %2 to the Trash", selectedItems.count(), fileItemListToString(selectedItems, fontMetrics.averageCharWidth() * 20, fontMetrics));
         break;
     case BottomBar::RenameContents:
-        buttonText = i18ncp("@action A more elaborate and clearly worded version of the Rename action",
-                            "Rename %2", "Rename %2", selection.count(),
-                            fileItemListToString(selection, fontMetrics.averageCharWidth() * 20, fontMetrics));
+        // i18n: A more elaborate and clearly worded version of the Rename action
+        // %2 is a textual representation of the currently selected files or folders. This can be the name of
+        // the file/files like "file1" or "file1, file2 and file3" or an aggregate like "8 Selected Folders".
+        // If this sort of word puzzle can not be correctly translated in your language, translate it as "NULL" (without the quotes)
+        // and a fallback will be used.
+        buttonText = i18ncp("@action", "Rename %2", "Rename %2", selectedItems.count(), fileItemListToString(selectedItems, fontMetrics.averageCharWidth() * 20, fontMetrics));
         break;
     default:
         return;
index 6255ff987cdb49159b0130a42dd93d5f54b073be..b9d7947ae318df11d3e40637a36854cce367ad42 100644 (file)
@@ -43,6 +43,9 @@ public:
      */
     explicit BottomBarContentsContainer(KActionCollection *actionCollection, QWidget *parent);
 
+    /**
+     * @param contents The kind of contents that should be contained instead.
+     */
     void resetContents(BottomBar::Contents contents);
     inline BottomBar::Contents contents() const
     {
@@ -53,9 +56,14 @@ public:
         return contents() != BottomBar::GeneralContents || m_internalContextMenu;
     }
 
-    void updateForNewWidth();
+    /**
+     * Is called when the BottomBar resizes to let this ContentsContainer know that it should adapt its contents to the new width.
+     * Adapting is done by showing or hiding labels or buttons.
+     */
+    void adaptToNewBarWidth(int newBarWidth);
 
 public Q_SLOTS:
+    /** Adapts the contents based on the selection in the related view. */
     void slotSelectionChanged(const KFileItemList &selection, const QUrl &baseUrl);
 
 Q_SIGNALS:
@@ -65,8 +73,8 @@ Q_SIGNALS:
     void error(const QString &errorMessage);
 
     /**
-     * Sometimes the contents see no reason to be visible and request the bar to be hidden instead which emits this signal.
-     * This can later change e.g. because the user selected items. Then this signal is used to request showing of the bar.
+     * When it does not make sense to show any specific contents, this signal is emitted and the receiver hides the bar.
+     * Later it might sense to show it again e.g. because the user selected items. Then this signal is used to request showing of the bar.
      */
     void barVisibilityChangeRequested(bool visible);
 
@@ -90,15 +98,15 @@ private:
     void addRenameContents();
 
     /**
-     * Deletes all visible widgets and layouts from the bar.
+     * Deletes every child layout and child widget of this container.
      */
     void emptyBarContents();
 
     /**
-     * @returns A vector containing contextual actions for the given \a selection in the \a baseUrl.
+     * @returns A vector containing contextual actions for the given \a selectedItems in the \a baseUrl.
      * Cut, Copy, Rename and MoveToTrash are always added. Any further contextual actions depend on
-     * \a selection and \a baseUrl. \a selection and \a baseUrl can be empty/default constructed if
-     * no item- or view-specific actions should be added aside from Cut, Copy, Rename, MoveToTrash.
+     * \a selectedItems and \a baseUrl.
+     * If there are no \a selectedItems, an empty vector is returned and m_internalContextMenu is deleted.
      * @param selectedItems The selected items for which contextual actions should be displayed.
      * @param baseUrl       Base URL of the viewport the contextual actions apply to.
      */
@@ -107,7 +115,7 @@ private:
     /**
      * @returns the amount of pixels that can be spared to add more widgets. A negative value might
      * be returned which signifies that some widgets should be hidden or removed from this bar to
-     * make sure that this SelectionModeBottomBar won't stretch the width of its parent.
+     * make sure that this BottomBarContentsContainer can fully fit on the BottomBar.
      */
     int unusedSpace() const;
 
@@ -118,12 +126,12 @@ private:
     void updateExplanatoryLabelVisibility();
 
     /**
-     * Changes the text and enabled state of the main action button
-     * based on the amount of currently selected items and the state of the current m_mainAction.
+     * Changes the text and enabled state of the main action button based on the amount of currently
+     * selected items and the state of the current m_mainAction.
      * The current main action depends on the current barContents.
-     * @param selection the currently selected fileItems.
+     * @param selectedItems the currently selected fileItems.
      */
-    void updateMainActionButton(const KFileItemList &selection);
+    void updateMainActionButton(const KFileItemList &selectedItems);
 
 private:
     /// All the actions that should be available from this bar when in general mode.
@@ -141,11 +149,12 @@ private:
     KActionCollection *m_actionCollection;
     /// Describes the current contents of the bar.
     BottomBar::Contents m_contents;
-    /** The layout all the buttons and labels are added to.
-     * Do not confuse this with layout() because we do have a QScrollView in between this widget and m_layout. */
+    /// The main layout of this ContentsContainer that all the buttons and labels are added to.
     QHBoxLayout *m_layout;
 
-    /// The info label used for some of the BarContents. Is hidden for narrow widths.
+    /// Caches the totalBarWidth as set in adaptToNewWidth(newBarWidth). */
+    int m_barWidth = 0;
+    /// The info label used for some of the Contents. Is hidden for narrow widths.
     QPointer<QLabel> m_explanatoryLabel;
 };
 
index d783c76caaa017754a05acbb1eeb7e70425b9fcb..51467cd99b797ec9df471bb4e2d2a4b967ebb76d 100644 (file)
@@ -42,7 +42,7 @@ TopBar::TopBar(QWidget *parent) :
     fillParentLayout->setContentsMargins(0, 0, 0, 0);
 
     // Put the contents into a QScrollArea. This prevents increasing the view width
-    // in case that not enough width for the contents is available. (this trick is also used in selectionmodebottombar.cpp.)
+    // in case that not enough width for the contents is available. (this trick is also used in bottombar.cpp.)
     auto scrollArea = new QScrollArea(this);
     fillParentLayout->addWidget(scrollArea);
     scrollArea->setFrameShape(QFrame::NoFrame);
@@ -111,9 +111,10 @@ void TopBar::setVisible(bool visible, Animated animated)
     m_heightAnimation->start(QAbstractAnimation::DeleteWhenStopped);
 }
 
-void TopBar::resizeEvent(QResizeEvent */* resizeEvent */)
+void TopBar::resizeEvent(QResizeEvent *resizeEvent)
 {
     updateLabelString();
+    return QWidget::resizeEvent(resizeEvent);
 }
 
 void TopBar::updateLabelString()
index e0cd34935dd5a8e32fda14ac92e72cb9b77a5926..10a65cba07bd92bdb1fccfc7a534ecb36a020ffe 100644 (file)
@@ -40,15 +40,17 @@ public:
      * @see QWidget::setVisible()
      */
     void setVisible(bool visible, Animated animated);
-    using QWidget::setVisible; // Makes sure that the setVisible() declaration above doesn't hide the one from QWidget.
 
 Q_SIGNALS:
     void leaveSelectionModeRequested();
 
 protected:
-    void resizeEvent(QResizeEvent */* resizeEvent */) override;
+    /** Calls updateLabelString() */
+    void resizeEvent(QResizeEvent *resizeEvent) override;
 
 private:
+    using QWidget::setVisible; // Makes sure that the setVisible() declaration above doesn't hide the one from QWidget so we can still use it privately.
+
     /** Decides whether the m_fullLabelString or m_shortLabelString should be used based on available width. */
     void updateLabelString();
 
index f235efffe2cdd391b20ccb794778d246f1c39a2a..0566dbf842b955f4d4a9d82534088d202c0c33f3 100644 (file)
@@ -301,7 +301,6 @@ bool DolphinView::selectionMode() const
     return m_container->controller()->selectionMode();
 }
 
-
 void DolphinView::setPreviewsShown(bool show)
 {
     if (previewsShown() == show) {
index 37af971379d429c4cd371882a61d1bb2e096e18c..9b0dee62e431507f153f35032b1eb11cd8d8ea15 100644 (file)
@@ -112,6 +112,9 @@ public:
     void setViewMode(Mode mode);
     Mode viewMode() const;
 
+    /**
+     * Enables or disables a mode for quick and easy selection of items.
+     */
     void setSelectionMode(bool enabled);
     bool selectionMode() const;
 
index ef30e91c9f46fd9b97102ab40d34383de44a1050..e6c3fc083aa68f3b3c16341f125b37308710dda2 100644 (file)
@@ -166,6 +166,7 @@ void DolphinViewActionHandler::createActions(SelectionMode::ActionTextHelper *ac
     connect(copyPathAction, &QAction::triggered, this, &DolphinViewActionHandler::slotCopyPath);
 
     if (actionTextHelper) {
+        // The "…" at the end make clear that they won't trigger their respective actions directly.
         actionTextHelper->registerTextWhenNothingIsSelected(trashAction, i18nc("@action:inmenu File", "Move to Trash…"));
         actionTextHelper->registerTextWhenNothingIsSelected(deleteAction, i18nc("@action:inmenu File", "Delete…"));
         actionTextHelper->registerTextWhenNothingIsSelected(duplicateAction, i18nc("@action:inmenu File", "Duplicate Here…"));
@@ -438,6 +439,7 @@ void DolphinViewActionHandler::slotRename()
     } else {
         Q_EMIT actionBeingHandled();
         m_currentView->renameSelectedItems();
+        // We don't exit selectionMode here because users might want to rename more items.
     }
 }