File indexing completed on 2024-04-28 11:41:26

0001 /*
0002     SPDX-FileCopyrightText: 2006 Peter Penz <peter.penz@gmx.at>
0003     SPDX-FileCopyrightText: 2006 Aaron J. Seigo <aseigo@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #ifndef KURLNAVIGATORBUTTON_P_H
0009 #define KURLNAVIGATORBUTTON_P_H
0010 
0011 #include "kurlnavigatorbuttonbase_p.h"
0012 #include "kurlnavigatormenu_p.h"
0013 
0014 #include <kio/global.h>
0015 #include <kio/udsentry.h>
0016 
0017 #include <QPointer>
0018 #include <QUrl>
0019 
0020 class KJob;
0021 class QDropEvent;
0022 class QPaintEvent;
0023 
0024 namespace KIO
0025 {
0026 class ListJob;
0027 class Job;
0028 }
0029 
0030 namespace KDEPrivate
0031 {
0032 /**
0033  * @brief Button of the URL navigator which contains one part of an URL.
0034  *
0035  * It is possible to drop a various number of items to an UrlNavigatorButton. In this case
0036  * a context menu is opened where the user must select whether he wants
0037  * to copy, move or link the dropped items to the URL part indicated by
0038  * the button.
0039  */
0040 class KUrlNavigatorButton : public KUrlNavigatorButtonBase
0041 {
0042     Q_OBJECT
0043     Q_PROPERTY(QString plainText READ plainText) // for the unittest
0044 
0045 public:
0046     explicit KUrlNavigatorButton(const QUrl &url, KUrlNavigator *parent);
0047     ~KUrlNavigatorButton() override;
0048 
0049     void setUrl(const QUrl &url);
0050     QUrl url() const;
0051 
0052     /* Implementation note: QAbstractButton::setText() is not virtual,
0053      * but KUrlNavigatorButton needs to adjust the minimum size when
0054      * the text has been changed. KUrlNavigatorButton::setText() hides
0055      * QAbstractButton::setText() which is not nice, but sufficient for
0056      * the usage in KUrlNavigator.
0057      */
0058     void setText(const QString &text);
0059 
0060     /**
0061      * Sets the name of the sub directory that should be marked when
0062      * opening the sub directories popup.
0063      */
0064     void setActiveSubDirectory(const QString &subDir);
0065     QString activeSubDirectory() const;
0066 
0067     /** @see QWidget::sizeHint() */
0068     QSize sizeHint() const override;
0069 
0070     void setShowMnemonic(bool show);
0071     bool showMnemonic() const;
0072 
0073     struct SubDirInfo {
0074         QString name;
0075         QString displayName;
0076     };
0077 
0078 Q_SIGNALS:
0079     /**
0080      * Emitted when URLs are dropped on the KUrlNavigatorButton associated with
0081      * the URL @p destination.
0082      */
0083     void urlsDroppedOnNavButton(const QUrl &destination, QDropEvent *event);
0084 
0085     void navigatorButtonActivated(const QUrl &url, Qt::MouseButton button, Qt::KeyboardModifiers modifiers);
0086 
0087     /**
0088      * Is emitted, if KUrlNavigatorButton::setUrl() cannot resolve
0089      * the text synchronously and KUrlNavigator::text() will return
0090      * an empty string in this case. The signal finishedTextResolving() is
0091      * emitted, as soon as the text has been resolved.
0092      */
0093     void startedTextResolving();
0094 
0095     /**
0096      * Is emitted, if the asynchronous resolving of the text has
0097      * been finished (see startTextResolving()).
0098      * KUrlNavigatorButton::text() contains the resolved text.
0099      */
0100     void finishedTextResolving();
0101 
0102 protected:
0103 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
0104     void enterEvent(QEnterEvent *event) override;
0105 #else
0106     void enterEvent(QEvent *event) override;
0107 #endif
0108 
0109     void paintEvent(QPaintEvent *event) override;
0110     void leaveEvent(QEvent *event) override;
0111     void keyPressEvent(QKeyEvent *event) override;
0112     void dropEvent(QDropEvent *event) override;
0113     void dragEnterEvent(QDragEnterEvent *event) override;
0114     void dragMoveEvent(QDragMoveEvent *event) override;
0115     void dragLeaveEvent(QDragLeaveEvent *event) override;
0116     void mousePressEvent(QMouseEvent *event) override;
0117     void mouseReleaseEvent(QMouseEvent *event) override;
0118     void mouseMoveEvent(QMouseEvent *event) override;
0119     void wheelEvent(QWheelEvent *event) override;
0120 
0121 private Q_SLOTS:
0122     /**
0123      * Requests to load the sub-directories after a short delay.
0124      * startSubDirsJob() is invoked if the delay is exceeded.
0125      */
0126     void requestSubDirs();
0127 
0128     /**
0129      * Starts to load the sub directories asynchronously. The directories
0130      * are stored in m_subDirs by addEntriesToSubDirs().
0131      */
0132     void startSubDirsJob();
0133 
0134     /**
0135      * Adds the entries from the sub-directories job to m_subDirs. The entries
0136      * will be shown if the job has been finished in openSubDirsMenu() or
0137      * replaceButton().
0138      */
0139     void addEntriesToSubDirs(KIO::Job *job, const KIO::UDSEntryList &entries);
0140 
0141     /**
0142      * Is called after the sub-directories job has been finished and opens a menu
0143      * showing all sub directories.
0144      */
0145     void openSubDirsMenu(KJob *job);
0146 
0147     /**
0148      * Is called after the sub-directories job has been finished and replaces
0149      * the button content by the current sub directory (triggered by
0150      * the scroll wheel).
0151      */
0152     void replaceButton(KJob *job);
0153 
0154     void slotUrlsDropped(QAction *action, QDropEvent *event);
0155 
0156     /**
0157      * Is called, if an action of a sub-menu has been triggered by
0158      * a click.
0159      */
0160     void slotMenuActionClicked(QAction *action, Qt::MouseButton button);
0161 
0162     void statFinished(KJob *);
0163 
0164 private:
0165     /**
0166      * Cancels any request done by requestSubDirs().
0167      */
0168     void cancelSubDirsRequest();
0169 
0170     /**
0171      * @return Text without mnemonic characters.
0172      */
0173     QString plainText() const;
0174 
0175     int arrowWidth() const;
0176     bool isAboveArrow(int x) const;
0177     bool isTextClipped() const;
0178     void updateMinimumWidth();
0179     void initMenu(KUrlNavigatorMenu *menu, int startIndex);
0180 
0181 private:
0182     bool m_hoverArrow;
0183     bool m_pendingTextChange;
0184     bool m_replaceButton;
0185     bool m_showMnemonic;
0186     int m_wheelSteps;
0187     QUrl m_url;
0188 
0189     QString m_subDir;
0190     QTimer *m_openSubDirsTimer;
0191     static QPointer<KUrlNavigatorMenu> m_subDirsMenu;
0192     KIO::ListJob *m_subDirsJob;
0193     std::vector<SubDirInfo> m_subDirs;
0194 };
0195 
0196 } // namespace KDEPrivate
0197 
0198 #endif