OSDN Git Service

am 4ad9c9b7: (-s ours) am 237bd75b: First draft of multitouch in the WebView.
[android-x86/external-webkit.git] / WebKit / qt / Api / qwebhistory.cpp
1 /*
2     Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
3
4     This library is free software; you can redistribute it and/or
5     modify it under the terms of the GNU Library General Public
6     License as published by the Free Software Foundation; either
7     version 2 of the License, or (at your option) any later version.
8
9     This library is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12     Library General Public License for more details.
13
14     You should have received a copy of the GNU Library General Public License
15     along with this library; see the file COPYING.LIB.  If not, write to
16     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17     Boston, MA 02110-1301, USA.
18 */
19
20 #include "config.h"
21 #include "qwebhistory.h"
22 #include "qwebhistory_p.h"
23 #include "qwebframe_p.h"
24
25 #include "PlatformString.h"
26 #include "Image.h"
27 #include "KURL.h"
28 #include "Page.h"
29 #include "PageGroup.h"
30
31 #include <QSharedData>
32 #include <QDebug>
33
34 enum {
35     InitialHistoryVersion = 1,
36     DefaultHistoryVersion = InitialHistoryVersion
37 };
38
39 /*!
40   \class QWebHistoryItem
41   \since 4.4
42   \brief The QWebHistoryItem class represents one item in the history of a QWebPage
43
44   \inmodule QtWebKit
45
46   Each QWebHistoryItem instance represents an entry in the history stack of a Web page,
47   containing information about the page, its location, and when it was last visited.
48
49   The following table shows the properties of the page held by the history item, and
50   the functions used to access them.
51
52   \table
53   \header \o Function      \o Description
54   \row    \o title()       \o The page title.
55   \row    \o url()         \o The location of the page.
56   \row    \o originalUrl() \o The URL used to access the page.
57   \row    \o lastVisited() \o The date and time of the user's last visit to the page.
58   \row    \o icon()        \o The icon associated with the page that was provided by the server.
59   \row    \o userData()    \o The user specific data that was stored with the history item.
60   \endtable
61
62   \note QWebHistoryItem objects are value based, but \e{explicitly shared}. Changing
63   a QWebHistoryItem instance by calling setUserData() will change all copies of that
64   instance.
65
66   \sa QWebHistory, QWebPage::history(), QWebHistoryInterface
67 */
68
69 /*!
70   Constructs a history item from \a other. The new item and \a other
71   will share their data, and modifying either this item or \a other will
72   modify both instances.
73 */
74 QWebHistoryItem::QWebHistoryItem(const QWebHistoryItem &other)
75     : d(other.d)
76 {
77 }
78
79 /*!
80   Assigns the \a other history item to this. This item and \a other
81   will share their data, and modifying either this item or \a other will
82   modify both instances.
83 */
84 QWebHistoryItem &QWebHistoryItem::operator=(const QWebHistoryItem &other)
85 {
86     d = other.d;
87     return *this;
88 }
89
90 /*!
91   Destroys the history item.
92 */
93 QWebHistoryItem::~QWebHistoryItem()
94 {
95 }
96
97 /*!
98  Returns the original URL associated with the history item.
99
100  \sa url()
101 */
102 QUrl QWebHistoryItem::originalUrl() const
103 {
104     if (d->item)
105         return QUrl(d->item->originalURL().string());
106     return QUrl();
107 }
108
109
110 /*!
111  Returns the URL associated with the history item.
112
113  \sa originalUrl(), title(), lastVisited()
114 */
115 QUrl QWebHistoryItem::url() const
116 {
117     if (d->item)
118         return QUrl(d->item->url().string());
119     return QUrl();
120 }
121
122
123 /*!
124  Returns the title of the page associated with the history item.
125
126  \sa icon(), url(), lastVisited()
127 */
128 QString QWebHistoryItem::title() const
129 {
130     if (d->item)
131         return d->item->title();
132     return QString();
133 }
134
135
136 /*!
137  Returns the date and time that the page associated with the item was last visited.
138
139  \sa title(), icon(), url()
140 */
141 QDateTime QWebHistoryItem::lastVisited() const
142 {
143     //FIXME : this will be wrong unless we correctly set lastVisitedTime ourselves
144     if (d->item)
145         return QDateTime::fromTime_t((uint)d->item->lastVisitedTime());
146     return QDateTime();
147 }
148
149
150 /*!
151  Returns the icon associated with the history item.
152
153  \sa title(), url(), lastVisited()
154 */
155 QIcon QWebHistoryItem::icon() const
156 {
157     if (d->item)
158         return *d->item->icon()->nativeImageForCurrentFrame();
159     return QIcon();
160 }
161
162 /*!
163   \since 4.5
164   Returns the user specific data that was stored with the history item.
165
166   \sa setUserData()
167 */
168 QVariant QWebHistoryItem::userData() const
169 {
170     if (d->item)
171         return d->item->userData();
172     return QVariant();
173 }
174
175 /*!
176   \since 4.5
177
178  Stores user specific data \a userData with the history item.
179  
180  \note All copies of this item will be modified.
181
182  \sa userData()
183 */
184 void QWebHistoryItem::setUserData(const QVariant& userData)
185 {
186     if (d->item)
187         d->item->setUserData(userData);
188 }
189
190 /*!*
191   \internal
192 */
193 QWebHistoryItem::QWebHistoryItem(QWebHistoryItemPrivate *priv)
194 {
195     d = priv;
196 }
197
198 /*!
199     \since 4.5
200     Returns whether this is a valid history item.
201 */
202 bool QWebHistoryItem::isValid() const
203 {
204     return d->item;
205 }
206
207 /*!
208   \class QWebHistory
209   \since 4.4
210   \brief The QWebHistory class represents the history of a QWebPage
211
212   \inmodule QtWebKit
213
214   Each QWebPage instance contains a history of visited pages that can be accessed
215   by QWebPage::history(). QWebHistory represents this history and makes it possible
216   to navigate it.
217
218   The history uses the concept of a \e{current item}, dividing the pages visited
219   into those that can be visited by navigating \e back and \e forward using the
220   back() and forward() functions. The current item can be obtained by calling
221   currentItem(), and an arbitrary item in the history can be made the current
222   item by passing it to goToItem().
223
224   A list of items describing the pages that can be visited by going back can be
225   obtained by calling the backItems() function; similarly, items describing the
226   pages ahead of the current page can be obtained with the forwardItems() function.
227   The total list of items is obtained with the items() function.
228
229   Just as with containers, functions are available to examine the history in terms
230   of a list. Arbitrary items in the history can be obtained with itemAt(), the total
231   number of items is given by count(), and the history can be cleared with the
232   clear() function.
233
234   QWebHistory's state can be saved to a QDataStream using the >> operator and loaded
235   by using the << operator.
236
237   \sa QWebHistoryItem, QWebHistoryInterface, QWebPage
238 */
239
240
241 QWebHistory::QWebHistory()
242     : d(0)
243 {
244 }
245
246 QWebHistory::~QWebHistory()
247 {
248     delete d;
249 }
250
251 /*!
252   Clears the history.
253
254   \sa count(), items()
255 */
256 void QWebHistory::clear()
257 {
258     //shortcut to private BackForwardList
259     WebCore::BackForwardList* lst = d->lst;
260
261     //clear visited links
262     WebCore::Page* page = lst->page();
263     if (page && page->groupPtr())
264         page->groupPtr()->removeVisitedLinks();
265
266     //if count() == 0 then just return
267     if (!lst->entries().size())
268         return;
269
270     RefPtr<WebCore::HistoryItem> current = lst->currentItem();
271     int capacity = lst->capacity();
272     lst->setCapacity(0);
273
274     lst->setCapacity(capacity);   //revert capacity
275     lst->addItem(current.get());  //insert old current item
276     lst->goToItem(current.get()); //and set it as current again
277
278     d->page()->updateNavigationActions();
279 }
280
281 /*!
282   Returns a list of all items currently in the history.
283
284   \sa count(), clear()
285 */
286 QList<QWebHistoryItem> QWebHistory::items() const
287 {
288     const WebCore::HistoryItemVector &items = d->lst->entries();
289
290     QList<QWebHistoryItem> ret;
291     for (unsigned i = 0; i < items.size(); ++i) {
292         QWebHistoryItemPrivate *priv = new QWebHistoryItemPrivate(items[i].get());
293         ret.append(QWebHistoryItem(priv));
294     }
295     return ret;
296 }
297
298 /*!
299   Returns the list of items in the backwards history list.
300   At most \a maxItems entries are returned.
301
302   \sa forwardItems()
303 */
304 QList<QWebHistoryItem> QWebHistory::backItems(int maxItems) const
305 {
306     WebCore::HistoryItemVector items(maxItems);
307     d->lst->backListWithLimit(maxItems, items);
308
309     QList<QWebHistoryItem> ret;
310     for (unsigned i = 0; i < items.size(); ++i) {
311         QWebHistoryItemPrivate *priv = new QWebHistoryItemPrivate(items[i].get());
312         ret.append(QWebHistoryItem(priv));
313     }
314     return ret;
315 }
316
317 /*!
318   Returns the list of items in the forward history list.
319   At most \a maxItems entries are returned.
320
321   \sa backItems()
322 */
323 QList<QWebHistoryItem> QWebHistory::forwardItems(int maxItems) const
324 {
325     WebCore::HistoryItemVector items(maxItems);
326     d->lst->forwardListWithLimit(maxItems, items);
327
328     QList<QWebHistoryItem> ret;
329     for (unsigned i = 0; i < items.size(); ++i) {
330         QWebHistoryItemPrivate *priv = new QWebHistoryItemPrivate(items[i].get());
331         ret.append(QWebHistoryItem(priv));
332     }
333     return ret;
334 }
335
336 /*!
337   Returns true if there is an item preceding the current item in the history;
338   otherwise returns false.
339
340   \sa canGoForward()
341 */
342 bool QWebHistory::canGoBack() const
343 {
344     return d->lst->backListCount() > 0;
345 }
346
347 /*!
348   Returns true if we have an item to go forward to; otherwise returns false.
349
350   \sa canGoBack()
351 */
352 bool QWebHistory::canGoForward() const
353 {
354     return d->lst->forwardListCount() > 0;
355 }
356
357 /*!
358   Set the current item to be the previous item in the history and goes to the
359   corresponding page; i.e., goes back one history item.
360
361   \sa forward(), goToItem()
362 */
363 void QWebHistory::back()
364 {
365     if (canGoBack()) {
366         d->lst->goBack();
367         WebCore::Page* page = d->lst->page();
368         page->goToItem(currentItem().d->item, WebCore::FrameLoadTypeIndexedBackForward);
369     }
370 }
371
372 /*!
373   Sets the current item to be the next item in the history and goes to the
374   corresponding page; i.e., goes forward one history item.
375
376   \sa back(), goToItem()
377 */
378 void QWebHistory::forward()
379 {
380     if (canGoForward()) {
381         d->lst->goForward();
382         WebCore::Page* page = d->lst->page();
383         page->goToItem(currentItem().d->item, WebCore::FrameLoadTypeIndexedBackForward);
384     }
385 }
386
387 /*!
388   Sets the current item to be the specified \a item in the history and goes to the page.
389
390   \sa back(), forward()
391 */
392 void QWebHistory::goToItem(const QWebHistoryItem &item)
393 {
394     d->lst->goToItem(item.d->item);
395     WebCore::Page* page = d->lst->page();
396     page->goToItem(currentItem().d->item, WebCore::FrameLoadTypeIndexedBackForward);
397 }
398
399 /*!
400   Returns the item before the current item in the history.
401 */
402 QWebHistoryItem QWebHistory::backItem() const
403 {
404     WebCore::HistoryItem *i = d->lst->backItem();
405     QWebHistoryItemPrivate *priv = new QWebHistoryItemPrivate(i);
406     return QWebHistoryItem(priv);
407 }
408
409 /*!
410   Returns the current item in the history.
411 */
412 QWebHistoryItem QWebHistory::currentItem() const
413 {
414     WebCore::HistoryItem *i = d->lst->currentItem();
415     QWebHistoryItemPrivate *priv = new QWebHistoryItemPrivate(i);
416     return QWebHistoryItem(priv);
417 }
418
419 /*!
420   Returns the item after the current item in the history.
421 */
422 QWebHistoryItem QWebHistory::forwardItem() const
423 {
424     WebCore::HistoryItem *i = d->lst->forwardItem();
425     QWebHistoryItemPrivate *priv = new QWebHistoryItemPrivate(i);
426     return QWebHistoryItem(priv);
427 }
428
429 /*!
430   \since 4.5
431   Returns the index of the current item in history.
432 */
433 int QWebHistory::currentItemIndex() const
434 {
435     return d->lst->backListCount();
436 }
437
438 /*!
439   Returns the item at index \a i in the history.
440 */
441 QWebHistoryItem QWebHistory::itemAt(int i) const
442 {
443     QWebHistoryItemPrivate *priv;
444     if (i < 0 || i >= count())
445         priv = new QWebHistoryItemPrivate(0);
446     else {
447         WebCore::HistoryItem *item = d->lst->entries()[i].get();
448         priv = new QWebHistoryItemPrivate(item);
449     }
450     return QWebHistoryItem(priv);
451 }
452
453 /*!
454     Returns the total number of items in the history.
455 */
456 int QWebHistory::count() const
457 {
458     return d->lst->entries().size();
459 }
460
461 /*!
462   \since 4.5
463   Returns the maximum number of items in the history.
464
465   \sa setMaximumItemCount()
466 */
467 int QWebHistory::maximumItemCount() const
468 {
469     return d->lst->capacity();
470 }
471
472 /*!
473   \since 4.5
474   Sets the maximum number of items in the history to \a count.
475
476   \sa maximumItemCount()
477 */
478 void QWebHistory::setMaximumItemCount(int count)
479 {
480     d->lst->setCapacity(count);
481 }
482
483 /*!
484   \since 4.6
485   \fn QDataStream& operator<<(QDataStream& stream, const QWebHistory& history)
486   \relates QWebHistory
487
488   \brief The operator<< function streams a history into a data stream.
489
490   It saves the \a history into the specified \a stream.
491 */
492
493 QDataStream& operator<<(QDataStream& target, const QWebHistory& history)
494 {
495     QWebHistoryPrivate* d = history.d;
496
497     int version = DefaultHistoryVersion;
498
499     target << version;
500     target << history.count() << history.currentItemIndex();
501
502     const WebCore::HistoryItemVector &items = d->lst->entries();
503     for (unsigned i = 0; i < items.size(); i++)
504         items[i].get()->saveState(target, version);
505
506     return target;
507 }
508
509 /*!
510   \fn QDataStream& operator>>(QDataStream& stream, QWebHistory& history)
511   \relates QWebHistory
512   \since 4.6
513
514   \brief The operator>> function loads a history from a data stream.
515
516   Loads a QWebHistory from the specified \a stream into the given \a history.
517 */
518
519 QDataStream& operator>>(QDataStream& source, QWebHistory& history)
520 {
521     QWebHistoryPrivate* d = history.d;
522
523     int version;
524
525     source >> version;
526
527     if (version == 1) {
528         int count;
529         int currentIndex;
530         source >> count >> currentIndex;
531
532         history.clear();
533         // only if there are elements
534         if (count) {
535             // after clear() is new clear HistoryItem (at the end we had to remove it)
536             WebCore::HistoryItem* nullItem = d->lst->currentItem();
537             for (int i = 0; i < count; i++) {
538                 WTF::PassRefPtr<WebCore::HistoryItem> item = WebCore::HistoryItem::create();
539                 item->restoreState(source, version);
540                 d->lst->addItem(item);
541             }
542             d->lst->removeItem(nullItem);
543             history.goToItem(history.itemAt(currentIndex));
544         }
545     }
546
547     d->page()->updateNavigationActions();
548
549     return source;
550 }
551
552 QWebPagePrivate* QWebHistoryPrivate::page()
553 {
554     return QWebFramePrivate::kit(lst->page()->mainFrame())->page()->handle();
555 }