File indexing completed on 2024-04-28 07:44:11

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     void enterEvent(QEnterEvent *event) override;
0104 
0105     void paintEvent(QPaintEvent *event) override;
0106     void leaveEvent(QEvent *event) override;
0107     void keyPressEvent(QKeyEvent *event) override;
0108     void dropEvent(QDropEvent *event) override;
0109     void dragEnterEvent(QDragEnterEvent *event) override;
0110     void dragMoveEvent(QDragMoveEvent *event) override;
0111     void dragLeaveEvent(QDragLeaveEvent *event) override;
0112     void mousePressEvent(QMouseEvent *event) override;
0113     void mouseReleaseEvent(QMouseEvent *event) override;
0114     void mouseMoveEvent(QMouseEvent *event) override;
0115     void wheelEvent(QWheelEvent *event) override;
0116 
0117 private Q_SLOTS:
0118     /**
0119      * Requests to load the sub-directories after a short delay.
0120      * startSubDirsJob() is invoked if the delay is exceeded.
0121      */
0122     void requestSubDirs();
0123 
0124     /**
0125      * Starts to load the sub directories asynchronously. The directories
0126      * are stored in m_subDirs by addEntriesToSubDirs().
0127      */
0128     void startSubDirsJob();
0129 
0130     /**
0131      * Adds the entries from the sub-directories job to m_subDirs. The entries
0132      * will be shown if the job has been finished in openSubDirsMenu() or
0133      * replaceButton().
0134      */
0135     void addEntriesToSubDirs(KIO::Job *job, const KIO::UDSEntryList &entries);
0136 
0137     /**
0138      * Is called after the sub-directories job has been finished and opens a menu
0139      * showing all sub directories.
0140      */
0141     void openSubDirsMenu(KJob *job);
0142 
0143     /**
0144      * Is called after the sub-directories job has been finished and replaces
0145      * the button content by the current sub directory (triggered by
0146      * the scroll wheel).
0147      */
0148     void replaceButton(KJob *job);
0149 
0150     void slotUrlsDropped(QAction *action, QDropEvent *event);
0151 
0152     /**
0153      * Is called, if an action of a sub-menu has been triggered by
0154      * a click.
0155      */
0156     void slotMenuActionClicked(QAction *action, Qt::MouseButton button);
0157 
0158     void statFinished(KJob *);
0159 
0160 private:
0161     /**
0162      * Cancels any request done by requestSubDirs().
0163      */
0164     void cancelSubDirsRequest();
0165 
0166     /**
0167      * @return Text without mnemonic characters.
0168      */
0169     QString plainText() const;
0170 
0171     int arrowWidth() const;
0172     bool isAboveArrow(int x) const;
0173     bool isTextClipped() const;
0174     void updateMinimumWidth();
0175     void initMenu(KUrlNavigatorMenu *menu, int startIndex);
0176 
0177 private:
0178     bool m_hoverArrow;
0179     bool m_pendingTextChange;
0180     bool m_replaceButton;
0181     bool m_showMnemonic;
0182     int m_wheelSteps;
0183     QUrl m_url;
0184 
0185     QString m_subDir;
0186     QTimer *m_openSubDirsTimer;
0187     static QPointer<KUrlNavigatorMenu> m_subDirsMenu;
0188     KIO::ListJob *m_subDirsJob;
0189     std::vector<SubDirInfo> m_subDirs;
0190 };
0191 
0192 } // namespace KDEPrivate
0193 
0194 #endif