File indexing completed on 2023-10-01 04:05:51
0001 /* 0002 SPDX-FileCopyrightText: 2006-2010 Peter Penz <peter.penz@gmx.at> 0003 SPDX-FileCopyrightText: 2006 Aaron J. Seigo <aseigo@kde.org> 0004 SPDX-FileCopyrightText: 2007 Kevin Ottens <ervin@kde.org> 0005 SPDX-FileCopyrightText: 2007 Urs Wolfer <uwolfer @ kde.org> 0006 0007 SPDX-License-Identifier: LGPL-2.0-or-later 0008 */ 0009 0010 #ifndef KURLNAVIGATOR_H 0011 #define KURLNAVIGATOR_H 0012 0013 #include "kiofilewidgets_export.h" 0014 0015 #include <QByteArray> 0016 #include <QUrl> 0017 #include <QWidget> 0018 0019 #include <memory> 0020 0021 class QMouseEvent; 0022 0023 class KFilePlacesModel; 0024 class KUrlComboBox; 0025 0026 class KUrlNavigatorPrivate; 0027 0028 /** 0029 * @class KUrlNavigator kurlnavigator.h <KUrlNavigator> 0030 * 0031 * @brief Widget that allows to navigate through the paths of an URL. 0032 * 0033 * The URL navigator offers two modes: 0034 * - Editable: The URL of the location is editable inside an editor. 0035 * By pressing RETURN the URL will get activated. 0036 * - Non editable ("breadcrumb view"): The URL of the location is represented by 0037 * a number of buttons, where each button represents a path 0038 * of the URL. By clicking on a button the path will get 0039 * activated. This mode also supports drag and drop of items. 0040 * 0041 * The mode can be changed by clicking on the empty area of the URL navigator. 0042 * It is recommended that the application remembers the setting 0043 * or allows to configure the default mode (see KUrlNavigator::setUrlEditable()). 0044 * 0045 * The URL navigator remembers the URL history during navigation and allows to go 0046 * back and forward within this history. 0047 * 0048 * In the non editable mode ("breadcrumb view") it can be configured whether 0049 * the full path should be shown. It is recommended that the application 0050 * remembers the setting or allows to configure the default mode (see 0051 * KUrlNavigator::setShowFullPath()). 0052 * 0053 * The typical usage of the KUrlNavigator is: 0054 * - Create an instance providing a places model and an URL. 0055 * - Create an instance of QAbstractItemView which shows the content of the URL 0056 * given by the URL navigator. 0057 * - Connect to the signal KUrlNavigator::urlChanged() and synchronize the content of 0058 * QAbstractItemView with the URL given by the URL navigator. 0059 * 0060 * It is recommended, that the application remembers the state of the QAbstractItemView 0061 * when the URL has been changed. This allows to restore the view state when going back in history. 0062 * KUrlNavigator offers support for remembering the view state: 0063 * - The signal urlAboutToBeChanged() will be emitted before the URL change takes places. 0064 * This allows the application to store the view state by KUrlNavigator::saveLocationState(). 0065 * - The signal urlChanged() will be emitted after the URL change took place. This allows 0066 * the application to restore the view state by getting the values from 0067 * KUrlNavigator::locationState(). 0068 */ 0069 class KIOFILEWIDGETS_EXPORT KUrlNavigator : public QWidget 0070 { 0071 Q_OBJECT 0072 0073 public: 0074 /** @since 4.5 */ 0075 KUrlNavigator(QWidget *parent = nullptr); 0076 0077 /** 0078 * @param placesModel Model for the places which are selectable inside a 0079 * menu. A place can be a bookmark or a device. If it is 0, 0080 * no places selector is displayed. 0081 * @param url URL which is used for the navigation or editing. 0082 * @param parent Parent widget. 0083 */ 0084 KUrlNavigator(KFilePlacesModel *placesModel, const QUrl &url, QWidget *parent); 0085 ~KUrlNavigator() override; 0086 0087 /** 0088 * @return URL of the location given by the \a historyIndex. If \a historyIndex 0089 * is smaller than 0, the URL of the current location is returned. 0090 * @since 4.5 0091 */ 0092 QUrl locationUrl(int historyIndex = -1) const; 0093 0094 /** 0095 * Saves the location state described by \a state for the current location. It is recommended 0096 * that at least the scroll position of a view is remembered and restored when traversing 0097 * through the history. Saving the location state should be done when the signal 0098 * KUrlNavigator::urlAboutToBeChanged() has been emitted. Restoring the location state (see 0099 * KUrlNavigator::locationState()) should be done when the signal KUrlNavigator::urlChanged() 0100 * has been emitted. 0101 * 0102 * Example: 0103 * \code 0104 * QByteArray state; 0105 * QDataStream data(&state, QIODevice::WriteOnly); 0106 * data << QPoint(x, y); 0107 * data << ...; 0108 * ... 0109 * urlNavigator->saveLocationState(state); 0110 * \endcode 0111 * 0112 * @since 4.5 0113 */ 0114 void saveLocationState(const QByteArray &state); 0115 0116 /** 0117 * @return Location state given by \a historyIndex. If \a historyIndex 0118 * is smaller than 0, the state of the current location is returned. 0119 * @see KUrlNavigator::saveLocationState() 0120 * @since 4.5 0121 */ 0122 QByteArray locationState(int historyIndex = -1) const; 0123 0124 /** 0125 * Goes back one step in the URL history. The signals 0126 * KUrlNavigator::urlAboutToBeChanged(), KUrlNavigator::urlChanged() and 0127 * KUrlNavigator::historyChanged() are emitted if true is returned. False is returned 0128 * if the beginning of the history has already been reached and hence going back was 0129 * not possible. The history index (see KUrlNavigator::historyIndex()) is 0130 * increased by one if the operation was successful. 0131 */ 0132 bool goBack(); 0133 0134 /** 0135 * Goes forward one step in the URL history. The signals 0136 * KUrlNavigator::urlAboutToBeChanged(), KUrlNavigator::urlChanged() and 0137 * KUrlNavigator::historyChanged() are emitted if true is returned. False is returned 0138 * if the end of the history has already been reached and hence going forward 0139 * was not possible. The history index (see KUrlNavigator::historyIndex()) is 0140 * decreased by one if the operation was successful. 0141 */ 0142 bool goForward(); 0143 0144 /** 0145 * Goes up one step of the URL path and remembers the old path 0146 * in the history. The signals KUrlNavigator::urlAboutToBeChanged(), 0147 * KUrlNavigator::urlChanged() and KUrlNavigator::historyChanged() are 0148 * emitted if true is returned. False is returned if going up was not 0149 * possible as the root has been reached. 0150 */ 0151 bool goUp(); 0152 0153 /** 0154 * Goes to the home URL and remembers the old URL in the history. 0155 * The signals KUrlNavigator::urlAboutToBeChanged(), KUrlNavigator::urlChanged() 0156 * and KUrlNavigator::historyChanged() are emitted. 0157 * 0158 * @see KUrlNavigator::setHomeUrl() 0159 */ 0160 // KDE5: Remove the home-property. It is sufficient to invoke 0161 // KUrlNavigator::setLocationUrl(homeUrl) on application-side. 0162 void goHome(); 0163 0164 /** 0165 * Sets the home URL used by KUrlNavigator::goHome(). If no 0166 * home URL is set, the default home path of the user is used. 0167 * @since 4.5 0168 */ 0169 // KDE5: Remove the home-property. It is sufficient to invoke 0170 // KUrlNavigator::setLocationUrl(homeUrl) on application-side. 0171 void setHomeUrl(const QUrl &url); 0172 0173 QUrl homeUrl() const; 0174 0175 /** 0176 * Allows to edit the URL of the navigation bar if \a editable 0177 * is true, and sets the focus accordingly. 0178 * If \a editable is false, each part of 0179 * the URL is presented by a button for a fast navigation ("breadcrumb view"). 0180 */ 0181 void setUrlEditable(bool editable); 0182 0183 /** 0184 * @return True, if the URL is editable within a line editor. 0185 * If false is returned, each part of the URL is presented by a button 0186 * for fast navigation ("breadcrumb view"). 0187 */ 0188 bool isUrlEditable() const; 0189 0190 /** 0191 * Shows the full path of the URL even if a place represents a part of the URL. 0192 * Assuming that a place called "Pictures" uses the URL /home/user/Pictures. 0193 * An URL like /home/user/Pictures/2008 is shown as [Pictures] > [2008] 0194 * in the breadcrumb view, if showing the full path is turned off. If 0195 * showing the full path is turned on, the URL is shown 0196 * as [/] > [home] > [Pictures] > [2008]. 0197 * @since 4.2 0198 */ 0199 void setShowFullPath(bool show); 0200 0201 /** 0202 * @return True, if the full path of the URL should be shown in the breadcrumb view. 0203 * @since 4.2 0204 */ 0205 bool showFullPath() const; 0206 0207 /** 0208 * Set the URL navigator to the active mode, if \a active 0209 * is true. The active mode is default. The inactive mode only differs 0210 * visually from the active mode, no change of the behavior is given. 0211 * 0212 * Using the URL navigator in the inactive mode is useful when having split views, 0213 * where the inactive view is indicated by an inactive URL 0214 * navigator visually. 0215 */ 0216 void setActive(bool active); 0217 0218 /** 0219 * @return True, if the URL navigator is in the active mode. 0220 * @see KUrlNavigator::setActive() 0221 */ 0222 bool isActive() const; 0223 0224 /** 0225 * Sets the places selector visible, if \a visible is true. 0226 * The places selector allows to select the places provided 0227 * by the places model passed in the constructor. Per default 0228 * the places selector is visible. 0229 */ 0230 void setPlacesSelectorVisible(bool visible); 0231 0232 /** @return True, if the places selector is visible. */ 0233 bool isPlacesSelectorVisible() const; 0234 0235 /** 0236 * @return The currently entered, but not accepted URL. 0237 * It is possible that the returned URL is not valid. 0238 */ 0239 QUrl uncommittedUrl() const; 0240 0241 /** 0242 * @return The amount of locations in the history. The data for each 0243 * location can be retrieved by KUrlNavigator::locationUrl() and 0244 * KUrlNavigator::locationState(). 0245 */ 0246 int historySize() const; 0247 0248 /** 0249 * @return The history index of the current location, where 0250 * 0 <= history index < KUrlNavigator::historySize(). 0 is the most 0251 * recent history entry. 0252 */ 0253 int historyIndex() const; 0254 0255 /** 0256 * @return The used editor when the navigator is in the edit mode 0257 * @see KUrlNavigator::setUrlEditable() 0258 */ 0259 KUrlComboBox *editor() const; 0260 0261 #if KIOFILEWIDGETS_ENABLE_DEPRECATED_SINCE(5, 103) 0262 /** 0263 * If an application supports only some special protocols, they can be set 0264 * with \a protocols . 0265 * @deprecated Since 5.103, use setSupportedSchemes(const QStringList &) instead. 0266 */ 0267 KIOFILEWIDGETS_DEPRECATED_VERSION(5, 103, "Use KUrlNavigator::setSupportedSchemes(const QStringList &)") 0268 void setCustomProtocols(const QStringList &protocols); 0269 #endif 0270 0271 #if KIOFILEWIDGETS_ENABLE_DEPRECATED_SINCE(5, 103) 0272 /** 0273 * @return The custom protocols if they are set, QStringList() otherwise. 0274 * @deprecated Since 5.103, use supportedSchemes() const instead. 0275 */ 0276 KIOFILEWIDGETS_DEPRECATED_VERSION(5, 103, "Use KUrlNavigator::supportedSchemes() const") 0277 QStringList customProtocols() const; 0278 #endif 0279 0280 /** 0281 * Set the URL schemes that the navigator should allow navigating to. 0282 * 0283 * If the passed list is empty, all schemes are supported. Examples for 0284 * schemes are @c "file" or @c "ftp". 0285 * 0286 * @sa QFileDialog::setSupportedSchemes 0287 * @since 5.103 0288 */ 0289 void setSupportedSchemes(const QStringList &schemes); 0290 0291 /** 0292 * Returns the URL schemes that the navigator should allow navigating to. 0293 * 0294 * If the returned list is empty, all schemes are supported. 0295 * 0296 * @sa QFileDialog::supportedSchemes 0297 * @since 5.103 0298 */ 0299 QStringList supportedSchemes() const; 0300 0301 /** 0302 * The child widget that received the QDropEvent when dropping on the URL 0303 * navigator. You can pass this widget to KJobWidgets::setWindow() 0304 * if you need to show a drop menu with KIO::drop(). 0305 * @return Child widget that has received the last drop event, or nullptr if 0306 * nothing has been dropped yet on the URL navigator. 0307 * @since 5.37 0308 * @see KIO::drop() 0309 */ 0310 QWidget *dropWidget() const; 0311 0312 /** 0313 * Sets whether to show hidden folders in the subdirectories popup. 0314 * @since 5.87 0315 */ 0316 void setShowHiddenFolders(bool showHiddenFolders); 0317 0318 /** 0319 * Returns whether to show hidden folders in the subdirectories popup. 0320 * @since 5.87 0321 */ 0322 bool showHiddenFolders() const; 0323 0324 /** 0325 * Sets whether to sort hidden folders in the subdirectories popup last. 0326 * @since 5.87 0327 */ 0328 void setSortHiddenFoldersLast(bool sortHiddenFoldersLast); 0329 0330 /** 0331 * Returns whether to sort hidden folders in the subdirectories popup last. 0332 * @since 5.87 0333 */ 0334 bool sortHiddenFoldersLast() const; 0335 0336 #if KIOFILEWIDGETS_ENABLE_DEPRECATED_SINCE(4, 5) 0337 /** 0338 * @return The current URL of the location. 0339 * @deprecated Since 4.5, use KUrlNavigator::locationUrl() instead. 0340 */ 0341 KIOFILEWIDGETS_DEPRECATED_VERSION(4, 5, "Use KUrlNavigator::locationUrl(int)") 0342 const QUrl &url() const; 0343 #endif 0344 0345 #if KIOFILEWIDGETS_ENABLE_DEPRECATED_SINCE(4, 5) 0346 /** 0347 * @return The portion of the current URL up to the path part given 0348 * by \a index. Assuming that the current URL is /home/peter/Documents/Music, 0349 * then the following URLs are returned for an index: 0350 * - index <= 0: /home 0351 * - index is 1: /home/peter 0352 * - index is 2: /home/peter/Documents 0353 * - index >= 3: /home/peter/Documents/Music 0354 * @deprecated Since 4.5. It should not be necessary for a client of KUrlNavigator to query this information. 0355 */ 0356 KIOFILEWIDGETS_DEPRECATED_VERSION(4, 5, "Do not use") 0357 QUrl url(int index) const; 0358 #endif 0359 0360 #if KIOFILEWIDGETS_ENABLE_DEPRECATED_SINCE(4, 5) 0361 /** 0362 * @return URL for the history element with the index \a historyIndex. 0363 * The history index 0 represents the most recent URL. 0364 * @since 4.3 0365 * @deprecated Since 4.5, use KUrlNavigator::locationUrl(historyIndex) instead. 0366 */ 0367 KIOFILEWIDGETS_DEPRECATED_VERSION(4, 5, "Use KUrlNavigator::locationUrl(int)") 0368 QUrl historyUrl(int historyIndex) const; 0369 #endif 0370 0371 #if KIOFILEWIDGETS_ENABLE_DEPRECATED_SINCE(4, 5) 0372 /** 0373 * @return The saved root URL for the current URL (see KUrlNavigator::saveRootUrl()). 0374 * @deprecated Since 4.5, use KUrlNavigator::locationState() instead. 0375 */ 0376 KIOFILEWIDGETS_DEPRECATED_VERSION(4, 5, "Use KUrlNavigator::locationState(int)") 0377 const QUrl &savedRootUrl() const; 0378 #endif 0379 0380 #if KIOFILEWIDGETS_ENABLE_DEPRECATED_SINCE(4, 5) 0381 /** 0382 * @return The saved contents position of the upper left corner 0383 * for the current URL. 0384 * @deprecated Since 4.5, use KUrlNavigator::locationState() instead. 0385 */ 0386 KIOFILEWIDGETS_DEPRECATED_VERSION(4, 5, "Use KUrlNavigator::locationState(int)") 0387 QPoint savedPosition() const; 0388 #endif 0389 0390 #if KIOFILEWIDGETS_ENABLE_DEPRECATED_SINCE(4, 5) 0391 /** @deprecated Since 4.5, use setHomeUrl(const QUrl& url) instead. */ 0392 KIOFILEWIDGETS_DEPRECATED_VERSION(4, 5, "Use KUrlNavigator::setHomeUrl(const QUrl&)") 0393 void setHomeUrl(const QString &homeUrl); 0394 #endif 0395 0396 public Q_SLOTS: 0397 /** 0398 * Sets the location to \a url. The old URL is added to the history. 0399 * The signals KUrlNavigator::urlAboutToBeChanged(), KUrlNavigator::urlChanged() 0400 * and KUrlNavigator::historyChanged() are emitted. Use 0401 * KUrlNavigator::locationUrl() to read the location. 0402 * @since 4.5 0403 */ 0404 void setLocationUrl(const QUrl &url); 0405 0406 /** 0407 * Activates the URL navigator (KUrlNavigator::isActive() will return true) 0408 * and emits the signal KUrlNavigator::activated(). 0409 * @see KUrlNavigator::setActive() 0410 */ 0411 void requestActivation(); 0412 0413 #if !defined(K_DOXYGEN) 0414 // KDE5: Remove and listen for focus-signal instead 0415 void setFocus(); 0416 #endif 0417 0418 #if KIOFILEWIDGETS_ENABLE_DEPRECATED_SINCE(4, 5) 0419 /** 0420 * Sets the location to \a url. 0421 * @deprecated Since 4.5, use KUrlNavigator::setLocationUrl(url). 0422 */ 0423 KIOFILEWIDGETS_DEPRECATED_VERSION(4, 5, "Use KUrlNavigator::setLocationUrl(const QUrl&))") 0424 void setUrl(const QUrl &url); 0425 #endif 0426 0427 #if KIOFILEWIDGETS_ENABLE_DEPRECATED_SINCE(4, 5) 0428 /** 0429 * Saves the used root URL of the content for the current history element. 0430 * @deprecated Since 4.5, use KUrlNavigator::saveLocationState() instead. 0431 */ 0432 KIOFILEWIDGETS_DEPRECATED_VERSION(4, 5, "Use KUrlNavigator::saveLocationState(const QByteArray &)") 0433 void saveRootUrl(const QUrl &url); 0434 #endif 0435 0436 #if KIOFILEWIDGETS_ENABLE_DEPRECATED_SINCE(4, 5) 0437 /** 0438 * Saves the coordinates of the contents for the current history element. 0439 * @deprecated Since 4.5, use KUrlNavigator::saveLocationState() instead. 0440 */ 0441 KIOFILEWIDGETS_DEPRECATED_VERSION(4, 5, "Use KUrlNavigator::saveLocationState(const QByteArray &)") 0442 void savePosition(int x, int y); 0443 #endif 0444 0445 Q_SIGNALS: 0446 /** 0447 * Is emitted, if the URL navigator has been activated by 0448 * an user interaction 0449 * @see KUrlNavigator::setActive() 0450 */ 0451 void activated(); 0452 0453 /** 0454 * Is emitted, if the location URL has been changed e. g. by 0455 * the user. 0456 * @see KUrlNavigator::setUrl() 0457 */ 0458 void urlChanged(const QUrl &url); 0459 0460 /** 0461 * Is emitted, before the location URL is going to be changed to \a newUrl. 0462 * The signal KUrlNavigator::urlChanged() will be emitted after the change 0463 * has been done. Connecting to this signal is useful to save the state 0464 * of a view with KUrlNavigator::saveLocationState(). 0465 * @since 4.5 0466 */ 0467 void urlAboutToBeChanged(const QUrl &newUrl); 0468 0469 /** 0470 * Is emitted, if the editable state for the URL has been changed 0471 * (see KUrlNavigator::setUrlEditable()). 0472 */ 0473 void editableStateChanged(bool editable); 0474 0475 /** 0476 * Is emitted, if the history has been changed. Usually 0477 * the history is changed if a new URL has been selected. 0478 */ 0479 void historyChanged(); 0480 0481 /** 0482 * Is emitted if a dropping has been done above the destination 0483 * \a destination. The receiver must accept the drop event if 0484 * the dropped data can be handled. 0485 * @since 4.2 0486 */ 0487 void urlsDropped(const QUrl &destination, QDropEvent *event); 0488 0489 /** 0490 * This signal is emitted when the Return or Enter key is pressed. 0491 */ 0492 void returnPressed(); 0493 0494 /** 0495 * Is emitted if the URL \a url should be opened in a new inactive tab because 0496 * the user clicked on a breadcrumb with the middle mouse button or 0497 * left-clicked with the ctrl modifier pressed. 0498 * @since 4.5 0499 */ 0500 void tabRequested(const QUrl &url); 0501 0502 /** 0503 * Is emitted if the URL \a url should be opened in a new active tab because 0504 * the user clicked on a breadcrumb with the middle mouse button with 0505 * the shift modifier pressed or left-clicked with both the ctrl and shift 0506 * modifiers pressed. 0507 * @since 5.89 0508 */ 0509 void activeTabRequested(const QUrl &url); 0510 0511 /** 0512 * Is emitted if the URL \a url should be opened in a new window because 0513 * the user left-clicked on a breadcrumb with the shift modifier pressed. 0514 * @since 5.89 0515 */ 0516 void newWindowRequested(const QUrl &url); 0517 0518 /** 0519 * When the URL is changed and the new URL (e.g.\ /home/user1/) 0520 * is a parent of the previous URL (e.g.\ /home/user1/data/stuff), 0521 * then this signal is emitted and \p url is set to the child 0522 * directory of the new URL which is an ancestor of the old URL 0523 * (in the example paths this would be /home/user1/data/). 0524 * This signal allows file managers to pre-select the directory 0525 * that the user is navigating up from. 0526 * @since 5.37.0 0527 */ 0528 void urlSelectionRequested(const QUrl &url); 0529 0530 protected: 0531 #if !defined(K_DOXYGEN) 0532 /** 0533 * If the Escape key is pressed, the navigation bar should switch 0534 * to the breadcrumb view. 0535 * @see QWidget::keyPressEvent() 0536 */ 0537 void keyPressEvent(QKeyEvent *event) override; 0538 0539 /** 0540 * Reimplemented for internal purposes. 0541 */ 0542 void keyReleaseEvent(QKeyEvent *event) override; 0543 0544 /** 0545 * Paste the clipboard content as URL, if the middle mouse 0546 * button has been clicked. 0547 * @see QWidget::mouseReleaseEvent() 0548 */ 0549 void mouseReleaseEvent(QMouseEvent *event) override; 0550 0551 /** 0552 * Reimplemented to activate on middle mousse button click 0553 */ 0554 void mousePressEvent(QMouseEvent *event) override; 0555 0556 void resizeEvent(QResizeEvent *event) override; 0557 0558 void wheelEvent(QWheelEvent *event) override; 0559 0560 bool eventFilter(QObject *watched, QEvent *event) override; 0561 #endif 0562 0563 private: 0564 friend class KUrlNavigatorPrivate; 0565 std::unique_ptr<KUrlNavigatorPrivate> const d; 0566 0567 Q_DISABLE_COPY(KUrlNavigator) 0568 }; 0569 0570 #endif