1 | /***************************************************************************** |
2 | * Copyright (C) 2006-2010 by Peter Penz <peter.penz@gmx.at> * |
3 | * Copyright (C) 2006 by Aaron J. Seigo <aseigo@kde.org> * |
4 | * Copyright (C) 2007 by Kevin Ottens <ervin@kde.org> * |
5 | * Copyright (C) 2007 by Urs Wolfer <uwolfer @ kde.org> * |
6 | * * |
7 | * This library is free software; you can redistribute it and/or * |
8 | * modify it under the terms of the GNU Library General Public * |
9 | * License as published by the Free Software Foundation; either * |
10 | * version 2 of the License, or (at your option) any later version. * |
11 | * * |
12 | * This library is distributed in the hope that it will be useful, * |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * |
15 | * Library General Public License for more details. * |
16 | * * |
17 | * You should have received a copy of the GNU Library General Public License * |
18 | * along with this library; see the file COPYING.LIB. If not, write to * |
19 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * |
20 | * Boston, MA 02110-1301, USA. * |
21 | *****************************************************************************/ |
22 | |
23 | #ifndef KURLNAVIGATOR_H |
24 | #define KURLNAVIGATOR_H |
25 | |
26 | #include <kfile_export.h> |
27 | |
28 | #include <kurl.h> |
29 | #include <QtGui/QWidget> |
30 | #include <QtCore/QByteArray> |
31 | |
32 | class KFilePlacesModel; |
33 | class KUrlComboBox; |
34 | class QMouseEvent; |
35 | |
36 | /** |
37 | * @brief Widget that allows to navigate through the paths of an URL. |
38 | * |
39 | * The URL navigator offers two modes: |
40 | * - Editable: The URL of the location is editable inside an editor. |
41 | * By pressing RETURN the URL will get activated. |
42 | * - Non editable ("breadcrumb view"): The URL of the location is represented by |
43 | * a number of buttons, where each button represents a path |
44 | * of the URL. By clicking on a button the path will get |
45 | * activated. This mode also supports drag and drop of items. |
46 | * |
47 | * The mode can be changed by clicking on the empty area of the URL navigator. |
48 | * It is recommended that the application remembers the setting |
49 | * or allows to configure the default mode (see KUrlNavigator::setUrlEditable()). |
50 | * |
51 | * The URL navigator remembers the URL history during navigation and allows to go |
52 | * back and forward within this history. |
53 | * |
54 | * In the non editable mode ("breadcrumb view") it can be configured whether |
55 | * the full path should be shown. It is recommended that the application |
56 | * remembers the setting or allows to configure the default mode (see |
57 | * KUrlNavigator::setShowFullPath()). |
58 | * |
59 | * The typical usage of the KUrlNavigator is: |
60 | * - Create an instance providing a places model and an URL. |
61 | * - Create an instance of QAbstractItemView which shows the content of the URL |
62 | * given by the URL navigator. |
63 | * - Connect to the signal KUrlNavigator::urlChanged() and synchronize the content of |
64 | * QAbstractItemView with the URL given by the URL navigator. |
65 | * |
66 | * It is recommended, that the application remembers the state of the QAbstractItemView |
67 | * when the URL has been changed. This allows to restore the view state when going back in history. |
68 | * KUrlNavigator offers support for remembering the view state: |
69 | * - The signal urlAboutToBeChanged() will be emitted before the URL change takes places. |
70 | * This allows the application to store the view state by KUrlNavigator::saveLocationState(). |
71 | * - The signal urlChanged() will be emitted after the URL change took place. This allows |
72 | * the application to restore the view state by getting the values from |
73 | * KUrlNavigator::locationState(). |
74 | */ |
75 | class KFILE_EXPORT KUrlNavigator : public QWidget |
76 | { |
77 | Q_OBJECT |
78 | |
79 | public: |
80 | /** @since 4.5 */ |
81 | KUrlNavigator(QWidget* parent = 0); |
82 | |
83 | /** |
84 | * @param placesModel Model for the places which are selectable inside a |
85 | * menu. A place can be a bookmark or a device. If it is 0, |
86 | * no places selector is displayed. |
87 | * @param url URL which is used for the navigation or editing. |
88 | * @param parent Parent widget. |
89 | */ |
90 | KUrlNavigator(KFilePlacesModel* placesModel, const KUrl& url, QWidget* parent); |
91 | virtual ~KUrlNavigator(); |
92 | |
93 | /** |
94 | * @return URL of the location given by the \a historyIndex. If \a historyIndex |
95 | * is smaller than 0, the URL of the current location is returned. |
96 | * @since 4.5 |
97 | */ |
98 | KUrl locationUrl(int historyIndex = -1) const; |
99 | |
100 | /** |
101 | * Saves the location state described by \a state for the current location. It is recommended |
102 | * that at least the scroll position of a view is remembered and restored when traversing |
103 | * through the history. Saving the location state should be done when the signal |
104 | * KUrlNavigator::urlAboutToBeChanged() has been emitted. Restoring the location state (see |
105 | * KUrlNavigator::locationState()) should be done when the signal KUrlNavigator::urlChanged() |
106 | * has been emitted. |
107 | * |
108 | * Example: |
109 | * \code |
110 | * QByteArray state; |
111 | * QDataStream data(&state, QIODevice::WriteOnly); |
112 | * data << QPoint(x, y); |
113 | * data << ...; |
114 | * ... |
115 | * urlNavigator->saveLocationState(state); |
116 | * \endcode |
117 | * |
118 | * @since 4.5 |
119 | */ |
120 | void saveLocationState(const QByteArray& state); |
121 | |
122 | /** |
123 | * @return Location state given by \a historyIndex. If \a historyIndex |
124 | * is smaller than 0, the state of the current location is returned. |
125 | * @see KUrlNavigator::saveLocationState() |
126 | * @since 4.5 |
127 | */ |
128 | QByteArray locationState(int historyIndex = -1) const; |
129 | |
130 | /** |
131 | * Goes back one step in the URL history. The signals |
132 | * KUrlNavigator::urlAboutToBeChanged(), KUrlNavigator::urlChanged() and |
133 | * KUrlNavigator::historyChanged() are emitted if true is returned. False is returned |
134 | * if the beginning of the history has already been reached and hence going back was |
135 | * not possible. The history index (see KUrlNavigator::historyIndex()) is |
136 | * increased by one if the operation was successful. |
137 | */ |
138 | bool goBack(); |
139 | |
140 | /** |
141 | * Goes forward one step in the URL history. The signals |
142 | * KUrlNavigator::urlAboutToBeChanged(), KUrlNavigator::urlChanged() and |
143 | * KUrlNavigator::historyChanged() are emitted if true is returned. False is returned |
144 | * if the end of the history has already been reached and hence going forward |
145 | * was not possible. The history index (see KUrlNavigator::historyIndex()) is |
146 | * decreased by one if the operation was successful. |
147 | */ |
148 | bool goForward(); |
149 | |
150 | /** |
151 | * Goes up one step of the URL path and remembers the old path |
152 | * in the history. The signals KUrlNavigator::urlAboutToBeChanged(), |
153 | * KUrlNavigator::urlChanged() and KUrlNavigator::historyChanged() are |
154 | * emitted if true is returned. False is returned if going up was not |
155 | * possible as the root has been reached. |
156 | */ |
157 | bool goUp(); |
158 | |
159 | /** |
160 | * Goes to the home URL and remembers the old URL in the history. |
161 | * The signals KUrlNavigator::urlAboutToBeChanged(), KUrlNavigator::urlChanged() |
162 | * and KUrlNavigator::historyChanged() are emitted. |
163 | * |
164 | * @see KUrlNavigator::setHomeUrl() |
165 | */ |
166 | // KDE5: Remove the home-property. It is sufficient to invoke |
167 | // KUrlNavigator::setLocationUrl(homeUrl) on application-side. |
168 | void goHome(); |
169 | |
170 | /** |
171 | * Sets the home URL used by KUrlNavigator::goHome(). If no |
172 | * home URL is set, the default home path of the user is used. |
173 | * @since 4.5 |
174 | */ |
175 | // KDE5: Remove the home-property. It is sufficient to invoke |
176 | // KUrlNavigator::setLocationUrl(homeUrl) on application-side. |
177 | void setHomeUrl(const KUrl& url); |
178 | |
179 | KUrl homeUrl() const; |
180 | |
181 | /** |
182 | * Allows to edit the URL of the navigation bar if \a editable |
183 | * is true, and sets the focus accordingly. |
184 | * If \a editable is false, each part of |
185 | * the URL is presented by a button for a fast navigation ("breadcrumb view"). |
186 | */ |
187 | void setUrlEditable(bool editable); |
188 | |
189 | /** |
190 | * @return True, if the URL is editable within a line editor. |
191 | * If false is returned, each part of the URL is presented by a button |
192 | * for fast navigation ("breadcrumb view"). |
193 | */ |
194 | bool isUrlEditable() const; |
195 | |
196 | /** |
197 | * Shows the full path of the URL even if a place represents a part of the URL. |
198 | * Assuming that a place called "Pictures" uses the URL /home/user/Pictures. |
199 | * An URL like /home/user/Pictures/2008 is shown as [Pictures] > [2008] |
200 | * in the breadcrumb view, if showing the full path is turned off. If |
201 | * showing the full path is turned on, the URL is shown |
202 | * as [/] > [home] > [Pictures] > [2008]. |
203 | * @since 4.2 |
204 | */ |
205 | void setShowFullPath(bool show); |
206 | |
207 | /** |
208 | * @return True, if the full path of the URL should be shown in the breadcrumb view. |
209 | * @since 4.2 |
210 | */ |
211 | bool showFullPath() const; |
212 | |
213 | /** |
214 | * Set the URL navigator to the active mode, if \a active |
215 | * is true. The active mode is default. The inactive mode only differs |
216 | * visually from the active mode, no change of the behavior is given. |
217 | * |
218 | * Using the URL navigator in the inactive mode is useful when having split views, |
219 | * where the inactive view is indicated by an inactive URL |
220 | * navigator visually. |
221 | */ |
222 | void setActive(bool active); |
223 | |
224 | /** |
225 | * @return True, if the URL navigator is in the active mode. |
226 | * @see KUrlNavigator::setActive() |
227 | */ |
228 | bool isActive() const; |
229 | |
230 | /** |
231 | * Sets the places selector visible, if \a visible is true. |
232 | * The places selector allows to select the places provided |
233 | * by the places model passed in the constructor. Per default |
234 | * the places selector is visible. |
235 | */ |
236 | void setPlacesSelectorVisible(bool visible); |
237 | |
238 | /** @return True, if the places selector is visible. */ |
239 | bool isPlacesSelectorVisible() const; |
240 | |
241 | /** |
242 | * @return The currently entered, but not accepted URL. |
243 | * It is possible that the returned URL is not valid. |
244 | */ |
245 | KUrl uncommittedUrl() const; |
246 | |
247 | /** |
248 | * @return The amount of locations in the history. The data for each |
249 | * location can be retrieved by KUrlNavigator::locationUrl() and |
250 | * KUrlNavigator::locationState(). |
251 | */ |
252 | int historySize() const; |
253 | |
254 | /** |
255 | * @return The history index of the current location, where |
256 | * 0 <= history index < KUrlNavigator::historySize(). 0 is the most |
257 | * recent history entry. |
258 | */ |
259 | int historyIndex() const; |
260 | |
261 | /** |
262 | * @return The used editor when the navigator is in the edit mode |
263 | * @see KUrlNavigator::setUrlEditable() |
264 | */ |
265 | KUrlComboBox* editor() const; |
266 | |
267 | /** |
268 | * If an application supports only some special protocols, they can be set |
269 | * with \a protocols . |
270 | */ |
271 | // KDE5: Think about removing the custom-protocols-property. It had been used |
272 | // only by one application currently which uses a different approach now. |
273 | void setCustomProtocols(const QStringList& protocols); |
274 | |
275 | /** |
276 | * @return The custom protocols if they are set, QStringList() otherwise. |
277 | */ |
278 | QStringList customProtocols() const; |
279 | |
280 | #if !defined(KDE_NO_DEPRECATED) && !defined(DOXYGEN_SHOULD_SKIP_THIS) |
281 | /** |
282 | * @return The current URL of the location. |
283 | * @deprecated Use KUrlNavigator::locationUrl() instead. |
284 | */ |
285 | KDE_DEPRECATED const KUrl& url() const; |
286 | |
287 | /** |
288 | * @return The portion of the current URL up to the path part given |
289 | * by \a index. Assuming that the current URL is /home/peter/Documents/Music, |
290 | * then the following URLs are returned for an index: |
291 | * - index <= 0: /home |
292 | * - index is 1: /home/peter |
293 | * - index is 2: /home/peter/Documents |
294 | * - index >= 3: /home/peter/Documents/Music |
295 | * @deprecated It should not be necessary for a client of KUrlNavigator to query this information. |
296 | */ |
297 | KDE_DEPRECATED KUrl url(int index) const; |
298 | |
299 | /** |
300 | * @return URL for the history element with the index \a historyIndex. |
301 | * The history index 0 represents the most recent URL. |
302 | * @since 4.3 |
303 | * @deprecated Use KUrlNavigator::locationUrl(historyIndex) instead. |
304 | */ |
305 | KDE_DEPRECATED KUrl historyUrl(int historyIndex) const; |
306 | |
307 | /** |
308 | * @return The saved root URL for the current URL (see KUrlNavigator::saveRootUrl()). |
309 | * @deprecated Use KUrlNavigator::locationState() instead. |
310 | */ |
311 | KDE_DEPRECATED const KUrl& savedRootUrl() const; |
312 | |
313 | /** |
314 | * @return The saved contents position of the upper left corner |
315 | * for the current URL. |
316 | * @deprecated Use KUrlNavigator::locationState() instead. |
317 | */ |
318 | KDE_DEPRECATED QPoint savedPosition() const; |
319 | |
320 | /** @deprecated Use setHomeUrl(const KUrl& url) instead. */ |
321 | KDE_DEPRECATED void setHomeUrl(const QString& homeUrl); |
322 | #endif |
323 | |
324 | public Q_SLOTS: |
325 | /** |
326 | * Sets the location to \a url. The old URL is added to the history. |
327 | * The signals KUrlNavigator::urlAboutToBeChanged(), KUrlNavigator::urlChanged() |
328 | * and KUrlNavigator::historyChanged() are emitted. Use |
329 | * KUrlNavigator::locationUrl() to read the location. |
330 | * @since 4.5 |
331 | */ |
332 | void setLocationUrl(const KUrl& url); |
333 | |
334 | /** |
335 | * Activates the URL navigator (KUrlNavigator::isActive() will return true) |
336 | * and emits the signal KUrlNavigator::activated(). |
337 | * @see KUrlNavigator::setActive() |
338 | */ |
339 | void requestActivation(); |
340 | |
341 | #if !defined(DOXYGEN_SHOULD_SKIP_THIS) |
342 | // KDE5: Remove and listen for focus-signal instead |
343 | void setFocus(); |
344 | #endif |
345 | |
346 | #if !defined(KDE_NO_DEPRECATED) && !defined(DOXYGEN_SHOULD_SKIP_THIS) |
347 | /** |
348 | * Sets the location to \a url. |
349 | * @deprecated Use KUrlNavigator::setLocationUrl(url). |
350 | */ |
351 | KDE_DEPRECATED void setUrl(const KUrl& url); |
352 | |
353 | /** |
354 | * Saves the used root URL of the content for the current history element. |
355 | * @deprecated Use KUrlNavigator::saveLocationState() instead. |
356 | */ |
357 | KDE_DEPRECATED void saveRootUrl(const KUrl& url); |
358 | |
359 | /** |
360 | * Saves the coordinates of the contents for the current history element. |
361 | * @deprecated Use KUrlNavigator::saveLocationState() instead. |
362 | */ |
363 | KDE_DEPRECATED void savePosition(int x, int y); |
364 | #endif |
365 | |
366 | Q_SIGNALS: |
367 | /** |
368 | * Is emitted, if the URL navigator has been activated by |
369 | * an user interaction |
370 | * @see KUrlNavigator::setActive() |
371 | */ |
372 | void activated(); |
373 | |
374 | /** |
375 | * Is emitted, if the location URL has been changed e. g. by |
376 | * the user. |
377 | * @see KUrlNavigator::setUrl() |
378 | */ |
379 | void urlChanged(const KUrl& url); |
380 | |
381 | /** |
382 | * Is emitted, before the location URL is going to be changed to \a newUrl. |
383 | * The signal KUrlNavigator::urlChanged() will be emitted after the change |
384 | * has been done. Connecting to this signal is useful to save the state |
385 | * of a view with KUrlNavigator::saveLocationState(). |
386 | * @since 4.5 |
387 | */ |
388 | void urlAboutToBeChanged(const KUrl& newUrl); |
389 | |
390 | /** |
391 | * Is emitted, if the editable state for the URL has been changed |
392 | * (see KUrlNavigator::setUrlEditable()). |
393 | */ |
394 | void editableStateChanged(bool editable); |
395 | |
396 | /** |
397 | * Is emitted, if the history has been changed. Usually |
398 | * the history is changed if a new URL has been selected. |
399 | */ |
400 | void historyChanged(); |
401 | |
402 | /** |
403 | * Is emitted if a dropping has been done above the destination |
404 | * \a destination. The receiver must accept the drop event if |
405 | * the dropped data can be handled. |
406 | * @since 4.2 |
407 | */ |
408 | void urlsDropped(const KUrl& destination, QDropEvent* event); |
409 | |
410 | /** |
411 | * This signal is emitted when the Return or Enter key is pressed. |
412 | */ |
413 | void returnPressed(); |
414 | |
415 | /** |
416 | * Is emitted if the URL \a url should be opened in a new tab because |
417 | * the user clicked on a breadcrumb with the middle mouse button. |
418 | * @since 4.5 |
419 | */ |
420 | void tabRequested(const KUrl& url); |
421 | |
422 | #if !defined(KDE_NO_DEPRECATED) && !defined(DOXYGEN_SHOULD_SKIP_THIS) |
423 | /** |
424 | * Is emitted if the URLs \a urls have been dropped |
425 | * to the destination \a destination. |
426 | * @deprecated Use |
427 | * KUrlNavigator::urlsDropped(const KUrl& destination, QDropEvent* event) |
428 | * instead. |
429 | */ |
430 | // KDE5: remove, as the signal has been replaced by |
431 | // urlsDropped(const KUrl& destination, QDropEvent* event) |
432 | KDE_DEPRECATED void urlsDropped(const KUrl::List& urls, |
433 | const KUrl& destination); |
434 | #endif |
435 | |
436 | protected: |
437 | #if !defined(DOXYGEN_SHOULD_SKIP_THIS) |
438 | /** |
439 | * If the Escape key is pressed, the navigation bar should switch |
440 | * to the breadcrumb view. |
441 | * @see QWidget::keyPressEvent() |
442 | */ |
443 | virtual void keyPressEvent(QKeyEvent* event); |
444 | |
445 | /** |
446 | * Reimplemented for internal purposes. |
447 | */ |
448 | virtual void keyReleaseEvent(QKeyEvent* event); |
449 | |
450 | /** |
451 | * Paste the clipboard content as URL, if the middle mouse |
452 | * button has been clicked. |
453 | * @see QWidget::mouseReleaseEvent() |
454 | */ |
455 | virtual void mouseReleaseEvent(QMouseEvent* event); |
456 | |
457 | virtual void resizeEvent(QResizeEvent* event); |
458 | |
459 | virtual void wheelEvent(QWheelEvent* event); |
460 | |
461 | virtual bool eventFilter(QObject* watched, QEvent* event); |
462 | #endif |
463 | |
464 | private: |
465 | Q_PRIVATE_SLOT(d, void slotReturnPressed()) |
466 | Q_PRIVATE_SLOT(d, void slotProtocolChanged(const QString& protocol)) |
467 | Q_PRIVATE_SLOT(d, void switchView()) |
468 | Q_PRIVATE_SLOT(d, void dropUrls(const KUrl& destination, QDropEvent*)) |
469 | Q_PRIVATE_SLOT(d, void slotNavigatorButtonClicked(const KUrl& url, Qt::MouseButton button)) |
470 | Q_PRIVATE_SLOT(d, void openContextMenu()) |
471 | Q_PRIVATE_SLOT(d, void openPathSelectorMenu()) |
472 | Q_PRIVATE_SLOT(d, void updateButtonVisibility()) |
473 | Q_PRIVATE_SLOT(d, void switchToBreadcrumbMode()) |
474 | Q_PRIVATE_SLOT(d, void slotPathBoxChanged(const QString& text)) |
475 | Q_PRIVATE_SLOT(d, void updateContent()) |
476 | |
477 | private: |
478 | class Private; |
479 | Private* const d; |
480 | |
481 | Q_DISABLE_COPY(KUrlNavigator) |
482 | }; |
483 | |
484 | #endif |
485 | |