| 1 | /* |
| 2 | SPDX-FileCopyrightText: 2006 Peter Penz <peter.penz@gmx.at> |
| 3 | SPDX-FileCopyrightText: 2006 Aaron J. Seigo <aseigo@kde.org> |
| 4 | |
| 5 | SPDX-License-Identifier: LGPL-2.0-or-later |
| 6 | */ |
| 7 | |
| 8 | #ifndef KURLNAVIGATORBUTTON_P_H |
| 9 | #define KURLNAVIGATORBUTTON_P_H |
| 10 | |
| 11 | #include "kurlnavigatorbuttonbase_p.h" |
| 12 | #include "kurlnavigatormenu_p.h" |
| 13 | |
| 14 | #include <kio/global.h> |
| 15 | #include <kio/udsentry.h> |
| 16 | |
| 17 | #include <QPointer> |
| 18 | #include <QUrl> |
| 19 | |
| 20 | class KJob; |
| 21 | class QDropEvent; |
| 22 | class QPaintEvent; |
| 23 | |
| 24 | namespace KIO |
| 25 | { |
| 26 | class ListJob; |
| 27 | class Job; |
| 28 | } |
| 29 | |
| 30 | namespace KDEPrivate |
| 31 | { |
| 32 | /*! |
| 33 | * Button of the URL navigator which contains one part of an URL. |
| 34 | * |
| 35 | * It is possible to drop a various number of items to an UrlNavigatorButton. In this case |
| 36 | * a context menu is opened where the user must select whether he wants |
| 37 | * to copy, move or link the dropped items to the URL part indicated by |
| 38 | * the button. |
| 39 | * |
| 40 | * \internal |
| 41 | */ |
| 42 | class KUrlNavigatorButton : public KUrlNavigatorButtonBase |
| 43 | { |
| 44 | Q_OBJECT |
| 45 | Q_PROPERTY(QString plainText READ plainText) // for the unittest |
| 46 | |
| 47 | public: |
| 48 | explicit KUrlNavigatorButton(const QUrl &url, KUrlNavigator *parent); |
| 49 | ~KUrlNavigatorButton() override; |
| 50 | |
| 51 | void setUrl(const QUrl &url); |
| 52 | QUrl url() const; |
| 53 | |
| 54 | /* Implementation note: QAbstractButton::setText() is not virtual, |
| 55 | * but KUrlNavigatorButton needs to adjust the minimum size when |
| 56 | * the text has been changed. KUrlNavigatorButton::setText() hides |
| 57 | * QAbstractButton::setText() which is not nice, but sufficient for |
| 58 | * the usage in KUrlNavigator. |
| 59 | */ |
| 60 | void setText(const QString &text); |
| 61 | |
| 62 | /*! |
| 63 | * Sets the name of the sub directory that should be marked when |
| 64 | * opening the sub directories popup. |
| 65 | */ |
| 66 | void setActiveSubDirectory(const QString &subDir); |
| 67 | QString activeSubDirectory() const; |
| 68 | |
| 69 | /*! \sa QWidget::sizeHint() */ |
| 70 | QSize sizeHint() const override; |
| 71 | |
| 72 | void setShowMnemonic(bool show); |
| 73 | bool showMnemonic() const; |
| 74 | |
| 75 | void setDrawSeparator(bool draw); |
| 76 | bool drawSeparator() const; |
| 77 | |
| 78 | struct SubDirInfo { |
| 79 | QString name; |
| 80 | QString displayName; |
| 81 | }; |
| 82 | |
| 83 | Q_SIGNALS: |
| 84 | /*! |
| 85 | * Emitted when URLs are dropped on the KUrlNavigatorButton associated with |
| 86 | * the URL @p destination. |
| 87 | */ |
| 88 | void urlsDroppedOnNavButton(const QUrl &destination, QDropEvent *event); |
| 89 | |
| 90 | void navigatorButtonActivated(const QUrl &url, Qt::MouseButton button, Qt::KeyboardModifiers modifiers); |
| 91 | |
| 92 | /*! |
| 93 | * Is emitted, if KUrlNavigatorButton::setUrl() cannot resolve |
| 94 | * the text synchronously and KUrlNavigator::text() will return |
| 95 | * an empty string in this case. The signal finishedTextResolving() is |
| 96 | * emitted, as soon as the text has been resolved. |
| 97 | */ |
| 98 | void startedTextResolving(); |
| 99 | |
| 100 | /*! |
| 101 | * Is emitted, if the asynchronous resolving of the text has |
| 102 | * been finished (see startTextResolving()). |
| 103 | * KUrlNavigatorButton::text() contains the resolved text. |
| 104 | */ |
| 105 | void finishedTextResolving(); |
| 106 | |
| 107 | protected: |
| 108 | void enterEvent(QEnterEvent *event) override; |
| 109 | |
| 110 | void paintEvent(QPaintEvent *event) override; |
| 111 | void leaveEvent(QEvent *event) override; |
| 112 | void keyPressEvent(QKeyEvent *event) override; |
| 113 | void dropEvent(QDropEvent *event) override; |
| 114 | void dragEnterEvent(QDragEnterEvent *event) override; |
| 115 | void dragMoveEvent(QDragMoveEvent *event) override; |
| 116 | void dragLeaveEvent(QDragLeaveEvent *event) override; |
| 117 | void mousePressEvent(QMouseEvent *event) override; |
| 118 | void mouseReleaseEvent(QMouseEvent *event) override; |
| 119 | void mouseMoveEvent(QMouseEvent *event) override; |
| 120 | void wheelEvent(QWheelEvent *event) override; |
| 121 | |
| 122 | private Q_SLOTS: |
| 123 | /*! |
| 124 | * Requests to load the sub-directories after a short delay. |
| 125 | * startSubDirsJob() is invoked if the delay is exceeded. |
| 126 | */ |
| 127 | void requestSubDirs(); |
| 128 | |
| 129 | /*! |
| 130 | * Starts to load the sub directories asynchronously. The directories |
| 131 | * are stored in m_subDirs by addEntriesToSubDirs(). |
| 132 | */ |
| 133 | void startSubDirsJob(); |
| 134 | |
| 135 | /*! |
| 136 | * Adds the entries from the sub-directories job to m_subDirs. The entries |
| 137 | * will be shown if the job has been finished in openSubDirsMenu() or |
| 138 | * replaceButton(). |
| 139 | */ |
| 140 | void addEntriesToSubDirs(KIO::Job *job, const KIO::UDSEntryList &entries); |
| 141 | |
| 142 | /*! |
| 143 | * Is called after the sub-directories job has been finished and opens a menu |
| 144 | * showing all sub directories. |
| 145 | */ |
| 146 | void (KJob *job); |
| 147 | |
| 148 | /*! |
| 149 | * Is called after the sub-directories job has been finished and replaces |
| 150 | * the button content by the current sub directory (triggered by |
| 151 | * the scroll wheel). |
| 152 | */ |
| 153 | void replaceButton(KJob *job); |
| 154 | |
| 155 | void slotUrlsDropped(QAction *action, QDropEvent *event); |
| 156 | |
| 157 | /*! |
| 158 | * Is called, if an action of a sub-menu has been triggered by |
| 159 | * a click. |
| 160 | */ |
| 161 | void (QAction *action, Qt::MouseButton button); |
| 162 | |
| 163 | void statFinished(KJob *); |
| 164 | |
| 165 | private: |
| 166 | /*! |
| 167 | * Cancels any request done by requestSubDirs(). |
| 168 | */ |
| 169 | void cancelSubDirsRequest(); |
| 170 | |
| 171 | /*! |
| 172 | * Returns Text without mnemonic characters. |
| 173 | */ |
| 174 | QString plainText() const; |
| 175 | |
| 176 | int arrowWidth() const; |
| 177 | int textWidth() const; |
| 178 | bool isAboveSeparator(int x) const; |
| 179 | bool isTextClipped() const; |
| 180 | void updateMinimumWidth(); |
| 181 | void (KUrlNavigatorMenu *, int startIndex); |
| 182 | |
| 183 | private: |
| 184 | bool m_hoverOverArrow; |
| 185 | bool m_hoverOverButton; |
| 186 | bool m_pendingTextChange; |
| 187 | bool m_replaceButton; |
| 188 | bool m_showMnemonic; |
| 189 | bool m_drawSeparator; |
| 190 | int m_wheelSteps; |
| 191 | QUrl m_url; |
| 192 | |
| 193 | QString m_subDir; |
| 194 | QTimer *m_openSubDirsTimer; |
| 195 | static QPointer<KUrlNavigatorMenu> ; |
| 196 | KIO::ListJob *m_subDirsJob; |
| 197 | std::vector<SubDirInfo> m_subDirs; |
| 198 | |
| 199 | int m_padding; |
| 200 | }; |
| 201 | |
| 202 | } // namespace KDEPrivate |
| 203 | |
| 204 | #endif |
| 205 | |