File indexing completed on 2024-04-21 05:45:27

0001 /*
0002     This file is part of the KDE project
0003     SPDX-FileCopyrightText: 2022 Felix Ernst <felixernst@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006 */
0007 
0008 #ifndef BOTTOMBARCONTENTSCONTAINER_H
0009 #define BOTTOMBARCONTENTSCONTAINER_H
0010 
0011 #include "actionwithwidget.h"
0012 #include "bottombar.h"
0013 
0014 #include <QPointer>
0015 #include <QPushButton>
0016 #include <QWidget>
0017 
0018 class DolphinContextMenu;
0019 class KActionCollection;
0020 class KFileItemActions;
0021 class KFileItemList;
0022 class QHBoxLayout;
0023 class QLabel;
0024 class QUrl;
0025 
0026 namespace SelectionMode
0027 {
0028 
0029 /**
0030  * @brief An internal widget of BottomBar that controls the visible contents/widgets on it.
0031  *
0032  * This class should only be interacted with from the BottomBar class.
0033  * @see BottomBar
0034  */
0035 class BottomBarContentsContainer : public QWidget
0036 {
0037     Q_OBJECT
0038 
0039 public:
0040     /**
0041      * @param actionCollection the collection where the actions for the contents are retrieved from
0042      * @param parent           the parent widget. Typically a ScrollView within the BottomBar
0043      */
0044     explicit BottomBarContentsContainer(KActionCollection *actionCollection, QWidget *parent);
0045 
0046     /**
0047      * @param contents The kind of contents that should be contained instead.
0048      */
0049     void resetContents(BottomBar::Contents contents);
0050     inline BottomBar::Contents contents() const
0051     {
0052         return m_contents;
0053     };
0054 
0055     inline bool hasSomethingToShow()
0056     {
0057         return contents() != BottomBar::GeneralContents || m_internalContextMenu;
0058     }
0059 
0060     /**
0061      * Is called when the BottomBar resizes to let this ContentsContainer know that it should adapt its contents to the new width.
0062      * Adapting is done by showing or hiding labels or buttons.
0063      */
0064     void adaptToNewBarWidth(int newBarWidth);
0065 
0066 public Q_SLOTS:
0067     /** Adapts the contents based on the selection in the related view. */
0068     void slotSelectionChanged(const KFileItemList &selection, const QUrl &baseUrl);
0069 
0070 Q_SIGNALS:
0071     /**
0072      * Forwards the errors from the KFileItemAction::error() used for contextual actions.
0073      */
0074     void error(const QString &errorMessage);
0075 
0076     /**
0077      * When it does not make sense to show any specific contents, this signal is emitted and the receiver hides the bar.
0078      * Later it might make sense to show it again e.g. because the user selected items. Then this signal is used to request showing of the bar.
0079      */
0080     void barVisibilityChangeRequested(bool visible);
0081 
0082     void selectionModeLeavingRequested();
0083 
0084 private:
0085     void addCopyContents();
0086     void addCopyLocationContents();
0087     void addCopyToOtherViewContents();
0088     void addCutContents();
0089     void addDeleteContents();
0090     void addDuplicateContents();
0091     /**
0092      * Adds the actions of m_generalBarActions as buttons to the bar. An overflow menu button is
0093      * created to make sure any amount of actions can be accessed.
0094      */
0095     void addGeneralContents();
0096     void addMoveToOtherViewContents();
0097     void addMoveToTrashContents();
0098     void addPasteContents();
0099     void addRenameContents();
0100 
0101     /**
0102      * Deletes every child layout and child widget of this container.
0103      */
0104     void emptyBarContents();
0105 
0106     /**
0107      * @returns A vector containing contextual actions for the given \a selectedItems in the \a baseUrl.
0108      * Cut, Copy, Rename and MoveToTrash are always added. Any further contextual actions depend on
0109      * \a selectedItems and \a baseUrl.
0110      * If there are no \a selectedItems, an empty vector is returned and m_internalContextMenu is deleted.
0111      * @param selectedItems The selected items for which contextual actions should be displayed.
0112      * @param baseUrl       Base URL of the viewport the contextual actions apply to.
0113      */
0114     std::vector<QAction *> contextActionsFor(const KFileItemList &selectedItems, const QUrl &baseUrl);
0115 
0116     /**
0117      * @returns the amount of pixels that can be spared to add more widgets. A negative value might
0118      * be returned which signifies that some widgets should be hidden or removed from this bar to
0119      * make sure that this BottomBarContentsContainer can fully fit on the BottomBar.
0120      */
0121     int unusedSpace() const;
0122 
0123     /**
0124      * The label isn't that important. This method hides it if there isn't enough room on the bar or
0125      * shows it if there is.
0126      */
0127     void updateExplanatoryLabelVisibility();
0128 
0129     /**
0130      * Changes the text and enabled state of the main action button based on the amount of currently
0131      * selected items and the state of the current m_mainAction.
0132      * The current main action depends on the current barContents.
0133      * @param selectedItems the currently selected fileItems.
0134      */
0135     void updateMainActionButton(const KFileItemList &selectedItems);
0136 
0137 private:
0138     /// All the actions that should be available from this bar when in general mode.
0139     std::vector<ActionWithWidget> m_generalBarActions;
0140     /// The context menu used to retrieve all the actions that are relevant for the current selection.
0141     std::unique_ptr<DolphinContextMenu> m_internalContextMenu;
0142     /// An object that is necessary to keep around for m_internalContextMenu.
0143     KFileItemActions *m_fileItemActions = nullptr;
0144 
0145     /// @see updateMainActionButtonText
0146     ActionWithWidget m_mainAction = ActionWithWidget(nullptr);
0147     /// The button containing all the actions that don't currently fit into the bar.
0148     QPointer<QPushButton> m_overflowButton;
0149     /// The actionCollection from which the actions for this bar are retrieved.
0150     KActionCollection *m_actionCollection;
0151     /// Describes the current contents of the bar.
0152     BottomBar::Contents m_contents;
0153     /// The main layout of this ContentsContainer that all the buttons and labels are added to.
0154     QHBoxLayout *m_layout;
0155 
0156     /// Caches the totalBarWidth as set in adaptToNewWidth(newBarWidth). */
0157     int m_barWidth = 0;
0158     /// The info label used for some of the Contents. Is hidden for narrow widths.
0159     QPointer<QLabel> m_explanatoryLabel;
0160 };
0161 
0162 }
0163 
0164 #endif // BOTTOMBARCONTENTSCONTAINER_H