File indexing completed on 2025-04-20 12:24:54
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